Line data Source code
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/heap/heap.h"
15 : #include "src/objects/code.h"
16 : #include "src/objects/heap-object.h"
17 : #include "src/objects/maybe-object-inl.h"
18 : #include "src/objects/slots.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 :
23 : // Do not use these internal details anywhere outside of this file. These
24 : // internals are only intended to shortcut write barrier checks.
25 : namespace heap_internals {
26 :
27 : struct MemoryChunk {
28 : static constexpr uintptr_t kFlagsOffset = sizeof(size_t);
29 : static constexpr uintptr_t kHeapOffset =
30 : kFlagsOffset + kUIntptrSize + 4 * kSystemPointerSize;
31 : static constexpr uintptr_t kMarkingBit = uintptr_t{1} << 18;
32 : static constexpr uintptr_t kFromSpaceBit = uintptr_t{1} << 3;
33 : static constexpr uintptr_t kToSpaceBit = uintptr_t{1} << 4;
34 :
35 : V8_INLINE static heap_internals::MemoryChunk* FromHeapObject(
36 : HeapObject object) {
37 4758000832 : return reinterpret_cast<MemoryChunk*>(object->ptr() & ~kPageAlignmentMask);
38 : }
39 :
40 2173969290 : V8_INLINE bool IsMarking() const { return GetFlags() & kMarkingBit; }
41 :
42 : V8_INLINE bool InNewSpace() const {
43 : constexpr uintptr_t kNewSpaceMask = kFromSpaceBit | kToSpaceBit;
44 2154913233 : return GetFlags() & kNewSpaceMask;
45 : }
46 :
47 : V8_INLINE uintptr_t GetFlags() const {
48 4328882517 : return *reinterpret_cast<const uintptr_t*>(reinterpret_cast<Address>(this) +
49 4328882523 : kFlagsOffset);
50 : }
51 :
52 : V8_INLINE Heap* GetHeap() {
53 599034167 : Heap* heap = *reinterpret_cast<Heap**>(reinterpret_cast<Address>(this) +
54 599034167 : kHeapOffset);
55 : SLOW_DCHECK(heap != nullptr);
56 : return heap;
57 : }
58 : };
59 :
60 1978988613 : inline void GenerationalBarrierInternal(HeapObject object, Address slot,
61 : HeapObject value) {
62 : DCHECK(Heap::PageFlagsAreConsistent(object));
63 : heap_internals::MemoryChunk* value_chunk =
64 : heap_internals::MemoryChunk::FromHeapObject(value);
65 : heap_internals::MemoryChunk* object_chunk =
66 : heap_internals::MemoryChunk::FromHeapObject(object);
67 :
68 4127891808 : if (!value_chunk->InNewSpace() || object_chunk->InNewSpace()) return;
69 :
70 106743185 : Heap::GenerationalBarrierSlow(object, slot, value);
71 : }
72 :
73 2083761867 : inline void MarkingBarrierInternal(HeapObject object, Address slot,
74 : HeapObject value) {
75 : DCHECK(Heap::PageFlagsAreConsistent(object));
76 : heap_internals::MemoryChunk* value_chunk =
77 : heap_internals::MemoryChunk::FromHeapObject(value);
78 :
79 4167524130 : if (!value_chunk->IsMarking()) return;
80 :
81 275081447 : Heap::MarkingBarrierSlow(object, slot, value);
82 : }
83 :
84 : } // namespace heap_internals
85 :
86 5953671 : inline void WriteBarrierForCode(Code host, RelocInfo* rinfo, Object value) {
87 : DCHECK(!HasWeakHeapObjectTag(value));
88 5953671 : if (!value->IsHeapObject()) return;
89 5953671 : HeapObject object = HeapObject::cast(value);
90 5953671 : GenerationalBarrierForCode(host, rinfo, object);
91 5953664 : MarkingBarrierForCode(host, rinfo, object);
92 : }
93 :
94 : inline void WriteBarrierForCode(Code host) {
95 96 : Heap::WriteBarrierForCodeSlow(host);
96 : }
97 :
98 2029039615 : inline void GenerationalBarrier(HeapObject object, ObjectSlot slot,
99 : Object value) {
100 : DCHECK(!HasWeakHeapObjectTag(*slot));
101 : DCHECK(!HasWeakHeapObjectTag(value));
102 4058077345 : if (!value->IsHeapObject()) return;
103 : heap_internals::GenerationalBarrierInternal(object, slot.address(),
104 1698250008 : HeapObject::cast(value));
105 : }
106 :
107 1299396228 : inline void GenerationalBarrier(HeapObject object, MaybeObjectSlot slot,
108 : MaybeObject value) {
109 1299396228 : HeapObject value_heap_object;
110 2318056354 : if (!value->GetHeapObject(&value_heap_object)) return;
111 : heap_internals::GenerationalBarrierInternal(object, slot.address(),
112 280738711 : value_heap_object);
113 : }
114 :
115 9280 : inline void GenerationalBarrierForElements(Heap* heap, FixedArray array,
116 : int offset, int length) {
117 : heap_internals::MemoryChunk* array_chunk =
118 : heap_internals::MemoryChunk::FromHeapObject(array);
119 18560 : if (array_chunk->InNewSpace()) return;
120 :
121 1002 : Heap::GenerationalBarrierForElementsSlow(heap, array, offset, length);
122 : }
123 :
124 5999870 : inline void GenerationalBarrierForCode(Code host, RelocInfo* rinfo,
125 : HeapObject object) {
126 : heap_internals::MemoryChunk* object_chunk =
127 : heap_internals::MemoryChunk::FromHeapObject(object);
128 11999740 : if (!object_chunk->InNewSpace()) return;
129 435098 : Heap::GenerationalBarrierForCodeSlow(host, rinfo, object);
130 : }
131 :
132 2134091705 : inline void MarkingBarrier(HeapObject object, ObjectSlot slot, Object value) {
133 : DCHECK_IMPLIES(slot.address() != kNullAddress, !HasWeakHeapObjectTag(*slot));
134 : DCHECK(!HasWeakHeapObjectTag(value));
135 4268184223 : if (!value->IsHeapObject()) return;
136 : heap_internals::MarkingBarrierInternal(object, slot.address(),
137 1803299435 : HeapObject::cast(value));
138 : }
139 :
140 1299119234 : inline void MarkingBarrier(HeapObject object, MaybeObjectSlot slot,
141 : MaybeObject value) {
142 1299119234 : HeapObject value_heap_object;
143 2317778531 : if (!value->GetHeapObject(&value_heap_object)) return;
144 : heap_internals::MarkingBarrierInternal(object, slot.address(),
145 280462453 : value_heap_object);
146 : }
147 :
148 9280 : inline void MarkingBarrierForElements(Heap* heap, HeapObject object) {
149 : heap_internals::MemoryChunk* object_chunk =
150 : heap_internals::MemoryChunk::FromHeapObject(object);
151 18560 : if (!object_chunk->IsMarking()) return;
152 :
153 615 : Heap::MarkingBarrierForElementsSlow(heap, object);
154 : }
155 :
156 7711053 : inline void MarkingBarrierForCode(Code host, RelocInfo* rinfo,
157 : HeapObject object) {
158 : DCHECK(!HasWeakHeapObjectTag(object.ptr()));
159 : heap_internals::MemoryChunk* object_chunk =
160 : heap_internals::MemoryChunk::FromHeapObject(object);
161 15422110 : if (!object_chunk->IsMarking()) return;
162 254942 : Heap::MarkingBarrierForCodeSlow(host, rinfo, object);
163 : }
164 :
165 82486871 : inline void MarkingBarrierForDescriptorArray(Heap* heap, HeapObject host,
166 : HeapObject descriptor_array,
167 : int number_of_own_descriptors) {
168 : heap_internals::MemoryChunk* chunk =
169 : heap_internals::MemoryChunk::FromHeapObject(descriptor_array);
170 164973732 : if (!chunk->IsMarking()) return;
171 :
172 : Heap::MarkingBarrierForDescriptorArraySlow(heap, host, descriptor_array,
173 8864012 : number_of_own_descriptors);
174 : }
175 :
176 599033996 : inline Heap* GetHeapFromWritableObject(const HeapObject object) {
177 : heap_internals::MemoryChunk* chunk =
178 : heap_internals::MemoryChunk::FromHeapObject(object);
179 599034167 : return chunk->GetHeap();
180 : }
181 :
182 : } // namespace internal
183 : } // namespace v8
184 :
185 : #endif // V8_HEAP_HEAP_WRITE_BARRIER_INL_H_
|