@@ -20,13 +20,39 @@ namespace internal {
2020
2121class Isolate ;
2222
23+ // IsolateData fields, defined as: V(Offset, Size, Name)
24+ #define ISOLATE_DATA_FIELDS (V ) \
25+ V (kEmbedderDataOffset , Internals::kNumIsolateDataSlots * kSystemPointerSize , \
26+ embedder_data) \
27+ V (kFastCCallCallerFPOffset , kSystemPointerSize , fast_c_call_caller_fp) \
28+ V (kFastCCallCallerPCOffset , kSystemPointerSize , fast_c_call_caller_pc) \
29+ V (kFastApiCallTargetOffset , kSystemPointerSize , fast_api_call_target) \
30+ V (kCageBaseOffset , kSystemPointerSize , cage_base) \
31+ V (kLongTaskStatsCounterOffset , kSizetSize , long_task_stats_counter) \
32+ V (kStackGuardOffset , StackGuard::kSizeInBytes , stack_guard) \
33+ V (kRootsTableOffset , RootsTable::kEntriesCount * kSystemPointerSize , \
34+ roots_table) \
35+ V (kExternalReferenceTableOffset , ExternalReferenceTable::kSizeInBytes , \
36+ external_reference_table) \
37+ V (kThreadLocalTopOffset , ThreadLocalTop::kSizeInBytes , thread_local_top) \
38+ V (kBuiltinEntryTableOffset , Builtins::kBuiltinCount * kSystemPointerSize , \
39+ builtin_entry_table) \
40+ V (kBuiltinTableOffset , Builtins::kBuiltinCount * kSystemPointerSize , \
41+ builtin_table) \
42+ ISOLATE_DATA_FIELDS_HEAP_SANDBOX (V) \
43+ V (kStackIsIterableOffset , kUInt8Size , stack_is_iterable)
44+
45+ #ifdef V8_HEAP_SANDBOX
46+ #define ISOLATE_DATA_FIELDS_HEAP_SANDBOX (V ) \
47+ V (kExternalPointerTableOffset , kSystemPointerSize * 3 , external_pointer_table)
48+ #else
49+ #define ISOLATE_DATA_FIELDS_HEAP_SANDBOX (V )
50+ #endif // V8_HEAP_SANDBOX
51+
2352// This class contains a collection of data accessible from both C++ runtime
24- // and compiled code (including assembly stubs, builtins, interpreter bytecode
25- // handlers and optimized code).
26- // In particular, it contains pointer to the V8 heap roots table, external
27- // reference table and builtins array.
28- // The compiled code accesses the isolate data fields indirectly via the root
29- // register.
53+ // and compiled code (including builtins, interpreter bytecode handlers and
54+ // optimized code). The compiled code accesses the isolate data fields
55+ // indirectly via the root register.
3056class IsolateData final {
3157 public:
3258 IsolateData (Isolate* isolate, Address cage_base)
@@ -37,170 +63,106 @@ class IsolateData final {
3763
3864 static constexpr intptr_t kIsolateRootBias = kRootRegisterBias ;
3965
40- // The value of kPointerCageBaseRegister
41- Address cage_base () const {
42- return COMPRESS_POINTERS_BOOL ? cage_base_ : kNullAddress ;
43- }
44-
4566 // The value of the kRootRegister.
4667 Address isolate_root () const {
4768 return reinterpret_cast <Address>(this ) + kIsolateRootBias ;
4869 }
4970
50- // Root-register-relative offset of the roots table.
51- static constexpr int roots_table_offset () {
52- return kRootsTableOffset - kIsolateRootBias ;
53- }
71+ // Root-register-relative offsets.
72+
73+ #define V (Offset, Size, Name ) \
74+ static constexpr int Name##_offset() { return Offset - kIsolateRootBias ; }
75+ ISOLATE_DATA_FIELDS (V)
76+ #undef V
5477
55- // Root-register-relative offset of the given root table entry.
5678 static constexpr int root_slot_offset (RootIndex root_index) {
5779 return roots_table_offset () + RootsTable::offset_of (root_index);
5880 }
5981
60- // Root-register-relative offset of the external reference table.
61- static constexpr int external_reference_table_offset () {
62- return kExternalReferenceTableOffset - kIsolateRootBias ;
63- }
64-
65- // Root-register-relative offset of the builtin entry table.
66- static constexpr int builtin_entry_table_offset () {
67- return kBuiltinEntryTableOffset - kIsolateRootBias ;
68- }
69- static constexpr int builtin_entry_slot_offset (Builtin builtin) {
70- DCHECK (Builtins::IsBuiltinId (builtin));
82+ static int builtin_entry_slot_offset (Builtin id) {
7183 return builtin_entry_table_offset () +
72- static_cast <int >(builtin) * kSystemPointerSize ;
73- }
74-
75- // Root-register-relative offset of the builtins table.
76- static constexpr int builtins_table_offset () {
77- return kBuiltinsTableOffset - kIsolateRootBias ;
78- }
79-
80- // Root-register-relative offset of the external pointer table.
81- #ifdef V8_HEAP_SANDBOX
82- static constexpr int external_pointer_table_offset () {
83- return kExternalPointerTableOffset - kIsolateRootBias ;
84- }
85- #endif
86-
87- static constexpr int fast_c_call_caller_fp_offset () {
88- return kFastCCallCallerFPOffset - kIsolateRootBias ;
89- }
90-
91- static constexpr int fast_c_call_caller_pc_offset () {
92- return kFastCCallCallerPCOffset - kIsolateRootBias ;
84+ Builtins::ToInt (id) * kSystemPointerSize ;
9385 }
9486
95- static constexpr int fast_api_call_target_offset () {
96- return kFastApiCallTargetOffset - kIsolateRootBias ;
97- }
98-
99- static constexpr int cage_base_offset () {
100- return kCageBaseOffset - kIsolateRootBias ;
101- }
102-
103- // Root-register-relative offset of the given builtin table entry.
10487 // TODO(ishell): remove in favour of typified id version.
10588 static int builtin_slot_offset (int builtin_index) {
10689 DCHECK (Builtins::IsBuiltinId (builtin_index));
107- return builtins_table_offset () + builtin_index * kSystemPointerSize ;
90+ return builtin_table_offset () + builtin_index * kSystemPointerSize ;
10891 }
10992
110- // Root-register-relative offset of the builtin table entry.
11193 static int builtin_slot_offset (Builtin id) {
112- return builtins_table_offset () + static_cast < int > (id) * kSystemPointerSize ;
94+ return builtin_table_offset () + Builtins::ToInt (id) * kSystemPointerSize ;
11395 }
11496
115- // The FP and PC that are saved right before TurboAssembler::CallCFunction.
116- Address* fast_c_call_caller_fp_address () { return &fast_c_call_caller_fp_; }
117- Address* fast_c_call_caller_pc_address () { return &fast_c_call_caller_pc_; }
118- // The address of the fast API callback right before it's executed from
119- // generated code.
120- Address* fast_api_call_target_address () { return &fast_api_call_target_; }
97+ #define V (Offset, Size, Name ) \
98+ Address Name##_address() { return reinterpret_cast <Address>(&Name##_); }
99+ ISOLATE_DATA_FIELDS (V)
100+ #undef V
101+
102+ Address fast_c_call_caller_fp () const { return fast_c_call_caller_fp_; }
103+ Address fast_c_call_caller_pc () const { return fast_c_call_caller_pc_; }
104+ Address fast_api_call_target () const { return fast_api_call_target_; }
105+ // The value of kPointerCageBaseRegister.
106+ Address cage_base () const { return cage_base_; }
121107 StackGuard* stack_guard () { return &stack_guard_; }
122- uint8_t * stack_is_iterable_address () { return &stack_is_iterable_; }
123- Address fast_c_call_caller_fp () { return fast_c_call_caller_fp_; }
124- Address fast_c_call_caller_pc () { return fast_c_call_caller_pc_; }
125- Address fast_api_call_target () { return fast_api_call_target_; }
126- uint8_t stack_is_iterable () { return stack_is_iterable_; }
127-
128- // Returns true if this address points to data stored in this instance.
129- // If it's the case then the value can be accessed indirectly through the
130- // root register.
131- bool contains (Address address) const {
132- STATIC_ASSERT (std::is_unsigned<Address>::value);
133- Address start = reinterpret_cast <Address>(this );
134- return (address - start) < sizeof (*this );
108+ RootsTable& roots () { return roots_table_; }
109+ const RootsTable& roots () const { return roots_table_; }
110+ ExternalReferenceTable* external_reference_table () {
111+ return &external_reference_table_;
135112 }
136-
137113 ThreadLocalTop& thread_local_top () { return thread_local_top_; }
138114 ThreadLocalTop const & thread_local_top () const { return thread_local_top_; }
115+ Address* builtin_entry_table () { return builtin_entry_table_; }
116+ Address* builtin_table () { return builtin_table_; }
117+ uint8_t stack_is_iterable () const { return stack_is_iterable_; }
139118
140- RootsTable& roots () { return roots_; }
141- const RootsTable& roots () const { return roots_; }
142-
143- ExternalReferenceTable* external_reference_table () {
144- return &external_reference_table_;
119+ // Returns true if this address points to data stored in this instance. If
120+ // it's the case then the value can be accessed indirectly through the root
121+ // register.
122+ bool contains (Address address) const {
123+ STATIC_ASSERT (std::is_unsigned<Address>::value);
124+ Address start = reinterpret_cast <Address>(this );
125+ return (address - start) < sizeof (*this );
145126 }
146127
147- Address* builtin_entry_table () { return builtin_entry_table_; }
148- Address* builtins () { return builtins_; }
149-
150128 private:
151129 // Static layout definition.
152130 //
153131 // Note: The location of fields within IsolateData is significant. The
154132 // closer they are to the value of kRootRegister (i.e.: isolate_root()), the
155133 // cheaper it is to access them. See also: https://crbug.com/993264.
156- // The recommend guideline is to put frequently-accessed fields close to the
157- // beginning of IsolateData.
158- #define FIELDS (V ) \
159- V (kEmbedderDataOffset , Internals::kNumIsolateDataSlots * kSystemPointerSize ) \
160- V (kFastCCallCallerFPOffset , kSystemPointerSize ) \
161- V (kFastCCallCallerPCOffset , kSystemPointerSize ) \
162- V (kFastApiCallTargetOffset , kSystemPointerSize ) \
163- V (kCageBaseOffset , kSystemPointerSize ) \
164- V (kLongTaskStatsCounterOffset , kSizetSize ) \
165- V (kStackGuardOffset , StackGuard::kSizeInBytes ) \
166- V (kRootsTableOffset , RootsTable::kEntriesCount * kSystemPointerSize ) \
167- V (kExternalReferenceTableOffset , ExternalReferenceTable::kSizeInBytes ) \
168- V (kThreadLocalTopOffset , ThreadLocalTop::kSizeInBytes ) \
169- V (kBuiltinEntryTableOffset , Builtins::kBuiltinCount * kSystemPointerSize ) \
170- V (kBuiltinsTableOffset , Builtins::kBuiltinCount * kSystemPointerSize ) \
171- FIELDS_HEAP_SANDBOX (V) \
172- V (kStackIsIterableOffset , kUInt8Size ) \
173- /* This padding aligns IsolateData size by 8 bytes. */ \
174- V (kPaddingOffset , \
175- 8 + RoundUp<8 >(static_cast <int >(kPaddingOffset )) - kPaddingOffset ) \
176- /* Total size. */ \
134+ // The recommended guideline is to put frequently-accessed fields close to
135+ // the beginning of IsolateData.
136+ #define FIELDS (V ) \
137+ ISOLATE_DATA_FIELDS (V) \
138+ /* This padding aligns IsolateData size by 8 bytes. */ \
139+ V (kPaddingOffset , \
140+ 8 + RoundUp<8 >(static_cast <int >(kPaddingOffset )) - kPaddingOffset ) \
141+ /* Total size. */ \
177142 V (kSize , 0 )
178143
179- #ifdef V8_HEAP_SANDBOX
180- #define FIELDS_HEAP_SANDBOX (V ) \
181- V (kExternalPointerTableOffset , kSystemPointerSize * 3 )
182- #else
183- #define FIELDS_HEAP_SANDBOX (V )
184- #endif // V8_HEAP_SANDBOX
185-
186144 DEFINE_FIELD_OFFSET_CONSTANTS (0 , FIELDS)
187145#undef FIELDS
188146
189147 // These fields are accessed through the API, offsets must be kept in sync
190- // with v8::internal::Internals (in include/v8-internal.h) constants.
191- // The layout consitency is verified in Isolate::CheckIsolateLayout() using
148+ // with v8::internal::Internals (in include/v8-internal.h) constants. The
149+ // layout consistency is verified in Isolate::CheckIsolateLayout() using
192150 // runtime checks.
193151 void * embedder_data_[Internals::kNumIsolateDataSlots ] = {};
194152
195153 // Stores the state of the caller for TurboAssembler::CallCFunction so that
196154 // the sampling CPU profiler can iterate the stack during such calls. These
197155 // are stored on IsolateData so that they can be stored to with only one move
198156 // instruction in compiled code.
157+ //
158+ // The FP and PC that are saved right before TurboAssembler::CallCFunction.
199159 Address fast_c_call_caller_fp_ = kNullAddress ;
200160 Address fast_c_call_caller_pc_ = kNullAddress ;
161+ // The address of the fast API callback right before it's executed from
162+ // generated code.
201163 Address fast_api_call_target_ = kNullAddress ;
202164
203- Address cage_base_ = kNullAddress ;
165+ const Address cage_base_;
204166
205167 // Used for implementation of LongTaskStats. Counts the number of potential
206168 // long tasks.
@@ -210,8 +172,7 @@ class IsolateData final {
210172 // the stack limit used by stack checks in generated code.
211173 StackGuard stack_guard_;
212174
213- RootsTable roots_;
214-
175+ RootsTable roots_table_;
215176 ExternalReferenceTable external_reference_table_;
216177
217178 ThreadLocalTop thread_local_top_;
@@ -222,7 +183,7 @@ class IsolateData final {
222183 Address builtin_entry_table_[Builtins::kBuiltinCount ] = {};
223184
224185 // The entries in this array are tagged pointers to Code objects.
225- Address builtins_ [Builtins::kBuiltinCount ] = {};
186+ Address builtin_table_ [Builtins::kBuiltinCount ] = {};
226187
227188 // Table containing pointers to external objects.
228189#ifdef V8_HEAP_SANDBOX
@@ -259,31 +220,16 @@ void IsolateData::AssertPredictableLayout() {
259220 STATIC_ASSERT (std::is_standard_layout<ThreadLocalTop>::value);
260221 STATIC_ASSERT (std::is_standard_layout<ExternalReferenceTable>::value);
261222 STATIC_ASSERT (std::is_standard_layout<IsolateData>::value);
262- STATIC_ASSERT (offsetof (IsolateData, roots_) == kRootsTableOffset );
263- STATIC_ASSERT (offsetof (IsolateData, external_reference_table_) ==
264- kExternalReferenceTableOffset );
265- STATIC_ASSERT (offsetof (IsolateData, thread_local_top_) ==
266- kThreadLocalTopOffset );
267- STATIC_ASSERT (offsetof (IsolateData, builtins_) == kBuiltinsTableOffset );
268- STATIC_ASSERT (offsetof (IsolateData, fast_c_call_caller_fp_) ==
269- kFastCCallCallerFPOffset );
270- STATIC_ASSERT (offsetof (IsolateData, fast_c_call_caller_pc_) ==
271- kFastCCallCallerPCOffset );
272- STATIC_ASSERT (offsetof (IsolateData, fast_api_call_target_) ==
273- kFastApiCallTargetOffset );
274- STATIC_ASSERT (offsetof (IsolateData, cage_base_) == kCageBaseOffset );
275- STATIC_ASSERT (offsetof (IsolateData, long_task_stats_counter_) ==
276- kLongTaskStatsCounterOffset );
277- STATIC_ASSERT (offsetof (IsolateData, stack_guard_) == kStackGuardOffset );
278- #ifdef V8_HEAP_SANDBOX
279- STATIC_ASSERT (offsetof (IsolateData, external_pointer_table_) ==
280- kExternalPointerTableOffset );
281- #endif
282- STATIC_ASSERT (offsetof (IsolateData, stack_is_iterable_) ==
283- kStackIsIterableOffset );
223+ #define V (Offset, Size, Name ) \
224+ STATIC_ASSERT (offsetof (IsolateData, Name##_) == Offset);
225+ ISOLATE_DATA_FIELDS (V)
226+ #undef V
284227 STATIC_ASSERT (sizeof (IsolateData) == IsolateData::kSize );
285228}
286229
230+ #undef ISOLATE_DATA_FIELDS_HEAP_SANDBOX
231+ #undef ISOLATE_DATA_FIELDS
232+
287233} // namespace internal
288234} // namespace v8
289235
0 commit comments