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