diff options
Diffstat (limited to 'deps/v8/src/heap/heap-write-barrier-inl.h')
-rw-r--r-- | deps/v8/src/heap/heap-write-barrier-inl.h | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/deps/v8/src/heap/heap-write-barrier-inl.h b/deps/v8/src/heap/heap-write-barrier-inl.h new file mode 100644 index 0000000000..1e4550679c --- /dev/null +++ b/deps/v8/src/heap/heap-write-barrier-inl.h @@ -0,0 +1,157 @@ +// 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_HEAP_HEAP_WRITE_BARRIER_INL_H_ +#define V8_HEAP_HEAP_WRITE_BARRIER_INL_H_ + +// Clients of this interface shouldn't depend on lots of heap internals. +// Do not include anything from src/heap here! + +#include "src/heap/heap-write-barrier.h" + +#include "src/globals.h" +#include "src/objects-inl.h" +#include "src/objects/maybe-object-inl.h" + +namespace v8 { +namespace internal { + +// Do not use these internal details anywhere outside of this file. These +// internals are only intended to shortcut write barrier checks. +namespace heap_internals { + +struct MemoryChunk { + static constexpr uintptr_t kFlagsOffset = sizeof(size_t); + static constexpr uintptr_t kMarkingBit = uintptr_t{1} << 18; + static constexpr uintptr_t kFromSpaceBit = uintptr_t{1} << 3; + static constexpr uintptr_t kToSpaceBit = uintptr_t{1} << 4; + + V8_INLINE static heap_internals::MemoryChunk* FromHeapObject( + HeapObject* object) { + return reinterpret_cast<MemoryChunk*>(reinterpret_cast<Address>(object) & + ~kPageAlignmentMask); + } + + V8_INLINE bool IsMarking() const { return GetFlags() & kMarkingBit; } + + V8_INLINE bool InNewSpace() const { + constexpr uintptr_t kNewSpaceMask = kFromSpaceBit | kToSpaceBit; + return GetFlags() & kNewSpaceMask; + } + + V8_INLINE uintptr_t GetFlags() const { + return *reinterpret_cast<const uintptr_t*>( + reinterpret_cast<const uint8_t*>(this) + kFlagsOffset); + } +}; + +inline void GenerationalBarrierInternal(HeapObject* object, Address slot, + HeapObject* value) { + DCHECK(Heap::PageFlagsAreConsistent(object)); + heap_internals::MemoryChunk* value_chunk = + heap_internals::MemoryChunk::FromHeapObject(value); + heap_internals::MemoryChunk* object_chunk = + heap_internals::MemoryChunk::FromHeapObject(object); + + if (!value_chunk->InNewSpace() || object_chunk->InNewSpace()) return; + + Heap::GenerationalBarrierSlow(object, slot, value); +} + +inline void MarkingBarrierInternal(HeapObject* object, Address slot, + HeapObject* value) { + DCHECK(Heap::PageFlagsAreConsistent(object)); + heap_internals::MemoryChunk* value_chunk = + heap_internals::MemoryChunk::FromHeapObject(value); + + if (!value_chunk->IsMarking()) return; + + Heap::MarkingBarrierSlow(object, slot, value); +} + +} // namespace heap_internals + +inline void WriteBarrierForCode(Code* host, RelocInfo* rinfo, Object* value) { + DCHECK(!HasWeakHeapObjectTag(value)); + if (!value->IsHeapObject()) return; + HeapObject* object = HeapObject::cast(value); + GenerationalBarrierForCode(host, rinfo, object); + MarkingBarrierForCode(host, rinfo, object); +} + +inline void WriteBarrierForCode(Code* host) { + Heap::WriteBarrierForCodeSlow(host); +} + +inline void GenerationalBarrier(HeapObject* object, Object** slot, + Object* value) { + DCHECK(!HasWeakHeapObjectTag(*slot)); + DCHECK(!HasWeakHeapObjectTag(value)); + if (!value->IsHeapObject()) return; + heap_internals::GenerationalBarrierInternal( + object, reinterpret_cast<Address>(slot), HeapObject::cast(value)); +} + +inline void GenerationalBarrier(HeapObject* object, MaybeObject** slot, + MaybeObject* value) { + HeapObject* value_heap_object; + if (!value->ToStrongOrWeakHeapObject(&value_heap_object)) return; + heap_internals::GenerationalBarrierInternal( + object, reinterpret_cast<Address>(slot), value_heap_object); +} + +inline void GenerationalBarrierForElements(Heap* heap, FixedArray* array, + int offset, int length) { + heap_internals::MemoryChunk* array_chunk = + heap_internals::MemoryChunk::FromHeapObject(array); + if (array_chunk->InNewSpace()) return; + + Heap::GenerationalBarrierForElementsSlow(heap, array, offset, length); +} + +inline void GenerationalBarrierForCode(Code* host, RelocInfo* rinfo, + HeapObject* object) { + heap_internals::MemoryChunk* object_chunk = + heap_internals::MemoryChunk::FromHeapObject(object); + if (!object_chunk->InNewSpace()) return; + Heap::GenerationalBarrierForCodeSlow(host, rinfo, object); +} + +inline void MarkingBarrier(HeapObject* object, Object** slot, Object* value) { + DCHECK_IMPLIES(slot != nullptr, !HasWeakHeapObjectTag(*slot)); + DCHECK(!HasWeakHeapObjectTag(value)); + if (!value->IsHeapObject()) return; + heap_internals::MarkingBarrierInternal( + object, reinterpret_cast<Address>(slot), HeapObject::cast(value)); +} + +inline void MarkingBarrier(HeapObject* object, MaybeObject** slot, + MaybeObject* value) { + HeapObject* value_heap_object; + if (!value->ToStrongOrWeakHeapObject(&value_heap_object)) return; + heap_internals::MarkingBarrierInternal( + object, reinterpret_cast<Address>(slot), value_heap_object); +} + +inline void MarkingBarrierForElements(Heap* heap, HeapObject* object) { + heap_internals::MemoryChunk* object_chunk = + heap_internals::MemoryChunk::FromHeapObject(object); + if (!object_chunk->IsMarking()) return; + + Heap::MarkingBarrierForElementsSlow(heap, object); +} + +inline void MarkingBarrierForCode(Code* host, RelocInfo* rinfo, + HeapObject* object) { + DCHECK(!HasWeakHeapObjectTag(object)); + heap_internals::MemoryChunk* object_chunk = + heap_internals::MemoryChunk::FromHeapObject(object); + if (!object_chunk->IsMarking()) return; + Heap::MarkingBarrierForCodeSlow(host, rinfo, object); +} + +} // namespace internal +} // namespace v8 + +#endif // V8_HEAP_HEAP_WRITE_BARRIER_INL_H_ |