| Index: src/keys.cc
|
| diff --git a/src/keys.cc b/src/keys.cc
|
| index 35ca22301fc5c860b805cbc43ac77192e520d09e..d1b28690c8361f8b5f6ea435350a23e1844d9d97 100644
|
| --- a/src/keys.cc
|
| +++ b/src/keys.cc
|
| @@ -227,7 +227,7 @@ void TrySettingEmptyEnumCache(JSReceiver* object) {
|
| map->SetEnumLength(0);
|
| }
|
|
|
| -bool CheckAndInitalizeSimpleEnumCache(JSReceiver* object) {
|
| +bool CheckAndInitalizeEmptyEnumCache(JSReceiver* object) {
|
| if (object->map()->EnumLength() == kInvalidEnumCacheSentinel) {
|
| TrySettingEmptyEnumCache(object);
|
| }
|
| @@ -248,7 +248,7 @@ void FastKeyAccumulator::Prepare() {
|
| for (PrototypeIterator iter(isolate_, *receiver_); !iter.IsAtEnd();
|
| iter.Advance()) {
|
| JSReceiver* current = iter.GetCurrent<JSReceiver>();
|
| - bool has_no_properties = CheckAndInitalizeSimpleEnumCache(current);
|
| + bool has_no_properties = CheckAndInitalizeEmptyEnumCache(current);
|
| if (has_no_properties) continue;
|
| last_prototype = current;
|
| has_empty_prototype_ = false;
|
| @@ -271,6 +271,8 @@ static Handle<FixedArray> ReduceFixedArrayTo(Isolate* isolate,
|
| return isolate->factory()->CopyFixedArrayUpTo(array, length);
|
| }
|
|
|
| +// Initializes and directly returns the enume cache. Users of this function
|
| +// have to make sure to never directly leak the enum cache.
|
| Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
|
| Handle<JSObject> object) {
|
| Handle<Map> map(object->map());
|
| @@ -370,25 +372,6 @@ MaybeHandle<FixedArray> GetOwnKeysWithElements(Isolate* isolate,
|
| return result;
|
| }
|
|
|
| -MaybeHandle<FixedArray> GetOwnKeysWithUninitializedEnumCache(
|
| - Isolate* isolate, Handle<JSObject> object) {
|
| - // Uninitalized enum cache
|
| - Map* map = object->map();
|
| - if (object->elements() != isolate->heap()->empty_fixed_array() ||
|
| - object->elements() != isolate->heap()->empty_slow_element_dictionary()) {
|
| - // Assume that there are elements.
|
| - return MaybeHandle<FixedArray>();
|
| - }
|
| - int number_of_own_descriptors = map->NumberOfOwnDescriptors();
|
| - if (number_of_own_descriptors == 0) {
|
| - map->SetEnumLength(0);
|
| - return isolate->factory()->empty_fixed_array();
|
| - }
|
| - // We have no elements but possibly enumerable property keys, hence we can
|
| - // directly initialize the enum cache.
|
| - return GetFastEnumPropertyKeys(isolate, object);
|
| -}
|
| -
|
| bool OnlyHasSimpleProperties(Map* map) {
|
| return map->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER;
|
| }
|
| @@ -428,8 +411,7 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
|
| if (enum_length == kInvalidEnumCacheSentinel) {
|
| Handle<FixedArray> keys;
|
| // Try initializing the enum cache and return own properties.
|
| - if (GetOwnKeysWithUninitializedEnumCache(isolate_, object)
|
| - .ToHandle(&keys)) {
|
| + if (GetOwnKeysWithUninitializedEnumCache().ToHandle(&keys)) {
|
| if (FLAG_trace_for_in_enumerate) {
|
| PrintF("| strings=%d symbols=0 elements=0 || prototypes>=1 ||\n",
|
| keys->length());
|
| @@ -444,6 +426,28 @@ MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysFast(
|
| return GetOwnKeysWithElements<true>(isolate_, object, keys_conversion);
|
| }
|
|
|
| +MaybeHandle<FixedArray>
|
| +FastKeyAccumulator::GetOwnKeysWithUninitializedEnumCache() {
|
| + Handle<JSObject> object = Handle<JSObject>::cast(receiver_);
|
| + // Uninitalized enum cache
|
| + Map* map = object->map();
|
| + if (object->elements()->length() != 0) {
|
| + // Assume that there are elements.
|
| + return MaybeHandle<FixedArray>();
|
| + }
|
| + int number_of_own_descriptors = map->NumberOfOwnDescriptors();
|
| + if (number_of_own_descriptors == 0) {
|
| + map->SetEnumLength(0);
|
| + return isolate_->factory()->empty_fixed_array();
|
| + }
|
| + // We have no elements but possibly enumerable property keys, hence we can
|
| + // directly initialize the enum cache.
|
| + Handle<FixedArray> keys = GetFastEnumPropertyKeys(isolate_, object);
|
| + if (is_for_in_) return keys;
|
| + // Do not leak the enum cache as it might end up as an elements backing store.
|
| + return isolate_->factory()->CopyFixedArray(keys);
|
| +}
|
| +
|
| MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
|
| GetKeysConversion keys_conversion) {
|
| KeyAccumulator accumulator(isolate_, mode_, filter_);
|
|
|