external-reference-table.cc 8.34 KB
Newer Older
1 2 3 4 5 6 7 8
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/external-reference-table.h"

#include "src/accessors.h"
#include "src/counters.h"
9
#include "src/external-reference.h"
10 11
#include "src/ic/stub-cache.h"

12 13 14
#if defined(DEBUG) && defined(V8_OS_LINUX) && !defined(V8_OS_ANDROID)
#define SYMBOLIZE_FUNCTION
#include <execinfo.h>
15
#include <vector>
16 17
#endif  // DEBUG && V8_OS_LINUX && !V8_OS_ANDROID

18 19 20
namespace v8 {
namespace internal {

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
#define ADD_EXT_REF_NAME(name, desc) desc,
#define ADD_BUILTIN_NAME(Name, ...) "Builtin_" #Name,
#define ADD_RUNTIME_FUNCTION(name, ...) "Runtime::" #name,
#define ADD_ISOLATE_ADDR(Name, name) "Isolate::" #name "_address",
#define ADD_ACCESSOR_INFO_NAME(_, __, AccessorName, ...) \
  "Accessors::" #AccessorName "Getter",
#define ADD_ACCESSOR_SETTER_NAME(name) "Accessors::" #name,
// static
const char* const
    ExternalReferenceTable::ref_name_[ExternalReferenceTable::kSize] = {
        // Special references:
        "nullptr",
        // External references:
        EXTERNAL_REFERENCE_LIST(ADD_EXT_REF_NAME)
            EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXT_REF_NAME)
        // Builtins:
        BUILTIN_LIST_C(ADD_BUILTIN_NAME)
        // Runtime functions:
        FOR_EACH_INTRINSIC(ADD_RUNTIME_FUNCTION)
        // Isolate addresses:
        FOR_EACH_ISOLATE_ADDRESS_NAME(ADD_ISOLATE_ADDR)
        // Accessors:
        ACCESSOR_INFO_LIST_GENERATOR(ADD_ACCESSOR_INFO_NAME, /* not used */)
            ACCESSOR_SETTER_LIST(ADD_ACCESSOR_SETTER_NAME)
        // Stub cache:
        "Load StubCache::primary_->key",
        "Load StubCache::primary_->value",
        "Load StubCache::primary_->map",
        "Load StubCache::secondary_->key",
        "Load StubCache::secondary_->value",
        "Load StubCache::secondary_->map",
        "Store StubCache::primary_->key",
        "Store StubCache::primary_->value",
        "Store StubCache::primary_->map",
        "Store StubCache::secondary_->key",
        "Store StubCache::secondary_->value",
        "Store StubCache::secondary_->map",
};
#undef ADD_EXT_REF_NAME
#undef ADD_BUILTIN_NAME
#undef ADD_RUNTIME_FUNCTION
#undef ADD_ISOLATE_ADDR
#undef ADD_ACCESSOR_INFO_NAME
#undef ADD_ACCESSOR_SETTER_NAME

66 67
// Forward declarations for C++ builtins.
#define FORWARD_DECLARE(Name) \
68
  Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
69 70 71
BUILTIN_LIST_C(FORWARD_DECLARE)
#undef FORWARD_DECLARE

72
void ExternalReferenceTable::Init(Isolate* isolate) {
73 74
  int index = 0;

75
  // kNullAddress is preserved through serialization/deserialization.
76
  Add(kNullAddress, &index);
77
  AddReferences(isolate, &index);
78 79
  AddBuiltins(&index);
  AddRuntimeFunctions(&index);
80
  AddIsolateAddresses(isolate, &index);
81
  AddAccessors(&index);
82
  AddStubCache(isolate, &index);
83 84
  is_initialized_ = static_cast<uint32_t>(true);
  USE(unused_padding_);
85 86

  CHECK_EQ(kSize, index);
87 88
}

89
const char* ExternalReferenceTable::ResolveSymbol(void* address) {
90
#ifdef SYMBOLIZE_FUNCTION
91 92 93 94 95 96
  char** names = backtrace_symbols(&address, 1);
  const char* name = names[0];
  // The array of names is malloc'ed. However, each name string is static
  // and do not need to be freed.
  free(names);
  return name;
97 98 99 100 101
#else
  return "<unresolved>";
#endif  // SYMBOLIZE_FUNCTION
}

102 103
void ExternalReferenceTable::Add(Address address, int* index) {
  ref_addr_[(*index)++] = address;
104 105
}

106 107 108
void ExternalReferenceTable::AddReferences(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount, *index);

109
#define ADD_EXTERNAL_REFERENCE(name, desc) \
110
  Add(ExternalReference::name().address(), index);
111
  EXTERNAL_REFERENCE_LIST(ADD_EXTERNAL_REFERENCE)
112 113
#undef ADD_EXTERNAL_REFERENCE

114
#define ADD_EXTERNAL_REFERENCE(name, desc) \
115
  Add(ExternalReference::name(isolate).address(), index);
116 117 118
  EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXTERNAL_REFERENCE)
#undef ADD_EXTERNAL_REFERENCE

119
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
120
}
121

122
void ExternalReferenceTable::AddBuiltins(int* index) {
123 124
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);

125 126
  static const Address c_builtins[] = {
#define DEF_ENTRY(Name, ...) FUNCTION_ADDR(&Builtin_##Name),
127 128
      BUILTIN_LIST_C(DEF_ENTRY)
#undef DEF_ENTRY
129
  };
130 131
  for (Address addr : c_builtins) {
    Add(ExternalReference::Create(addr).address(), index);
132
  }
133 134 135 136

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount,
           *index);
137
}
138

139
void ExternalReferenceTable::AddRuntimeFunctions(int* index) {
140 141 142 143
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount,
           *index);

144 145
  static constexpr Runtime::FunctionId runtime_functions[] = {
#define RUNTIME_ENTRY(name, ...) Runtime::k##name,
146 147 148 149
      FOR_EACH_INTRINSIC(RUNTIME_ENTRY)
#undef RUNTIME_ENTRY
  };

150 151
  for (Runtime::FunctionId fId : runtime_functions) {
    Add(ExternalReference::Create(fId).address(), index);
152
  }
153 154 155 156

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount,
           *index);
157
}
158

159 160 161 162 163
void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount,
           *index);

164
  for (int i = 0; i < IsolateAddressId::kIsolateAddressCount; ++i) {
165
    Add(isolate->get_address_from_id(static_cast<IsolateAddressId>(i)), index);
166
  }
167 168 169 170 171

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount,
           *index);
172
}
173

174
void ExternalReferenceTable::AddAccessors(int* index) {
175 176 177 178 179
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount,
           *index);

180 181 182 183
  static const Address accessors[] = {
  // Getters:
#define ACCESSOR_INFO_DECLARATION(_, __, AccessorName, ...) \
  FUNCTION_ADDR(&Accessors::AccessorName##Getter),
184
      ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_DECLARATION, /* not used */)
185
#undef ACCESSOR_INFO_DECLARATION
186 187 188
  // Setters:
#define ACCESSOR_SETTER_DECLARATION(name) FUNCTION_ADDR(&Accessors::name),
          ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
189
#undef ACCESSOR_SETTER_DECLARATION
190 191
  };

192 193
  for (Address addr : accessors) {
    Add(addr, index);
194
  }
195 196 197 198 199

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount + kAccessorReferenceCount,
           *index);
200
}
201

202 203 204 205 206 207
void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount + kAccessorReferenceCount,
           *index);

208
  StubCache* load_stub_cache = isolate->load_stub_cache();
209 210

  // Stub cache tables
211 212 213 214 215 216
  Add(load_stub_cache->key_reference(StubCache::kPrimary).address(), index);
  Add(load_stub_cache->value_reference(StubCache::kPrimary).address(), index);
  Add(load_stub_cache->map_reference(StubCache::kPrimary).address(), index);
  Add(load_stub_cache->key_reference(StubCache::kSecondary).address(), index);
  Add(load_stub_cache->value_reference(StubCache::kSecondary).address(), index);
  Add(load_stub_cache->map_reference(StubCache::kSecondary).address(), index);
217 218 219 220

  StubCache* store_stub_cache = isolate->store_stub_cache();

  // Stub cache tables
221 222 223 224
  Add(store_stub_cache->key_reference(StubCache::kPrimary).address(), index);
  Add(store_stub_cache->value_reference(StubCache::kPrimary).address(), index);
  Add(store_stub_cache->map_reference(StubCache::kPrimary).address(), index);
  Add(store_stub_cache->key_reference(StubCache::kSecondary).address(), index);
225
  Add(store_stub_cache->value_reference(StubCache::kSecondary).address(),
226 227
      index);
  Add(store_stub_cache->map_reference(StubCache::kSecondary).address(), index);
228 229 230 231 232 233 234

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount + kAccessorReferenceCount +
               kStubCacheReferenceCount,
           *index);
  CHECK_EQ(kSize, *index);
235
}
236 237 238

}  // namespace internal
}  // namespace v8
239 240

#undef SYMBOLIZE_FUNCTION