From: vogelheim Date: Fri, 25 Sep 2015 17:22:05 +0000 (-0700) Subject: Revert of JSObject::GetEnumProperty cleanup (patchset #2 id:20001 of https://coderevi... X-Git-Tag: upstream/4.7.83~90 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1213929ac3830e2fcf9ca72785d64f9e129b71e2;p=platform%2Fupstream%2Fv8.git Revert of JSObject::GetEnumProperty cleanup (patchset #2 id:20001 of https://codereview.chromium.org/1363293002/ ) Reason for revert: Reverting, because of broken GC stress bots. @cbruni: Sorry for the revert. I'm not entirely sure it's actually your CL; but policy is to revert speculatively if we can't determine an exact cause. Original issue's description: > JSObject::GetEnumProperty cleanup > > BUG= > > Committed: https://crrev.com/a00d47c802f93cf9835eafce4c9da2dd10b44f6a > Cr-Commit-Position: refs/heads/master@{#30946} TBR=jkummerow@chromium.org,cbruni@chromium.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG= Review URL: https://codereview.chromium.org/1371673004 Cr-Commit-Position: refs/heads/master@{#30950} --- diff --git a/src/field-index-inl.h b/src/field-index-inl.h index b8bc67b..042e4fb 100644 --- a/src/field-index-inl.h +++ b/src/field-index-inl.h @@ -89,7 +89,8 @@ inline int FieldIndex::GetLoadByFieldIndex() const { inline FieldIndex FieldIndex::ForDescriptor(Map* map, int descriptor_index) { PropertyDetails details = map->instance_descriptors()->GetDetails(descriptor_index); - int field_index = details.field_index(); + int field_index = + map->instance_descriptors()->GetFieldIndex(descriptor_index); return ForPropertyIndex(map, field_index, details.representation().IsDouble()); } diff --git a/src/objects.cc b/src/objects.cc index aa48edb..02d8d34 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -6568,90 +6568,91 @@ static Handle ReduceFixedArrayTo( } -namespace { +Handle JSObject::GetEnumPropertyKeys(Handle object, + bool cache_result) { + Isolate* isolate = object->GetIsolate(); + if (object->HasFastProperties()) { + int own_property_count = object->map()->EnumLength(); + // If the enum length of the given map is set to kInvalidEnumCache, this + // means that the map itself has never used the present enum cache. The + // first step to using the cache is to set the enum length of the map by + // counting the number of own descriptors that are not DONT_ENUM or + // SYMBOLIC. + if (own_property_count == kInvalidEnumCacheSentinel) { + own_property_count = object->map()->NumberOfDescribedProperties( + OWN_DESCRIPTORS, DONT_SHOW); + } else { + DCHECK(own_property_count == object->map()->NumberOfDescribedProperties( + OWN_DESCRIPTORS, DONT_SHOW)); + } + + if (object->map()->instance_descriptors()->HasEnumCache()) { + DescriptorArray* desc = object->map()->instance_descriptors(); + Handle keys(desc->GetEnumCache(), isolate); + + // In case the number of properties required in the enum are actually + // present, we can reuse the enum cache. Otherwise, this means that the + // enum cache was generated for a previous (smaller) version of the + // Descriptor Array. In that case we regenerate the enum cache. + if (own_property_count <= keys->length()) { + if (cache_result) object->map()->SetEnumLength(own_property_count); + isolate->counters()->enum_cache_hits()->Increment(); + return ReduceFixedArrayTo(keys, own_property_count); + } + } -Handle GetFastEnumPropertyKeys(Isolate* isolate, - Handle object, - bool cache_enum_length) { - Handle map(object->map()); - Handle descs = - Handle(map->instance_descriptors(), isolate); - int own_property_count = map->EnumLength(); - // If the enum length of the given map is set to kInvalidEnumCache, this - // means that the map itself has never used the present enum cache. The - // first step to using the cache is to set the enum length of the map by - // counting the number of own descriptors that are not DONT_ENUM or - // SYMBOLIC. - if (own_property_count == kInvalidEnumCacheSentinel) { - own_property_count = - map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_SHOW); - } else { - DCHECK(own_property_count == - map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_SHOW)); - } + Handle map(object->map()); - if (descs->HasEnumCache()) { - Handle keys(descs->GetEnumCache(), isolate); - // In case the number of properties required in the enum are actually - // present, we can reuse the enum cache. Otherwise, this means that the - // enum cache was generated for a previous (smaller) version of the - // Descriptor Array. In that case we regenerate the enum cache. - if (own_property_count <= keys->length()) { + if (map->instance_descriptors()->IsEmpty()) { isolate->counters()->enum_cache_hits()->Increment(); - if (cache_enum_length) map->SetEnumLength(own_property_count); - return ReduceFixedArrayTo(keys, own_property_count); + if (cache_result) map->SetEnumLength(0); + return isolate->factory()->empty_fixed_array(); } - } - if (descs->IsEmpty()) { - isolate->counters()->enum_cache_hits()->Increment(); - if (cache_enum_length) map->SetEnumLength(0); - return isolate->factory()->empty_fixed_array(); - } + isolate->counters()->enum_cache_misses()->Increment(); - isolate->counters()->enum_cache_misses()->Increment(); + Handle storage = isolate->factory()->NewFixedArray( + own_property_count); + Handle indices = isolate->factory()->NewFixedArray( + own_property_count); - Handle storage = - isolate->factory()->NewFixedArray(own_property_count); - Handle indices = - isolate->factory()->NewFixedArray(own_property_count); + Handle descs = + Handle(object->map()->instance_descriptors(), isolate); - int size = map->NumberOfOwnDescriptors(); - int index = 0; + int size = map->NumberOfOwnDescriptors(); + int index = 0; - for (int i = 0; i < size; i++) { - PropertyDetails details = descs->GetDetails(i); - Object* key = descs->GetKey(i); - if (details.IsDontEnum() || key->IsSymbol()) continue; - storage->set(index, key); - if (!indices.is_null()) { - if (details.type() != DATA) { - indices = Handle(); - } else { - FieldIndex field_index = FieldIndex::ForDescriptor(*map, i); - int load_by_field_index = field_index.GetLoadByFieldIndex(); - indices->set(index, Smi::FromInt(load_by_field_index)); + for (int i = 0; i < size; i++) { + PropertyDetails details = descs->GetDetails(i); + Object* key = descs->GetKey(i); + if (!(details.IsDontEnum() || key->IsSymbol())) { + storage->set(index, key); + if (!indices.is_null()) { + if (details.type() != DATA) { + indices = Handle(); + } else { + FieldIndex field_index = FieldIndex::ForDescriptor(*map, i); + int load_by_field_index = field_index.GetLoadByFieldIndex(); + indices->set(index, Smi::FromInt(load_by_field_index)); + } + } + index++; } } - index++; - } - DCHECK(index == storage->length()); - - descs->SetEnumCache(isolate, storage, indices); - if (cache_enum_length) { - map->SetEnumLength(own_property_count); - } - return storage; -} - -} // namespace - + DCHECK(index == storage->length()); -Handle JSObject::GetEnumPropertyKeys(Handle object, - bool cache_enum_length) { - Isolate* isolate = object->GetIsolate(); - if (object->HasFastProperties()) { - return GetFastEnumPropertyKeys(isolate, object, cache_enum_length); + Handle bridge_storage = + isolate->factory()->NewFixedArray( + DescriptorArray::kEnumCacheBridgeLength); + DescriptorArray* desc = object->map()->instance_descriptors(); + desc->SetEnumCache(*bridge_storage, + *storage, + indices.is_null() ? Object::cast(Smi::FromInt(0)) + : Object::cast(*indices)); + if (cache_result) { + object->map()->SetEnumLength(own_property_count); + } + return storage; } else if (object->IsGlobalObject()) { Handle dictionary(object->global_dictionary()); int length = dictionary->NumberOfEnumElements(); @@ -6855,14 +6856,14 @@ MaybeHandle JSReceiver::GetKeys(Handle object, // 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_length = + 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 enum_keys = - JSObject::GetEnumPropertyKeys(current, cache_enum_length); + JSObject::GetEnumPropertyKeys(current, cache_enum_keys); accumulator.AddKeys(enum_keys, FixedArray::ALL_KEYS); DCHECK(ContainsOnlyValidKeys(accumulator.GetKeys())); @@ -8615,25 +8616,18 @@ void DescriptorArray::Replace(int index, Descriptor* descriptor) { } -void DescriptorArray::SetEnumCache(Isolate* isolate, - Handle new_cache, - Handle new_index_cache) { +void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, + FixedArray* new_cache, + Object* new_index_cache) { + DCHECK(bridge_storage->length() >= kEnumCacheBridgeLength); + DCHECK(new_index_cache->IsSmi() || new_index_cache->IsFixedArray()); DCHECK(!IsEmpty()); - FixedArray* bridge_storage; - bool needs_new_enum_cache = !HasEnumCache(); - if (needs_new_enum_cache) { - bridge_storage = *isolate->factory()->NewFixedArray( - DescriptorArray::kEnumCacheBridgeLength); - } else { - bridge_storage = FixedArray::cast(get(kEnumCacheIndex)); - } - bridge_storage->set(kEnumCacheBridgeCacheIndex, *new_cache); - bridge_storage->set(kEnumCacheBridgeIndicesCacheIndex, - new_index_cache.is_null() ? Object::cast(Smi::FromInt(0)) - : *new_index_cache); - if (needs_new_enum_cache) { - set(kEnumCacheIndex, bridge_storage); - } + DCHECK(!HasEnumCache() || new_cache->length() > GetEnumCache()->length()); + FixedArray::cast(bridge_storage)-> + set(kEnumCacheBridgeCacheIndex, new_cache); + FixedArray::cast(bridge_storage)-> + set(kEnumCacheBridgeIndicesCacheIndex, new_index_cache); + set(kEnumCacheIndex, bridge_storage); } diff --git a/src/objects.h b/src/objects.h index 571ae20..6838f27 100644 --- a/src/objects.h +++ b/src/objects.h @@ -2745,8 +2745,9 @@ class DescriptorArray: public FixedArray { // Initialize or change the enum cache, // using the supplied storage for the small "bridge". - void SetEnumCache(Isolate* isolate, Handle new_cache, - Handle new_index_cache); + void SetEnumCache(FixedArray* bridge_storage, + FixedArray* new_cache, + Object* new_index_cache); bool CanHoldValue(int descriptor, Object* value);