| Index: Source/platform/heap/Heap.h
|
| diff --git a/Source/platform/heap/Heap.h b/Source/platform/heap/Heap.h
|
| index 3b3077abf8f802b21905a0d9c8369732a76828cd..617c6ba6e4060abac5aa9379e9b1c46edc1eacdd 100644
|
| --- a/Source/platform/heap/Heap.h
|
| +++ b/Source/platform/heap/Heap.h
|
| @@ -65,7 +65,8 @@ 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 maxHeapObjectSize = 1 << 27;
|
| +const size_t maxHeapObjectSizeLog2 = 27;
|
| +const size_t maxHeapObjectSize = 1 << maxHeapObjectSizeLog2;
|
|
|
| const size_t markBitMask = 1;
|
| const size_t freeListMask = 2;
|
| @@ -76,7 +77,14 @@ const size_t freeListMask = 2;
|
| // tracing of already finalized objects in another thread's heap which is a
|
| // use-after-free situation.
|
| const size_t deadBitMask = 4;
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| +const size_t heapObjectGenerations = 8;
|
| +const size_t maxHeapObjectAge = heapObjectGenerations - 1;
|
| +const size_t heapObjectAgeMask = ~(maxHeapObjectSize - 1);
|
| +const size_t sizeMask = ~heapObjectAgeMask & ~static_cast<size_t>(7);
|
| +#else
|
| const size_t sizeMask = ~static_cast<size_t>(7);
|
| +#endif
|
| const uint8_t freelistZapValue = 42;
|
| const uint8_t finalizedZapValue = 24;
|
| // The orphaned zap value must be zero in the lowest bits to allow for using
|
| @@ -95,6 +103,10 @@ template<ThreadAffinity affinity> class ThreadLocalPersistents;
|
| template<typename T, typename RootsAccessor = ThreadLocalPersistents<ThreadingTrait<T>::Affinity > > class Persistent;
|
| template<typename T> class CrossThreadPersistent;
|
|
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| +class TracedValue;
|
| +#endif
|
| +
|
| PLATFORM_EXPORT size_t osPageSize();
|
|
|
| // Blink heap pages are set up with a guard page before and after the
|
| @@ -173,7 +185,7 @@ public:
|
| virtual void checkAndMarkPointer(Visitor*, Address) OVERRIDE;
|
| virtual bool isLargeObject() OVERRIDE { return true; }
|
|
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILE_MARKING)
|
| virtual const GCInfo* findGCInfo(Address address)
|
| {
|
| if (!objectContains(address))
|
| @@ -182,6 +194,10 @@ public:
|
| }
|
| #endif
|
|
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| + void snapshot(TracedValue*, ThreadState::SnapshotInfo*);
|
| +#endif
|
| +
|
| void link(LargeHeapObject<Header>** previousNext)
|
| {
|
| m_next = *previousNext;
|
| @@ -264,6 +280,22 @@ public:
|
| NO_SANITIZE_ADDRESS
|
| size_t size() const { return m_size & sizeMask; }
|
|
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| + NO_SANITIZE_ADDRESS
|
| + size_t encodedSize() const { return m_size; }
|
| +
|
| + NO_SANITIZE_ADDRESS
|
| + size_t age() const { return m_size >> maxHeapObjectSizeLog2; }
|
| +
|
| + NO_SANITIZE_ADDRESS
|
| + void incAge()
|
| + {
|
| + size_t current = age();
|
| + if (current < maxHeapObjectAge)
|
| + m_size = ((current + 1) << maxHeapObjectSizeLog2) | (m_size & ~heapObjectAgeMask);
|
| + }
|
| +#endif
|
| +
|
| protected:
|
| size_t m_size;
|
| };
|
| @@ -474,9 +506,12 @@ public:
|
| void clearObjectStartBitMap();
|
| void finalize(Header*);
|
| virtual void checkAndMarkPointer(Visitor*, Address) OVERRIDE;
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILE_MARKING)
|
| const GCInfo* findGCInfo(Address) OVERRIDE;
|
| #endif
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| + virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*);
|
| +#endif
|
| ThreadHeap<Header>* heap() { return m_heap; }
|
| #if defined(ADDRESS_SANITIZER)
|
| void poisonUnmarkedObjects();
|
| @@ -806,10 +841,14 @@ public:
|
| // page in this thread heap.
|
| virtual BaseHeapPage* heapPageFromAddress(Address) = 0;
|
|
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILE_MARKING)
|
| virtual const GCInfo* findGCInfoOfLargeHeapObject(Address) = 0;
|
| #endif
|
|
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| + virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*) = 0;
|
| +#endif
|
| +
|
| // Sweep this part of the Blink heap. This finalizes dead objects
|
| // and builds freelists for all the unused memory.
|
| virtual void sweep() = 0;
|
| @@ -849,9 +888,12 @@ public:
|
| virtual void cleanupPages();
|
|
|
| virtual BaseHeapPage* heapPageFromAddress(Address);
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILE_MARKING)
|
| virtual const GCInfo* findGCInfoOfLargeHeapObject(Address);
|
| #endif
|
| +#if ENABLE(GC_PROFILE_HEAP)
|
| + virtual void snapshot(TracedValue*, ThreadState::SnapshotInfo*);
|
| +#endif
|
| virtual void sweep();
|
| virtual void clearFreeLists();
|
| virtual void clearLiveAndMarkDead();
|
| @@ -979,7 +1021,7 @@ public:
|
| // heaps. If so marks the object pointed to as live.
|
| static Address checkAndMarkPointer(Visitor*, Address);
|
|
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILE_MARKING)
|
| // Dump the path to specified object on the next GC. This method is to be invoked from GDB.
|
| static void dumpPathToObjectOnNextGC(void* p);
|
|
|
| @@ -1833,7 +1875,7 @@ struct GCInfoTrait<HashMap<Key, Value, T, U, V, HeapAllocator> > {
|
| 0,
|
| false, // HashMap needs no finalizer.
|
| WTF::IsPolymorphic<TargetType>::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -1851,7 +1893,7 @@ struct GCInfoTrait<HashSet<T, U, V, HeapAllocator> > {
|
| 0,
|
| false, // HashSet needs no finalizer.
|
| WTF::IsPolymorphic<TargetType>::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -1869,7 +1911,7 @@ struct GCInfoTrait<LinkedHashSet<T, U, V, HeapAllocator> > {
|
| LinkedHashSet<T, U, V, HeapAllocator>::finalize,
|
| true, // Needs finalization. The anchor needs to unlink itself from the chain.
|
| WTF::IsPolymorphic<TargetType>::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -1887,7 +1929,7 @@ struct GCInfoTrait<ListHashSet<ValueArg, inlineCapacity, U, HeapListHashSetAlloc
|
| 0,
|
| false, // ListHashSet needs no finalization though its backing might.
|
| false, // no vtable.
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -1905,7 +1947,7 @@ struct GCInfoTrait<WTF::ListHashSetNode<T, Allocator> > {
|
| TargetType::finalize,
|
| WTF::HashTraits<T>::needsDestruction, // The node needs destruction if its data does.
|
| false, // no vtable.
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -1917,7 +1959,7 @@ template<typename T>
|
| struct GCInfoTrait<Vector<T, 0, HeapAllocator> > {
|
| static const GCInfo* get()
|
| {
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| typedef Vector<T, 0, HeapAllocator> TargetType;
|
| #endif
|
| static const GCInfo info = {
|
| @@ -1925,7 +1967,7 @@ struct GCInfoTrait<Vector<T, 0, HeapAllocator> > {
|
| 0,
|
| false, // Vector needs no finalizer if it has no inline capacity.
|
| WTF::IsPolymorphic<Vector<T, 0, HeapAllocator> >::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -1947,7 +1989,7 @@ struct GCInfoTrait<Vector<T, inlineCapacity, HeapAllocator> > {
|
| // Finalizer is needed to destruct things stored in the inline capacity.
|
| inlineCapacity && VectorTraits<T>::needsDestruction,
|
| WTF::IsPolymorphic<TargetType>::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -1965,7 +2007,7 @@ struct GCInfoTrait<Deque<T, 0, HeapAllocator> > {
|
| 0,
|
| false, // Deque needs no finalizer if it has no inline capacity.
|
| WTF::IsPolymorphic<TargetType>::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -1984,7 +2026,7 @@ struct GCInfoTrait<HashCountedSet<T, U, V, HeapAllocator> > {
|
| 0,
|
| false, // HashCountedSet is just a HashTable, and needs no finalizer.
|
| WTF::IsPolymorphic<TargetType>::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -2007,7 +2049,7 @@ struct GCInfoTrait<Deque<T, inlineCapacity, HeapAllocator> > {
|
| // Finalizer is needed to destruct things stored in the inline capacity.
|
| inlineCapacity && VectorTraits<T>::needsDestruction,
|
| WTF::IsPolymorphic<TargetType>::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -2026,7 +2068,7 @@ struct GCInfoTrait<HeapVectorBacking<T, Traits> > {
|
| FinalizerTrait<TargetType>::finalize,
|
| Traits::needsDestruction,
|
| false, // We don't support embedded objects in HeapVectors with vtables.
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
| @@ -2044,7 +2086,7 @@ struct GCInfoTrait<HeapHashTableBacking<Table> > {
|
| HeapHashTableBacking<Table>::finalize,
|
| Table::ValueTraits::needsDestruction,
|
| WTF::IsPolymorphic<TargetType>::value,
|
| -#if ENABLE(GC_TRACING)
|
| +#if ENABLE(GC_PROFILING)
|
| TypenameStringTrait<TargetType>::get()
|
| #endif
|
| };
|
|
|