| Index: Source/platform/heap/Heap.h | 
| diff --git a/Source/platform/heap/Heap.h b/Source/platform/heap/Heap.h | 
| index f006bb647cb850a3598420fbc56b7a2093ee1fda..f5106c50a0bb383f6ebc6380f77367ff778b2978 100644 | 
| --- a/Source/platform/heap/Heap.h | 
| +++ b/Source/platform/heap/Heap.h | 
| @@ -401,11 +401,26 @@ public: | 
| bool terminating() { return m_terminating; } | 
| void setTerminating() { m_terminating = true; } | 
|  | 
| +    void markAsLazilySwept(); | 
| +    PLATFORM_EXPORT bool hasBeenLazilySwept() const; | 
| + | 
| private: | 
| PageMemory* m_storage; | 
| ThreadHeap* m_heap; | 
| // Whether the page is part of a terminating thread or not. | 
| bool m_terminating; | 
| + | 
| +protected: | 
| +    // Track the (lazy) sweeping state of a page. The page's | 
| +    // ThreadState keeps a sweep token value, with the page being | 
| +    // updated with that value as it is swept. | 
| +    // | 
| +    // By comparing the ThreadState's current sweep token value with | 
| +    // the page's sweep status, its swept/unswept status can | 
| +    // readily be determined. | 
| +    // | 
| +    // 0 represents the unused/no-toggle state. | 
| +    unsigned m_sweepStatus : 2; | 
| }; | 
|  | 
| class HeapPage final : public BaseHeapPage { | 
| @@ -806,6 +821,8 @@ private: | 
| size_t m_promptlyFreedSize; | 
| }; | 
|  | 
| +extern BaseHeapPage* pageFromObject(const void*); | 
| + | 
| class PLATFORM_EXPORT Heap { | 
| public: | 
| static void init(); | 
| @@ -818,6 +835,34 @@ public: | 
| static bool containedInHeapOrOrphanedPage(void*); | 
| #endif | 
|  | 
| +    // Is the finalizable GC object still alive? If no GC is in progress, | 
| +    // it must be true. If a lazy sweep is in progress, it will be true if | 
| +    // the object hasn't been swept yet and it is marked, or it has | 
| +    // been swept and it is still alive. | 
| +    // | 
| +    // isFinalizedObjectAlive() must not be used with already-finalized object | 
| +    // references. | 
| +    // | 
| +    template<typename T> | 
| +    static bool isFinalizedObjectAlive(const T* objectPointer) | 
| +    { | 
| +        static_assert(IsGarbageCollectedType<T>::value, "only objects deriving from GarbageCollected can be used."); | 
| +#if ENABLE(OILPAN) | 
| +        BaseHeapPage* page = pageFromObject(objectPointer); | 
| +        if (!page->heap()->threadState()->isSweepingInProgress()) | 
| +            return true; | 
| + | 
| +        if (page->hasBeenLazilySwept()) | 
| +            return true; | 
| + | 
| +        return ObjectAliveTrait<T>::isHeapObjectAlive(s_markingVisitor, const_cast<T*>(objectPointer)); | 
| +#else | 
| +        // FIXME: remove when incremental sweeping is always on | 
| +        // (cf. ThreadState::postGCProcessing()). | 
| +        return true; | 
| +#endif | 
| +    } | 
| + | 
| // Push a trace callback on the marking stack. | 
| static void pushTraceCallback(void* containerObject, TraceCallback); | 
|  | 
|  |