Index: third_party/WebKit/Source/platform/heap/VisitorImpl.h |
diff --git a/third_party/WebKit/Source/platform/heap/VisitorImpl.h b/third_party/WebKit/Source/platform/heap/VisitorImpl.h |
new file mode 100644 |
index 0000000000000000000000000000000000000000..f2e90e00bfc7f4be09a74bc76448f26a6c59de66 |
--- /dev/null |
+++ b/third_party/WebKit/Source/platform/heap/VisitorImpl.h |
@@ -0,0 +1,137 @@ |
+// Copyright 2017 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#ifndef VisitorImpl_h |
+#define VisitorImpl_h |
+ |
+#include "platform/heap/Heap.h" |
+#include "platform/heap/ThreadState.h" |
+#include "platform/heap/Visitor.h" |
+#include "wtf/Allocator.h" |
+ |
+namespace blink { |
+ |
+inline void Visitor::markHeader(HeapObjectHeader* header, |
+ const void* objectPointer, |
+ TraceCallback callback) { |
+ DCHECK(header); |
+ DCHECK(objectPointer); |
+ |
+ // If you hit this DCHECK, it means that there is a dangling pointer |
+ // from a live thread heap to a dead thread heap. We must eliminate |
+ // the dangling pointer. |
+ // Release builds don't have the DCHECK, but it is OK because |
+ // release builds will crash in the following header->isMarked() |
+ // because all the entries of the orphaned arenas are zapped. |
+ DCHECK(!pageFromObject(objectPointer)->orphaned()); |
+ |
+ if (header->isMarked()) |
+ return; |
+ |
+ DCHECK(ThreadState::current()->isInGC()); |
+ DCHECK(getMarkingMode() != VisitorMarkingMode::WeakProcessing); |
+ |
+ // A GC should only mark the objects that belong in its heap. |
+ DCHECK(&pageFromObject(objectPointer)->arena()->getThreadState()->heap() == |
+ &heap()); |
+ |
+ header->mark(); |
+ |
+ if (callback) |
+ heap().pushTraceCallback(const_cast<void*>(objectPointer), callback); |
+} |
+ |
+inline void Visitor::markHeader(HeapObjectHeader* header, |
+ TraceCallback callback) { |
+ markHeader(header, header->payload(), callback); |
+} |
+ |
+inline void Visitor::mark(const void* objectPointer, TraceCallback callback) { |
+ if (!objectPointer) |
+ return; |
+ HeapObjectHeader* header = HeapObjectHeader::fromPayload(objectPointer); |
+ markHeader(header, header->payload(), callback); |
+} |
+ |
+inline void Visitor::markHeaderNoTracing(HeapObjectHeader* header) { |
+ markHeader(header, header->payload(), reinterpret_cast<TraceCallback>(0)); |
+} |
+ |
+inline void Visitor::registerDelayedMarkNoTracing(const void* objectPointer) { |
+ DCHECK(getMarkingMode() != VisitorMarkingMode::WeakProcessing); |
+ heap().pushPostMarkingCallback(const_cast<void*>(objectPointer), |
+ &markNoTracingCallback); |
+} |
+ |
+inline void Visitor::registerWeakMembers(const void* closure, |
+ const void* objectPointer, |
+ WeakCallback callback) { |
+ DCHECK(getMarkingMode() != VisitorMarkingMode::WeakProcessing); |
+ // We don't want to run weak processings when taking a snapshot. |
+ if (getMarkingMode() == VisitorMarkingMode::SnapshotMarking) |
+ return; |
+ heap().pushThreadLocalWeakCallback( |
+ const_cast<void*>(closure), const_cast<void*>(objectPointer), callback); |
+} |
+ |
+inline void Visitor::registerWeakTable( |
+ const void* closure, |
+ EphemeronCallback iterationCallback, |
+ EphemeronCallback iterationDoneCallback) { |
+ DCHECK(getMarkingMode() != VisitorMarkingMode::WeakProcessing); |
+ heap().registerWeakTable(const_cast<void*>(closure), iterationCallback, |
+ iterationDoneCallback); |
+} |
+ |
+#if DCHECK_IS_ON() |
+inline bool Visitor::weakTableRegistered(const void* closure) { |
+ return heap().weakTableRegistered(closure); |
+} |
+#endif |
+ |
+inline bool Visitor::ensureMarked(const void* objectPointer) { |
+ if (!objectPointer) |
+ return false; |
+ |
+ HeapObjectHeader* header = HeapObjectHeader::fromPayload(objectPointer); |
+ if (header->isMarked()) |
+ return false; |
+#if DCHECK_IS_ON() |
+ markNoTracing(objectPointer); |
+#else |
+ // Inline what the above markNoTracing() call expands to, |
+ // so as to make sure that we do get all the benefits (asserts excepted.) |
+ header->mark(); |
+#endif |
+ return true; |
+} |
+ |
+inline void Visitor::registerWeakCellWithCallback(void** cell, |
+ WeakCallback callback) { |
+ DCHECK(getMarkingMode() != VisitorMarkingMode::WeakProcessing); |
+ // We don't want to run weak processings when taking a snapshot. |
+ if (getMarkingMode() == VisitorMarkingMode::SnapshotMarking) |
+ return; |
+ heap().pushGlobalWeakCallback(cell, callback); |
+} |
+ |
+inline void Visitor::registerBackingStoreReference(void* slot) { |
+ if (getMarkingMode() != VisitorMarkingMode::GlobalMarkingWithCompaction) |
+ return; |
+ heap().registerMovingObjectReference( |
+ reinterpret_cast<MovableReference*>(slot)); |
+} |
+ |
+inline void Visitor::registerBackingStoreCallback(void* backingStore, |
+ MovingObjectCallback callback, |
+ void* callbackData) { |
+ if (getMarkingMode() != VisitorMarkingMode::GlobalMarkingWithCompaction) |
+ return; |
+ heap().registerMovingObjectCallback( |
+ reinterpret_cast<MovableReference>(backingStore), callback, callbackData); |
+} |
+ |
+} // namespace blink |
+ |
+#endif |