| Index: src/heap/object-stats.cc
|
| diff --git a/src/heap/object-stats.cc b/src/heap/object-stats.cc
|
| index 4cdd8074ff6eef0ddbf0bfc4402abf216875401f..195723e86d8526e7e75abee45d402f16f7c78a55 100644
|
| --- a/src/heap/object-stats.cc
|
| +++ b/src/heap/object-stats.cc
|
| @@ -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
|
|
|