Ignore:
Timestamp:
Apr 22, 2007, 8:28:45 PM (18 years ago)
Author:
mjs
Message:

Reviewed by Darin and Geoff.


This change is a .66% speedup on JS iBench for 32-bit platforms, probably much more
for 64-bit since it finally gives a reasonable cell size, but I did not test that.


  • kjs/collector.cpp: (KJS::): Use different cell size for 32-bit and 64-bit, now that there is no oversize allocation. (KJS::Collector::allocate): Remove oversize allocator. (KJS::Collector::markStackObjectsConservatively): Don't check oversize objects. (KJS::Collector::markMainThreadOnlyObjects): Ditto. (KJS::Collector::collect): Ditto.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/collector.cpp

    r20971 r21015  
    2626#include <wtf/FastMallocInternal.h>
    2727#include <wtf/HashCountedSet.h>
     28#include <wtf/UnusedParam.h>
    2829#include "internal.h"
    2930#include "list.h"
     
    5960namespace KJS {
    6061
     62
     63
    6164// tunable parameters
    62 const size_t MINIMUM_CELL_SIZE = 48;
     65
     66template<size_t bytesPerWord> struct CellSize;
     67template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 48; }; // 32-bit
     68template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 80; }; // 64-bit
     69
    6370const size_t BLOCK_SIZE = (8 * 4096);
    6471const size_t SPARE_EMPTY_BLOCKS = 2;
     
    6976
    7077// derived constants
    71 const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0);
     78const size_t MINIMUM_CELL_SIZE = CellSize<sizeof(void*)>::m_value;
     79const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? 1 : 0);
    7280const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double);
    73 const size_t CELLS_PER_BLOCK = ((BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void *) * 8) / (CELL_SIZE * 8));
    74 
     81const size_t CELLS_PER_BLOCK = ((BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void*) * 8) / (CELL_SIZE * 8));
    7582
    7683
     
    98105  size_t firstBlockWithPossibleSpace;
    99106 
    100   CollectorCell **oversizeCells;
    101   size_t numOversizeCells;
    102   size_t usedOversizeCells;
    103 
    104107  size_t numLiveObjects;
    105108  size_t numLiveObjectsAtLastCollect;
    106109};
    107110
    108 static CollectorHeap heap = {NULL, 0, 0, 0, NULL, 0, 0, 0, 0};
     111static CollectorHeap heap = {NULL, 0, 0, 0, 0, 0};
    109112
    110113size_t Collector::mainThreadOnlyObjectCount = 0;
     
    137140  ASSERT(JSLock::lockCount() > 0);
    138141  ASSERT(JSLock::currentThreadIsHoldingLock());
     142  ASSERT(s <= CELL_SIZE);
     143  UNUSED_PARAM(s); // s is now only used for the above assert
    139144
    140145  // collect if needed
     
    151156  GCLock lock;
    152157#endif
    153  
    154   if (s > CELL_SIZE) {
    155     // oversize allocator
    156     size_t usedOversizeCells = heap.usedOversizeCells;
    157     size_t numOversizeCells = heap.numOversizeCells;
    158 
    159     if (usedOversizeCells == numOversizeCells) {
    160       numOversizeCells = max(MIN_ARRAY_SIZE, numOversizeCells * GROWTH_FACTOR);
    161       heap.numOversizeCells = numOversizeCells;
    162       heap.oversizeCells = static_cast<CollectorCell **>(fastRealloc(heap.oversizeCells, numOversizeCells * sizeof(CollectorCell *)));
    163     }
    164    
    165     void *newCell = fastMalloc(s);
    166     heap.oversizeCells[usedOversizeCells] = static_cast<CollectorCell *>(newCell);
    167     heap.usedOversizeCells = usedOversizeCells + 1;
    168     heap.numLiveObjects = numLiveObjects + 1;
    169 
    170     return newCell;
    171   }
    172158 
    173159  // slab allocator
     
    387373  size_t usedBlocks = heap.usedBlocks;
    388374  CollectorBlock **blocks = heap.blocks;
    389   size_t usedOversizeCells = heap.usedOversizeCells;
    390   CollectorCell **oversizeCells = heap.oversizeCells;
    391375
    392376  const size_t lastCellOffset = sizeof(CollectorCell) * (CELLS_PER_BLOCK - 1);
     
    397381      for (size_t block = 0; block < usedBlocks; block++) {
    398382        size_t offset = x - reinterpret_cast<char *>(blocks[block]);
    399         if (offset <= lastCellOffset && offset % sizeof(CollectorCell) == 0)
    400           goto gotGoodPointer;
    401       }
    402       for (size_t i = 0; i != usedOversizeCells; i++)
    403         if (x == reinterpret_cast<char *>(oversizeCells[i]))
    404           goto gotGoodPointer;
    405       continue;
    406 
    407 gotGoodPointer:
    408       if (((CollectorCell *)x)->u.freeCell.zeroIfFree != 0) {
    409         JSCell *imp = reinterpret_cast<JSCell *>(x);
    410         if (!imp->marked())
    411           imp->mark();
     383        if (offset <= lastCellOffset && offset % sizeof(CollectorCell) == 0) {
     384          if (((CollectorCell *)x)->u.freeCell.zeroIfFree != 0) {
     385            JSCell *imp = reinterpret_cast<JSCell *>(x);
     386            if (!imp->marked())
     387              imp->mark();
     388          }
     389          break;
     390        }
    412391      }
    413392    }
     
    702681        }
    703682    }
    704 
    705     for (size_t cell = 0; cell < heap.usedOversizeCells; cell++) {
    706         ASSERT(count < mainThreadOnlyObjectCount);
    707 
    708         JSCell* imp = reinterpret_cast<JSCell*>(heap.oversizeCells[cell]);
    709         if (imp->m_collectOnMainThreadOnly) {
    710             if (!imp->marked())
    711                 imp->mark();
    712             if (++count == mainThreadOnlyObjectCount)
    713                 return;
    714         }
    715     }
    716683}
    717684
     
    851818    heap.firstBlockWithPossibleSpace = 0;
    852819 
    853   size_t cell = 0;
    854   while (cell < heap.usedOversizeCells) {
    855     JSCell *imp = (JSCell *)heap.oversizeCells[cell];
    856    
    857     if (imp->m_marked) {
    858       imp->m_marked = false;
    859       cell++;
    860     } else {
    861       ASSERT(currentThreadIsMainThread || !imp->m_collectOnMainThreadOnly);
    862       if (imp->m_collectOnMainThreadOnly)
    863         --mainThreadOnlyObjectCount;
    864       imp->~JSCell();
    865 #if DEBUG_COLLECTOR
    866       heap.oversizeCells[cell]->u.freeCell.zeroIfFree = 0;
    867 #else
    868       fastFree(imp);
    869 #endif
    870 
    871       // swap with the last oversize cell so we compact as we go
    872       heap.oversizeCells[cell] = heap.oversizeCells[heap.usedOversizeCells - 1];
    873 
    874       heap.usedOversizeCells--;
    875       numLiveObjects--;
    876 
    877       if (heap.numOversizeCells > MIN_ARRAY_SIZE && heap.usedOversizeCells < heap.numOversizeCells / LOW_WATER_FACTOR) {
    878         heap.numOversizeCells = heap.numOversizeCells / GROWTH_FACTOR;
    879         heap.oversizeCells = (CollectorCell **)fastRealloc(heap.oversizeCells, heap.numOversizeCells * sizeof(CollectorCell *));
    880       }
    881     }
    882   }
    883  
    884820  bool deleted = heap.numLiveObjects != numLiveObjects;
    885821
Note: See TracChangeset for help on using the changeset viewer.