Chromium Code Reviews| Index: third_party/WebKit/Source/platform/heap/Heap.h |
| diff --git a/third_party/WebKit/Source/platform/heap/Heap.h b/third_party/WebKit/Source/platform/heap/Heap.h |
| index 9762d092378cd86c26cb7a15f283c1e230bcb974..6131e703e12ff8c3e9dbee16c824268bb8ebfcad 100644 |
| --- a/third_party/WebKit/Source/platform/heap/Heap.h |
| +++ b/third_party/WebKit/Source/platform/heap/Heap.h |
| @@ -114,20 +114,147 @@ public: |
| } |
| }; |
| +// Stats for the heap. |
| +class GCHeapStats { |
| +public: |
| + GCHeapStats(); |
| + void setMarkedObjectSizeAtLastCompleteSweep(size_t size) { releaseStore(&m_markedObjectSizeAtLastCompleteSweep, size); } |
| + size_t markedObjectSizeAtLastCompleteSweep() { return acquireLoad(&m_markedObjectSizeAtLastCompleteSweep); } |
| + void increaseAllocatedObjectSize(size_t delta); |
| + void decreaseAllocatedObjectSize(size_t delta); |
| + size_t allocatedObjectSize() { return acquireLoad(&m_allocatedObjectSize); } |
| + void increaseMarkedObjectSize(size_t delta); |
| + size_t markedObjectSize() { return acquireLoad(&m_markedObjectSize); } |
| + void increaseAllocatedSpace(size_t delta); |
| + void decreaseAllocatedSpace(size_t delta); |
| + size_t allocatedSpace() { return acquireLoad(&m_allocatedSpace); } |
| + size_t objectSizeAtLastGC() { return acquireLoad(&m_objectSizeAtLastGC); } |
| + void increaseWrapperCount(size_t delta) { atomicAdd(&m_wrapperCount, static_cast<long>(delta)); } |
| + void decreaseWrapperCount(size_t delta) { atomicSubtract(&m_wrapperCount, static_cast<long>(delta)); } |
| + size_t wrapperCount() { return acquireLoad(&m_wrapperCount); } |
| + size_t wrapperCountAtLastGC() { return acquireLoad(&m_wrapperCountAtLastGC); } |
| + void increaseCollectedWrapperCount(size_t delta) { atomicAdd(&m_collectedWrapperCount, static_cast<long>(delta)); } |
| + size_t collectedWrapperCount() { return acquireLoad(&m_collectedWrapperCount); } |
| + size_t partitionAllocSizeAtLastGC() { return acquireLoad(&m_partitionAllocSizeAtLastGC); } |
| + void setEstimatedMarkingTimePerByte(double estimatedMarkingTimePerByte) { m_estimatedMarkingTimePerByte = estimatedMarkingTimePerByte; } |
| + double estimatedMarkingTimePerByte() const { return m_estimatedMarkingTimePerByte; } |
| + double estimatedMarkingTime(); |
| + void reset(); |
| + |
| +private: |
| + size_t m_allocatedSpace; |
| + size_t m_allocatedObjectSize; |
| + size_t m_objectSizeAtLastGC; |
| + size_t m_markedObjectSize; |
| + size_t m_markedObjectSizeAtLastCompleteSweep; |
| + size_t m_wrapperCount; |
| + size_t m_wrapperCountAtLastGC; |
| + size_t m_collectedWrapperCount; |
| + size_t m_partitionAllocSizeAtLastGC; |
| + double m_estimatedMarkingTimePerByte; |
| +}; |
| + |
| +using ThreadStateSet = HashSet<ThreadState*>; |
| + |
| class PLATFORM_EXPORT Heap { |
| - STATIC_ONLY(Heap); |
| public: |
| - static void init(); |
| - static void shutdown(); |
| - static void doShutdown(); |
| + Heap(); |
| + ~Heap(); |
| + |
| + RecursiveMutex& threadAttachMutex() { return m_threadAttachMutex; } |
| + const ThreadStateSet& threads() const { return m_threads; } |
| + GCHeapStats& heapStats() { return m_stats; } |
| + SafePointBarrier* safePointBarrier() { return m_safePointBarrier.get(); } |
| + FreePagePool* freePagePool() { return m_freePagePool.get(); } |
| + OrphanedPagePool* orphanedPagePool() { return m_orphanedPagePool.get(); } |
| + CallbackStack* markingStack() const { return m_markingStack.get(); } |
| + CallbackStack* postMarkingCallbackStack() const { return m_postMarkingCallbackStack.get(); } |
| + CallbackStack* globalWeakCallbackStack() const { return m_globalWeakCallbackStack.get(); } |
| + CallbackStack* ephemeronStack() const { return m_ephemeronStack.get(); } |
| + |
| + void attach(ThreadState*); |
| + void detach(ThreadState*); |
| + void lockThreadAttachMutex(); |
| + void unlockThreadAttachMutex(); |
| + bool park(); |
| + void resume(); |
| +#if ENABLE(ASSERT) |
| + bool isAtSafePoint() const; |
| + BasePage* findPageFromAddress(Address); |
| +#endif |
| + void preGC(); |
| + void postGC(BlinkGC::GCType); |
| + size_t objectPayloadSizeForTesting(); |
| + void visitPersistentRoots(Visitor*); |
| + void visitStackRoots(Visitor*); |
| + void checkAndPark(ThreadState*, SafePointAwareMutexLocker*); |
| + void enterSafePoint(ThreadState*); |
| + void leaveSafePoint(ThreadState*, SafePointAwareMutexLocker*); |
| + void flushHeapDoesNotContainCache(); |
| - static CrossThreadPersistentRegion& crossThreadPersistentRegion(); |
| + // This look-up uses the region search tree and a negative contains cache to |
| + // provide an efficient mapping from arbitrary addresses to the containing |
| + // heap-page if one exists. |
| + BasePage* lookupPageForAddress(Address); |
| + void addPageMemoryRegion(PageMemoryRegion*); |
| + void removePageMemoryRegion(PageMemoryRegion*); |
| + |
| + // Push a trace callback on the marking stack. |
| + void pushTraceCallback(void* containerObject, TraceCallback); |
| + |
| + // Push a trace callback on the post-marking callback stack. These |
| + // callbacks are called after normal marking (including ephemeron |
| + // iteration). |
| + void pushPostMarkingCallback(void*, TraceCallback); |
| + |
| + // Similar to the more general pushThreadLocalWeakCallback, but cell |
| + // pointer callbacks are added to a static callback work list and the weak |
| + // callback is performed on the thread performing garbage collection. This |
| + // is OK because cells are just cleared and no deallocation can happen. |
| + void pushGlobalWeakCallback(void** cell, WeakCallback); |
| + |
| + // Pop the top of a marking stack and call the callback with the visitor |
| + // and the object. Returns false when there is nothing more to do. |
| + bool popAndInvokeTraceCallback(Visitor*); |
| + |
| + // Remove an item from the post-marking callback stack and call |
| + // the callback with the visitor and the object pointer. Returns |
| + // false when there is nothing more to do. |
| + bool popAndInvokePostMarkingCallback(Visitor*); |
| + |
| + // Remove an item from the weak callback work list and call the callback |
| + // with the visitor and the closure pointer. Returns false when there is |
| + // nothing more to do. |
| + bool popAndInvokeGlobalWeakCallback(Visitor*); |
| + // Register an ephemeron table for fixed-point iteration. |
| + void registerWeakTable(void* containerObject, EphemeronCallback, EphemeronCallback); |
| #if ENABLE(ASSERT) |
| - static BasePage* findPageFromAddress(Address); |
| - static BasePage* findPageFromAddress(const void* pointer) { return findPageFromAddress(reinterpret_cast<Address>(const_cast<void*>(pointer))); } |
| + bool weakTableRegistered(const void*); |
| #endif |
| + void decommitCallbackStacks(); |
| + |
| + // Conservatively checks whether an address is a pointer in any of the |
| + // thread heaps. If so marks the object pointed to as live. |
| + Address checkAndMarkPointer(Visitor*, Address); |
| + |
| + void processMarkingStack(Visitor*); |
| + void postMarkingProcessing(Visitor*); |
| + void globalWeakProcessing(Visitor*); |
| + |
| + // Reset counters that track live and allocated-since-last-GC sizes. |
| + void resetHeapCounters(); |
| + |
| + // Add a weak pointer callback to the weak callback work list. General |
| + // object pointer callbacks are added to a thread local weak callback work |
| + // list and the callback is called on the thread that owns the object, with |
| + // the closure pointer as an argument. Most of the time, the closure and |
| + // the containerObject can be the same thing, but the containerObject is |
| + // constrained to be on the heap, since the heap is used to identify the |
| + // correct thread. |
| + void pushThreadLocalWeakCallback(void* closure, void* containerObject, WeakCallback); |
| + |
| template<typename T> |
| static inline bool isHeapObjectAlive(T* object) |
| { |
| @@ -178,54 +305,11 @@ public: |
| BasePage* page = pageFromObject(objectPointer); |
| if (page->hasBeenSwept()) |
| return false; |
| - ASSERT(page->heap()->threadState()->isSweepingInProgress()); |
| + ASSERT(page->arena()->threadState()->isSweepingInProgress()); |
| return !Heap::isHeapObjectAlive(const_cast<T*>(objectPointer)); |
| } |
| - // Push a trace callback on the marking stack. |
| - static void pushTraceCallback(void* containerObject, TraceCallback); |
| - |
| - // Push a trace callback on the post-marking callback stack. These |
| - // callbacks are called after normal marking (including ephemeron |
| - // iteration). |
| - static void pushPostMarkingCallback(void*, TraceCallback); |
| - |
| - // Add a weak pointer callback to the weak callback work list. General |
| - // object pointer callbacks are added to a thread local weak callback work |
| - // list and the callback is called on the thread that owns the object, with |
| - // the closure pointer as an argument. Most of the time, the closure and |
| - // the containerObject can be the same thing, but the containerObject is |
| - // constrained to be on the heap, since the heap is used to identify the |
| - // correct thread. |
| - static void pushThreadLocalWeakCallback(void* closure, void* containerObject, WeakCallback); |
| - |
| - // Similar to the more general pushThreadLocalWeakCallback, but cell |
| - // pointer callbacks are added to a static callback work list and the weak |
| - // callback is performed on the thread performing garbage collection. This |
| - // is OK because cells are just cleared and no deallocation can happen. |
| - static void pushGlobalWeakCallback(void** cell, WeakCallback); |
| - |
| - // Pop the top of a marking stack and call the callback with the visitor |
| - // and the object. Returns false when there is nothing more to do. |
| - static bool popAndInvokeTraceCallback(Visitor*); |
| - |
| - // Remove an item from the post-marking callback stack and call |
| - // the callback with the visitor and the object pointer. Returns |
| - // false when there is nothing more to do. |
| - static bool popAndInvokePostMarkingCallback(Visitor*); |
| - |
| - // Remove an item from the weak callback work list and call the callback |
| - // with the visitor and the closure pointer. Returns false when there is |
| - // nothing more to do. |
| - static bool popAndInvokeGlobalWeakCallback(Visitor*); |
| - |
| - // Register an ephemeron table for fixed-point iteration. |
| - static void registerWeakTable(void* containerObject, EphemeronCallback, EphemeronCallback); |
| -#if ENABLE(ASSERT) |
| - static bool weakTableRegistered(const void*); |
| -#endif |
| - |
| static inline size_t allocationSizeFromSize(size_t size) |
| { |
| // Check the size before computing the actual allocation size. The |
| @@ -239,41 +323,14 @@ public: |
| allocationSize = (allocationSize + allocationMask) & ~allocationMask; |
| return allocationSize; |
| } |
| - static Address allocateOnHeapIndex(ThreadState*, size_t, int heapIndex, size_t gcInfoIndex); |
| + static Address allocateOnArenaIndex(ThreadState*, size_t, int arenaIndex, size_t gcInfoIndex); |
| template<typename T> static Address allocate(size_t, bool eagerlySweep = false); |
| template<typename T> static Address reallocate(void* previous, size_t); |
| - static const char* gcReasonString(BlinkGC::GCReason); |
| static void collectGarbage(BlinkGC::StackState, BlinkGC::GCType, BlinkGC::GCReason); |
| static void collectGarbageForTerminatingThread(ThreadState*); |
| static void collectAllGarbage(); |
| - static void processMarkingStack(Visitor*); |
| - static void postMarkingProcessing(Visitor*); |
| - static void globalWeakProcessing(Visitor*); |
| - static void setForcePreciseGCForTesting(); |
| - |
| - static void preGC(); |
| - static void postGC(BlinkGC::GCType); |
| - |
| - // Conservatively checks whether an address is a pointer in any of the |
| - // thread heaps. If so marks the object pointed to as live. |
| - static Address checkAndMarkPointer(Visitor*, Address); |
| - |
| - static size_t objectPayloadSizeForTesting(); |
| - |
| - static void flushHeapDoesNotContainCache(); |
| - |
| - static FreePagePool* freePagePool() { return s_freePagePool; } |
| - static OrphanedPagePool* orphanedPagePool() { return s_orphanedPagePool; } |
| - |
| - // This look-up uses the region search tree and a negative contains cache to |
| - // provide an efficient mapping from arbitrary addresses to the containing |
| - // heap-page if one exists. |
| - static BasePage* lookup(Address); |
| - static void addPageMemoryRegion(PageMemoryRegion*); |
| - static void removePageMemoryRegion(PageMemoryRegion*); |
| - |
| static const GCInfo* gcInfo(size_t gcInfoIndex) |
| { |
| ASSERT(gcInfoIndex >= 1); |
| @@ -284,66 +341,59 @@ public: |
| return info; |
| } |
| - static void setMarkedObjectSizeAtLastCompleteSweep(size_t size) { releaseStore(&s_markedObjectSizeAtLastCompleteSweep, size); } |
| - static size_t markedObjectSizeAtLastCompleteSweep() { return acquireLoad(&s_markedObjectSizeAtLastCompleteSweep); } |
| - static void increaseAllocatedObjectSize(size_t delta) { atomicAdd(&s_allocatedObjectSize, static_cast<long>(delta)); } |
| - static void decreaseAllocatedObjectSize(size_t delta) { atomicSubtract(&s_allocatedObjectSize, static_cast<long>(delta)); } |
| - static size_t allocatedObjectSize() { return acquireLoad(&s_allocatedObjectSize); } |
| - static void increaseMarkedObjectSize(size_t delta) { atomicAdd(&s_markedObjectSize, static_cast<long>(delta)); } |
| - static size_t markedObjectSize() { return acquireLoad(&s_markedObjectSize); } |
| - static void increaseAllocatedSpace(size_t delta) { atomicAdd(&s_allocatedSpace, static_cast<long>(delta)); } |
| - static void decreaseAllocatedSpace(size_t delta) { atomicSubtract(&s_allocatedSpace, static_cast<long>(delta)); } |
| - static size_t allocatedSpace() { return acquireLoad(&s_allocatedSpace); } |
| - static size_t objectSizeAtLastGC() { return acquireLoad(&s_objectSizeAtLastGC); } |
| - static void increaseWrapperCount(size_t delta) { atomicAdd(&s_wrapperCount, static_cast<long>(delta)); } |
| - static void decreaseWrapperCount(size_t delta) { atomicSubtract(&s_wrapperCount, static_cast<long>(delta)); } |
| - static size_t wrapperCount() { return acquireLoad(&s_wrapperCount); } |
| - static size_t wrapperCountAtLastGC() { return acquireLoad(&s_wrapperCountAtLastGC); } |
| - static void increaseCollectedWrapperCount(size_t delta) { atomicAdd(&s_collectedWrapperCount, static_cast<long>(delta)); } |
| - static size_t collectedWrapperCount() { return acquireLoad(&s_collectedWrapperCount); } |
| - static size_t partitionAllocSizeAtLastGC() { return acquireLoad(&s_partitionAllocSizeAtLastGC); } |
| - |
| - static double estimatedMarkingTime(); |
| + static CrossThreadPersistentRegion& crossThreadPersistentRegion(); |
| + |
| + static const char* gcReasonString(BlinkGC::GCReason); |
| + |
| static void reportMemoryUsageHistogram(); |
| static void reportMemoryUsageForTracing(); |
| - static bool isLowEndDevice() { return s_isLowEndDevice; } |
| -#if ENABLE(ASSERT) |
| - static uint16_t gcGeneration() { return s_gcGeneration; } |
| -#endif |
| + static void increaseTotalAllocatedObjectSize(size_t delta) { atomicAdd(&s_totalAllocatedObjectSize, static_cast<long>(delta)); } |
| + static void decreaseTotalAllocatedObjectSize(size_t delta) { atomicSubtract(&s_totalAllocatedObjectSize, static_cast<long>(delta)); } |
| + static size_t totalAllocatedObjectSize() { return acquireLoad(&s_totalAllocatedObjectSize); } |
| + static void increaseTotalMarkedObjectSize(size_t delta) { atomicAdd(&s_totalMarkedObjectSize, static_cast<long>(delta)); } |
| + static size_t totalMarkedObjectSize() { return acquireLoad(&s_totalMarkedObjectSize); } |
| + static void increaseTotalAllocatedSpace(size_t delta) { atomicAdd(&s_totalAllocatedSpace, static_cast<long>(delta)); } |
| + static void decreaseTotalAllocatedSpace(size_t delta) { atomicSubtract(&s_totalAllocatedSpace, static_cast<long>(delta)); } |
| + static size_t totalAllocatedSpace() { return acquireLoad(&s_totalAllocatedSpace); } |
| -private: |
| - // Reset counters that track live and allocated-since-last-GC sizes. |
| - static void resetHeapCounters(); |
| + static bool isLowEndDevice() { return s_isLowEndDevice; } |
| - static int heapIndexForObjectSize(size_t); |
| - static bool isNormalHeapIndex(int); |
| + static void init(); |
| + // Shutdown tears down the global objects. If threads are still attached the actual shutdown task is delayed. |
| + static void shutdown(); |
| + // Run the shutdown task if necessary. |
| + static void doShutdownIfNecessary(); |
| - static void decommitCallbackStacks(); |
| + static HashSet<Heap*>& all(); |
| + static RecursiveMutex& heapAttachMutex(); |
| + |
| +private: |
| + static int arenaIndexForObjectSize(size_t); |
| + static bool isNormalArenaIndex(int); |
| + |
| + RecursiveMutex m_threadAttachMutex; |
| + ThreadStateSet m_threads; |
| + GCHeapStats m_stats; |
| + Mutex m_regionTreeMutex; |
| + RegionTree* m_regionTree; |
| + OwnPtr<HeapDoesNotContainCache> m_heapDoesNotContainCache; |
| + OwnPtr<SafePointBarrier> m_safePointBarrier; |
| + OwnPtr<FreePagePool> m_freePagePool; |
| + OwnPtr<OrphanedPagePool> m_orphanedPagePool; |
| + OwnPtr<CallbackStack> m_markingStack; |
| + OwnPtr<CallbackStack> m_postMarkingCallbackStack; |
| + OwnPtr<CallbackStack> m_globalWeakCallbackStack; |
| + OwnPtr<CallbackStack> m_ephemeronStack; |
| - static CallbackStack* s_markingStack; |
| - static CallbackStack* s_postMarkingCallbackStack; |
| - static CallbackStack* s_globalWeakCallbackStack; |
| - static CallbackStack* s_ephemeronStack; |
| - static HeapDoesNotContainCache* s_heapDoesNotContainCache; |
| static bool s_shutdownCalled; |
| - static FreePagePool* s_freePagePool; |
| - static OrphanedPagePool* s_orphanedPagePool; |
| - static RegionTree* s_regionTree; |
| - static size_t s_allocatedSpace; |
| - static size_t s_allocatedObjectSize; |
| - static size_t s_objectSizeAtLastGC; |
| - static size_t s_markedObjectSize; |
| - static size_t s_markedObjectSizeAtLastCompleteSweep; |
| - static size_t s_wrapperCount; |
| - static size_t s_wrapperCountAtLastGC; |
| - static size_t s_collectedWrapperCount; |
| - static size_t s_partitionAllocSizeAtLastGC; |
| - static double s_estimatedMarkingTimePerByte; |
| + static bool s_shutdownComplete; |
| static bool s_isLowEndDevice; |
| -#if ENABLE(ASSERT) |
| - static uint16_t s_gcGeneration; |
| -#endif |
| + |
| + // Stats for the entire Oilpan heap. |
| + static size_t s_totalAllocatedSpace; |
| + static size_t s_totalAllocatedObjectSize; |
| + static size_t s_totalMarkedObjectSize; |
|
haraken
2016/02/29 11:17:45
Shall we factor out these static variables to anot
|
| friend class ThreadState; |
| }; |
| @@ -427,21 +477,21 @@ protected: |
| // for a class. |
| // |
| -inline int Heap::heapIndexForObjectSize(size_t size) |
| +inline int Heap::arenaIndexForObjectSize(size_t size) |
| { |
| if (size < 64) { |
| if (size < 32) |
| - return BlinkGC::NormalPage1HeapIndex; |
| - return BlinkGC::NormalPage2HeapIndex; |
| + return BlinkGC::NormalPage1ArenaIndex; |
| + return BlinkGC::NormalPage2ArenaIndex; |
| } |
| if (size < 128) |
| - return BlinkGC::NormalPage3HeapIndex; |
| - return BlinkGC::NormalPage4HeapIndex; |
| + return BlinkGC::NormalPage3ArenaIndex; |
| + return BlinkGC::NormalPage4ArenaIndex; |
| } |
| -inline bool Heap::isNormalHeapIndex(int index) |
| +inline bool Heap::isNormalArenaIndex(int index) |
| { |
| - return index >= BlinkGC::NormalPage1HeapIndex && index <= BlinkGC::NormalPage4HeapIndex; |
| + return index >= BlinkGC::NormalPage1ArenaIndex && index <= BlinkGC::NormalPage4ArenaIndex; |
| } |
| #define DECLARE_EAGER_FINALIZATION_OPERATOR_NEW() \ |
| @@ -452,7 +502,7 @@ public: \ |
| return allocateObject(size, true); \ |
| } |
| -#define IS_EAGERLY_FINALIZED() (pageFromObject(this)->heap()->heapIndex() == BlinkGC::EagerSweepHeapIndex) |
| +#define IS_EAGERLY_FINALIZED() (pageFromObject(this)->arena()->arenaIndex() == BlinkGC::EagerSweepArenaIndex) |
| #if ENABLE(ASSERT) && ENABLE(OILPAN) |
| class VerifyEagerFinalization { |
| DISALLOW_NEW(); |
| @@ -485,11 +535,11 @@ public: \ |
| #define EAGERLY_FINALIZE_WILL_BE_REMOVED() |
| #endif |
| -inline Address Heap::allocateOnHeapIndex(ThreadState* state, size_t size, int heapIndex, size_t gcInfoIndex) |
| +inline Address Heap::allocateOnArenaIndex(ThreadState* state, size_t size, int arenaIndex, size_t gcInfoIndex) |
| { |
| ASSERT(state->isAllocationAllowed()); |
| - ASSERT(heapIndex != BlinkGC::LargeObjectHeapIndex); |
| - NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); |
| + ASSERT(arenaIndex != BlinkGC::LargeObjectArenaIndex); |
| + NormalPageArena* heap = static_cast<NormalPageArena*>(state->arena(arenaIndex)); |
| return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex); |
| } |
| @@ -497,7 +547,7 @@ template<typename T> |
| Address Heap::allocate(size_t size, bool eagerlySweep) |
| { |
| ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
| - Address address = Heap::allocateOnHeapIndex(state, size, eagerlySweep ? BlinkGC::EagerSweepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::index()); |
| + Address address = Heap::allocateOnArenaIndex(state, size, eagerlySweep ? BlinkGC::EagerSweepArenaIndex : Heap::arenaIndexForObjectSize(size), GCInfoTrait<T>::index()); |
| const char* typeName = WTF_HEAP_PROFILER_TYPE_NAME(T); |
| HeapAllocHooks::allocationHookIfEnabled(address, size, typeName); |
| return address; |
| @@ -519,16 +569,16 @@ Address Heap::reallocate(void* previous, size_t size) |
| HeapObjectHeader* previousHeader = HeapObjectHeader::fromPayload(previous); |
| BasePage* page = pageFromObject(previousHeader); |
| ASSERT(page); |
| - int heapIndex = page->heap()->heapIndex(); |
| + int arenaIndex = page->arena()->arenaIndex(); |
| // Recompute the effective heap index if previous allocation |
| // was on the normal heaps or a large object. |
| - if (isNormalHeapIndex(heapIndex) || heapIndex == BlinkGC::LargeObjectHeapIndex) |
| - heapIndex = heapIndexForObjectSize(size); |
| + if (isNormalArenaIndex(arenaIndex) || arenaIndex == BlinkGC::LargeObjectArenaIndex) |
| + arenaIndex = arenaIndexForObjectSize(size); |
| // TODO(haraken): We don't support reallocate() for finalizable objects. |
| ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); |
| ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); |
| - Address address = Heap::allocateOnHeapIndex(state, size, heapIndex, GCInfoTrait<T>::index()); |
| + Address address = Heap::allocateOnArenaIndex(state, size, arenaIndex, GCInfoTrait<T>::index()); |
| size_t copySize = previousHeader->payloadSize(); |
| if (copySize > size) |
| copySize = size; |