• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/codegen/external-reference-table.h"
6 
7 #include "src/builtins/accessors.h"
8 #include "src/codegen/external-reference.h"
9 #include "src/ic/stub-cache.h"
10 #include "src/logging/counters.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);
BUILTIN_LIST_C(FORWARD_DECLARE)75 BUILTIN_LIST_C(FORWARD_DECLARE)
76 #undef FORWARD_DECLARE
77 
78 void ExternalReferenceTable::Init(Isolate* isolate) {
79   int index = 0;
80 
81   // kNullAddress is preserved through serialization/deserialization.
82   Add(kNullAddress, &index);
83   AddReferences(isolate, &index);
84   AddBuiltins(&index);
85   AddRuntimeFunctions(&index);
86   AddIsolateAddresses(isolate, &index);
87   AddAccessors(&index);
88   AddStubCache(isolate, &index);
89   AddNativeCodeStatsCounters(isolate, &index);
90   is_initialized_ = static_cast<uint32_t>(true);
91 
92   CHECK_EQ(kSize, index);
93 }
94 
ResolveSymbol(void * address)95 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   return "<unresolved>";
105 #endif  // SYMBOLIZE_FUNCTION
106 }
107 
Add(Address address,int * index)108 void ExternalReferenceTable::Add(Address address, int* index) {
109   ref_addr_[(*index)++] = address;
110 }
111 
AddReferences(Isolate * isolate,int * index)112 void ExternalReferenceTable::AddReferences(Isolate* isolate, int* index) {
113   CHECK_EQ(kSpecialReferenceCount, *index);
114 
115 #define ADD_EXTERNAL_REFERENCE(name, desc) \
116   Add(ExternalReference::name().address(), index);
117   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   EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXTERNAL_REFERENCE)
123 #undef ADD_EXTERNAL_REFERENCE
124 
125   CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
126 }
127 
AddBuiltins(int * index)128 void ExternalReferenceTable::AddBuiltins(int* index) {
129   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   for (Address addr : c_builtins) {
137     Add(ExternalReference::Create(addr).address(), index);
138   }
139 
140   CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
141                kBuiltinsReferenceCount,
142            *index);
143 }
144 
AddRuntimeFunctions(int * index)145 void ExternalReferenceTable::AddRuntimeFunctions(int* index) {
146   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   for (Runtime::FunctionId fId : runtime_functions) {
157     Add(ExternalReference::Create(fId).address(), index);
158   }
159 
160   CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
161                kBuiltinsReferenceCount + kRuntimeReferenceCount,
162            *index);
163 }
164 
AddIsolateAddresses(Isolate * isolate,int * index)165 void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate, int* index) {
166   CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
167                kBuiltinsReferenceCount + kRuntimeReferenceCount,
168            *index);
169 
170   for (int i = 0; i < IsolateAddressId::kIsolateAddressCount; ++i) {
171     Add(isolate->get_address_from_id(static_cast<IsolateAddressId>(i)), index);
172   }
173 
174   CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
175                kBuiltinsReferenceCount + kRuntimeReferenceCount +
176                kIsolateAddressReferenceCount,
177            *index);
178 }
179 
AddAccessors(int * index)180 void ExternalReferenceTable::AddAccessors(int* index) {
181   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   for (Address addr : accessors) {
199     Add(addr, index);
200   }
201 
202   CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
203                kBuiltinsReferenceCount + kRuntimeReferenceCount +
204                kIsolateAddressReferenceCount + kAccessorReferenceCount,
205            *index);
206 }
207 
AddStubCache(Isolate * isolate,int * index)208 void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
209   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   CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
236                kBuiltinsReferenceCount + kRuntimeReferenceCount +
237                kIsolateAddressReferenceCount + kAccessorReferenceCount +
238                kStubCacheReferenceCount,
239            *index);
240 }
241 
GetStatsCounterAddress(StatsCounter * counter)242 Address ExternalReferenceTable::GetStatsCounterAddress(StatsCounter* counter) {
243   int* address = counter->Enabled()
244                      ? counter->GetInternalPointer()
245                      : reinterpret_cast<int*>(&dummy_stats_counter_);
246   return reinterpret_cast<Address>(address);
247 }
248 
AddNativeCodeStatsCounters(Isolate * isolate,int * index)249 void ExternalReferenceTable::AddNativeCodeStatsCounters(Isolate* isolate,
250                                                         int* index) {
251   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   STATS_COUNTER_NATIVE_CODE_LIST(SC)
261 #undef SC
262 
263   CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
264                kBuiltinsReferenceCount + kRuntimeReferenceCount +
265                kIsolateAddressReferenceCount + kAccessorReferenceCount +
266                kStubCacheReferenceCount + kStatsCountersReferenceCount,
267            *index);
268   CHECK_EQ(kSize, *index);
269 }
270 
271 }  // namespace internal
272 }  // namespace v8
273 
274 #undef SYMBOLIZE_FUNCTION
275