Commit 310f2ece authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[heap] Move ObjectStatsVisitor into the proper component.

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}
parent c7de3e7f
......@@ -2368,6 +2368,7 @@ class Heap {
friend class IncrementalMarking;
friend class MarkCompactCollector;
friend class MarkCompactMarkingVisitor;
friend class ObjectStatsVisitor;
friend class Page;
friend class StoreBuffer;
......
......@@ -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)
......
......@@ -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
......@@ -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
......
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