• 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/v8memory.h>
18 
19 #define DECL_PRIMITIVE_ACCESSORS(name, type) \
20   inline type name() const;                  \
21   inline void set_##name(type value);
22 
23 #define DECL_BOOLEAN_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, bool)
24 
25 #define DECL_INT_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int)
26 
27 #define DECL_INT32_ACCESSORS(name) DECL_PRIMITIVE_ACCESSORS(name, int32_t)
28 
29 #define DECL_UINT16_ACCESSORS(name) \
30   inline uint16_t name() const;     \
31   inline void set_##name(int value);
32 
33 #define DECL_UINT8_ACCESSORS(name) \
34   inline uint8_t name() const;     \
35   inline void set_##name(int value);
36 
37 #define DECL_ACCESSORS(name, type)    \
38   inline type* name() const;          \
39   inline void set_##name(type* value, \
40                          WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
41 
42 #define DECL_CAST(type)                        \
43   V8_INLINE static type* cast(Object* object); \
44   V8_INLINE static const type* cast(const Object* object);
45 
46 #define CAST_ACCESSOR(type)                       \
47   type* type::cast(Object* object) {              \
48     SLOW_DCHECK(object->Is##type());              \
49     return reinterpret_cast<type*>(object);       \
50   }                                               \
51   const type* type::cast(const Object* object) {  \
52     SLOW_DCHECK(object->Is##type());              \
53     return reinterpret_cast<const type*>(object); \
54   }
55 
56 #define INT_ACCESSORS(holder, name, offset)                         \
57   int holder::name() const { return READ_INT_FIELD(this, offset); } \
58   void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
59 
60 #define INT32_ACCESSORS(holder, name, offset)                             \
61   int32_t holder::name() const { return READ_INT32_FIELD(this, offset); } \
62   void holder::set_##name(int32_t value) {                                \
63     WRITE_INT32_FIELD(this, offset, value);                               \
64   }
65 
66 #define UINT16_ACCESSORS(holder, name, offset)                              \
67   uint16_t holder::name() const { return READ_UINT16_FIELD(this, offset); } \
68   void holder::set_##name(int value) {                                      \
69     DCHECK_GE(value, 0);                                                    \
70     DCHECK_LE(value, static_cast<uint16_t>(-1));                            \
71     WRITE_UINT16_FIELD(this, offset, value);                                \
72   }
73 
74 #define UINT8_ACCESSORS(holder, name, offset)                             \
75   uint8_t holder::name() const { return READ_UINT8_FIELD(this, offset); } \
76   void holder::set_##name(int value) {                                    \
77     DCHECK_GE(value, 0);                                                  \
78     DCHECK_LE(value, static_cast<uint8_t>(-1));                           \
79     WRITE_UINT8_FIELD(this, offset, value);                               \
80   }
81 
82 #define ACCESSORS_CHECKED2(holder, name, type, offset, get_condition, \
83                            set_condition)                             \
84   type* holder::name() const {                                        \
85     type* value = type::cast(READ_FIELD(this, offset));               \
86     DCHECK(get_condition);                                            \
87     return value;                                                     \
88   }                                                                   \
89   void holder::set_##name(type* value, WriteBarrierMode mode) {       \
90     DCHECK(set_condition);                                            \
91     WRITE_FIELD(this, offset, value);                                 \
92     CONDITIONAL_WRITE_BARRIER(this, offset, value, mode);             \
93   }
94 #define ACCESSORS_CHECKED(holder, name, type, offset, condition) \
95   ACCESSORS_CHECKED2(holder, name, type, offset, condition, condition)
96 
97 #define ACCESSORS(holder, name, type, offset) \
98   ACCESSORS_CHECKED(holder, name, type, offset, true)
99 
100 #define WEAK_ACCESSORS_CHECKED2(holder, name, offset, get_condition,   \
101                                 set_condition)                         \
102   MaybeObject* holder::name() const {                                  \
103     MaybeObject* value = READ_WEAK_FIELD(this, offset);                \
104     DCHECK(get_condition);                                             \
105     return value;                                                      \
106   }                                                                    \
107   void holder::set_##name(MaybeObject* value, WriteBarrierMode mode) { \
108     DCHECK(set_condition);                                             \
109     WRITE_WEAK_FIELD(this, offset, value);                             \
110     CONDITIONAL_WEAK_WRITE_BARRIER(this, offset, value, mode);         \
111   }
112 
113 #define WEAK_ACCESSORS_CHECKED(holder, name, offset, condition) \
114   WEAK_ACCESSORS_CHECKED2(holder, name, offset, condition, condition)
115 
116 #define WEAK_ACCESSORS(holder, name, offset) \
117   WEAK_ACCESSORS_CHECKED(holder, name, offset, true)
118 
119 // Getter that returns a Smi as an int and writes an int as a Smi.
120 #define SMI_ACCESSORS_CHECKED(holder, name, offset, condition) \
121   int holder::name() const {                                   \
122     DCHECK(condition);                                         \
123     Object* value = READ_FIELD(this, offset);                  \
124     return Smi::ToInt(value);                                  \
125   }                                                            \
126   void holder::set_##name(int value) {                         \
127     DCHECK(condition);                                         \
128     WRITE_FIELD(this, offset, Smi::FromInt(value));            \
129   }
130 
131 #define SMI_ACCESSORS(holder, name, offset) \
132   SMI_ACCESSORS_CHECKED(holder, name, offset, true)
133 
134 #define SYNCHRONIZED_SMI_ACCESSORS(holder, name, offset)    \
135   int holder::synchronized_##name() const {                 \
136     Object* value = ACQUIRE_READ_FIELD(this, offset);       \
137     return Smi::ToInt(value);                               \
138   }                                                         \
139   void holder::synchronized_set_##name(int value) {         \
140     RELEASE_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
141   }
142 
143 #define RELAXED_SMI_ACCESSORS(holder, name, offset)         \
144   int holder::relaxed_read_##name() const {                 \
145     Object* value = RELAXED_READ_FIELD(this, offset);       \
146     return Smi::ToInt(value);                               \
147   }                                                         \
148   void holder::relaxed_write_##name(int value) {            \
149     RELAXED_WRITE_FIELD(this, offset, Smi::FromInt(value)); \
150   }
151 
152 #define BOOL_GETTER(holder, field, name, offset) \
153   bool holder::name() const { return BooleanBit::get(field(), offset); }
154 
155 #define BOOL_ACCESSORS(holder, field, name, offset)                      \
156   bool holder::name() const { return BooleanBit::get(field(), offset); } \
157   void holder::set_##name(bool value) {                                  \
158     set_##field(BooleanBit::set(field(), offset, value));                \
159   }
160 
161 #define BIT_FIELD_ACCESSORS(holder, field, name, BitField)      \
162   typename BitField::FieldType holder::name() const {           \
163     return BitField::decode(field());                           \
164   }                                                             \
165   void holder::set_##name(typename BitField::FieldType value) { \
166     set_##field(BitField::update(field(), value));              \
167   }
168 
169 #define INSTANCE_TYPE_CHECKER(type, forinstancetype)    \
170   V8_INLINE bool Is##type(InstanceType instance_type) { \
171     return instance_type == forinstancetype;            \
172   }
173 
174 #define TYPE_CHECKER(type, ...)                                   \
175   bool HeapObject::Is##type() const {                             \
176     return InstanceTypeChecker::Is##type(map()->instance_type()); \
177   }
178 
179 #define FIELD_ADDR(p, offset) \
180   (reinterpret_cast<Address>(p) + offset - kHeapObjectTag)
181 
182 #define READ_FIELD(p, offset) \
183   (*reinterpret_cast<Object* const*>(FIELD_ADDR(p, offset)))
184 
185 #define READ_WEAK_FIELD(p, offset) \
186   (*reinterpret_cast<MaybeObject* const*>(FIELD_ADDR(p, offset)))
187 
188 #define ACQUIRE_READ_FIELD(p, offset)           \
189   reinterpret_cast<Object*>(base::Acquire_Load( \
190       reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR(p, offset))))
191 
192 #define RELAXED_READ_FIELD(p, offset)           \
193   reinterpret_cast<Object*>(base::Relaxed_Load( \
194       reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR(p, offset))))
195 
196 #define RELAXED_READ_WEAK_FIELD(p, offset)           \
197   reinterpret_cast<MaybeObject*>(base::Relaxed_Load( \
198       reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR(p, offset))))
199 
200 #ifdef V8_CONCURRENT_MARKING
201 #define WRITE_FIELD(p, offset, value)                             \
202   base::Relaxed_Store(                                            \
203       reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
204       reinterpret_cast<base::AtomicWord>(value));
205 #define WRITE_WEAK_FIELD(p, offset, value)                        \
206   base::Relaxed_Store(                                            \
207       reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
208       reinterpret_cast<base::AtomicWord>(value));
209 #else
210 #define WRITE_FIELD(p, offset, value) \
211   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
212 #define WRITE_WEAK_FIELD(p, offset, value) \
213   (*reinterpret_cast<MaybeObject**>(FIELD_ADDR(p, offset)) = value)
214 #endif
215 
216 #define RELEASE_WRITE_FIELD(p, offset, value)                     \
217   base::Release_Store(                                            \
218       reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
219       reinterpret_cast<base::AtomicWord>(value));
220 
221 #define RELAXED_WRITE_FIELD(p, offset, value)                     \
222   base::Relaxed_Store(                                            \
223       reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
224       reinterpret_cast<base::AtomicWord>(value));
225 
226 #define WRITE_BARRIER(object, offset, value)                                  \
227   do {                                                                        \
228     DCHECK_NOT_NULL(Heap::FromWritableHeapObject(object));                    \
229     MarkingBarrier(object, HeapObject::RawField(object, offset), value);      \
230     GenerationalBarrier(object, HeapObject::RawField(object, offset), value); \
231   } while (false)
232 
233 #define WEAK_WRITE_BARRIER(object, offset, value)                              \
234   do {                                                                         \
235     DCHECK_NOT_NULL(Heap::FromWritableHeapObject(object));                     \
236     MarkingBarrier(object, HeapObject::RawMaybeWeakField(object, offset),      \
237                    value);                                                     \
238     GenerationalBarrier(object, HeapObject::RawMaybeWeakField(object, offset), \
239                         value);                                                \
240   } while (false)
241 
242 #define CONDITIONAL_WRITE_BARRIER(object, offset, value, mode)               \
243   do {                                                                       \
244     DCHECK_NOT_NULL(Heap::FromWritableHeapObject(object));                   \
245     if (mode != SKIP_WRITE_BARRIER) {                                        \
246       if (mode == UPDATE_WRITE_BARRIER) {                                    \
247         MarkingBarrier(object, HeapObject::RawField(object, offset), value); \
248       }                                                                      \
249       GenerationalBarrier(object, HeapObject::RawField(object, offset),      \
250                           value);                                            \
251     }                                                                        \
252   } while (false)
253 
254 #define CONDITIONAL_WEAK_WRITE_BARRIER(object, offset, value, mode)           \
255   do {                                                                        \
256     DCHECK_NOT_NULL(Heap::FromWritableHeapObject(object));                    \
257     if (mode != SKIP_WRITE_BARRIER) {                                         \
258       if (mode == UPDATE_WRITE_BARRIER) {                                     \
259         MarkingBarrier(object, HeapObject::RawMaybeWeakField(object, offset), \
260                        value);                                                \
261       }                                                                       \
262       GenerationalBarrier(                                                    \
263           object, HeapObject::RawMaybeWeakField(object, offset), value);      \
264     }                                                                         \
265   } while (false)
266 
267 #define READ_DOUBLE_FIELD(p, offset) ReadDoubleValue(FIELD_ADDR(p, offset))
268 
269 #define WRITE_DOUBLE_FIELD(p, offset, value) \
270   WriteDoubleValue(FIELD_ADDR(p, offset), value)
271 
272 #define READ_INT_FIELD(p, offset) \
273   (*reinterpret_cast<const int*>(FIELD_ADDR(p, offset)))
274 
275 #define WRITE_INT_FIELD(p, offset, value) \
276   (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
277 
278 #define RELAXED_READ_INTPTR_FIELD(p, offset) \
279   static_cast<intptr_t>(base::Relaxed_Load(  \
280       reinterpret_cast<const base::AtomicWord*>(FIELD_ADDR(p, offset))))
281 
282 #define READ_INTPTR_FIELD(p, offset) \
283   (*reinterpret_cast<const intptr_t*>(FIELD_ADDR(p, offset)))
284 
285 #define RELAXED_WRITE_INTPTR_FIELD(p, offset, value)              \
286   base::Relaxed_Store(                                            \
287       reinterpret_cast<base::AtomicWord*>(FIELD_ADDR(p, offset)), \
288       static_cast<base::AtomicWord>(value));
289 
290 #define WRITE_INTPTR_FIELD(p, offset, value) \
291   (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
292 
293 #define READ_UINT8_FIELD(p, offset) \
294   (*reinterpret_cast<const uint8_t*>(FIELD_ADDR(p, offset)))
295 
296 #define WRITE_UINT8_FIELD(p, offset, value) \
297   (*reinterpret_cast<uint8_t*>(FIELD_ADDR(p, offset)) = value)
298 
299 #define RELAXED_WRITE_INT8_FIELD(p, offset, value)                             \
300   base::Relaxed_Store(reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
301                       static_cast<base::Atomic8>(value));
302 
303 #define READ_INT8_FIELD(p, offset) \
304   (*reinterpret_cast<const int8_t*>(FIELD_ADDR(p, offset)))
305 
306 #define RELAXED_READ_INT8_FIELD(p, offset) \
307   static_cast<int8_t>(base::Relaxed_Load(  \
308       reinterpret_cast<const base::Atomic8*>(FIELD_ADDR(p, offset))))
309 
310 #define WRITE_INT8_FIELD(p, offset, value) \
311   (*reinterpret_cast<int8_t*>(FIELD_ADDR(p, offset)) = value)
312 
313 #define READ_UINT16_FIELD(p, offset) \
314   (*reinterpret_cast<const uint16_t*>(FIELD_ADDR(p, offset)))
315 
316 #define WRITE_UINT16_FIELD(p, offset, value) \
317   (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
318 
319 #define READ_INT16_FIELD(p, offset) \
320   (*reinterpret_cast<const int16_t*>(FIELD_ADDR(p, offset)))
321 
322 #define WRITE_INT16_FIELD(p, offset, value) \
323   (*reinterpret_cast<int16_t*>(FIELD_ADDR(p, offset)) = value)
324 
325 #define READ_UINT32_FIELD(p, offset) \
326   (*reinterpret_cast<const uint32_t*>(FIELD_ADDR(p, offset)))
327 
328 #define WRITE_UINT32_FIELD(p, offset, value) \
329   (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
330 
331 #define READ_INT32_FIELD(p, offset) \
332   (*reinterpret_cast<const int32_t*>(FIELD_ADDR(p, offset)))
333 
334 #define WRITE_INT32_FIELD(p, offset, value) \
335   (*reinterpret_cast<int32_t*>(FIELD_ADDR(p, offset)) = value)
336 
337 #define READ_FLOAT_FIELD(p, offset) \
338   (*reinterpret_cast<const float*>(FIELD_ADDR(p, offset)))
339 
340 #define WRITE_FLOAT_FIELD(p, offset, value) \
341   (*reinterpret_cast<float*>(FIELD_ADDR(p, offset)) = value)
342 
343 #define READ_UINT64_FIELD(p, offset) \
344   (*reinterpret_cast<const uint64_t*>(FIELD_ADDR(p, offset)))
345 
346 #define WRITE_UINT64_FIELD(p, offset, value) \
347   (*reinterpret_cast<uint64_t*>(FIELD_ADDR(p, offset)) = value)
348 
349 #define READ_INT64_FIELD(p, offset) \
350   (*reinterpret_cast<const int64_t*>(FIELD_ADDR(p, offset)))
351 
352 #define WRITE_INT64_FIELD(p, offset, value) \
353   (*reinterpret_cast<int64_t*>(FIELD_ADDR(p, offset)) = value)
354 
355 #define READ_BYTE_FIELD(p, offset) \
356   (*reinterpret_cast<const byte*>(FIELD_ADDR(p, offset)))
357 
358 #define RELAXED_READ_BYTE_FIELD(p, offset) \
359   static_cast<byte>(base::Relaxed_Load(    \
360       reinterpret_cast<const base::Atomic8*>(FIELD_ADDR(p, offset))))
361 
362 #define WRITE_BYTE_FIELD(p, offset, value) \
363   (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
364 
365 #define RELAXED_WRITE_BYTE_FIELD(p, offset, value)                             \
366   base::Relaxed_Store(reinterpret_cast<base::Atomic8*>(FIELD_ADDR(p, offset)), \
367                       static_cast<base::Atomic8>(value));
368 
369 #ifdef VERIFY_HEAP
370 #define DECL_VERIFIER(Name) void Name##Verify(Isolate* isolate);
371 #else
372 #define DECL_VERIFIER(Name)
373 #endif
374 
375 #define DEFINE_DEOPT_ELEMENT_ACCESSORS(name, type)                             \
376   type* DeoptimizationData::name() { return type::cast(get(k##name##Index)); } \
377   void DeoptimizationData::Set##name(type* value) {                            \
378     set(k##name##Index, value);                                                \
379   }
380 
381 #define DEFINE_DEOPT_ENTRY_ACCESSORS(name, type)                \
382   type* DeoptimizationData::name(int i) {                       \
383     return type::cast(get(IndexForEntry(i) + k##name##Offset)); \
384   }                                                             \
385   void DeoptimizationData::Set##name(int i, type* value) {      \
386     set(IndexForEntry(i) + k##name##Offset, value);             \
387   }
388