| Index: src/keys.cc
|
| diff --git a/src/keys.cc b/src/keys.cc
|
| index eaf33557f1de3cdbc1df0a250f6bcaa0b7b90a08..f8b606ca4bf1cd9b8ddd07ad1d0c75d9532ddb7b 100644
|
| --- a/src/keys.cc
|
| +++ b/src/keys.cc
|
| @@ -363,11 +363,19 @@ void FastKeyAccumulator::Prepare() {
|
| }
|
|
|
| namespace {
|
| +
|
| +template <bool fast_properties>
|
| Handle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
|
| Handle<JSObject> object,
|
| GetKeysConversion convert) {
|
| - Handle<FixedArray> keys = JSObject::GetFastEnumPropertyKeys(isolate, object);
|
| + Handle<FixedArray> keys;
|
| ElementsAccessor* accessor = object->GetElementsAccessor();
|
| + if (fast_properties) {
|
| + keys = JSObject::GetFastEnumPropertyKeys(isolate, object);
|
| + } else {
|
| + // TODO(cbruni): preallocate big enough array to also hold elements.
|
| + keys = JSObject::GetEnumPropertyKeys(object);
|
| + }
|
| Handle<FixedArray> result =
|
| accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE);
|
|
|
| @@ -397,6 +405,10 @@ MaybeHandle<FixedArray> GetOwnKeysWithUninitializedEnumCache(
|
| return JSObject::GetFastEnumPropertyKeys(isolate, object);
|
| }
|
|
|
| +bool OnlyHasSimpleProperties(Map* map) {
|
| + return map->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER;
|
| +}
|
| +
|
| } // namespace
|
|
|
| MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) {
|
| @@ -410,16 +422,22 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) {
|
| MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
|
| GetKeysConversion convert) {
|
| bool own_only = has_empty_prototype_ || type_ == OWN_ONLY;
|
| - if (!own_only || !receiver_->map()->OnlyHasSimpleProperties()) {
|
| + Map* map = receiver_->map();
|
| + if (!own_only || !OnlyHasSimpleProperties(map)) {
|
| return MaybeHandle<FixedArray>();
|
| }
|
|
|
| - Handle<FixedArray> keys;
|
| + // From this point on we are certiain to only collect own keys.
|
| DCHECK(receiver_->IsJSObject());
|
| Handle<JSObject> object = Handle<JSObject>::cast(receiver_);
|
|
|
| + // Do not try to use the enum-cache for dict-mode objects.
|
| + if (map->is_dictionary_map()) {
|
| + return GetOwnKeysWithElements<false>(isolate_, object, convert);
|
| + }
|
| int enum_length = receiver_->map()->EnumLength();
|
| if (enum_length == kInvalidEnumCacheSentinel) {
|
| + Handle<FixedArray> keys;
|
| // Try initializing the enum cache and return own properties.
|
| if (GetOwnKeysWithUninitializedEnumCache(isolate_, object)
|
| .ToHandle(&keys)) {
|
| @@ -427,7 +445,6 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
|
| PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n",
|
| keys->length());
|
| }
|
| -
|
| is_receiver_simple_enum_ =
|
| object->map()->EnumLength() != kInvalidEnumCacheSentinel;
|
| return keys;
|
| @@ -435,7 +452,7 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
|
| }
|
| // The properties-only case failed because there were probably elements on the
|
| // receiver.
|
| - return GetOwnKeysWithElements(isolate_, object, convert);
|
| + return GetOwnKeysWithElements<true>(isolate_, object, convert);
|
| }
|
|
|
| MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
|
|
|