Index: Source/platform/heap/Heap.h |
diff --git a/Source/platform/heap/Heap.h b/Source/platform/heap/Heap.h |
index 0ea584fa03180b5019feaed7ead2362acc70e66d..2ca89dd4070e421526e505713a1b9dc57a54be1c 100644 |
--- a/Source/platform/heap/Heap.h |
+++ b/Source/platform/heap/Heap.h |
@@ -2292,6 +2292,90 @@ struct GCInfoTrait<HeapDeque<T, inlineCapacity> > : public GCInfoTrait<Deque<T, |
template<typename T, typename U, typename V> |
struct GCInfoTrait<HeapHashCountedSet<T, U, V> > : public GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator> > { }; |
+static inline bool objectInTerminatingThreadHeap(const void* objectPointer) |
+{ |
+ BaseHeapPage* page = pageFromObject(objectPointer); |
+ ASSERT(!page->orphaned()); |
+ // When doing a thread local GC, the marker checks if |
+ // the object resides in another thread's heap. The |
+ // object should not be traced, if it does. |
+ return page->terminating(); |
+} |
+ |
+NO_SANITIZE_ADDRESS inline |
+void HeapObjectHeader::mark() |
+{ |
+ checkHeader(); |
+ ASSERT(!isMarked()); |
+ m_size = m_size | markBitMask; |
+} |
+ |
+NO_SANITIZE_ADDRESS inline |
+bool HeapObjectHeader::isMarked() const |
+{ |
+ checkHeader(); |
+ return m_size & markBitMask; |
+} |
+ |
+inline |
+HeapObjectHeader* HeapObjectHeader::fromPayload(const void* payload) |
+{ |
+ Address addr = reinterpret_cast<Address>(const_cast<void*>(payload)); |
+ HeapObjectHeader* header = |
+ reinterpret_cast<HeapObjectHeader*>(addr - sizeof(HeapObjectHeader)); |
+ return header; |
+} |
+ |
+inline |
+GeneralHeapObjectHeader* GeneralHeapObjectHeader::fromPayload(const void* payload) |
+{ |
+ Address addr = reinterpret_cast<Address>(const_cast<void*>(payload)); |
+ GeneralHeapObjectHeader* header = |
+ reinterpret_cast<GeneralHeapObjectHeader*>(addr - sizeof(GeneralHeapObjectHeader)); |
+ return header; |
+} |
+ |
+ inline bool Visitor::ensureMarked(const void* objectPointer) |
+ { |
+ (void)m_mode; |
+ if (!objectPointer) |
+ return false; |
+ // if (UNLIKELY(m_mode && !objectInTerminatingThreadHeap(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; |
+ } |
+ |
+ // if (UNLIKELY(m_mode && !objectInTerminatingThreadHeap(objectPointer))) |
+ // return false; |
+#define DEFINE_ENSURE_MARKED_METHOD(Type) \ |
+ inline bool Visitor::ensureMarked(const Type* objectPointer) \ |
+ { \ |
+ if (!objectPointer) \ |
+ return false; \ |
+ HeapObjectHeader* header = \ |
+ HeapObjectHeader::fromPayload(objectPointer); \ |
+ if (header->isMarked()) \ |
+ return false; \ |
+ header->mark(); \ |
+ return true; \ |
+ } |
+ FOR_EACH_TYPED_HEAP(DEFINE_ENSURE_MARKED_METHOD) |
+#undef DEFINE_ENSURE_MARKED_METHOD |
+ |
} // namespace blink |
#endif // Heap_h |