You can't use BinarySearch on an unsorted array and other
authorerik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Sun, 26 Oct 2008 20:50:05 +0000 (20:50 +0000)
committererik.corry@gmail.com <erik.corry@gmail.com@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Sun, 26 Oct 2008 20:50:05 +0000 (20:50 +0000)
sillinesses found while trying to get rid of medium-sized strings.

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@595 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/factory.cc
src/heap.cc
src/ic-ia32.cc
src/objects-inl.h
src/objects.cc
src/objects.h
test/mjsunit/in.js

index 82e646f9209b081cbb71bbc8695c1ba225eaac83..55af33df0d9a2eefaed400e4c75b861e9b90af26 100644 (file)
@@ -524,7 +524,7 @@ Handle<DescriptorArray> Factory::CopyAppendCallbackDescriptors(
     Handle<String> key =
         SymbolFromString(Handle<String>(String::cast(entry->name())));
     // Check if a descriptor with this name already exists before writing.
-    if (result->BinarySearch(*key, 0, descriptor_count - 1) ==
+    if (result->LinearSearch(*key, descriptor_count) ==
         DescriptorArray::kNotFound) {
       CallbacksDescriptor desc(*key, *entry, entry->property_attributes());
       w.Write(&desc);
index 4262cb06eaa050a5ddeb6e0950518e3d5b63f67c..14c19408ed2282d563a2ad38e03c2955fef3a132 100644 (file)
@@ -1936,17 +1936,17 @@ Map* Heap::SymbolMapForString(String* string) {
   }
 
   if (map == short_sliced_string_map()) return short_sliced_symbol_map();
-  if (map == medium_sliced_string_map()) return short_sliced_symbol_map();
-  if (map == long_sliced_string_map()) return short_sliced_symbol_map();
+  if (map == medium_sliced_string_map()) return medium_sliced_symbol_map();
+  if (map == long_sliced_string_map()) return long_sliced_symbol_map();
 
   if (map == short_sliced_ascii_string_map()) {
     return short_sliced_ascii_symbol_map();
   }
   if (map == medium_sliced_ascii_string_map()) {
-    return short_sliced_ascii_symbol_map();
+    return medium_sliced_ascii_symbol_map();
   }
   if (map == long_sliced_ascii_string_map()) {
-    return short_sliced_ascii_symbol_map();
+    return long_sliced_ascii_symbol_map();
   }
 
   if (map == short_external_string_map()) return short_external_string_map();
index a422ccf2ac77f3a6b5486c1b2475b5ed9ccc39da..31e33703c7519648ca3596c2491e6e78635592fd 100644 (file)
@@ -206,6 +206,18 @@ void LoadIC::GenerateFunctionPrototype(MacroAssembler* masm) {
 }
 
 
+#ifdef DEBUG
+// For use in assert below.
+static int TenToThe(int exponent) {
+  ASSERT(exponent <= 9);
+  ASSERT(exponent >= 1);
+  int answer = 10;
+  for (int i = 1; i < exponent; i++) answer *= 10;
+  return answer;
+}
+#endif
+
+
 void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   // ----------- S t a t e -------------
   //  -- esp[0] : return address
@@ -262,6 +274,11 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
   __ IncrementCounter(&Counters::keyed_load_generic_symbol, 1);
   __ ret(0);
   // Array index string: If short enough use cache in length/hash field (ebx).
+  // We assert that there are enough bits in an int32_t after the hash shift
+  // bits have been subtracted to allow space for the length and the cached
+  // array index.
+  ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) <
+             (1 << (String::kShortLengthShift - String::kHashShift)));
   __ bind(&index_string);
   const int kLengthFieldLimit =
       (String::kMaxCachedArrayIndexLength + 1) << String::kShortLengthShift;
index 49fb76a4b72f0f3fe7a82826e3de55a8d51d6523..33bca561fa5971794f6173bcc5a537605a5b8c7c 100644 (file)
@@ -1130,10 +1130,7 @@ int DescriptorArray::Search(String* name) {
   // Fast case: do linear search for small arrays.
   const int kMaxElementsForLinearSearch = 8;
   if (name->IsSymbol() && nof < kMaxElementsForLinearSearch) {
-    for (int number = 0; number < nof; number++) {
-      if (name == GetKey(number)) return number;
-    }
-    return kNotFound;
+    return LinearSearch(name, nof);
   }
 
   // Slow case: perform binary search.
index 0be6d283f944a80dd47a8b3ba1aa89100c0e52c6..7cfa5a0df8a1668b8b91237b81e158b151370c55 100644 (file)
@@ -2877,6 +2877,14 @@ int DescriptorArray::BinarySearch(String* name, int low, int high) {
 }
 
 
+int DescriptorArray::LinearSearch(String* name, int len) {
+  for (int number = 0; number < len; number++) {
+    if (name->Equals(GetKey(number))) return number;
+  }
+  return kNotFound;
+}
+
+
 #ifdef DEBUG
 bool DescriptorArray::IsEqualTo(DescriptorArray* other) {
   if (IsEmpty()) return other->IsEmpty();
index 05379ca6cebcac754afaf2fbab8e3a9287f169aa..a3a43abb218356596d86629de5d2ee994d7296c4 100644 (file)
@@ -1629,6 +1629,10 @@ class DescriptorArray: public FixedArray {
   // with low=0 and high=2.
   int BinarySearch(String* name, int low, int high);
 
+  // Perform a linear search in the instance descriptors represented
+  // by this fixed array.  len is the number of descriptor indeces that are
+  // valid.  Does not require the descriptors to be sorted.
+  int LinearSearch(String* name, int len);
 
   // Allocates a DescriptorArray, but returns the singleton
   // empty descriptor array object if number_of_descriptors is 0.
index 23ef65efdba54ce5c809aa5392e00858a0cd6c79..f98db42f6197269446461241ad442a26f8221452 100644 (file)
@@ -81,18 +81,12 @@ assertFalse(NaN in a);
 assertFalse(Infinity in a);
 assertFalse(-Infinity in a);
 
-/*****
- * NOTE: Two of the tests below are disabled due to a bug in V8.
- * Fast case (non-dictionary) sparse arrays do not work as advertised.
- *
- */
-
 var a = [];
 a[1] = 2;
-//assertFalse(0 in a);
+assertFalse(0 in a);
 assertTrue(1 in a);
 assertFalse(2 in a);
-//assertFalse('0' in a); 
+assertFalse('0' in a); 
 assertTrue('1' in a);
 assertFalse('2' in a);
 assertTrue('toString' in a, "toString");