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)); |
| } |