Changeset 92217 in webkit


Ignore:
Timestamp:
Aug 2, 2011 12:57:06 PM (13 years ago)
Author:
fpizlo@apple.com
Message:

JSC does a GC even when the heap still has free pages
https://bugs.webkit.org/show_bug.cgi?id=65445

Reviewed by Oliver Hunt.

If the high watermark is not reached, then we allocate new blocks as
before. If the current watermark does reach (or exceed) the high
watermark, then we check if there is a block on the free block pool.
If there is, we simply allocation from it. If there isn't, we
invoke a collectin as before. This effectively couples the elastic
scavenging to the collector's decision function. That is, if an
application rapidly varies its heap usage (sometimes using more and
sometimes less) then the collector will not thrash as it used to.
But if heap usage drops and stays low then the scavenger thread and
the GC will eventually reach a kind of consensus: the GC will set
the watermark low because of low heap usage, and the scavenger thread
will steadily eliminate pages from the free page pool, until the size
of the free pool is below the high watermark.

On command-line, this is neutral on SunSpider and Kraken and a 3% win
on V8. In browser, this is a 1% win on V8 and neutral on the other
two.

  • heap/Heap.cpp:

(JSC::Heap::allocateSlowCase):
(JSC::Heap::allocateBlock):

  • heap/Heap.h:
Location:
trunk/Source/JavaScriptCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r92210 r92217  
     12011-08-02  Filip Pizlo  <fpizlo@apple.com>
     2
     3        JSC does a GC even when the heap still has free pages
     4        https://bugs.webkit.org/show_bug.cgi?id=65445
     5
     6        Reviewed by Oliver Hunt.
     7       
     8        If the high watermark is not reached, then we allocate new blocks as
     9        before.  If the current watermark does reach (or exceed) the high
     10        watermark, then we check if there is a block on the free block pool.
     11        If there is, we simply allocation from it.  If there isn't, we
     12        invoke a collectin as before.  This effectively couples the elastic
     13        scavenging to the collector's decision function.  That is, if an
     14        application rapidly varies its heap usage (sometimes using more and
     15        sometimes less) then the collector will not thrash as it used to.
     16        But if heap usage drops and stays low then the scavenger thread and
     17        the GC will eventually reach a kind of consensus: the GC will set
     18        the watermark low because of low heap usage, and the scavenger thread
     19        will steadily eliminate pages from the free page pool, until the size
     20        of the free pool is below the high watermark.
     21       
     22        On command-line, this is neutral on SunSpider and Kraken and a 3% win
     23        on V8.  In browser, this is a 1% win on V8 and neutral on the other
     24        two.
     25
     26        * heap/Heap.cpp:
     27        (JSC::Heap::allocateSlowCase):
     28        (JSC::Heap::allocateBlock):
     29        * heap/Heap.h:
     30
    1312011-08-02  Jeff Miller  <jeffm@apple.com>
    232
  • trunk/Source/JavaScriptCore/heap/Heap.cpp

    r92084 r92217  
    405405        return result;
    406406
    407     if (m_newSpace.waterMark() < m_newSpace.highWaterMark() || !m_isSafeToCollect) {
    408         m_newSpace.addBlock(sizeClass, allocateBlock(sizeClass.cellSize));
     407    AllocationEffort allocationEffort;
     408   
     409    if (m_newSpace.waterMark() < m_newSpace.highWaterMark() || !m_isSafeToCollect)
     410        allocationEffort = AllocationMustSucceed;
     411    else
     412        allocationEffort = AllocationCanFail;
     413   
     414    MarkedBlock* block = allocateBlock(sizeClass.cellSize, allocationEffort);
     415    if (block) {
     416        m_newSpace.addBlock(sizeClass, block);
    409417        void* result = tryAllocate(sizeClass);
    410418        ASSERT(result);
     
    421429    ASSERT(m_newSpace.waterMark() < m_newSpace.highWaterMark());
    422430   
    423     m_newSpace.addBlock(sizeClass, allocateBlock(sizeClass.cellSize));
     431    m_newSpace.addBlock(sizeClass, allocateBlock(sizeClass.cellSize, AllocationMustSucceed));
    424432   
    425433    result = tryAllocate(sizeClass);
     
    695703}
    696704
    697 MarkedBlock* Heap::allocateBlock(size_t cellSize)
     705MarkedBlock* Heap::allocateBlock(size_t cellSize, Heap::AllocationEffort allocationEffort)
    698706{
    699707    MarkedBlock* block;
    700708   
    701709#if !ENABLE(LAZY_BLOCK_FREEING)
     710    if (allocationEffort == AllocationCanFail)
     711        return 0;
     712   
    702713    block = MarkedBlock::create(this, cellSize);
    703714#else
     
    713724    if (block)
    714725        block->initForCellSize(cellSize);
     726    else if (allocationEffort == AllocationCanFail)
     727        return 0;
    715728    else
    716729        block = MarkedBlock::create(this, cellSize);
  • trunk/Source/JavaScriptCore/heap/Heap.h

    r92084 r92217  
    125125        static const size_t minExtraCost = 256;
    126126        static const size_t maxExtraCost = 1024 * 1024;
     127       
     128        enum AllocationEffort { AllocationMustSucceed, AllocationCanFail };
    127129
    128130        bool isValidAllocation(size_t);
     
    131133        void resetAllocator();
    132134
    133         MarkedBlock* allocateBlock(size_t cellSize);
     135        MarkedBlock* allocateBlock(size_t cellSize, AllocationEffort);
    134136        void freeBlocks(MarkedBlock*);
    135137
Note: See TracChangeset for help on using the changeset viewer.