external-reference-table.cc 11.1 KB
Newer Older
1 2 3 4
// 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.

5
#include "src/codegen/external-reference-table.h"
6

7
#include "src/builtins/accessors.h"
8
#include "src/codegen/external-reference.h"
9
#include "src/execution/isolate.h"
10
#include "src/ic/stub-cache.h"
11
#include "src/logging/counters.h"
12

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

17
#include <vector>
18 19

#include "src/base/platform/wrappers.h"
20 21
#endif  // DEBUG && V8_OS_LINUX && !V8_OS_ANDROID

22 23 24
namespace v8 {
namespace internal {

25 26 27 28 29 30 31
#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,
32
#define ADD_STATS_COUNTER_NAME(name, ...) "StatsCounter::" #name,
33
// static
34
// clang-format off
35 36
const char* const
    ExternalReferenceTable::ref_name_[ExternalReferenceTable::kSize] = {
37
        // === Isolate independent ===
38 39
        // Special references:
        "nullptr",
40
        // External references (without isolate):
41 42 43 44 45 46 47
        EXTERNAL_REFERENCE_LIST(ADD_EXT_REF_NAME)
        // Builtins:
        BUILTIN_LIST_C(ADD_BUILTIN_NAME)
        // Runtime functions:
        FOR_EACH_INTRINSIC(ADD_RUNTIME_FUNCTION)
        // Accessors:
        ACCESSOR_INFO_LIST_GENERATOR(ADD_ACCESSOR_INFO_NAME, /* not used */)
48
        ACCESSOR_SETTER_LIST(ADD_ACCESSOR_SETTER_NAME)
49 50 51 52 53 54

        // === Isolate dependent ===
        // External references (with isolate):
        EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXT_REF_NAME)
        // Isolate addresses:
        FOR_EACH_ISOLATE_ADDRESS_NAME(ADD_ISOLATE_ADDR)
55 56 57 58 59 60 61 62 63 64 65 66 67
        // 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",
68 69
        // Native code counters:
        STATS_COUNTER_NATIVE_CODE_LIST(ADD_STATS_COUNTER_NAME)
70
};
71
// clang-format on
72 73 74 75 76 77
#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
78
#undef ADD_STATS_COUNTER_NAME
79

80 81 82 83 84
namespace {
static Address ref_addr_isolate_independent_
    [ExternalReferenceTable::kSizeIsolateIndependent] = {0};
}  // namespace

85 86
// Forward declarations for C++ builtins.
#define FORWARD_DECLARE(Name) \
87
  Address Builtin_##Name(int argc, Address* args, Isolate* isolate);
88 89 90
BUILTIN_LIST_C(FORWARD_DECLARE)
#undef FORWARD_DECLARE

91
void ExternalReferenceTable::Init(Isolate* isolate) {
92 93
  int index = 0;

94 95 96
  CopyIsolateIndependentReferences(&index);

  AddIsolateDependentReferences(isolate, &index);
97 98
  AddIsolateAddresses(isolate, &index);
  AddStubCache(isolate, &index);
99
  AddNativeCodeStatsCounters(isolate, &index);
100
  is_initialized_ = static_cast<uint32_t>(true);
101 102

  CHECK_EQ(kSize, index);
103 104
}

105
const char* ExternalReferenceTable::ResolveSymbol(void* address) {
106
#ifdef SYMBOLIZE_FUNCTION
107 108 109 110
  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.
111
  base::Free(names);
112
  return name;
113 114 115 116 117
#else
  return "<unresolved>";
#endif  // SYMBOLIZE_FUNCTION
}

118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
void ExternalReferenceTable::InitializeOncePerProcess() {
  int index = 0;

  // kNullAddress is preserved through serialization/deserialization.
  AddIsolateIndependent(kNullAddress, &index);
  AddIsolateIndependentReferences(&index);
  AddBuiltins(&index);
  AddRuntimeFunctions(&index);
  AddAccessors(&index);

  CHECK_EQ(kSizeIsolateIndependent, index);
}

const char* ExternalReferenceTable::NameOfIsolateIndependentAddress(
    Address address) {
  for (int i = 0; i < kSizeIsolateIndependent; i++) {
    if (ref_addr_isolate_independent_[i] == address) {
      return ref_name_[i];
    }
  }
  return "<unknown>";
}

141 142
void ExternalReferenceTable::Add(Address address, int* index) {
  ref_addr_[(*index)++] = address;
143 144
}

145 146 147 148 149 150
void ExternalReferenceTable::AddIsolateIndependent(Address address,
                                                   int* index) {
  ref_addr_isolate_independent_[(*index)++] = address;
}

void ExternalReferenceTable::AddIsolateIndependentReferences(int* index) {
151 152
  CHECK_EQ(kSpecialReferenceCount, *index);

153
#define ADD_EXTERNAL_REFERENCE(name, desc) \
154
  AddIsolateIndependent(ExternalReference::name().address(), index);
155
  EXTERNAL_REFERENCE_LIST(ADD_EXTERNAL_REFERENCE)
156 157
#undef ADD_EXTERNAL_REFERENCE

158 159 160 161 162 163 164 165
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent,
           *index);
}

void ExternalReferenceTable::AddIsolateDependentReferences(Isolate* isolate,
                                                           int* index) {
  CHECK_EQ(kSizeIsolateIndependent, *index);

166
#define ADD_EXTERNAL_REFERENCE(name, desc) \
167
  Add(ExternalReference::name(isolate).address(), index);
168 169 170
  EXTERNAL_REFERENCE_LIST_WITH_ISOLATE(ADD_EXTERNAL_REFERENCE)
#undef ADD_EXTERNAL_REFERENCE

171 172
  CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent,
           *index);
173
}
174

175
void ExternalReferenceTable::AddBuiltins(int* index) {
176 177
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent,
           *index);
178

179 180
  static const Address c_builtins[] = {
#define DEF_ENTRY(Name, ...) FUNCTION_ADDR(&Builtin_##Name),
181 182
      BUILTIN_LIST_C(DEF_ENTRY)
#undef DEF_ENTRY
183
  };
184
  for (Address addr : c_builtins) {
185
    AddIsolateIndependent(ExternalReference::Create(addr).address(), index);
186
  }
187

188
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
189 190
               kBuiltinsReferenceCount,
           *index);
191
}
192

193
void ExternalReferenceTable::AddRuntimeFunctions(int* index) {
194
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
195 196 197
               kBuiltinsReferenceCount,
           *index);

198 199
  static constexpr Runtime::FunctionId runtime_functions[] = {
#define RUNTIME_ENTRY(name, ...) Runtime::k##name,
200 201 202 203
      FOR_EACH_INTRINSIC(RUNTIME_ENTRY)
#undef RUNTIME_ENTRY
  };

204
  for (Runtime::FunctionId fId : runtime_functions) {
205
    AddIsolateIndependent(ExternalReference::Create(fId).address(), index);
206
  }
207

208
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
209 210
               kBuiltinsReferenceCount + kRuntimeReferenceCount,
           *index);
211
}
212

213 214 215 216 217 218 219 220
void ExternalReferenceTable::CopyIsolateIndependentReferences(int* index) {
  CHECK_EQ(0, *index);

  std::copy(ref_addr_isolate_independent_,
            ref_addr_isolate_independent_ + kSizeIsolateIndependent, ref_addr_);
  *index += kSizeIsolateIndependent;
}

221
void ExternalReferenceTable::AddIsolateAddresses(Isolate* isolate, int* index) {
222
  CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent,
223 224
           *index);

225
  for (int i = 0; i < IsolateAddressId::kIsolateAddressCount; ++i) {
226
    Add(isolate->get_address_from_id(static_cast<IsolateAddressId>(i)), index);
227
  }
228

229
  CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
230 231
               kIsolateAddressReferenceCount,
           *index);
232
}
233

234
void ExternalReferenceTable::AddAccessors(int* index) {
235 236
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
               kBuiltinsReferenceCount + kRuntimeReferenceCount,
237 238
           *index);

239 240 241 242
  static const Address accessors[] = {
  // Getters:
#define ACCESSOR_INFO_DECLARATION(_, __, AccessorName, ...) \
  FUNCTION_ADDR(&Accessors::AccessorName##Getter),
243
      ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_DECLARATION, /* not used */)
244
#undef ACCESSOR_INFO_DECLARATION
245 246 247
  // Setters:
#define ACCESSOR_SETTER_DECLARATION(name) FUNCTION_ADDR(&Accessors::name),
          ACCESSOR_SETTER_LIST(ACCESSOR_SETTER_DECLARATION)
248
#undef ACCESSOR_SETTER_DECLARATION
249 250
  };

251
  for (Address addr : accessors) {
252
    AddIsolateIndependent(addr, index);
253
  }
254

255
  CHECK_EQ(kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
256
               kBuiltinsReferenceCount + kRuntimeReferenceCount +
257
               kAccessorReferenceCount,
258
           *index);
259
}
260

261
void ExternalReferenceTable::AddStubCache(Isolate* isolate, int* index) {
262 263
  CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
               kIsolateAddressReferenceCount,
264 265
           *index);

266
  StubCache* load_stub_cache = isolate->load_stub_cache();
267 268

  // Stub cache tables
269 270 271 272 273 274
  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);
275 276 277 278

  StubCache* store_stub_cache = isolate->store_stub_cache();

  // Stub cache tables
279 280 281 282
  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);
283
  Add(store_stub_cache->value_reference(StubCache::kSecondary).address(),
284 285
      index);
  Add(store_stub_cache->map_reference(StubCache::kSecondary).address(), index);
286

287 288
  CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
               kIsolateAddressReferenceCount + kStubCacheReferenceCount,
289
           *index);
290 291 292 293 294 295 296 297 298 299 300
}

Address ExternalReferenceTable::GetStatsCounterAddress(StatsCounter* counter) {
  int* address = counter->Enabled()
                     ? counter->GetInternalPointer()
                     : reinterpret_cast<int*>(&dummy_stats_counter_);
  return reinterpret_cast<Address>(address);
}

void ExternalReferenceTable::AddNativeCodeStatsCounters(Isolate* isolate,
                                                        int* index) {
301 302
  CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
               kIsolateAddressReferenceCount + kStubCacheReferenceCount,
303 304 305 306 307 308 309 310
           *index);

  Counters* counters = isolate->counters();

#define SC(name, caption) Add(GetStatsCounterAddress(counters->name()), index);
  STATS_COUNTER_NATIVE_CODE_LIST(SC)
#undef SC

311 312 313
  CHECK_EQ(kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
               kIsolateAddressReferenceCount + kStubCacheReferenceCount +
               kStatsCountersReferenceCount,
314
           *index);
315
  CHECK_EQ(kSize, *index);
316
}
317 318 319

}  // namespace internal
}  // namespace v8
320 321

#undef SYMBOLIZE_FUNCTION