Bug Summary

File:out/../deps/v8/src/heap/object-stats.cc
Warning:line 71, column 7
Value stored to 'tagged_fields_count_in_object' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name object-stats.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -ffunction-sections -fdata-sections -fcoverage-compilation-dir=/home/maurizio/node-v18.6.0/out -resource-dir /usr/local/lib/clang/16.0.0 -D _GLIBCXX_USE_CXX11_ABI=1 -D NODE_OPENSSL_CONF_NAME=nodejs_conf -D NODE_OPENSSL_HAS_QUIC -D V8_GYP_BUILD -D V8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64 -D __STDC_FORMAT_MACROS -D OPENSSL_NO_PINSHARED -D OPENSSL_THREADS -D V8_TARGET_ARCH_X64 -D V8_HAVE_TARGET_OS -D V8_TARGET_OS_LINUX -D V8_EMBEDDER_STRING="-node.8" -D ENABLE_DISASSEMBLER -D V8_PROMISE_INTERNAL_FIELD_COUNT=1 -D V8_SHORT_BUILTIN_CALLS -D OBJECT_PRINT -D V8_INTL_SUPPORT -D V8_ATOMIC_OBJECT_FIELD_WRITES -D V8_ENABLE_LAZY_SOURCE_POSITIONS -D V8_USE_SIPHASH -D V8_SHARED_RO_HEAP -D V8_WIN64_UNWINDING_INFO -D V8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH -D V8_SNAPSHOT_COMPRESSION -D V8_ENABLE_WEBASSEMBLY -D V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS -D V8_ALLOCATION_FOLDING -D V8_ALLOCATION_SITE_TRACKING -D V8_SCRIPTORMODULE_LEGACY_LIFETIME -D V8_ADVANCED_BIGINT_ALGORITHMS -D ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC -D UCONFIG_NO_SERVICE=1 -D U_ENABLE_DYLOAD=0 -D U_STATIC_IMPLEMENTATION=1 -D U_HAVE_STD_STRING=1 -D UCONFIG_NO_BREAK_ITERATION=0 -I ../deps/v8 -I ../deps/v8/include -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/inspector-generated-output-root -I ../deps/v8/third_party/inspector_protocol -I /home/maurizio/node-v18.6.0/out/Release/obj/gen -I /home/maurizio/node-v18.6.0/out/Release/obj/gen/generate-bytecode-output-root -I ../deps/icu-small/source/i18n -I ../deps/icu-small/source/common -I ../deps/v8/third_party/zlib -I ../deps/v8/third_party/zlib/google -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8 -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/x86_64-redhat-linux -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../include/c++/8/backward -internal-isystem /usr/local/lib/clang/16.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-redhat-linux/8/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-unused-parameter -Wno-return-type -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/home/maurizio/node-v18.6.0/out -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2022-08-22-142216-507842-1 -x c++ ../deps/v8/src/heap/object-stats.cc
1// Copyright 2015 the V8 project authors. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5
6#include "src/heap/object-stats.h"
7
8#include <unordered_set>
9
10#include "src/base/bits.h"
11#include "src/codegen/assembler-inl.h"
12#include "src/codegen/compilation-cache.h"
13#include "src/common/globals.h"
14#include "src/execution/isolate.h"
15#include "src/heap/combined-heap.h"
16#include "src/heap/heap-inl.h"
17#include "src/heap/mark-compact.h"
18#include "src/logging/counters.h"
19#include "src/objects/compilation-cache-table-inl.h"
20#include "src/objects/heap-object.h"
21#include "src/objects/js-array-inl.h"
22#include "src/objects/js-collection-inl.h"
23#include "src/objects/literal-objects-inl.h"
24#include "src/objects/slots.h"
25#include "src/objects/templates.h"
26#include "src/objects/visitors.h"
27#include "src/utils/memcopy.h"
28#include "src/utils/ostreams.h"
29
30namespace v8 {
31namespace internal {
32
33static base::LazyMutex object_stats_mutex = LAZY_MUTEX_INITIALIZER{ { 0 }, { {} } };
34
35class FieldStatsCollector : public ObjectVisitorWithCageBases {
36 public:
37 FieldStatsCollector(Heap* heap, size_t* tagged_fields_count,
38 size_t* embedder_fields_count,
39 size_t* inobject_smi_fields_count,
40 size_t* boxed_double_fields_count,
41 size_t* string_data_count, size_t* raw_fields_count)
42 : ObjectVisitorWithCageBases(heap),
43 tagged_fields_count_(tagged_fields_count),
44 embedder_fields_count_(embedder_fields_count),
45 inobject_smi_fields_count_(inobject_smi_fields_count),
46 boxed_double_fields_count_(boxed_double_fields_count),
47 string_data_count_(string_data_count),
48 raw_fields_count_(raw_fields_count) {}
49
50 void RecordStats(HeapObject host) {
51 size_t old_pointer_fields_count = *tagged_fields_count_;
52 host.Iterate(cage_base(), this);
53 size_t tagged_fields_count_in_object =
54 *tagged_fields_count_ - old_pointer_fields_count;
55
56 int object_size_in_words = host.Size(cage_base()) / kTaggedSize;
57 DCHECK_LE(tagged_fields_count_in_object, object_size_in_words)((void) 0);
58 size_t raw_fields_count_in_object =
59 object_size_in_words - tagged_fields_count_in_object;
60
61 if (host.IsJSObject(cage_base())) {
62 JSObjectFieldStats field_stats = GetInobjectFieldStats(host.map());
63 // Embedder fields are already included into pointer words.
64 DCHECK_LE(field_stats.embedded_fields_count_,((void) 0)
65 tagged_fields_count_in_object)((void) 0);
66 tagged_fields_count_in_object -= field_stats.embedded_fields_count_;
67 *tagged_fields_count_ -= field_stats.embedded_fields_count_;
68 *embedder_fields_count_ += field_stats.embedded_fields_count_;
69
70 // Smi fields are also included into pointer words.
71 tagged_fields_count_in_object -= field_stats.smi_fields_count_;
Value stored to 'tagged_fields_count_in_object' is never read
72 *tagged_fields_count_ -= field_stats.smi_fields_count_;
73 *inobject_smi_fields_count_ += field_stats.smi_fields_count_;
74 } else if (host.IsHeapNumber(cage_base())) {
75 DCHECK_LE(kDoubleSize / kTaggedSize, raw_fields_count_in_object)((void) 0);
76 raw_fields_count_in_object -= kDoubleSize / kTaggedSize;
77 *boxed_double_fields_count_ += 1;
78 } else if (host.IsSeqString(cage_base())) {
79 int string_data = SeqString::cast(host).length(kAcquireLoad) *
80 (String::cast(host).IsOneByteRepresentation() ? 1 : 2) /
81 kTaggedSize;
82 DCHECK_LE(string_data, raw_fields_count_in_object)((void) 0);
83 raw_fields_count_in_object -= string_data;
84 *string_data_count_ += string_data;
85 }
86 *raw_fields_count_ += raw_fields_count_in_object;
87 }
88
89 void VisitPointers(HeapObject host, ObjectSlot start,
90 ObjectSlot end) override {
91 *tagged_fields_count_ += (end - start);
92 }
93 void VisitPointers(HeapObject host, MaybeObjectSlot start,
94 MaybeObjectSlot end) override {
95 *tagged_fields_count_ += (end - start);
96 }
97
98 V8_INLINEinline __attribute__((always_inline)) void VisitCodePointer(HeapObject host,
99 CodeObjectSlot slot) override {
100 CHECK(V8_EXTERNAL_CODE_SPACE_BOOL)do { if ((__builtin_expect(!!(!(false)), 0))) { V8_Fatal("Check failed: %s."
, "V8_EXTERNAL_CODE_SPACE_BOOL"); } } while (false)
;
101 *tagged_fields_count_ += 1;
102 }
103
104 void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
105 // Code target is most likely encoded as a relative 32-bit offset and not
106 // as a full tagged value, so there's nothing to count.
107 }
108
109 void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
110 *tagged_fields_count_ += 1;
111 }
112
113 void VisitMapPointer(HeapObject host) override {
114 // Just do nothing, but avoid the inherited UNREACHABLE implementation.
115 }
116
117 private:
118 struct JSObjectFieldStats {
119 JSObjectFieldStats() : embedded_fields_count_(0), smi_fields_count_(0) {}
120
121 unsigned embedded_fields_count_ : kDescriptorIndexBitCount;
122 unsigned smi_fields_count_ : kDescriptorIndexBitCount;
123 };
124 std::unordered_map<Map, JSObjectFieldStats, Object::Hasher>
125 field_stats_cache_;
126
127 JSObjectFieldStats GetInobjectFieldStats(Map map);
128
129 size_t* const tagged_fields_count_;
130 size_t* const embedder_fields_count_;
131 size_t* const inobject_smi_fields_count_;
132 size_t* const boxed_double_fields_count_;
133 size_t* const string_data_count_;
134 size_t* const raw_fields_count_;
135};
136
137FieldStatsCollector::JSObjectFieldStats
138FieldStatsCollector::GetInobjectFieldStats(Map map) {
139 auto iter = field_stats_cache_.find(map);
140 if (iter != field_stats_cache_.end()) {
141 return iter->second;
142 }
143 // Iterate descriptor array and calculate stats.
144 JSObjectFieldStats stats;
145 stats.embedded_fields_count_ = JSObject::GetEmbedderFieldCount(map);
146 if (!map.is_dictionary_map()) {
147 DescriptorArray descriptors = map.instance_descriptors();
148 for (InternalIndex descriptor : map.IterateOwnDescriptors()) {
149 PropertyDetails details = descriptors.GetDetails(descriptor);
150 if (details.location() == PropertyLocation::kField) {
151 FieldIndex index = FieldIndex::ForDescriptor(map, descriptor);
152 // Stop on first out-of-object field.
153 if (!index.is_inobject()) break;
154 if (details.representation().IsSmi()) {
155 ++stats.smi_fields_count_;
156 }
157 }
158 }
159 }
160 field_stats_cache_.insert(std::make_pair(map, stats));
161 return stats;
162}
163
164void ObjectStats::ClearObjectStats(bool clear_last_time_stats) {
165 memset(object_counts_, 0, sizeof(object_counts_));
166 memset(object_sizes_, 0, sizeof(object_sizes_));
167 memset(over_allocated_, 0, sizeof(over_allocated_));
168 memset(size_histogram_, 0, sizeof(size_histogram_));
169 memset(over_allocated_histogram_, 0, sizeof(over_allocated_histogram_));
170 if (clear_last_time_stats) {
171 memset(object_counts_last_time_, 0, sizeof(object_counts_last_time_));
172 memset(object_sizes_last_time_, 0, sizeof(object_sizes_last_time_));
173 }
174 tagged_fields_count_ = 0;
175 embedder_fields_count_ = 0;
176 inobject_smi_fields_count_ = 0;
177 boxed_double_fields_count_ = 0;
178 string_data_count_ = 0;
179 raw_fields_count_ = 0;
180}
181
182// Tell the compiler to never inline this: occasionally, the optimizer will
183// decide to inline this and unroll the loop, making the compiled code more than
184// 100KB larger.
185V8_NOINLINE__attribute__((noinline)) static void PrintJSONArray(size_t* array, const int len) {
186 PrintF("[ ");
187 for (int i = 0; i < len; i++) {
188 PrintF("%zu", array[i]);
189 if (i != (len - 1)) PrintF(", ");
190 }
191 PrintF(" ]");
192}
193
194V8_NOINLINE__attribute__((noinline)) static void DumpJSONArray(std::stringstream& stream, size_t* array,
195 const int len) {
196 stream << PrintCollection(base::Vector<size_t>(array, len));
197}
198
199void ObjectStats::PrintKeyAndId(const char* key, int gc_count) {
200 PrintF("\"isolate\": \"%p\", \"id\": %d, \"key\": \"%s\", ",
201 reinterpret_cast<void*>(isolate()), gc_count, key);
202}
203
204void ObjectStats::PrintInstanceTypeJSON(const char* key, int gc_count,
205 const char* name, int index) {
206 PrintF("{ ");
207 PrintKeyAndId(key, gc_count);
208 PrintF("\"type\": \"instance_type_data\", ");
209 PrintF("\"instance_type\": %d, ", index);
210 PrintF("\"instance_type_name\": \"%s\", ", name);
211 PrintF("\"overall\": %zu, ", object_sizes_[index]);
212 PrintF("\"count\": %zu, ", object_counts_[index]);
213 PrintF("\"over_allocated\": %zu, ", over_allocated_[index]);
214 PrintF("\"histogram\": ");
215 PrintJSONArray(size_histogram_[index], kNumberOfBuckets);
216 PrintF(",");
217 PrintF("\"over_allocated_histogram\": ");
218 PrintJSONArray(over_allocated_histogram_[index], kNumberOfBuckets);
219 PrintF(" }\n");
220}
221
222void ObjectStats::PrintJSON(const char* key) {
223 double time = isolate()->time_millis_since_init();
224 int gc_count = heap()->gc_count();
225
226 // gc_descriptor
227 PrintF("{ ");
228 PrintKeyAndId(key, gc_count);
229 PrintF("\"type\": \"gc_descriptor\", \"time\": %f }\n", time);
230 // field_data
231 PrintF("{ ");
232 PrintKeyAndId(key, gc_count);
233 PrintF("\"type\": \"field_data\"");
234 PrintF(", \"tagged_fields\": %zu", tagged_fields_count_ * kTaggedSize);
235 PrintF(", \"embedder_fields\": %zu",
236 embedder_fields_count_ * kEmbedderDataSlotSize);
237 PrintF(", \"inobject_smi_fields\": %zu",
238 inobject_smi_fields_count_ * kTaggedSize);
239 PrintF(", \"boxed_double_fields\": %zu",
240 boxed_double_fields_count_ * kDoubleSize);
241 PrintF(", \"string_data\": %zu", string_data_count_ * kTaggedSize);
242 PrintF(", \"other_raw_fields\": %zu", raw_fields_count_ * kSystemPointerSize);
243 PrintF(" }\n");
244 // bucket_sizes
245 PrintF("{ ");
246 PrintKeyAndId(key, gc_count);
247 PrintF("\"type\": \"bucket_sizes\", \"sizes\": [ ");
248 for (int i = 0; i < kNumberOfBuckets; i++) {
249 PrintF("%d", 1 << (kFirstBucketShift + i));
250 if (i != (kNumberOfBuckets - 1)) PrintF(", ");
251 }
252 PrintF(" ] }\n");
253
254#define INSTANCE_TYPE_WRAPPER(name) \
255 PrintInstanceTypeJSON(key, gc_count, #name, name);
256
257#define VIRTUAL_INSTANCE_TYPE_WRAPPER(name) \
258 PrintInstanceTypeJSON(key, gc_count, #name, FIRST_VIRTUAL_TYPE + name);
259
260 INSTANCE_TYPE_LIST(INSTANCE_TYPE_WRAPPER)INSTANCE_TYPE_WRAPPER(INTERNALIZED_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(EXTERNAL_INTERNALIZED_STRING_TYPE) INSTANCE_TYPE_WRAPPER(ONE_BYTE_INTERNALIZED_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(STRING_TYPE) INSTANCE_TYPE_WRAPPER(CONS_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(EXTERNAL_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(SLICED_STRING_TYPE) INSTANCE_TYPE_WRAPPER(THIN_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER(CONS_ONE_BYTE_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(EXTERNAL_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(SLICED_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER(THIN_ONE_BYTE_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(UNCACHED_EXTERNAL_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(SHARED_STRING_TYPE) INSTANCE_TYPE_WRAPPER(SHARED_THIN_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(SHARED_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(SHARED_THIN_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER(SYMBOL_TYPE
) INSTANCE_TYPE_WRAPPER(BIG_INT_BASE_TYPE) INSTANCE_TYPE_WRAPPER
(HEAP_NUMBER_TYPE) INSTANCE_TYPE_WRAPPER(ODDBALL_TYPE) INSTANCE_TYPE_WRAPPER
(PROMISE_FULFILL_REACTION_JOB_TASK_TYPE) INSTANCE_TYPE_WRAPPER
(PROMISE_REJECT_REACTION_JOB_TASK_TYPE) INSTANCE_TYPE_WRAPPER
(CALLABLE_TASK_TYPE) INSTANCE_TYPE_WRAPPER(CALLBACK_TASK_TYPE
) INSTANCE_TYPE_WRAPPER(PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE
) INSTANCE_TYPE_WRAPPER(LOAD_HANDLER_TYPE) INSTANCE_TYPE_WRAPPER
(STORE_HANDLER_TYPE) INSTANCE_TYPE_WRAPPER(FUNCTION_TEMPLATE_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(OBJECT_TEMPLATE_INFO_TYPE) INSTANCE_TYPE_WRAPPER
(ACCESS_CHECK_INFO_TYPE) INSTANCE_TYPE_WRAPPER(ACCESSOR_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(ACCESSOR_PAIR_TYPE) INSTANCE_TYPE_WRAPPER
(ALIASED_ARGUMENTS_ENTRY_TYPE) INSTANCE_TYPE_WRAPPER(ALLOCATION_MEMENTO_TYPE
) INSTANCE_TYPE_WRAPPER(ALLOCATION_SITE_TYPE) INSTANCE_TYPE_WRAPPER
(ARRAY_BOILERPLATE_DESCRIPTION_TYPE) INSTANCE_TYPE_WRAPPER(ASM_WASM_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(ASYNC_GENERATOR_REQUEST_TYPE) INSTANCE_TYPE_WRAPPER
(BREAK_POINT_TYPE) INSTANCE_TYPE_WRAPPER(BREAK_POINT_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(CACHED_TEMPLATE_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(CALL_HANDLER_INFO_TYPE) INSTANCE_TYPE_WRAPPER(CALL_SITE_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(CLASS_POSITIONS_TYPE) INSTANCE_TYPE_WRAPPER
(DEBUG_INFO_TYPE) INSTANCE_TYPE_WRAPPER(ENUM_CACHE_TYPE) INSTANCE_TYPE_WRAPPER
(ERROR_STACK_DATA_TYPE) INSTANCE_TYPE_WRAPPER(FEEDBACK_CELL_TYPE
) INSTANCE_TYPE_WRAPPER(FUNCTION_TEMPLATE_RARE_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(INTERCEPTOR_INFO_TYPE) INSTANCE_TYPE_WRAPPER(INTERPRETER_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(MODULE_REQUEST_TYPE) INSTANCE_TYPE_WRAPPER
(PROMISE_CAPABILITY_TYPE) INSTANCE_TYPE_WRAPPER(PROMISE_ON_STACK_TYPE
) INSTANCE_TYPE_WRAPPER(PROMISE_REACTION_TYPE) INSTANCE_TYPE_WRAPPER
(PROPERTY_DESCRIPTOR_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(PROTOTYPE_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(REG_EXP_BOILERPLATE_DESCRIPTION_TYPE)
INSTANCE_TYPE_WRAPPER(SCRIPT_TYPE) INSTANCE_TYPE_WRAPPER(SCRIPT_OR_MODULE_TYPE
) INSTANCE_TYPE_WRAPPER(SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE) INSTANCE_TYPE_WRAPPER
(STACK_FRAME_INFO_TYPE) INSTANCE_TYPE_WRAPPER(TEMPLATE_OBJECT_DESCRIPTION_TYPE
) INSTANCE_TYPE_WRAPPER(TUPLE2_TYPE) INSTANCE_TYPE_WRAPPER(WASM_CONTINUATION_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_EXCEPTION_TAG_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_INDIRECT_FUNCTION_TABLE_TYPE) INSTANCE_TYPE_WRAPPER(FIXED_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(HASH_TABLE_TYPE) INSTANCE_TYPE_WRAPPER
(EPHEMERON_HASH_TABLE_TYPE) INSTANCE_TYPE_WRAPPER(GLOBAL_DICTIONARY_TYPE
) INSTANCE_TYPE_WRAPPER(NAME_DICTIONARY_TYPE) INSTANCE_TYPE_WRAPPER
(NAME_TO_INDEX_HASH_TABLE_TYPE) INSTANCE_TYPE_WRAPPER(NUMBER_DICTIONARY_TYPE
) INSTANCE_TYPE_WRAPPER(ORDERED_HASH_MAP_TYPE) INSTANCE_TYPE_WRAPPER
(ORDERED_HASH_SET_TYPE) INSTANCE_TYPE_WRAPPER(ORDERED_NAME_DICTIONARY_TYPE
) INSTANCE_TYPE_WRAPPER(REGISTERED_SYMBOL_TABLE_TYPE) INSTANCE_TYPE_WRAPPER
(SIMPLE_NUMBER_DICTIONARY_TYPE) INSTANCE_TYPE_WRAPPER(CLOSURE_FEEDBACK_CELL_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(OBJECT_BOILERPLATE_DESCRIPTION_TYPE) INSTANCE_TYPE_WRAPPER
(SCRIPT_CONTEXT_TABLE_TYPE) INSTANCE_TYPE_WRAPPER(BYTE_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(BYTECODE_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER
(FIXED_DOUBLE_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER(INTERNAL_CLASS_WITH_SMI_ELEMENTS_TYPE
) INSTANCE_TYPE_WRAPPER(SLOPPY_ARGUMENTS_ELEMENTS_TYPE) INSTANCE_TYPE_WRAPPER
(TURBOFAN_BITSET_TYPE_TYPE) INSTANCE_TYPE_WRAPPER(TURBOFAN_HEAP_CONSTANT_TYPE_TYPE
) INSTANCE_TYPE_WRAPPER(TURBOFAN_OTHER_NUMBER_CONSTANT_TYPE_TYPE
) INSTANCE_TYPE_WRAPPER(TURBOFAN_RANGE_TYPE_TYPE) INSTANCE_TYPE_WRAPPER
(TURBOFAN_UNION_TYPE_TYPE) INSTANCE_TYPE_WRAPPER(FOREIGN_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_INTERNAL_FUNCTION_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_TYPE_INFO_TYPE) INSTANCE_TYPE_WRAPPER(AWAIT_CONTEXT_TYPE
) INSTANCE_TYPE_WRAPPER(BLOCK_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER
(CATCH_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER(DEBUG_EVALUATE_CONTEXT_TYPE
) INSTANCE_TYPE_WRAPPER(EVAL_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER
(FUNCTION_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER(MODULE_CONTEXT_TYPE
) INSTANCE_TYPE_WRAPPER(NATIVE_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER
(SCRIPT_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER(WITH_CONTEXT_TYPE
) INSTANCE_TYPE_WRAPPER(UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(UNCOMPILED_DATA_WITH_PREPARSE_DATA_AND_JOB_TYPE
) INSTANCE_TYPE_WRAPPER(UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_WITH_JOB_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_FUNCTION_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_CAPI_FUNCTION_DATA_TYPE) INSTANCE_TYPE_WRAPPER(WASM_EXPORTED_FUNCTION_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_JS_FUNCTION_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(EXPORTED_SUB_CLASS_BASE_TYPE) INSTANCE_TYPE_WRAPPER(EXPORTED_SUB_CLASS_TYPE
) INSTANCE_TYPE_WRAPPER(EXPORTED_SUB_CLASS2_TYPE) INSTANCE_TYPE_WRAPPER
(SMALL_ORDERED_HASH_MAP_TYPE) INSTANCE_TYPE_WRAPPER(SMALL_ORDERED_HASH_SET_TYPE
) INSTANCE_TYPE_WRAPPER(SMALL_ORDERED_NAME_DICTIONARY_TYPE) INSTANCE_TYPE_WRAPPER
(ABSTRACT_INTERNAL_CLASS_SUBCLASS1_TYPE) INSTANCE_TYPE_WRAPPER
(ABSTRACT_INTERNAL_CLASS_SUBCLASS2_TYPE) INSTANCE_TYPE_WRAPPER
(DESCRIPTOR_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER(STRONG_DESCRIPTOR_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(SOURCE_TEXT_MODULE_TYPE) INSTANCE_TYPE_WRAPPER
(SYNTHETIC_MODULE_TYPE) INSTANCE_TYPE_WRAPPER(WEAK_FIXED_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(TRANSITION_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER
(CELL_TYPE) INSTANCE_TYPE_WRAPPER(CODE_TYPE) INSTANCE_TYPE_WRAPPER
(CODE_DATA_CONTAINER_TYPE) INSTANCE_TYPE_WRAPPER(COVERAGE_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(EMBEDDER_DATA_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER
(FEEDBACK_METADATA_TYPE) INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_TYPE
) INSTANCE_TYPE_WRAPPER(FILLER_TYPE) INSTANCE_TYPE_WRAPPER(FREE_SPACE_TYPE
) INSTANCE_TYPE_WRAPPER(INTERNAL_CLASS_TYPE) INSTANCE_TYPE_WRAPPER
(INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE) INSTANCE_TYPE_WRAPPER
(MAP_TYPE) INSTANCE_TYPE_WRAPPER(MEGA_DOM_HANDLER_TYPE) INSTANCE_TYPE_WRAPPER
(ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(PREPARSE_DATA_TYPE) INSTANCE_TYPE_WRAPPER(PROPERTY_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(PROPERTY_CELL_TYPE) INSTANCE_TYPE_WRAPPER
(SCOPE_INFO_TYPE) INSTANCE_TYPE_WRAPPER(SHARED_FUNCTION_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(SMI_BOX_TYPE) INSTANCE_TYPE_WRAPPER(SMI_PAIR_TYPE
) INSTANCE_TYPE_WRAPPER(SORT_STATE_TYPE) INSTANCE_TYPE_WRAPPER
(SWISS_NAME_DICTIONARY_TYPE) INSTANCE_TYPE_WRAPPER(WASM_API_FUNCTION_REF_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_ON_FULFILLED_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(WEAK_ARRAY_LIST_TYPE) INSTANCE_TYPE_WRAPPER(WEAK_CELL_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER(WASM_STRUCT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_PROXY_TYPE) INSTANCE_TYPE_WRAPPER(JS_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_GLOBAL_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_GLOBAL_PROXY_TYPE
) INSTANCE_TYPE_WRAPPER(JS_MODULE_NAMESPACE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_SPECIAL_API_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_PRIMITIVE_WRAPPER_TYPE
) INSTANCE_TYPE_WRAPPER(JS_API_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_LAST_DUMMY_API_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_DATA_VIEW_TYPE
) INSTANCE_TYPE_WRAPPER(JS_TYPED_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ARRAY_BUFFER_TYPE) INSTANCE_TYPE_WRAPPER(JS_PROMISE_TYPE)
INSTANCE_TYPE_WRAPPER(JS_BOUND_FUNCTION_TYPE) INSTANCE_TYPE_WRAPPER
(JS_WRAPPED_FUNCTION_TYPE) INSTANCE_TYPE_WRAPPER(JS_FUNCTION_TYPE
) INSTANCE_TYPE_WRAPPER(BIGINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(BIGUINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(FLOAT32_TYPED_ARRAY_CONSTRUCTOR_TYPE)
INSTANCE_TYPE_WRAPPER(FLOAT64_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER
(INT16_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER(INT32_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(INT8_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER
(UINT16_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER(UINT32_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(UINT8_CLAMPED_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(UINT8_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_PROMISE_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_REG_EXP_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_CLASS_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_ARRAY_ITERATOR_PROTOTYPE_TYPE
) INSTANCE_TYPE_WRAPPER(JS_ITERATOR_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_MAP_ITERATOR_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER(JS_OBJECT_PROTOTYPE_TYPE
) INSTANCE_TYPE_WRAPPER(JS_PROMISE_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_REG_EXP_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER(JS_SET_ITERATOR_PROTOTYPE_TYPE
) INSTANCE_TYPE_WRAPPER(JS_SET_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_STRING_ITERATOR_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER(JS_TYPED_ARRAY_PROTOTYPE_TYPE
) INSTANCE_TYPE_WRAPPER(JS_MAP_KEY_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_MAP_KEY_VALUE_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_MAP_VALUE_ITERATOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_SET_KEY_VALUE_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_SET_VALUE_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_GENERATOR_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_ASYNC_FUNCTION_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ASYNC_GENERATOR_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_MAP_TYPE
) INSTANCE_TYPE_WRAPPER(JS_SET_TYPE) INSTANCE_TYPE_WRAPPER(JS_WEAK_MAP_TYPE
) INSTANCE_TYPE_WRAPPER(JS_WEAK_SET_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ARGUMENTS_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(JS_ARRAY_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ASYNC_FROM_SYNC_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_COLLATOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_CONTEXT_EXTENSION_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_DATE_TYPE) INSTANCE_TYPE_WRAPPER(JS_DATE_TIME_FORMAT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_DISPLAY_NAMES_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ERROR_TYPE) INSTANCE_TYPE_WRAPPER(JS_EXTERNAL_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_FINALIZATION_REGISTRY_TYPE) INSTANCE_TYPE_WRAPPER
(JS_LIST_FORMAT_TYPE) INSTANCE_TYPE_WRAPPER(JS_LOCALE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_MESSAGE_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_NUMBER_FORMAT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_PLURAL_RULES_TYPE) INSTANCE_TYPE_WRAPPER
(JS_REG_EXP_TYPE) INSTANCE_TYPE_WRAPPER(JS_REG_EXP_STRING_ITERATOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_RELATIVE_TIME_FORMAT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_SEGMENT_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_SEGMENTER_TYPE
) INSTANCE_TYPE_WRAPPER(JS_SEGMENTS_TYPE) INSTANCE_TYPE_WRAPPER
(JS_SHADOW_REALM_TYPE) INSTANCE_TYPE_WRAPPER(JS_SHARED_STRUCT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_STRING_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_TEMPORAL_CALENDAR_TYPE) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_DURATION_TYPE
) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_INSTANT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_TEMPORAL_PLAIN_DATE_TYPE) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_PLAIN_DATE_TIME_TYPE
) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE) INSTANCE_TYPE_WRAPPER
(JS_TEMPORAL_PLAIN_TIME_TYPE) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE
) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_TIME_ZONE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_TEMPORAL_ZONED_DATE_TIME_TYPE) INSTANCE_TYPE_WRAPPER(JS_V8_BREAK_ITERATOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_WEAK_REF_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_GLOBAL_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(WASM_INSTANCE_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_MEMORY_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_MODULE_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(WASM_SUSPENDER_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_TABLE_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_TAG_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(WASM_VALUE_OBJECT_TYPE
)
261 VIRTUAL_INSTANCE_TYPE_LIST(VIRTUAL_INSTANCE_TYPE_WRAPPER)VIRTUAL_INSTANCE_TYPE_WRAPPER(BYTECODE_HANDLER) VIRTUAL_INSTANCE_TYPE_WRAPPER
(FOR_TESTING) VIRTUAL_INSTANCE_TYPE_WRAPPER(BUILTIN) VIRTUAL_INSTANCE_TYPE_WRAPPER
(REGEXP) VIRTUAL_INSTANCE_TYPE_WRAPPER(WASM_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER
(WASM_TO_CAPI_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER(WASM_TO_JS_FUNCTION
) VIRTUAL_INSTANCE_TYPE_WRAPPER(JS_TO_WASM_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER
(JS_TO_JS_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER(C_WASM_ENTRY
) VIRTUAL_INSTANCE_TYPE_WRAPPER(INTERPRETED_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER
(BASELINE) VIRTUAL_INSTANCE_TYPE_WRAPPER(MAGLEV) VIRTUAL_INSTANCE_TYPE_WRAPPER
(TURBOFAN) VIRTUAL_INSTANCE_TYPE_WRAPPER(ARRAY_BOILERPLATE_DESCRIPTION_ELEMENTS_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(ARRAY_DICTIONARY_ELEMENTS_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(ARRAY_ELEMENTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(BOILERPLATE_ELEMENTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(BOILERPLATE_PROPERTY_ARRAY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(BOILERPLATE_PROPERTY_DICTIONARY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(BYTECODE_ARRAY_CONSTANT_POOL_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(BYTECODE_ARRAY_HANDLER_TABLE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(COW_ARRAY_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(DEOPTIMIZATION_DATA_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(DEPENDENT_CODE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(DEPRECATED_DESCRIPTOR_ARRAY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(EMBEDDED_OBJECT_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(ENUM_KEYS_CACHE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(ENUM_INDICES_CACHE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_ENTRY_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(FEEDBACK_VECTOR_HEADER_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_CALL_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_ENUM_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_LOAD_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_OTHER_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_STORE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(GLOBAL_ELEMENTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(GLOBAL_PROPERTIES_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(JS_ARRAY_BOILERPLATE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(JS_COLLECTION_TABLE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(JS_OBJECT_BOILERPLATE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(JS_UNCOMPILED_FUNCTION_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(MAP_ABANDONED_PROTOTYPE_TYPE)
VIRTUAL_INSTANCE_TYPE_WRAPPER(MAP_DEPRECATED_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(MAP_DICTIONARY_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(MAP_PROTOTYPE_DICTIONARY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(MAP_PROTOTYPE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(MAP_STABLE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(NUMBER_STRING_CACHE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(OBJECT_DICTIONARY_ELEMENTS_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(OBJECT_ELEMENTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(OBJECT_PROPERTY_ARRAY_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(OBJECT_PROPERTY_DICTIONARY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(OBJECT_TO_CODE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(OPTIMIZED_CODE_LITERALS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(
OTHER_CONTEXT_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(PROTOTYPE_DESCRIPTOR_ARRAY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(PROTOTYPE_PROPERTY_ARRAY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(PROTOTYPE_PROPERTY_DICTIONARY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(PROTOTYPE_USERS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(REGEXP_MULTIPLE_CACHE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(RELOC_INFO_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(RETAINED_MAPS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(SCRIPT_LIST_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SHARED_FUNCTION_INFOS_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SERIALIZED_OBJECTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(SINGLE_CHARACTER_STRING_CACHE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(STRING_SPLIT_CACHE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SOURCE_POSITION_TABLE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(UNCOMPILED_SHARED_FUNCTION_INFO_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE)
262
263#undef INSTANCE_TYPE_WRAPPER
264#undef VIRTUAL_INSTANCE_TYPE_WRAPPER
265}
266
267void ObjectStats::DumpInstanceTypeData(std::stringstream& stream,
268 const char* name, int index) {
269 stream << "\"" << name << "\":{";
270 stream << "\"type\":" << static_cast<int>(index) << ",";
271 stream << "\"overall\":" << object_sizes_[index] << ",";
272 stream << "\"count\":" << object_counts_[index] << ",";
273 stream << "\"over_allocated\":" << over_allocated_[index] << ",";
274 stream << "\"histogram\":";
275 DumpJSONArray(stream, size_histogram_[index], kNumberOfBuckets);
276 stream << ",\"over_allocated_histogram\":";
277 DumpJSONArray(stream, over_allocated_histogram_[index], kNumberOfBuckets);
278 stream << "},";
279}
280
281void ObjectStats::Dump(std::stringstream& stream) {
282 double time = isolate()->time_millis_since_init();
283 int gc_count = heap()->gc_count();
284
285 stream << "{";
286 stream << "\"isolate\":\"" << reinterpret_cast<void*>(isolate()) << "\",";
287 stream << "\"id\":" << gc_count << ",";
288 stream << "\"time\":" << time << ",";
289
290 // field_data
291 stream << "\"field_data\":{";
292 stream << "\"tagged_fields\":" << (tagged_fields_count_ * kTaggedSize);
293 stream << ",\"embedder_fields\":"
294 << (embedder_fields_count_ * kEmbedderDataSlotSize);
295 stream << ",\"inobject_smi_fields\": "
296 << (inobject_smi_fields_count_ * kTaggedSize);
297 stream << ",\"boxed_double_fields\": "
298 << (boxed_double_fields_count_ * kDoubleSize);
299 stream << ",\"string_data\": " << (string_data_count_ * kTaggedSize);
300 stream << ",\"other_raw_fields\":"
301 << (raw_fields_count_ * kSystemPointerSize);
302 stream << "}, ";
303
304 stream << "\"bucket_sizes\":[";
305 for (int i = 0; i < kNumberOfBuckets; i++) {
306 stream << (1 << (kFirstBucketShift + i));
307 if (i != (kNumberOfBuckets - 1)) stream << ",";
308 }
309 stream << "],";
310 stream << "\"type_data\":{";
311
312#define INSTANCE_TYPE_WRAPPER(name) DumpInstanceTypeData(stream, #name, name);
313
314#define VIRTUAL_INSTANCE_TYPE_WRAPPER(name) \
315 DumpInstanceTypeData(stream, #name, FIRST_VIRTUAL_TYPE + name);
316
317 INSTANCE_TYPE_LIST(INSTANCE_TYPE_WRAPPER)INSTANCE_TYPE_WRAPPER(INTERNALIZED_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(EXTERNAL_INTERNALIZED_STRING_TYPE) INSTANCE_TYPE_WRAPPER(ONE_BYTE_INTERNALIZED_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(UNCACHED_EXTERNAL_INTERNALIZED_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(UNCACHED_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(STRING_TYPE) INSTANCE_TYPE_WRAPPER(CONS_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(EXTERNAL_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(SLICED_STRING_TYPE) INSTANCE_TYPE_WRAPPER(THIN_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER(CONS_ONE_BYTE_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(EXTERNAL_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(SLICED_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER(THIN_ONE_BYTE_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(UNCACHED_EXTERNAL_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(UNCACHED_EXTERNAL_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(SHARED_STRING_TYPE) INSTANCE_TYPE_WRAPPER(SHARED_THIN_STRING_TYPE
) INSTANCE_TYPE_WRAPPER(SHARED_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER
(SHARED_THIN_ONE_BYTE_STRING_TYPE) INSTANCE_TYPE_WRAPPER(SYMBOL_TYPE
) INSTANCE_TYPE_WRAPPER(BIG_INT_BASE_TYPE) INSTANCE_TYPE_WRAPPER
(HEAP_NUMBER_TYPE) INSTANCE_TYPE_WRAPPER(ODDBALL_TYPE) INSTANCE_TYPE_WRAPPER
(PROMISE_FULFILL_REACTION_JOB_TASK_TYPE) INSTANCE_TYPE_WRAPPER
(PROMISE_REJECT_REACTION_JOB_TASK_TYPE) INSTANCE_TYPE_WRAPPER
(CALLABLE_TASK_TYPE) INSTANCE_TYPE_WRAPPER(CALLBACK_TASK_TYPE
) INSTANCE_TYPE_WRAPPER(PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE
) INSTANCE_TYPE_WRAPPER(LOAD_HANDLER_TYPE) INSTANCE_TYPE_WRAPPER
(STORE_HANDLER_TYPE) INSTANCE_TYPE_WRAPPER(FUNCTION_TEMPLATE_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(OBJECT_TEMPLATE_INFO_TYPE) INSTANCE_TYPE_WRAPPER
(ACCESS_CHECK_INFO_TYPE) INSTANCE_TYPE_WRAPPER(ACCESSOR_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(ACCESSOR_PAIR_TYPE) INSTANCE_TYPE_WRAPPER
(ALIASED_ARGUMENTS_ENTRY_TYPE) INSTANCE_TYPE_WRAPPER(ALLOCATION_MEMENTO_TYPE
) INSTANCE_TYPE_WRAPPER(ALLOCATION_SITE_TYPE) INSTANCE_TYPE_WRAPPER
(ARRAY_BOILERPLATE_DESCRIPTION_TYPE) INSTANCE_TYPE_WRAPPER(ASM_WASM_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(ASYNC_GENERATOR_REQUEST_TYPE) INSTANCE_TYPE_WRAPPER
(BREAK_POINT_TYPE) INSTANCE_TYPE_WRAPPER(BREAK_POINT_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(CACHED_TEMPLATE_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(CALL_HANDLER_INFO_TYPE) INSTANCE_TYPE_WRAPPER(CALL_SITE_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(CLASS_POSITIONS_TYPE) INSTANCE_TYPE_WRAPPER
(DEBUG_INFO_TYPE) INSTANCE_TYPE_WRAPPER(ENUM_CACHE_TYPE) INSTANCE_TYPE_WRAPPER
(ERROR_STACK_DATA_TYPE) INSTANCE_TYPE_WRAPPER(FEEDBACK_CELL_TYPE
) INSTANCE_TYPE_WRAPPER(FUNCTION_TEMPLATE_RARE_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(INTERCEPTOR_INFO_TYPE) INSTANCE_TYPE_WRAPPER(INTERPRETER_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(MODULE_REQUEST_TYPE) INSTANCE_TYPE_WRAPPER
(PROMISE_CAPABILITY_TYPE) INSTANCE_TYPE_WRAPPER(PROMISE_ON_STACK_TYPE
) INSTANCE_TYPE_WRAPPER(PROMISE_REACTION_TYPE) INSTANCE_TYPE_WRAPPER
(PROPERTY_DESCRIPTOR_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(PROTOTYPE_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(REG_EXP_BOILERPLATE_DESCRIPTION_TYPE)
INSTANCE_TYPE_WRAPPER(SCRIPT_TYPE) INSTANCE_TYPE_WRAPPER(SCRIPT_OR_MODULE_TYPE
) INSTANCE_TYPE_WRAPPER(SOURCE_TEXT_MODULE_INFO_ENTRY_TYPE) INSTANCE_TYPE_WRAPPER
(STACK_FRAME_INFO_TYPE) INSTANCE_TYPE_WRAPPER(TEMPLATE_OBJECT_DESCRIPTION_TYPE
) INSTANCE_TYPE_WRAPPER(TUPLE2_TYPE) INSTANCE_TYPE_WRAPPER(WASM_CONTINUATION_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_EXCEPTION_TAG_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_INDIRECT_FUNCTION_TABLE_TYPE) INSTANCE_TYPE_WRAPPER(FIXED_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(HASH_TABLE_TYPE) INSTANCE_TYPE_WRAPPER
(EPHEMERON_HASH_TABLE_TYPE) INSTANCE_TYPE_WRAPPER(GLOBAL_DICTIONARY_TYPE
) INSTANCE_TYPE_WRAPPER(NAME_DICTIONARY_TYPE) INSTANCE_TYPE_WRAPPER
(NAME_TO_INDEX_HASH_TABLE_TYPE) INSTANCE_TYPE_WRAPPER(NUMBER_DICTIONARY_TYPE
) INSTANCE_TYPE_WRAPPER(ORDERED_HASH_MAP_TYPE) INSTANCE_TYPE_WRAPPER
(ORDERED_HASH_SET_TYPE) INSTANCE_TYPE_WRAPPER(ORDERED_NAME_DICTIONARY_TYPE
) INSTANCE_TYPE_WRAPPER(REGISTERED_SYMBOL_TABLE_TYPE) INSTANCE_TYPE_WRAPPER
(SIMPLE_NUMBER_DICTIONARY_TYPE) INSTANCE_TYPE_WRAPPER(CLOSURE_FEEDBACK_CELL_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(OBJECT_BOILERPLATE_DESCRIPTION_TYPE) INSTANCE_TYPE_WRAPPER
(SCRIPT_CONTEXT_TABLE_TYPE) INSTANCE_TYPE_WRAPPER(BYTE_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(BYTECODE_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER
(FIXED_DOUBLE_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER(INTERNAL_CLASS_WITH_SMI_ELEMENTS_TYPE
) INSTANCE_TYPE_WRAPPER(SLOPPY_ARGUMENTS_ELEMENTS_TYPE) INSTANCE_TYPE_WRAPPER
(TURBOFAN_BITSET_TYPE_TYPE) INSTANCE_TYPE_WRAPPER(TURBOFAN_HEAP_CONSTANT_TYPE_TYPE
) INSTANCE_TYPE_WRAPPER(TURBOFAN_OTHER_NUMBER_CONSTANT_TYPE_TYPE
) INSTANCE_TYPE_WRAPPER(TURBOFAN_RANGE_TYPE_TYPE) INSTANCE_TYPE_WRAPPER
(TURBOFAN_UNION_TYPE_TYPE) INSTANCE_TYPE_WRAPPER(FOREIGN_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_INTERNAL_FUNCTION_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_TYPE_INFO_TYPE) INSTANCE_TYPE_WRAPPER(AWAIT_CONTEXT_TYPE
) INSTANCE_TYPE_WRAPPER(BLOCK_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER
(CATCH_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER(DEBUG_EVALUATE_CONTEXT_TYPE
) INSTANCE_TYPE_WRAPPER(EVAL_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER
(FUNCTION_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER(MODULE_CONTEXT_TYPE
) INSTANCE_TYPE_WRAPPER(NATIVE_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER
(SCRIPT_CONTEXT_TYPE) INSTANCE_TYPE_WRAPPER(WITH_CONTEXT_TYPE
) INSTANCE_TYPE_WRAPPER(UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(UNCOMPILED_DATA_WITH_PREPARSE_DATA_AND_JOB_TYPE
) INSTANCE_TYPE_WRAPPER(UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_WITH_JOB_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_FUNCTION_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_CAPI_FUNCTION_DATA_TYPE) INSTANCE_TYPE_WRAPPER(WASM_EXPORTED_FUNCTION_DATA_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_JS_FUNCTION_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(EXPORTED_SUB_CLASS_BASE_TYPE) INSTANCE_TYPE_WRAPPER(EXPORTED_SUB_CLASS_TYPE
) INSTANCE_TYPE_WRAPPER(EXPORTED_SUB_CLASS2_TYPE) INSTANCE_TYPE_WRAPPER
(SMALL_ORDERED_HASH_MAP_TYPE) INSTANCE_TYPE_WRAPPER(SMALL_ORDERED_HASH_SET_TYPE
) INSTANCE_TYPE_WRAPPER(SMALL_ORDERED_NAME_DICTIONARY_TYPE) INSTANCE_TYPE_WRAPPER
(ABSTRACT_INTERNAL_CLASS_SUBCLASS1_TYPE) INSTANCE_TYPE_WRAPPER
(ABSTRACT_INTERNAL_CLASS_SUBCLASS2_TYPE) INSTANCE_TYPE_WRAPPER
(DESCRIPTOR_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER(STRONG_DESCRIPTOR_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(SOURCE_TEXT_MODULE_TYPE) INSTANCE_TYPE_WRAPPER
(SYNTHETIC_MODULE_TYPE) INSTANCE_TYPE_WRAPPER(WEAK_FIXED_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(TRANSITION_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER
(CELL_TYPE) INSTANCE_TYPE_WRAPPER(CODE_TYPE) INSTANCE_TYPE_WRAPPER
(CODE_DATA_CONTAINER_TYPE) INSTANCE_TYPE_WRAPPER(COVERAGE_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(EMBEDDER_DATA_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER
(FEEDBACK_METADATA_TYPE) INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_TYPE
) INSTANCE_TYPE_WRAPPER(FILLER_TYPE) INSTANCE_TYPE_WRAPPER(FREE_SPACE_TYPE
) INSTANCE_TYPE_WRAPPER(INTERNAL_CLASS_TYPE) INSTANCE_TYPE_WRAPPER
(INTERNAL_CLASS_WITH_STRUCT_ELEMENTS_TYPE) INSTANCE_TYPE_WRAPPER
(MAP_TYPE) INSTANCE_TYPE_WRAPPER(MEGA_DOM_HANDLER_TYPE) INSTANCE_TYPE_WRAPPER
(ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(PREPARSE_DATA_TYPE) INSTANCE_TYPE_WRAPPER(PROPERTY_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(PROPERTY_CELL_TYPE) INSTANCE_TYPE_WRAPPER
(SCOPE_INFO_TYPE) INSTANCE_TYPE_WRAPPER(SHARED_FUNCTION_INFO_TYPE
) INSTANCE_TYPE_WRAPPER(SMI_BOX_TYPE) INSTANCE_TYPE_WRAPPER(SMI_PAIR_TYPE
) INSTANCE_TYPE_WRAPPER(SORT_STATE_TYPE) INSTANCE_TYPE_WRAPPER
(SWISS_NAME_DICTIONARY_TYPE) INSTANCE_TYPE_WRAPPER(WASM_API_FUNCTION_REF_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_ON_FULFILLED_DATA_TYPE) INSTANCE_TYPE_WRAPPER
(WEAK_ARRAY_LIST_TYPE) INSTANCE_TYPE_WRAPPER(WEAK_CELL_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER(WASM_STRUCT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_PROXY_TYPE) INSTANCE_TYPE_WRAPPER(JS_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_GLOBAL_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_GLOBAL_PROXY_TYPE
) INSTANCE_TYPE_WRAPPER(JS_MODULE_NAMESPACE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_SPECIAL_API_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_PRIMITIVE_WRAPPER_TYPE
) INSTANCE_TYPE_WRAPPER(JS_API_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_LAST_DUMMY_API_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_DATA_VIEW_TYPE
) INSTANCE_TYPE_WRAPPER(JS_TYPED_ARRAY_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ARRAY_BUFFER_TYPE) INSTANCE_TYPE_WRAPPER(JS_PROMISE_TYPE)
INSTANCE_TYPE_WRAPPER(JS_BOUND_FUNCTION_TYPE) INSTANCE_TYPE_WRAPPER
(JS_WRAPPED_FUNCTION_TYPE) INSTANCE_TYPE_WRAPPER(JS_FUNCTION_TYPE
) INSTANCE_TYPE_WRAPPER(BIGINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(BIGUINT64_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(FLOAT32_TYPED_ARRAY_CONSTRUCTOR_TYPE)
INSTANCE_TYPE_WRAPPER(FLOAT64_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER
(INT16_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER(INT32_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(INT8_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER
(UINT16_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER(UINT32_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(UINT8_CLAMPED_TYPED_ARRAY_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(UINT8_TYPED_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ARRAY_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_PROMISE_CONSTRUCTOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_REG_EXP_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_CLASS_CONSTRUCTOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_ARRAY_ITERATOR_PROTOTYPE_TYPE
) INSTANCE_TYPE_WRAPPER(JS_ITERATOR_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_MAP_ITERATOR_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER(JS_OBJECT_PROTOTYPE_TYPE
) INSTANCE_TYPE_WRAPPER(JS_PROMISE_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_REG_EXP_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER(JS_SET_ITERATOR_PROTOTYPE_TYPE
) INSTANCE_TYPE_WRAPPER(JS_SET_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_STRING_ITERATOR_PROTOTYPE_TYPE) INSTANCE_TYPE_WRAPPER(JS_TYPED_ARRAY_PROTOTYPE_TYPE
) INSTANCE_TYPE_WRAPPER(JS_MAP_KEY_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_MAP_KEY_VALUE_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_MAP_VALUE_ITERATOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_SET_KEY_VALUE_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_SET_VALUE_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_GENERATOR_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_ASYNC_FUNCTION_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ASYNC_GENERATOR_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_MAP_TYPE
) INSTANCE_TYPE_WRAPPER(JS_SET_TYPE) INSTANCE_TYPE_WRAPPER(JS_WEAK_MAP_TYPE
) INSTANCE_TYPE_WRAPPER(JS_WEAK_SET_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ARGUMENTS_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_ARRAY_TYPE
) INSTANCE_TYPE_WRAPPER(JS_ARRAY_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ASYNC_FROM_SYNC_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_COLLATOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_CONTEXT_EXTENSION_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_DATE_TYPE) INSTANCE_TYPE_WRAPPER(JS_DATE_TIME_FORMAT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_DISPLAY_NAMES_TYPE) INSTANCE_TYPE_WRAPPER
(JS_ERROR_TYPE) INSTANCE_TYPE_WRAPPER(JS_EXTERNAL_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_FINALIZATION_REGISTRY_TYPE) INSTANCE_TYPE_WRAPPER
(JS_LIST_FORMAT_TYPE) INSTANCE_TYPE_WRAPPER(JS_LOCALE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_MESSAGE_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(JS_NUMBER_FORMAT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_PLURAL_RULES_TYPE) INSTANCE_TYPE_WRAPPER
(JS_REG_EXP_TYPE) INSTANCE_TYPE_WRAPPER(JS_REG_EXP_STRING_ITERATOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_RELATIVE_TIME_FORMAT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_SEGMENT_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER(JS_SEGMENTER_TYPE
) INSTANCE_TYPE_WRAPPER(JS_SEGMENTS_TYPE) INSTANCE_TYPE_WRAPPER
(JS_SHADOW_REALM_TYPE) INSTANCE_TYPE_WRAPPER(JS_SHARED_STRUCT_TYPE
) INSTANCE_TYPE_WRAPPER(JS_STRING_ITERATOR_TYPE) INSTANCE_TYPE_WRAPPER
(JS_TEMPORAL_CALENDAR_TYPE) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_DURATION_TYPE
) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_INSTANT_TYPE) INSTANCE_TYPE_WRAPPER
(JS_TEMPORAL_PLAIN_DATE_TYPE) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_PLAIN_DATE_TIME_TYPE
) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_PLAIN_MONTH_DAY_TYPE) INSTANCE_TYPE_WRAPPER
(JS_TEMPORAL_PLAIN_TIME_TYPE) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_PLAIN_YEAR_MONTH_TYPE
) INSTANCE_TYPE_WRAPPER(JS_TEMPORAL_TIME_ZONE_TYPE) INSTANCE_TYPE_WRAPPER
(JS_TEMPORAL_ZONED_DATE_TIME_TYPE) INSTANCE_TYPE_WRAPPER(JS_V8_BREAK_ITERATOR_TYPE
) INSTANCE_TYPE_WRAPPER(JS_WEAK_REF_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_GLOBAL_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(WASM_INSTANCE_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_MEMORY_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_MODULE_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(WASM_SUSPENDER_OBJECT_TYPE
) INSTANCE_TYPE_WRAPPER(WASM_TABLE_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER
(WASM_TAG_OBJECT_TYPE) INSTANCE_TYPE_WRAPPER(WASM_VALUE_OBJECT_TYPE
)
;
318 VIRTUAL_INSTANCE_TYPE_LIST(VIRTUAL_INSTANCE_TYPE_WRAPPER)VIRTUAL_INSTANCE_TYPE_WRAPPER(BYTECODE_HANDLER) VIRTUAL_INSTANCE_TYPE_WRAPPER
(FOR_TESTING) VIRTUAL_INSTANCE_TYPE_WRAPPER(BUILTIN) VIRTUAL_INSTANCE_TYPE_WRAPPER
(REGEXP) VIRTUAL_INSTANCE_TYPE_WRAPPER(WASM_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER
(WASM_TO_CAPI_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER(WASM_TO_JS_FUNCTION
) VIRTUAL_INSTANCE_TYPE_WRAPPER(JS_TO_WASM_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER
(JS_TO_JS_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER(C_WASM_ENTRY
) VIRTUAL_INSTANCE_TYPE_WRAPPER(INTERPRETED_FUNCTION) VIRTUAL_INSTANCE_TYPE_WRAPPER
(BASELINE) VIRTUAL_INSTANCE_TYPE_WRAPPER(MAGLEV) VIRTUAL_INSTANCE_TYPE_WRAPPER
(TURBOFAN) VIRTUAL_INSTANCE_TYPE_WRAPPER(ARRAY_BOILERPLATE_DESCRIPTION_ELEMENTS_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(ARRAY_DICTIONARY_ELEMENTS_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(ARRAY_ELEMENTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(BOILERPLATE_ELEMENTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(BOILERPLATE_PROPERTY_ARRAY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(BOILERPLATE_PROPERTY_DICTIONARY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(BYTECODE_ARRAY_CONSTANT_POOL_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(BYTECODE_ARRAY_HANDLER_TABLE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(COW_ARRAY_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(DEOPTIMIZATION_DATA_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(DEPENDENT_CODE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(DEPRECATED_DESCRIPTOR_ARRAY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(EMBEDDED_OBJECT_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(ENUM_KEYS_CACHE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(ENUM_INDICES_CACHE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_ENTRY_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(FEEDBACK_VECTOR_HEADER_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_CALL_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_ENUM_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_LOAD_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_OTHER_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_STORE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(GLOBAL_ELEMENTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(GLOBAL_PROPERTIES_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(JS_ARRAY_BOILERPLATE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(JS_COLLECTION_TABLE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(JS_OBJECT_BOILERPLATE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(JS_UNCOMPILED_FUNCTION_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(MAP_ABANDONED_PROTOTYPE_TYPE)
VIRTUAL_INSTANCE_TYPE_WRAPPER(MAP_DEPRECATED_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(MAP_DICTIONARY_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(MAP_PROTOTYPE_DICTIONARY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(MAP_PROTOTYPE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(MAP_STABLE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(NUMBER_STRING_CACHE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(OBJECT_DICTIONARY_ELEMENTS_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(OBJECT_ELEMENTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(OBJECT_PROPERTY_ARRAY_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(OBJECT_PROPERTY_DICTIONARY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(OBJECT_TO_CODE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(OPTIMIZED_CODE_LITERALS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(
OTHER_CONTEXT_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(PROTOTYPE_DESCRIPTOR_ARRAY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(PROTOTYPE_PROPERTY_ARRAY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(PROTOTYPE_PROPERTY_DICTIONARY_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(PROTOTYPE_USERS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(REGEXP_MULTIPLE_CACHE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(RELOC_INFO_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(RETAINED_MAPS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(SCRIPT_LIST_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SHARED_FUNCTION_INFOS_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SERIALIZED_OBJECTS_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(SINGLE_CHARACTER_STRING_CACHE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(STRING_SPLIT_CACHE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER(STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE
) VIRTUAL_INSTANCE_TYPE_WRAPPER(SOURCE_POSITION_TABLE_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(UNCOMPILED_SHARED_FUNCTION_INFO_TYPE) VIRTUAL_INSTANCE_TYPE_WRAPPER
(WEAK_NEW_SPACE_OBJECT_TO_CODE_TYPE)
319 stream << "\"END\":{}}}";
320
321#undef INSTANCE_TYPE_WRAPPER
322#undef VIRTUAL_INSTANCE_TYPE_WRAPPER
323}
324
325void ObjectStats::CheckpointObjectStats() {
326 base::MutexGuard lock_guard(object_stats_mutex.Pointer());
327 MemCopy(object_counts_last_time_, object_counts_, sizeof(object_counts_));
328 MemCopy(object_sizes_last_time_, object_sizes_, sizeof(object_sizes_));
329 ClearObjectStats();
330}
331
332namespace {
333
334int Log2ForSize(size_t size) {
335 DCHECK_GT(size, 0)((void) 0);
336 return kSizetSize * 8 - 1 - base::bits::CountLeadingZeros(size);
337}
338
339} // namespace
340
341int ObjectStats::HistogramIndexFromSize(size_t size) {
342 if (size == 0) return 0;
343 return std::min({std::max(Log2ForSize(size) + 1 - kFirstBucketShift, 0),
344 kLastValueBucketIndex});
345}
346
347void ObjectStats::RecordObjectStats(InstanceType type, size_t size,
348 size_t over_allocated) {
349 DCHECK_LE(type, LAST_TYPE)((void) 0);
350 object_counts_[type]++;
351 object_sizes_[type] += size;
352 size_histogram_[type][HistogramIndexFromSize(size)]++;
353 over_allocated_[type] += over_allocated;
354 over_allocated_histogram_[type][HistogramIndexFromSize(size)]++;
355}
356
357void ObjectStats::RecordVirtualObjectStats(VirtualInstanceType type,
358 size_t size, size_t over_allocated) {
359 DCHECK_LE(type, LAST_VIRTUAL_TYPE)((void) 0);
360 object_counts_[FIRST_VIRTUAL_TYPE + type]++;
361 object_sizes_[FIRST_VIRTUAL_TYPE + type] += size;
362 size_histogram_[FIRST_VIRTUAL_TYPE + type][HistogramIndexFromSize(size)]++;
363 over_allocated_[FIRST_VIRTUAL_TYPE + type] += over_allocated;
364 over_allocated_histogram_[FIRST_VIRTUAL_TYPE + type]
365 [HistogramIndexFromSize(size)]++;
366}
367
368Isolate* ObjectStats::isolate() { return heap()->isolate(); }
369
370class ObjectStatsCollectorImpl {
371 public:
372 enum Phase {
373 kPhase1,
374 kPhase2,
375 };
376 static const int kNumberOfPhases = kPhase2 + 1;
377
378 ObjectStatsCollectorImpl(Heap* heap, ObjectStats* stats);
379
380 void CollectGlobalStatistics();
381
382 enum class CollectFieldStats { kNo, kYes };
383 void CollectStatistics(HeapObject obj, Phase phase,
384 CollectFieldStats collect_field_stats);
385
386 private:
387 enum CowMode {
388 kCheckCow,
389 kIgnoreCow,
390 };
391
392 Isolate* isolate() { return heap_->isolate(); }
393
394 bool RecordVirtualObjectStats(HeapObject parent, HeapObject obj,
395 ObjectStats::VirtualInstanceType type,
396 size_t size, size_t over_allocated,
397 CowMode check_cow_array = kCheckCow);
398 void RecordExternalResourceStats(Address resource,
399 ObjectStats::VirtualInstanceType type,
400 size_t size);
401 // Gets size from |ob| and assumes no over allocating.
402 bool RecordSimpleVirtualObjectStats(HeapObject parent, HeapObject obj,
403 ObjectStats::VirtualInstanceType type);
404 // For HashTable it is possible to compute over allocated memory.
405 template <typename Derived, typename Shape>
406 void RecordHashTableVirtualObjectStats(HeapObject parent,
407 HashTable<Derived, Shape> hash_table,
408 ObjectStats::VirtualInstanceType type);
409
410 bool SameLiveness(HeapObject obj1, HeapObject obj2);
411 bool CanRecordFixedArray(FixedArrayBase array);
412 bool IsCowArray(FixedArrayBase array);
413
414 // Blocklist for objects that should not be recorded using
415 // VirtualObjectStats and RecordSimpleVirtualObjectStats. For recording those
416 // objects dispatch to the low level ObjectStats::RecordObjectStats manually.
417 bool ShouldRecordObject(HeapObject object, CowMode check_cow_array);
418
419 void RecordObjectStats(
420 HeapObject obj, InstanceType type, size_t size,
421 size_t over_allocated = ObjectStats::kNoOverAllocation);
422
423 // Specific recursion into constant pool or embedded code objects. Records
424 // FixedArrays and Tuple2.
425 void RecordVirtualObjectsForConstantPoolOrEmbeddedObjects(
426 HeapObject parent, HeapObject object,
427 ObjectStats::VirtualInstanceType type);
428
429 // Details.
430 void RecordVirtualAllocationSiteDetails(AllocationSite site);
431 void RecordVirtualBytecodeArrayDetails(BytecodeArray bytecode);
432 void RecordVirtualCodeDetails(Code code);
433 void RecordVirtualContext(Context context);
434 void RecordVirtualFeedbackVectorDetails(FeedbackVector vector);
435 void RecordVirtualFixedArrayDetails(FixedArray array);
436 void RecordVirtualFunctionTemplateInfoDetails(FunctionTemplateInfo fti);
437 void RecordVirtualJSGlobalObjectDetails(JSGlobalObject object);
438 void RecordVirtualJSObjectDetails(JSObject object);
439 void RecordVirtualMapDetails(Map map);
440 void RecordVirtualScriptDetails(Script script);
441 void RecordVirtualExternalStringDetails(ExternalString script);
442 void RecordVirtualSharedFunctionInfoDetails(SharedFunctionInfo info);
443
444 void RecordVirtualArrayBoilerplateDescription(
445 ArrayBoilerplateDescription description);
446
447 PtrComprCageBase cage_base() const {
448 return field_stats_collector_.cage_base();
449 }
450
451 Heap* heap_;
452 ObjectStats* stats_;
453 MarkCompactCollector::NonAtomicMarkingState* marking_state_;
454 std::unordered_set<HeapObject, Object::Hasher> virtual_objects_;
455 std::unordered_set<Address> external_resources_;
456 FieldStatsCollector field_stats_collector_;
457};
458
459ObjectStatsCollectorImpl::ObjectStatsCollectorImpl(Heap* heap,
460 ObjectStats* stats)
461 : heap_(heap),
462 stats_(stats),
463 marking_state_(
464 heap->mark_compact_collector()->non_atomic_marking_state()),
465 field_stats_collector_(
466 heap_, &stats->tagged_fields_count_, &stats->embedder_fields_count_,
467 &stats->inobject_smi_fields_count_,
468 &stats->boxed_double_fields_count_, &stats->string_data_count_,
469 &stats->raw_fields_count_) {}
470
471bool ObjectStatsCollectorImpl::ShouldRecordObject(HeapObject obj,
472 CowMode check_cow_array) {
473 if (obj.IsFixedArrayExact()) {
474 FixedArray fixed_array = FixedArray::cast(obj);
475 bool cow_check = check_cow_array == kIgnoreCow || !IsCowArray(fixed_array);
476 return CanRecordFixedArray(fixed_array) && cow_check;
477 }
478 if (obj == ReadOnlyRoots(heap_).empty_property_array()) return false;
479 return true;
480}
481
482template <typename Derived, typename Shape>
483void ObjectStatsCollectorImpl::RecordHashTableVirtualObjectStats(
484 HeapObject parent, HashTable<Derived, Shape> hash_table,
485 ObjectStats::VirtualInstanceType type) {
486 size_t over_allocated =
487 (hash_table.Capacity() -
488 (hash_table.NumberOfElements() + hash_table.NumberOfDeletedElements())) *
489 HashTable<Derived, Shape>::kEntrySize * kTaggedSize;
490 RecordVirtualObjectStats(parent, hash_table, type, hash_table.Size(),
491 over_allocated);
492}
493
494bool ObjectStatsCollectorImpl::RecordSimpleVirtualObjectStats(
495 HeapObject parent, HeapObject obj, ObjectStats::VirtualInstanceType type) {
496 return RecordVirtualObjectStats(parent, obj, type, obj.Size(cage_base()),
497 ObjectStats::kNoOverAllocation, kCheckCow);
498}
499
500bool ObjectStatsCollectorImpl::RecordVirtualObjectStats(
501 HeapObject parent, HeapObject obj, ObjectStats::VirtualInstanceType type,
502 size_t size, size_t over_allocated, CowMode check_cow_array) {
503 CHECK_LT(over_allocated, size)do { bool _cmp = ::v8::base::CmpLTImpl< typename ::v8::base
::pass_value_or_ref<decltype(over_allocated)>::type, typename
::v8::base::pass_value_or_ref<decltype(size)>::type>
((over_allocated), (size)); do { if ((__builtin_expect(!!(!(_cmp
)), 0))) { V8_Fatal("Check failed: %s.", "over_allocated" " "
"<" " " "size"); } } while (false); } while (false)
;
504 if (!SameLiveness(parent, obj) || !ShouldRecordObject(obj, check_cow_array)) {
505 return false;
506 }
507
508 if (virtual_objects_.find(obj) == virtual_objects_.end()) {
509 virtual_objects_.insert(obj);
510 stats_->RecordVirtualObjectStats(type, size, over_allocated);
511 return true;
512 }
513 return false;
514}
515
516void ObjectStatsCollectorImpl::RecordExternalResourceStats(
517 Address resource, ObjectStats::VirtualInstanceType type, size_t size) {
518 if (external_resources_.find(resource) == external_resources_.end()) {
519 external_resources_.insert(resource);
520 stats_->RecordVirtualObjectStats(type, size, 0);
521 }
522}
523
524void ObjectStatsCollectorImpl::RecordVirtualAllocationSiteDetails(
525 AllocationSite site) {
526 if (!site.PointsToLiteral()) return;
527 JSObject boilerplate = site.boilerplate();
528 if (boilerplate.IsJSArray()) {
529 RecordSimpleVirtualObjectStats(site, boilerplate,
530 ObjectStats::JS_ARRAY_BOILERPLATE_TYPE);
531 // Array boilerplates cannot have properties.
532 } else {
533 RecordVirtualObjectStats(
534 site, boilerplate, ObjectStats::JS_OBJECT_BOILERPLATE_TYPE,
535 boilerplate.Size(), ObjectStats::kNoOverAllocation);
536 if (boilerplate.HasFastProperties()) {
537 // We'll mis-classify the empty_property_array here. Given that there is a
538 // single instance, this is negligible.
539 PropertyArray properties = boilerplate.property_array();
540 RecordSimpleVirtualObjectStats(
541 site, properties, ObjectStats::BOILERPLATE_PROPERTY_ARRAY_TYPE);
542 } else {
543 NameDictionary properties = boilerplate.property_dictionary();
544 RecordSimpleVirtualObjectStats(
545 site, properties, ObjectStats::BOILERPLATE_PROPERTY_DICTIONARY_TYPE);
546 }
547 }
548 FixedArrayBase elements = boilerplate.elements();
549 RecordSimpleVirtualObjectStats(site, elements,
550 ObjectStats::BOILERPLATE_ELEMENTS_TYPE);
551}
552
553void ObjectStatsCollectorImpl::RecordVirtualFunctionTemplateInfoDetails(
554 FunctionTemplateInfo fti) {
555 // named_property_handler and indexed_property_handler are recorded as
556 // INTERCEPTOR_INFO_TYPE.
557 HeapObject call_code = fti.call_code(kAcquireLoad);
558 if (!call_code.IsUndefined(isolate())) {
559 RecordSimpleVirtualObjectStats(
560 fti, CallHandlerInfo::cast(call_code),
561 ObjectStats::FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE);
562 }
563 if (!fti.GetInstanceCallHandler().IsUndefined(isolate())) {
564 RecordSimpleVirtualObjectStats(
565 fti, CallHandlerInfo::cast(fti.GetInstanceCallHandler()),
566 ObjectStats::FUNCTION_TEMPLATE_INFO_ENTRIES_TYPE);
567 }
568}
569
570void ObjectStatsCollectorImpl::RecordVirtualJSGlobalObjectDetails(
571 JSGlobalObject object) {
572 // Properties.
573 GlobalDictionary properties = object.global_dictionary(kAcquireLoad);
574 RecordHashTableVirtualObjectStats(object, properties,
575 ObjectStats::GLOBAL_PROPERTIES_TYPE);
576 // Elements.
577 FixedArrayBase elements = object.elements();
578 RecordSimpleVirtualObjectStats(object, elements,
579 ObjectStats::GLOBAL_ELEMENTS_TYPE);
580}
581
582void ObjectStatsCollectorImpl::RecordVirtualJSObjectDetails(JSObject object) {
583 // JSGlobalObject is recorded separately.
584 if (object.IsJSGlobalObject()) return;
585
586 // Uncompiled JSFunction has a separate type.
587 if (object.IsJSFunction() && !JSFunction::cast(object).is_compiled()) {
588 RecordSimpleVirtualObjectStats(HeapObject(), object,
589 ObjectStats::JS_UNCOMPILED_FUNCTION_TYPE);
590 }
591
592 // Properties.
593 if (object.HasFastProperties()) {
594 PropertyArray properties = object.property_array();
595 if (properties != ReadOnlyRoots(heap_).empty_property_array()) {
596 size_t over_allocated = object.map().UnusedPropertyFields() * kTaggedSize;
597 RecordVirtualObjectStats(object, properties,
598 object.map().is_prototype_map()
599 ? ObjectStats::PROTOTYPE_PROPERTY_ARRAY_TYPE
600 : ObjectStats::OBJECT_PROPERTY_ARRAY_TYPE,
601 properties.Size(), over_allocated);
602 }
603 } else {
604 NameDictionary properties = object.property_dictionary();
605 RecordHashTableVirtualObjectStats(
606 object, properties,
607 object.map().is_prototype_map()
608 ? ObjectStats::PROTOTYPE_PROPERTY_DICTIONARY_TYPE
609 : ObjectStats::OBJECT_PROPERTY_DICTIONARY_TYPE);
610 }
611
612 // Elements.
613 FixedArrayBase elements = object.elements();
614 if (object.HasDictionaryElements()) {
615 RecordHashTableVirtualObjectStats(
616 object, NumberDictionary::cast(elements),
617 object.IsJSArray() ? ObjectStats::ARRAY_DICTIONARY_ELEMENTS_TYPE
618 : ObjectStats::OBJECT_DICTIONARY_ELEMENTS_TYPE);
619 } else if (object.IsJSArray()) {
620 if (elements != ReadOnlyRoots(heap_).empty_fixed_array()) {
621 size_t element_size =
622 (elements.Size() - FixedArrayBase::kHeaderSize) / elements.length();
623 uint32_t length = JSArray::cast(object).length().Number();
624 size_t over_allocated = (elements.length() - length) * element_size;
625 RecordVirtualObjectStats(object, elements,
626 ObjectStats::ARRAY_ELEMENTS_TYPE,
627 elements.Size(), over_allocated);
628 }
629 } else {
630 RecordSimpleVirtualObjectStats(object, elements,
631 ObjectStats::OBJECT_ELEMENTS_TYPE);
632 }
633
634 // JSCollections.
635 if (object.IsJSCollection()) {
636 // TODO(bmeurer): Properly compute over-allocation here.
637 RecordSimpleVirtualObjectStats(
638 object, FixedArray::cast(JSCollection::cast(object).table()),
639 ObjectStats::JS_COLLECTION_TABLE_TYPE);
640 }
641}
642
643static ObjectStats::VirtualInstanceType GetFeedbackSlotType(
644 MaybeObject maybe_obj, FeedbackSlotKind kind, Isolate* isolate) {
645 if (maybe_obj->IsCleared())
646 return ObjectStats::FEEDBACK_VECTOR_SLOT_OTHER_TYPE;
647 Object obj = maybe_obj->GetHeapObjectOrSmi();
648 switch (kind) {
649 case FeedbackSlotKind::kCall:
650 if (obj == *isolate->factory()->uninitialized_symbol()) {
651 return ObjectStats::FEEDBACK_VECTOR_SLOT_CALL_UNUSED_TYPE;
652 }
653 return ObjectStats::FEEDBACK_VECTOR_SLOT_CALL_TYPE;
654
655 case FeedbackSlotKind::kLoadProperty:
656 case FeedbackSlotKind::kLoadGlobalInsideTypeof:
657 case FeedbackSlotKind::kLoadGlobalNotInsideTypeof:
658 case FeedbackSlotKind::kLoadKeyed:
659 case FeedbackSlotKind::kHasKeyed:
660 if (obj == *isolate->factory()->uninitialized_symbol()) {
661 return ObjectStats::FEEDBACK_VECTOR_SLOT_LOAD_UNUSED_TYPE;
662 }
663 return ObjectStats::FEEDBACK_VECTOR_SLOT_LOAD_TYPE;
664
665 case FeedbackSlotKind::kSetNamedSloppy:
666 case FeedbackSlotKind::kSetNamedStrict:
667 case FeedbackSlotKind::kDefineNamedOwn:
668 case FeedbackSlotKind::kStoreGlobalSloppy:
669 case FeedbackSlotKind::kStoreGlobalStrict:
670 case FeedbackSlotKind::kSetKeyedSloppy:
671 case FeedbackSlotKind::kSetKeyedStrict:
672 if (obj == *isolate->factory()->uninitialized_symbol()) {
673 return ObjectStats::FEEDBACK_VECTOR_SLOT_STORE_UNUSED_TYPE;
674 }
675 return ObjectStats::FEEDBACK_VECTOR_SLOT_STORE_TYPE;
676
677 case FeedbackSlotKind::kBinaryOp:
678 case FeedbackSlotKind::kCompareOp:
679 return ObjectStats::FEEDBACK_VECTOR_SLOT_ENUM_TYPE;
680
681 default:
682 return ObjectStats::FEEDBACK_VECTOR_SLOT_OTHER_TYPE;
683 }
684}
685
686void ObjectStatsCollectorImpl::RecordVirtualFeedbackVectorDetails(
687 FeedbackVector vector) {
688 if (virtual_objects_.find(vector) != virtual_objects_.end()) return;
689 // Manually insert the feedback vector into the virtual object list, since
690 // we're logging its component parts separately.
691 virtual_objects_.insert(vector);
692
693 size_t calculated_size = 0;
694
695 // Log the feedback vector's header (fixed fields).
696 size_t header_size = vector.slots_start().address() - vector.address();
697 stats_->RecordVirtualObjectStats(ObjectStats::FEEDBACK_VECTOR_HEADER_TYPE,
698 header_size, ObjectStats::kNoOverAllocation);
699 calculated_size += header_size;
700
701 // Iterate over the feedback slots and log each one.
702 if (!vector.shared_function_info().HasFeedbackMetadata()) return;
703
704 FeedbackMetadataIterator it(vector.metadata());
705 while (it.HasNext()) {
706 FeedbackSlot slot = it.Next();
707 // Log the entry (or entries) taken up by this slot.
708 size_t slot_size = it.entry_size() * kTaggedSize;
709 stats_->RecordVirtualObjectStats(
710 GetFeedbackSlotType(vector.Get(slot), it.kind(), heap_->isolate()),
711 slot_size, ObjectStats::kNoOverAllocation);
712 calculated_size += slot_size;
713
714 // Log the monomorphic/polymorphic helper objects that this slot owns.
715 for (int i = 0; i < it.entry_size(); i++) {
716 MaybeObject raw_object = vector.Get(slot.WithOffset(i));
717 HeapObject object;
718 if (raw_object->GetHeapObject(&object)) {
719 if (object.IsCell(cage_base()) ||
720 object.IsWeakFixedArray(cage_base())) {
721 RecordSimpleVirtualObjectStats(
722 vector, object, ObjectStats::FEEDBACK_VECTOR_ENTRY_TYPE);
723 }
724 }
725 }
726 }
727
728 CHECK_EQ(calculated_size, vector.Size())do { bool _cmp = ::v8::base::CmpEQImpl< typename ::v8::base
::pass_value_or_ref<decltype(calculated_size)>::type, typename
::v8::base::pass_value_or_ref<decltype(vector.Size())>
::type>((calculated_size), (vector.Size())); do { if ((__builtin_expect
(!!(!(_cmp)), 0))) { V8_Fatal("Check failed: %s.", "calculated_size"
" " "==" " " "vector.Size()"); } } while (false); } while (false
)
;
729}
730
731void ObjectStatsCollectorImpl::RecordVirtualFixedArrayDetails(
732 FixedArray array) {
733 if (IsCowArray(array)) {
734 RecordVirtualObjectStats(HeapObject(), array, ObjectStats::COW_ARRAY_TYPE,
735 array.Size(), ObjectStats::kNoOverAllocation,
736 kIgnoreCow);
737 }
738}
739
740void ObjectStatsCollectorImpl::CollectStatistics(
741 HeapObject obj, Phase phase, CollectFieldStats collect_field_stats) {
742 DisallowGarbageCollection no_gc;
743 Map map = obj.map(cage_base());
744 InstanceType instance_type = map.instance_type();
745 switch (phase) {
746 case kPhase1:
747 if (InstanceTypeChecker::IsFeedbackVector(instance_type)) {
748 RecordVirtualFeedbackVectorDetails(FeedbackVector::cast(obj));
749 } else if (InstanceTypeChecker::IsMap(instance_type)) {
750 RecordVirtualMapDetails(Map::cast(obj));
751 } else if (InstanceTypeChecker::IsBytecodeArray(instance_type)) {
752 RecordVirtualBytecodeArrayDetails(BytecodeArray::cast(obj));
753 } else if (InstanceTypeChecker::IsCode(instance_type)) {
754 RecordVirtualCodeDetails(Code::cast(obj));
755 } else if (InstanceTypeChecker::IsFunctionTemplateInfo(instance_type)) {
756 RecordVirtualFunctionTemplateInfoDetails(
757 FunctionTemplateInfo::cast(obj));
758 } else if (InstanceTypeChecker::IsJSGlobalObject(instance_type)) {
759 RecordVirtualJSGlobalObjectDetails(JSGlobalObject::cast(obj));
760 } else if (InstanceTypeChecker::IsJSObject(instance_type)) {
761 // This phase needs to come after RecordVirtualAllocationSiteDetails
762 // to properly split among boilerplates.
763 RecordVirtualJSObjectDetails(JSObject::cast(obj));
764 } else if (InstanceTypeChecker::IsSharedFunctionInfo(instance_type)) {
765 RecordVirtualSharedFunctionInfoDetails(SharedFunctionInfo::cast(obj));
766 } else if (InstanceTypeChecker::IsContext(instance_type)) {
767 RecordVirtualContext(Context::cast(obj));
768 } else if (InstanceTypeChecker::IsScript(instance_type)) {
769 RecordVirtualScriptDetails(Script::cast(obj));
770 } else if (InstanceTypeChecker::IsArrayBoilerplateDescription(
771 instance_type)) {
772 RecordVirtualArrayBoilerplateDescription(
773 ArrayBoilerplateDescription::cast(obj));
774 } else if (InstanceTypeChecker::IsFixedArrayExact(instance_type)) {
775 // Has to go last as it triggers too eagerly.
776 RecordVirtualFixedArrayDetails(FixedArray::cast(obj));
777 }
778 break;
779 case kPhase2:
780 if (InstanceTypeChecker::IsExternalString(instance_type)) {
781 // This has to be in Phase2 to avoid conflicting with recording Script
782 // sources. We still want to run RecordObjectStats after though.
783 RecordVirtualExternalStringDetails(ExternalString::cast(obj));
784 }
785 size_t over_allocated = ObjectStats::kNoOverAllocation;
786 if (InstanceTypeChecker::IsJSObject(instance_type)) {
787 over_allocated = map.instance_size() - map.UsedInstanceSize();
788 }
789 RecordObjectStats(obj, instance_type, obj.Size(cage_base()),
790 over_allocated);
791 if (collect_field_stats == CollectFieldStats::kYes) {
792 field_stats_collector_.RecordStats(obj);
793 }
794 break;
795 }
796}
797
798void ObjectStatsCollectorImpl::CollectGlobalStatistics() {
799 // Iterate boilerplates first to disambiguate them from regular JS objects.
800 Object list = heap_->allocation_sites_list();
801 while (list.IsAllocationSite(cage_base())) {
802 AllocationSite site = AllocationSite::cast(list);
803 RecordVirtualAllocationSiteDetails(site);
804 list = site.weak_next();
805 }
806
807 // FixedArray.
808 RecordSimpleVirtualObjectStats(HeapObject(), heap_->serialized_objects(),
809 ObjectStats::SERIALIZED_OBJECTS_TYPE);
810 RecordSimpleVirtualObjectStats(HeapObject(), heap_->number_string_cache(),
811 ObjectStats::NUMBER_STRING_CACHE_TYPE);
812 RecordSimpleVirtualObjectStats(
813 HeapObject(), heap_->single_character_string_cache(),
814 ObjectStats::SINGLE_CHARACTER_STRING_CACHE_TYPE);
815 RecordSimpleVirtualObjectStats(HeapObject(), heap_->string_split_cache(),
816 ObjectStats::STRING_SPLIT_CACHE_TYPE);
817 RecordSimpleVirtualObjectStats(HeapObject(), heap_->regexp_multiple_cache(),
818 ObjectStats::REGEXP_MULTIPLE_CACHE_TYPE);
819
820 // WeakArrayList.
821 RecordSimpleVirtualObjectStats(HeapObject(),
822 WeakArrayList::cast(heap_->script_list()),
823 ObjectStats::SCRIPT_LIST_TYPE);
824}
825
826void ObjectStatsCollectorImpl::RecordObjectStats(HeapObject obj,
827 InstanceType type, size_t size,
828 size_t over_allocated) {
829 if (virtual_objects_.find(obj) == virtual_objects_.end()) {
830 stats_->RecordObjectStats(type, size, over_allocated);
831 }
832}
833
834bool ObjectStatsCollectorImpl::CanRecordFixedArray(FixedArrayBase array) {
835 ReadOnlyRoots roots(heap_);
836 return array != roots.empty_fixed_array() &&
837 array != roots.empty_slow_element_dictionary() &&
838 array != roots.empty_property_dictionary();
839}
840
841bool ObjectStatsCollectorImpl::IsCowArray(FixedArrayBase array) {
842 return array.map(cage_base()) == ReadOnlyRoots(heap_).fixed_cow_array_map();
843}
844
845bool ObjectStatsCollectorImpl::SameLiveness(HeapObject obj1, HeapObject obj2) {
846 return obj1.is_null() || obj2.is_null() ||
847 marking_state_->Color(obj1) == marking_state_->Color(obj2);
848}
849
850void ObjectStatsCollectorImpl::RecordVirtualMapDetails(Map map) {
851 // TODO(mlippautz): map->dependent_code(): DEPENDENT_CODE_TYPE.
852
853 // For Map we want to distinguish between various different states
854 // to get a better picture of what's going on in MapSpace. This
855 // method computes the virtual instance type to use for a given map,
856 // using MAP_TYPE for regular maps that aren't special in any way.
857 if (map.is_prototype_map()) {
858 if (map.is_dictionary_map()) {
859 RecordSimpleVirtualObjectStats(
860 HeapObject(), map, ObjectStats::MAP_PROTOTYPE_DICTIONARY_TYPE);
861 } else if (map.is_abandoned_prototype_map()) {
862 RecordSimpleVirtualObjectStats(HeapObject(), map,
863 ObjectStats::MAP_ABANDONED_PROTOTYPE_TYPE);
864 } else {
865 RecordSimpleVirtualObjectStats(HeapObject(), map,
866 ObjectStats::MAP_PROTOTYPE_TYPE);
867 }
868 } else if (map.is_deprecated()) {
869 RecordSimpleVirtualObjectStats(HeapObject(), map,
870 ObjectStats::MAP_DEPRECATED_TYPE);
871 } else if (map.is_dictionary_map()) {
872 RecordSimpleVirtualObjectStats(HeapObject(), map,
873 ObjectStats::MAP_DICTIONARY_TYPE);
874 } else if (map.is_stable()) {
875 RecordSimpleVirtualObjectStats(HeapObject(), map,
876 ObjectStats::MAP_STABLE_TYPE);
877 } else {
878 // This will be logged as MAP_TYPE in Phase2.
879 }
880
881 DescriptorArray array = map.instance_descriptors(cage_base());
882 if (map.owns_descriptors() &&
883 array != ReadOnlyRoots(heap_).empty_descriptor_array()) {
884 // Generally DescriptorArrays have their own instance type already
885 // (DESCRIPTOR_ARRAY_TYPE), but we'd like to be able to tell which
886 // of those are for (abandoned) prototypes, and which of those are
887 // owned by deprecated maps.
888 if (map.is_prototype_map()) {
889 RecordSimpleVirtualObjectStats(
890 map, array, ObjectStats::PROTOTYPE_DESCRIPTOR_ARRAY_TYPE);
891 } else if (map.is_deprecated()) {
892 RecordSimpleVirtualObjectStats(
893 map, array, ObjectStats::DEPRECATED_DESCRIPTOR_ARRAY_TYPE);
894 }
895
896 EnumCache enum_cache = array.enum_cache();
897 RecordSimpleVirtualObjectStats(array, enum_cache.keys(),
898 ObjectStats::ENUM_KEYS_CACHE_TYPE);
899 RecordSimpleVirtualObjectStats(array, enum_cache.indices(),
900 ObjectStats::ENUM_INDICES_CACHE_TYPE);
901 }
902
903 if (map.is_prototype_map()) {
904 if (map.prototype_info().IsPrototypeInfo(cage_base())) {
905 PrototypeInfo info = PrototypeInfo::cast(map.prototype_info());
906 Object users = info.prototype_users();
907 if (users.IsWeakFixedArray(cage_base())) {
908 RecordSimpleVirtualObjectStats(map, WeakArrayList::cast(users),
909 ObjectStats::PROTOTYPE_USERS_TYPE);
910 }
911 }
912 }
913}
914
915void ObjectStatsCollectorImpl::RecordVirtualScriptDetails(Script script) {
916 RecordSimpleVirtualObjectStats(
917 script, script.shared_function_infos(),
918 ObjectStats::SCRIPT_SHARED_FUNCTION_INFOS_TYPE);
919
920 // Log the size of external source code.
921 Object raw_source = script.source();
922 if (raw_source.IsExternalString(cage_base())) {
923 // The contents of external strings aren't on the heap, so we have to record
924 // them manually. The on-heap String object is recorded indepentendely in
925 // the normal pass.
926 ExternalString string = ExternalString::cast(raw_source);
927 Address resource = string.resource_as_address();
928 size_t off_heap_size = string.ExternalPayloadSize();
929 RecordExternalResourceStats(
930 resource,
931 string.IsOneByteRepresentation()
932 ? ObjectStats::SCRIPT_SOURCE_EXTERNAL_ONE_BYTE_TYPE
933 : ObjectStats::SCRIPT_SOURCE_EXTERNAL_TWO_BYTE_TYPE,
934 off_heap_size);
935 } else if (raw_source.IsString(cage_base())) {
936 String source = String::cast(raw_source);
937 RecordSimpleVirtualObjectStats(
938 script, source,
939 source.IsOneByteRepresentation()
940 ? ObjectStats::SCRIPT_SOURCE_NON_EXTERNAL_ONE_BYTE_TYPE
941 : ObjectStats::SCRIPT_SOURCE_NON_EXTERNAL_TWO_BYTE_TYPE);
942 }
943}
944
945void ObjectStatsCollectorImpl::RecordVirtualExternalStringDetails(
946 ExternalString string) {
947 // Track the external string resource size in a separate category.
948
949 Address resource = string.resource_as_address();
950 size_t off_heap_size = string.ExternalPayloadSize();
951 RecordExternalResourceStats(
952 resource,
953 string.IsOneByteRepresentation(cage_base())
954 ? ObjectStats::STRING_EXTERNAL_RESOURCE_ONE_BYTE_TYPE
955 : ObjectStats::STRING_EXTERNAL_RESOURCE_TWO_BYTE_TYPE,
956 off_heap_size);
957}
958
959void ObjectStatsCollectorImpl::RecordVirtualSharedFunctionInfoDetails(
960 SharedFunctionInfo info) {
961 // Uncompiled SharedFunctionInfo gets its own category.
962 if (!info.is_compiled()) {
963 RecordSimpleVirtualObjectStats(
964 HeapObject(), info, ObjectStats::UNCOMPILED_SHARED_FUNCTION_INFO_TYPE);
965 }
966}
967
968void ObjectStatsCollectorImpl::RecordVirtualArrayBoilerplateDescription(
969 ArrayBoilerplateDescription description) {
970 RecordVirtualObjectsForConstantPoolOrEmbeddedObjects(
971 description, description.constant_elements(),
972 ObjectStats::ARRAY_BOILERPLATE_DESCRIPTION_ELEMENTS_TYPE);
973}
974
975void ObjectStatsCollectorImpl::
976 RecordVirtualObjectsForConstantPoolOrEmbeddedObjects(
977 HeapObject parent, HeapObject object,
978 ObjectStats::VirtualInstanceType type) {
979 if (!RecordSimpleVirtualObjectStats(parent, object, type)) return;
980 if (object.IsFixedArrayExact(cage_base())) {
981 FixedArray array = FixedArray::cast(object);
982 for (int i = 0; i < array.length(); i++) {
983 Object entry = array.get(i);
984 if (!entry.IsHeapObject()) continue;
985 RecordVirtualObjectsForConstantPoolOrEmbeddedObjects(
986 array, HeapObject::cast(entry), type);
987 }
988 }
989}
990
991void ObjectStatsCollectorImpl::RecordVirtualBytecodeArrayDetails(
992 BytecodeArray bytecode) {
993 RecordSimpleVirtualObjectStats(
994 bytecode, bytecode.constant_pool(),
995 ObjectStats::BYTECODE_ARRAY_CONSTANT_POOL_TYPE);
996 // FixedArrays on constant pool are used for holding descriptor information.
997 // They are shared with optimized code.
998 FixedArray constant_pool = FixedArray::cast(bytecode.constant_pool());
999 for (int i = 0; i < constant_pool.length(); i++) {
1000 Object entry = constant_pool.get(i);
1001 if (entry.IsFixedArrayExact(cage_base())) {
1002 RecordVirtualObjectsForConstantPoolOrEmbeddedObjects(
1003 constant_pool, HeapObject::cast(entry),
1004 ObjectStats::EMBEDDED_OBJECT_TYPE);
1005 }
1006 }
1007 RecordSimpleVirtualObjectStats(
1008 bytecode, bytecode.handler_table(),
1009 ObjectStats::BYTECODE_ARRAY_HANDLER_TABLE_TYPE);
1010 if (bytecode.HasSourcePositionTable()) {
1011 RecordSimpleVirtualObjectStats(bytecode, bytecode.SourcePositionTable(),
1012 ObjectStats::SOURCE_POSITION_TABLE_TYPE);
1013 }
1014}
1015
1016namespace {
1017
1018ObjectStats::VirtualInstanceType CodeKindToVirtualInstanceType(CodeKind kind) {
1019 switch (kind) {
1020#define CODE_KIND_CASE(type) \
1021 case CodeKind::type: \
1022 return ObjectStats::type;
1023 CODE_KIND_LIST(CODE_KIND_CASE)CODE_KIND_CASE(BYTECODE_HANDLER) CODE_KIND_CASE(FOR_TESTING) CODE_KIND_CASE
(BUILTIN) CODE_KIND_CASE(REGEXP) CODE_KIND_CASE(WASM_FUNCTION
) CODE_KIND_CASE(WASM_TO_CAPI_FUNCTION) CODE_KIND_CASE(WASM_TO_JS_FUNCTION
) CODE_KIND_CASE(JS_TO_WASM_FUNCTION) CODE_KIND_CASE(JS_TO_JS_FUNCTION
) CODE_KIND_CASE(C_WASM_ENTRY) CODE_KIND_CASE(INTERPRETED_FUNCTION
) CODE_KIND_CASE(BASELINE) CODE_KIND_CASE(MAGLEV) CODE_KIND_CASE
(TURBOFAN)
1024#undef CODE_KIND_CASE
1025 }
1026 UNREACHABLE()V8_Fatal("unreachable code");
1027}
1028
1029} // namespace
1030
1031void ObjectStatsCollectorImpl::RecordVirtualCodeDetails(Code code) {
1032 RecordSimpleVirtualObjectStats(HeapObject(), code,
1033 CodeKindToVirtualInstanceType(code.kind()));
1034 RecordSimpleVirtualObjectStats(code, code.relocation_info(),
1035 ObjectStats::RELOC_INFO_TYPE);
1036 if (CodeKindIsOptimizedJSFunction(code.kind())) {
1037 Object source_position_table = code.source_position_table();
1038 if (source_position_table.IsHeapObject()) {
1039 RecordSimpleVirtualObjectStats(code,
1040 HeapObject::cast(source_position_table),
1041 ObjectStats::SOURCE_POSITION_TABLE_TYPE);
1042 }
1043 RecordSimpleVirtualObjectStats(code, code.deoptimization_data(),
1044 ObjectStats::DEOPTIMIZATION_DATA_TYPE);
1045 DeoptimizationData input_data =
1046 DeoptimizationData::cast(code.deoptimization_data());
1047 if (input_data.length() > 0) {
1048 RecordSimpleVirtualObjectStats(code.deoptimization_data(),
1049 input_data.LiteralArray(),
1050 ObjectStats::OPTIMIZED_CODE_LITERALS_TYPE);
1051 }
1052 }
1053 int const mode_mask = RelocInfo::EmbeddedObjectModeMask();
1054 for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
1055 DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode()))((void) 0);
1056 Object target = it.rinfo()->target_object(cage_base());
1057 if (target.IsFixedArrayExact(cage_base())) {
1058 RecordVirtualObjectsForConstantPoolOrEmbeddedObjects(
1059 code, HeapObject::cast(target), ObjectStats::EMBEDDED_OBJECT_TYPE);
1060 }
1061 }
1062}
1063
1064void ObjectStatsCollectorImpl::RecordVirtualContext(Context context) {
1065 if (context.IsNativeContext()) {
1066 RecordObjectStats(context, NATIVE_CONTEXT_TYPE, context.Size());
1067 if (context.retained_maps().IsWeakArrayList(cage_base())) {
1068 RecordSimpleVirtualObjectStats(
1069 context, WeakArrayList::cast(context.retained_maps()),
1070 ObjectStats::RETAINED_MAPS_TYPE);
1071 }
1072
1073 } else if (context.IsFunctionContext()) {
1074 RecordObjectStats(context, FUNCTION_CONTEXT_TYPE, context.Size());
1075 } else {
1076 RecordSimpleVirtualObjectStats(HeapObject(), context,
1077 ObjectStats::OTHER_CONTEXT_TYPE);
1078 }
1079}
1080
1081class ObjectStatsVisitor {
1082 public:
1083 ObjectStatsVisitor(Heap* heap, ObjectStatsCollectorImpl* live_collector,
1084 ObjectStatsCollectorImpl* dead_collector,
1085 ObjectStatsCollectorImpl::Phase phase)
1086 : live_collector_(live_collector),
1087 dead_collector_(dead_collector),
1088 marking_state_(
1089 heap->mark_compact_collector()->non_atomic_marking_state()),
1090 phase_(phase) {}
1091
1092 void Visit(HeapObject obj) {
1093 if (marking_state_->IsBlack(obj)) {
1094 live_collector_->CollectStatistics(
1095 obj, phase_, ObjectStatsCollectorImpl::CollectFieldStats::kYes);
1096 } else {
1097 DCHECK(!marking_state_->IsGrey(obj))((void) 0);
1098 dead_collector_->CollectStatistics(
1099 obj, phase_, ObjectStatsCollectorImpl::CollectFieldStats::kNo);
1100 }
1101 }
1102
1103 private:
1104 ObjectStatsCollectorImpl* live_collector_;
1105 ObjectStatsCollectorImpl* dead_collector_;
1106 MarkCompactCollector::NonAtomicMarkingState* marking_state_;
1107 ObjectStatsCollectorImpl::Phase phase_;
1108};
1109
1110namespace {
1111
1112void IterateHeap(Heap* heap, ObjectStatsVisitor* visitor) {
1113 // We don't perform a GC while collecting object stats but need this scope for
1114 // the nested SafepointScope inside CombinedHeapObjectIterator.
1115 AllowGarbageCollection allow_gc;
1116 CombinedHeapObjectIterator iterator(heap);
1117 for (HeapObject obj = iterator.Next(); !obj.is_null();
1118 obj = iterator.Next()) {
1119 visitor->Visit(obj);
1120 }
1121}
1122
1123} // namespace
1124
1125void ObjectStatsCollector::Collect() {
1126 ObjectStatsCollectorImpl live_collector(heap_, live_);
1127 ObjectStatsCollectorImpl dead_collector(heap_, dead_);
1128 live_collector.CollectGlobalStatistics();
1129 for (int i = 0; i < ObjectStatsCollectorImpl::kNumberOfPhases; i++) {
1130 ObjectStatsVisitor visitor(heap_, &live_collector, &dead_collector,
1131 static_cast<ObjectStatsCollectorImpl::Phase>(i));
1132 IterateHeap(heap_, &visitor);
1133 }
1134}
1135
1136} // namespace internal
1137} // namespace v8