Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index d7fa18ff0ba22c068476683534d30830cee06c9c..5d08705ae73d99852159c3643be4a488fd56d2d3 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -3335,8 +3335,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
// Allocate new content. |
int real_size = map_of_this->NumberOfOwnDescriptors(); |
- int property_count = |
- map_of_this->NumberOfDescribedProperties(OWN_DESCRIPTORS); |
+ int property_count = real_size; |
if (expected_additional_properties > 0) { |
property_count += expected_additional_properties; |
} else { |
@@ -7450,6 +7449,51 @@ static bool ClearBackPointer(Heap* heap, Map* target) { |
} |
+static void TrimEnumCache(Heap* heap, Map* map, DescriptorArray* descriptors) { |
+ int live_enum = map->EnumLength(); |
+ if (live_enum == Map::kInvalidEnumCache) { |
+ live_enum = map->NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM); |
+ } |
+ if (live_enum == 0) return descriptors->ClearEnumCache(); |
+ |
+ FixedArray* enum_cache = descriptors->GetEnumCache(); |
+ |
+ int to_trim = enum_cache->length() - live_enum; |
+ if (to_trim <= 0) return; |
+ RightTrimFixedArray<FROM_GC>(heap, descriptors->GetEnumCache(), to_trim); |
+ |
+ if (!descriptors->HasEnumIndicesCache()) return; |
+ FixedArray* enum_indices_cache = descriptors->GetEnumIndicesCache(); |
+ RightTrimFixedArray<FROM_GC>(heap, enum_indices_cache, to_trim); |
+} |
+ |
+ |
+static void TrimDescriptorArray(Heap* heap, |
+ Map* map, |
+ DescriptorArray* descriptors, |
+ int number_of_own_descriptors) { |
+ int number_of_descriptors = descriptors->number_of_descriptors(); |
+ int to_trim = number_of_descriptors - number_of_own_descriptors; |
+ if (to_trim <= 0) return; |
+ |
+ // Maximally keep 50% of unused descriptors. |
+ int keep = Min(to_trim, number_of_own_descriptors / 2); |
+ for (int i = number_of_own_descriptors; |
+ i < number_of_own_descriptors + keep; |
+ ++i) { |
+ descriptors->EraseDescriptor(heap, i); |
+ } |
+ |
+ if (to_trim > keep) { |
+ RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim - keep); |
+ } |
+ descriptors->SetNumberOfDescriptors(number_of_own_descriptors); |
+ |
+ if (descriptors->HasEnumCache()) TrimEnumCache(heap, map, descriptors); |
+ descriptors->Sort(); |
+} |
+ |
+ |
// TODO(mstarzinger): This method should be moved into MarkCompactCollector, |
// because it cannot be called from outside the GC and we already have methods |
// depending on the transitions layout in the GC anyways. |
@@ -7508,40 +7552,7 @@ void Map::ClearNonLiveTransitions(Heap* heap) { |
if (descriptors_owner_died) { |
if (number_of_own_descriptors > 0) { |
- int number_of_descriptors = descriptors->number_of_descriptors(); |
- int to_trim = number_of_descriptors - number_of_own_descriptors; |
- if (to_trim > 0) { |
- // Maximally keep 50% of unused descriptors. |
- int keep = Min(to_trim, number_of_own_descriptors / 2); |
- for (int i = number_of_own_descriptors; |
- i < number_of_own_descriptors + keep; |
- ++i) { |
- descriptors->EraseDescriptor(heap, i); |
- } |
- if (to_trim > keep) { |
- RightTrimFixedArray<FROM_GC>(heap, descriptors, to_trim - keep); |
- } |
- descriptors->SetNumberOfDescriptors(number_of_own_descriptors); |
- if (descriptors->HasEnumCache()) { |
- int live_enum = |
- NumberOfDescribedProperties(OWN_DESCRIPTORS, DONT_ENUM); |
- if (live_enum == 0) { |
- descriptors->ClearEnumCache(); |
- } else { |
- FixedArray* enum_cache = descriptors->GetEnumCache(); |
- to_trim = enum_cache->length() - live_enum; |
- if (to_trim > 0) { |
- RightTrimFixedArray<FROM_GC>( |
- heap, descriptors->GetEnumCache(), to_trim); |
- if (descriptors->HasEnumIndicesCache()) { |
- RightTrimFixedArray<FROM_GC>( |
- heap, descriptors->GetEnumIndicesCache(), to_trim); |
- } |
- } |
- } |
- } |
- descriptors->Sort(); |
- } |
+ TrimDescriptorArray(heap, this, descriptors, number_of_own_descriptors); |
ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); |
} else { |
t->set_descriptors(heap->empty_descriptor_array()); |
@@ -10679,9 +10690,16 @@ bool JSObject::HasRealNamedCallbackProperty(String* key) { |
int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
- return HasFastProperties() ? |
- map()->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter) : |
- property_dictionary()->NumberOfElementsFilterAttributes(filter); |
+ if (HasFastProperties()) { |
+ Map* map = this->map(); |
+ if (filter == NONE) return map->NumberOfOwnDescriptors(); |
+ if (filter == DONT_ENUM) { |
+ int result = map->EnumLength(); |
+ if (result != Map::kInvalidEnumCache) return result; |
+ } |
+ return map->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter); |
+ } |
+ return property_dictionary()->NumberOfElementsFilterAttributes(filter); |
} |