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 #ifndef V8_EXTERNAL_REFERENCE_TABLE_H_
6 #define V8_EXTERNAL_REFERENCE_TABLE_H_
7 
8 #include <vector>
9 
10 #include "src/accessors.h"
11 #include "src/builtins/builtins.h"
12 #include "src/external-reference.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 class Isolate;
18 
19 // ExternalReferenceTable is a helper class that defines the relationship
20 // between external references and their encodings. It is used to build
21 // hashmaps in ExternalReferenceEncoder and ExternalReferenceDecoder.
22 class ExternalReferenceTable {
23  public:
24   // For the nullptr ref, see the constructor.
25   static constexpr int kSpecialReferenceCount = 1;
26   static constexpr int kExternalReferenceCount =
27       ExternalReference::kExternalReferenceCount;
28   static constexpr int kBuiltinsReferenceCount =
29 #define COUNT_C_BUILTIN(...) +1
30       BUILTIN_LIST_C(COUNT_C_BUILTIN);
31 #undef COUNT_C_BUILTIN
32   static constexpr int kRuntimeReferenceCount =
33       Runtime::kNumFunctions / 2;  // Don't count dupe kInline... functions.
34   static constexpr int kIsolateAddressReferenceCount = kIsolateAddressCount;
35   static constexpr int kAccessorReferenceCount =
36       Accessors::kAccessorInfoCount + Accessors::kAccessorSetterCount;
37   // The number of stub cache external references, see AddStubCache.
38   static constexpr int kStubCacheReferenceCount = 12;
39   static constexpr int kSize =
40       kSpecialReferenceCount + kExternalReferenceCount +
41       kBuiltinsReferenceCount + kRuntimeReferenceCount +
42       kIsolateAddressReferenceCount + kAccessorReferenceCount +
43       kStubCacheReferenceCount;
44 
size()45   static constexpr uint32_t size() { return static_cast<uint32_t>(kSize); }
address(uint32_t i)46   Address address(uint32_t i) { return refs_[i].address; }
name(uint32_t i)47   const char* name(uint32_t i) { return refs_[i].name; }
48 
is_initialized()49   bool is_initialized() const { return is_initialized_ != 0; }
50 
51   static const char* ResolveSymbol(void* address);
52 
EntrySize()53   static constexpr uint32_t EntrySize() {
54     return sizeof(ExternalReferenceEntry);
55   }
56 
OffsetOfEntry(uint32_t i)57   static constexpr uint32_t OffsetOfEntry(uint32_t i) {
58     // Used in CodeAssembler::LookupExternalReference.
59     STATIC_ASSERT(offsetof(ExternalReferenceEntry, address) == 0);
60     return i * EntrySize();
61   }
62 
NameFromOffset(uint32_t offset)63   const char* NameFromOffset(uint32_t offset) {
64     DCHECK_EQ(offset % EntrySize(), 0);
65     DCHECK_LT(offset, SizeInBytes());
66     int index = offset / EntrySize();
67     return name(index);
68   }
69 
SizeInBytes()70   static constexpr uint32_t SizeInBytes() {
71     STATIC_ASSERT(OffsetOfEntry(size()) + 2 * kUInt32Size ==
72                   sizeof(ExternalReferenceTable));
73     return OffsetOfEntry(size()) + 2 * kUInt32Size;
74   }
75 
ExternalReferenceTable()76   ExternalReferenceTable() {}
77   void Init(Isolate* isolate);
78 
79  private:
80   struct ExternalReferenceEntry {
81     Address address;
82     const char* name;
83 
ExternalReferenceEntryExternalReferenceEntry84     ExternalReferenceEntry() : address(kNullAddress), name(nullptr) {}
ExternalReferenceEntryExternalReferenceEntry85     ExternalReferenceEntry(Address address, const char* name)
86         : address(address), name(name) {}
87   };
88 
89   void Add(Address address, const char* name, int* index);
90 
91   void AddReferences(Isolate* isolate, int* index);
92   void AddBuiltins(int* index);
93   void AddRuntimeFunctions(int* index);
94   void AddIsolateAddresses(Isolate* isolate, int* index);
95   void AddAccessors(int* index);
96   void AddStubCache(Isolate* isolate, int* index);
97 
98   ExternalReferenceEntry refs_[kSize];
99   uint32_t is_initialized_ = 0;  // Not bool to guarantee deterministic size.
100   uint32_t unused_padding_ = 0;  // For alignment.
101 
102   DISALLOW_COPY_AND_ASSIGN(ExternalReferenceTable);
103 };
104 
105 }  // namespace internal
106 }  // namespace v8
107 #endif  // V8_EXTERNAL_REFERENCE_TABLE_H_
108