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 : // static
29 : const char* const
30 : ExternalReferenceTable::ref_name_[ExternalReferenceTable::kSize] = {
31 : // Special references:
32 : "nullptr",
33 : // External references:
34 : EXTERNAL_REFERENCE_LIST(ADD_EXT_REF_NAME)
35 : EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXT_REF_NAME)
36 : // Builtins:
37 : BUILTIN_LIST_C(ADD_BUILTIN_NAME)
38 : // Runtime functions:
39 : FOR_EACH_INTRINSIC(ADD_RUNTIME_FUNCTION)
40 : // Isolate addresses:
41 : FOR_EACH_ISOLATE_ADDRESS_NAME(ADD_ISOLATE_ADDR)
42 : // Accessors:
43 : ACCESSOR_INFO_LIST_GENERATOR(ADD_ACCESSOR_INFO_NAME, /* not used */)
44 : ACCESSOR_SETTER_LIST(ADD_ACCESSOR_SETTER_NAME)
45 : // Stub cache:
46 : "Load StubCache::primary_->key",
47 : "Load StubCache::primary_->value",
48 : "Load StubCache::primary_->map",
49 : "Load StubCache::secondary_->key",
50 : "Load StubCache::secondary_->value",
51 : "Load StubCache::secondary_->map",
52 : "Store StubCache::primary_->key",
53 : "Store StubCache::primary_->value",
54 : "Store StubCache::primary_->map",
55 : "Store StubCache::secondary_->key",
56 : "Store StubCache::secondary_->value",
57 : "Store StubCache::secondary_->map",
58 : };
59 : #undef ADD_EXT_REF_NAME
60 : #undef ADD_BUILTIN_NAME
61 : #undef ADD_RUNTIME_FUNCTION
62 : #undef ADD_ISOLATE_ADDR
63 : #undef ADD_ACCESSOR_INFO_NAME
64 : #undef ADD_ACCESSOR_SETTER_NAME
65 :
66 : // Forward declarations for C++ builtins.
67 : #define FORWARD_DECLARE(Name) \
68 : Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
69 : BUILTIN_LIST_C(FORWARD_DECLARE)
70 : #undef FORWARD_DECLARE
71 :
72 62883 : void ExternalReferenceTable::Init(Isolate* isolate) {
73 62883 : int index = 0;
74 :
75 : // kNullAddress is preserved through serialization/deserialization.
76 : Add(kNullAddress, &index);
77 62883 : AddReferences(isolate, &index);
78 62883 : AddBuiltins(&index);
79 62883 : AddRuntimeFunctions(&index);
80 62883 : AddIsolateAddresses(isolate, &index);
81 62883 : AddAccessors(&index);
82 62883 : AddStubCache(isolate, &index);
83 62883 : is_initialized_ = static_cast<uint32_t>(true);
84 : USE(unused_padding_);
85 :
86 62883 : CHECK_EQ(kSize, index);
87 62883 : }
88 :
89 0 : const char* ExternalReferenceTable::ResolveSymbol(void* address) {
90 : #ifdef SYMBOLIZE_FUNCTION
91 : char** names = backtrace_symbols(&address, 1);
92 : const char* name = names[0];
93 : // The array of names is malloc'ed. However, each name string is static
94 : // and do not need to be freed.
95 : free(names);
96 : return name;
97 : #else
98 0 : return "<unresolved>";
99 : #endif // SYMBOLIZE_FUNCTION
100 : }
101 :
102 0 : void ExternalReferenceTable::Add(Address address, int* index) {
103 58669203 : ref_addr_[(*index)++] = address;
104 0 : }
105 :
106 62883 : void ExternalReferenceTable::AddReferences(Isolate* isolate, int* index) {
107 62883 : CHECK_EQ(kSpecialReferenceCount, *index);
108 :
109 : #define ADD_EXTERNAL_REFERENCE(name, desc) \
110 : Add(ExternalReference::name().address(), index);
111 7231523 : EXTERNAL_REFERENCE_LIST(ADD_EXTERNAL_REFERENCE)
112 : #undef ADD_EXTERNAL_REFERENCE
113 :
114 : #define ADD_EXTERNAL_REFERENCE(name, desc) \
115 : Add(ExternalReference::name(isolate).address(), index);
116 2892613 : EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXTERNAL_REFERENCE)
117 : #undef ADD_EXTERNAL_REFERENCE
118 :
119 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
120 62883 : }
121 :
122 62896 : void ExternalReferenceTable::AddBuiltins(int* index) {
123 62896 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
124 :
125 : static const Address c_builtins[] = {
126 : #define DEF_ENTRY(Name, ...) FUNCTION_ADDR(&Builtin_##Name),
127 : BUILTIN_LIST_C(DEF_ENTRY)
128 : #undef DEF_ENTRY
129 : };
130 35088463 : for (Address addr : c_builtins) {
131 35088463 : Add(ExternalReference::Create(addr).address(), index);
132 : }
133 :
134 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
135 : kBuiltinsReferenceCount,
136 : *index);
137 62883 : }
138 :
139 62896 : void ExternalReferenceTable::AddRuntimeFunctions(int* index) {
140 62896 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
141 : kBuiltinsReferenceCount,
142 : *index);
143 :
144 : static constexpr Runtime::FunctionId runtime_functions[] = {
145 : #define RUNTIME_ENTRY(name, ...) Runtime::k##name,
146 : FOR_EACH_INTRINSIC(RUNTIME_ENTRY)
147 : #undef RUNTIME_ENTRY
148 : };
149 :
150 57096821 : for (Runtime::FunctionId fId : runtime_functions) {
151 57096821 : Add(ExternalReference::Create(fId).address(), index);
152 : }
153 :
154 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
155 : kBuiltinsReferenceCount + kRuntimeReferenceCount,
156 : *index);
157 62883 : }
158 :
159 62883 : void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate, int* index) {
160 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
161 : kBuiltinsReferenceCount + kRuntimeReferenceCount,
162 : *index);
163 :
164 754596 : for (int i = 0; i < IsolateAddressId::kIsolateAddressCount; ++i) {
165 754596 : Add(isolate->get_address_from_id(static_cast<IsolateAddressId>(i)), index);
166 : }
167 :
168 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
169 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
170 : kIsolateAddressReferenceCount,
171 : *index);
172 62883 : }
173 :
174 62883 : void ExternalReferenceTable::AddAccessors(int* index) {
175 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
176 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
177 : kIsolateAddressReferenceCount,
178 : *index);
179 :
180 : static const Address accessors[] = {
181 : // Getters:
182 : #define ACCESSOR_INFO_DECLARATION(_, __, AccessorName, ...) \
183 : FUNCTION_ADDR(&Accessors::AccessorName##Getter),
184 : ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_DECLARATION, /* not used */)
185 : #undef ACCESSOR_INFO_DECLARATION
186 : // Setters:
187 : #define ACCESSOR_SETTER_DECLARATION(name) FUNCTION_ADDR(&Accessors::name),
188 : ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
189 : #undef ACCESSOR_SETTER_DECLARATION
190 : };
191 :
192 2012256 : for (Address addr : accessors) {
193 : Add(addr, index);
194 : }
195 :
196 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
197 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
198 : kIsolateAddressReferenceCount + kAccessorReferenceCount,
199 : *index);
200 62883 : }
201 :
202 188649 : void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
203 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
204 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
205 : kIsolateAddressReferenceCount + kAccessorReferenceCount,
206 : *index);
207 :
208 : StubCache* load_stub_cache = isolate->load_stub_cache();
209 :
210 : // Stub cache tables
211 : Add(load_stub_cache->key_reference(StubCache::kPrimary).address(), index);
212 : Add(load_stub_cache->value_reference(StubCache::kPrimary).address(), index);
213 : Add(load_stub_cache->map_reference(StubCache::kPrimary).address(), index);
214 : Add(load_stub_cache->key_reference(StubCache::kSecondary).address(), index);
215 : Add(load_stub_cache->value_reference(StubCache::kSecondary).address(), index);
216 : Add(load_stub_cache->map_reference(StubCache::kSecondary).address(), index);
217 :
218 : StubCache* store_stub_cache = isolate->store_stub_cache();
219 :
220 : // Stub cache tables
221 : Add(store_stub_cache->key_reference(StubCache::kPrimary).address(), index);
222 : Add(store_stub_cache->value_reference(StubCache::kPrimary).address(), index);
223 : Add(store_stub_cache->map_reference(StubCache::kPrimary).address(), index);
224 : Add(store_stub_cache->key_reference(StubCache::kSecondary).address(), index);
225 : Add(store_stub_cache->value_reference(StubCache::kSecondary).address(),
226 : index);
227 : Add(store_stub_cache->map_reference(StubCache::kSecondary).address(), index);
228 :
229 62883 : CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
230 : kBuiltinsReferenceCount + kRuntimeReferenceCount +
231 : kIsolateAddressReferenceCount + kAccessorReferenceCount +
232 : kStubCacheReferenceCount,
233 : *index);
234 62883 : CHECK_EQ(kSize, *index);
235 62883 : }
236 :
237 : } // namespace internal
238 183867 : } // namespace v8
239 :
240 : #undef SYMBOLIZE_FUNCTION
|