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( |