external-reference-table.cc 8.3 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
// Forward declarations for C++ builtins.
#define FORWARD_DECLARE(Name) \
  Object* Builtin_##Name(int argc, Object** args, Isolate* isolate);
BUILTIN_LIST_C(FORWARD_DECLARE)
#undef FORWARD_DECLARE

27 28 29
ExternalReferenceTable* ExternalReferenceTable::instance(Isolate* isolate) {
  ExternalReferenceTable* external_reference_table =
      isolate->external_reference_table();
30
  if (external_reference_table == nullptr) {
31 32 33 34 35 36 37
    external_reference_table = new ExternalReferenceTable(isolate);
    isolate->set_external_reference_table(external_reference_table);
  }
  return external_reference_table;
}

ExternalReferenceTable::ExternalReferenceTable(Isolate* isolate) {
38 39
  int index = 0;

40
  // nullptr is preserved through serialization/deserialization.
41 42 43 44 45 46 47 48 49
  Add(nullptr, "nullptr", &index);
  AddReferences(isolate, &index);
  AddBuiltins(isolate, &index);
  AddRuntimeFunctions(isolate, &index);
  AddIsolateAddresses(isolate, &index);
  AddAccessors(isolate, &index);
  AddStubCache(isolate, &index);

  CHECK_EQ(kSize, index);
50 51
}

52
const char* ExternalReferenceTable::ResolveSymbol(void* address) {
53
#ifdef SYMBOLIZE_FUNCTION
54 55 56 57 58 59
  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;
60 61 62 63 64
#else
  return "<unresolved>";
#endif  // SYMBOLIZE_FUNCTION
}

65 66 67
void ExternalReferenceTable::Add(Address address, const char* name,
                                 int* index) {
  refs_[(*index)++] = {address, name};
68 69
}

70 71 72
void ExternalReferenceTable::AddReferences(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount, *index);

73
#define ADD_EXTERNAL_REFERENCE(name, desc) \
74
  Add(ExternalReference::name(isolate).address(), desc, index);
75 76
  EXTERNAL_REFERENCE_LIST(ADD_EXTERNAL_REFERENCE)
#undef ADD_EXTERNAL_REFERENCE
77 78

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);
79
}
80

81 82 83
void ExternalReferenceTable::AddBuiltins(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount, *index);

84 85
  struct CBuiltinEntry {
    Address address;
86 87
    const char* name;
  };
88 89
  static const CBuiltinEntry c_builtins[] = {
#define DEF_ENTRY(Name, ...) {FUNCTION_ADDR(&Builtin_##Name), "Builtin_" #Name},
90 91
      BUILTIN_LIST_C(DEF_ENTRY)
#undef DEF_ENTRY
92 93
  };
  for (unsigned i = 0; i < arraysize(c_builtins); ++i) {
94
    Add(ExternalReference(c_builtins[i].address, isolate).address(),
95
        c_builtins[i].name, index);
96
  }
97 98 99 100

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount,
           *index);
101
}
102

103 104 105 106 107
void ExternalReferenceTable::AddRuntimeFunctions(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount,
           *index);

108 109 110 111 112 113
  struct RuntimeEntry {
    Runtime::FunctionId id;
    const char* name;
  };

  static const RuntimeEntry runtime_functions[] = {
114 115 116 117 118 119
#define RUNTIME_ENTRY(name, i1, i2) {Runtime::k##name, "Runtime::" #name},
      FOR_EACH_INTRINSIC(RUNTIME_ENTRY)
#undef RUNTIME_ENTRY
  };

  for (unsigned i = 0; i < arraysize(runtime_functions); ++i) {
120
    ExternalReference ref(runtime_functions[i].id, isolate);
121
    Add(ref.address(), runtime_functions[i].name, index);
122
  }
123 124 125 126

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount,
           *index);
127
}
128

129 130 131 132 133
void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount,
           *index);

134 135 136
  // Top addresses
  static const char* address_names[] = {
#define BUILD_NAME_LITERAL(Name, name) "Isolate::" #name "_address",
137
      FOR_EACH_ISOLATE_ADDRESS_NAME(BUILD_NAME_LITERAL) nullptr
138 139 140
#undef BUILD_NAME_LITERAL
  };

141 142
  for (int i = 0; i < IsolateAddressId::kIsolateAddressCount; ++i) {
    Add(isolate->get_address_from_id(static_cast<IsolateAddressId>(i)),
143
        address_names[i], index);
144
  }
145 146 147 148 149

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount,
           *index);
150
}
151

152 153 154 155 156 157
void ExternalReferenceTable::AddAccessors(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount,
           *index);

158 159 160 161 162 163
  // Accessors
  struct AccessorRefTable {
    Address address;
    const char* name;
  };

164
  static const AccessorRefTable getters[] = {
165 166 167
#define ACCESSOR_INFO_DECLARATION(accessor_name, AccessorName) \
  {FUNCTION_ADDR(&Accessors::AccessorName##Getter),            \
   "Accessors::" #AccessorName "Getter"}, /* NOLINT(whitespace/indent) */
168
      ACCESSOR_INFO_LIST(ACCESSOR_INFO_DECLARATION)
169
#undef ACCESSOR_INFO_DECLARATION
170 171
  };
  static const AccessorRefTable setters[] = {
172
#define ACCESSOR_SETTER_DECLARATION(name) \
173
  { FUNCTION_ADDR(&Accessors::name), "Accessors::" #name},
174
      ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
175
#undef ACCESSOR_SETTER_DECLARATION
176 177
  };

178
  for (unsigned i = 0; i < arraysize(getters); ++i) {
179
    Add(getters[i].address, getters[i].name, index);
180 181 182
  }

  for (unsigned i = 0; i < arraysize(setters); ++i) {
183
    Add(setters[i].address, setters[i].name, index);
184
  }
185 186 187 188 189

  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount + kAccessorReferenceCount,
           *index);
190
}
191

192 193 194 195 196 197
void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCount +
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
               kIsolateAddressReferenceCount + kAccessorReferenceCount,
           *index);

198
  StubCache* load_stub_cache = isolate->load_stub_cache();
199 200

  // Stub cache tables
201
  Add(load_stub_cache->key_reference(StubCache::kPrimary).address(),
202
      "Load StubCache::primary_->key", index);
203
  Add(load_stub_cache->value_reference(StubCache::kPrimary).address(),
204
      "Load StubCache::primary_->value", index);
205
  Add(load_stub_cache->map_reference(StubCache::kPrimary).address(),
206
      "Load StubCache::primary_->map", index);
207
  Add(load_stub_cache->key_reference(StubCache::kSecondary).address(),
208
      "Load StubCache::secondary_->key", index);
209
  Add(load_stub_cache->value_reference(StubCache::kSecondary).address(),
210
      "Load StubCache::secondary_->value", index);
211
  Add(load_stub_cache->map_reference(StubCache::kSecondary).address(),
212
      "Load StubCache::secondary_->map", index);
213 214 215 216 217

  StubCache* store_stub_cache = isolate->store_stub_cache();

  // Stub cache tables
  Add(store_stub_cache->key_reference(StubCache::kPrimary).address(),
218
      "Store StubCache::primary_->key", index);
219
  Add(store_stub_cache->value_reference(StubCache::kPrimary).address(),
220
      "Store StubCache::primary_->value", index);
221
  Add(store_stub_cache->map_reference(StubCache::kPrimary).address(),
222
      "Store StubCache::primary_->map", index);
223
  Add(store_stub_cache->key_reference(StubCache::kSecondary).address(),
224
      "Store StubCache::secondary_->key", index);
225
  Add(store_stub_cache->value_reference(StubCache::kSecondary).address(),
226
      "Store StubCache::secondary_->value", index);
227
  Add(store_stub_cache->map_reference(StubCache::kSecondary).address(),
228 229 230 231 232 233 234 235
      "Store StubCache::secondary_->map", index);

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

}  // namespace internal
}  // namespace v8
240 241

#undef SYMBOLIZE_FUNCTION