Title: [88389] trunk/Source/_javascript_Core
Revision
88389
Author
gga...@apple.com
Date
2011-06-08 14:39:27 -0700 (Wed, 08 Jun 2011)

Log Message

2011-06-08  Geoffrey Garen  <gga...@apple.com>

        Reviewed by Oliver Hunt.

        Took some responsibilities away from NewSpace
        https://bugs.webkit.org/show_bug.cgi?id=62325
        
        NewSpace is basically just an allocator now.
        
        Heap acts as a controller, responsible for managing the set of all
        MarkedBlocks.
        
        This is in preparation for moving parts of the controller logic into
        separate helper classes that can act on arbitrary sets of MarkedBlocks
        that may or may not be in NewSpace.

        * heap/Heap.cpp:
        (JSC::Heap::Heap):
        (JSC::Heap::destroy):
        (JSC::Heap::allocate):
        (JSC::Heap::markRoots):
        (JSC::Heap::clearMarks):
        (JSC::Heap::sweep):
        (JSC::Heap::objectCount):
        (JSC::Heap::size):
        (JSC::Heap::capacity):
        (JSC::Heap::collect):
        (JSC::Heap::resetAllocator):
        (JSC::Heap::allocateBlock):
        (JSC::Heap::freeBlocks):
        (JSC::Heap::shrink): Moved the set of MarkedBlocks from NewSpace to Heap,
        along with all functions that operate on the set of MarkedBlocks. Also
        moved responsibility for deciding whether to allocate a new MarkedBlock,
        and for allocating it.

        * heap/Heap.h:
        (JSC::Heap::contains):
        (JSC::Heap::forEach): Ditto.

        * heap/NewSpace.cpp:
        (JSC::NewSpace::addBlock):
        (JSC::NewSpace::removeBlock):
        (JSC::NewSpace::resetAllocator):
        * heap/NewSpace.h:
        (JSC::NewSpace::waterMark):
        (JSC::NewSpace::allocate): Ditto.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (88388 => 88389)


--- trunk/Source/_javascript_Core/ChangeLog	2011-06-08 21:38:24 UTC (rev 88388)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-06-08 21:39:27 UTC (rev 88389)
@@ -2,6 +2,53 @@
 
         Reviewed by Oliver Hunt.
 
+        Took some responsibilities away from NewSpace
+        https://bugs.webkit.org/show_bug.cgi?id=62325
+        
+        NewSpace is basically just an allocator now.
+        
+        Heap acts as a controller, responsible for managing the set of all
+        MarkedBlocks.
+        
+        This is in preparation for moving parts of the controller logic into
+        separate helper classes that can act on arbitrary sets of MarkedBlocks
+        that may or may not be in NewSpace.
+
+        * heap/Heap.cpp:
+        (JSC::Heap::Heap):
+        (JSC::Heap::destroy):
+        (JSC::Heap::allocate):
+        (JSC::Heap::markRoots):
+        (JSC::Heap::clearMarks):
+        (JSC::Heap::sweep):
+        (JSC::Heap::objectCount):
+        (JSC::Heap::size):
+        (JSC::Heap::capacity):
+        (JSC::Heap::collect):
+        (JSC::Heap::resetAllocator):
+        (JSC::Heap::allocateBlock):
+        (JSC::Heap::freeBlocks):
+        (JSC::Heap::shrink): Moved the set of MarkedBlocks from NewSpace to Heap,
+        along with all functions that operate on the set of MarkedBlocks. Also
+        moved responsibility for deciding whether to allocate a new MarkedBlock,
+        and for allocating it.
+
+        * heap/Heap.h:
+        (JSC::Heap::contains):
+        (JSC::Heap::forEach): Ditto.
+
+        * heap/NewSpace.cpp:
+        (JSC::NewSpace::addBlock):
+        (JSC::NewSpace::removeBlock):
+        (JSC::NewSpace::resetAllocator):
+        * heap/NewSpace.h:
+        (JSC::NewSpace::waterMark):
+        (JSC::NewSpace::allocate): Ditto.
+
+2011-06-08  Geoffrey Garen  <gga...@apple.com>
+
+        Reviewed by Oliver Hunt.
+
         Some more MarkedSpace => NewSpace renaming
         https://bugs.webkit.org/show_bug.cgi?id=62305
 

Modified: trunk/Source/_javascript_Core/heap/Heap.cpp (88388 => 88389)


--- trunk/Source/_javascript_Core/heap/Heap.cpp	2011-06-08 21:38:24 UTC (rev 88388)
+++ trunk/Source/_javascript_Core/heap/Heap.cpp	2011-06-08 21:39:27 UTC (rev 88389)
@@ -66,13 +66,13 @@
 Heap::Heap(JSGlobalData* globalData)
     : m_operationInProgress(NoOperation)
     , m_newSpace(this)
+    , m_extraCost(0)
     , m_markListSet(0)
     , m_activityCallback(DefaultGCActivityCallback::create(this))
-    , m_globalData(globalData)
     , m_machineThreads(this)
     , m_markStack(globalData->jsArrayVPtr)
     , m_handleHeap(globalData)
-    , m_extraCost(0)
+    , m_globalData(globalData)
 {
     m_newSpace.setHighWaterMark(minBytesPerCycle);
     (*m_activityCallback)();
@@ -104,11 +104,16 @@
 
     delete m_markListSet;
     m_markListSet = 0;
-    m_newSpace.clearMarks();
+
+    clearMarks();
     m_handleHeap.finalizeWeakHandles();
     m_globalData->smallStrings.finalizeSmallStrings();
-    m_newSpace.destroy();
 
+#if !ENABLE(JSC_ZOMBIES)
+    shrink();
+    ASSERT(!size());
+#endif
+
     m_globalData = 0;
 }
 
@@ -137,18 +142,20 @@
     ASSERT(m_operationInProgress == NoOperation);
 #endif
 
+    m_operationInProgress = Allocation;
     void* result = m_newSpace.allocate(sizeClass);
+    m_operationInProgress = NoOperation;
+
     if (result)
         return result;
 
+    if (m_newSpace.waterMark() < m_newSpace.highWaterMark()) {
+        m_newSpace.addBlock(sizeClass, allocateBlock(sizeClass.cellSize));
+        return allocate(sizeClass);
+    }
+
     collect(DoNotSweep);
-
-    m_operationInProgress = Allocation;
-    result = m_newSpace.allocate(sizeClass);
-    m_operationInProgress = NoOperation;
-
-    ASSERT(result);
-    return result;
+    return allocate(sizeClass);
 }
 
 void Heap::protect(JSValue k)
@@ -232,7 +239,7 @@
     ConservativeRoots registerFileRoots(this);
     registerFile().gatherConservativeRoots(registerFileRoots);
 
-    m_newSpace.clearMarks();
+    clearMarks();
 
     visitor.append(machineThreadRoots);
     visitor.drain();
@@ -273,19 +280,45 @@
     m_operationInProgress = NoOperation;
 }
 
+void Heap::clearMarks()
+{
+    BlockIterator end = m_blocks.end();
+    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+        (*it)->clearMarks();
+}
+
+void Heap::sweep()
+{
+    BlockIterator end = m_blocks.end();
+    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+        (*it)->sweep();
+}
+
 size_t Heap::objectCount() const
 {
-    return m_newSpace.objectCount();
+    size_t result = 0;
+    BlockIterator end = m_blocks.end();
+    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+        result += (*it)->markCount();
+    return result;
 }
 
 size_t Heap::size() const
 {
-    return m_newSpace.size();
+    size_t result = 0;
+    BlockIterator end = m_blocks.end();
+    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+        result += (*it)->size();
+    return result;
 }
 
 size_t Heap::capacity() const
 {
-    return m_newSpace.capacity();
+    size_t result = 0;
+    BlockIterator end = m_blocks.end();
+    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+        result += (*it)->capacity();
+    return result;
 }
 
 size_t Heap::globalObjectCount()
@@ -404,24 +437,23 @@
     m_globalData->smallStrings.finalizeSmallStrings();
 
     _javascript_CORE_GC_MARKED();
+    
+    resetAllocator();
 
-    m_newSpace.resetAllocator();
-    m_extraCost = 0;
-
 #if ENABLE(JSC_ZOMBIES)
     sweepToggle = DoSweep;
 #endif
 
     if (sweepToggle == DoSweep) {
-        m_newSpace.sweep();
-        m_newSpace.shrink();
+        sweep();
+        shrink();
     }
 
     // To avoid pathological GC churn in large heaps, we set the allocation high
     // water mark to be proportional to the current size of the heap. The exact
     // proportion is a bit arbitrary. A 2X multiplier gives a 1:1 (heap size :
     // new bytes allocated) proportion, and seems to work well in benchmarks.
-    size_t proportionalBytes = 2 * m_newSpace.size();
+    size_t proportionalBytes = 2 * size();
     m_newSpace.setHighWaterMark(max(proportionalBytes, minBytesPerCycle));
 
     _javascript_CORE_GC_END();
@@ -429,6 +461,17 @@
     (*m_activityCallback)();
 }
 
+void Heap::resetAllocator()
+{
+    m_newSpace.resetAllocator();
+
+    BlockIterator end = m_blocks.end();
+    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+        (*it)->resetAllocator();
+
+    m_extraCost = 0;
+}
+
 void Heap::setActivityCallback(PassOwnPtr<GCActivityCallback> activityCallback)
 {
     m_activityCallback = activityCallback;
@@ -453,4 +496,41 @@
     return true;
 }
 
+MarkedBlock* Heap::allocateBlock(size_t cellSize)
+{
+    MarkedBlock* block = MarkedBlock::create(this, cellSize);
+    m_blocks.add(block);
+
+    return block;
+}
+
+void Heap::freeBlocks(DoublyLinkedList<MarkedBlock>& blocks)
+{
+    MarkedBlock* next;
+    for (MarkedBlock* block = blocks.head(); block; block = next) {
+        next = block->next();
+
+        m_blocks.remove(block);
+        MarkedBlock::destroy(block);
+    }
+}
+
+void Heap::shrink()
+{
+    // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
+    DoublyLinkedList<MarkedBlock> empties;
+
+    BlockIterator end = m_blocks.end();
+    for (BlockIterator it = m_blocks.begin(); it != end; ++it) {
+        MarkedBlock* block = *it;
+        if (!block->isEmpty())
+            continue;
+
+        m_newSpace.removeBlock(block);
+        empties.append(block);
+    }
+    
+    freeBlocks(empties);
+}
+
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/Heap.h (88388 => 88389)


--- trunk/Source/_javascript_Core/heap/Heap.h	2011-06-08 21:38:24 UTC (rev 88388)
+++ trunk/Source/_javascript_Core/heap/Heap.h	2011-06-08 21:39:27 UTC (rev 88389)
@@ -89,7 +89,7 @@
         void protect(JSValue);
         bool unprotect(JSValue); // True when the protect count drops to 0.
 
-        bool contains(void*);
+        bool contains(const void*);
 
         size_t size() const;
         size_t capacity() const;
@@ -113,40 +113,49 @@
         HandleStack* handleStack() { return &m_handleStack; }
 
     private:
+        typedef HashSet<MarkedBlock*>::iterator BlockIterator;
+
         static const size_t minExtraCost = 256;
         static const size_t maxExtraCost = 1024 * 1024;
 
         bool isValidAllocation(size_t);
         void* allocateSlowCase(size_t);
         void reportExtraMemoryCostSlowCase(size_t);
+        void resetAllocator();
 
+        MarkedBlock* allocateBlock(size_t cellSize);
+        void freeBlocks(DoublyLinkedList<MarkedBlock>&);
+
+        void clearMarks();
         void markRoots();
         void markProtectedObjects(HeapRootVisitor&);
         void markTempSortVectors(HeapRootVisitor&);
 
         enum SweepToggle { DoNotSweep, DoSweep };
         void collect(SweepToggle);
+        void shrink();
+        void sweep();
 
         RegisterFile& registerFile();
 
         OperationInProgress m_operationInProgress;
         NewSpace m_newSpace;
+        HashSet<MarkedBlock*> m_blocks;
 
+        size_t m_extraCost;
+
         ProtectCountSet m_protectedValues;
         Vector<Vector<ValueStringPair>* > m_tempSortingVectors;
-
         HashSet<MarkedArgumentBuffer*>* m_markListSet;
 
         OwnPtr<GCActivityCallback> m_activityCallback;
-
-        JSGlobalData* m_globalData;
         
         MachineThreads m_machineThreads;
         MarkStack m_markStack;
         HandleHeap m_handleHeap;
         HandleStack m_handleStack;
 
-        size_t m_extraCost;
+        JSGlobalData* m_globalData;
     };
 
     bool Heap::isBusy()
@@ -194,9 +203,16 @@
     {
     }
 
-    inline bool Heap::contains(void* p)
+    inline bool Heap::contains(const void* x)
     {
-        return m_newSpace.contains(p);
+        if (!MarkedBlock::isAtomAligned(x))
+            return false;
+
+        MarkedBlock* block = MarkedBlock::blockFor(x);
+        if (!block || !m_blocks.contains(block))
+            return false;
+            
+        return true;
     }
 
     inline void Heap::reportExtraMemoryCost(size_t cost)
@@ -207,7 +223,9 @@
 
     template <typename Functor> inline void Heap::forEach(Functor& functor)
     {
-        m_newSpace.forEach(functor);
+        BlockIterator end = m_blocks.end();
+        for (BlockIterator it = m_blocks.begin(); it != end; ++it)
+            (*it)->forEach(functor);
     }
 
     inline void* Heap::allocate(size_t bytes)

Modified: trunk/Source/_javascript_Core/heap/NewSpace.cpp (88388 => 88389)


--- trunk/Source/_javascript_Core/heap/NewSpace.cpp	2011-06-08 21:38:24 UTC (rev 88388)
+++ trunk/Source/_javascript_Core/heap/NewSpace.cpp	2011-06-08 21:39:27 UTC (rev 88389)
@@ -43,99 +43,19 @@
         sizeClassFor(cellSize).cellSize = cellSize;
 }
 
-void NewSpace::destroy()
+void NewSpace::addBlock(SizeClass& sizeClass, MarkedBlock* block)
 {
-    /* Keep our precious zombies! */
-#if !ENABLE(JSC_ZOMBIES)
-    clearMarks();
-    shrink();
-    ASSERT(!size());
-#endif
-}
-
-MarkedBlock* NewSpace::allocateBlock(SizeClass& sizeClass)
-{
-    MarkedBlock* block = MarkedBlock::create(m_heap, sizeClass.cellSize);
-    sizeClass.blockList.append(block);
     sizeClass.nextBlock = block;
-    m_blocks.add(block);
-
-    return block;
+    sizeClass.blockList.append(block);
 }
 
-void NewSpace::freeBlocks(DoublyLinkedList<MarkedBlock>& blocks)
+void NewSpace::removeBlock(MarkedBlock* block)
 {
-    MarkedBlock* next;
-    for (MarkedBlock* block = blocks.head(); block; block = next) {
-        next = block->next();
-
-        blocks.remove(block);
-        m_blocks.remove(block);
-        MarkedBlock::destroy(block);
-    }
+    SizeClass& sizeClass = sizeClassFor(block->cellSize());
+    sizeClass.nextBlock = block->next();
+    sizeClass.blockList.remove(block);
 }
 
-void NewSpace::shrink()
-{
-    // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
-    DoublyLinkedList<MarkedBlock> empties;
-
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it) {
-        MarkedBlock* block = *it;
-        if (block->isEmpty()) {
-            SizeClass& sizeClass = sizeClassFor(block->cellSize());
-            sizeClass.blockList.remove(block);
-            sizeClass.nextBlock = sizeClass.blockList.head();
-            empties.append(block);
-        }
-    }
-    
-    freeBlocks(empties);
-    ASSERT(empties.isEmpty());
-}
-
-void NewSpace::clearMarks()
-{
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        (*it)->clearMarks();
-}
-
-void NewSpace::sweep()
-{
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        (*it)->sweep();
-}
-
-size_t NewSpace::objectCount() const
-{
-    size_t result = 0;
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        result += (*it)->markCount();
-    return result;
-}
-
-size_t NewSpace::size() const
-{
-    size_t result = 0;
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        result += (*it)->size();
-    return result;
-}
-
-size_t NewSpace::capacity() const
-{
-    size_t result = 0;
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        result += (*it)->capacity();
-    return result;
-}
-
 void NewSpace::resetAllocator()
 {
     m_waterMark = 0;
@@ -145,10 +65,6 @@
 
     for (size_t cellSize = impreciseStep; cellSize < impreciseCutoff; cellSize += impreciseStep)
         sizeClassFor(cellSize).resetAllocator();
-
-    BlockIterator end = m_blocks.end();
-    for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-        (*it)->resetAllocator();
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/heap/NewSpace.h (88388 => 88389)


--- trunk/Source/_javascript_Core/heap/NewSpace.h	2011-06-08 21:38:24 UTC (rev 88388)
+++ trunk/Source/_javascript_Core/heap/NewSpace.h	2011-06-08 21:39:27 UTC (rev 88389)
@@ -58,28 +58,19 @@
         };
 
         NewSpace(Heap*);
-        void destroy();
 
-        size_t highWaterMark();
-        void setHighWaterMark(size_t);
-
         SizeClass& sizeClassFor(size_t);
         void* allocate(SizeClass&);
 
-        void clearMarks();
-        void markRoots();
-        void resetAllocator();
-        void sweep();
-        void shrink();
+        void addBlock(SizeClass&, MarkedBlock*);
+        void removeBlock(MarkedBlock*);
 
-        size_t size() const;
-        size_t capacity() const;
-        size_t objectCount() const;
+        size_t waterMark();
+        size_t highWaterMark();
+        void setHighWaterMark(size_t);
 
-        bool contains(const void*);
+        void resetAllocator();
 
-        template<typename Functor> void forEach(Functor&);
-
     private:
         // [ 8, 16... 128 )
         static const size_t preciseStep = MarkedBlock::atomSize;
@@ -91,40 +82,18 @@
         static const size_t impreciseCutoff = maxCellSize;
         static const size_t impreciseCount = impreciseCutoff / impreciseStep - 1;
 
-        typedef HashSet<MarkedBlock*>::iterator BlockIterator;
-
-        MarkedBlock* allocateBlock(SizeClass&);
-        void freeBlocks(DoublyLinkedList<MarkedBlock>&);
-
-        void clearMarks(MarkedBlock*);
-
         SizeClass m_preciseSizeClasses[preciseCount];
         SizeClass m_impreciseSizeClasses[impreciseCount];
-        HashSet<MarkedBlock*> m_blocks;
         size_t m_waterMark;
         size_t m_highWaterMark;
         Heap* m_heap;
     };
 
-    inline bool NewSpace::contains(const void* x)
+    inline size_t NewSpace::waterMark()
     {
-        if (!MarkedBlock::isAtomAligned(x))
-            return false;
-
-        MarkedBlock* block = MarkedBlock::blockFor(x);
-        if (!block || !m_blocks.contains(block))
-            return false;
-            
-        return true;
+        return m_waterMark;
     }
 
-    template <typename Functor> inline void NewSpace::forEach(Functor& functor)
-    {
-        BlockIterator end = m_blocks.end();
-        for (BlockIterator it = m_blocks.begin(); it != end; ++it)
-            (*it)->forEach(functor);
-    }
-
     inline size_t NewSpace::highWaterMark()
     {
         return m_highWaterMark;
@@ -152,9 +121,6 @@
             m_waterMark += block->capacity();
         }
 
-        if (m_waterMark < m_highWaterMark)
-            return allocateBlock(sizeClass)->allocate();
-
         return 0;
     }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to