OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium 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 MarkingVisitorImpl_h | |
6 #define MarkingVisitorImpl_h | |
7 | |
8 #include "platform/heap/Heap.h" | |
9 #include "platform/heap/ThreadState.h" | |
10 #include "platform/heap/Visitor.h" | |
11 #include "wtf/Allocator.h" | |
12 | |
13 namespace blink { | |
14 | |
15 template <typename Derived> | |
16 class MarkingVisitorImpl { | |
17 USING_FAST_MALLOC(MarkingVisitorImpl); | |
18 | |
19 protected: | |
20 inline void markHeader(HeapObjectHeader* header, | |
21 const void* objectPointer, | |
22 TraceCallback callback) { | |
23 ASSERT(header); | |
24 ASSERT(objectPointer); | |
25 | |
26 // If you hit this ASSERT, it means that there is a dangling pointer | |
27 // from a live thread heap to a dead thread heap. We must eliminate | |
28 // the dangling pointer. | |
29 // Release builds don't have the ASSERT, but it is OK because | |
30 // release builds will crash in the following header->isMarked() | |
31 // because all the entries of the orphaned arenas are zapped. | |
32 ASSERT(!pageFromObject(objectPointer)->orphaned()); | |
33 | |
34 if (header->isMarked()) | |
35 return; | |
36 | |
37 ASSERT(ThreadState::current()->isInGC()); | |
38 DCHECK(toDerived()->getMarkingMode() != VisitorMarkingMode::WeakProcessing); | |
39 | |
40 // A GC should only mark the objects that belong in its heap. | |
41 DCHECK(&pageFromObject(objectPointer)->arena()->getThreadState()->heap() == | |
42 &toDerived()->heap()); | |
43 | |
44 header->mark(); | |
45 | |
46 if (callback) | |
47 toDerived()->heap().pushTraceCallback(const_cast<void*>(objectPointer), | |
48 callback); | |
49 } | |
50 | |
51 inline void mark(const void* objectPointer, TraceCallback callback) { | |
52 if (!objectPointer) | |
53 return; | |
54 HeapObjectHeader* header = HeapObjectHeader::fromPayload(objectPointer); | |
55 markHeader(header, header->payload(), callback); | |
56 } | |
57 | |
58 inline void registerDelayedMarkNoTracing(const void* objectPointer) { | |
59 DCHECK(toDerived()->getMarkingMode() != VisitorMarkingMode::WeakProcessing); | |
60 toDerived()->heap().pushPostMarkingCallback( | |
61 const_cast<void*>(objectPointer), &markNoTracingCallback); | |
62 } | |
63 | |
64 inline void registerWeakMembers(const void* closure, | |
65 const void* objectPointer, | |
66 WeakCallback callback) { | |
67 DCHECK(toDerived()->getMarkingMode() != VisitorMarkingMode::WeakProcessing); | |
68 // We don't want to run weak processings when taking a snapshot. | |
69 if (toDerived()->getMarkingMode() == VisitorMarkingMode::SnapshotMarking) | |
70 return; | |
71 toDerived()->heap().pushThreadLocalWeakCallback( | |
72 const_cast<void*>(closure), const_cast<void*>(objectPointer), callback); | |
73 } | |
74 | |
75 inline void registerWeakTable(const void* closure, | |
76 EphemeronCallback iterationCallback, | |
77 EphemeronCallback iterationDoneCallback) { | |
78 DCHECK(toDerived()->getMarkingMode() != VisitorMarkingMode::WeakProcessing); | |
79 toDerived()->heap().registerWeakTable( | |
80 const_cast<void*>(closure), iterationCallback, iterationDoneCallback); | |
81 } | |
82 | |
83 #if DCHECK_IS_ON() | |
84 inline bool weakTableRegistered(const void* closure) { | |
85 return toDerived()->heap().weakTableRegistered(closure); | |
86 } | |
87 #endif | |
88 | |
89 inline bool ensureMarked(const void* objectPointer) { | |
90 if (!objectPointer) | |
91 return false; | |
92 | |
93 HeapObjectHeader* header = HeapObjectHeader::fromPayload(objectPointer); | |
94 if (header->isMarked()) | |
95 return false; | |
96 #if DCHECK_IS_ON() | |
97 toDerived()->markNoTracing(objectPointer); | |
98 #else | |
99 // Inline what the above markNoTracing() call expands to, | |
100 // so as to make sure that we do get all the benefits (asserts excepted.) | |
101 header->mark(); | |
102 #endif | |
103 return true; | |
104 } | |
105 | |
106 inline void registerWeakCellWithCallback(void** cell, WeakCallback callback) { | |
107 DCHECK(toDerived()->getMarkingMode() != VisitorMarkingMode::WeakProcessing); | |
108 // We don't want to run weak processings when taking a snapshot. | |
109 if (toDerived()->getMarkingMode() == VisitorMarkingMode::SnapshotMarking) | |
110 return; | |
111 toDerived()->heap().pushGlobalWeakCallback(cell, callback); | |
112 } | |
113 | |
114 Derived* toDerived() { return static_cast<Derived*>(this); } | |
115 | |
116 private: | |
117 static void markNoTracingCallback(Visitor* visitor, void* object) { | |
118 visitor->markNoTracing(object); | |
119 } | |
120 }; | |
121 | |
122 } // namespace blink | |
123 | |
124 #endif | |
OLD | NEW |