Splitting DescriptorArray::CopyInsert into CopyInsert, CopyAdd and CopyReplace.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 12 Jul 2012 13:34:02 +0000 (13:34 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 12 Jul 2012 13:34:02 +0000 (13:34 +0000)
Review URL: https://chromiumcodereview.appspot.com/10743003

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

src/factory.cc
src/objects.cc
src/objects.h
src/runtime.cc

index fa609e01f4631a184b911677e7a5d2a97c80260d..7b915371616863782650b973e22d331f4c0806e6 100644 (file)
@@ -888,13 +888,13 @@ Handle<Code> Factory::CopyCode(Handle<Code> code, Vector<byte> reloc_info) {
 }
 
 
-MUST_USE_RESULT static inline MaybeObject* DoCopyInsert(
+MUST_USE_RESULT static inline MaybeObject* DoCopyAdd(
     DescriptorArray* array,
     String* key,
     Object* value,
     PropertyAttributes attributes) {
   CallbacksDescriptor desc(key, value, attributes, 0);
-  MaybeObject* obj = array->CopyInsert(&desc);
+  MaybeObject* obj = array->CopyAdd(&desc);
   return obj;
 }
 
@@ -906,7 +906,7 @@ Handle<DescriptorArray> Factory::CopyAppendForeignDescriptor(
     Handle<Object> value,
     PropertyAttributes attributes) {
   CALL_HEAP_FUNCTION(isolate(),
-                     DoCopyInsert(*array, *key, *value, attributes),
+                     DoCopyAdd(*array, *key, *value, attributes),
                      DescriptorArray);
 }
 
index d6c86ddd8b2430155852f7883db61838c3936240..518826e8b2aac5048843d1c9d80adc167a5fcb37 100644 (file)
@@ -1553,8 +1553,7 @@ MaybeObject* JSObject::AddFastProperty(String* name,
   // Allocate new instance descriptors with (name, index) added
   FieldDescriptor new_field(name, index, attributes, 0);
   DescriptorArray* new_descriptors;
-  { MaybeObject* maybe_new_descriptors =
-        old_descriptors->CopyInsert(&new_field);
+  { MaybeObject* maybe_new_descriptors = old_descriptors->CopyAdd(&new_field);
     if (!maybe_new_descriptors->To(&new_descriptors)) {
       return maybe_new_descriptors;
     }
@@ -1615,7 +1614,7 @@ MaybeObject* JSObject::AddConstantFunctionProperty(
   ConstantFunctionDescriptor d(name, function, attributes, 0);
   DescriptorArray* new_descriptors;
   { MaybeObject* maybe_new_descriptors =
-        map()->instance_descriptors()->CopyInsert(&d);
+        map()->instance_descriptors()->CopyAdd(&d);
     if (!maybe_new_descriptors->To(&new_descriptors)) {
       return maybe_new_descriptors;
     }
@@ -4594,7 +4593,7 @@ static MaybeObject* CreateFreshAccessor(JSObject* obj,
   CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0);
   DescriptorArray* descriptors2;
   { MaybeObject* maybe_descriptors2 =
-        map1->instance_descriptors()->CopyInsert(&callbacks_descr2);
+        map1->instance_descriptors()->CopyAdd(&callbacks_descr2);
     if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2;
   }
 
@@ -5863,28 +5862,66 @@ MaybeObject* DescriptorArray::CopyFrom(int dst_index,
   return this;
 }
 
+MaybeObject* DescriptorArray::CopyReplace(Descriptor* descriptor,
+                                          int insertion_index) {
+  ASSERT(0 <= insertion_index && insertion_index < number_of_descriptors());
 
-MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) {
   // Ensure the key is a symbol.
   { MaybeObject* maybe_result = descriptor->KeyToSymbol();
     if (maybe_result->IsFailure()) return maybe_result;
   }
 
-  int new_size = number_of_descriptors();
+  int size = number_of_descriptors();
+
+  DescriptorArray* new_descriptors;
+  { MaybeObject* maybe_result = Allocate(size, MAY_BE_SHARED);
+    if (!maybe_result->To(&new_descriptors)) return maybe_result;
+  }
+
+  FixedArray::WhitenessWitness witness(new_descriptors);
+
+  // Copy the descriptors, replacing a descriptor.
+  for (int index = 0; index < size; ++index) {
+    if (index == insertion_index) continue;
+    MaybeObject* copy_result =
+        new_descriptors->CopyFrom(index, this, index, witness);
+    if (copy_result->IsFailure()) return copy_result;
+  }
+
+  descriptor->SetEnumerationIndex(GetDetails(insertion_index).index());
+  new_descriptors->Set(insertion_index, descriptor, witness);
+  new_descriptors->SetLastAdded(LastAdded());
+
+  SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
+
+  return new_descriptors;
+}
+
+
+MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) {
+  // Ensure the key is a symbol.
+  { MaybeObject* maybe_result = descriptor->KeyToSymbol();
+    if (maybe_result->IsFailure()) return maybe_result;
+  }
 
-  // If key is in descriptor, we replace it in-place when filtering.
-  // Count a null descriptor for key as inserted, not replaced.
+  // We replace the key if it is already present.
   int index = SearchWithCache(descriptor->GetKey());
-  const bool replacing = (index != kNotFound);
-  bool keep_enumeration_index = false;
-  if (replacing) {
-    // We are replacing an existing descriptor. We keep the enumeration index
-    // of a visible property.
-    keep_enumeration_index = true;
-  } else {
-    ++new_size;
+  if (index == kNotFound) return CopyAdd(descriptor);
+  return CopyReplace(descriptor, index);
+}
+
+
+MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) {
+  // Ensure the key is a symbol.
+  { MaybeObject* maybe_result = descriptor->KeyToSymbol();
+    if (maybe_result->IsFailure()) return maybe_result;
   }
 
+  String* key = descriptor->GetKey();
+  ASSERT(Search(key) == kNotFound);
+
+  int new_size = number_of_descriptors() + 1;
+
   DescriptorArray* new_descriptors;
   { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED);
     if (!maybe_result->To(&new_descriptors)) return maybe_result;
@@ -5892,42 +5929,25 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) {
 
   FixedArray::WhitenessWitness witness(new_descriptors);
 
-  // Set the enumeration index in the descriptors and set the enumeration index
-  // in the result.
-  if (keep_enumeration_index) {
-    descriptor->SetEnumerationIndex(GetDetails(index).index());
-  } else {
-    descriptor->SetEnumerationIndex(NextEnumerationIndex());
-  }
-
-  // Copy the descriptors, inserting or replacing a descriptor.
-  int to_index = 0;
+  // Copy the descriptors, inserting a descriptor.
   int insertion_index = -1;
-  int from_index = 0;
-  while (from_index < number_of_descriptors()) {
-    if (insertion_index < 0 &&
-        InsertionPointFound(GetKey(from_index), descriptor->GetKey())) {
-      insertion_index = to_index++;
-      if (replacing) from_index++;
-    } else {
-      MaybeObject* copy_result =
-          new_descriptors->CopyFrom(to_index++, this, from_index, witness);
-      if (copy_result->IsFailure()) return copy_result;
-      from_index++;
+  int to = 0;
+  for (int from = 0; from < number_of_descriptors(); ++from) {
+    if (insertion_index < 0 && InsertionPointFound(GetKey(from), key)) {
+      insertion_index = to++;
     }
+    MaybeObject* copy_result =
+        new_descriptors->CopyFrom(to++, this, from, witness);
+    if (copy_result->IsFailure()) return copy_result;
   }
-  if (insertion_index < 0) insertion_index = to_index++;
+  if (insertion_index < 0) insertion_index = to++;
 
-  ASSERT(insertion_index < new_descriptors->number_of_descriptors());
-  new_descriptors->Set(insertion_index, descriptor, witness);
+  ASSERT(to == new_descriptors->number_of_descriptors());
 
-  if (!replacing) {
-    new_descriptors->SetLastAdded(insertion_index);
-  } else {
-    new_descriptors->SetLastAdded(LastAdded());
-  }
+  descriptor->SetEnumerationIndex(NextEnumerationIndex());
+  new_descriptors->Set(insertion_index, descriptor, witness);
+  new_descriptors->SetLastAdded(insertion_index);
 
-  ASSERT(to_index == new_descriptors->number_of_descriptors());
   SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
 
   return new_descriptors;
index 89d28099f69cf6595b364a4948e82057a7ea9b95..28eb4f3096412d59fc276b75327199793a32072a 100644 (file)
@@ -2569,6 +2569,9 @@ class DescriptorArray: public FixedArray {
   // If adding a real property, map transitions must be removed.  If adding
   // a transition, they must not be removed.  All null descriptors are removed.
   MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor);
+  MUST_USE_RESULT MaybeObject* CopyAdd(Descriptor* descriptor);
+  MUST_USE_RESULT MaybeObject* CopyReplace(Descriptor* descriptor,
+                                           int insertion_index);
 
   // Indicates whether the search function should expect a sorted or an unsorted
   // descriptor array as input.
index 42d19aacde1999e01c454c35039122ff95743d37..ddbee6d12537e5be4420a8f261a7fa52e62a5c74 100644 (file)
@@ -2181,7 +2181,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
         details.index());
     // Construct a new field descriptors array containing the new descriptor.
     DescriptorArray* new_descriptors;
-    { MaybeObject* maybe_descriptors = instance_desc->CopyInsert(&new_desc);
+    { MaybeObject* maybe_descriptors =
+          instance_desc->CopyReplace(&new_desc, index);
       if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
     }
     // Create a new map featuring the new field descriptors array.