Commit 947663aa authored by verwaest@chromium.org's avatar verwaest@chromium.org

Use NumberOfOwnDescriptors/EnumLength for counting properties on fast objects.

Also split CNLT into small functions.

Review URL: https://chromiumcodereview.appspot.com/10950023

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@12545 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 8b57f269
...@@ -4189,7 +4189,7 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) { ...@@ -4189,7 +4189,7 @@ MaybeObject* Heap::AllocateGlobalObject(JSFunction* constructor) {
StringDictionary* dictionary; StringDictionary* dictionary;
MaybeObject* maybe_dictionary = MaybeObject* maybe_dictionary =
StringDictionary::Allocate( StringDictionary::Allocate(
map->NumberOfDescribedProperties() * 2 + initial_size); map->NumberOfOwnDescriptors() * 2 + initial_size);
if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary;
// The global object might be created from an object template with accessors. // The global object might be created from an object template with accessors.
......
...@@ -3335,8 +3335,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, ...@@ -3335,8 +3335,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
// Allocate new content. // Allocate new content.
int real_size = map_of_this->NumberOfOwnDescriptors(); int real_size = map_of_this->NumberOfOwnDescriptors();
int property_count = int property_count = real_size;
map_of_this->NumberOfDescribedProperties(OWN_DESCRIPTORS);
if (expected_additional_properties > 0) { if (expected_additional_properties > 0) {
property_count += expected_additional_properties; property_count += expected_additional_properties;
} else { } else {
...@@ -7450,6 +7449,51 @@ static bool ClearBackPointer(Heap* heap, Map* target) { ...@@ -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, // TODO(mstarzinger): This method should be moved into MarkCompactCollector,
// because it cannot be called from outside the GC and we already have methods // because it cannot be called from outside the GC and we already have methods
// depending on the transitions layout in the GC anyways. // depending on the transitions layout in the GC anyways.
...@@ -7508,40 +7552,7 @@ void Map::ClearNonLiveTransitions(Heap* heap) { ...@@ -7508,40 +7552,7 @@ void Map::ClearNonLiveTransitions(Heap* heap) {
if (descriptors_owner_died) { if (descriptors_owner_died) {
if (number_of_own_descriptors > 0) { if (number_of_own_descriptors > 0) {
int number_of_descriptors = descriptors->number_of_descriptors(); TrimDescriptorArray(heap, this, descriptors, number_of_own_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();
}
ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors); ASSERT(descriptors->number_of_descriptors() == number_of_own_descriptors);
} else { } else {
t->set_descriptors(heap->empty_descriptor_array()); t->set_descriptors(heap->empty_descriptor_array());
...@@ -10679,9 +10690,16 @@ bool JSObject::HasRealNamedCallbackProperty(String* key) { ...@@ -10679,9 +10690,16 @@ bool JSObject::HasRealNamedCallbackProperty(String* key) {
int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { int JSObject::NumberOfLocalProperties(PropertyAttributes filter) {
return HasFastProperties() ? if (HasFastProperties()) {
map()->NumberOfDescribedProperties(OWN_DESCRIPTORS, filter) : Map* map = this->map();
property_dictionary()->NumberOfElementsFilterAttributes(filter); 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);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment