| Index: Source/platform/heap/Heap.h
|
| diff --git a/Source/platform/heap/Heap.h b/Source/platform/heap/Heap.h
|
| index 6e4793554fb6a32774527b027917ceea9f8892a9..fb6184e72a181cae532192422c3a61ab2d7a7f0f 100644
|
| --- a/Source/platform/heap/Heap.h
|
| +++ b/Source/platform/heap/Heap.h
|
| @@ -66,11 +66,12 @@ const size_t blinkPagesPerRegion = 10;
|
| const size_t allocationGranularity = 8;
|
| const size_t allocationMask = allocationGranularity - 1;
|
| const size_t objectStartBitMapSize = (blinkPageSize + ((8 * allocationGranularity) - 1)) / (8 * allocationGranularity);
|
| -const size_t reservedForObjectBitMap = ((objectStartBitMapSize + allocationMask) & ~allocationMask);
|
| +const size_t reservedForObjectStartBitMap = ((objectStartBitMapSize + allocationMask) & ~allocationMask);
|
| +const size_t objectMarkBitMapSize = (blinkPageSize + ((8 * allocationGranularity) - 1)) / (8 * allocationGranularity);
|
| +const size_t reservedForObjectMarkBitMap = ((objectStartBitMapSize + allocationMask) & ~allocationMask);
|
| const size_t maxHeapObjectSizeLog2 = 27;
|
| const size_t maxHeapObjectSize = 1 << maxHeapObjectSizeLog2;
|
|
|
| -const size_t markBitMask = 1;
|
| const size_t freeListMask = 2;
|
| // The dead bit is used for objects that have gone through a GC marking, but did
|
| // not get swept before a new GC started. In that case we set the dead bit on
|
| @@ -179,7 +180,10 @@ PLATFORM_EXPORT inline BaseHeapPage* pageHeaderFromObject(const void* object)
|
| template<typename Header>
|
| class LargeHeapObject : public BaseHeapPage {
|
| public:
|
| - LargeHeapObject(PageMemory* storage, const GCInfo* gcInfo, ThreadState* state) : BaseHeapPage(storage, gcInfo, state)
|
| + LargeHeapObject(PageMemory* storage, const GCInfo* gcInfo, ThreadState* state)
|
| + : BaseHeapPage(storage, gcInfo, state)
|
| + , m_next(nullptr)
|
| + , m_marked(false)
|
| {
|
| COMPILE_ASSERT(!(sizeof(LargeHeapObject<Header>) & allocationMask), large_heap_object_header_misaligned);
|
| }
|
| @@ -187,6 +191,22 @@ public:
|
| virtual void checkAndMarkPointer(Visitor*, Address) override;
|
| virtual bool isLargeObject() override { return true; }
|
|
|
| + virtual void markObject(Address address) override
|
| + {
|
| + ASSERT(!m_marked);
|
| + m_marked = true;
|
| + }
|
| +
|
| + virtual bool objectIsMarked(Address address) override
|
| + {
|
| + return m_marked;
|
| + }
|
| +
|
| + void clearObjectMarkBitMap()
|
| + {
|
| + m_marked = false;
|
| + }
|
| +
|
| #if ENABLE(GC_PROFILE_MARKING)
|
| virtual const GCInfo* findGCInfo(Address address)
|
| {
|
| @@ -245,10 +265,10 @@ public:
|
| return reinterpret_cast<Header*>(headerAddress);
|
| }
|
|
|
| + void mark(Visitor*);
|
| bool isMarked();
|
| - void unmark();
|
| +
|
| size_t objectPayloadSizeForTesting();
|
| - void mark(Visitor*);
|
| void finalize();
|
| void setDeadMark();
|
| virtual void markOrphaned()
|
| @@ -263,6 +283,7 @@ private:
|
| friend class ThreadHeap<Header>;
|
|
|
| LargeHeapObject<Header>* m_next;
|
| + bool m_marked;
|
| };
|
|
|
| // The BasicObjectHeader is the minimal object header. It is used when
|
| @@ -340,10 +361,9 @@ public:
|
| { }
|
|
|
| inline void checkHeader() const;
|
| - inline bool isMarked() const;
|
|
|
| inline void mark();
|
| - inline void unmark();
|
| + inline bool isMarked() const;
|
|
|
| inline const GCInfo* gcInfo() { return 0; }
|
|
|
| @@ -497,6 +517,23 @@ public:
|
|
|
| bool isEmpty();
|
|
|
| + virtual void markObject(Address object) override
|
| + {
|
| + size_t offset = (object - payload()) / allocationGranularity;
|
| + ASSERT(!((object - payload()) & allocationMask));
|
| + ASSERT(!(m_objectMarkBitMap[offset / 8] & (1 << (offset & 7))));
|
| + m_objectMarkBitMap[offset / 8] |= (1 << (offset & 7));
|
| + }
|
| +
|
| + virtual bool objectIsMarked(Address object) override
|
| + {
|
| + size_t offset = (object - payload()) / allocationGranularity;
|
| + ASSERT(!((object - payload()) & allocationMask));
|
| + return m_objectMarkBitMap[offset / 8] & (1 << (offset & 7));
|
| + }
|
| +
|
| + void clearObjectMarkBitMap();
|
| +
|
| // Returns true for the whole blinkPageSize page that the page is on, even
|
| // for the header, and the unmapped guard page at the start. That ensures
|
| // the result can be used to populate the negative page cache.
|
| @@ -522,7 +559,7 @@ public:
|
| Address end() { return payload() + payloadSize(); }
|
|
|
| size_t objectPayloadSizeForTesting();
|
| - void clearLiveAndMarkDead();
|
| + void makeUnmarkedObjectsDead();
|
| void sweep(ThreadHeap<Header>*);
|
| void clearObjectStartBitMap();
|
| void finalize(Header*);
|
| @@ -566,7 +603,8 @@ protected:
|
| HeapPage<Header>* m_next;
|
| intptr_t m_padding; // Preserve 8-byte alignment on 32-bit systems.
|
| bool m_objectStartBitMapComputed;
|
| - uint8_t m_objectStartBitMap[reservedForObjectBitMap];
|
| + uint8_t m_objectStartBitMap[reservedForObjectStartBitMap];
|
| + uint8_t m_objectMarkBitMap[reservedForObjectMarkBitMap];
|
|
|
| friend class ThreadHeap<Header>;
|
| };
|
| @@ -694,7 +732,8 @@ public:
|
| virtual void postSweepProcessing() = 0;
|
|
|
| virtual void clearFreeLists() = 0;
|
| - virtual void clearLiveAndMarkDead() = 0;
|
| + virtual void clearObjectMarkBitMaps() = 0;
|
| + virtual void makeUnmarkedObjectsDead() = 0;
|
|
|
| virtual void makeConsistentForSweeping() = 0;
|
| #if ENABLE(ASSERT)
|
| @@ -761,7 +800,8 @@ public:
|
| virtual void postSweepProcessing() override;
|
|
|
| virtual void clearFreeLists() override;
|
| - virtual void clearLiveAndMarkDead() override;
|
| + virtual void clearObjectMarkBitMaps() override;
|
| + virtual void makeUnmarkedObjectsDead() override;
|
|
|
| virtual void makeConsistentForSweeping() override;
|
| #if ENABLE(ASSERT)
|
| @@ -1307,11 +1347,10 @@ Address HeapObjectHeader::payloadEnd()
|
| return reinterpret_cast<Address>(this) + size();
|
| }
|
|
|
| -NO_SANITIZE_ADDRESS
|
| void HeapObjectHeader::mark()
|
| {
|
| checkHeader();
|
| - m_size = m_size | markBitMask;
|
| + pageHeaderFromObject(this)->markObject(reinterpret_cast<Address>(this));
|
| }
|
|
|
| Address FinalizedHeapObjectHeader::payload()
|
|
|