| Index: src/heap/object-stats.cc
|
| diff --git a/src/heap/object-stats.cc b/src/heap/object-stats.cc
|
| index 3c82c7f7852bf307ed6a1b4bd86577a2fc2fd8bc..bd986a3fbd01fa7bf0b19c2eb39349d8b8a9df82 100644
|
| --- a/src/heap/object-stats.cc
|
| +++ b/src/heap/object-stats.cc
|
| @@ -25,6 +25,7 @@ void ObjectStats::ClearObjectStats(bool clear_last_time_stats) {
|
| memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_));
|
| memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_));
|
| }
|
| + visited_fixed_array_sub_types_.clear();
|
| }
|
|
|
| static void PrintJSONArray(size_t* array, const int len) {
|
| @@ -190,9 +191,29 @@ void ObjectStatsCollector::CollectStatistics(ObjectStats* stats,
|
| }
|
|
|
| static bool CanRecordFixedArray(Heap* heap, FixedArrayBase* array) {
|
| - return array->map() != heap->fixed_cow_array_map() &&
|
| + return array->map()->instance_type() == FIXED_ARRAY_TYPE &&
|
| + array->map() != heap->fixed_cow_array_map() &&
|
| array->map() != heap->fixed_double_array_map() &&
|
| - array != heap->empty_fixed_array();
|
| + array != heap->empty_fixed_array() &&
|
| + array != heap->empty_byte_array() &&
|
| + array != heap->empty_literals_array() &&
|
| + array != heap->empty_sloppy_arguments_elements() &&
|
| + array != heap->empty_slow_element_dictionary() &&
|
| + array != heap->empty_descriptor_array() &&
|
| + array != heap->empty_properties_dictionary();
|
| +}
|
| +
|
| +static bool SameLiveness(HeapObject* obj1, HeapObject* obj2) {
|
| + return ObjectMarking::Color(obj1) == ObjectMarking::Color(obj2);
|
| +}
|
| +
|
| +void ObjectStatsCollector::RecordFixedArrayHelper(
|
| + ObjectStats* stats, Heap* heap, HeapObject* parent, FixedArray* array,
|
| + int subtype, size_t overhead) {
|
| + if (SameLiveness(parent, array) && CanRecordFixedArray(heap, array)) {
|
| + stats->RecordFixedArraySubTypeStats(array, subtype, array->Size(),
|
| + overhead);
|
| + }
|
| }
|
|
|
| void ObjectStatsCollector::RecordJSObjectDetails(ObjectStats* stats, Heap* heap,
|
| @@ -202,13 +223,13 @@ void ObjectStatsCollector::RecordJSObjectDetails(ObjectStats* stats, Heap* heap,
|
| size_t overhead = 0;
|
| FixedArrayBase* elements = object->elements();
|
| if (CanRecordFixedArray(heap, elements)) {
|
| - if (elements->IsDictionary()) {
|
| - SeededNumberDictionary* dict = object->element_dictionary();
|
| + if (elements->IsDictionary() && SameLiveness(object, elements)) {
|
| + SeededNumberDictionary* dict = SeededNumberDictionary::cast(elements);
|
| int used = dict->NumberOfElements() * SeededNumberDictionary::kEntrySize;
|
| CHECK_GE(elements->Size(), used);
|
| overhead = elements->Size() - used;
|
| - stats->RecordFixedArraySubTypeStats(DICTIONARY_ELEMENTS_SUB_TYPE,
|
| - elements->Size(), overhead);
|
| + stats->RecordFixedArraySubTypeStats(
|
| + elements, DICTIONARY_ELEMENTS_SUB_TYPE, elements->Size(), overhead);
|
| } else {
|
| if (IsFastHoleyElementsKind(object->GetElementsKind())) {
|
| int used = object->GetFastElementsUsage() * kPointerSize;
|
| @@ -216,23 +237,25 @@ void ObjectStatsCollector::RecordJSObjectDetails(ObjectStats* stats, Heap* heap,
|
| CHECK_GE(elements->Size(), used);
|
| overhead = elements->Size() - used;
|
| }
|
| - stats->RecordFixedArraySubTypeStats(FAST_ELEMENTS_SUB_TYPE,
|
| + stats->RecordFixedArraySubTypeStats(elements, FAST_ELEMENTS_SUB_TYPE,
|
| elements->Size(), overhead);
|
| }
|
| }
|
|
|
| overhead = 0;
|
| FixedArrayBase* properties = object->properties();
|
| - if (CanRecordFixedArray(heap, properties)) {
|
| + if (CanRecordFixedArray(heap, properties) &&
|
| + SameLiveness(object, properties)) {
|
| if (properties->IsDictionary()) {
|
| - NameDictionary* dict = object->property_dictionary();
|
| + NameDictionary* dict = NameDictionary::cast(properties);
|
| int used = dict->NumberOfElements() * NameDictionary::kEntrySize;
|
| CHECK_GE(properties->Size(), used);
|
| overhead = properties->Size() - used;
|
| - stats->RecordFixedArraySubTypeStats(DICTIONARY_PROPERTIES_SUB_TYPE,
|
| + stats->RecordFixedArraySubTypeStats(properties,
|
| + DICTIONARY_PROPERTIES_SUB_TYPE,
|
| properties->Size(), overhead);
|
| } else {
|
| - stats->RecordFixedArraySubTypeStats(FAST_PROPERTIES_SUB_TYPE,
|
| + stats->RecordFixedArraySubTypeStats(properties, FAST_PROPERTIES_SUB_TYPE,
|
| properties->Size(), overhead);
|
| }
|
| }
|
| @@ -244,8 +267,8 @@ void ObjectStatsCollector::RecordJSWeakCollectionDetails(
|
| ObjectHashTable* table = ObjectHashTable::cast(obj->table());
|
| int used = table->NumberOfElements() * ObjectHashTable::kEntrySize;
|
| size_t overhead = table->Size() - used;
|
| - stats->RecordFixedArraySubTypeStats(WEAK_COLLECTION_SUB_TYPE, table->Size(),
|
| - overhead);
|
| + RecordFixedArrayHelper(stats, heap, obj, table, WEAK_COLLECTION_SUB_TYPE,
|
| + overhead);
|
| }
|
| }
|
|
|
| @@ -254,24 +277,23 @@ void ObjectStatsCollector::RecordMapDetails(ObjectStats* stats, Heap* heap,
|
| Map* map_obj = Map::cast(obj);
|
| DCHECK(obj->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();
|
| - stats->RecordFixedArraySubTypeStats(DESCRIPTOR_ARRAY_SUB_TYPE,
|
| - fixed_array_size, 0);
|
| + if (map_obj->owns_descriptors() && array != heap->empty_descriptor_array() &&
|
| + SameLiveness(map_obj, array)) {
|
| + RecordFixedArrayHelper(stats, heap, map_obj, array,
|
| + DESCRIPTOR_ARRAY_SUB_TYPE, 0);
|
| if (array->HasEnumCache()) {
|
| - stats->RecordFixedArraySubTypeStats(ENUM_CACHE_SUB_TYPE,
|
| - array->GetEnumCache()->Size(), 0);
|
| + RecordFixedArrayHelper(stats, heap, array, array->GetEnumCache(),
|
| + ENUM_CACHE_SUB_TYPE, 0);
|
| }
|
| if (array->HasEnumIndicesCache()) {
|
| - stats->RecordFixedArraySubTypeStats(
|
| - ENUM_INDICES_CACHE_SUB_TYPE, array->GetEnumIndicesCache()->Size(), 0);
|
| + RecordFixedArrayHelper(stats, heap, array, array->GetEnumIndicesCache(),
|
| + ENUM_INDICES_CACHE_SUB_TYPE, 0);
|
| }
|
| }
|
|
|
| if (map_obj->has_code_cache()) {
|
| - FixedArray* cache = map_obj->code_cache();
|
| - stats->RecordFixedArraySubTypeStats(MAP_CODE_CACHE_SUB_TYPE, cache->Size(),
|
| - 0);
|
| + RecordFixedArrayHelper(stats, heap, map_obj, map_obj->code_cache(),
|
| + MAP_CODE_CACHE_SUB_TYPE, 0);
|
| }
|
| }
|
|
|
| @@ -283,36 +305,20 @@ void ObjectStatsCollector::RecordCodeDetails(ObjectStats* stats, Heap* heap,
|
| stats->RecordCodeSubTypeStats(code_obj->kind(), code_obj->GetAge(),
|
| object_size);
|
| Code* code = Code::cast(obj);
|
| - if (code->deoptimization_data() != heap->empty_fixed_array()) {
|
| - stats->RecordFixedArraySubTypeStats(DEOPTIMIZATION_DATA_SUB_TYPE,
|
| - code->deoptimization_data()->Size(), 0);
|
| - }
|
| - FixedArrayBase* reloc_info =
|
| - reinterpret_cast<FixedArrayBase*>(code->unchecked_relocation_info());
|
| - if (reloc_info != heap->empty_fixed_array()) {
|
| - stats->RecordFixedArraySubTypeStats(RELOC_INFO_SUB_TYPE,
|
| - code->relocation_info()->Size(), 0);
|
| - }
|
| - FixedArrayBase* source_pos_table =
|
| - reinterpret_cast<FixedArrayBase*>(code->source_position_table());
|
| - if (source_pos_table != heap->empty_fixed_array()) {
|
| - stats->RecordFixedArraySubTypeStats(SOURCE_POS_SUB_TYPE,
|
| - source_pos_table->Size(), 0);
|
| - }
|
| + RecordFixedArrayHelper(stats, heap, code, code->deoptimization_data(),
|
| + DEOPTIMIZATION_DATA_SUB_TYPE, 0);
|
| }
|
|
|
| void ObjectStatsCollector::RecordSharedFunctionInfoDetails(ObjectStats* stats,
|
| Heap* heap,
|
| HeapObject* obj) {
|
| SharedFunctionInfo* sfi = SharedFunctionInfo::cast(obj);
|
| - if (sfi->scope_info() != heap->empty_fixed_array()) {
|
| - stats->RecordFixedArraySubTypeStats(SCOPE_INFO_SUB_TYPE,
|
| - sfi->scope_info()->Size(), 0);
|
| - }
|
| - if (sfi->feedback_metadata() != heap->empty_fixed_array()) {
|
| - stats->RecordFixedArraySubTypeStats(TYPE_FEEDBACK_METADATA_SUB_TYPE,
|
| - sfi->feedback_metadata()->Size(), 0);
|
| - }
|
| + FixedArray* scope_info = sfi->scope_info();
|
| + RecordFixedArrayHelper(stats, heap, sfi, scope_info, SCOPE_INFO_SUB_TYPE, 0);
|
| + FixedArray* feedback_metadata = sfi->feedback_metadata();
|
| + RecordFixedArrayHelper(stats, heap, sfi, feedback_metadata,
|
| + TYPE_FEEDBACK_METADATA_SUB_TYPE, 0);
|
| +
|
| if (!sfi->OptimizedCodeMapIsCleared()) {
|
| FixedArray* optimized_code_map = sfi->optimized_code_map();
|
| // Optimized code map should be small, so skip accounting.
|
| @@ -331,12 +337,10 @@ void ObjectStatsCollector::RecordSharedFunctionInfoDetails(ObjectStats* stats,
|
| literals = LiteralsArray::cast(slot);
|
| }
|
| if (literals != nullptr) {
|
| - stats->RecordFixedArraySubTypeStats(LITERALS_ARRAY_SUB_TYPE,
|
| - literals->Size(), 0);
|
| - TypeFeedbackVector* tfv = literals->feedback_vector();
|
| -
|
| - stats->RecordFixedArraySubTypeStats(TYPE_FEEDBACK_VECTOR_SUB_TYPE,
|
| - tfv->Size(), 0);
|
| + RecordFixedArrayHelper(stats, heap, sfi, literals,
|
| + LITERALS_ARRAY_SUB_TYPE, 0);
|
| + RecordFixedArrayHelper(stats, heap, sfi, literals->feedback_vector(),
|
| + TYPE_FEEDBACK_VECTOR_SUB_TYPE, 0);
|
| }
|
| }
|
| }
|
| @@ -346,24 +350,22 @@ void ObjectStatsCollector::RecordFixedArrayDetails(ObjectStats* stats,
|
| Heap* heap,
|
| HeapObject* obj) {
|
| FixedArray* fixed_array = FixedArray::cast(obj);
|
| - if (fixed_array == heap->string_table()) {
|
| - stats->RecordFixedArraySubTypeStats(STRING_TABLE_SUB_TYPE,
|
| - fixed_array->Size(), 0);
|
| - }
|
| if (fixed_array == heap->weak_object_to_code_table()) {
|
| WeakHashTable* table = reinterpret_cast<WeakHashTable*>(fixed_array);
|
| int used = table->NumberOfElements() * WeakHashTable::kEntrySize;
|
| CHECK_GE(fixed_array->Size(), used);
|
| size_t overhead = fixed_array->Size() - used;
|
| - stats->RecordFixedArraySubTypeStats(OBJECT_TO_CODE_SUB_TYPE,
|
| + stats->RecordFixedArraySubTypeStats(table, OBJECT_TO_CODE_SUB_TYPE,
|
| fixed_array->Size(), overhead);
|
| }
|
| - if (obj->IsContext()) {
|
| - stats->RecordFixedArraySubTypeStats(CONTEXT_SUB_TYPE, fixed_array->Size(),
|
| - 0);
|
| - }
|
| - if (fixed_array->map() == heap->fixed_cow_array_map()) {
|
| - stats->RecordFixedArraySubTypeStats(COPY_ON_WRITE_SUB_TYPE,
|
| +
|
| + int subtype = -1;
|
| + if (fixed_array == heap->string_table()) subtype = STRING_TABLE_SUB_TYPE;
|
| + if (fixed_array->IsContext()) subtype = CONTEXT_SUB_TYPE;
|
| + if (fixed_array->map() == heap->fixed_cow_array_map())
|
| + subtype = COPY_ON_WRITE_SUB_TYPE;
|
| + if (subtype != -1) {
|
| + stats->RecordFixedArraySubTypeStats(fixed_array, subtype,
|
| fixed_array->Size(), 0);
|
| }
|
| }
|
|
|