2011-05-29 Geoffrey Garen <ggaren@apple.com>
authorggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 29 May 2011 21:56:53 +0000 (21:56 +0000)
committerggaren@apple.com <ggaren@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 29 May 2011 21:56:53 +0000 (21:56 +0000)
        Reviewed by Sam Weinig.

        Some heap refactoring
        https://bugs.webkit.org/show_bug.cgi?id=61704

        SunSpider says no change.

        * JavaScriptCore.exp: Export!

        * heap/Heap.cpp: COLLECT_ON_EVERY_ALLOCATION can actually do so now.

        (JSC::Heap::Heap): Changed Heap sub-objects to point to the heap.

        (JSC::Heap::allocate): Changed inline allocation code to only select the
        size class, since this can be optimized out at compile time -- everything
        else is now inlined into this out-of-line function.

        No need to duplicate ASSERTs made in our caller.

        * heap/Heap.h:
        (JSC::Heap::heap):
        (JSC::Heap::isMarked):
        (JSC::Heap::testAndSetMarked):
        (JSC::Heap::testAndClearMarked):
        (JSC::Heap::setMarked): Call directly into MarkedBlock instead of adding
        a layer of indirection through MarkedSpace.

        (JSC::Heap::allocate): See above.

        * heap/MarkedBlock.cpp:
        (JSC::MarkedBlock::create):
        (JSC::MarkedBlock::MarkedBlock):
        * heap/MarkedBlock.h: Changed Heap sub-objects to point to the heap.

        * heap/MarkedSpace.cpp:
        (JSC::MarkedSpace::MarkedSpace):
        (JSC::MarkedSpace::allocateBlock):
        * heap/MarkedSpace.h:
        (JSC::MarkedSpace::allocate): Updated to match changes above.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@87653 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/JavaScriptCore.exp
Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def
Source/JavaScriptCore/heap/Heap.cpp
Source/JavaScriptCore/heap/Heap.h
Source/JavaScriptCore/heap/MarkedBlock.cpp
Source/JavaScriptCore/heap/MarkedBlock.h
Source/JavaScriptCore/heap/MarkedSpace.cpp
Source/JavaScriptCore/heap/MarkedSpace.h

index 615467d..bf8a5b1 100644 (file)
@@ -1,3 +1,45 @@
+2011-05-29  Geoffrey Garen  <ggaren@apple.com>
+
+        Reviewed by Sam Weinig.
+
+        Some heap refactoring
+        https://bugs.webkit.org/show_bug.cgi?id=61704
+        
+        SunSpider says no change.
+
+        * JavaScriptCore.exp: Export!
+
+        * heap/Heap.cpp: COLLECT_ON_EVERY_ALLOCATION can actually do so now.
+
+        (JSC::Heap::Heap): Changed Heap sub-objects to point to the heap.
+
+        (JSC::Heap::allocate): Changed inline allocation code to only select the
+        size class, since this can be optimized out at compile time -- everything
+        else is now inlined into this out-of-line function.
+        
+        No need to duplicate ASSERTs made in our caller.
+
+        * heap/Heap.h:
+        (JSC::Heap::heap):
+        (JSC::Heap::isMarked):
+        (JSC::Heap::testAndSetMarked):
+        (JSC::Heap::testAndClearMarked):
+        (JSC::Heap::setMarked): Call directly into MarkedBlock instead of adding
+        a layer of indirection through MarkedSpace.
+
+        (JSC::Heap::allocate): See above.
+
+        * heap/MarkedBlock.cpp:
+        (JSC::MarkedBlock::create):
+        (JSC::MarkedBlock::MarkedBlock):
+        * heap/MarkedBlock.h: Changed Heap sub-objects to point to the heap.
+
+        * heap/MarkedSpace.cpp:
+        (JSC::MarkedSpace::MarkedSpace):
+        (JSC::MarkedSpace::allocateBlock):
+        * heap/MarkedSpace.h:
+        (JSC::MarkedSpace::allocate): Updated to match changes above.
+
 2011-05-28  David Kilzer  <ddkilzer@apple.com>
 
         BUILD FIX when building only the interpreter
index e28c89d..1e05cf2 100644 (file)
@@ -116,7 +116,6 @@ __ZN3JSC10throwErrorEPNS_9ExecStateEPNS_8JSObjectE
 __ZN3JSC11JSByteArray13s_defaultInfoE
 __ZN3JSC11JSByteArray15createStructureERNS_12JSGlobalDataENS_7JSValueEPKNS_9ClassInfoE
 __ZN3JSC11JSByteArrayC1EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE
-__ZN3JSC11MarkedSpace21allocateFromSizeClassERNS0_9SizeClassE
 __ZN3JSC11ParserArena5resetEv
 __ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
 __ZN3JSC11createErrorEPNS_9ExecStateERKNS_7UStringE
@@ -223,7 +222,6 @@ __ZN3JSC35createInterruptedExecutionExceptionEPNS_12JSGlobalDataE
 __ZN3JSC3NaNE
 __ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
 __ZN3JSC4Heap16activityCallbackEv
-__ZN3JSC4Heap16allocateSlowCaseEm
 __ZN3JSC4Heap16objectTypeCountsEv
 __ZN3JSC4Heap17collectAllGarbageEv
 __ZN3JSC4Heap17globalObjectCountEv
@@ -235,6 +233,7 @@ __ZN3JSC4Heap26protectedGlobalObjectCountEv
 __ZN3JSC4Heap29reportExtraMemoryCostSlowCaseEm
 __ZN3JSC4Heap7destroyEv
 __ZN3JSC4Heap7protectENS_7JSValueE
+__ZN3JSC4Heap8allocateERNS_11MarkedSpace9SizeClassE
 __ZN3JSC4Heap9unprotectENS_7JSValueE
 __ZN3JSC4Yarr11YarrPatternC1ERKNS_7UStringEbbPPKc
 __ZN3JSC4Yarr11byteCompileERNS0_11YarrPatternEPN3WTF20BumpPointerAllocatorE
index c15c089..79946f4 100644 (file)
@@ -56,10 +56,9 @@ EXPORTS
     ?addPropertyWithoutTransition@Structure@JSC@@QAEIAAVJSGlobalData@2@ABVIdentifier@2@IPAVJSCell@2@@Z
     ?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@MarkedSpace@2@@Z
     ?allocate@Heap@JSC@@QAEPAXI@Z
-    ?allocateFromSizeClass@MarkedSpace@JSC@@AAEPAXAAUSizeClass@12@@Z
     ?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z
-    ?allocateSlowCase@Heap@JSC@@AAEPAXI@Z
     ?append@StringBuilder@WTF@@QAEXPBDI@Z
     ?append@StringBuilder@WTF@@QAEXPB_WI@Z
     ?ascii@UString@JSC@@QBE?AVCString@WTF@@XZ
index 5800966..866bf91 100644 (file)
@@ -33,7 +33,7 @@
 #include "Tracing.h"
 #include <algorithm>
 
-#define COLLECT_ON_EVERY_SLOW_ALLOCATION 0
+#define COLLECT_ON_EVERY_ALLOCATION 0
 
 using namespace std;
 
@@ -65,7 +65,7 @@ static inline bool isValidThreadState(JSGlobalData* globalData)
 
 Heap::Heap(JSGlobalData* globalData)
     : m_operationInProgress(NoOperation)
-    , m_markedSpace(globalData)
+    , m_markedSpace(this)
     , m_markListSet(0)
     , m_activityCallback(DefaultGCActivityCallback::create(this))
     , m_globalData(globalData)
@@ -130,23 +130,21 @@ void Heap::reportExtraMemoryCostSlowCase(size_t cost)
     m_extraCost += cost;
 }
 
-void* Heap::allocateSlowCase(size_t bytes)
+void* Heap::allocate(MarkedSpace::SizeClass& sizeClass)
 {
-    ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
-    ASSERT(JSLock::lockCount() > 0);
-    ASSERT(JSLock::currentThreadIsHoldingLock());
-    ASSERT(bytes <= MarkedSpace::maxCellSize);
-    ASSERT(m_operationInProgress == NoOperation);
-
-#if COLLECT_ON_EVERY_SLOW_ALLOCATION
+#if COLLECT_ON_EVERY_ALLOCATION
     collectAllGarbage();
     ASSERT(m_operationInProgress == NoOperation);
 #endif
 
+    void* result = m_markedSpace.allocate(sizeClass);
+    if (result)
+        return result;
+
     reset(DoNotSweep);
 
     m_operationInProgress = Allocation;
-    void* result = m_markedSpace.allocate(bytes);
+    result = m_markedSpace.allocate(sizeClass);
     m_operationInProgress = NoOperation;
 
     ASSERT(result);
index f4fab35..75049b8 100644 (file)
@@ -81,6 +81,7 @@ namespace JSC {
         inline bool isBusy();
 
         void* allocate(size_t);
+        void* allocate(MarkedSpace::SizeClass&);
         void collectAllGarbage();
 
         void reportExtraMemoryCost(size_t cost);
@@ -112,8 +113,6 @@ namespace JSC {
         HandleStack* handleStack() { return &m_handleStack; }
 
     private:
-        friend class JSGlobalData;
-
         static const size_t minExtraCost = 256;
         static const size_t maxExtraCost = 1024 * 1024;
 
@@ -155,24 +154,36 @@ namespace JSC {
         return m_operationInProgress != NoOperation;
     }
 
+    inline Heap* Heap::heap(JSCell* cell)
+    {
+        return MarkedBlock::blockFor(cell)->heap();
+    }
+
+    inline Heap* Heap::heap(JSValue v)
+    {
+        if (!v.isCell())
+            return 0;
+        return heap(v.asCell());
+    }
+
     inline bool Heap::isMarked(const void* cell)
     {
-        return MarkedSpace::isMarked(cell);
+        return MarkedBlock::blockFor(cell)->isMarked(cell);
     }
 
     inline bool Heap::testAndSetMarked(const void* cell)
     {
-        return MarkedSpace::testAndSetMarked(cell);
+        return MarkedBlock::blockFor(cell)->testAndSetMarked(cell);
     }
 
     inline bool Heap::testAndClearMarked(const void* cell)
     {
-        return MarkedSpace::testAndClearMarked(cell);
+        return MarkedBlock::blockFor(cell)->testAndClearMarked(cell);
     }
 
     inline void Heap::setMarked(const void* cell)
     {
-        MarkedSpace::setMarked(cell);
+        MarkedBlock::blockFor(cell)->setMarked(cell);
     }
 
     inline void Heap::writeBarrier(const JSCell*, JSValue)
@@ -202,26 +213,8 @@ namespace JSC {
     inline void* Heap::allocate(size_t bytes)
     {
         ASSERT(isValidAllocation(bytes));
-
-        m_operationInProgress = Allocation;
-        void* result = m_markedSpace.allocate(bytes);
-        m_operationInProgress = NoOperation;
-        if (result)
-            return result;
-
-        return allocateSlowCase(bytes);
-    }
-
-    inline Heap* Heap::heap(JSValue v)
-    {
-        if (!v.isCell())
-            return 0;
-        return heap(v.asCell());
-    }
-
-    inline Heap* Heap::heap(JSCell* c)
-    {
-        return MarkedSpace::heap(c);
+        MarkedSpace::SizeClass& sizeClass = m_markedSpace.sizeClassFor(bytes);
+        return allocate(sizeClass);
     }
 
 } // namespace JSC
index 94757bc..7ffac18 100644 (file)
 
 namespace JSC {
 
-MarkedBlock* MarkedBlock::create(JSGlobalData* globalData, size_t cellSize)
+MarkedBlock* MarkedBlock::create(Heap* heap, size_t cellSize)
 {
     PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockSize, OSAllocator::JSGCHeapPages);
     if (!static_cast<bool>(allocation))
         CRASH();
-    return new (allocation.base()) MarkedBlock(allocation, globalData, cellSize);
+    return new (allocation.base()) MarkedBlock(allocation, heap, cellSize);
 }
 
 void MarkedBlock::destroy(MarkedBlock* block)
@@ -48,17 +48,17 @@ void MarkedBlock::destroy(MarkedBlock* block)
     block->m_allocation.deallocate();
 }
 
-MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, JSGlobalData* globalData, size_t cellSize)
+MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize)
     : m_nextAtom(firstAtom())
     , m_allocation(allocation)
-    , m_heap(&globalData->heap)
+    , m_heap(heap)
 {
     m_atomsPerCell = (cellSize + atomSize - 1) / atomSize;
     m_endAtom = atomsPerBlock - m_atomsPerCell + 1;
 
-    Structure* dummyMarkableCellStructure = globalData->dummyMarkableCellStructure.get();
+    Structure* dummyMarkableCellStructure = heap->globalData()->dummyMarkableCellStructure.get();
     for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell)
-        new (&atoms()[i]) JSCell(*globalData, dummyMarkableCellStructure, JSCell::CreatingEarlyCell);
+        new (&atoms()[i]) JSCell(*heap->globalData(), dummyMarkableCellStructure, JSCell::CreatingEarlyCell);
 }
 
 void MarkedBlock::sweep()
index 027229c..e168190 100644 (file)
@@ -31,7 +31,6 @@ namespace JSC {
 
     class Heap;
     class JSCell;
-    class JSGlobalData;
 
     typedef uintptr_t Bits;
 
@@ -44,7 +43,7 @@ namespace JSC {
     public:
         static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
 
-        static MarkedBlock* create(JSGlobalData*, size_t cellSize);
+        static MarkedBlock* create(Heap*, size_t cellSize);
         static void destroy(MarkedBlock*);
 
         static bool isAtomAligned(const void*);
@@ -85,7 +84,7 @@ namespace JSC {
 
         typedef char Atom[atomSize];
 
-        MarkedBlock(const PageAllocationAligned&, JSGlobalData*, size_t cellSize);
+        MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize);
         Atom* atoms();
 
         size_t m_nextAtom;
index 8de2d9a..3958b85 100644 (file)
@@ -23,7 +23,6 @@
 
 #include "JSGlobalObject.h"
 #include "JSCell.h"
-#include "JSGlobalData.h"
 #include "JSLock.h"
 #include "JSObject.h"
 #include "ScopeChain.h"
@@ -32,10 +31,10 @@ namespace JSC {
 
 class Structure;
 
-MarkedSpace::MarkedSpace(JSGlobalData* globalData)
+MarkedSpace::MarkedSpace(Heap* heap)
     : m_waterMark(0)
     , m_highWaterMark(0)
-    , m_globalData(globalData)
+    , m_heap(heap)
 {
     for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
         sizeClassFor(cellSize).cellSize = cellSize;
@@ -56,7 +55,7 @@ void MarkedSpace::destroy()
 
 MarkedBlock* MarkedSpace::allocateBlock(SizeClass& sizeClass)
 {
-    MarkedBlock* block = MarkedBlock::create(globalData(), sizeClass.cellSize);
+    MarkedBlock* block = MarkedBlock::create(m_heap, sizeClass.cellSize);
     sizeClass.blockList.append(block);
     sizeClass.nextBlock = block;
     m_blocks.add(block);
@@ -76,21 +75,6 @@ void MarkedSpace::freeBlocks(DoublyLinkedList<MarkedBlock>& blocks)
     }
 }
 
-void* MarkedSpace::allocateFromSizeClass(SizeClass& sizeClass)
-{
-    for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
-        if (void* result = block->allocate())
-            return result;
-
-        m_waterMark += block->capacity();
-    }
-
-    if (m_waterMark < m_highWaterMark)
-        return allocateBlock(sizeClass)->allocate();
-
-    return 0;
-}
-
 void MarkedSpace::shrink()
 {
     // We record a temporary list of empties to avoid modifying m_blocks while iterating it.
index 1e7669e..9e1b15d 100644 (file)
@@ -38,7 +38,6 @@ namespace JSC {
 
     class Heap;
     class JSCell;
-    class JSGlobalData;
     class LiveObjectIterator;
     class MarkStack;
     class WeakGCHandle;
@@ -47,25 +46,25 @@ namespace JSC {
     class MarkedSpace {
         WTF_MAKE_NONCOPYABLE(MarkedSpace);
     public:
-        // Currently public for use in assertions.
         static const size_t maxCellSize = 1024;
 
-        static Heap* heap(JSCell*);
+        struct SizeClass {
+            SizeClass();
+            void reset();
 
-        static bool isMarked(const void*);
-        static bool testAndSetMarked(const void*);
-        static bool testAndClearMarked(const void*);
-        static void setMarked(const void*);
+            MarkedBlock* nextBlock;
+            DoublyLinkedList<MarkedBlock> blockList;
+            size_t cellSize;
+        };
 
-        MarkedSpace(JSGlobalData*);
+        MarkedSpace(Heap*);
         void destroy();
 
-        JSGlobalData* globalData();
-
         size_t highWaterMark();
         void setHighWaterMark(size_t);
 
-        void* allocate(size_t);
+        SizeClass& sizeClassFor(size_t);
+        void* allocate(SizeClass&);
 
         void clearMarks();
         void markRoots();
@@ -94,21 +93,9 @@ namespace JSC {
 
         typedef HashSet<MarkedBlock*>::iterator BlockIterator;
 
-        struct SizeClass {
-            SizeClass();
-            void reset();
-
-            MarkedBlock* nextBlock;
-            DoublyLinkedList<MarkedBlock> blockList;
-            size_t cellSize;
-        };
-
         MarkedBlock* allocateBlock(SizeClass&);
         void freeBlocks(DoublyLinkedList<MarkedBlock>&);
 
-        SizeClass& sizeClassFor(size_t);
-        void* allocateFromSizeClass(SizeClass&);
-
         void clearMarks(MarkedBlock*);
 
         SizeClass m_preciseSizeClasses[preciseCount];
@@ -116,34 +103,9 @@ namespace JSC {
         HashSet<MarkedBlock*> m_blocks;
         size_t m_waterMark;
         size_t m_highWaterMark;
-        JSGlobalData* m_globalData;
+        Heap* m_heap;
     };
 
-    inline Heap* MarkedSpace::heap(JSCell* cell)
-    {
-        return MarkedBlock::blockFor(cell)->heap();
-    }
-
-    inline bool MarkedSpace::isMarked(const void* cell)
-    {
-        return MarkedBlock::blockFor(cell)->isMarked(cell);
-    }
-
-    inline bool MarkedSpace::testAndSetMarked(const void* cell)
-    {
-        return MarkedBlock::blockFor(cell)->testAndSetMarked(cell);
-    }
-
-    inline bool MarkedSpace::testAndClearMarked(const void* cell)
-    {
-        return MarkedBlock::blockFor(cell)->testAndClearMarked(cell);
-    }
-
-    inline void MarkedSpace::setMarked(const void* cell)
-    {
-        MarkedBlock::blockFor(cell)->setMarked(cell);
-    }
-
     inline bool MarkedSpace::contains(const void* x)
     {
         if (!MarkedBlock::isAtomAligned(x))
@@ -163,11 +125,6 @@ namespace JSC {
             (*it)->forEach(functor);
     }
 
-    inline JSGlobalData* MarkedSpace::globalData()
-    {
-        return m_globalData;
-    }
-
     inline size_t MarkedSpace::highWaterMark()
     {
         return m_highWaterMark;
@@ -186,12 +143,21 @@ namespace JSC {
         return m_impreciseSizeClasses[(bytes - 1) / impreciseStep];
     }
 
-    inline void* MarkedSpace::allocate(size_t bytes)
+    inline void* MarkedSpace::allocate(SizeClass& sizeClass)
     {
-        SizeClass& sizeClass = sizeClassFor(bytes);
-        return allocateFromSizeClass(sizeClass);
+        for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
+            if (void* result = block->allocate())
+                return result;
+
+            m_waterMark += block->capacity();
+        }
+
+        if (m_waterMark < m_highWaterMark)
+            return allocateBlock(sizeClass)->allocate();
+
+        return 0;
     }
-    
+
     inline MarkedSpace::SizeClass::SizeClass()
         : nextBlock(0)
         , cellSize(0)