Chromium Code Reviews| Index: src/handles.cc |
| diff --git a/src/handles.cc b/src/handles.cc |
| index 7ccfe08e4579016ebb496c9e010d5611df7fec16..c29369dd097e9ab940f763f62ffbe1dcedef7ce2 100644 |
| --- a/src/handles.cc |
| +++ b/src/handles.cc |
| @@ -705,33 +705,52 @@ Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, |
| Isolate* isolate = object->GetIsolate(); |
| if (object->HasFastProperties()) { |
| if (object->map()->instance_descriptors()->HasEnumCache()) { |
| - isolate->counters()->enum_cache_hits()->Increment(); |
| + int own_property_count = object->map()->EnumLength(); |
| + |
| + // Mark that we have an enum cache if we are allowed to cache it. |
| + if (cache_result && own_property_count == Map::kInvalidEnumCache) { |
| + int num_enum = object->map()->NumberOfDescribedProperties(DONT_ENUM); |
| + object->map()->SetEnumLength(num_enum); |
| + } |
| + |
| DescriptorArray* desc = object->map()->instance_descriptors(); |
| - return Handle<FixedArray>(FixedArray::cast(desc->GetEnumCache()), |
| - isolate); |
| + Handle<FixedArray> keys(FixedArray::cast(desc->GetEnumCache()), isolate); |
| + |
| + isolate->counters()->enum_cache_hits()->Increment(); |
| + return keys; |
| } |
| - isolate->counters()->enum_cache_misses()->Increment(); |
| + |
| Handle<Map> map(object->map()); |
| - int num_enum = object->NumberOfLocalProperties(DONT_ENUM); |
| - Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum); |
| - Handle<FixedArray> sort_array = isolate->factory()->NewFixedArray(num_enum); |
| + if (map->instance_descriptors()->IsEmpty()) { |
| + // Count encountering the empty descriptor array as a cache hit. |
|
Michael Starzinger
2012/08/06 15:06:22
Hmm, "encountering" is an adjective, I would just
Toon Verwaest
2012/08/07 10:49:47
Done.
|
| + isolate->counters()->enum_cache_hits()->Increment(); |
| + if (cache_result) map->SetEnumLength(0); |
| + return Handle<FixedArray>(isolate->factory()->empty_fixed_array()); |
|
Michael Starzinger
2012/08/06 15:06:22
No need for a copy constructor of the handle here!
Toon Verwaest
2012/08/07 10:49:47
Done.
|
| + } |
| + |
| + isolate->counters()->enum_cache_misses()->Increment(); |
| + |
| + int num_enum = map->NumberOfDescribedProperties(DONT_ENUM); |
| + |
| + Handle<FixedArray> storage; |
| + Handle<FixedArray> sort_array; |
| Handle<FixedArray> indices; |
| Handle<FixedArray> sort_array2; |
| - if (cache_result) { |
| - indices = isolate->factory()->NewFixedArray(num_enum); |
| - sort_array2 = isolate->factory()->NewFixedArray(num_enum); |
| - } |
| + storage = isolate->factory()->NewFixedArray(num_enum); |
|
Michael Starzinger
2012/08/06 15:06:22
Can we just merge the handle declarations and the
Toon Verwaest
2012/08/07 10:49:47
Done.
|
| + sort_array = isolate->factory()->NewFixedArray(num_enum); |
| + indices = isolate->factory()->NewFixedArray(num_enum); |
| + sort_array2 = isolate->factory()->NewFixedArray(num_enum); |
| Handle<DescriptorArray> descs = |
| Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate); |
| for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| - if (!descs->GetDetails(i).IsDontEnum()) { |
| + PropertyDetails details = descs->GetDetails(i); |
| + if (!details.IsDontEnum()) { |
| storage->set(index, descs->GetKey(i)); |
| - PropertyDetails details = descs->GetDetails(i); |
| sort_array->set(index, Smi::FromInt(details.index())); |
| if (!indices.is_null()) { |
| if (details.type() != FIELD) { |
| @@ -749,21 +768,24 @@ Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, |
| index++; |
| } |
| } |
| + ASSERT(index == storage->length()); |
| + |
| storage->SortPairs(*sort_array, sort_array->length()); |
| if (!indices.is_null()) { |
| indices->SortPairs(*sort_array2, sort_array2->length()); |
| } |
| + |
| + Handle<FixedArray> bridge_storage = |
| + isolate->factory()->NewFixedArray( |
| + DescriptorArray::kEnumCacheBridgeLength); |
| + DescriptorArray* desc = object->map()->instance_descriptors(); |
| + desc->SetEnumCache(*bridge_storage, |
| + *storage, |
| + indices.is_null() ? Object::cast(Smi::FromInt(0)) |
| + : Object::cast(*indices)); |
| if (cache_result) { |
| - Handle<FixedArray> bridge_storage = |
| - isolate->factory()->NewFixedArray( |
| - DescriptorArray::kEnumCacheBridgeLength); |
| - DescriptorArray* desc = object->map()->instance_descriptors(); |
| - desc->SetEnumCache(*bridge_storage, |
| - *storage, |
| - indices.is_null() ? Object::cast(Smi::FromInt(0)) |
| - : Object::cast(*indices)); |
| + object->map()->SetEnumLength(index); |
| } |
| - ASSERT(storage->length() == index); |
| return storage; |
| } else { |
| int num_enum = object->NumberOfLocalProperties(DONT_ENUM); |