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

Reply via email to