Commit 0a41b8c2 authored by verwaest@chromium.org's avatar verwaest@chromium.org

Splitting DescriptorArray::CopyInsert into CopyInsert, CopyAdd and CopyReplace.

Review URL: https://chromiumcodereview.appspot.com/10743003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12060 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8ce1ebb5
...@@ -888,13 +888,13 @@ Handle<Code> Factory::CopyCode(Handle<Code> code, Vector<byte> reloc_info) { ...@@ -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, DescriptorArray* array,
String* key, String* key,
Object* value, Object* value,
PropertyAttributes attributes) { PropertyAttributes attributes) {
CallbacksDescriptor desc(key, value, attributes, 0); CallbacksDescriptor desc(key, value, attributes, 0);
MaybeObject* obj = array->CopyInsert(&desc); MaybeObject* obj = array->CopyAdd(&desc);
return obj; return obj;
} }
...@@ -906,7 +906,7 @@ Handle<DescriptorArray> Factory::CopyAppendForeignDescriptor( ...@@ -906,7 +906,7 @@ Handle<DescriptorArray> Factory::CopyAppendForeignDescriptor(
Handle<Object> value, Handle<Object> value,
PropertyAttributes attributes) { PropertyAttributes attributes) {
CALL_HEAP_FUNCTION(isolate(), CALL_HEAP_FUNCTION(isolate(),
DoCopyInsert(*array, *key, *value, attributes), DoCopyAdd(*array, *key, *value, attributes),
DescriptorArray); DescriptorArray);
} }
......
...@@ -1553,8 +1553,7 @@ MaybeObject* JSObject::AddFastProperty(String* name, ...@@ -1553,8 +1553,7 @@ MaybeObject* JSObject::AddFastProperty(String* name,
// Allocate new instance descriptors with (name, index) added // Allocate new instance descriptors with (name, index) added
FieldDescriptor new_field(name, index, attributes, 0); FieldDescriptor new_field(name, index, attributes, 0);
DescriptorArray* new_descriptors; DescriptorArray* new_descriptors;
{ MaybeObject* maybe_new_descriptors = { MaybeObject* maybe_new_descriptors = old_descriptors->CopyAdd(&new_field);
old_descriptors->CopyInsert(&new_field);
if (!maybe_new_descriptors->To(&new_descriptors)) { if (!maybe_new_descriptors->To(&new_descriptors)) {
return maybe_new_descriptors; return maybe_new_descriptors;
} }
...@@ -1615,7 +1614,7 @@ MaybeObject* JSObject::AddConstantFunctionProperty( ...@@ -1615,7 +1614,7 @@ MaybeObject* JSObject::AddConstantFunctionProperty(
ConstantFunctionDescriptor d(name, function, attributes, 0); ConstantFunctionDescriptor d(name, function, attributes, 0);
DescriptorArray* new_descriptors; DescriptorArray* new_descriptors;
{ MaybeObject* maybe_new_descriptors = { MaybeObject* maybe_new_descriptors =
map()->instance_descriptors()->CopyInsert(&d); map()->instance_descriptors()->CopyAdd(&d);
if (!maybe_new_descriptors->To(&new_descriptors)) { if (!maybe_new_descriptors->To(&new_descriptors)) {
return maybe_new_descriptors; return maybe_new_descriptors;
} }
...@@ -4594,7 +4593,7 @@ static MaybeObject* CreateFreshAccessor(JSObject* obj, ...@@ -4594,7 +4593,7 @@ static MaybeObject* CreateFreshAccessor(JSObject* obj,
CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0); CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0);
DescriptorArray* descriptors2; DescriptorArray* descriptors2;
{ MaybeObject* maybe_descriptors2 = { MaybeObject* maybe_descriptors2 =
map1->instance_descriptors()->CopyInsert(&callbacks_descr2); map1->instance_descriptors()->CopyAdd(&callbacks_descr2);
if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2; if (!maybe_descriptors2->To(&descriptors2)) return maybe_descriptors2;
} }
...@@ -5863,28 +5862,66 @@ MaybeObject* DescriptorArray::CopyFrom(int dst_index, ...@@ -5863,28 +5862,66 @@ MaybeObject* DescriptorArray::CopyFrom(int dst_index,
return this; 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. // Ensure the key is a symbol.
{ MaybeObject* maybe_result = descriptor->KeyToSymbol(); { MaybeObject* maybe_result = descriptor->KeyToSymbol();
if (maybe_result->IsFailure()) return maybe_result; if (maybe_result->IsFailure()) return maybe_result;
} }
int new_size = number_of_descriptors(); int size = number_of_descriptors();
// If key is in descriptor, we replace it in-place when filtering. DescriptorArray* new_descriptors;
// Count a null descriptor for key as inserted, not replaced. { 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;
}
// We replace the key if it is already present.
int index = SearchWithCache(descriptor->GetKey()); int index = SearchWithCache(descriptor->GetKey());
const bool replacing = (index != kNotFound); if (index == kNotFound) return CopyAdd(descriptor);
bool keep_enumeration_index = false; return CopyReplace(descriptor, index);
if (replacing) { }
// We are replacing an existing descriptor. We keep the enumeration index
// of a visible property.
keep_enumeration_index = true; MaybeObject* DescriptorArray::CopyAdd(Descriptor* descriptor) {
} else { // Ensure the key is a symbol.
++new_size; { 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; DescriptorArray* new_descriptors;
{ MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED); { MaybeObject* maybe_result = Allocate(new_size, MAY_BE_SHARED);
if (!maybe_result->To(&new_descriptors)) return maybe_result; if (!maybe_result->To(&new_descriptors)) return maybe_result;
...@@ -5892,42 +5929,25 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) { ...@@ -5892,42 +5929,25 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) {
FixedArray::WhitenessWitness witness(new_descriptors); FixedArray::WhitenessWitness witness(new_descriptors);
// Set the enumeration index in the descriptors and set the enumeration index // Copy the descriptors, inserting a descriptor.
// 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;
int insertion_index = -1; int insertion_index = -1;
int from_index = 0; int to = 0;
while (from_index < number_of_descriptors()) { for (int from = 0; from < number_of_descriptors(); ++from) {
if (insertion_index < 0 && if (insertion_index < 0 && InsertionPointFound(GetKey(from), key)) {
InsertionPointFound(GetKey(from_index), descriptor->GetKey())) { insertion_index = to++;
insertion_index = to_index++; }
if (replacing) from_index++;
} else {
MaybeObject* copy_result = MaybeObject* copy_result =
new_descriptors->CopyFrom(to_index++, this, from_index, witness); new_descriptors->CopyFrom(to++, this, from, witness);
if (copy_result->IsFailure()) return copy_result; if (copy_result->IsFailure()) return copy_result;
from_index++;
}
} }
if (insertion_index < 0) insertion_index = to_index++; if (insertion_index < 0) insertion_index = to++;
ASSERT(insertion_index < new_descriptors->number_of_descriptors()); ASSERT(to == new_descriptors->number_of_descriptors());
new_descriptors->Set(insertion_index, descriptor, witness);
if (!replacing) { descriptor->SetEnumerationIndex(NextEnumerationIndex());
new_descriptors->Set(insertion_index, descriptor, witness);
new_descriptors->SetLastAdded(insertion_index); new_descriptors->SetLastAdded(insertion_index);
} else {
new_descriptors->SetLastAdded(LastAdded());
}
ASSERT(to_index == new_descriptors->number_of_descriptors());
SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates()); SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
return new_descriptors; return new_descriptors;
......
...@@ -2569,6 +2569,9 @@ class DescriptorArray: public FixedArray { ...@@ -2569,6 +2569,9 @@ class DescriptorArray: public FixedArray {
// If adding a real property, map transitions must be removed. If adding // If adding a real property, map transitions must be removed. If adding
// a transition, they must not be removed. All null descriptors are removed. // a transition, they must not be removed. All null descriptors are removed.
MUST_USE_RESULT MaybeObject* CopyInsert(Descriptor* descriptor); 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 // Indicates whether the search function should expect a sorted or an unsorted
// descriptor array as input. // descriptor array as input.
......
...@@ -2181,7 +2181,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) { ...@@ -2181,7 +2181,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_FunctionSetReadOnlyPrototype) {
details.index()); details.index());
// Construct a new field descriptors array containing the new descriptor. // Construct a new field descriptors array containing the new descriptor.
DescriptorArray* new_descriptors; 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; if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;
} }
// Create a new map featuring the new field descriptors array. // Create a new map featuring the new field descriptors array.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment