Home | History | Annotate | Download | only in src
      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