Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index d6c86ddd8b2430155852f7883db61838c3936240..518826e8b2aac5048843d1c9d80adc167a5fcb37 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -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; |