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