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