[heap] Move ObjectStatsVisitor into the proper component.
authormstarzinger <mstarzinger@chromium.org>
Wed, 2 Sep 2015 17:09:43 +0000 (10:09 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 2 Sep 2015 17:09:54 +0000 (17:09 +0000)
This is a follow-up to a previous change and moved object statistics
tracking into its own component. It is no longer intertwinded with the
normal marking logic, but separated out into ObjectStatsVisitor.

R=mlippautz@chromium.org

Review URL: https://codereview.chromium.org/1310953008

Cr-Commit-Position: refs/heads/master@{#30548}

src/heap/heap.h
src/heap/mark-compact.cc
src/heap/object-stats.cc
src/heap/object-stats.h

index 933c4dc..d74d9cf 100644 (file)
@@ -2368,6 +2368,7 @@ class Heap {
   friend class IncrementalMarking;
   friend class MarkCompactCollector;
   friend class MarkCompactMarkingVisitor;
+  friend class ObjectStatsVisitor;
   friend class Page;
   friend class StoreBuffer;
 
index b66dd55..6159796 100644 (file)
@@ -1229,19 +1229,6 @@ MarkCompactCollector::~MarkCompactCollector() {
 class MarkCompactMarkingVisitor
     : public StaticMarkingVisitor<MarkCompactMarkingVisitor> {
  public:
-  static void ObjectStatsVisitBase(StaticVisitorBase::VisitorId id, Map* map,
-                                   HeapObject* obj);
-
-  static void ObjectStatsCountFixedArray(
-      FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type,
-      FixedArraySubInstanceType dictionary_type);
-
-  template <MarkCompactMarkingVisitor::VisitorId id>
-  class ObjectStatsTracker {
-   public:
-    static inline void Visit(Map* map, HeapObject* obj);
-  };
-
   static void Initialize();
 
   INLINE(static void VisitPointer(Heap* heap, HeapObject* object, Object** p)) {
@@ -1404,134 +1391,6 @@ class MarkCompactMarkingVisitor
     // Visit the fields of the RegExp, including the updated FixedArray.
     VisitJSRegExp(map, object);
   }
-
-  static VisitorDispatchTable<Callback> non_count_table_;
-};
-
-
-void MarkCompactMarkingVisitor::ObjectStatsCountFixedArray(
-    FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type,
-    FixedArraySubInstanceType dictionary_type) {
-  Heap* heap = fixed_array->map()->GetHeap();
-  if (fixed_array->map() != heap->fixed_cow_array_map() &&
-      fixed_array->map() != heap->fixed_double_array_map() &&
-      fixed_array != heap->empty_fixed_array()) {
-    if (fixed_array->IsDictionary()) {
-      heap->object_stats_->RecordFixedArraySubTypeStats(dictionary_type,
-                                                        fixed_array->Size());
-    } else {
-      heap->object_stats_->RecordFixedArraySubTypeStats(fast_type,
-                                                        fixed_array->Size());
-    }
-  }
-}
-
-
-void MarkCompactMarkingVisitor::ObjectStatsVisitBase(
-    MarkCompactMarkingVisitor::VisitorId id, Map* map, HeapObject* obj) {
-  Heap* heap = map->GetHeap();
-  int object_size = obj->Size();
-  heap->object_stats_->RecordObjectStats(map->instance_type(), object_size);
-  non_count_table_.GetVisitorById(id)(map, obj);
-  if (obj->IsJSObject()) {
-    JSObject* object = JSObject::cast(obj);
-    ObjectStatsCountFixedArray(object->elements(), DICTIONARY_ELEMENTS_SUB_TYPE,
-                               FAST_ELEMENTS_SUB_TYPE);
-    ObjectStatsCountFixedArray(object->properties(),
-                               DICTIONARY_PROPERTIES_SUB_TYPE,
-                               FAST_PROPERTIES_SUB_TYPE);
-  }
-}
-
-
-template <MarkCompactMarkingVisitor::VisitorId id>
-void MarkCompactMarkingVisitor::ObjectStatsTracker<id>::Visit(Map* map,
-                                                              HeapObject* obj) {
-  ObjectStatsVisitBase(id, map, obj);
-}
-
-
-template <>
-class MarkCompactMarkingVisitor::ObjectStatsTracker<
-    MarkCompactMarkingVisitor::kVisitMap> {
- public:
-  static inline void Visit(Map* map, HeapObject* obj) {
-    Heap* heap = map->GetHeap();
-    Map* map_obj = Map::cast(obj);
-    DCHECK(map->instance_type() == MAP_TYPE);
-    DescriptorArray* array = map_obj->instance_descriptors();
-    if (map_obj->owns_descriptors() &&
-        array != heap->empty_descriptor_array()) {
-      int fixed_array_size = array->Size();
-      heap->object_stats_->RecordFixedArraySubTypeStats(
-          DESCRIPTOR_ARRAY_SUB_TYPE, fixed_array_size);
-    }
-    if (TransitionArray::IsFullTransitionArray(map_obj->raw_transitions())) {
-      int fixed_array_size =
-          TransitionArray::cast(map_obj->raw_transitions())->Size();
-      heap->object_stats_->RecordFixedArraySubTypeStats(
-          TRANSITION_ARRAY_SUB_TYPE, fixed_array_size);
-    }
-    if (map_obj->has_code_cache()) {
-      CodeCache* cache = CodeCache::cast(map_obj->code_cache());
-      heap->object_stats_->RecordFixedArraySubTypeStats(
-          MAP_CODE_CACHE_SUB_TYPE, cache->default_cache()->Size());
-      if (!cache->normal_type_cache()->IsUndefined()) {
-        heap->object_stats_->RecordFixedArraySubTypeStats(
-            MAP_CODE_CACHE_SUB_TYPE,
-            FixedArray::cast(cache->normal_type_cache())->Size());
-      }
-    }
-    ObjectStatsVisitBase(kVisitMap, map, obj);
-  }
-};
-
-
-template <>
-class MarkCompactMarkingVisitor::ObjectStatsTracker<
-    MarkCompactMarkingVisitor::kVisitCode> {
- public:
-  static inline void Visit(Map* map, HeapObject* obj) {
-    Heap* heap = map->GetHeap();
-    int object_size = obj->Size();
-    DCHECK(map->instance_type() == CODE_TYPE);
-    Code* code_obj = Code::cast(obj);
-    heap->object_stats_->RecordCodeSubTypeStats(
-        code_obj->kind(), code_obj->GetAge(), object_size);
-    ObjectStatsVisitBase(kVisitCode, map, obj);
-  }
-};
-
-
-template <>
-class MarkCompactMarkingVisitor::ObjectStatsTracker<
-    MarkCompactMarkingVisitor::kVisitSharedFunctionInfo> {
- public:
-  static inline void Visit(Map* map, HeapObject* obj) {
-    Heap* heap = map->GetHeap();
-    SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
-    if (sfi->scope_info() != heap->empty_fixed_array()) {
-      heap->object_stats_->RecordFixedArraySubTypeStats(
-          SCOPE_INFO_SUB_TYPE, FixedArray::cast(sfi->scope_info())->Size());
-    }
-    ObjectStatsVisitBase(kVisitSharedFunctionInfo, map, obj);
-  }
-};
-
-
-template <>
-class MarkCompactMarkingVisitor::ObjectStatsTracker<
-    MarkCompactMarkingVisitor::kVisitFixedArray> {
- public:
-  static inline void Visit(Map* map, HeapObject* obj) {
-    Heap* heap = map->GetHeap();
-    FixedArray* fixed_array = FixedArray::cast(obj);
-    if (fixed_array == heap->string_table()) {
-      heap->object_stats_->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE,
-                                                        fixed_array->Size());
-    }
-    ObjectStatsVisitBase(kVisitFixedArray, map, obj);
-  }
 };
 
 
@@ -1541,20 +1400,11 @@ void MarkCompactMarkingVisitor::Initialize() {
   table_.Register(kVisitJSRegExp, &VisitRegExpAndFlushCode);
 
   if (FLAG_track_gc_object_stats) {
-    // Copy the visitor table to make call-through possible.
-    non_count_table_.CopyFrom(&table_);
-#define VISITOR_ID_COUNT_FUNCTION(id) \
-  table_.Register(kVisit##id, ObjectStatsTracker<kVisit##id>::Visit);
-    VISITOR_ID_LIST(VISITOR_ID_COUNT_FUNCTION)
-#undef VISITOR_ID_COUNT_FUNCTION
+    ObjectStatsVisitor::Initialize(&table_);
   }
 }
 
 
-VisitorDispatchTable<MarkCompactMarkingVisitor::Callback>
-    MarkCompactMarkingVisitor::non_count_table_;
-
-
 class CodeMarkingVisitor : public ThreadVisitor {
  public:
   explicit CodeMarkingVisitor(MarkCompactCollector* collector)
index 4cdd807..195723e 100644 (file)
@@ -134,5 +134,125 @@ void ObjectStats::CheckpointObjectStats() {
 
 Isolate* ObjectStats::isolate() { return heap()->isolate(); }
 
+
+void ObjectStatsVisitor::CountFixedArray(
+    FixedArrayBase* fixed_array, FixedArraySubInstanceType fast_type,
+    FixedArraySubInstanceType dictionary_type) {
+  Heap* heap = fixed_array->map()->GetHeap();
+  if (fixed_array->map() != heap->fixed_cow_array_map() &&
+      fixed_array->map() != heap->fixed_double_array_map() &&
+      fixed_array != heap->empty_fixed_array()) {
+    if (fixed_array->IsDictionary()) {
+      heap->object_stats_->RecordFixedArraySubTypeStats(dictionary_type,
+                                                        fixed_array->Size());
+    } else {
+      heap->object_stats_->RecordFixedArraySubTypeStats(fast_type,
+                                                        fixed_array->Size());
+    }
+  }
+}
+
+
+void ObjectStatsVisitor::VisitBase(VisitorId id, Map* map, HeapObject* obj) {
+  Heap* heap = map->GetHeap();
+  int object_size = obj->Size();
+  heap->object_stats_->RecordObjectStats(map->instance_type(), object_size);
+  table_.GetVisitorById(id)(map, obj);
+  if (obj->IsJSObject()) {
+    JSObject* object = JSObject::cast(obj);
+    CountFixedArray(object->elements(), DICTIONARY_ELEMENTS_SUB_TYPE,
+                    FAST_ELEMENTS_SUB_TYPE);
+    CountFixedArray(object->properties(), DICTIONARY_PROPERTIES_SUB_TYPE,
+                    FAST_PROPERTIES_SUB_TYPE);
+  }
+}
+
+
+template <ObjectStatsVisitor::VisitorId id>
+void ObjectStatsVisitor::Visit(Map* map, HeapObject* obj) {
+  VisitBase(id, map, obj);
+}
+
+
+template <>
+void ObjectStatsVisitor::Visit<ObjectStatsVisitor::kVisitMap>(Map* map,
+                                                              HeapObject* obj) {
+  Heap* heap = map->GetHeap();
+  Map* map_obj = Map::cast(obj);
+  DCHECK(map->instance_type() == MAP_TYPE);
+  DescriptorArray* array = map_obj->instance_descriptors();
+  if (map_obj->owns_descriptors() && array != heap->empty_descriptor_array()) {
+    int fixed_array_size = array->Size();
+    heap->object_stats_->RecordFixedArraySubTypeStats(DESCRIPTOR_ARRAY_SUB_TYPE,
+                                                      fixed_array_size);
+  }
+  if (TransitionArray::IsFullTransitionArray(map_obj->raw_transitions())) {
+    int fixed_array_size =
+        TransitionArray::cast(map_obj->raw_transitions())->Size();
+    heap->object_stats_->RecordFixedArraySubTypeStats(TRANSITION_ARRAY_SUB_TYPE,
+                                                      fixed_array_size);
+  }
+  if (map_obj->has_code_cache()) {
+    CodeCache* cache = CodeCache::cast(map_obj->code_cache());
+    heap->object_stats_->RecordFixedArraySubTypeStats(
+        MAP_CODE_CACHE_SUB_TYPE, cache->default_cache()->Size());
+    if (!cache->normal_type_cache()->IsUndefined()) {
+      heap->object_stats_->RecordFixedArraySubTypeStats(
+          MAP_CODE_CACHE_SUB_TYPE,
+          FixedArray::cast(cache->normal_type_cache())->Size());
+    }
+  }
+  VisitBase(kVisitMap, map, obj);
+}
+
+
+template <>
+void ObjectStatsVisitor::Visit<ObjectStatsVisitor::kVisitCode>(
+    Map* map, HeapObject* obj) {
+  Heap* heap = map->GetHeap();
+  int object_size = obj->Size();
+  DCHECK(map->instance_type() == CODE_TYPE);
+  Code* code_obj = Code::cast(obj);
+  heap->object_stats_->RecordCodeSubTypeStats(code_obj->kind(),
+                                              code_obj->GetAge(), object_size);
+  VisitBase(kVisitCode, map, obj);
+}
+
+
+template <>
+void ObjectStatsVisitor::Visit<ObjectStatsVisitor::kVisitSharedFunctionInfo>(
+    Map* map, HeapObject* obj) {
+  Heap* heap = map->GetHeap();
+  SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
+  if (sfi->scope_info() != heap->empty_fixed_array()) {
+    heap->object_stats_->RecordFixedArraySubTypeStats(
+        SCOPE_INFO_SUB_TYPE, FixedArray::cast(sfi->scope_info())->Size());
+  }
+  VisitBase(kVisitSharedFunctionInfo, map, obj);
+}
+
+
+template <>
+void ObjectStatsVisitor::Visit<ObjectStatsVisitor::kVisitFixedArray>(
+    Map* map, HeapObject* obj) {
+  Heap* heap = map->GetHeap();
+  FixedArray* fixed_array = FixedArray::cast(obj);
+  if (fixed_array == heap->string_table()) {
+    heap->object_stats_->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE,
+                                                      fixed_array->Size());
+  }
+  VisitBase(kVisitFixedArray, map, obj);
+}
+
+
+void ObjectStatsVisitor::Initialize(VisitorDispatchTable<Callback>* original) {
+  // Copy the original visitor table to make call-through possible. After we
+  // preserved a copy locally, we patch the original table to call us.
+  table_.CopyFrom(original);
+#define COUNT_FUNCTION(id) original->Register(kVisit##id, Visit<kVisit##id>);
+  VISITOR_ID_LIST(COUNT_FUNCTION)
+#undef COUNT_FUNCTION
+}
+
 }  // namespace internal
 }  // namespace v8
index ae85516..bd3baf1 100644 (file)
@@ -80,6 +80,21 @@ class ObjectStats {
   size_t object_sizes_last_time_[OBJECT_STATS_COUNT];
 };
 
+
+class ObjectStatsVisitor : public StaticMarkingVisitor<ObjectStatsVisitor> {
+ public:
+  static void Initialize(VisitorDispatchTable<Callback>* original);
+
+  static void VisitBase(VisitorId id, Map* map, HeapObject* obj);
+
+  static void CountFixedArray(FixedArrayBase* fixed_array,
+                              FixedArraySubInstanceType fast_type,
+                              FixedArraySubInstanceType dictionary_type);
+
+  template <VisitorId id>
+  static inline void Visit(Map* map, HeapObject* obj);
+};
+
 }  // namespace internal
 }  // namespace v8