V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
heap-write-barrier-inl.h
1 // Copyright 2018 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 #ifndef V8_HEAP_HEAP_WRITE_BARRIER_INL_H_
6 #define V8_HEAP_HEAP_WRITE_BARRIER_INL_H_
7 
8 // Clients of this interface shouldn't depend on lots of heap internals.
9 // Do not include anything from src/heap here!
10 
11 #include "src/heap/heap-write-barrier.h"
12 
13 #include "src/globals.h"
14 #include "src/objects-inl.h"
15 #include "src/objects/heap-object.h"
16 #include "src/objects/maybe-object-inl.h"
17 #include "src/objects/slots.h"
18 
19 namespace v8 {
20 namespace internal {
21 
22 // Do not use these internal details anywhere outside of this file. These
23 // internals are only intended to shortcut write barrier checks.
24 namespace heap_internals {
25 
26 struct MemoryChunk {
27  static constexpr uintptr_t kFlagsOffset = sizeof(size_t);
28  static constexpr uintptr_t kMarkingBit = uintptr_t{1} << 18;
29  static constexpr uintptr_t kFromSpaceBit = uintptr_t{1} << 3;
30  static constexpr uintptr_t kToSpaceBit = uintptr_t{1} << 4;
31 
32  V8_INLINE static heap_internals::MemoryChunk* FromHeapObject(
33  HeapObject* object) {
34  return reinterpret_cast<MemoryChunk*>(reinterpret_cast<Address>(object) &
35  ~kPageAlignmentMask);
36  }
37 
38  V8_INLINE bool IsMarking() const { return GetFlags() & kMarkingBit; }
39 
40  V8_INLINE bool InNewSpace() const {
41  constexpr uintptr_t kNewSpaceMask = kFromSpaceBit | kToSpaceBit;
42  return GetFlags() & kNewSpaceMask;
43  }
44 
45  V8_INLINE uintptr_t GetFlags() const {
46  return *reinterpret_cast<const uintptr_t*>(
47  reinterpret_cast<const uint8_t*>(this) + kFlagsOffset);
48  }
49 };
50 
51 inline void GenerationalBarrierInternal(HeapObject* object, Address slot,
52  HeapObject* value) {
53  DCHECK(Heap::PageFlagsAreConsistent(object));
54  heap_internals::MemoryChunk* value_chunk =
55  heap_internals::MemoryChunk::FromHeapObject(value);
56  heap_internals::MemoryChunk* object_chunk =
57  heap_internals::MemoryChunk::FromHeapObject(object);
58 
59  if (!value_chunk->InNewSpace() || object_chunk->InNewSpace()) return;
60 
61  Heap::GenerationalBarrierSlow(object, slot, value);
62 }
63 
64 inline void MarkingBarrierInternal(HeapObject* object, Address slot,
65  HeapObject* value) {
66  DCHECK(Heap::PageFlagsAreConsistent(object));
67  heap_internals::MemoryChunk* value_chunk =
68  heap_internals::MemoryChunk::FromHeapObject(value);
69 
70  if (!value_chunk->IsMarking()) return;
71 
72  Heap::MarkingBarrierSlow(object, slot, value);
73 }
74 
75 } // namespace heap_internals
76 
77 inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object* value) {
78  DCHECK(!HasWeakHeapObjectTag(value));
79  if (!value->IsHeapObject()) return;
80  HeapObject* object = HeapObject::cast(value);
81  GenerationalBarrierForCode(host, rinfo, object);
82  MarkingBarrierForCode(host, rinfo, object);
83 }
84 
85 inline void WriteBarrierForCode(Code host) {
86  Heap::WriteBarrierForCodeSlow(host);
87 }
88 
89 inline void GenerationalBarrier(HeapObject* object, ObjectSlot slot,
90  Object* value) {
91  DCHECK(!HasWeakHeapObjectTag(*slot));
92  DCHECK(!HasWeakHeapObjectTag(value));
93  if (!value->IsHeapObject()) return;
94  heap_internals::GenerationalBarrierInternal(object, slot.address(),
95  HeapObject::cast(value));
96 }
97 
98 inline void GenerationalBarrier(HeapObject* object, MaybeObjectSlot slot,
99  MaybeObject value) {
100  HeapObject* value_heap_object;
101  if (!value->GetHeapObject(&value_heap_object)) return;
102  heap_internals::GenerationalBarrierInternal(object, slot.address(),
103  value_heap_object);
104 }
105 
106 inline void GenerationalBarrier(HeapObjectPtr* object, ObjectSlot slot,
107  Object* value) {
108  DCHECK(!HasWeakHeapObjectTag(*slot));
109  DCHECK(!HasWeakHeapObjectTag(value));
110  if (!value->IsHeapObject()) return;
111  heap_internals::GenerationalBarrierInternal(
112  reinterpret_cast<HeapObject*>(object->ptr()), slot.address(),
113  HeapObject::cast(value));
114 }
115 
116 inline void GenerationalBarrier(HeapObjectPtr* object, MaybeObjectSlot slot,
117  MaybeObject value) {
118  HeapObject* value_heap_object;
119  if (!value->GetHeapObject(&value_heap_object)) return;
120  heap_internals::GenerationalBarrierInternal(
121  reinterpret_cast<HeapObject*>(object->ptr()), slot.address(),
122  value_heap_object);
123 }
124 
125 inline void GenerationalBarrierForElements(Heap* heap, FixedArray array,
126  int offset, int length) {
127  heap_internals::MemoryChunk* array_chunk =
128  heap_internals::MemoryChunk::FromHeapObject(array);
129  if (array_chunk->InNewSpace()) return;
130 
131  Heap::GenerationalBarrierForElementsSlow(heap, array, offset, length);
132 }
133 
134 inline void GenerationalBarrierForCode(Code host, RelocInfo* rinfo,
135  HeapObject* object) {
136  heap_internals::MemoryChunk* object_chunk =
137  heap_internals::MemoryChunk::FromHeapObject(object);
138  if (!object_chunk->InNewSpace()) return;
139  Heap::GenerationalBarrierForCodeSlow(host, rinfo, object);
140 }
141 
142 inline void MarkingBarrier(HeapObject* object, ObjectSlot slot, Object* value) {
143  DCHECK_IMPLIES(slot.address() != kNullAddress, !HasWeakHeapObjectTag(*slot));
144  DCHECK(!HasWeakHeapObjectTag(value));
145  if (!value->IsHeapObject()) return;
146  heap_internals::MarkingBarrierInternal(object, slot.address(),
147  HeapObject::cast(value));
148 }
149 
150 inline void MarkingBarrier(HeapObject* object, MaybeObjectSlot slot,
151  MaybeObject value) {
152  HeapObject* value_heap_object;
153  if (!value->GetHeapObject(&value_heap_object)) return;
154  heap_internals::MarkingBarrierInternal(object, slot.address(),
155  value_heap_object);
156 }
157 
158 inline void MarkingBarrier(HeapObjectPtr* object, ObjectSlot slot,
159  Object* value) {
160  DCHECK_IMPLIES(slot.address() != kNullAddress, !HasWeakHeapObjectTag(*slot));
161  DCHECK(!HasWeakHeapObjectTag(value));
162  if (!value->IsHeapObject()) return;
163  heap_internals::MarkingBarrierInternal(
164  reinterpret_cast<HeapObject*>(object->ptr()), slot.address(),
165  HeapObject::cast(value));
166 }
167 
168 inline void MarkingBarrier(HeapObjectPtr* object, MaybeObjectSlot slot,
169  MaybeObject value) {
170  HeapObject* value_heap_object;
171  if (!value->GetHeapObject(&value_heap_object)) return;
172  heap_internals::MarkingBarrierInternal(
173  reinterpret_cast<HeapObject*>(object->ptr()), slot.address(),
174  value_heap_object);
175 }
176 
177 inline void MarkingBarrierForElements(Heap* heap, HeapObject* object) {
178  heap_internals::MemoryChunk* object_chunk =
179  heap_internals::MemoryChunk::FromHeapObject(object);
180  if (!object_chunk->IsMarking()) return;
181 
182  Heap::MarkingBarrierForElementsSlow(heap, object);
183 }
184 
185 inline void MarkingBarrierForCode(Code host, RelocInfo* rinfo,
186  HeapObject* object) {
187  DCHECK(!HasWeakHeapObjectTag(object));
188  heap_internals::MemoryChunk* object_chunk =
189  heap_internals::MemoryChunk::FromHeapObject(object);
190  if (!object_chunk->IsMarking()) return;
191  Heap::MarkingBarrierForCodeSlow(host, rinfo, object);
192 }
193 
194 } // namespace internal
195 } // namespace v8
196 
197 #endif // V8_HEAP_HEAP_WRITE_BARRIER_INL_H_
Definition: libplatform.h:13