| // Copyright 2018 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef V8_OBJECTS_SLOTS_INL_H_ |
| #define V8_OBJECTS_SLOTS_INL_H_ |
| |
| #include "src/base/atomic-utils.h" |
| #include "src/common/globals.h" |
| #include "src/common/ptr-compr-inl.h" |
| #include "src/objects/compressed-slots.h" |
| #include "src/objects/heap-object.h" |
| #include "src/objects/maybe-object.h" |
| #include "src/objects/objects.h" |
| #include "src/objects/slots.h" |
| #include "src/utils/memcopy.h" |
| |
| namespace v8 { |
| namespace internal { |
| |
| // |
| // FullObjectSlot implementation. |
| // |
| |
| FullObjectSlot::FullObjectSlot(Object* object) |
| : SlotBase(reinterpret_cast<Address>(&object->ptr_)) {} |
| |
| bool FullObjectSlot::contains_value(Address raw_value) const { |
| return base::AsAtomicPointer::Relaxed_Load(location()) == raw_value; |
| } |
| |
| Object FullObjectSlot::operator*() const { return Object(*location()); } |
| |
| Object FullObjectSlot::load(IsolateRoot isolate) const { return **this; } |
| |
| void FullObjectSlot::store(Object value) const { *location() = value.ptr(); } |
| |
| Object FullObjectSlot::Acquire_Load() const { |
| return Object(base::AsAtomicPointer::Acquire_Load(location())); |
| } |
| |
| Object FullObjectSlot::Acquire_Load(IsolateRoot isolate) const { |
| return Acquire_Load(); |
| } |
| |
| Object FullObjectSlot::Relaxed_Load() const { |
| return Object(base::AsAtomicPointer::Relaxed_Load(location())); |
| } |
| |
| Object FullObjectSlot::Relaxed_Load(IsolateRoot isolate) const { |
| return Relaxed_Load(); |
| } |
| |
| void FullObjectSlot::Relaxed_Store(Object value) const { |
| base::AsAtomicPointer::Relaxed_Store(location(), value.ptr()); |
| } |
| |
| void FullObjectSlot::Release_Store(Object value) const { |
| base::AsAtomicPointer::Release_Store(location(), value.ptr()); |
| } |
| |
| Object FullObjectSlot::Relaxed_CompareAndSwap(Object old, Object target) const { |
| Address result = base::AsAtomicPointer::Relaxed_CompareAndSwap( |
| location(), old.ptr(), target.ptr()); |
| return Object(result); |
| } |
| |
| Object FullObjectSlot::Release_CompareAndSwap(Object old, Object target) const { |
| Address result = base::AsAtomicPointer::Release_CompareAndSwap( |
| location(), old.ptr(), target.ptr()); |
| return Object(result); |
| } |
| |
| // |
| // FullMaybeObjectSlot implementation. |
| // |
| |
| MaybeObject FullMaybeObjectSlot::operator*() const { |
| return MaybeObject(*location()); |
| } |
| |
| MaybeObject FullMaybeObjectSlot::load(IsolateRoot isolate) const { |
| return **this; |
| } |
| |
| void FullMaybeObjectSlot::store(MaybeObject value) const { |
| *location() = value.ptr(); |
| } |
| |
| MaybeObject FullMaybeObjectSlot::Relaxed_Load() const { |
| return MaybeObject(base::AsAtomicPointer::Relaxed_Load(location())); |
| } |
| |
| MaybeObject FullMaybeObjectSlot::Relaxed_Load(IsolateRoot isolate) const { |
| return Relaxed_Load(); |
| } |
| |
| void FullMaybeObjectSlot::Relaxed_Store(MaybeObject value) const { |
| base::AsAtomicPointer::Relaxed_Store(location(), value->ptr()); |
| } |
| |
| void FullMaybeObjectSlot::Release_CompareAndSwap(MaybeObject old, |
| MaybeObject target) const { |
| base::AsAtomicPointer::Release_CompareAndSwap(location(), old.ptr(), |
| target.ptr()); |
| } |
| |
| // |
| // FullHeapObjectSlot implementation. |
| // |
| |
| HeapObjectReference FullHeapObjectSlot::operator*() const { |
| return HeapObjectReference(*location()); |
| } |
| |
| HeapObjectReference FullHeapObjectSlot::load(IsolateRoot isolate) const { |
| return **this; |
| } |
| |
| void FullHeapObjectSlot::store(HeapObjectReference value) const { |
| *location() = value.ptr(); |
| } |
| |
| HeapObject FullHeapObjectSlot::ToHeapObject() const { |
| DCHECK((*location() & kHeapObjectTagMask) == kHeapObjectTag); |
| return HeapObject::cast(Object(*location())); |
| } |
| |
| void FullHeapObjectSlot::StoreHeapObject(HeapObject value) const { |
| *location() = value.ptr(); |
| } |
| |
| // |
| // Utils. |
| // |
| |
| // Copies tagged words from |src| to |dst|. The data spans must not overlap. |
| // |src| and |dst| must be kTaggedSize-aligned. |
| inline void CopyTagged(Address dst, const Address src, size_t num_tagged) { |
| static const size_t kBlockCopyLimit = 16; |
| CopyImpl<kBlockCopyLimit>(reinterpret_cast<Tagged_t*>(dst), |
| reinterpret_cast<const Tagged_t*>(src), num_tagged); |
| } |
| |
| // Sets |counter| number of kTaggedSize-sized values starting at |start| slot. |
| inline void MemsetTagged(Tagged_t* start, Object value, size_t counter) { |
| #ifdef V8_COMPRESS_POINTERS |
| Tagged_t raw_value = CompressTagged(value.ptr()); |
| MemsetUint32(start, raw_value, counter); |
| #else |
| Address raw_value = value.ptr(); |
| MemsetPointer(start, raw_value, counter); |
| #endif |
| } |
| |
| // Sets |counter| number of kTaggedSize-sized values starting at |start| slot. |
| template <typename T> |
| inline void MemsetTagged(SlotBase<T, Tagged_t> start, Object value, |
| size_t counter) { |
| MemsetTagged(start.location(), value, counter); |
| } |
| |
| // Sets |counter| number of kSystemPointerSize-sized values starting at |start| |
| // slot. |
| inline void MemsetPointer(FullObjectSlot start, Object value, size_t counter) { |
| MemsetPointer(start.location(), value.ptr(), counter); |
| } |
| |
| } // namespace internal |
| } // namespace v8 |
| |
| #endif // V8_OBJECTS_SLOTS_INL_H_ |