• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/code.h"
9 #include "src/objects/objects.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(ARRAY_DICTIONARY_ELEMENTS_TYPE)              \
21   V(ARRAY_ELEMENTS_TYPE)                         \
22   V(BOILERPLATE_ELEMENTS_TYPE)                   \
23   V(BOILERPLATE_PROPERTY_ARRAY_TYPE)             \
24   V(BOILERPLATE_PROPERTY_DICTIONARY_TYPE)        \
25   V(BYTECODE_ARRAY_CONSTANT_POOL_TYPE)           \
26   V(BYTECODE_ARRAY_HANDLER_TABLE_TYPE)           \
27   V(COW_ARRAY_TYPE)                              \
28   V(DEOPTIMIZATION_DATA_TYPE)                    \
29   V(DEPENDENT_CODE_TYPE)                         \
30   V(DEPRECATED_DESCRIPTOR_ARRAY_TYPE)            \
31   V(EMBEDDED_OBJECT_TYPE)                        \
32   V(ENUM_KEYS_CACHE_TYPE)                        \
33   V(ENUM_INDICES_CACHE_TYPE)                     \
34   V(FEEDBACK_VECTOR_ENTRY_TYPE)                  \
35   V(FEEDBACK_VECTOR_HEADER_TYPE)                 \
36   V(FEEDBACK_VECTOR_SLOT_CALL_TYPE)              \
37   V(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE)       \
38   V(FEEDBACK_VECTOR_SLOT_ENUM_TYPE)              \
39   V(FEEDBACK_VECTOR_SLOT_LOAD_TYPE)              \
40   V(FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE)       \
41   V(FEEDBACK_VECTOR_SLOT_OTHER_TYPE)             \
42   V(FEEDBACK_VECTOR_SLOT_STORE_TYPE)             \
43   V(FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE)      \
44   V(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE)         \
45   V(GLOBAL_ELEMENTS_TYPE)                        \
46   V(GLOBAL_PROPERTIES_TYPE)                      \
47   V(JS_ARRAY_BOILERPLATE_TYPE)                   \
48   V(JS_COLLECTION_TABLE_TYPE)                    \
49   V(JS_OBJECT_BOILERPLATE_TYPE)                  \
50   V(JS_UNCOMPILED_FUNCTION_TYPE)                 \
51   V(MAP_ABANDONED_PROTOTYPE_TYPE)                \
52   V(MAP_DEPRECATED_TYPE)                         \
53   V(MAP_DICTIONARY_TYPE)                         \
54   V(MAP_PROTOTYPE_DICTIONARY_TYPE)               \
55   V(MAP_PROTOTYPE_TYPE)                          \
56   V(MAP_STABLE_TYPE)                             \
57   V(NUMBER_STRING_CACHE_TYPE)                    \
58   V(OBJECT_DICTIONARY_ELEMENTS_TYPE)             \
59   V(OBJECT_ELEMENTS_TYPE)                        \
60   V(OBJECT_PROPERTY_ARRAY_TYPE)                  \
61   V(OBJECT_PROPERTY_DICTIONARY_TYPE)             \
62   V(OBJECT_TO_CODE_TYPE)                         \
63   V(OPTIMIZED_CODE_LITERALS_TYPE)                \
64   V(OTHER_CONTEXT_TYPE)                          \
65   V(PROTOTYPE_DESCRIPTOR_ARRAY_TYPE)             \
66   V(PROTOTYPE_PROPERTY_ARRAY_TYPE)               \
67   V(PROTOTYPE_PROPERTY_DICTIONARY_TYPE)          \
68   V(PROTOTYPE_USERS_TYPE)                        \
69   V(REGEXP_MULTIPLE_CACHE_TYPE)                  \
70   V(RELOC_INFO_TYPE)                             \
71   V(RETAINED_MAPS_TYPE)                          \
72   V(SCRIPT_LIST_TYPE)                            \
73   V(SCRIPT_SHARED_FUNCTION_INFOS_TYPE)           \
74   V(SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE)        \
75   V(SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE)        \
76   V(SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE)    \
77   V(SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE)    \
78   V(SERIALIZED_OBJECTS_TYPE)                     \
79   V(SINGLE_CHARACTER_STRING_CACHE_TYPE)          \
80   V(STRING_SPLIT_CACHE_TYPE)                     \
81   V(STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE)      \
82   V(STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE)      \
83   V(SOURCE_POSITION_TABLE_TYPE)                  \
84   V(UNCOMPILED_SHARED_FUNCTION_INFO_TYPE)        \
85   V(WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE)
86 
87 namespace v8 {
88 namespace internal {
89 
90 class Heap;
91 class Isolate;
92 
93 class ObjectStats {
94  public:
95   static const size_t kNoOverAllocation = 0;
96 
ObjectStats(Heap * heap)97   explicit ObjectStats(Heap* heap) : heap_(heap) { ClearObjectStats(true); }
98 
99   // See description on VIRTUAL_INSTANCE_TYPE_LIST.
100   enum VirtualInstanceType {
101 #define DEFINE_VIRTUAL_INSTANCE_TYPE(type) type,
102     VIRTUAL_INSTANCE_TYPE_LIST(DEFINE_VIRTUAL_INSTANCE_TYPE)
103 #undef DEFINE_FIXED_ARRAY_SUB_INSTANCE_TYPE
104         LAST_VIRTUAL_TYPE = WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE,
105   };
106 
107   // ObjectStats are kept in two arrays, counts and sizes. Related stats are
108   // stored in a contiguous linear buffer. Stats groups are stored one after
109   // another.
110   enum {
111     FIRST_VIRTUAL_TYPE = LAST_TYPE + 1,
112     OBJECT_STATS_COUNT = FIRST_VIRTUAL_TYPE + LAST_VIRTUAL_TYPE + 1,
113   };
114 
115   void ClearObjectStats(bool clear_last_time_stats = false);
116 
117   void PrintJSON(const char* key);
118   void Dump(std::stringstream& stream);
119 
120   void CheckpointObjectStats();
121   void RecordObjectStats(InstanceType type, size_t size,
122                          size_t over_allocated = kNoOverAllocation);
123   void RecordVirtualObjectStats(VirtualInstanceType type, size_t size,
124                                 size_t over_allocated);
125 
object_count_last_gc(size_t index)126   size_t object_count_last_gc(size_t index) {
127     return object_counts_last_time_[index];
128   }
129 
object_size_last_gc(size_t index)130   size_t object_size_last_gc(size_t index) {
131     return object_sizes_last_time_[index];
132   }
133 
134   Isolate* isolate();
heap()135   Heap* heap() { return heap_; }
136 
137  private:
138   static const int kFirstBucketShift = 5;  // <32
139   static const int kLastBucketShift = 20;  // >=1M
140   static const int kFirstBucket = 1 << kFirstBucketShift;
141   static const int kLastBucket = 1 << kLastBucketShift;
142   static const int kNumberOfBuckets = kLastBucketShift - kFirstBucketShift + 1;
143   static const int kLastValueBucketIndex = kLastBucketShift - kFirstBucketShift;
144 
145   void PrintKeyAndId(const char* key, int gc_count);
146   // The following functions are excluded from inline to reduce the overall
147   // binary size of VB. On x64 this save around 80KB.
148   V8_NOINLINE void PrintInstanceTypeJSON(const char* key, int gc_count,
149                                          const char* name, int index);
150   V8_NOINLINE void DumpInstanceTypeData(std::stringstream& stream,
151                                         const char* name, int index);
152 
153   int HistogramIndexFromSize(size_t size);
154 
155   Heap* heap_;
156   // Object counts and used memory by InstanceType.
157   size_t object_counts_[OBJECT_STATS_COUNT];
158   size_t object_counts_last_time_[OBJECT_STATS_COUNT];
159   size_t object_sizes_[OBJECT_STATS_COUNT];
160   size_t object_sizes_last_time_[OBJECT_STATS_COUNT];
161   // Approximation of overallocated memory by InstanceType.
162   size_t over_allocated_[OBJECT_STATS_COUNT];
163   // Detailed histograms by InstanceType.
164   size_t size_histogram_[OBJECT_STATS_COUNT][kNumberOfBuckets];
165   size_t over_allocated_histogram_[OBJECT_STATS_COUNT][kNumberOfBuckets];
166 
167   size_t tagged_fields_count_;
168   size_t embedder_fields_count_;
169   size_t inobject_smi_fields_count_;
170   size_t boxed_double_fields_count_;
171   size_t string_data_count_;
172   size_t raw_fields_count_;
173 
174   friend class ObjectStatsCollectorImpl;
175 };
176 
177 class ObjectStatsCollector {
178  public:
ObjectStatsCollector(Heap * heap,ObjectStats * live,ObjectStats * dead)179   ObjectStatsCollector(Heap* heap, ObjectStats* live, ObjectStats* dead)
180       : heap_(heap), live_(live), dead_(dead) {
181     DCHECK_NOT_NULL(heap_);
182     DCHECK_NOT_NULL(live_);
183     DCHECK_NOT_NULL(dead_);
184   }
185 
186   // Collects type information of live and dead objects. Requires mark bits to
187   // be present.
188   void Collect();
189 
190  private:
191   Heap* const heap_;
192   ObjectStats* const live_;
193   ObjectStats* const dead_;
194 };
195 
196 }  // namespace internal
197 }  // namespace v8
198 
199 #endif  // V8_HEAP_OBJECT_STATS_H_
200