Reviewers: Jakob,
Message:
PTAL.
Description:
Use NumberOfOwnDescriptors/EnumLength for counting properties on fast
objects.
Also split CNLT into small functions.
Please review this at https://chromiumcodereview.appspot.com/10950023/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/heap.cc
M src/objects.cc
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index
6c65454bd4ab61ed97fbe592b005a25e4507c01a..0515019630ad1d7e69f0f3b788072b50b090681c
100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -4189,7 +4189,7 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction*
constructor) {
StringDictionary* dictionary;
MaybeObject* maybe_dictionary =
StringDictionary::Allocate(
- map->NumberOfDescribedProperties() * 2 + initial_size);
+ map->NumberOfOwnDescriptors() * 2 + initial_size);
if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
// The global object might be created from an object template with
accessors.
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);
}
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev