• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Note 1: Any file that includes this one should include object-macros-undef.h
6 // at the bottom.
7 
8 // Note 2: This file is deliberately missing the include guards (the undeffing
9 // approach wouldn't work otherwise).
10 //
11 // PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD
12 
13 // The accessors with RELAXED_, ACQUIRE_, and RELEASE_ prefixes should be used
14 // for fields that can be written to and read from multiple threads at the same
15 // time. See comments in src/base/atomicops.h for the memory ordering sematics.
16 
17 #include "src/base/memory.h"
18 
19 // Since this changes visibility, it should always be last in a class
20 // definition.
21 #define OBJECT_CONSTRUCTORS(Type, ...)             \
22  public:                                           \
23   constexpr Type() : __VA_ARGS__() {}              \
24                                                    \
25  protected:                                        \
26   template <typename TFieldType, int kFieldOffset> \
27   friend class TaggedField;                        \
28                                                    \
29   explicit inline Type(Address ptr)
30 
31 #define OBJECT_CONSTRUCTORS_IMPL(Type, Super) \
32   inline Type::Type(Address ptr) : Super(ptr) { SLOW_DCHECK(Is##Type()); }
33 
34 #define NEVER_READ_ONLY_SPACE   \
35   inline Heap* GetHeap() const; \
36   inline Isolate* GetIsolate() const;
37 
38 // TODO(leszeks): Add checks in the factory that we never allocate these
39 // objects in RO space.
40 #define NEVER_READ_ONLY_SPACE_IMPL(Type)                                   \
41   Heap* Type::GetHeap() const { return GetHeapFromWritableObject(*this); } \
42   Isolate* Type::GetIsolate() const {                                      \
43     return GetIsolateFromWritableObject(*this);                            \
44   }
45 
46 #define DECL_PRIMITIVE_GETTER(name, type) inline type name() const;
47 
48 #define DECL_PRIMITIVE_SETTER(name, type) inline void set_##name(type value);
49 
50 #define DECL_PRIMITIVE_ACCESSORS(name, type) \
51   DECL_PRIMITIVE_GETTER(name, type)          \
52   DECL_PRIMITIVE_SETTER(name, type)
53 
54 #define DECL_BOOLEAN_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, bool)
55 
56 #define DECL_INT_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int)
57 
58 #define DECL_INT32_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int32_t)
59 
60 #define DECL_SANDBOXED_POINTER_ACCESSORS(name, type) \
61   DECL_PRIMITIVE_GETTER(name, type)                  \
62   DECL_PRIMITIVE_SETTER(name, type)
63 
64 #define DECL_UINT16_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, uint16_t)
65 
66 #define DECL_INT16_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int16_t)
67 
68 #define DECL_UINT8_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, uint8_t)
69 
70 #define DECL_RELAXED_PRIMITIVE_ACCESSORS(name, type) \
71   inline type name(RelaxedLoadTag) const;            \
72   inline void set_##name(type value, RelaxedStoreTag);
73 
74 #define DECL_RELAXED_INT32_ACCESSORS(name) \
75   DECL_RELAXED_PRIMITIVE_ACCESSORS(name, int32_t)
76 
77 #define DECL_RELAXED_UINT16_ACCESSORS(name) \
78   DECL_RELAXED_PRIMITIVE_ACCESSORS(name, uint16_t)
79 
80 // TODO(ishell): eventually isolate-less getters should not be used anymore.
81 // For full pointer-mode the C++ compiler should optimize away unused isolate
82 // parameter.
83 #define DECL_GETTER(name, type) \
84   inline type name() const;     \
85   inline type name(PtrComprCageBase cage_base) const;
86 
87 #define DEF_GETTER(holder, name, type)                       \
88   type holder::name() const {                                \
89     PtrComprCageBase cage_base = GetPtrComprCageBase(*this); \
90     return holder::name(cage_base);                          \
91   }                                                          \
92   type holder::name(PtrComprCageBase cage_base) const
93 
94 #define DEF_RELAXED_GETTER(holder, name, type)               \
95   type holder::name(RelaxedLoadTag tag) const {              \
96     PtrComprCageBase cage_base = GetPtrComprCageBase(*this); \
97     return holder::name(cage_base, tag);                     \
98   }                                                          \
99   type holder::name(PtrComprCageBase cage_base, RelaxedLoadTag) const
100 
101 #define DEF_ACQUIRE_GETTER(holder, name, type)               \
102   type holder::name(AcquireLoadTag tag) const {              \
103     PtrComprCageBase cage_base = GetPtrComprCageBase(*this); \
104     return holder::name(cage_base, tag);                     \
105   }                                                          \
106   type holder::name(PtrComprCageBase cage_base, AcquireLoadTag) const
107 
108 #define TQ_FIELD_TYPE(name, tq_type) \
109   static constexpr const char* k##name##TqFieldType = tq_type;
110 
111 #define DECL_FIELD_OFFSET_TQ(name, value, tq_type) \
112   static const int k##name##Offset = value;        \
113   TQ_FIELD_TYPE(name, tq_type)
114 
115 #define DECL_SETTER(name, type)      \
116   inline void set_##name(type value, \
117                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
118 
119 #define DECL_ACCESSORS(name, type) \
120   DECL_GETTER(name, type)          \
121   DECL_SETTER(name, type)
122 
123 #define DECL_ACCESSORS_LOAD_TAG(name, type, tag_type) \
124   inline type name(tag_type tag) const;               \
125   inline type name(PtrComprCageBase cage_base, tag_type) const;
126 
127 #define DECL_ACCESSORS_STORE_TAG(name, type, tag_type) \
128   inline void set_##name(type value, tag_type,         \
129                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
130 
131 #define DECL_RELAXED_GETTER(name, type) \
132   DECL_ACCESSORS_LOAD_TAG(name, type, RelaxedLoadTag)
133 
134 #define DECL_RELAXED_SETTER(name, type) \
135   DECL_ACCESSORS_STORE_TAG(name, type, RelaxedStoreTag)
136 
137 #define DECL_RELAXED_ACCESSORS(name, type) \
138   DECL_RELAXED_GETTER(name, type)          \
139   DECL_RELAXED_SETTER(name, type)
140 
141 #define DECL_ACQUIRE_GETTER(name, type) \
142   DECL_ACCESSORS_LOAD_TAG(name, type, AcquireLoadTag)
143 
144 #define DECL_RELEASE_SETTER(name, type) \
145   DECL_ACCESSORS_STORE_TAG(name, type, ReleaseStoreTag)
146 
147 #define DECL_RELEASE_ACQUIRE_ACCESSORS(name, type) \
148   DECL_ACQUIRE_GETTER(name, type)                  \
149   DECL_RELEASE_SETTER(name, type)
150 
151 #define DECL_RELEASE_ACQUIRE_WEAK_ACCESSORS(name) \
152   DECL_ACQUIRE_GETTER(name, MaybeObject)          \
153   DECL_RELEASE_SETTER(name, MaybeObject)
154 
155 #define DECL_CAST(Type)                                 \
156   V8_INLINE static Type cast(Object object);            \
157   V8_INLINE static Type unchecked_cast(Object object) { \
158     return bit_cast<Type>(object);                      \
159   }
160 
161 #define CAST_ACCESSOR(Type) \
162   Type Type::cast(Object object) { return Type(object.ptr()); }
163 
164 #define DEF_PRIMITIVE_ACCESSORS(holder, name, offset, type)     \
165   type holder::name() const { return ReadField<type>(offset); } \
166   void holder::set_##name(type value) { WriteField<type>(offset, value); }
167 
168 #define INT_ACCESSORS(holder, name, offset) \
169   DEF_PRIMITIVE_ACCESSORS(holder, name, offset, int)
170 
171 #define INT32_ACCESSORS(holder, name, offset) \
172   DEF_PRIMITIVE_ACCESSORS(holder, name, offset, int32_t)
173 
174 #define UINT16_ACCESSORS(holder, name, offset) \
175   DEF_PRIMITIVE_ACCESSORS(holder, name, offset, uint16_t)
176 
177 #define UINT8_ACCESSORS(holder, name, offset) \
178   DEF_PRIMITIVE_ACCESSORS(holder, name, offset, uint8_t)
179 
180 #define RELAXED_INT32_ACCESSORS(holder, name, offset)       \
181   int32_t holder::name(RelaxedLoadTag) const {              \
182     return RELAXED_READ_INT32_FIELD(*this, offset);         \
183   }                                                         \
184   void holder::set_##name(int32_t value, RelaxedStoreTag) { \
185     RELAXED_WRITE_INT32_FIELD(*this, offset, value);        \
186   }
187 
188 #define RELAXED_UINT16_ACCESSORS(holder, name, offset)       \
189   uint16_t holder::name(RelaxedLoadTag) const {              \
190     return RELAXED_READ_UINT16_FIELD(*this, offset);         \
191   }                                                          \
192   void holder::set_##name(uint16_t value, RelaxedStoreTag) { \
193     RELAXED_WRITE_UINT16_FIELD(*this, offset, value);        \
194   }
195 
196 #define ACCESSORS_CHECKED2(holder, name, type, offset, get_condition, \
197                            set_condition)                             \
198   DEF_GETTER(holder, name, type) {                                    \
199     type value = TaggedField<type, offset>::load(cage_base, *this);   \
200     DCHECK(get_condition);                                            \
201     return value;                                                     \
202   }                                                                   \
203   void holder::set_##name(type value, WriteBarrierMode mode) {        \
204     DCHECK(set_condition);                                            \
205     TaggedField<type, offset>::store(*this, value);                   \
206     CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);            \
207   }
208 
209 #define ACCESSORS_CHECKED(holder, name, type, offset, condition) \
210   ACCESSORS_CHECKED2(holder, name, type, offset, condition, condition)
211 
212 #define ACCESSORS(holder, name, type, offset) \
213   ACCESSORS_CHECKED(holder, name, type, offset, true)
214 
215 #define RENAME_TORQUE_ACCESSORS(holder, name, torque_name, type)      \
216   inline type holder::name() const {                                  \
217     return TorqueGeneratedClass::torque_name();                       \
218   }                                                                   \
219   inline void holder::set_##name(type value, WriteBarrierMode mode) { \
220     TorqueGeneratedClass::set_##torque_name(value, mode);             \
221   }
222 
223 #define RENAME_PRIMITIVE_TORQUE_ACCESSORS(holder, name, torque_name, type)  \
224   type holder::name() const { return TorqueGeneratedClass::torque_name(); } \
225   void holder::set_##name(type value) {                                     \
226     TorqueGeneratedClass::set_##torque_name(value);                         \
227   }
228 
229 #define ACCESSORS_RELAXED_CHECKED2(holder, name, type, offset, get_condition, \
230                                    set_condition)                             \
231   type holder::name() const {                                                 \
232     PtrComprCageBase cage_base = GetPtrComprCageBase(*this);                  \
233     return holder::name(cage_base);                                           \
234   }                                                                           \
235   type holder::name(PtrComprCageBase cage_base) const {                       \
236     type value = TaggedField<type, offset>::Relaxed_Load(cage_base, *this);   \
237     DCHECK(get_condition);                                                    \
238     return value;                                                             \
239   }                                                                           \
240   void holder::set_##name(type value, WriteBarrierMode mode) {                \
241     DCHECK(set_condition);                                                    \
242     TaggedField<type, offset>::Relaxed_Store(*this, value);                   \
243     CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);                    \
244   }
245 
246 #define ACCESSORS_RELAXED_CHECKED(holder, name, type, offset, condition) \
247   ACCESSORS_RELAXED_CHECKED2(holder, name, type, offset, condition, condition)
248 
249 #define ACCESSORS_RELAXED(holder, name, type, offset) \
250   ACCESSORS_RELAXED_CHECKED(holder, name, type, offset, true)
251 
252 // Similar to ACCESSORS_RELAXED above but with respective relaxed tags.
253 #define RELAXED_ACCESSORS_CHECKED2(holder, name, type, offset, get_condition, \
254                                    set_condition)                             \
255   DEF_RELAXED_GETTER(holder, name, type) {                                    \
256     type value = TaggedField<type, offset>::Relaxed_Load(cage_base, *this);   \
257     DCHECK(get_condition);                                                    \
258     return value;                                                             \
259   }                                                                           \
260   void holder::set_##name(type value, RelaxedStoreTag,                        \
261                           WriteBarrierMode mode) {                            \
262     DCHECK(set_condition);                                                    \
263     TaggedField<type, offset>::Relaxed_Store(*this, value);                   \
264     CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);                    \
265   }
266 
267 #define RELAXED_ACCESSORS_CHECKED(holder, name, type, offset, condition) \
268   RELAXED_ACCESSORS_CHECKED2(holder, name, type, offset, condition, condition)
269 
270 #define RELAXED_ACCESSORS(holder, name, type, offset) \
271   RELAXED_ACCESSORS_CHECKED(holder, name, type, offset, true)
272 
273 #define RELEASE_ACQUIRE_ACCESSORS_CHECKED2(holder, name, type, offset,      \
274                                            get_condition, set_condition)    \
275   DEF_ACQUIRE_GETTER(holder, name, type) {                                  \
276     type value = TaggedField<type, offset>::Acquire_Load(cage_base, *this); \
277     DCHECK(get_condition);                                                  \
278     return value;                                                           \
279   }                                                                         \
280   void holder::set_##name(type value, ReleaseStoreTag,                      \
281                           WriteBarrierMode mode) {                          \
282     DCHECK(set_condition);                                                  \
283     TaggedField<type, offset>::Release_Store(*this, value);                 \
284     CONDITIONAL_WRITE_BARRIER(*this, offset, value, mode);                  \
285   }
286 
287 #define RELEASE_ACQUIRE_ACCESSORS_CHECKED(holder, name, type, offset,       \
288                                           condition)                        \
289   RELEASE_ACQUIRE_ACCESSORS_CHECKED2(holder, name, type, offset, condition, \
290                                      condition)
291 
292 #define RELEASE_ACQUIRE_ACCESSORS(holder, name, type, offset) \
293   RELEASE_ACQUIRE_ACCESSORS_CHECKED(holder, name, type, offset, true)
294 
295 #define WEAK_ACCESSORS_CHECKED2(holder, name, offset, get_condition,  \
296                                 set_condition)                        \
297   DEF_GETTER(holder, name, MaybeObject) {                             \
298     MaybeObject value =                                               \
299         TaggedField<MaybeObject, offset>::load(cage_base, *this);     \
300     DCHECK(get_condition);                                            \
301     return value;                                                     \
302   }                                                                   \
303   void holder::set_##name(MaybeObject value, WriteBarrierMode mode) { \
304     DCHECK(set_condition);                                            \
305     TaggedField<MaybeObject, offset>::store(*this, value);            \
306     CONDITIONAL_WEAK_WRITE_BARRIER(*this, offset, value, mode);       \
307   }
308 
309 #define WEAK_ACCESSORS_CHECKED(holder, name, offset, condition) \
310   WEAK_ACCESSORS_CHECKED2(holder, name, offset, condition, condition)
311 
312 #define WEAK_ACCESSORS(holder, name, offset) \
313   WEAK_ACCESSORS_CHECKED(holder, name, offset, true)
314 
315 #define RELEASE_ACQUIRE_WEAK_ACCESSORS_CHECKED2(holder, name, offset,         \
316                                                 get_condition, set_condition) \
317   DEF_ACQUIRE_GETTER(holder, name, MaybeObject) {                             \
318     MaybeObject value =                                                       \
319         TaggedField<MaybeObject, offset>::Acquire_Load(cage_base, *this);     \
320     DCHECK(get_condition);                                                    \
321     return value;                                                             \
322   }                                                                           \
323   void holder::set_##name(MaybeObject value, ReleaseStoreTag,                 \
324                           WriteBarrierMode mode) {                            \
325     DCHECK(set_condition);                                                    \
326     TaggedField<MaybeObject, offset>::Release_Store(*this, value);            \
327     CONDITIONAL_WEAK_WRITE_BARRIER(*this, offset, value, mode);               \
328   }
329 
330 #define RELEASE_ACQUIRE_WEAK_ACCESSORS_CHECKED(holder, name, offset,       \
331                                                condition)                  \
332   RELEASE_ACQUIRE_WEAK_ACCESSORS_CHECKED2(holder, name, offset, condition, \
333                                           condition)
334 
335 #define RELEASE_ACQUIRE_WEAK_ACCESSORS(holder, name, offset) \
336   RELEASE_ACQUIRE_WEAK_ACCESSORS_CHECKED(holder, name, offset, true)
337 
338 // Getter that returns a Smi as an int and writes an int as a Smi.
339 #define SMI_ACCESSORS_CHECKED(holder, name, offset, condition)   \
340   int holder::name() const {                                     \
341     DCHECK(condition);                                           \
342     Smi value = TaggedField<Smi, offset>::load(*this);           \
343     return value.value();                                        \
344   }                                                              \
345   void holder::set_##name(int value) {                           \
346     DCHECK(condition);                                           \
347     TaggedField<Smi, offset>::store(*this, Smi::FromInt(value)); \
348   }
349 
350 #define SMI_ACCESSORS(holder, name, offset) \
351   SMI_ACCESSORS_CHECKED(holder, name, offset, true)
352 
353 #define DECL_RELEASE_ACQUIRE_INT_ACCESSORS(name) \
354   inline int name(AcquireLoadTag) const;         \
355   inline void set_##name(int value, ReleaseStoreTag);
356 
357 #define RELEASE_ACQUIRE_SMI_ACCESSORS(holder, name, offset)              \
358   int holder::name(AcquireLoadTag) const {                               \
359     Smi value = TaggedField<Smi, offset>::Acquire_Load(*this);           \
360     return value.value();                                                \
361   }                                                                      \
362   void holder::set_##name(int value, ReleaseStoreTag) {                  \
363     TaggedField<Smi, offset>::Release_Store(*this, Smi::FromInt(value)); \
364   }
365 
366 #define DECL_RELAXED_SMI_ACCESSORS(name) \
367   inline int name(RelaxedLoadTag) const; \
368   inline void set_##name(int value, RelaxedStoreTag);
369 
370 #define RELAXED_SMI_ACCESSORS(holder, name, offset)                      \
371   int holder::name(RelaxedLoadTag) const {                               \
372     Smi value = TaggedField<Smi, offset>::Relaxed_Load(*this);           \
373     return value.value();                                                \
374   }                                                                      \
375   void holder::set_##name(int value, RelaxedStoreTag) {                  \
376     TaggedField<Smi, offset>::Relaxed_Store(*this, Smi::FromInt(value)); \
377   }
378 
379 #define BOOL_GETTER(holder, field, name, offset) \
380   bool holder::name() const { return BooleanBit::get(field(), offset); }
381 
382 #define BOOL_ACCESSORS(holder, field, name, offset)                      \
383   bool holder::name() const { return BooleanBit::get(field(), offset); } \
384   void holder::set_##name(bool value) {                                  \
385     set_##field(BooleanBit::set(field(), offset, value));                \
386   }
387 
388 #define DECL_RELAXED_BOOL_ACCESSORS(name) \
389   inline bool name(RelaxedLoadTag) const; \
390   inline void set_##name(bool value, RelaxedStoreTag);
391 
392 #define RELAXED_BOOL_ACCESSORS(holder, field, name, offset)          \
393   bool holder::name(RelaxedLoadTag) const {                          \
394     return BooleanBit::get(field(kRelaxedLoad), offset);             \
395   }                                                                  \
396   void holder::set_##name(bool value, RelaxedStoreTag) {             \
397     set_##field(BooleanBit::set(field(kRelaxedLoad), offset, value), \
398                 kRelaxedStore);                                      \
399   }
400 
401 #define BIT_FIELD_ACCESSORS2(holder, get_field, set_field, name, BitField) \
402   typename BitField::FieldType holder::name() const {                      \
403     return BitField::decode(get_field());                                  \
404   }                                                                        \
405   void holder::set_##name(typename BitField::FieldType value) {            \
406     set_##set_field(BitField::update(set_field(), value));                 \
407   }
408 
409 #define BIT_FIELD_ACCESSORS(holder, field, name, BitField) \
410   BIT_FIELD_ACCESSORS2(holder, field, field, name, BitField)
411 
412 #define RELAXED_INT16_ACCESSORS(holder, name, offset) \
413   int16_t holder::name() const {                      \
414     return RELAXED_READ_INT16_FIELD(*this, offset);   \
415   }                                                   \
416   void holder::set_##name(int16_t value) {            \
417     RELAXED_WRITE_INT16_FIELD(*this, offset, value);  \
418   }
419 
420 #define FIELD_ADDR(p, offset) ((p).ptr() + offset - kHeapObjectTag)
421 
422 #define SEQ_CST_READ_FIELD(p, offset) \
423   TaggedField<Object>::SeqCst_Load(p, offset)
424 
425 #define ACQUIRE_READ_FIELD(p, offset) \
426   TaggedField<Object>::Acquire_Load(p, offset)
427 
428 #define RELAXED_READ_FIELD(p, offset) \
429   TaggedField<Object>::Relaxed_Load(p, offset)
430 
431 #define RELAXED_READ_WEAK_FIELD(p, offset) \
432   TaggedField<MaybeObject>::Relaxed_Load(p, offset)
433 
434 #define WRITE_FIELD(p, offset, value) \
435   TaggedField<Object>::store(p, offset, value)
436 
437 #define SEQ_CST_WRITE_FIELD(p, offset, value) \
438   TaggedField<Object>::SeqCst_Store(p, offset, value)
439 
440 #define RELEASE_WRITE_FIELD(p, offset, value) \
441   TaggedField<Object>::Release_Store(p, offset, value)
442 
443 #define RELAXED_WRITE_FIELD(p, offset, value) \
444   TaggedField<Object>::Relaxed_Store(p, offset, value)
445 
446 #define RELAXED_WRITE_WEAK_FIELD(p, offset, value) \
447   TaggedField<MaybeObject>::Relaxed_Store(p, offset, value)
448 
449 #ifdef V8_DISABLE_WRITE_BARRIERS
450 #define WRITE_BARRIER(object, offset, value)
451 #else
452 #define WRITE_BARRIER(object, offset, value)                         \
453   do {                                                               \
454     DCHECK_NOT_NULL(GetHeapFromWritableObject(object));              \
455     WriteBarrier::Marking(object, (object).RawField(offset), value); \
456     GenerationalBarrier(object, (object).RawField(offset), value);   \
457   } while (false)
458 #endif
459 
460 #ifdef V8_DISABLE_WRITE_BARRIERS
461 #define WEAK_WRITE_BARRIER(object, offset, value)
462 #else
463 #define WEAK_WRITE_BARRIER(object, offset, value)                             \
464   do {                                                                        \
465     DCHECK_NOT_NULL(GetHeapFromWritableObject(object));                       \
466     WriteBarrier::Marking(object, (object).RawMaybeWeakField(offset), value); \
467     GenerationalBarrier(object, (object).RawMaybeWeakField(offset), value);   \
468   } while (false)
469 #endif
470 
471 #ifdef V8_DISABLE_WRITE_BARRIERS
472 #define EPHEMERON_KEY_WRITE_BARRIER(object, offset, value)
473 #elif V8_ENABLE_UNCONDITIONAL_WRITE_BARRIERS
474 #define EPHEMERON_KEY_WRITE_BARRIER(object, offset, value) \
475   WRITE_BARRIER(object, offset, value)
476 #else
477 #define EPHEMERON_KEY_WRITE_BARRIER(object, offset, value)                    \
478   do {                                                                        \
479     DCHECK_NOT_NULL(GetHeapFromWritableObject(object));                       \
480     EphemeronHashTable table = EphemeronHashTable::cast(object);              \
481     WriteBarrier::Marking(object, (object).RawField(offset), value);          \
482     GenerationalEphemeronKeyBarrier(table, (object).RawField(offset), value); \
483   } while (false)
484 #endif
485 
486 #ifdef V8_DISABLE_WRITE_BARRIERS
487 #define CONDITIONAL_WRITE_BARRIER(object, offset, value, mode)
488 #elif V8_ENABLE_UNCONDITIONAL_WRITE_BARRIERS
489 #define CONDITIONAL_WRITE_BARRIER(object, offset, value, mode) \
490   WRITE_BARRIER(object, offset, value)
491 #else
492 #define CONDITIONAL_WRITE_BARRIER(object, offset, value, mode)           \
493   do {                                                                   \
494     DCHECK_NOT_NULL(GetHeapFromWritableObject(object));                  \
495     DCHECK_NE(mode, UPDATE_EPHEMERON_KEY_WRITE_BARRIER);                 \
496     if (mode != SKIP_WRITE_BARRIER) {                                    \
497       if (mode == UPDATE_WRITE_BARRIER) {                                \
498         WriteBarrier::Marking(object, (object).RawField(offset), value); \
499       }                                                                  \
500       GenerationalBarrier(object, (object).RawField(offset), value);     \
501     } else {                                                             \
502       SLOW_DCHECK(!WriteBarrier::IsRequired(object, value));             \
503     }                                                                    \
504   } while (false)
505 #endif
506 
507 #ifdef V8_DISABLE_WRITE_BARRIERS
508 #define CONDITIONAL_WEAK_WRITE_BARRIER(object, offset, value, mode)
509 #elif V8_ENABLE_UNCONDITIONAL_WRITE_BARRIERS
510 #define CONDITIONAL_WEAK_WRITE_BARRIER(object, offset, value, mode) \
511   WRITE_BARRIER(object, offset, value)
512 #else
513 #define CONDITIONAL_WEAK_WRITE_BARRIER(object, offset, value, mode)           \
514   do {                                                                        \
515     DCHECK_NOT_NULL(GetHeapFromWritableObject(object));                       \
516     DCHECK_NE(mode, UPDATE_EPHEMERON_KEY_WRITE_BARRIER);                      \
517     if (mode != SKIP_WRITE_BARRIER) {                                         \
518       if (mode == UPDATE_WRITE_BARRIER) {                                     \
519         WriteBarrier::Marking(object, (object).RawMaybeWeakField(offset),     \
520                               value);                                         \
521       }                                                                       \
522       GenerationalBarrier(object, (object).RawMaybeWeakField(offset), value); \
523     } else {                                                                  \
524       SLOW_DCHECK(!WriteBarrier::IsRequired(object, value));                  \
525     }                                                                         \
526   } while (false)
527 #endif
528 
529 #ifdef V8_DISABLE_WRITE_BARRIERS
530 #define CONDITIONAL_EPHEMERON_KEY_WRITE_BARRIER(object, offset, value, mode)
531 #else
532 #define CONDITIONAL_EPHEMERON_KEY_WRITE_BARRIER(object, offset, value, mode) \
533   do {                                                                       \
534     DCHECK_NOT_NULL(GetHeapFromWritableObject(object));                      \
535     DCHECK_NE(mode, UPDATE_EPHEMERON_KEY_WRITE_BARRIER);                     \
536     EphemeronHashTable table = EphemeronHashTable::cast(object);             \
537     if (mode != SKIP_WRITE_BARRIER) {                                        \
538       if (mode == UPDATE_WRITE_BARRIER) {                                    \
539         WriteBarrier::Marking(object, (object).RawField(offset), value);     \
540       }                                                                      \
541       GenerationalEphemeronKeyBarrier(table, (object).RawField(offset),      \
542                                       value);                                \
543     } else {                                                                 \
544       SLOW_DCHECK(!WriteBarrier::IsRequired(object, value));                 \
545     }                                                                        \
546   } while (false)
547 #endif
548 
549 #define ACQUIRE_READ_INT8_FIELD(p, offset) \
550   static_cast<int8_t>(base::Acquire_Load(  \
551       reinterpret_cast<const base::Atomic8*>(FIELD_ADDR(p, offset))))
552 
553 #define ACQUIRE_READ_INT32_FIELD(p, offset) \
554   static_cast<int32_t>(base::Acquire_Load(  \
555       reinterpret_cast<const base::Atomic32*>(FIELD_ADDR(p, offset))))
556 
557 #define RELAXED_WRITE_INT8_FIELD(p, offset, value)                             \
558   base::Relaxed_Store(reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
559                       static_cast<base::Atomic8>(value));
560 #define RELAXED_READ_INT8_FIELD(p, offset) \
561   static_cast<int8_t>(base::Relaxed_Load(  \
562       reinterpret_cast<const base::Atomic8*>(FIELD_ADDR(p, offset))))
563 
564 #define RELAXED_READ_UINT16_FIELD(p, offset) \
565   static_cast<uint16_t>(base::Relaxed_Load(  \
566       reinterpret_cast<const base::Atomic16*>(FIELD_ADDR(p, offset))))
567 
568 #define RELAXED_WRITE_UINT16_FIELD(p, offset, value)            \
569   base::Relaxed_Store(                                          \
570       reinterpret_cast<base::Atomic16*>(FIELD_ADDR(p, offset)), \
571       static_cast<base::Atomic16>(value));
572 
573 #define RELAXED_READ_INT16_FIELD(p, offset) \
574   static_cast<int16_t>(base::Relaxed_Load(  \
575       reinterpret_cast<const base::Atomic16*>(FIELD_ADDR(p, offset))))
576 
577 #define RELAXED_WRITE_INT16_FIELD(p, offset, value)             \
578   base::Relaxed_Store(                                          \
579       reinterpret_cast<base::Atomic16*>(FIELD_ADDR(p, offset)), \
580       static_cast<base::Atomic16>(value));
581 
582 #define RELAXED_READ_UINT32_FIELD(p, offset) \
583   static_cast<uint32_t>(base::Relaxed_Load(  \
584       reinterpret_cast<const base::Atomic32*>(FIELD_ADDR(p, offset))))
585 
586 #define ACQUIRE_READ_UINT32_FIELD(p, offset) \
587   static_cast<uint32_t>(base::Acquire_Load(  \
588       reinterpret_cast<const base::Atomic32*>(FIELD_ADDR(p, offset))))
589 
590 #define RELAXED_WRITE_UINT32_FIELD(p, offset, value)            \
591   base::Relaxed_Store(                                          \
592       reinterpret_cast<base::Atomic32*>(FIELD_ADDR(p, offset)), \
593       static_cast<base::Atomic32>(value));
594 
595 #define RELEASE_WRITE_INT8_FIELD(p, offset, value)                             \
596   base::Release_Store(reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
597                       static_cast<base::Atomic8>(value));
598 
599 #define RELEASE_WRITE_UINT32_FIELD(p, offset, value)            \
600   base::Release_Store(                                          \
601       reinterpret_cast<base::Atomic32*>(FIELD_ADDR(p, offset)), \
602       static_cast<base::Atomic32>(value));
603 
604 #define RELAXED_READ_INT32_FIELD(p, offset) \
605   static_cast<int32_t>(base::Relaxed_Load(  \
606       reinterpret_cast<const base::Atomic32*>(FIELD_ADDR(p, offset))))
607 
608 #define RELEASE_WRITE_INT32_FIELD(p, offset, value)             \
609   base::Release_Store(                                          \
610       reinterpret_cast<base::Atomic32*>(FIELD_ADDR(p, offset)), \
611       static_cast<base::Atomic32>(value))
612 
613 #define RELAXED_WRITE_INT32_FIELD(p, offset, value)             \
614   base::Relaxed_Store(                                          \
615       reinterpret_cast<base::Atomic32*>(FIELD_ADDR(p, offset)), \
616       static_cast<base::Atomic32>(value))
617 
618 static_assert(sizeof(int) == sizeof(int32_t),
619               "sizeof int must match sizeof int32_t");
620 
621 #define RELAXED_READ_INT_FIELD(p, offset) RELAXED_READ_INT32_FIELD(p, offset)
622 
623 #define RELAXED_WRITE_INT_FIELD(p, offset, value) \
624   RELAXED_WRITE_INT32_FIELD(p, offset, value)
625 
626 static_assert(sizeof(unsigned) == sizeof(uint32_t),
627               "sizeof unsigned must match sizeof uint32_t");
628 
629 #define RELAXED_READ_UINT_FIELD(p, offset) RELAXED_READ_UINT32_FIELD(p, offset)
630 
631 #define RELAXED_WRITE_UINT_FIELD(p, offset, value) \
632   RELAXED_WRITE_UINT32_FIELD(p, offset, value)
633 
634 #define RELAXED_READ_BYTE_FIELD(p, offset) \
635   static_cast<byte>(base::Relaxed_Load(    \
636       reinterpret_cast<const base::Atomic8*>(FIELD_ADDR(p, offset))))
637 
638 #define ACQUIRE_READ_BYTE_FIELD(p, offset) \
639   static_cast<byte>(base::Acquire_Load(    \
640       reinterpret_cast<const base::Atomic8*>(FIELD_ADDR(p, offset))))
641 
642 #define RELAXED_WRITE_BYTE_FIELD(p, offset, value)                             \
643   base::Relaxed_Store(reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
644                       static_cast<base::Atomic8>(value));
645 
646 #define RELEASE_WRITE_BYTE_FIELD(p, offset, value)                             \
647   base::Release_Store(reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
648                       static_cast<base::Atomic8>(value));
649 
650 #ifdef OBJECT_PRINT
651 #define DECL_PRINTER(Name) void Name##Print(std::ostream& os);
652 #else
653 #define DECL_PRINTER(Name)
654 #endif
655 
656 #ifdef VERIFY_HEAP
657 #define DECL_VERIFIER(Name) void Name##Verify(Isolate* isolate);
658 #define EXPORT_DECL_VERIFIER(Name) \
659   V8_EXPORT_PRIVATE void Name##Verify(Isolate* isolate);
660 #else
661 #define DECL_VERIFIER(Name)
662 #define EXPORT_DECL_VERIFIER(Name)
663 #endif
664 
665 #define DEFINE_DEOPT_ELEMENT_ACCESSORS(name, type) \
666   type DeoptimizationData::name() const {          \
667     return type::cast(get(k##name##Index));        \
668   }                                                \
669   void DeoptimizationData::Set##name(type value) { set(k##name##Index, value); }
670 
671 #define DEFINE_DEOPT_ENTRY_ACCESSORS(name, type)                \
672   type DeoptimizationData::name(int i) const {                  \
673     return type::cast(get(IndexForEntry(i) + k##name##Offset)); \
674   }                                                             \
675   void DeoptimizationData::Set##name(int i, type value) {       \
676     set(IndexForEntry(i) + k##name##Offset, value);             \
677   }
678 
679 #define TQ_OBJECT_CONSTRUCTORS(Type)               \
680  public:                                           \
681   constexpr Type() = default;                      \
682                                                    \
683  protected:                                        \
684   template <typename TFieldType, int kFieldOffset> \
685   friend class TaggedField;                        \
686                                                    \
687   inline explicit Type(Address ptr);               \
688   friend class TorqueGenerated##Type<Type, Super>;
689 
690 #define TQ_OBJECT_CONSTRUCTORS_IMPL(Type) \
691   inline Type::Type(Address ptr)          \
692       : TorqueGenerated##Type<Type, Type::Super>(ptr) {}
693 
694 #define TQ_CPP_OBJECT_DEFINITION_ASSERTS(_class, parent) \
695   template class TorqueGenerated##_class##Asserts<_class, parent>;
696