Changeset 87653 in webkit


Ignore:
Timestamp:
May 29, 2011 2:56:53 PM (13 years ago)
Author:
ggaren@apple.com
Message:

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.

  • 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.
Location:
trunk/Source/JavaScriptCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r87614 r87653  
     12011-05-29  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Sam Weinig.
     4
     5        Some heap refactoring
     6        https://bugs.webkit.org/show_bug.cgi?id=61704
     7       
     8        SunSpider says no change.
     9
     10        * JavaScriptCore.exp: Export!
     11
     12        * heap/Heap.cpp: COLLECT_ON_EVERY_ALLOCATION can actually do so now.
     13
     14        (JSC::Heap::Heap): Changed Heap sub-objects to point to the heap.
     15
     16        (JSC::Heap::allocate): Changed inline allocation code to only select the
     17        size class, since this can be optimized out at compile time -- everything
     18        else is now inlined into this out-of-line function.
     19       
     20        No need to duplicate ASSERTs made in our caller.
     21
     22        * heap/Heap.h:
     23        (JSC::Heap::heap):
     24        (JSC::Heap::isMarked):
     25        (JSC::Heap::testAndSetMarked):
     26        (JSC::Heap::testAndClearMarked):
     27        (JSC::Heap::setMarked): Call directly into MarkedBlock instead of adding
     28        a layer of indirection through MarkedSpace.
     29
     30        (JSC::Heap::allocate): See above.
     31
     32        * heap/MarkedBlock.cpp:
     33        (JSC::MarkedBlock::create):
     34        (JSC::MarkedBlock::MarkedBlock):
     35        * heap/MarkedBlock.h: Changed Heap sub-objects to point to the heap.
     36
     37        * heap/MarkedSpace.cpp:
     38        (JSC::MarkedSpace::MarkedSpace):
     39        (JSC::MarkedSpace::allocateBlock):
     40        * heap/MarkedSpace.h:
     41        (JSC::MarkedSpace::allocate): Updated to match changes above.
     42
    1432011-05-28  David Kilzer  <ddkilzer@apple.com>
    244
  • trunk/Source/JavaScriptCore/JavaScriptCore.exp

    r87434 r87653  
    117117__ZN3JSC11JSByteArray15createStructureERNS_12JSGlobalDataENS_7JSValueEPKNS_9ClassInfoE
    118118__ZN3JSC11JSByteArrayC1EPNS_9ExecStateEPNS_9StructureEPN3WTF9ByteArrayE
    119 __ZN3JSC11MarkedSpace21allocateFromSizeClassERNS0_9SizeClassE
    120119__ZN3JSC11ParserArena5resetEv
    121120__ZN3JSC11checkSyntaxEPNS_9ExecStateERKNS_10SourceCodeE
     
    224223__ZN3JSC41constructFunctionSkippingEvalEnabledCheckEPNS_9ExecStateEPNS_14JSGlobalObjectERKNS_7ArgListERKNS_10IdentifierERKNS_7UStringEi
    225224__ZN3JSC4Heap16activityCallbackEv
    226 __ZN3JSC4Heap16allocateSlowCaseEm
    227225__ZN3JSC4Heap16objectTypeCountsEv
    228226__ZN3JSC4Heap17collectAllGarbageEv
     
    236234__ZN3JSC4Heap7destroyEv
    237235__ZN3JSC4Heap7protectENS_7JSValueE
     236__ZN3JSC4Heap8allocateERNS_11MarkedSpace9SizeClassE
    238237__ZN3JSC4Heap9unprotectENS_7JSValueE
    239238__ZN3JSC4Yarr11YarrPatternC1ERKNS_7UStringEbbPPKc
  • trunk/Source/JavaScriptCore/JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def

    r87440 r87653  
    5757    ?addSlowCase@Identifier@JSC@@CA?AV?$PassRefPtr@VStringImpl@WTF@@@WTF@@PAVExecState@2@PAVStringImpl@4@@Z
    5858    ?addStaticGlobals@JSGlobalObject@JSC@@IAEXPAUGlobalPropertyInfo@12@H@Z
     59    ?allocate@Heap@JSC@@QAEPAXAAUSizeClass@MarkedSpace@2@@Z
    5960    ?allocate@Heap@JSC@@QAEPAXI@Z
    60     ?allocateFromSizeClass@MarkedSpace@JSC@@AAEPAXAAUSizeClass@12@@Z
    6161    ?allocatePropertyStorage@JSObject@JSC@@QAEXII@Z
    62     ?allocateSlowCase@Heap@JSC@@AAEPAXI@Z
    6362    ?append@StringBuilder@WTF@@QAEXPBDI@Z
    6463    ?append@StringBuilder@WTF@@QAEXPB_WI@Z
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r87450 r87653  
    3434#include <algorithm>
    3535
    36 #define COLLECT_ON_EVERY_SLOW_ALLOCATION 0
     36#define COLLECT_ON_EVERY_ALLOCATION 0
    3737
    3838using namespace std;
     
    6666Heap::Heap(JSGlobalData* globalData)
    6767    : m_operationInProgress(NoOperation)
    68     , m_markedSpace(globalData)
     68    , m_markedSpace(this)
    6969    , m_markListSet(0)
    7070    , m_activityCallback(DefaultGCActivityCallback::create(this))
     
    131131}
    132132
    133 void* Heap::allocateSlowCase(size_t bytes)
    134 {
    135     ASSERT(globalData()->identifierTable == wtfThreadData().currentIdentifierTable());
    136     ASSERT(JSLock::lockCount() > 0);
    137     ASSERT(JSLock::currentThreadIsHoldingLock());
    138     ASSERT(bytes <= MarkedSpace::maxCellSize);
    139     ASSERT(m_operationInProgress == NoOperation);
    140 
    141 #if COLLECT_ON_EVERY_SLOW_ALLOCATION
     133void* Heap::allocate(MarkedSpace::SizeClass& sizeClass)
     134{
     135#if COLLECT_ON_EVERY_ALLOCATION
    142136    collectAllGarbage();
    143137    ASSERT(m_operationInProgress == NoOperation);
    144138#endif
    145139
     140    void* result = m_markedSpace.allocate(sizeClass);
     141    if (result)
     142        return result;
     143
    146144    reset(DoNotSweep);
    147145
    148146    m_operationInProgress = Allocation;
    149     void* result = m_markedSpace.allocate(bytes);
     147    result = m_markedSpace.allocate(sizeClass);
    150148    m_operationInProgress = NoOperation;
    151149
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r87522 r87653  
    8282
    8383        void* allocate(size_t);
     84        void* allocate(MarkedSpace::SizeClass&);
    8485        void collectAllGarbage();
    8586
     
    113114
    114115    private:
    115         friend class JSGlobalData;
    116 
    117116        static const size_t minExtraCost = 256;
    118117        static const size_t maxExtraCost = 1024 * 1024;
     
    156155    }
    157156
    158     inline bool Heap::isMarked(const void* cell)
    159     {
    160         return MarkedSpace::isMarked(cell);
    161     }
    162 
    163     inline bool Heap::testAndSetMarked(const void* cell)
    164     {
    165         return MarkedSpace::testAndSetMarked(cell);
    166     }
    167 
    168     inline bool Heap::testAndClearMarked(const void* cell)
    169     {
    170         return MarkedSpace::testAndClearMarked(cell);
    171     }
    172 
    173     inline void Heap::setMarked(const void* cell)
    174     {
    175         MarkedSpace::setMarked(cell);
    176     }
    177 
    178     inline void Heap::writeBarrier(const JSCell*, JSValue)
    179     {
    180     }
    181 
    182     inline void Heap::writeBarrier(const JSCell*, JSCell*)
    183     {
    184     }
    185 
    186     inline bool Heap::contains(void* p)
    187     {
    188         return m_markedSpace.contains(p);
    189     }
    190 
    191     inline void Heap::reportExtraMemoryCost(size_t cost)
    192     {
    193         if (cost > minExtraCost)
    194             reportExtraMemoryCostSlowCase(cost);
    195     }
    196 
    197     template <typename Functor> inline void Heap::forEach(Functor& functor)
    198     {
    199         m_markedSpace.forEach(functor);
    200     }
    201 
    202     inline void* Heap::allocate(size_t bytes)
    203     {
    204         ASSERT(isValidAllocation(bytes));
    205 
    206         m_operationInProgress = Allocation;
    207         void* result = m_markedSpace.allocate(bytes);
    208         m_operationInProgress = NoOperation;
    209         if (result)
    210             return result;
    211 
    212         return allocateSlowCase(bytes);
     157    inline Heap* Heap::heap(JSCell* cell)
     158    {
     159        return MarkedBlock::blockFor(cell)->heap();
    213160    }
    214161
     
    220167    }
    221168
    222     inline Heap* Heap::heap(JSCell* c)
    223     {
    224         return MarkedSpace::heap(c);
     169    inline bool Heap::isMarked(const void* cell)
     170    {
     171        return MarkedBlock::blockFor(cell)->isMarked(cell);
     172    }
     173
     174    inline bool Heap::testAndSetMarked(const void* cell)
     175    {
     176        return MarkedBlock::blockFor(cell)->testAndSetMarked(cell);
     177    }
     178
     179    inline bool Heap::testAndClearMarked(const void* cell)
     180    {
     181        return MarkedBlock::blockFor(cell)->testAndClearMarked(cell);
     182    }
     183
     184    inline void Heap::setMarked(const void* cell)
     185    {
     186        MarkedBlock::blockFor(cell)->setMarked(cell);
     187    }
     188
     189    inline void Heap::writeBarrier(const JSCell*, JSValue)
     190    {
     191    }
     192
     193    inline void Heap::writeBarrier(const JSCell*, JSCell*)
     194    {
     195    }
     196
     197    inline bool Heap::contains(void* p)
     198    {
     199        return m_markedSpace.contains(p);
     200    }
     201
     202    inline void Heap::reportExtraMemoryCost(size_t cost)
     203    {
     204        if (cost > minExtraCost)
     205            reportExtraMemoryCostSlowCase(cost);
     206    }
     207
     208    template <typename Functor> inline void Heap::forEach(Functor& functor)
     209    {
     210        m_markedSpace.forEach(functor);
     211    }
     212
     213    inline void* Heap::allocate(size_t bytes)
     214    {
     215        ASSERT(isValidAllocation(bytes));
     216        MarkedSpace::SizeClass& sizeClass = m_markedSpace.sizeClassFor(bytes);
     217        return allocate(sizeClass);
    225218    }
    226219
  • trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp

    r87427 r87653  
    3434namespace JSC {
    3535
    36 MarkedBlock* MarkedBlock::create(JSGlobalData* globalData, size_t cellSize)
     36MarkedBlock* MarkedBlock::create(Heap* heap, size_t cellSize)
    3737{
    3838    PageAllocationAligned allocation = PageAllocationAligned::allocate(blockSize, blockSize, OSAllocator::JSGCHeapPages);
    3939    if (!static_cast<bool>(allocation))
    4040        CRASH();
    41     return new (allocation.base()) MarkedBlock(allocation, globalData, cellSize);
     41    return new (allocation.base()) MarkedBlock(allocation, heap, cellSize);
    4242}
    4343
     
    4949}
    5050
    51 MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, JSGlobalData* globalData, size_t cellSize)
     51MarkedBlock::MarkedBlock(const PageAllocationAligned& allocation, Heap* heap, size_t cellSize)
    5252    : m_nextAtom(firstAtom())
    5353    , m_allocation(allocation)
    54     , m_heap(&globalData->heap)
     54    , m_heap(heap)
    5555{
    5656    m_atomsPerCell = (cellSize + atomSize - 1) / atomSize;
    5757    m_endAtom = atomsPerBlock - m_atomsPerCell + 1;
    5858
    59     Structure* dummyMarkableCellStructure = globalData->dummyMarkableCellStructure.get();
     59    Structure* dummyMarkableCellStructure = heap->globalData()->dummyMarkableCellStructure.get();
    6060    for (size_t i = firstAtom(); i < m_endAtom; i += m_atomsPerCell)
    61         new (&atoms()[i]) JSCell(*globalData, dummyMarkableCellStructure, JSCell::CreatingEarlyCell);
     61        new (&atoms()[i]) JSCell(*heap->globalData(), dummyMarkableCellStructure, JSCell::CreatingEarlyCell);
    6262}
    6363
  • trunk/Source/JavaScriptCore/heap/MarkedBlock.h

    r87522 r87653  
    3232    class Heap;
    3333    class JSCell;
    34     class JSGlobalData;
    3534
    3635    typedef uintptr_t Bits;
     
    4544        static const size_t atomSize = sizeof(double); // Ensures natural alignment for all built-in types.
    4645
    47         static MarkedBlock* create(JSGlobalData*, size_t cellSize);
     46        static MarkedBlock* create(Heap*, size_t cellSize);
    4847        static void destroy(MarkedBlock*);
    4948
     
    8685        typedef char Atom[atomSize];
    8786
    88         MarkedBlock(const PageAllocationAligned&, JSGlobalData*, size_t cellSize);
     87        MarkedBlock(const PageAllocationAligned&, Heap*, size_t cellSize);
    8988        Atom* atoms();
    9089
  • trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp

    r86974 r87653  
    2424#include "JSGlobalObject.h"
    2525#include "JSCell.h"
    26 #include "JSGlobalData.h"
    2726#include "JSLock.h"
    2827#include "JSObject.h"
     
    3332class Structure;
    3433
    35 MarkedSpace::MarkedSpace(JSGlobalData* globalData)
     34MarkedSpace::MarkedSpace(Heap* heap)
    3635    : m_waterMark(0)
    3736    , m_highWaterMark(0)
    38     , m_globalData(globalData)
     37    , m_heap(heap)
    3938{
    4039    for (size_t cellSize = preciseStep; cellSize < preciseCutoff; cellSize += preciseStep)
     
    5756MarkedBlock* MarkedSpace::allocateBlock(SizeClass& sizeClass)
    5857{
    59     MarkedBlock* block = MarkedBlock::create(globalData(), sizeClass.cellSize);
     58    MarkedBlock* block = MarkedBlock::create(m_heap, sizeClass.cellSize);
    6059    sizeClass.blockList.append(block);
    6160    sizeClass.nextBlock = block;
     
    7574        MarkedBlock::destroy(block);
    7675    }
    77 }
    78 
    79 void* MarkedSpace::allocateFromSizeClass(SizeClass& sizeClass)
    80 {
    81     for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
    82         if (void* result = block->allocate())
    83             return result;
    84 
    85         m_waterMark += block->capacity();
    86     }
    87 
    88     if (m_waterMark < m_highWaterMark)
    89         return allocateBlock(sizeClass)->allocate();
    90 
    91     return 0;
    9276}
    9377
  • trunk/Source/JavaScriptCore/heap/MarkedSpace.h

    r87522 r87653  
    3939    class Heap;
    4040    class JSCell;
    41     class JSGlobalData;
    4241    class LiveObjectIterator;
    4342    class MarkStack;
     
    4847        WTF_MAKE_NONCOPYABLE(MarkedSpace);
    4948    public:
    50         // Currently public for use in assertions.
    5149        static const size_t maxCellSize = 1024;
    5250
    53         static Heap* heap(JSCell*);
     51        struct SizeClass {
     52            SizeClass();
     53            void reset();
    5454
    55         static bool isMarked(const void*);
    56         static bool testAndSetMarked(const void*);
    57         static bool testAndClearMarked(const void*);
    58         static void setMarked(const void*);
     55            MarkedBlock* nextBlock;
     56            DoublyLinkedList<MarkedBlock> blockList;
     57            size_t cellSize;
     58        };
    5959
    60         MarkedSpace(JSGlobalData*);
     60        MarkedSpace(Heap*);
    6161        void destroy();
    62 
    63         JSGlobalData* globalData();
    6462
    6563        size_t highWaterMark();
    6664        void setHighWaterMark(size_t);
    6765
    68         void* allocate(size_t);
     66        SizeClass& sizeClassFor(size_t);
     67        void* allocate(SizeClass&);
    6968
    7069        void clearMarks();
     
    9594        typedef HashSet<MarkedBlock*>::iterator BlockIterator;
    9695
    97         struct SizeClass {
    98             SizeClass();
    99             void reset();
    100 
    101             MarkedBlock* nextBlock;
    102             DoublyLinkedList<MarkedBlock> blockList;
    103             size_t cellSize;
    104         };
    105 
    10696        MarkedBlock* allocateBlock(SizeClass&);
    10797        void freeBlocks(DoublyLinkedList<MarkedBlock>&);
    108 
    109         SizeClass& sizeClassFor(size_t);
    110         void* allocateFromSizeClass(SizeClass&);
    11198
    11299        void clearMarks(MarkedBlock*);
     
    117104        size_t m_waterMark;
    118105        size_t m_highWaterMark;
    119         JSGlobalData* m_globalData;
     106        Heap* m_heap;
    120107    };
    121 
    122     inline Heap* MarkedSpace::heap(JSCell* cell)
    123     {
    124         return MarkedBlock::blockFor(cell)->heap();
    125     }
    126 
    127     inline bool MarkedSpace::isMarked(const void* cell)
    128     {
    129         return MarkedBlock::blockFor(cell)->isMarked(cell);
    130     }
    131 
    132     inline bool MarkedSpace::testAndSetMarked(const void* cell)
    133     {
    134         return MarkedBlock::blockFor(cell)->testAndSetMarked(cell);
    135     }
    136 
    137     inline bool MarkedSpace::testAndClearMarked(const void* cell)
    138     {
    139         return MarkedBlock::blockFor(cell)->testAndClearMarked(cell);
    140     }
    141 
    142     inline void MarkedSpace::setMarked(const void* cell)
    143     {
    144         MarkedBlock::blockFor(cell)->setMarked(cell);
    145     }
    146108
    147109    inline bool MarkedSpace::contains(const void* x)
     
    164126    }
    165127
    166     inline JSGlobalData* MarkedSpace::globalData()
    167     {
    168         return m_globalData;
    169     }
    170 
    171128    inline size_t MarkedSpace::highWaterMark()
    172129    {
     
    187144    }
    188145
    189     inline void* MarkedSpace::allocate(size_t bytes)
     146    inline void* MarkedSpace::allocate(SizeClass& sizeClass)
    190147    {
    191         SizeClass& sizeClass = sizeClassFor(bytes);
    192         return allocateFromSizeClass(sizeClass);
     148        for (MarkedBlock*& block = sizeClass.nextBlock ; block; block = block->next()) {
     149            if (void* result = block->allocate())
     150                return result;
     151
     152            m_waterMark += block->capacity();
     153        }
     154
     155        if (m_waterMark < m_highWaterMark)
     156            return allocateBlock(sizeClass)->allocate();
     157
     158        return 0;
    193159    }
    194    
     160
    195161    inline MarkedSpace::SizeClass::SizeClass()
    196162        : nextBlock(0)
Note: See TracChangeset for help on using the changeset viewer.