Ignore:
Timestamp:
Aug 26, 2009, 4:00:39 PM (16 years ago)
Author:
[email protected]
Message:

A bit of Collector refatoring.

Patch by Geoffrey Garen <[email protected]> on 2009-08-26
Reviewed by Oliver Hunt.

SunSpider says no change. v8 says 1.003x faster (1.02x faster on splay).

  • runtime/JSCell.cpp:

(JSC::JSCell::toPrimitive):
(JSC::JSCell::getPrimitiveNumber):
(JSC::JSCell::toBoolean):
(JSC::JSCell::toNumber):
(JSC::JSCell::toString):
(JSC::JSCell::toObject): Removed pure virtual functions from
JSCell, so the collector can construct one. This allowed
me to remove a bunch of ASSERT_NOT_REACHED throughout the
code, too.

  • runtime/JSCell.h:

(JSC::JSCell::JSCell): ditto
(JSC::Heap::heap): Inlined this function because it's trivial.

  • runtime/Collector.cpp:

(JSC::Heap::destroy):
(JSC::Heap::allocateBlock):
(JSC::Heap::freeBlock):
(JSC::Heap::freeBlocks): Renamed freeHeap to freeBlocks, since
it doesn't actually free the Heap object.
(JSC::Heap::heapAllocate):
(JSC::Heap::sweep):

  • runtime/Collector.h: Refactored block allocation and destruction

into helper functions.

  • runtime/GetterSetter.cpp:
  • runtime/JSAPIValueWrapper.cpp:
  • runtime/JSPropertyNameIterator.cpp: Removed dummy implementations

of pure virtual functions. (See above.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/runtime/Collector.cpp

    r47795 r47799  
    9494#endif
    9595
    96 #define DEBUG_COLLECTOR 0
    9796#define COLLECT_ON_EVERY_ALLOCATION 0
    9897
     
    114113static RHeap* userChunk = 0;
    115114#endif
    116 
    117 static void freeHeap(CollectorHeap*);
    118115
    119116#if ENABLE(JSC_MULTIPLE_THREADS)
     
    205202    ASSERT(!primaryHeap.numLiveObjects);
    206203
    207     freeHeap(&primaryHeap);
    208     freeHeap(&numberHeap);
     204    freeBlocks(&primaryHeap);
     205    freeBlocks(&numberHeap);
    209206
    210207#if ENABLE(JSC_MULTIPLE_THREADS)
     
    226223
    227224template <HeapType heapType>
    228 static NEVER_INLINE CollectorBlock* allocateBlock()
     225NEVER_INLINE CollectorBlock* Heap::allocateBlock()
    229226{
    230227#if PLATFORM(DARWIN)
     
    273270    memset(reinterpret_cast<void*>(address), 0, BLOCK_SIZE);
    274271#endif
    275     reinterpret_cast<CollectorBlock*>(address)->type = heapType;
    276     return reinterpret_cast<CollectorBlock*>(address);
    277 }
    278 
    279 static void freeBlock(CollectorBlock* block)
     272
     273    CollectorBlock* block = reinterpret_cast<CollectorBlock*>(address);
     274    block->freeList = block->cells;
     275    block->heap = this;
     276    block->type = heapType;
     277
     278    CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
     279    size_t numBlocks = heap.numBlocks;
     280    if (heap.usedBlocks == numBlocks) {
     281        static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR;
     282        if (numBlocks > maxNumBlocks)
     283            CRASH();
     284        numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR);
     285        heap.numBlocks = numBlocks;
     286        heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, numBlocks * sizeof(CollectorBlock*)));
     287    }
     288    heap.blocks[heap.usedBlocks++] = block;
     289
     290    return block;
     291}
     292
     293template <HeapType heapType>
     294NEVER_INLINE void Heap::freeBlock(size_t block)
     295{
     296    CollectorHeap& heap = heapType == PrimaryHeap ? primaryHeap : numberHeap;
     297
     298    freeBlock(heap.blocks[block]);
     299
     300    // swap with the last block so we compact as we go
     301    heap.blocks[block] = heap.blocks[heap.usedBlocks - 1];
     302    heap.usedBlocks--;
     303
     304    if (heap.numBlocks > MIN_ARRAY_SIZE && heap.usedBlocks < heap.numBlocks / LOW_WATER_FACTOR) {
     305        heap.numBlocks = heap.numBlocks / GROWTH_FACTOR;
     306        heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock*)));
     307    }
     308}
     309
     310NEVER_INLINE void Heap::freeBlock(CollectorBlock* block)
    280311{
    281312#if PLATFORM(DARWIN)   
     
    292323}
    293324
    294 static void freeHeap(CollectorHeap* heap)
     325void Heap::freeBlocks(CollectorHeap* heap)
    295326{
    296327    for (size_t i = 0; i < heap->usedBlocks; ++i)
     
    395426                goto scan;
    396427        }
    397  
     428
    398429        // didn't find a block, and GC didn't reclaim anything, need to allocate a new block
    399         size_t numBlocks = heap.numBlocks;
    400         if (usedBlocks == numBlocks) {
    401             static const size_t maxNumBlocks = ULONG_MAX / sizeof(CollectorBlock*) / GROWTH_FACTOR;
    402             if (numBlocks > maxNumBlocks)
    403                 CRASH();
    404             numBlocks = max(MIN_ARRAY_SIZE, numBlocks * GROWTH_FACTOR);
    405             heap.numBlocks = numBlocks;
    406             heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, numBlocks * sizeof(CollectorBlock*)));
    407         }
    408 
    409430        targetBlock = reinterpret_cast<Block*>(allocateBlock<heapType>());
    410         targetBlock->freeList = targetBlock->cells;
    411         targetBlock->heap = this;
     431        heap.firstBlockWithPossibleSpace = heap.usedBlocks - 1;
    412432        targetBlockUsedCells = 0;
    413         heap.blocks[usedBlocks] = reinterpret_cast<CollectorBlock*>(targetBlock);
    414         heap.usedBlocks = usedBlocks + 1;
    415         heap.firstBlockWithPossibleSpace = usedBlocks;
    416     }
    417  
     433    }
     434
    418435    // find a free spot in the block and detach it from the free list
    419436    Cell* newCell = targetBlock->freeList;
     
    9851002    if (m_protectedValuesMutex)
    9861003        m_protectedValuesMutex->unlock();
    987 }
    988 
    989 Heap* Heap::heap(JSValue v)
    990 {
    991     if (!v.isCell())
    992         return 0;
    993     return Heap::cellBlock(v.asCell())->heap;
    9941004}
    9951005
     
    11071117            continue;
    11081118
    1109 #if !DEBUG_COLLECTOR
    1110         freeBlock(reinterpret_cast<CollectorBlock*>(curBlock));
    1111 #endif
    1112         // swap with the last block so we compact as we go
    1113         heap.blocks[block] = heap.blocks[heap.usedBlocks - 1];
    1114         heap.usedBlocks--;
     1119        freeBlock<heapType>(block);
    11151120        block--; // Don't move forward a step in this case
    1116 
    1117         if (heap.numBlocks > MIN_ARRAY_SIZE && heap.usedBlocks < heap.numBlocks / LOW_WATER_FACTOR) {
    1118             heap.numBlocks = heap.numBlocks / GROWTH_FACTOR;
    1119             heap.blocks = static_cast<CollectorBlock**>(fastRealloc(heap.blocks, heap.numBlocks * sizeof(CollectorBlock*)));
    1120         }
    11211121    }
    11221122
Note: See TracChangeset for help on using the changeset viewer.