Line data Source code
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 :
5 : #include "src/external-reference-table.h"
6 :
7 : #include "src/accessors.h"
8 : #include "src/counters.h"
9 : #include "src/external-reference.h"
10 : #include "src/ic/stub-cache.h"
11 :
12 : #if defined(DEBUG) && defined(V8_OS_LINUX) && !defined(V8_OS_ANDROID)
13 : #define SYMBOLIZE_FUNCTION
14 : #include <execinfo.h>
15 : #include <vector>
16 : #endif // DEBUG && V8_OS_LINUX && !V8_OS_ANDROID
17 :
18 : namespace v8 {
19 : namespace internal {
20 :
21 : #define ADD_EXT_REF_NAME(name, desc) desc,
22 : #define ADD_BUILTIN_NAME(Name, ...) "Builtin_" #Name,
23 : #define ADD_RUNTIME_FUNCTION(name, ...) "Runtime::" #name,
24 : #define ADD_ISOLATE_ADDR(Name, name) "Isolate::" #name "_address",
25 : #define ADD_ACCESSOR_INFO_NAME(_, __, AccessorName, ...) \
26 : "Accessors::" #AccessorName "Getter",
27 : #define ADD_ACCESSOR_SETTER_NAME(name) "Accessors::" #name,
28 : #define ADD_STATS_COUNTER_NAME(name, ...) "StatsCounter::" #name,
29 : // static
30 : // clang-format off
31 : const char* const
32 : ExternalReferenceTable::ref_name_[ExternalReferenceTable::kSize] = {
33 : // Special references:
34 : "nullptr",
35 : // External references:
36 : EXTERNAL_REFERENCE_LIST(ADD_EXT_REF_NAME)
37 : EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXT_REF_NAME)
38 : // Builtins:
39 : BUILTIN_LIST_C(ADD_BUILTIN_NAME)
40 : // Runtime functions:
41 : FOR_EACH_INTRINSIC(ADD_RUNTIME_FUNCTION)
42 : // Isolate addresses:
43 : FOR_EACH_ISOLATE_ADDRESS_NAME(ADD_ISOLATE_ADDR)
44 : // Accessors:
45 : ACCESSOR_INFO_LIST_GENERATOR(ADD_ACCESSOR_INFO_NAME, /* not used */)
46 : ACCESSOR_SETTER_LIST(ADD_ACCESSOR_SETTER_NAME)
47 : // Stub cache:
48 : "Load StubCache::primary_->key",
49 : "Load StubCache::primary_->value",
50 : "Load StubCache::primary_->map",
51 : "Load StubCache::secondary_->key",
52 : "Load StubCache::secondary_->value",
53 : "Load StubCache::secondary_->map",
54 : "Store StubCache::primary_->key",
55 : "Store StubCache::primary_->value",
56 : "Store StubCache::primary_->map",
57 : "Store StubCache::secondary_->key",
58 : "Store StubCache::secondary_->value",
59 : "Store StubCache::secondary_->map",
60 : // Native code counters:
61 : STATS_COUNTER_NATIVE_CODE_LIST(ADD_STATS_COUNTER_NAME)
62 : };
63 : // clang-format on
64 : #undef ADD_EXT_REF_NAME
65 : #undef ADD_BUILTIN_NAME
66 : #undef ADD_RUNTIME_FUNCTION
67 : #undef ADD_ISOLATE_ADDR
68 : #undef ADD_ACCESSOR_INFO_NAME
69 : #undef ADD_ACCESSOR_SETTER_NAME
70 : #undef ADD_STATS_COUNTER_NAME
71 :
72 : // Forward declarations for C++ builtins.
73 : #define FORWARD_DECLARE(Name) \
74 : Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
75 : BUILTIN_LIST_C(FORWARD_DECLARE)
76 : #undef FORWARD_DECLARE
77 :
78 62442 : void ExternalReferenceTable::Init(Isolate* isolate) {
79 62442 : int index = 0;
80 :
81 : // kNullAddress is preserved through serialization/deserialization.
82 : Add(kNullAddress, &index);
83 62442 : AddReferences(isolate, &index);
84 62442 : AddBuiltins(&index);
85 62442 : AddRuntimeFunctions(&index);
86 62442 : AddIsolateAddresses(isolate, &index);
87 62442 : AddAccessors(&index);
88 62442 : AddStubCache(isolate, &index);
89 62442 : AddNativeCodeStatsCounters(isolate, &index);
90 62442 : is_initialized_ = static_cast<uint32_t>(true);
91 :
92 62442 : CHECK_EQ(kSize, index);
93 62442 : }
94 :
95 0 : const char* ExternalReferenceTable::ResolveSymbol(void* address) {
96 : #ifdef SYMBOLIZE_FUNCTION
97 : char** names = backtrace_symbols(&address, 1);
98 : const char* name = names[0];
99 : // The array of names is malloc'ed. However, each name string is static
100 : // and do not need to be freed.
101 : free(names);
102 : return name;
103 : #else
104 0 : return "<unresolved>";
105 : #endif // SYMBOLIZE_FUNCTION
106 : }
107 :
108 0 : void ExternalReferenceTable::Add(Address address, int* index) {
109 59257419 : ref_addr_[(*index)++] = address;
110 0 : }
111 :
112 62442 : void ExternalReferenceTable::AddReferences(Isolate* isolate, int* index) {
113 62442 : CHECK_EQ(kSpecialReferenceCount, *index);
114 :
115 : #define ADD_EXTERNAL_REFERENCE(name, desc) \
116 : Add(ExternalReference::name().address(), index);
117 7243272 : EXTERNAL_REFERENCE_LIST(ADD_EXTERNAL_REFERENCE)
118 : #undef ADD_EXTERNAL_REFERENCE
119 :
120 : #define ADD_EXTERNAL_REFERENCE(name, desc) \
121 : Add(ExternalReference::name(isolate).address(), index);
122 2872332 : EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXTERNAL_REFERENCE)
123 : #undef ADD_EXTERNAL_REFERENCE
124 :
125 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
126 62442 : }
127 :
128 62442 : void ExternalReferenceTable::AddBuiltins(int* index) {
129 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
130 :
131 : static const Address c_builtins[] = {
132 : #define DEF_ENTRY(Name, ...) FUNCTION_ADDR(&Builtin_##Name),
133 : BUILTIN_LIST_C(DEF_ENTRY)
134 : #undef DEF_ENTRY
135 : };
136 34780194 : for (Address addr : c_builtins) {
137 34717752 : Add(ExternalReference::Create(addr).address(), index);
138 : }
139 :
140 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
141 : kBuiltinsReferenceCount,
142 : *index);
143 62442 : }
144 :
145 62437 : void ExternalReferenceTable::AddRuntimeFunctions(int* index) {
146 62437 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
147 : kBuiltinsReferenceCount,
148 : *index);
149 :
150 : static constexpr Runtime::FunctionId runtime_functions[] = {
151 : #define RUNTIME_ENTRY(name, ...) Runtime::k##name,
152 : FOR_EACH_INTRINSIC(RUNTIME_ENTRY)
153 : #undef RUNTIME_ENTRY
154 : };
155 :
156 57384115 : for (Runtime::FunctionId fId : runtime_functions) {
157 57321673 : Add(ExternalReference::Create(fId).address(), index);
158 : }
159 :
160 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
161 : kBuiltinsReferenceCount + kRuntimeReferenceCount,
162 : *index);
163 62442 : }
164 :
165 62442 : void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate, int* index) {
166 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
167 : kBuiltinsReferenceCount + kRuntimeReferenceCount,
168 : *index);
169 :
170 1561050 : for (int i = 0; i < IsolateAddressId::kIsolateAddressCount; ++i) {
171 749304 : Add(isolate->get_address_from_id(static_cast<IsolateAddressId>(i)), index);
172 : }
173 :
174 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
175 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
176 : kIsolateAddressReferenceCount,
177 : *index);
178 62442 : }
179 :
180 62442 : void ExternalReferenceTable::AddAccessors(int* index) {
181 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
182 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
183 : kIsolateAddressReferenceCount,
184 : *index);
185 :
186 : static const Address accessors[] = {
187 : // Getters:
188 : #define ACCESSOR_INFO_DECLARATION(_, __, AccessorName, ...) \
189 : FUNCTION_ADDR(&Accessors::AccessorName##Getter),
190 : ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_DECLARATION, /* not used */)
191 : #undef ACCESSOR_INFO_DECLARATION
192 : // Setters:
193 : #define ACCESSOR_SETTER_DECLARATION(name) FUNCTION_ADDR(&Accessors::name),
194 : ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
195 : #undef ACCESSOR_SETTER_DECLARATION
196 : };
197 :
198 2060586 : for (Address addr : accessors) {
199 : Add(addr, index);
200 : }
201 :
202 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
203 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
204 : kIsolateAddressReferenceCount + kAccessorReferenceCount,
205 : *index);
206 62442 : }
207 :
208 62442 : void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
209 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
210 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
211 : kIsolateAddressReferenceCount + kAccessorReferenceCount,
212 : *index);
213 :
214 : StubCache* load_stub_cache = isolate->load_stub_cache();
215 :
216 : // Stub cache tables
217 : Add(load_stub_cache->key_reference(StubCache::kPrimary).address(), index);
218 : Add(load_stub_cache->value_reference(StubCache::kPrimary).address(), index);
219 : Add(load_stub_cache->map_reference(StubCache::kPrimary).address(), index);
220 : Add(load_stub_cache->key_reference(StubCache::kSecondary).address(), index);
221 : Add(load_stub_cache->value_reference(StubCache::kSecondary).address(), index);
222 : Add(load_stub_cache->map_reference(StubCache::kSecondary).address(), index);
223 :
224 : StubCache* store_stub_cache = isolate->store_stub_cache();
225 :
226 : // Stub cache tables
227 : Add(store_stub_cache->key_reference(StubCache::kPrimary).address(), index);
228 : Add(store_stub_cache->value_reference(StubCache::kPrimary).address(), index);
229 : Add(store_stub_cache->map_reference(StubCache::kPrimary).address(), index);
230 : Add(store_stub_cache->key_reference(StubCache::kSecondary).address(), index);
231 : Add(store_stub_cache->value_reference(StubCache::kSecondary).address(),
232 : index);
233 : Add(store_stub_cache->map_reference(StubCache::kSecondary).address(), index);
234 :
235 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
236 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
237 : kIsolateAddressReferenceCount + kAccessorReferenceCount +
238 : kStubCacheReferenceCount,
239 : *index);
240 62442 : }
241 :
242 686862 : Address ExternalReferenceTable::GetStatsCounterAddress(StatsCounter* counter) {
243 : int* address = counter->Enabled()
244 : ? counter->GetInternalPointer()
245 1373691 : : reinterpret_cast<int*>(&dummy_stats_counter_);
246 686862 : return reinterpret_cast<Address>(address);
247 : }
248 :
249 62442 : void ExternalReferenceTable::AddNativeCodeStatsCounters(Isolate* isolate,
250 : int* index) {
251 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
252 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
253 : kIsolateAddressReferenceCount + kAccessorReferenceCount +
254 : kStubCacheReferenceCount,
255 : *index);
256 :
257 : Counters* counters = isolate->counters();
258 :
259 : #define SC(name, caption) Add(GetStatsCounterAddress(counters->name()), index);
260 686862 : STATS_COUNTER_NATIVE_CODE_LIST(SC)
261 : #undef SC
262 :
263 62442 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
264 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
265 : kIsolateAddressReferenceCount + kAccessorReferenceCount +
266 : kStubCacheReferenceCount + kStatsCountersReferenceCount,
267 : *index);
268 62442 : CHECK_EQ(kSize, *index);
269 62442 : }
270 :
271 : } // namespace internal
272 122036 : } // namespace v8
273 :
274 : #undef SYMBOLIZE_FUNCTION
|