Commit a549d4a7 authored by cbruni's avatar cbruni Committed by Commit bot

[keys] adding fast-path for dict-mode objects with own keys only

BUG=

Review URL: https://codereview.chromium.org/1831783002

Cr-Commit-Position: refs/heads/master@{#35138}
parent 2c653a5d
...@@ -363,11 +363,19 @@ void FastKeyAccumulator::Prepare() { ...@@ -363,11 +363,19 @@ void FastKeyAccumulator::Prepare() {
} }
namespace { namespace {
template <bool fast_properties>
Handle<FixedArray> GetOwnKeysWithElements(Isolate* isolate, Handle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
Handle<JSObject> object, Handle<JSObject> object,
GetKeysConversion convert) { GetKeysConversion convert) {
Handle<FixedArray> keys = JSObject::GetFastEnumPropertyKeys(isolate, object); Handle<FixedArray> keys;
ElementsAccessor* accessor = object->GetElementsAccessor(); 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 = Handle<FixedArray> result =
accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE); accessor->PrependElementIndices(object, keys, convert, ONLY_ENUMERABLE);
...@@ -397,6 +405,10 @@ MaybeHandle<FixedArray> GetOwnKeysWithUninitializedEnumCache( ...@@ -397,6 +405,10 @@ MaybeHandle<FixedArray> GetOwnKeysWithUninitializedEnumCache(
return JSObject::GetFastEnumPropertyKeys(isolate, object); return JSObject::GetFastEnumPropertyKeys(isolate, object);
} }
bool OnlyHasSimpleProperties(Map* map) {
return map->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER;
}
} // namespace } // namespace
MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) { MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) {
...@@ -410,16 +422,22 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) { ...@@ -410,16 +422,22 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeys(GetKeysConversion convert) {
MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast( MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
GetKeysConversion convert) { GetKeysConversion convert) {
bool own_only = has_empty_prototype_ || type_ == OWN_ONLY; 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>(); return MaybeHandle<FixedArray>();
} }
Handle<FixedArray> keys; // From this point on we are certiain to only collect own keys.
DCHECK(receiver_->IsJSObject()); DCHECK(receiver_->IsJSObject());
Handle<JSObject> object = Handle<JSObject>::cast(receiver_); 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(); int enum_length = receiver_->map()->EnumLength();
if (enum_length == kInvalidEnumCacheSentinel) { if (enum_length == kInvalidEnumCacheSentinel) {
Handle<FixedArray> keys;
// Try initializing the enum cache and return own properties. // Try initializing the enum cache and return own properties.
if (GetOwnKeysWithUninitializedEnumCache(isolate_, object) if (GetOwnKeysWithUninitializedEnumCache(isolate_, object)
.ToHandle(&keys)) { .ToHandle(&keys)) {
...@@ -427,7 +445,6 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast( ...@@ -427,7 +445,6 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n", PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n",
keys->length()); keys->length());
} }
is_receiver_simple_enum_ = is_receiver_simple_enum_ =
object->map()->EnumLength() != kInvalidEnumCacheSentinel; object->map()->EnumLength() != kInvalidEnumCacheSentinel;
return keys; return keys;
...@@ -435,7 +452,7 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast( ...@@ -435,7 +452,7 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
} }
// The properties-only case failed because there were probably elements on the // The properties-only case failed because there were probably elements on the
// receiver. // receiver.
return GetOwnKeysWithElements(isolate_, object, convert); return GetOwnKeysWithElements<true>(isolate_, object, convert);
} }
MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow( MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
......
...@@ -8395,7 +8395,7 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object) { ...@@ -8395,7 +8395,7 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object) {
Handle<GlobalDictionary> dictionary(object->global_dictionary()); Handle<GlobalDictionary> dictionary(object->global_dictionary());
int length = dictionary->NumberOfEnumElements(); int length = dictionary->NumberOfEnumElements();
if (length == 0) { if (length == 0) {
return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); return isolate->factory()->empty_fixed_array();
} }
Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
dictionary->CopyEnumKeysTo(*storage); dictionary->CopyEnumKeysTo(*storage);
...@@ -8404,7 +8404,7 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object) { ...@@ -8404,7 +8404,7 @@ Handle<FixedArray> JSObject::GetEnumPropertyKeys(Handle<JSObject> object) {
Handle<NameDictionary> dictionary(object->property_dictionary()); Handle<NameDictionary> dictionary(object->property_dictionary());
int length = dictionary->NumberOfEnumElements(); int length = dictionary->NumberOfEnumElements();
if (length == 0) { if (length == 0) {
return Handle<FixedArray>(isolate->heap()->empty_fixed_array()); return isolate->factory()->empty_fixed_array();
} }
Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length); Handle<FixedArray> storage = isolate->factory()->NewFixedArray(length);
dictionary->CopyEnumKeysTo(*storage); dictionary->CopyEnumKeysTo(*storage);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment