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