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