Index: Source/platform/heap/Heap.h |
diff --git a/Source/platform/heap/Heap.h b/Source/platform/heap/Heap.h |
index 0088c15fce8173262c05554c8cf0cbf0a7a8b031..45b4d96324fb255864a538a9a25b57e084ee2d0b 100644 |
--- a/Source/platform/heap/Heap.h |
+++ b/Source/platform/heap/Heap.h |
@@ -185,7 +185,7 @@ public: |
if (!objectContains(address)) |
return nullptr; |
return gcInfo(); |
- } |
+ h |
#endif |
#if ENABLE(GC_PROFILE_HEAP) |
@@ -1433,8 +1433,8 @@ public: |
static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNoTracing(t); } |
- template<typename T, typename Traits> |
- static void trace(Visitor* visitor, T& t) |
+ template<typename T, typename Traits, typename VisitorDispatcher> |
+ static void trace(VisitorDispatcher visitor, T& t) |
{ |
CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t); |
} |
@@ -2007,7 +2007,8 @@ namespace WTF { |
// weak elements. |
template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits> { |
- static bool trace(blink::Visitor* visitor, T& t) |
+ template<typename VisitorDispatcher> |
+ static bool trace(VisitorDispatcher visitor, T& t) |
{ |
blink::TraceTrait<T>::trace(visitor, &t); |
return false; |
@@ -2016,7 +2017,8 @@ struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits> |
template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Member<T>, Traits> { |
- static bool trace(blink::Visitor* visitor, blink::Member<T>& t) |
+ template<typename VisitorDispatcher> |
+ static bool trace(VisitorDispatcher visitor, blink::Member<T>& t) |
{ |
blink::TraceTrait<T>::mark(visitor, const_cast<typename RemoveConst<T>::Type*>(t.get())); |
return false; |
@@ -2201,7 +2203,7 @@ namespace blink { |
// We do nothing, even if WTF::WeakPointersActStrong. |
template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, strongify, T, Traits> { |
- static bool trace(Visitor*, T&) { return false; } |
+ template<typename VisitorDispatcher> static bool trace(VisitorDispatcher, T&) { return false; } |
}; |
template<typename T> |
@@ -2219,7 +2221,7 @@ static void verifyGarbageCollectedIfMember(Member<T>* t) |
// both. |
template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
struct CollectionBackingTraceTrait { |
- static bool trace(Visitor* visitor, T&t) |
+ template<typename VisitorDispatcher> static bool trace(VisitorDispatcher visitor, T& t) |
{ |
verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); |
return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Traits>::trace(visitor, t); |
@@ -2334,6 +2336,85 @@ struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i |
template<typename T, typename U, typename V> |
struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator>> { }; |
+NO_SANITIZE_ADDRESS inline |
+bool HeapObjectHeader::isMarked() const |
+{ |
+ checkHeader(); |
+ return m_size & markBitMask; |
+} |
+ |
+NO_SANITIZE_ADDRESS inline |
+void HeapObjectHeader::mark() |
+{ |
+ checkHeader(); |
+ ASSERT(!isMarked()); |
+ m_size = m_size | markBitMask; |
+} |
+ |
+ALWAYS_INLINE bool InlinedGlobalMarkingVisitor::isMarked(const void* objectPointer) |
+{ |
+ return GeneralHeapObjectHeader::fromPayload(objectPointer)->isMarked(); |
+} |
+ |
+ALWAYS_INLINE void InlinedGlobalMarkingVisitor::visitHeader(HeapObjectHeader* header, const void* objectPointer, TraceCallback callback) |
+{ |
+ ASSERT(header); |
+ ASSERT(objectPointer); |
+ // Check that we are not marking objects that are outside |
+ // the heap by calling Heap::contains. However we cannot |
+ // call Heap::contains when outside a GC and we call mark |
+ // when doing weakness for ephemerons. Hence we only check |
+ // when called within. |
+ ASSERT(!ThreadState::current()->isInGC() || Heap::containedInHeapOrOrphanedPage(header)); |
+ |
+ // If you hit this ASSERT, 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 ASSERT, but it is OK because |
+ // release builds will crash in the following header->isMarked() |
+ // because all the entries of the orphaned heaps are zapped. |
+ ASSERT(!pageFromObject(objectPointer)->orphaned()); |
+ |
+ if (header->isMarked()) |
+ return; |
+ header->mark(); |
+ |
+#if ENABLE(GC_PROFILE_MARKING) |
+ QUACK! |
+#endif |
+ if (callback) |
+ m_visitor->pushTraceCallback(const_cast<void*>(objectPointer), callback); |
+} |
+ |
+ALWAYS_INLINE void InlinedGlobalMarkingVisitor::mark(const void* objectPointer, TraceCallback callback) |
+{ |
+ if (!objectPointer) |
+ return; |
+ GeneralHeapObjectHeader* header = GeneralHeapObjectHeader::fromPayload(objectPointer); |
+ visitHeader(header, header->payload(), callback); |
+} |
+ |
+ALWAYS_INLINE bool InlinedGlobalMarkingVisitor::ensureMarked(const void* objectPointer) |
+{ |
+ if (!objectPointer) |
+ return false; |
+#if ENABLE(ASSERT) |
+ if (isMarked(objectPointer)) |
+ return false; |
+ |
+ markNoTracing(objectPointer); |
+#else |
+ // Inline what the above markNoTracing() call expands to, |
+ // so as to make sure that we do get all the benefits. |
+ GeneralHeapObjectHeader* header = |
+ GeneralHeapObjectHeader::fromPayload(objectPointer); |
+ if (header->isMarked()) |
+ return false; |
+ header->mark(); |
+#endif |
+ return true; |
+} |
+ |
} // namespace blink |
#endif // Heap_h |