V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
isolate-data.h
1 // Copyright 2018 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_ISOLATE_DATA_H_
6 #define V8_ISOLATE_DATA_H_
7 
8 #include "src/builtins/builtins.h"
9 #include "src/constants-arch.h"
10 #include "src/external-reference-table.h"
11 #include "src/roots.h"
12 #include "src/utils.h"
13 
14 namespace v8 {
15 namespace internal {
16 
17 class Isolate;
18 
19 // This class contains a collection of data accessible from both C++ runtime
20 // and compiled code (including assembly stubs, builtins, interpreter bytecode
21 // handlers and optimized code).
22 // In particular, it contains pointer to the V8 heap roots table, external
23 // reference table and builtins array.
24 // The compiled code accesses the isolate data fields indirectly via the root
25 // register.
26 class IsolateData final {
27  public:
28  IsolateData() = default;
29 
30  static constexpr intptr_t kIsolateRootBias = kRootRegisterBias;
31 
32  // The value of the kRootRegister.
33  Address isolate_root() const {
34  return reinterpret_cast<Address>(this) + kIsolateRootBias;
35  }
36 
37  // Root-register-relative offset of the roots table.
38  static constexpr int roots_table_offset() {
39  return kRootsTableOffset - kIsolateRootBias;
40  }
41 
42  // Root-register-relative offset of the given root table entry.
43  static constexpr int root_slot_offset(RootIndex root_index) {
44  return roots_table_offset() + RootsTable::offset_of(root_index);
45  }
46 
47  // Root-register-relative offset of the external reference table.
48  static constexpr int external_reference_table_offset() {
49  return kExternalReferenceTableOffset - kIsolateRootBias;
50  }
51 
52  // Root-register-relative offset of the builtins table.
53  static constexpr int builtins_table_offset() {
54  return kBuiltinsTableOffset - kIsolateRootBias;
55  }
56 
57  // Root-register-relative offset of the given builtin table entry.
58  // TODO(ishell): remove in favour of typified id version.
59  static int builtin_slot_offset(int builtin_index) {
60  DCHECK(Builtins::IsBuiltinId(builtin_index));
61  return builtins_table_offset() + builtin_index * kPointerSize;
62  }
63 
64  // Root-register-relative offset of the builtin table entry.
65  static int builtin_slot_offset(Builtins::Name id) {
66  return builtins_table_offset() + id * kPointerSize;
67  }
68 
69  // Root-register-relative offset of the virtual call target register value.
70  static constexpr int virtual_call_target_register_offset() {
71  return kVirtualCallTargetRegisterOffset - kIsolateRootBias;
72  }
73 
74  // Returns true if this address points to data stored in this instance.
75  // If it's the case then the value can be accessed indirectly through the
76  // root register.
77  bool contains(Address address) const {
78  STATIC_ASSERT(std::is_unsigned<Address>::value);
79  Address start = reinterpret_cast<Address>(this);
80  return (address - start) < sizeof(*this);
81  }
82 
83  RootsTable& roots() { return roots_; }
84  const RootsTable& roots() const { return roots_; }
85 
86  ExternalReferenceTable* external_reference_table() {
87  return &external_reference_table_;
88  }
89 
90  Address* builtins() { return builtins_; }
91 
92  private:
93 // Static layout definition.
94 #define FIELDS(V) \
95  V(kEmbedderDataOffset, Internals::kNumIsolateDataSlots* kPointerSize) \
96  V(kExternalMemoryOffset, kInt64Size) \
97  V(kExternalMemoryLlimitOffset, kInt64Size) \
98  V(kExternalMemoryAtLastMarkCompactOffset, kInt64Size) \
99  V(kRootsTableOffset, RootsTable::kEntriesCount* kPointerSize) \
100  V(kExternalReferenceTableOffset, ExternalReferenceTable::SizeInBytes()) \
101  V(kBuiltinsTableOffset, Builtins::builtin_count* kPointerSize) \
102  V(kVirtualCallTargetRegisterOffset, kPointerSize) \
103  /* This padding aligns IsolateData size by 8 bytes. */ \
104  V(kPaddingOffset, \
105  8 + RoundUp<8>(static_cast<int>(kPaddingOffset)) - kPaddingOffset) \
106  /* Total size. */ \
107  V(kSize, 0)
108 
109  DEFINE_FIELD_OFFSET_CONSTANTS(0, FIELDS)
110 #undef FIELDS
111 
112  // These fields are accessed through the API, offsets must be kept in sync
113  // with v8::internal::Internals (in include/v8-internal.h) constants.
114  // The layout consitency is verified in Isolate::CheckIsolateLayout() using
115  // runtime checks.
116  void* embedder_data_[Internals::kNumIsolateDataSlots] = {};
117 
118  // TODO(ishell): Move these external memory counters back to Heap once the
119  // Node JS bot issue is solved.
120  // The amount of external memory registered through the API.
121  int64_t external_memory_ = 0;
122 
123  // The limit when to trigger memory pressure from the API.
124  int64_t external_memory_limit_ = kExternalAllocationSoftLimit;
125 
126  // Caches the amount of external memory registered at the last MC.
127  int64_t external_memory_at_last_mark_compact_ = 0;
128 
129  RootsTable roots_;
130 
131  ExternalReferenceTable external_reference_table_;
132 
133  // The entries in this array are tagged pointers to Code objects.
134  Address builtins_[Builtins::builtin_count] = {};
135 
136  // For isolate-independent calls on ia32.
137  // TODO(v8:6666): Remove once wasm supports pc-relative jumps to builtins on
138  // ia32 (otherwise the arguments adaptor call runs out of registers).
139  void* virtual_call_target_register_ = nullptr;
140 
141  // Ensure the size is 8-byte aligned in order to make alignment of the field
142  // following the IsolateData field predictable. This solves the issue with
143  // C++ compilers for 32-bit platforms which are not consistent at aligning
144  // int64_t fields.
145  // In order to avoid dealing with zero-size arrays the padding size is always
146  // in the range [8, 15).
147  STATIC_ASSERT(kPaddingOffsetEnd + 1 - kPaddingOffset >= 8);
148  char padding_[kPaddingOffsetEnd + 1 - kPaddingOffset];
149 
150  V8_INLINE static void AssertPredictableLayout();
151 
152  friend class Isolate;
153  friend class Heap;
154  FRIEND_TEST(HeapTest, ExternalLimitDefault);
155  FRIEND_TEST(HeapTest, ExternalLimitStaysAboveDefaultForExplicitHandling);
156 
157  DISALLOW_COPY_AND_ASSIGN(IsolateData);
158 };
159 
160 // IsolateData object must have "predictable" layout which does not change when
161 // cross-compiling to another platform. Otherwise there may be compatibility
162 // issues because of different compilers used for snapshot generator and
163 // actual V8 code.
164 void IsolateData::AssertPredictableLayout() {
165  STATIC_ASSERT(std::is_standard_layout<RootsTable>::value);
166  STATIC_ASSERT(std::is_standard_layout<ExternalReferenceTable>::value);
167  STATIC_ASSERT(std::is_standard_layout<IsolateData>::value);
168  STATIC_ASSERT(offsetof(IsolateData, roots_) == kRootsTableOffset);
169  STATIC_ASSERT(offsetof(IsolateData, external_reference_table_) ==
170  kExternalReferenceTableOffset);
171  STATIC_ASSERT(offsetof(IsolateData, builtins_) == kBuiltinsTableOffset);
172  STATIC_ASSERT(offsetof(IsolateData, virtual_call_target_register_) ==
173  kVirtualCallTargetRegisterOffset);
174  STATIC_ASSERT(offsetof(IsolateData, external_memory_) ==
175  kExternalMemoryOffset);
176  STATIC_ASSERT(offsetof(IsolateData, external_memory_limit_) ==
177  kExternalMemoryLlimitOffset);
178  STATIC_ASSERT(offsetof(IsolateData, external_memory_at_last_mark_compact_) ==
179  kExternalMemoryAtLastMarkCompactOffset);
180  STATIC_ASSERT(sizeof(IsolateData) == IsolateData::kSize);
181 }
182 
183 } // namespace internal
184 } // namespace v8
185 
186 #endif // V8_ISOLATE_DATA_H_
Definition: libplatform.h:13