Title: [91039] trunk/Source/_javascript_Core
Revision
91039
Author
[email protected]
Date
2011-07-14 18:40:25 -0700 (Thu, 14 Jul 2011)

Log Message

GC allocation fast path has too many operations.
https://bugs.webkit.org/show_bug.cgi?id=64493

Patch by Filip Pizlo <[email protected]> on 2011-07-14
Reviewed by Darin Adler.

Changed the timing of the lazy sweep so that it occurs when we land on
a previously-unsweeped block, rather than whenever we land on an unsweeped
cell.  After the per-block lazy sweep occurs, the block is turned into a
singly linked list of free cells.  The allocation fast path is now just a
load-branch-store to remove a cell from the head of the list.

Additionally, this changes the way new blocks are allocated.  Previously,
they would be populated with dummy cells.  With this patch, they are
turned into a free list, which means that there will never be destructor
calls for allocations in fresh blocks.

These changes result in a 1.9% speed-up on V8, and a 0.6% speed-up on
SunSpider.  There are no observed statistically significant slow-downs
on any individual benchmark.

* _javascript_Core.exp:
* heap/Heap.cpp:
(JSC::Heap::allocateSlowCase):
(JSC::Heap::collect):
(JSC::Heap::canonicalizeBlocks):
(JSC::Heap::resetAllocator):
* heap/Heap.h:
(JSC::Heap::forEachProtectedCell):
(JSC::Heap::forEachCell):
(JSC::Heap::forEachBlock):
(JSC::Heap::allocate):
* heap/MarkedBlock.cpp:
(JSC::MarkedBlock::MarkedBlock):
(JSC::MarkedBlock::lazySweep):
(JSC::MarkedBlock::blessNewBlockForFastPath):
(JSC::MarkedBlock::blessNewBlockForSlowPath):
(JSC::MarkedBlock::canonicalizeBlock):
* heap/MarkedBlock.h:
* heap/NewSpace.cpp:
(JSC::NewSpace::addBlock):
(JSC::NewSpace::canonicalizeBlocks):
* heap/NewSpace.h:
(JSC::NewSpace::allocate):
(JSC::NewSpace::SizeClass::SizeClass):
(JSC::NewSpace::SizeClass::canonicalizeBlock):
* heap/OldSpace.cpp:
(JSC::OldSpace::addBlock):

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (91038 => 91039)


--- trunk/Source/_javascript_Core/ChangeLog	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-07-15 01:40:25 UTC (rev 91039)
@@ -1,5 +1,55 @@
 2011-07-14  Filip Pizlo  <[email protected]>
 
+        GC allocation fast path has too many operations.
+        https://bugs.webkit.org/show_bug.cgi?id=64493
+
+        Reviewed by Darin Adler.
+        
+        Changed the timing of the lazy sweep so that it occurs when we land on
+        a previously-unsweeped block, rather than whenever we land on an unsweeped
+        cell.  After the per-block lazy sweep occurs, the block is turned into a
+        singly linked list of free cells.  The allocation fast path is now just a
+        load-branch-store to remove a cell from the head of the list.
+        
+        Additionally, this changes the way new blocks are allocated.  Previously,
+        they would be populated with dummy cells.  With this patch, they are
+        turned into a free list, which means that there will never be destructor
+        calls for allocations in fresh blocks.
+        
+        These changes result in a 1.9% speed-up on V8, and a 0.6% speed-up on
+        SunSpider.  There are no observed statistically significant slow-downs
+        on any individual benchmark.
+
+        * _javascript_Core.exp:
+        * heap/Heap.cpp:
+        (JSC::Heap::allocateSlowCase):
+        (JSC::Heap::collect):
+        (JSC::Heap::canonicalizeBlocks):
+        (JSC::Heap::resetAllocator):
+        * heap/Heap.h:
+        (JSC::Heap::forEachProtectedCell):
+        (JSC::Heap::forEachCell):
+        (JSC::Heap::forEachBlock):
+        (JSC::Heap::allocate):
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::MarkedBlock):
+        (JSC::MarkedBlock::lazySweep):
+        (JSC::MarkedBlock::blessNewBlockForFastPath):
+        (JSC::MarkedBlock::blessNewBlockForSlowPath):
+        (JSC::MarkedBlock::canonicalizeBlock):
+        * heap/MarkedBlock.h:
+        * heap/NewSpace.cpp:
+        (JSC::NewSpace::addBlock):
+        (JSC::NewSpace::canonicalizeBlocks):
+        * heap/NewSpace.h:
+        (JSC::NewSpace::allocate):
+        (JSC::NewSpace::SizeClass::SizeClass):
+        (JSC::NewSpace::SizeClass::canonicalizeBlock):
+        * heap/OldSpace.cpp:
+        (JSC::OldSpace::addBlock):
+
+2011-07-14  Filip Pizlo  <[email protected]>
+
         DFG JIT crashes on host constructor calls in debug mode.
         https://bugs.webkit.org/show_bug.cgi?id=64562
         

Modified: trunk/Source/_javascript_Core/_javascript_Core.exp (91038 => 91039)


--- trunk/Source/_javascript_Core/_javascript_Core.exp	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/_javascript_Core.exp	2011-07-15 01:40:25 UTC (rev 91039)
@@ -224,6 +224,7 @@
 __ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
 __ZN3JSC4Heap11objectCountEv
 __ZN3JSC4Heap16activityCallbackEv
+__ZN3JSC4Heap16allocateSlowCaseERNS_8NewSpace9SizeClassE
 __ZN3JSC4Heap16objectTypeCountsEv
 __ZN3JSC4Heap17collectAllGarbageEv
 __ZN3JSC4Heap17globalObjectCountEv
@@ -237,7 +238,6 @@
 __ZN3JSC4Heap4sizeEv
 __ZN3JSC4Heap7destroyEv
 __ZN3JSC4Heap7protectENS_7JSValueE
-__ZN3JSC4Heap8allocateERNS_8NewSpace9SizeClassE
 __ZN3JSC4Heap8capacityEv
 __ZN3JSC4Heap9unprotectENS_7JSValueE
 __ZN3JSC4Yarr11YarrPatternC1ERKNS_7UStringEbbPPKc

Modified: trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def (91038 => 91039)


--- trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/_javascript_Core.vcproj/_javascript_Core/_javascript_Core.def	2011-07-15 01:40:25 UTC (rev 91039)
@@ -56,8 +56,8 @@
     ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
     ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
     ?allocate@Heap@JSC@@QAEPAXAAUSizeClass@NewSpace@2@@Z
-    ?allocate@Heap@JSC@@QAEPAXI@Z
     ?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z
+    ?allocateSlowCase@Heap@JSC@@AAEPAXAAUSizeClass@NewSpace@2@@Z
     ?append@StringBuilder@WTF@@QAEXPBDI@Z
     ?append@StringBuilder@WTF@@QAEXPB_WI@Z
     ?ascii@UString@JSC@@QBE?AVCString@WTF@@XZ

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (91038 => 91039)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2011-07-15 01:40:25 UTC (rev 91039)
@@ -102,15 +102,6 @@
     block->clearMarks();
 }
 
-struct ResetAllocator : MarkedBlock::VoidFunctor {
-    void operator()(MarkedBlock*);
-};
-
-inline void ResetAllocator::operator()(MarkedBlock* block)
-{
-    block->resetAllocator();
-}
-
 struct Sweep : MarkedBlock::VoidFunctor {
     void operator()(MarkedBlock*);
 };
@@ -320,7 +311,7 @@
     return result;
 }
 
-void* Heap::allocate(NewSpace::SizeClass& sizeClass)
+void* Heap::allocateSlowCase(NewSpace::SizeClass& sizeClass)
 {
 #if COLLECT_ON_EVERY_ALLOCATION
     collectAllGarbage();
@@ -558,7 +549,9 @@
     ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
     ASSERT(m_isSafeToCollect);
     _javascript_CORE_GC_BEGIN();
-
+    
+    canonicalizeBlocks();
+    
     markRoots();
     m_handleHeap.finalizeWeakHandles();
     m_globalData->smallStrings.finalizeSmallStrings();
@@ -588,11 +581,15 @@
     (*m_activityCallback)();
 }
 
+void Heap::canonicalizeBlocks()
+{
+    m_newSpace.canonicalizeBlocks();
+}
+
 void Heap::resetAllocator()
 {
     m_extraCost = 0;
     m_newSpace.resetAllocator();
-    forEachBlock<ResetAllocator>();
 }
 
 void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)

Modified: trunk/Source/_javascript_Core/heap/Heap.h (91038 => 91039)


--- trunk/Source/_javascript_Core/heap/Heap.h	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2011-07-15 01:40:25 UTC (rev 91039)
@@ -24,9 +24,10 @@
 
 #include "HandleHeap.h"
 #include "HandleStack.h"
-#include "SlotVisitor.h"
+#include "MarkedBlock.h"
 #include "MarkedBlockSet.h"
 #include "NewSpace.h"
+#include "SlotVisitor.h"
 #include <wtf/Forward.h>
 #include <wtf/HashCountedSet.h>
 #include <wtf/HashSet.h>
@@ -124,8 +125,8 @@
         static const size_t maxExtraCost = 1024 * 1024;
 
         bool isValidAllocation(size_t);
-        void* allocateSlowCase(size_t);
         void reportExtraMemoryCostSlowCase(size_t);
+        void canonicalizeBlocks();
         void resetAllocator();
 
         MarkedBlock* allocateBlock(size_t cellSize);
@@ -137,6 +138,7 @@
         void markTempSortVectors(HeapRootVisitor&);
 
         void* tryAllocate(NewSpace::SizeClass&);
+        void* allocateSlowCase(NewSpace::SizeClass&);
         
         enum SweepToggle { DoNotSweep, DoSweep };
         void collect(SweepToggle);
@@ -242,6 +244,7 @@
 
     template<typename Functor> inline typename Functor::ReturnType Heap::forEachProtectedCell(Functor& functor)
     {
+        canonicalizeBlocks();
         ProtectCountSet::iterator end = m_protectedValues.end();
         for (ProtectCountSet::iterator it = m_protectedValues.begin(); it != end; ++it)
             functor(it->first);
@@ -258,6 +261,7 @@
 
     template<typename Functor> inline typename Functor::ReturnType Heap::forEachCell(Functor& functor)
     {
+        canonicalizeBlocks();
         BlockIterator end = m_blocks.set().end();
         for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
             (*it)->forEachCell(functor);
@@ -272,6 +276,7 @@
 
     template<typename Functor> inline typename Functor::ReturnType Heap::forEachBlock(Functor& functor)
     {
+        canonicalizeBlocks();
         BlockIterator end = m_blocks.set().end();
         for (BlockIterator it = m_blocks.set().begin(); it != end; ++it)
             functor(*it);
@@ -283,6 +288,17 @@
         Functor functor;
         return forEachBlock(functor);
     }
+    
+    inline void* Heap::allocate(NewSpace::SizeClass& sizeClass)
+    {
+        // This is a light-weight fast path to cover the most common case.
+        MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell;
+        if (UNLIKELY(!firstFreeCell))
+            return allocateSlowCase(sizeClass);
+        
+        sizeClass.firstFreeCell = firstFreeCell->next;
+        return firstFreeCell;
+    }
 
     inline void* Heap::allocate(size_t bytes)
     {

Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.cpp (91038 => 91039)


--- trunk/Source/_javascript_Core/heap/MarkedBlock.cpp	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.cpp	2011-07-15 01:40:25 UTC (rev 91039)
@@ -49,17 +49,12 @@
 }
 
 MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize)
-    : m_nextAtom(firstAtom())
-    , m_inNewSpace(false)
+    : m_inNewSpace(false)
     , m_allocation(allocation)
     , m_heap(heap)
 {
     m_atomsPerCell = (cellSize + atomSize - 1) / atomSize;
     m_endAtom = atomsPerBlock - m_atomsPerCell + 1;
-
-    Structure* dummyMarkableCellStructure = heap->globalData()->dummyMarkableCellStructure.get();
-    for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell)
-        new (&atoms()[i]) JSCell(*heap->globalData(), dummyMarkableCellStructure, JSCell::CreatingEarlyCell);
 }
 
 void MarkedBlock::sweep()
@@ -85,6 +80,64 @@
     }
 }
 
+MarkedBlock::FreeCell* MarkedBlock::lazySweep()
+{
+    // This returns a free list that is ordered in reverse through the block.
+    // This is fine, since the allocation code makes no assumptions about the
+    // order of the free list.
+    
+    FreeCell* result = 0;
+    
+    for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
+        if (!m_marks.testAndSet(i)) {
+            JSCell* cell = reinterpret_cast<JSCell*>(&atoms()[i]);
+            cell->~JSCell();
+            FreeCell* freeCell = reinterpret_cast<FreeCell*>(cell);
+            freeCell->next = result;
+            result = freeCell;
+        }
+    }
+    
+    return result;
+}
+
+MarkedBlock::FreeCell* MarkedBlock::blessNewBlockForFastPath()
+{
+    // This returns a free list that is ordered in reverse through the block,
+    // as in lazySweep() above.
+    
+    FreeCell* result = 0;
+    for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell) {
+        m_marks.set(i);
+        FreeCell* freeCell = reinterpret_cast<FreeCell*>(&atoms()[i]);
+        freeCell->next = result;
+        result = freeCell;
+    }
+    return result;
+}
+
+void MarkedBlock::blessNewBlockForSlowPath()
+{
+    Structure* dummyMarkableCellStructure = m_heap->globalData()->dummyMarkableCellStructure.get();
+    for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell)
+        new (&atoms()[i]) JSCell(*m_heap->globalData(), dummyMarkableCellStructure, JSCell::CreatingEarlyCell);
+}
+
+void MarkedBlock::canonicalizeBlock(FreeCell* firstFreeCell)
+{
+    Structure* dummyMarkableCellStructure = m_heap->globalData()->dummyMarkableCellStructure.get();
+    
+    for (FreeCell* current = firstFreeCell; current;) {
+        FreeCell* next = current->next;
+        size_t i = atomNumber(current);
+        
+        m_marks.clear(i);
+        new (static_cast<void*>(current)) JSCell(*m_heap->globalData(), dummyMarkableCellStructure, JSCell::CreatingEarlyCell);
+
+        current = next;
+    }
+}
+
 #if ENABLE(JSC_ZOMBIES)
 void MarkedBlock::clearMarks()
 {

Modified: trunk/Source/_javascript_Core/heap/MarkedBlock.h (91038 => 91039)


--- trunk/Source/_javascript_Core/heap/MarkedBlock.h	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/heap/MarkedBlock.h	2011-07-15 01:40:25 UTC (rev 91039)
@@ -48,6 +48,10 @@
         static const size_t atomsPerBlock = blockSize / atomSize; // ~1.5% overhead
         static const size_t ownerSetsPerBlock = 8; // ~2% overhead.
 
+        struct FreeCell {
+            FreeCell* next;
+        };
+        
         struct VoidFunctor {
             typedef void ReturnType;
             void returnValue() { }
@@ -84,9 +88,22 @@
         void setInNewSpace(bool);
 
         void* allocate();
-        void resetAllocator();
         void sweep();
         
+        // This invokes destructors on all cells that are not marked, marks
+        // them, and returns a linked list of those cells.
+        FreeCell* lazySweep();
+        
+        // These should be called immediately after a block is created.
+        // Blessing for fast path creates a linked list, while blessing for
+        // slow path creates dummy cells.
+        FreeCell* blessNewBlockForFastPath();
+        void blessNewBlockForSlowPath();
+        
+        // This unmarks all cells on the free list, and allocates dummy JSCells
+        // in their place.
+        void canonicalizeBlock(FreeCell* firstFreeCell);
+        
         bool isEmpty();
 
         void clearMarks();
@@ -118,7 +135,6 @@
         size_t atomNumber(const void*);
         size_t ownerSetNumber(const JSCell*);
 
-        size_t m_nextAtom;
         size_t m_endAtom; // This is a fuzzy end. Always test for < m_endAtom.
         size_t m_atomsPerCell;
         WTF::Bitmap<blockSize / atomSize> m_marks;
@@ -165,11 +181,6 @@
         m_inNewSpace = inNewSpace;
     }
 
-    inline void MarkedBlock::resetAllocator()
-    {
-        m_nextAtom = firstAtom();
-    }
-
     inline bool MarkedBlock::isEmpty()
     {
         return m_marks.isEmpty();
@@ -235,22 +246,7 @@
             functor(reinterpret_cast<JSCell*>(&atoms()[i]));
         }
     }
-
-    inline void* MarkedBlock::allocate()
-    {
-        while (m_nextAtom < m_endAtom) {
-            if (!m_marks.testAndSet(m_nextAtom)) {
-                JSCell* cell = reinterpret_cast<JSCell*>(&atoms()[m_nextAtom]);
-                m_nextAtom += m_atomsPerCell;
-                destructor(cell);
-                return cell;
-            }
-            m_nextAtom += m_atomsPerCell;
-        }
-
-        return 0;
-    }
-
+    
     inline size_t MarkedBlock::ownerSetNumber(const JSCell* cell)
     {
         return (reinterpret_cast<Bits>(cell) - reinterpret_cast<Bits>(this)) * ownerSetsPerBlock / blockSize;

Modified: trunk/Source/_javascript_Core/heap/MarkedBlockSet.h (91038 => 91039)


--- trunk/Source/_javascript_Core/heap/MarkedBlockSet.h	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/heap/MarkedBlockSet.h	2011-07-15 01:40:25 UTC (rev 91039)
@@ -28,6 +28,7 @@
 
 #include "MarkedBlock.h"
 #include "TinyBloomFilter.h"
+#include <wtf/HashSet.h>
 
 namespace JSC {
 

Modified: trunk/Source/_javascript_Core/heap/NewSpace.cpp (91038 => 91039)


--- trunk/Source/_javascript_Core/heap/NewSpace.cpp	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/heap/NewSpace.cpp	2011-07-15 01:40:25 UTC (rev 91039)
@@ -48,6 +48,10 @@
     block->setInNewSpace(true);
     sizeClass.nextBlock = block;
     sizeClass.blockList.append(block);
+    ASSERT(!sizeClass.currentBlock);
+    ASSERT(!sizeClass.firstFreeCell);
+    sizeClass.currentBlock = block;
+    sizeClass.firstFreeCell = block->blessNewBlockForFastPath();
 }
 
 void NewSpace::removeBlock(MarkedBlock* block)
@@ -69,4 +73,13 @@
         sizeClassFor(cellSize).resetAllocator();
 }
 
+void NewSpace::canonicalizeBlocks()
+{
+    for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
+        sizeClassFor(cellSize).canonicalizeBlock();
+
+    for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
+        sizeClassFor(cellSize).canonicalizeBlock();
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/NewSpace.h (91038 => 91039)


--- trunk/Source/_javascript_Core/heap/NewSpace.h	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/heap/NewSpace.h	2011-07-15 01:40:25 UTC (rev 91039)
@@ -50,7 +50,10 @@
         struct SizeClass {
             SizeClass();
             void resetAllocator();
+            void canonicalizeBlock();
 
+            MarkedBlock::FreeCell* firstFreeCell;
+            MarkedBlock* currentBlock;
             MarkedBlock* nextBlock;
             DoublyLinkedList<MarkedBlock> blockList;
             size_t cellSize;
@@ -64,6 +67,8 @@
 
         void addBlock(SizeClass&, MarkedBlock*);
         void removeBlock(MarkedBlock*);
+        
+        void canonicalizeBlocks();
 
         size_t waterMark();
         size_t highWaterMark();
@@ -115,14 +120,43 @@
 
     inline void* NewSpace::allocate(SizeClass& sizeClass)
     {
-        for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
-            if (void* result = block->allocate())
-                return result;
-
-            m_waterMark += block->capacity();
+        MarkedBlock::FreeCell* firstFreeCell = sizeClass.firstFreeCell;
+        if (!firstFreeCell) {
+            // There are two possibilities for why we got here:
+            // 1) We've exhausted the allocation cache for currentBlock, in which case
+            //    currentBlock == nextBlock, and we know that there is no reason to
+            //    repeat a lazy sweep of nextBlock because we won't find anything.
+            // 2) Allocation caches have been cleared, in which case nextBlock may
+            //    have (and most likely does have) free cells, so we almost certainly
+            //    should do a lazySweep for nextBlock. This also implies that
+            //    currentBlock == 0.
+            
+            if (sizeClass.currentBlock) {
+                ASSERT(sizeClass.currentBlock == sizeClass.nextBlock);
+                m_waterMark += sizeClass.nextBlock->capacity();
+                sizeClass.nextBlock = sizeClass.nextBlock->next();
+                sizeClass.currentBlock = 0;
+            }
+            
+            for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
+                firstFreeCell = block->lazySweep();
+                if (firstFreeCell) {
+                    sizeClass.firstFreeCell = firstFreeCell;
+                    sizeClass.currentBlock = block;
+                    break;
+                }
+                
+                m_waterMark += block->capacity();
+            }
+            
+            if (!firstFreeCell)
+                return 0;
         }
-
-        return 0;
+        
+        ASSERT(firstFreeCell);
+        
+        sizeClass.firstFreeCell = firstFreeCell->next;
+        return firstFreeCell;
     }
 
     template <typename Functor> inline typename Functor::ReturnType NewSpace::forEachBlock(Functor& functor)
@@ -155,7 +189,9 @@
     }
 
     inline NewSpace::SizeClass::SizeClass()
-        : nextBlock(0)
+        : firstFreeCell(0)
+        , currentBlock(0)
+        , nextBlock(0)
         , cellSize(0)
     {
     }
@@ -164,6 +200,19 @@
     {
         nextBlock = blockList.head();
     }
+    
+    inline void NewSpace::SizeClass::canonicalizeBlock()
+    {
+        if (currentBlock) {
+            currentBlock->canonicalizeBlock(firstFreeCell);
+            firstFreeCell = 0;
+        }
+        
+        ASSERT(!firstFreeCell);
+        
+        currentBlock = 0;
+        firstFreeCell = 0;
+    }
 
 } // namespace JSC
 

Modified: trunk/Source/_javascript_Core/heap/OldSpace.cpp (91038 => 91039)


--- trunk/Source/_javascript_Core/heap/OldSpace.cpp	2011-07-15 01:28:54 UTC (rev 91038)
+++ trunk/Source/_javascript_Core/heap/OldSpace.cpp	2011-07-15 01:40:25 UTC (rev 91039)
@@ -36,6 +36,7 @@
 void OldSpace::addBlock(MarkedBlock* block)
 {
     m_blocks.append(block);
+    block->blessNewBlockForSlowPath();
 }
 
 void OldSpace::removeBlock(MarkedBlock* block)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to