Changeset 78605 in webkit


Ignore:
Timestamp:
Feb 15, 2011 1:03:16 PM (13 years ago)
Author:
ggaren@apple.com
Message:

2011-02-15 Geoffrey Garen <ggaren@apple.com>

Reviewed by Darin Adler.

Moved MarkedBlock data members to the head of the block
https://bugs.webkit.org/show_bug.cgi?id=54482


This allows for a variable-sized tail, to accommodate oversized blocks.

SunSpider reports no change.


  • runtime/JSCell.h: (JSC::JSCell::MarkedBlock::allocate):
  • runtime/MarkedBlock.cpp: (JSC::MarkedBlock::destroy): (JSC::MarkedBlock::MarkedBlock): (JSC::MarkedBlock::sweep):
  • runtime/MarkedBlock.h: Added missing element to the CELLS_PER_BLOCK calculation. This kind of error is why we want to migrate to the system described below.

(JSC::roundUpToMultipleOf):
(JSC::MarkedBlock::firstCell):
(JSC::MarkedBlock::cells):
(JSC::MarkedBlock::cellNumber): Use subtraction instead of masking to
calculate cell number. The mask is no longer correct because the first
cell is not at the head of the block.

(JSC::MarkedBlock::forEach): Replaced m_cells data member with a cells()
accessor. We want to use sizeof(MarkedBlock) to calculate the size of the
block header, so we can't have an explicit data member to represent the block tail.


Also replaced iteration from zero with iteration from startCell(), since
the first N cells are now occupied by the header.

  • runtime/MarkedSpace.cpp: (JSC::MarkedSpace::MarkedSpace): (JSC::MarkedSpace::reset): Replaced iteration from zero as above.
Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r78597 r78605  
     12011-02-15  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        Moved MarkedBlock data members to the head of the block
     6        https://bugs.webkit.org/show_bug.cgi?id=54482
     7       
     8        This allows for a variable-sized tail, to accommodate oversized blocks.
     9
     10        SunSpider reports no change.
     11       
     12        * runtime/JSCell.h:
     13        (JSC::JSCell::MarkedBlock::allocate):
     14        * runtime/MarkedBlock.cpp:
     15        (JSC::MarkedBlock::destroy):
     16        (JSC::MarkedBlock::MarkedBlock):
     17        (JSC::MarkedBlock::sweep):
     18        * runtime/MarkedBlock.h: Added missing element to the CELLS_PER_BLOCK
     19        calculation. This kind of error is why we want to migrate to the system
     20        described below.
     21
     22        (JSC::roundUpToMultipleOf):
     23        (JSC::MarkedBlock::firstCell):
     24        (JSC::MarkedBlock::cells):
     25        (JSC::MarkedBlock::cellNumber): Use subtraction instead of masking to
     26        calculate cell number. The mask is no longer correct because the first
     27        cell is not at the head of the block.
     28
     29        (JSC::MarkedBlock::forEach): Replaced m_cells data member with a cells()
     30        accessor. We want to use sizeof(MarkedBlock) to calculate the size of the
     31        block header, so we can't have an explicit data member to represent the block tail.
     32       
     33        Also replaced iteration from zero with iteration from startCell(), since
     34        the first N cells are now occupied by the header.
     35
     36        * runtime/MarkedSpace.cpp:
     37        (JSC::MarkedSpace::MarkedSpace):
     38        (JSC::MarkedSpace::reset): Replaced iteration from zero as above.
     39
    1402011-02-15  Chris Rogers  <crogers@google.com>
    241
  • trunk/Source/JavaScriptCore/runtime/JSCell.h

    r78501 r78605  
    408408            ASSERT(nextCell < CELLS_PER_BLOCK);
    409409            if (!m_marks.testAndSet(nextCell)) { // Always false for the last cell in the block
    410                 JSCell* cell = reinterpret_cast<JSCell*>(&m_cells[nextCell++]);
     410                JSCell* cell = reinterpret_cast<JSCell*>(&cells()[nextCell++]);
    411411                cell->~JSCell();
    412412                return cell;
     
    414414            nextCell = m_marks.nextPossiblyUnset(nextCell);
    415415        } while (nextCell != CELLS_PER_BLOCK);
    416        
    417         nextCell = 0;
     416
     417        nextCell = firstCell();
    418418        return 0;
    419419    }
  • trunk/Source/JavaScriptCore/runtime/MarkedBlock.cpp

    r78501 r78605  
    4141void MarkedBlock::destroy(MarkedBlock* block)
    4242{
    43     for (size_t i = 0; i < CELLS_PER_BLOCK; ++i)
    44         reinterpret_cast<JSCell*>(&block->m_cells[i])->~JSCell();
     43    for (size_t i = block->firstCell(); i < CELLS_PER_BLOCK; ++i)
     44        reinterpret_cast<JSCell*>(&block->cells()[i])->~JSCell();
    4545    block->m_allocation.deallocate();
    4646}
     
    5353
    5454    Structure* dummyMarkableCellStructure = globalData->dummyMarkableCellStructure.get();
    55     for (size_t i = 0; i < CELLS_PER_BLOCK; ++i)
    56         new (&m_cells[i]) JSCell(dummyMarkableCellStructure);
     55    for (size_t i = firstCell(); i < CELLS_PER_BLOCK; ++i)
     56        new (&cells()[i]) JSCell(dummyMarkableCellStructure);
    5757}
    5858
     
    6363#endif
    6464
    65     for (size_t i = 0; i < CELLS_PER_BLOCK; ++i) {
     65    for (size_t i = firstCell(); i < CELLS_PER_BLOCK; ++i) {
    6666        if (m_marks.get(i))
    6767            continue;
    6868
    69         JSCell* cell = reinterpret_cast<JSCell*>(&m_cells[i]);
     69        JSCell* cell = reinterpret_cast<JSCell*>(&cells()[i]);
    7070#if ENABLE(JSC_ZOMBIES)
    7171        if (!cell->isZombie()) {
  • trunk/Source/JavaScriptCore/runtime/MarkedBlock.h

    r78501 r78605  
    3535    class JSGlobalData;
    3636
     37    // Efficient implementation that takes advantage of powers of two.
     38    template<size_t divisor> inline size_t roundUpToMultipleOf(size_t x)
     39    {
     40        COMPILE_ASSERT(divisor && !(divisor & (divisor - 1)), divisor_is_a_power_of_two);
     41
     42        size_t remainderMask = divisor - 1;
     43        return (x + remainderMask) & ~remainderMask;
     44    }
     45
    3746    class MarkedBlock {
    3847#if OS(WINCE) || OS(SYMBIAN) || PLATFORM(BREWMP)
     
    4251#endif
    4352
    44         static const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1;
    45         static const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK;
     53        static const size_t BLOCK_MASK = ~(BLOCK_SIZE - 1);
    4654        static const size_t MINIMUM_CELL_SIZE = 64;
    4755        static const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0);
     
    5462        static const size_t CELL_ALIGN_MASK = ~CELL_MASK;
    5563        static const size_t BITS_PER_BLOCK = BLOCK_SIZE / CELL_SIZE;
    56         static const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(Heap*) - sizeof(WTF::Bitmap<BITS_PER_BLOCK>)) / CELL_SIZE; // Division rounds down intentionally.
     64        static const size_t CELLS_PER_BLOCK = (BLOCK_SIZE - sizeof(WTF::Bitmap<BITS_PER_BLOCK>) - sizeof(PageAllocationAligned) - sizeof(Heap*)) / CELL_SIZE; // Division rounds down intentionally.
    5765       
    5866        struct CollectorCell {
     
    8290        size_t capacity();
    8391
     92        size_t firstCell();
     93
    8494        size_t cellNumber(const void*);
    8595        bool isMarked(const void*);
     
    91101    private:
    92102        MarkedBlock(const PageAllocationAligned&, JSGlobalData*);
     103        CollectorCell* cells();
    93104
    94         FixedArray<CollectorCell, CELLS_PER_BLOCK> m_cells;
    95105        WTF::Bitmap<BITS_PER_BLOCK> m_marks;
    96106        PageAllocationAligned m_allocation;
    97107        Heap* m_heap;
    98108    };
     109
     110    inline size_t MarkedBlock::firstCell()
     111    {
     112        return roundUpToMultipleOf<CELL_SIZE>(sizeof(MarkedBlock)) / CELL_SIZE;
     113    }
     114
     115    inline MarkedBlock::CollectorCell* MarkedBlock::cells()
     116    {
     117        return reinterpret_cast<CollectorCell*>(this);
     118    }
    99119
    100120    inline bool MarkedBlock::isCellAligned(const void* p)
     
    145165    inline size_t MarkedBlock::cellNumber(const void* cell)
    146166    {
    147         return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
     167        return (reinterpret_cast<uintptr_t>(cell) - reinterpret_cast<uintptr_t>(this)) / CELL_SIZE;
    148168    }
    149169
     
    165185    template <typename Functor> inline void MarkedBlock::forEach(Functor& functor)
    166186    {
    167         for (size_t i = 0; i < CELLS_PER_BLOCK - 1; ++i) { // The last cell is a dummy place-holder.
     187        for (size_t i = firstCell(); i < CELLS_PER_BLOCK - 1; ++i) { // The last cell is a dummy place-holder.
    168188            if (!m_marks.get(i))
    169189                continue;
    170             functor(reinterpret_cast<JSCell*>(&m_cells[i]));
     190            functor(reinterpret_cast<JSCell*>(&cells()[i]));
    171191        }
    172192    }
  • trunk/Source/JavaScriptCore/runtime/MarkedSpace.cpp

    r78382 r78605  
    3636{
    3737    allocateBlock();
     38    m_heap.nextCell = m_heap.collectorBlock(0)->firstCell();
    3839}
    3940
     
    128129void MarkedSpace::reset()
    129130{
    130     m_heap.nextCell = 0;
    131131    m_heap.nextBlock = 0;
     132    m_heap.nextCell = m_heap.collectorBlock(0)->firstCell();
    132133    m_waterMark = 0;
    133134#if ENABLE(JSC_ZOMBIES)
Note: See TracChangeset for help on using the changeset viewer.