summaryrefslogtreecommitdiff
path: root/deps/v8/src/heap/heap-write-barrier-inl.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/heap/heap-write-barrier-inl.h')
-rw-r--r--deps/v8/src/heap/heap-write-barrier-inl.h157
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_