Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(372)

Unified Diff: src/objects.cc

Issue 10695120: Ensure that all descriptors have a valid enumeration index, and replace NextEnumIndex with LastAdde… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comment. Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index abaaa2f378bfe50211a0a5e5cf2f948aee15e727..295830e107d86bbcc7f65cd9a6c288d5a0c77c15 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1546,7 +1546,7 @@ MaybeObject* JSObject::AddFastProperty(String* name,
int index = map()->NextFreePropertyIndex();
// Allocate new instance descriptors with (name, index) added
- FieldDescriptor new_field(name, index, attributes);
+ FieldDescriptor new_field(name, index, attributes, 0);
DescriptorArray* new_descriptors;
{ MaybeObject* maybe_new_descriptors =
old_descriptors->CopyInsert(&new_field);
@@ -1555,18 +1555,11 @@ MaybeObject* JSObject::AddFastProperty(String* name,
}
}
- // Only allow map transition if the object isn't the global object and there
- // is not a transition for the name, or there's a transition for the name but
- // it's unrelated to properties.
- int descriptor_index = old_descriptors->SearchWithCache(name);
-
- // Element transitions are stored in the descriptor for property "", which is
- // not a identifier and should have forced a switch to slow properties above.
- bool can_insert_transition = descriptor_index == DescriptorArray::kNotFound;
+ // Only allow map transition if the object isn't the global object.
bool allow_map_transition =
- can_insert_transition &&
(isolate->context()->global_context()->object_function()->map() != map());
+ ASSERT(old_descriptors->Search(name) == DescriptorArray::kNotFound);
ASSERT(index < map()->inobject_properties() ||
(index - map()->inobject_properties()) < properties()->length() ||
map()->unused_property_fields() == 0);
@@ -1622,7 +1615,7 @@ MaybeObject* JSObject::AddConstantFunctionProperty(
JSFunction* function,
PropertyAttributes attributes) {
// Allocate new instance descriptors with (name, function) added
- ConstantFunctionDescriptor d(name, function, attributes);
+ ConstantFunctionDescriptor d(name, function, attributes, 0);
DescriptorArray* new_descriptors;
{ MaybeObject* maybe_new_descriptors =
map()->instance_descriptors()->CopyInsert(&d);
@@ -1865,7 +1858,7 @@ MaybeObject* JSObject::ConvertDescriptorToField(String* name,
}
int index = map()->NextFreePropertyIndex();
- FieldDescriptor new_field(name, index, attributes);
+ FieldDescriptor new_field(name, index, attributes, 0);
// Make a new DescriptorArray replacing an entry with FieldDescriptor.
Object* descriptors_unchecked;
{ MaybeObject* maybe_descriptors_unchecked =
@@ -2938,7 +2931,7 @@ MaybeObject* JSObject::SetPropertyForResult(LookupResult* result,
Map* transition_map = Map::cast(transition);
DescriptorArray* descriptors = transition_map->instance_descriptors();
- int descriptor = descriptors->SearchWithCache(*name);
+ int descriptor = descriptors->LastAdded();
PropertyDetails details = descriptors->GetDetails(descriptor);
ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION);
@@ -3062,7 +3055,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
Map* transition_map = Map::cast(transition);
DescriptorArray* descriptors = transition_map->instance_descriptors();
- int descriptor = descriptors->Search(name);
+ int descriptor = descriptors->LastAdded();
PropertyDetails details = descriptors->GetDetails(descriptor);
ASSERT(details.type() == FIELD || details.type() == CONSTANT_FUNCTION);
@@ -4610,7 +4603,7 @@ static MaybeObject* CreateFreshAccessor(JSObject* obj,
// step 2: create a copy of the descriptors, incl. the new getter/setter pair
Map* map1 = obj->map();
- CallbacksDescriptor callbacks_descr2(name, accessors2, attributes);
+ CallbacksDescriptor callbacks_descr2(name, accessors2, attributes, 0);
DescriptorArray* descriptors2;
{ MaybeObject* maybe_descriptors2 =
map1->instance_descriptors()->CopyInsert(&callbacks_descr2);
@@ -4657,7 +4650,7 @@ static bool TransitionToSameAccessor(Object* map,
Object* accessor,
PropertyAttributes attributes ) {
DescriptorArray* descs = Map::cast(map)->instance_descriptors();
- int number = descs->SearchWithCache(name);
+ int number = descs->LastAdded();
ASSERT(number != DescriptorArray::kNotFound);
Object* target_accessor =
AccessorPair::cast(descs->GetCallbacksObject(number))->get(component);
@@ -4681,7 +4674,7 @@ static MaybeObject* NewCallbackTransition(JSObject* obj,
// step 2: create a copy of the descriptors, incl. the new getter/setter pair
Map* map2 = obj->map();
- CallbacksDescriptor callbacks_descr3(name, accessors3, attributes);
+ CallbacksDescriptor callbacks_descr3(name, accessors3, attributes, 0);
DescriptorArray* descriptors3;
{ MaybeObject* maybe_descriptors3 =
map2->instance_descriptors()->CopyInsert(&callbacks_descr3);
@@ -5817,8 +5810,7 @@ MaybeObject* DescriptorArray::Allocate(int number_of_descriptors,
if (!maybe_array->To(&result)) return maybe_array;
}
- result->set(kEnumerationIndexIndex,
- Smi::FromInt(PropertyDetails::kInitialIndex));
+ result->set(kLastAddedIndex, Smi::FromInt(-1));
result->set(kTransitionsIndex, Smi::FromInt(0));
return result;
}
@@ -5830,9 +5822,9 @@ void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
ASSERT(bridge_storage->length() >= kEnumCacheBridgeLength);
ASSERT(new_index_cache->IsSmi() || new_index_cache->IsFixedArray());
if (HasEnumCache()) {
- FixedArray::cast(get(kEnumerationIndexIndex))->
+ FixedArray::cast(get(kLastAddedIndex))->
set(kEnumCacheBridgeCacheIndex, new_cache);
- FixedArray::cast(get(kEnumerationIndexIndex))->
+ FixedArray::cast(get(kLastAddedIndex))->
set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
} else {
if (IsEmpty()) return; // Do nothing for empty descriptor array.
@@ -5841,9 +5833,9 @@ void DescriptorArray::SetEnumCache(FixedArray* bridge_storage,
FixedArray::cast(bridge_storage)->
set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache);
NoWriteBarrierSet(FixedArray::cast(bridge_storage),
- kEnumCacheBridgeEnumIndex,
- get(kEnumerationIndexIndex));
- set(kEnumerationIndexIndex, bridge_storage);
+ kEnumCacheBridgeLastAdded,
+ get(kLastAddedIndex));
+ set(kLastAddedIndex, bridge_storage);
}
}
@@ -5910,14 +5902,11 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) {
// Set the enumeration index in the descriptors and set the enumeration index
// in the result.
- int enumeration_index = NextEnumerationIndex();
if (keep_enumeration_index) {
descriptor->SetEnumerationIndex(GetDetails(index).index());
} else {
- descriptor->SetEnumerationIndex(enumeration_index);
- ++enumeration_index;
+ descriptor->SetEnumerationIndex(NextEnumerationIndex());
}
- new_descriptors->SetNextEnumerationIndex(enumeration_index);
// Copy the descriptors, inserting or replacing a descriptor.
int to_index = 0;
@@ -5939,6 +5928,11 @@ MaybeObject* DescriptorArray::CopyInsert(Descriptor* descriptor) {
ASSERT(insertion_index < new_descriptors->number_of_descriptors());
new_descriptors->Set(insertion_index, descriptor, witness);
+ if (!replacing) {
+ new_descriptors->SetLastAdded(insertion_index);
+ } else {
+ new_descriptors->SetLastAdded(LastAdded());
+ }
ASSERT(to_index == new_descriptors->number_of_descriptors());
SLOW_ASSERT(new_descriptors->IsSortedNoDuplicates());
@@ -5964,8 +5958,9 @@ MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) {
new_descriptors->CopyFrom(i, this, i, witness);
if (copy_result->IsFailure()) return copy_result;
}
+ new_descriptors->SetLastAdded(LastAdded());
}
- new_descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
+
return new_descriptors;
}
@@ -5976,6 +5971,8 @@ MaybeObject* DescriptorArray::Copy(SharedMode shared_mode) {
void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) {
// In-place heap sort.
int len = number_of_descriptors();
+ // Nothing to sort.
+ if (len == 0) return;
// Bottom-up max-heap construction.
// Index of the last node with children
@@ -6023,6 +6020,19 @@ void DescriptorArray::SortUnchecked(const WhitenessWitness& witness) {
parent_index = child_index;
}
}
+
+ int last_enum_index = -1;
+ int last_added = -1;
+ for (int i = 0; i < len; ++i) {
+ int current_enum = GetDetails(i).index();
+ if (current_enum > last_enum_index) {
+ last_added = i;
+ last_enum_index = current_enum;
+ }
+ }
+ SetLastAdded(last_added);
+
+ ASSERT(LastAdded() != -1);
}
@@ -12720,7 +12730,7 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
JSFunction::cast(value),
details.attributes(),
details.index());
- descriptors->Set(next_descriptor++, &d, witness);
+ descriptors->Set(next_descriptor, &d, witness);
} else if (type == NORMAL) {
if (current_offset < inobject_props) {
obj->InObjectPropertyAtPut(current_offset,
@@ -12734,7 +12744,7 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
current_offset++,
details.attributes(),
details.index());
- descriptors->Set(next_descriptor++, &d, witness);
+ descriptors->Set(next_descriptor, &d, witness);
} else if (type == CALLBACKS) {
if (value->IsAccessorPair()) {
MaybeObject* maybe_copy =
@@ -12745,10 +12755,11 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
value,
details.attributes(),
details.index());
- descriptors->Set(next_descriptor++, &d, witness);
+ descriptors->Set(next_descriptor, &d, witness);
} else {
UNREACHABLE();
}
+ ++next_descriptor;
}
}
ASSERT(current_offset == number_of_fields);
@@ -12768,7 +12779,6 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
obj->set_properties(FixedArray::cast(fields));
ASSERT(obj->IsJSObject());
- descriptors->SetNextEnumerationIndex(NextEnumerationIndex());
// Check that it really works.
ASSERT(obj->HasFastProperties());
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698