v8
V8 is Google’s open source high-performance JavaScript and WebAssembly engine, written in C++.
Loading...
Searching...
No Matches
external-reference-table.cc
Go to the documentation of this file.
1// Copyright 2016 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
6
10#include "src/ic/stub-cache.h"
12
13#if defined(DEBUG) && defined(V8_OS_LINUX) && !defined(V8_OS_ANDROID)
14#define SYMBOLIZE_FUNCTION
15#include <execinfo.h>
16
17#include <vector>
18
20#endif // DEBUG && V8_OS_LINUX && !V8_OS_ANDROID
21
22namespace v8 {
23namespace internal {
24
25#define ADD_EXT_REF_NAME(name, desc) desc,
26#define ADD_BUILTIN_NAME(Name, ...) "Builtin_" #Name,
27#define ADD_RUNTIME_FUNCTION(name, ...) "Runtime::" #name,
28#define ADD_ISOLATE_ADDR(Name, name) "Isolate::" #name "_address",
29#define ADD_ACCESSOR_INFO_NAME(_, __, AccessorName, ...) \
30 "Accessors::" #AccessorName "Getter",
31#define ADD_ACCESSOR_GETTER_NAME(name) "Accessors::" #name,
32#define ADD_ACCESSOR_SETTER_NAME(name) "Accessors::" #name,
33#define ADD_ACCESSOR_CALLBACK_NAME(_, name, ...) "Accessors::" #name,
34#define ADD_STATS_COUNTER_NAME(name, ...) "StatsCounter::" #name,
35// static
36// clang-format off
37const char* const
39 // === Isolate independent ===
40 // Special references:
41 "nullptr",
42 // External references (without isolate):
44 // Builtins:
46 // Runtime functions:
48 // Accessors:
53 /* not used */)
54
55 // === Isolate dependent ===
56 // External references (with isolate):
58 // Isolate addresses:
60 // Stub cache:
61 "Load StubCache::primary_->key",
62 "Load StubCache::primary_->value",
63 "Load StubCache::primary_->map",
64 "Load StubCache::secondary_->key",
65 "Load StubCache::secondary_->value",
66 "Load StubCache::secondary_->map",
67 "Store StubCache::primary_->key",
68 "Store StubCache::primary_->value",
69 "Store StubCache::primary_->map",
70 "Store StubCache::secondary_->key",
71 "Store StubCache::secondary_->value",
72 "Store StubCache::secondary_->map",
73 // Native code counters:
75};
76// clang-format on
77#undef ADD_EXT_REF_NAME
78#undef ADD_BUILTIN_NAME
79#undef ADD_RUNTIME_FUNCTION
80#undef ADD_ISOLATE_ADDR
81#undef ADD_ACCESSOR_INFO_NAME
82#undef ADD_ACCESSOR_SETTER_NAME
83#undef ADD_ACCESSOR_CALLBACK_NAME
84#undef ADD_STATS_COUNTER_NAME
85
86// Forward declarations for C++ builtins.
87#define FORWARD_DECLARE(Name, Argc) \
88 Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
90#undef FORWARD_DECLARE
91
93 MemorySpan<Address> shared_external_references) {
95
96 int index = 0;
97 CopyIsolateIndependentReferences(&index, shared_external_references);
99
101}
102
105
106 int index = kSizeIsolateIndependent;
107 AddIsolateDependentReferences(isolate, &index);
108 AddIsolateAddresses(isolate, &index);
109 AddStubCache(isolate, &index);
110 AddNativeCodeStatsCounters(isolate, &index);
111 CHECK_EQ(kSize, index);
112
114}
115
116const char* ExternalReferenceTable::ResolveSymbol(void* address) {
117#ifdef SYMBOLIZE_FUNCTION
118 char** names = backtrace_symbols(&address, 1);
119 const char* name = names[0];
120 // The array of names is malloc'ed. However, each name string is static
121 // and do not need to be freed.
122 base::Free(names);
123 return name;
124#else
125 return "<unresolved>";
126#endif // SYMBOLIZE_FUNCTION
127}
128
129// static
131 MemorySpan<Address> shared_external_references) {
132 int index = 0;
133
134 // kNullAddress is preserved through serialization/deserialization.
135 AddIsolateIndependent(kNullAddress, &index, shared_external_references);
136 AddIsolateIndependentReferences(&index, shared_external_references);
137 AddBuiltins(&index, shared_external_references);
138 AddRuntimeFunctions(&index, shared_external_references);
139 AddAccessors(&index, shared_external_references);
140
142}
143
144// static
146 Address address, MemorySpan<Address> shared_external_references) {
147 for (int i = 0; i < kSizeIsolateIndependent; i++) {
148 if (shared_external_references[i] == address) {
149 return ref_name_[i];
150 }
151 }
152 return "<unknown>";
153}
154
155void ExternalReferenceTable::Add(Address address, int* index) {
156 ref_addr_[(*index)++] = address;
157}
158
159// static
161 Address address, int* index,
162 MemorySpan<Address> shared_external_references) {
163 shared_external_references[(*index)++] = address;
164}
165
166// static
168 int* index, MemorySpan<Address> shared_external_references) {
170
171#define ADD_EXTERNAL_REFERENCE(name, desc) \
172 AddIsolateIndependent(ExternalReference::name().address(), index, \
173 shared_external_references);
175#undef ADD_EXTERNAL_REFERENCE
176
178 *index);
179}
180
182 int* index) {
184
185#define ADD_EXTERNAL_REFERENCE(name, desc) \
186 Add(ExternalReference::name(isolate).address(), index);
188#undef ADD_EXTERNAL_REFERENCE
189
191 *index);
192}
193
194// static
196 int* index, MemorySpan<Address> shared_external_references) {
198 *index);
199
200 static const Address c_builtins[] = {
201#define DEF_ENTRY(Name, ...) FUNCTION_ADDR(&Builtin_##Name),
203#undef DEF_ENTRY
204 };
205 for (Address addr : c_builtins) {
207 shared_external_references);
208 }
209
212 *index);
213}
214
215// static
217 int* index, MemorySpan<Address> shared_external_references) {
220 *index);
221
222 static constexpr Runtime::FunctionId runtime_functions[] = {
223#define RUNTIME_ENTRY(name, ...) Runtime::k##name,
225#undef RUNTIME_ENTRY
226 };
227
228 for (Runtime::FunctionId fId : runtime_functions) {
230 shared_external_references);
231 }
232
235 *index);
236}
237
239 int* index, MemorySpan<Address> shared_external_references) {
240 CHECK_EQ(0, *index);
241
242 DCHECK_GE(shared_external_references.size(), kSizeIsolateIndependent);
243 std::copy(shared_external_references.data(),
244 shared_external_references.data() + kSizeIsolateIndependent,
245 ref_addr_);
246 *index += kSizeIsolateIndependent;
247}
248
251 *index);
252
253 for (int i = 0; i < IsolateAddressId::kIsolateAddressCount; ++i) {
254 Add(isolate->get_address_from_id(static_cast<IsolateAddressId>(i)), index);
255 }
256
259 *index);
260}
261
262// static
264 int* index, MemorySpan<Address> shared_external_references) {
267 *index);
268
269#define ACCESSOR_INFO_DECLARATION(_, __, AccessorName, ...) \
270 FUNCTION_ADDR(&Accessors::AccessorName##Getter),
271#define ACCESSOR_GETTER_DECLARATION(name) FUNCTION_ADDR(&Accessors::name),
272#define ACCESSOR_SETTER_DECLARATION(name) FUNCTION_ADDR(&Accessors::name),
273#define ACCESSOR_CALLBACK_DECLARATION(_, AccessorName, ...) \
274 FUNCTION_ADDR(&Accessors::AccessorName),
275
276 static const Address accessors[] = {
277 // Getters:
279 // More getters:
281 // Setters:
283 // Callbacks:
285 /* not used */)};
286#undef ACCESSOR_INFO_DECLARATION
287#undef ACCESSOR_GETTER_DECLARATION
288#undef ACCESSOR_SETTER_DECLARATION
289#undef ACCESSOR_CALLBACK_DECLARATION
290
291 for (Address addr : accessors) {
292 AddIsolateIndependent(addr, index, shared_external_references);
293 }
294
298 *index);
299}
300
304 *index);
305
306 // Stub cache tables
307 std::array<StubCache*, 3> stub_caches{isolate->load_stub_cache(),
308 isolate->store_stub_cache(),
309 isolate->define_own_stub_cache()};
310
311 for (StubCache* stub_cache : stub_caches) {
312 Add(stub_cache->key_reference(StubCache::kPrimary).address(), index);
313 Add(stub_cache->value_reference(StubCache::kPrimary).address(), index);
314 Add(stub_cache->map_reference(StubCache::kPrimary).address(), index);
315 Add(stub_cache->key_reference(StubCache::kSecondary).address(), index);
316 Add(stub_cache->value_reference(StubCache::kSecondary).address(), index);
317 Add(stub_cache->map_reference(StubCache::kSecondary).address(), index);
318 }
319
322 *index);
323}
324
326 if (!counter->Enabled()) {
327 return reinterpret_cast<Address>(&dummy_stats_counter_);
328 }
329 std::atomic<int>* address = counter->GetInternalPointer();
330 static_assert(sizeof(address) == sizeof(Address));
331 return reinterpret_cast<Address>(address);
332}
333
335 int* index) {
338 *index);
339
340 Counters* counters = isolate->counters();
341
342#define SC(name, caption) Add(GetStatsCounterAddress(counters->name()), index);
344#undef SC
345
349 *index);
350 CHECK_EQ(kSize, *index);
351}
352
353} // namespace internal
354} // namespace v8
355
356#undef SYMBOLIZE_FUNCTION
#define ACCESSOR_GETTER_DECLARATION(_, accessor_name, AccessorName,...)
Definition accessors.h:68
#define ACCESSOR_CALLBACK_LIST_GENERATOR(V, _)
Definition accessors.h:60
#define ACCESSOR_SETTER_LIST(V)
Definition accessors.h:54
#define ACCESSOR_GETTER_LIST(V)
Definition accessors.h:52
#define ACCESSOR_SETTER_DECLARATION(AccessorName)
Definition accessors.h:81
#define ACCESSOR_INFO_DECLARATION(_, accessor_name, AccessorName,...)
Definition accessors.h:146
#define ACCESSOR_INFO_LIST_GENERATOR(V, _)
Definition accessors.h:25
#define ACCESSOR_CALLBACK_DECLARATION(_, AccessorName,...)
Definition accessors.h:88
#define BUILTIN_LIST_C(V)
#define FORWARD_DECLARE(Name, Argc)
Definition builtins.cc:30
constexpr T * data() const
constexpr size_t size() const
static constexpr int kExternalReferenceCountIsolateDependent
static void AddIsolateIndependent(Address address, int *index, MemorySpan< Address > shared_external_references)
Address GetStatsCounterAddress(StatsCounter *counter)
static void AddRuntimeFunctions(int *index, MemorySpan< Address > shared_external_references)
static void InitializeOncePerIsolateGroup(MemorySpan< Address > shared_external_references)
static void AddBuiltins(int *index, MemorySpan< Address > shared_external_references)
void AddStubCache(Isolate *isolate, int *index)
void Add(Address address, int *index)
static constexpr int kExternalReferenceCountIsolateIndependent
void InitIsolateIndependent(MemorySpan< Address > shared_external_references)
void AddIsolateDependentReferences(Isolate *isolate, int *index)
static const char * ResolveSymbol(void *address)
static void AddIsolateIndependentReferences(int *index, MemorySpan< Address > shared_external_references)
static void AddAccessors(int *index, MemorySpan< Address > shared_external_references)
static const char *const ref_name_[kSize]
static const char * NameOfIsolateIndependentAddress(Address address, MemorySpan< Address > shared_external_references)
void AddNativeCodeStatsCounters(Isolate *isolate, int *index)
void AddIsolateAddresses(Isolate *isolate, int *index)
void CopyIsolateIndependentReferences(int *index, MemorySpan< Address > shared_external_references)
static ExternalReference Create(const SCTableReference &table_ref)
V8_EXPORT_PRIVATE bool Enabled()
Definition counters.cc:32
std::atomic< int > * GetInternalPointer()
Definition counters.h:120
#define FOR_EACH_ISOLATE_ADDRESS_NAME(C)
Definition globals.h:2626
#define STATS_COUNTER_NATIVE_CODE_LIST(SC)
#define RUNTIME_ENTRY(name,...)
#define ADD_EXTERNAL_REFERENCE(name, desc)
#define ADD_ACCESSOR_GETTER_NAME(name)
#define ADD_BUILTIN_NAME(Name,...)
#define ADD_ACCESSOR_INFO_NAME(_, __, AccessorName,...)
#define DEF_ENTRY(Name,...)
#define ADD_ACCESSOR_CALLBACK_NAME(_, name,...)
#define ADD_STATS_COUNTER_NAME(name,...)
#define ADD_ISOLATE_ADDR(Name, name)
#define ADD_RUNTIME_FUNCTION(name,...)
#define ADD_EXT_REF_NAME(name, desc)
#define ADD_ACCESSOR_SETTER_NAME(name)
#define EXTERNAL_REFERENCE_LIST(V)
#define EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(V)
void Free(void *memory)
Definition memory.h:63
too high values may cause the compiler to set high thresholds for inlining to as much as possible avoid inlined allocation of objects that cannot escape trace load stores from virtual maglev objects use TurboFan fast string builder analyze liveness of environment slots and zap dead values trace TurboFan load elimination emit data about basic block usage in builtins to this enable builtin reordering when run mksnapshot flag for emit warnings when applying builtin profile data verify register allocation in TurboFan randomly schedule instructions to stress dependency tracking enable store store elimination in TurboFan rewrite far to near simulate GC compiler thread race related to allow float parameters to be passed in simulator mode JS Wasm Run additional turbo_optimize_inlined_js_wasm_wrappers enable experimental feedback collection in generic lowering enable Turboshaft s WasmLoadElimination enable Turboshaft s low level load elimination for JS enable Turboshaft s escape analysis for string concatenation use enable Turbolev features that we want to ship in the not too far future trace individual Turboshaft reduction steps trace intermediate Turboshaft reduction steps invocation count threshold for early optimization Enables optimizations which favor memory size over execution speed Enables sampling allocation profiler with X as a sample interval min size of a semi the new space consists of two semi spaces max size of the Collect garbage after Collect garbage after keeps maps alive for< n > old space garbage collections print one detailed trace line in name
Definition flags.cc:2086
@ kIsolateAddressCount
Definition globals.h:2646
constexpr Opcode SC
static constexpr Address kNullAddress
Definition v8-internal.h:53
#define FOR_EACH_INTRINSIC(F)
Definition runtime.h:884
#define DCHECK_GE(v1, v2)
Definition logging.h:488
#define CHECK_EQ(lhs, rhs)
#define DCHECK_EQ(v1, v2)
Definition logging.h:485