Chromium Code Reviews| Index: src/objects.cc | 
| diff --git a/src/objects.cc b/src/objects.cc | 
| index b6c40d67fe8a64c13d4f7b44779e47281956a306..80d00f69e398cdc5b5fe8c16f4bc4bd4c3de8d78 100644 | 
| --- a/src/objects.cc | 
| +++ b/src/objects.cc | 
| @@ -6831,8 +6831,9 @@ void KeyAccumulator::Grow() { | 
| } | 
| -MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 
| - KeyCollectionType type) { | 
| +MaybeHandle<FixedArray> JSReceiver::GetKeys( | 
| + Handle<JSReceiver> object, KeyCollectionType type, | 
| + IncludeSymbolNamedProperties include_symbols) { | 
| USE(ContainsOnlyValidKeys); | 
| Isolate* isolate = object->GetIsolate(); | 
| KeyAccumulator accumulator(isolate); | 
| @@ -6890,33 +6891,46 @@ MaybeHandle<FixedArray> JSReceiver::GetKeys(Handle<JSReceiver> object, | 
| DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 
| } | 
| - // We can cache the computed property keys if access checks are | 
| - // not needed and no interceptors are involved. | 
| - // | 
| - // We do not use the cache if the object has elements and | 
| - // therefore it does not make sense to cache the property names | 
| - // for arguments objects. Arguments objects will always have | 
| - // elements. | 
| - // Wrapped strings have elements, but don't have an elements | 
| - // array or dictionary. So the fast inline test for whether to | 
| - // use the cache says yes, so we should not create a cache. | 
| - bool cache_enum_keys = | 
| - ((current->map()->GetConstructor() != *arguments_function) && | 
| - !current->IsJSValue() && !current->IsAccessCheckNeeded() && | 
| - !current->HasNamedInterceptor() && !current->HasIndexedInterceptor()); | 
| - // Compute the property keys and cache them if possible. | 
| - | 
| - Handle<FixedArray> enum_keys = | 
| - JSObject::GetEnumPropertyKeys(current, cache_enum_keys); | 
| - accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); | 
| + if (include_symbols == SKIP_SYMBOLS) { | 
| + // We can cache the computed property keys if access checks are | 
| + // not needed and no interceptors are involved. | 
| + // | 
| + // We do not use the cache if the object has elements and | 
| + // therefore it does not make sense to cache the property names | 
| + // for arguments objects. Arguments objects will always have | 
| + // elements. | 
| + // Wrapped strings have elements, but don't have an elements | 
| + // array or dictionary. So the fast inline test for whether to | 
| + // use the cache says yes, so we should not create a cache. | 
| + bool cache_enum_keys = | 
| + ((current->map()->GetConstructor() != *arguments_function) && | 
| + !current->IsJSValue() && !current->IsAccessCheckNeeded() && | 
| + !current->HasNamedInterceptor() && | 
| + !current->HasIndexedInterceptor()); | 
| + // Compute the property keys and cache them if possible. | 
| + Handle<FixedArray> enum_keys = | 
| + JSObject::GetEnumPropertyKeys(current, cache_enum_keys); | 
| + accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); | 
| + } else { | 
| + DCHECK(include_symbols == INCLUDE_SYMBOLS); | 
| + PropertyAttributes filter = | 
| + static_cast<PropertyAttributes>(DONT_ENUM | PRIVATE_SYMBOL); | 
| + Handle<FixedArray> property_keys = isolate->factory()->NewFixedArray( | 
| + current->NumberOfOwnProperties(filter)); | 
| + current->GetOwnPropertyNames(*property_keys, 0, filter); | 
| 
 
Camillo Bruni
2015/09/29 16:27:20
Not sure how much work this would be, but essentia
 
Jakob Kummerow
2015/09/30 13:59:30
I'm leaving that to you :-)
 
 | 
| + accumulator.AddKeys(property_keys, FixedArray::ALL_KEYS); | 
| + } | 
| DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 
| - // Add the non-symbol property keys from the interceptor. | 
| + // Add the property keys from the interceptor. | 
| if (current->HasNamedInterceptor()) { | 
| Handle<JSObject> result; | 
| if (JSObject::GetKeysForNamedInterceptor( | 
| current, object).ToHandle(&result)) { | 
| - accumulator.AddKeys(result, FixedArray::NON_SYMBOL_KEYS); | 
| + FixedArray::KeyFilter filter = include_symbols == SKIP_SYMBOLS | 
| + ? FixedArray::NON_SYMBOL_KEYS | 
| + : FixedArray::ALL_KEYS; | 
| + accumulator.AddKeys(result, filter); | 
| } | 
| DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); | 
| } | 
| @@ -13832,13 +13846,8 @@ int JSObject::GetOwnPropertyNames(FixedArray* storage, int index, | 
| int JSObject::NumberOfOwnElements(PropertyAttributes filter) { | 
| - return GetOwnElementKeys(NULL, filter); | 
| -} | 
| - | 
| - | 
| -int JSObject::NumberOfEnumElements() { | 
| // Fast case for objects with no elements. | 
| - if (!IsJSValue() && HasFastObjectElements()) { | 
| + if (!IsJSValue() && HasFastElements()) { | 
| uint32_t length = IsJSArray() ? | 
| static_cast<uint32_t>( | 
| Smi::cast(JSArray::cast(this)->length())->value()) : | 
| @@ -13846,6 +13855,11 @@ int JSObject::NumberOfEnumElements() { | 
| if (length == 0) return 0; | 
| } | 
| // Compute the number of enumerable elements. | 
| + return GetOwnElementKeys(NULL, filter); | 
| +} | 
| + | 
| + | 
| +int JSObject::NumberOfEnumElements() { | 
| return NumberOfOwnElements(static_cast<PropertyAttributes>(DONT_ENUM)); | 
| } |