1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
// 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.
#ifndef V8_CODEGEN_EXTERNAL_REFERENCE_TABLE_H_
#define V8_CODEGEN_EXTERNAL_REFERENCE_TABLE_H_
#include "src/builtins/accessors.h"
#include "src/builtins/builtins.h"
#include "src/codegen/external-reference.h"
#include "src/logging/counters-definitions.h"
namespace v8 {
namespace internal {
class Isolate;
// ExternalReferenceTable is a helper class that defines the relationship
// between external references and their encodings. It is used to build
// hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder.
class ExternalReferenceTable {
public:
// For the nullptr ref, see the constructor.
static constexpr int kSpecialReferenceCount = 1;
static constexpr int kExternalReferenceCountIsolateIndependent =
ExternalReference::kExternalReferenceCountIsolateIndependent;
static constexpr int kExternalReferenceCountIsolateDependent =
ExternalReference::kExternalReferenceCountIsolateDependent;
static constexpr int kBuiltinsReferenceCount =
#define COUNT_C_BUILTIN(...) +1
BUILTIN_LIST_C(COUNT_C_BUILTIN);
#undef COUNT_C_BUILTIN
static constexpr int kRuntimeReferenceCount =
Runtime::kNumFunctions -
Runtime::kNumInlineFunctions; // Don't count dupe kInline... functions.
static constexpr int kIsolateAddressReferenceCount = kIsolateAddressCount;
static constexpr int kAccessorReferenceCount =
Accessors::kAccessorInfoCount + Accessors::kAccessorGetterCount +
Accessors::kAccessorSetterCount + Accessors::kAccessorCallbackCount;
// The number of stub cache external references, see AddStubCache.
static constexpr int kStubCacheReferenceCount = 12;
static constexpr int kStatsCountersReferenceCount =
#define SC(...) +1
STATS_COUNTER_NATIVE_CODE_LIST(SC);
#undef SC
static constexpr int kSizeIsolateIndependent =
kSpecialReferenceCount + kExternalReferenceCountIsolateIndependent +
kBuiltinsReferenceCount + kRuntimeReferenceCount +
kAccessorReferenceCount;
static constexpr int kSize =
kSizeIsolateIndependent + kExternalReferenceCountIsolateDependent +
kIsolateAddressReferenceCount + kStubCacheReferenceCount +
kStatsCountersReferenceCount;
static constexpr uint32_t kEntrySize =
static_cast<uint32_t>(kSystemPointerSize);
static constexpr uint32_t kSizeInBytes = kSize * kEntrySize + 2 * kUInt32Size;
Address address(uint32_t i) const { return ref_addr_[i]; }
const char* name(uint32_t i) const { return ref_name_[i]; }
bool is_initialized() const { return is_initialized_ == kInitialized; }
static const char* ResolveSymbol(void* address);
static constexpr uint32_t OffsetOfEntry(uint32_t i) {
// Used in CodeAssembler::LookupExternalReference.
return i * kEntrySize;
}
static void InitializeOncePerProcess();
static const char* NameOfIsolateIndependentAddress(Address address);
const char* NameFromOffset(uint32_t offset) {
DCHECK_EQ(offset % kEntrySize, 0);
DCHECK_LT(offset, kSizeInBytes);
int index = offset / kEntrySize;
return name(index);
}
ExternalReferenceTable() = default;
ExternalReferenceTable(const ExternalReferenceTable&) = delete;
ExternalReferenceTable& operator=(const ExternalReferenceTable&) = delete;
void InitIsolateIndependent(); // Step 1.
void Init(Isolate* isolate); // Step 2.
private:
static void AddIsolateIndependent(Address address, int* index);
static void AddIsolateIndependentReferences(int* index);
static void AddBuiltins(int* index);
static void AddRuntimeFunctions(int* index);
static void AddAccessors(int* index);
void Add(Address address, int* index);
void CopyIsolateIndependentReferences(int* index);
void AddIsolateDependentReferences(Isolate* isolate, int* index);
void AddIsolateAddresses(Isolate* isolate, int* index);
void AddStubCache(Isolate* isolate, int* index);
Address GetStatsCounterAddress(StatsCounter* counter);
void AddNativeCodeStatsCounters(Isolate* isolate, int* index);
static_assert(sizeof(Address) == kEntrySize);
#ifdef DEBUG
Address ref_addr_[kSize] = {kNullAddress};
#else
Address ref_addr_[kSize];
#endif // DEBUG
static const char* const ref_name_[kSize];
enum InitializationState : uint32_t {
kUninitialized,
kInitializedIsolateIndependent,
kInitialized,
};
InitializationState is_initialized_ = kUninitialized;
// Redirect disabled stats counters to this field. This is done to make sure
// we can have a snapshot that includes native counters even when the embedder
// isn't collecting them.
// This field is uint32_t since the MacroAssembler and CodeStubAssembler
// accesses this field as a uint32_t.
uint32_t dummy_stats_counter_ = 0;
};
static_assert(ExternalReferenceTable::kSizeInBytes ==
sizeof(ExternalReferenceTable));
} // namespace internal
} // namespace v8
#endif // V8_CODEGEN_EXTERNAL_REFERENCE_TABLE_H_
|