| Index: src/keys.cc
|
| diff --git a/src/keys.cc b/src/keys.cc
|
| index da26263fc49c2eac2a4e6435770d604c26a7530f..4af11f85c44e773ffaf436061153f3ea1b8c0489 100644
|
| --- a/src/keys.cc
|
| +++ b/src/keys.cc
|
| @@ -47,7 +47,8 @@ Handle<FixedArray> KeyAccumulator::GetKeys(GetKeysConversion convert) {
|
| return isolate_->factory()->empty_fixed_array();
|
| }
|
| if (mode_ == KeyCollectionMode::kOwnOnly &&
|
| - keys_->map() == isolate_->heap()->fixed_array_map()) {
|
| + (keys_->map() == isolate_->heap()->fixed_array_map() ||
|
| + keys_->map() == isolate_->heap()->fixed_cow_array_map())) {
|
| return Handle<FixedArray>::cast(keys_);
|
| }
|
| USE(ContainsOnlyValidKeys);
|
| @@ -263,9 +264,9 @@ void FastKeyAccumulator::Prepare() {
|
| }
|
|
|
| namespace {
|
| -static Handle<FixedArray> ReduceFixedArrayTo(Isolate* isolate,
|
| - Handle<FixedArray> array,
|
| - int length) {
|
| +
|
| +Handle<FixedArray> ReduceFixedArrayTo(Isolate* isolate,
|
| + Handle<FixedArray> array, int length) {
|
| DCHECK_LE(length, array->length());
|
| if (array->length() == length) return array;
|
| return isolate->factory()->CopyFixedArrayUpTo(array, length);
|
| @@ -315,33 +316,39 @@ Handle<FixedArray> GetFastEnumPropertyKeys(Isolate* isolate,
|
|
|
| isolate->counters()->enum_cache_misses()->Increment();
|
|
|
| - Handle<FixedArray> storage =
|
| - isolate->factory()->NewFixedArray(own_property_count);
|
| - Handle<FixedArray> indices =
|
| - isolate->factory()->NewFixedArray(own_property_count);
|
| -
|
| - int size = map->NumberOfOwnDescriptors();
|
| - int index = 0;
|
| -
|
| - for (int i = 0; i < size; i++) {
|
| - PropertyDetails details = descs->GetDetails(i);
|
| - if (details.IsDontEnum()) continue;
|
| - Object* key = descs->GetKey(i);
|
| - if (key->IsSymbol()) continue;
|
| - storage->set(index, key);
|
| - if (!indices.is_null()) {
|
| - if (details.location() == kField) {
|
| - DCHECK_EQ(kData, details.kind());
|
| - FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
|
| - int load_by_field_index = field_index.GetLoadByFieldIndex();
|
| - indices->set(index, Smi::FromInt(load_by_field_index));
|
| - } else {
|
| - indices = Handle<FixedArray>();
|
| + Handle<FixedArray> storage = isolate->factory()->empty_fixed_array();
|
| + Handle<FixedArray> indices = isolate->factory()->empty_fixed_array();
|
| + if (own_property_count != 0) {
|
| + storage = isolate->factory()->NewFixedArray(own_property_count);
|
| + indices = isolate->factory()->NewFixedArray(own_property_count);
|
| +
|
| + int size = map->NumberOfOwnDescriptors();
|
| + int index = 0;
|
| +
|
| + for (int i = 0; i < size; i++) {
|
| + PropertyDetails details = descs->GetDetails(i);
|
| + if (details.IsDontEnum()) continue;
|
| + Object* key = descs->GetKey(i);
|
| + if (key->IsSymbol()) continue;
|
| + storage->set(index, key);
|
| + if (!indices.is_null()) {
|
| + if (details.location() == kField) {
|
| + DCHECK_EQ(kData, details.kind());
|
| + FieldIndex field_index = FieldIndex::ForDescriptor(*map, i);
|
| + int load_by_field_index = field_index.GetLoadByFieldIndex();
|
| + indices->set(index, Smi::FromInt(load_by_field_index));
|
| + } else {
|
| + indices = Handle<FixedArray>();
|
| + }
|
| }
|
| + index++;
|
| }
|
| - index++;
|
| + DCHECK_EQ(index, storage->length());
|
| +
|
| + // Mark the {storage} as copy-on-write, so we can use this
|
| + // as JSArray elements backing store directly w/o copying.
|
| + storage->set_map(isolate->heap()->fixed_cow_array_map());
|
| }
|
| - DCHECK(index == storage->length());
|
|
|
| DescriptorArray::SetEnumCache(descs, isolate, storage, indices);
|
| if (cache_enum_length) {
|
| @@ -442,10 +449,7 @@ FastKeyAccumulator::GetOwnKeysWithUninitializedEnumCache() {
|
| }
|
| // 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);
|
| + return GetFastEnumPropertyKeys(isolate_, object);
|
| }
|
|
|
| MaybeHandle<FixedArray> FastKeyAccumulator::GetKeysSlow(
|
|
|