1 // Copyright 2015 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_HEAP_OBJECT_STATS_H_ 6 #define V8_HEAP_OBJECT_STATS_H_ 7 8 #include "src/objects.h" 9 #include "src/objects/code.h" 10 11 // These instance types do not exist for actual use but are merely introduced 12 // for object stats tracing. In contrast to Code and FixedArray sub types 13 // these types are not known to other counters outside of object stats 14 // tracing. 15 // 16 // Update LAST_VIRTUAL_TYPE below when changing this macro. 17 #define VIRTUAL_INSTANCE_TYPE_LIST(V) \ 18 CODE_KIND_LIST(V) \ 19 V(ARRAY_BOILERPLATE_DESCRIPTION_ELEMENTS_TYPE) \ 20 V(BOILERPLATE_ELEMENTS_TYPE) \ 21 V(BOILERPLATE_PROPERTY_ARRAY_TYPE) \ 22 V(BOILERPLATE_PROPERTY_DICTIONARY_TYPE) \ 23 V(BYTECODE_ARRAY_CONSTANT_POOL_TYPE) \ 24 V(BYTECODE_ARRAY_HANDLER_TABLE_TYPE) \ 25 V(CODE_STUBS_TABLE_TYPE) \ 26 V(COW_ARRAY_TYPE) \ 27 V(DEOPTIMIZATION_DATA_TYPE) \ 28 V(DEPENDENT_CODE_TYPE) \ 29 V(ELEMENTS_TYPE) \ 30 V(EMBEDDED_OBJECT_TYPE) \ 31 V(ENUM_CACHE_TYPE) \ 32 V(ENUM_INDICES_CACHE_TYPE) \ 33 V(FEEDBACK_VECTOR_ENTRY_TYPE) \ 34 V(FEEDBACK_VECTOR_HEADER_TYPE) \ 35 V(FEEDBACK_VECTOR_SLOT_CALL_TYPE) \ 36 V(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE) \ 37 V(FEEDBACK_VECTOR_SLOT_ENUM_TYPE) \ 38 V(FEEDBACK_VECTOR_SLOT_LOAD_TYPE) \ 39 V(FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE) \ 40 V(FEEDBACK_VECTOR_SLOT_OTHER_TYPE) \ 41 V(FEEDBACK_VECTOR_SLOT_STORE_TYPE) \ 42 V(FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE) \ 43 V(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE) \ 44 V(GLOBAL_ELEMENTS_TYPE) \ 45 V(GLOBAL_PROPERTIES_TYPE) \ 46 V(JS_ARRAY_BOILERPLATE_TYPE) \ 47 V(JS_COLLETION_TABLE_TYPE) \ 48 V(JS_OBJECT_BOILERPLATE_TYPE) \ 49 V(NOSCRIPT_SHARED_FUNCTION_INFOS_TYPE) \ 50 V(NUMBER_STRING_CACHE_TYPE) \ 51 V(OBJECT_PROPERTY_DICTIONARY_TYPE) \ 52 V(OBJECT_TO_CODE_TYPE) \ 53 V(OPTIMIZED_CODE_LITERALS_TYPE) \ 54 V(OTHER_CONTEXT_TYPE) \ 55 V(PROTOTYPE_USERS_TYPE) \ 56 V(REGEXP_MULTIPLE_CACHE_TYPE) \ 57 V(RELOC_INFO_TYPE) \ 58 V(RETAINED_MAPS_TYPE) \ 59 V(SCRIPT_LIST_TYPE) \ 60 V(SCRIPT_SHARED_FUNCTION_INFOS_TYPE) \ 61 V(SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE) \ 62 V(SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE) \ 63 V(SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE) \ 64 V(SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE) \ 65 V(SERIALIZED_OBJECTS_TYPE) \ 66 V(SINGLE_CHARACTER_STRING_CACHE_TYPE) \ 67 V(STRING_SPLIT_CACHE_TYPE) \ 68 V(STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE) \ 69 V(STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE) \ 70 V(SOURCE_POSITION_TABLE_TYPE) \ 71 V(UNCOMPILED_JS_FUNCTION_TYPE) \ 72 V(UNCOMPILED_SHARED_FUNCTION_INFO_TYPE) \ 73 V(WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE) 74 75 namespace v8 { 76 namespace internal { 77 78 class Heap; 79 class Isolate; 80 81 class ObjectStats { 82 public: 83 static const size_t kNoOverAllocation = 0; 84 ObjectStats(Heap * heap)85 explicit ObjectStats(Heap* heap) : heap_(heap) { ClearObjectStats(); } 86 87 // See description on VIRTUAL_INSTANCE_TYPE_LIST. 88 enum VirtualInstanceType { 89 #define DEFINE_VIRTUAL_INSTANCE_TYPE(type) type, 90 VIRTUAL_INSTANCE_TYPE_LIST(DEFINE_VIRTUAL_INSTANCE_TYPE) 91 #undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE 92 LAST_VIRTUAL_TYPE = WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE, 93 }; 94 95 // ObjectStats are kept in two arrays, counts and sizes. Related stats are 96 // stored in a contiguous linear buffer. Stats groups are stored one after 97 // another. 98 enum { 99 FIRST_VIRTUAL_TYPE = LAST_TYPE + 1, 100 OBJECT_STATS_COUNT = FIRST_VIRTUAL_TYPE + LAST_VIRTUAL_TYPE + 1, 101 }; 102 103 void ClearObjectStats(bool clear_last_time_stats = false); 104 105 void PrintJSON(const char* key); 106 void Dump(std::stringstream& stream); 107 108 void CheckpointObjectStats(); 109 void RecordObjectStats(InstanceType type, size_t size); 110 void RecordVirtualObjectStats(VirtualInstanceType type, size_t size, 111 size_t over_allocated); 112 object_count_last_gc(size_t index)113 size_t object_count_last_gc(size_t index) { 114 return object_counts_last_time_[index]; 115 } 116 object_size_last_gc(size_t index)117 size_t object_size_last_gc(size_t index) { 118 return object_sizes_last_time_[index]; 119 } 120 121 Isolate* isolate(); heap()122 Heap* heap() { return heap_; } 123 124 private: 125 static const int kFirstBucketShift = 5; // <32 126 static const int kLastBucketShift = 20; // >=1M 127 static const int kFirstBucket = 1 << kFirstBucketShift; 128 static const int kLastBucket = 1 << kLastBucketShift; 129 static const int kNumberOfBuckets = kLastBucketShift - kFirstBucketShift + 1; 130 static const int kLastValueBucketIndex = kLastBucketShift - kFirstBucketShift; 131 132 void PrintKeyAndId(const char* key, int gc_count); 133 // The following functions are excluded from inline to reduce the overall 134 // binary size of VB. On x64 this save around 80KB. 135 V8_NOINLINE void PrintInstanceTypeJSON(const char* key, int gc_count, 136 const char* name, int index); 137 V8_NOINLINE void DumpInstanceTypeData(std::stringstream& stream, 138 const char* name, int index); 139 140 int HistogramIndexFromSize(size_t size); 141 142 Heap* heap_; 143 // Object counts and used memory by InstanceType. 144 size_t object_counts_[OBJECT_STATS_COUNT]; 145 size_t object_counts_last_time_[OBJECT_STATS_COUNT]; 146 size_t object_sizes_[OBJECT_STATS_COUNT]; 147 size_t object_sizes_last_time_[OBJECT_STATS_COUNT]; 148 // Approximation of overallocated memory by InstanceType. 149 size_t over_allocated_[OBJECT_STATS_COUNT]; 150 // Detailed histograms by InstanceType. 151 size_t size_histogram_[OBJECT_STATS_COUNT][kNumberOfBuckets]; 152 size_t over_allocated_histogram_[OBJECT_STATS_COUNT][kNumberOfBuckets]; 153 154 size_t tagged_fields_count_; 155 size_t embedder_fields_count_; 156 size_t unboxed_double_fields_count_; 157 size_t raw_fields_count_; 158 159 friend class ObjectStatsCollectorImpl; 160 }; 161 162 class ObjectStatsCollector { 163 public: ObjectStatsCollector(Heap * heap,ObjectStats * live,ObjectStats * dead)164 ObjectStatsCollector(Heap* heap, ObjectStats* live, ObjectStats* dead) 165 : heap_(heap), live_(live), dead_(dead) { 166 DCHECK_NOT_NULL(heap_); 167 DCHECK_NOT_NULL(live_); 168 DCHECK_NOT_NULL(dead_); 169 } 170 171 // Collects type information of live and dead objects. Requires mark bits to 172 // be present. 173 void Collect(); 174 175 private: 176 Heap* const heap_; 177 ObjectStats* const live_; 178 ObjectStats* const dead_; 179 }; 180 181 } // namespace internal 182 } // namespace v8 183 184 #endif // V8_HEAP_OBJECT_STATS_H_ 185