• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/maybe-object-inl.h"
16 
17 namespace v8 {
18 namespace internal {
19 
20 // Do not use these internal details anywhere outside of this file. These
21 // internals are only intended to shortcut write barrier checks.
22 namespace heap_internals {
23 
24 struct MemoryChunk {
25   static constexpr uintptr_t kFlagsOffset = sizeof(size_t);
26   static constexpr uintptr_t kMarkingBit = uintptr_t{1} << 18;
27   static constexpr uintptr_t kFromSpaceBit = uintptr_t{1} << 3;
28   static constexpr uintptr_t kToSpaceBit = uintptr_t{1} << 4;
29 
FromHeapObjectMemoryChunk30   V8_INLINE static heap_internals::MemoryChunk* FromHeapObject(
31       HeapObject* object) {
32     return reinterpret_cast<MemoryChunk*>(reinterpret_cast<Address>(object) &
33                                           ~kPageAlignmentMask);
34   }
35 
IsMarkingMemoryChunk36   V8_INLINE bool IsMarking() const { return GetFlags() & kMarkingBit; }
37 
InNewSpaceMemoryChunk38   V8_INLINE bool InNewSpace() const {
39     constexpr uintptr_t kNewSpaceMask = kFromSpaceBit | kToSpaceBit;
40     return GetFlags() & kNewSpaceMask;
41   }
42 
GetFlagsMemoryChunk43   V8_INLINE uintptr_t GetFlags() const {
44     return *reinterpret_cast<const uintptr_t*>(
45         reinterpret_cast<const uint8_t*>(this) + kFlagsOffset);
46   }
47 };
48 
GenerationalBarrierInternal(HeapObject * object,Address slot,HeapObject * value)49 inline void GenerationalBarrierInternal(HeapObject* object, Address slot,
50                                         HeapObject* value) {
51   DCHECK(Heap::PageFlagsAreConsistent(object));
52   heap_internals::MemoryChunk* value_chunk =
53       heap_internals::MemoryChunk::FromHeapObject(value);
54   heap_internals::MemoryChunk* object_chunk =
55       heap_internals::MemoryChunk::FromHeapObject(object);
56 
57   if (!value_chunk->InNewSpace() || object_chunk->InNewSpace()) return;
58 
59   Heap::GenerationalBarrierSlow(object, slot, value);
60 }
61 
MarkingBarrierInternal(HeapObject * object,Address slot,HeapObject * value)62 inline void MarkingBarrierInternal(HeapObject* object, Address slot,
63                                    HeapObject* value) {
64   DCHECK(Heap::PageFlagsAreConsistent(object));
65   heap_internals::MemoryChunk* value_chunk =
66       heap_internals::MemoryChunk::FromHeapObject(value);
67 
68   if (!value_chunk->IsMarking()) return;
69 
70   Heap::MarkingBarrierSlow(object, slot, value);
71 }
72 
73 }  // namespace heap_internals
74 
WriteBarrierForCode(Code * host,RelocInfo * rinfo,Object * value)75 inline void WriteBarrierForCode(Code* host, RelocInfo* rinfo, Object* value) {
76   DCHECK(!HasWeakHeapObjectTag(value));
77   if (!value->IsHeapObject()) return;
78   HeapObject* object = HeapObject::cast(value);
79   GenerationalBarrierForCode(host, rinfo, object);
80   MarkingBarrierForCode(host, rinfo, object);
81 }
82 
WriteBarrierForCode(Code * host)83 inline void WriteBarrierForCode(Code* host) {
84   Heap::WriteBarrierForCodeSlow(host);
85 }
86 
GenerationalBarrier(HeapObject * object,Object ** slot,Object * value)87 inline void GenerationalBarrier(HeapObject* object, Object** slot,
88                                 Object* value) {
89   DCHECK(!HasWeakHeapObjectTag(*slot));
90   DCHECK(!HasWeakHeapObjectTag(value));
91   if (!value->IsHeapObject()) return;
92   heap_internals::GenerationalBarrierInternal(
93       object, reinterpret_cast<Address>(slot), HeapObject::cast(value));
94 }
95 
GenerationalBarrier(HeapObject * object,MaybeObject ** slot,MaybeObject * value)96 inline void GenerationalBarrier(HeapObject* object, MaybeObject** slot,
97                                 MaybeObject* value) {
98   HeapObject* value_heap_object;
99   if (!value->ToStrongOrWeakHeapObject(&value_heap_object)) return;
100   heap_internals::GenerationalBarrierInternal(
101       object, reinterpret_cast<Address>(slot), value_heap_object);
102 }
103 
GenerationalBarrierForElements(Heap * heap,FixedArray * array,int offset,int length)104 inline void GenerationalBarrierForElements(Heap* heap, FixedArray* array,
105                                            int offset, int length) {
106   heap_internals::MemoryChunk* array_chunk =
107       heap_internals::MemoryChunk::FromHeapObject(array);
108   if (array_chunk->InNewSpace()) return;
109 
110   Heap::GenerationalBarrierForElementsSlow(heap, array, offset, length);
111 }
112 
GenerationalBarrierForCode(Code * host,RelocInfo * rinfo,HeapObject * object)113 inline void GenerationalBarrierForCode(Code* host, RelocInfo* rinfo,
114                                        HeapObject* object) {
115   heap_internals::MemoryChunk* object_chunk =
116       heap_internals::MemoryChunk::FromHeapObject(object);
117   if (!object_chunk->InNewSpace()) return;
118   Heap::GenerationalBarrierForCodeSlow(host, rinfo, object);
119 }
120 
MarkingBarrier(HeapObject * object,Object ** slot,Object * value)121 inline void MarkingBarrier(HeapObject* object, Object** slot, Object* value) {
122   DCHECK_IMPLIES(slot != nullptr, !HasWeakHeapObjectTag(*slot));
123   DCHECK(!HasWeakHeapObjectTag(value));
124   if (!value->IsHeapObject()) return;
125   heap_internals::MarkingBarrierInternal(
126       object, reinterpret_cast<Address>(slot), HeapObject::cast(value));
127 }
128 
MarkingBarrier(HeapObject * object,MaybeObject ** slot,MaybeObject * value)129 inline void MarkingBarrier(HeapObject* object, MaybeObject** slot,
130                            MaybeObject* value) {
131   HeapObject* value_heap_object;
132   if (!value->ToStrongOrWeakHeapObject(&value_heap_object)) return;
133   heap_internals::MarkingBarrierInternal(
134       object, reinterpret_cast<Address>(slot), value_heap_object);
135 }
136 
MarkingBarrierForElements(Heap * heap,HeapObject * object)137 inline void MarkingBarrierForElements(Heap* heap, HeapObject* object) {
138   heap_internals::MemoryChunk* object_chunk =
139       heap_internals::MemoryChunk::FromHeapObject(object);
140   if (!object_chunk->IsMarking()) return;
141 
142   Heap::MarkingBarrierForElementsSlow(heap, object);
143 }
144 
MarkingBarrierForCode(Code * host,RelocInfo * rinfo,HeapObject * object)145 inline void MarkingBarrierForCode(Code* host, RelocInfo* rinfo,
146                                   HeapObject* object) {
147   DCHECK(!HasWeakHeapObjectTag(object));
148   heap_internals::MemoryChunk* object_chunk =
149       heap_internals::MemoryChunk::FromHeapObject(object);
150   if (!object_chunk->IsMarking()) return;
151   Heap::MarkingBarrierForCodeSlow(host, rinfo, object);
152 }
153 
154 }  // namespace internal
155 }  // namespace v8
156 
157 #endif  // V8_HEAP_HEAP_WRITE_BARRIER_INL_H_
158