Changeset 119364 in webkit


Ignore:
Timestamp:
Jun 3, 2012 2:16:55 PM (12 years ago)
Author:
ggaren@apple.com
Message:

Weak pointer finalization should be lazy
https://bugs.webkit.org/show_bug.cgi?id=87599

Reviewed by Sam Weinig.

This time for sure!

  • heap/Heap.cpp:

(JSC::Heap::collect): Don't sweep eagerly -- we'll sweep lazily instead.

  • heap/MarkedBlock.cpp:

(JSC::MarkedBlock::sweep): Sweep our weak set before we sweep our other
destructors -- this is our last chance to run weak set finalizers before
we recycle our memory.

  • heap/MarkedBlock.h:

(JSC::MarkedBlock::resetAllocator):

  • heap/MarkedSpace.cpp:

(JSC::MarkedSpace::resetAllocators):

  • heap/MarkedSpace.h:

(JSC::MarkedSpace::resetAllocators): Don't force allocator reset anymore.
It will happen automatically when a weak set is swept. It's simpler to
have only one canonical way for this to happen, and it wasn't buying
us anything to do it eagerly.

  • heap/WeakBlock.cpp:

(JSC::WeakBlock::sweep): Don't short-circuit a sweep unless we know
the sweep would be a no-op. If even one finalizer is pending, we need to
run it, since we won't get another chance.

  • heap/WeakSet.cpp:

(JSC::WeakSet::sweep): This loop can be simpler now that
WeakBlock::sweep() does what we mean.

Reset our allocator after a sweep because this is the optimal time to
start trying to recycle old weak pointers.

(JSC::WeakSet::tryFindAllocator): Don't sweep when searching for an
allocator because we've swept already, and forcing a new sweep would be
wasteful.

  • heap/WeakSet.h:

(JSC::WeakSet::shrink): Be sure to reset our allocator after a shrink
because the shrink may have removed the block the allocator was going to
allocate out of.

Location:
trunk/Source/JavaScriptCore
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r119343 r119364  
     12012-06-02  Geoffrey Garen  <ggaren@apple.com>
     2
     3        Weak pointer finalization should be lazy
     4        https://bugs.webkit.org/show_bug.cgi?id=87599
     5
     6        Reviewed by Sam Weinig.
     7
     8        This time for sure!
     9
     10        * heap/Heap.cpp:
     11        (JSC::Heap::collect): Don't sweep eagerly -- we'll sweep lazily instead.
     12
     13        * heap/MarkedBlock.cpp:
     14        (JSC::MarkedBlock::sweep): Sweep our weak set before we sweep our other
     15        destructors -- this is our last chance to run weak set finalizers before
     16        we recycle our memory.
     17
     18        * heap/MarkedBlock.h:
     19        (JSC::MarkedBlock::resetAllocator):
     20        * heap/MarkedSpace.cpp:
     21        (JSC::MarkedSpace::resetAllocators):
     22        * heap/MarkedSpace.h:
     23        (JSC::MarkedSpace::resetAllocators): Don't force allocator reset anymore.
     24        It will happen automatically when a weak set is swept. It's simpler to
     25        have only one canonical way for this to happen, and it wasn't buying
     26        us anything to do it eagerly.
     27
     28        * heap/WeakBlock.cpp:
     29        (JSC::WeakBlock::sweep): Don't short-circuit a sweep unless we know
     30        the sweep would be a no-op. If even one finalizer is pending, we need to
     31        run it, since we won't get another chance.
     32
     33        * heap/WeakSet.cpp:
     34        (JSC::WeakSet::sweep): This loop can be simpler now that
     35        WeakBlock::sweep() does what we mean.
     36
     37        Reset our allocator after a sweep because this is the optimal time to
     38        start trying to recycle old weak pointers.
     39
     40        (JSC::WeakSet::tryFindAllocator): Don't sweep when searching for an
     41        allocator because we've swept already, and forcing a new sweep would be
     42        wasteful.
     43
     44        * heap/WeakSet.h:
     45        (JSC::WeakSet::shrink): Be sure to reset our allocator after a shrink
     46        because the shrink may have removed the block the allocator was going to
     47        allocate out of.
     48
    1492012-06-02  Filip Pizlo  <fpizlo@apple.com>
    250
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r119028 r119364  
    689689
    690690    {
    691         GCPHASE(FinalizeWeakHandles);
    692         m_objectSpace.sweepWeakSets();
     691        GCPHASE(FinalizeSmallString);
    693692        m_globalData->smallStrings.finalizeSmallStrings();
    694693    }
  • trunk/Source/JavaScriptCore/heap/MarkedBlock.cpp

    r118901 r119364  
    115115    HEAP_LOG_BLOCK_STATE_TRANSITION(this);
    116116
     117    m_weakSet.sweep();
     118
    117119    if (sweepMode == SweepOnly && !m_cellsNeedDestruction)
    118120        return FreeList();
  • trunk/Source/JavaScriptCore/heap/MarkedBlock.h

    r119028 r119364  
    130130
    131131        void shrink();
    132         void resetAllocator();
    133132
    134133        void visitWeakSet(HeapRootVisitor&);
     
    273272    {
    274273        m_weakSet.shrink();
    275     }
    276 
    277     inline void MarkedBlock::resetAllocator()
    278     {
    279         m_weakSet.resetAllocator();
    280274    }
    281275
  • trunk/Source/JavaScriptCore/heap/MarkedSpace.cpp

    r118901 r119364  
    113113}
    114114
    115 struct ResetAllocator : MarkedBlock::VoidFunctor {
    116     void operator()(MarkedBlock* block) { block->resetAllocator(); }
    117 };
    118 
    119115void MarkedSpace::resetAllocators()
    120116{
     
    128124        destructorAllocatorFor(cellSize).reset();
    129125    }
    130 
    131     forEachBlock<ResetAllocator>();
    132126}
    133127
     
    141135{
    142136    forEachBlock<ReapWeakSet>();
    143 }
    144 
    145 void MarkedSpace::sweepWeakSets()
    146 {
    147     forEachBlock<SweepWeakSet>();
    148137}
    149138
  • trunk/Source/JavaScriptCore/heap/MarkedSpace.h

    r118901 r119364  
    8686    void visitWeakSets(HeapRootVisitor&);
    8787    void reapWeakSets();
    88     void sweepWeakSets();
    8988
    9089    MarkedBlockSet& blocks() { return m_blocks; }
  • trunk/Source/JavaScriptCore/heap/WeakBlock.cpp

    r118269 r119364  
    7070void WeakBlock::sweep()
    7171{
    72     if (!m_sweepResult.isNull())
     72    // If a block is completely empty, a sweep won't have any effect.
     73    if (isEmpty())
    7374        return;
    7475
  • trunk/Source/JavaScriptCore/heap/WeakSet.cpp

    r118416 r119364  
    4343void WeakSet::sweep()
    4444{
    45     WeakBlock* next;
    46     for (WeakBlock* block = m_blocks.head(); block; block = next) {
    47         next = block->next();
     45    for (WeakBlock* block = m_blocks.head(); block; block = block->next())
     46        block->sweep();
    4847
    49         // If a block is completely empty, a new sweep won't have any effect.
    50         if (block->isEmpty())
    51             continue;
    52 
    53         block->takeSweepResult(); // Force a new sweep by discarding the last sweep.
    54         block->sweep();
    55     }
     48    resetAllocator();
    5649}
    5750
     
    7063        m_nextAllocator = m_nextAllocator->next();
    7164
    72         block->sweep();
    7365        WeakBlock::SweepResult sweepResult = block->takeSweepResult();
    7466        if (sweepResult.freeList)
  • trunk/Source/JavaScriptCore/heap/WeakSet.h

    r118416 r119364  
    119119            removeAllocator(block);
    120120    }
     121
     122    resetAllocator();
    121123}
    122124
Note: See TracChangeset for help on using the changeset viewer.