Ignore:
Timestamp:
Apr 23, 2007, 2:54:33 PM (18 years ago)
Author:
mjs
Message:

Reviewed by Darin and Geoff.


  • move mark and collectOnMainThreadOnly bits into separate bitmaps


This saves 4 bytes per cell, allowing shrink of cell size to 32,
which leads to a .8% speed improvement on iBench.


This is only feasible because of all the previous changes on the branch.

  • kjs/collector.cpp: (KJS::allocateBlock): Adjust for some renames of constants. (KJS::Collector::markStackObjectsConservatively): Now that cells are 32 bytes (64 bytes on 64-bit) the cell alignment check can be made much more strict, and also obsoletes the need for a % sizeof(CollectorCell) check. Also, we can mask off the low bits of the pointer to have a potential block pointer to look for. (KJS::Collector::collectOnMainThreadOnly): Use bitmap. (KJS::Collector::markMainThreadOnlyObjects): Use bitmap. (KJS::Collector::collect): When sweeping, use bitmaps directly to find mark bits.
  • kjs/collector.h: (KJS::): Move needed constants and type declarations here. (KJS::CollectorBitmap::get): Bit twiddling to get a bitmap value. (KJS::CollectorBitmap::set): Bit twiddling to set a bitmap bit to true. (KJS::CollectorBitmap::clear): Bit twiddling to set a bitmap bit to false. (KJS::CollectorBitmap::clearAll): Clear whole bitmap at one go. (KJS::Collector::cellBlock): New operation, compute the block pointer for a cell by masking off low bits. (KJS::Collector::cellOffset): New operation, compute the cell offset for a cell by masking off high bits and dividing (actually a shift). (KJS::Collector::isCellMarked): Check mark bit in bitmap (KJS::Collector::markCell): Set mark bit in bitmap.
  • kjs/value.h: (KJS::JSCell::JSCell): No more bits. (KJS::JSCell::marked): Let collector handle it. (KJS::JSCell::mark): Let collector handle it.
File:
1 edited

Legend:

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

    r20351 r21047  
    2525#define KJSCOLLECTOR_H_
    2626
    27 #include "value.h"
    2827#include <wtf/HashCountedSet.h>
    2928
     
    3130
    3231namespace KJS {
     32
     33  class JSCell;
     34  class JSValue;
     35  class CollectorBlock;
    3336
    3437  class Collector {
     
    6164    static void registerAsMainThread();
    6265
     66    static bool isCellMarked(const JSCell*);
     67    static void markCell(JSCell*);
     68
    6369  private:
     70    static const CollectorBlock* cellBlock(const JSCell*);
     71    static CollectorBlock* cellBlock(JSCell*);
     72    static size_t cellOffset(const JSCell* cell);
     73
    6474    Collector();
    6575
     
    7585  };
    7686
     87  // tunable parameters
     88  template<size_t bytesPerWord> struct CellSize;
     89
     90  // cell size needs to be a power of two for certain optimizations in collector.cpp
     91  template<> struct CellSize<sizeof(uint32_t)> { static const size_t m_value = 32; }; // 32-bit
     92  template<> struct CellSize<sizeof(uint64_t)> { static const size_t m_value = 64; }; // 64-bit
     93  const size_t BLOCK_SIZE = 16 * 4096; // 64k
     94 
     95  // derived constants
     96  const size_t BLOCK_OFFSET_MASK = BLOCK_SIZE - 1;
     97  const size_t BLOCK_MASK = ~BLOCK_OFFSET_MASK;
     98  const size_t MINIMUM_CELL_SIZE = CellSize<sizeof(void*)>::m_value;
     99  const size_t CELL_ARRAY_LENGTH = (MINIMUM_CELL_SIZE / sizeof(double)) + (MINIMUM_CELL_SIZE % sizeof(double) != 0 ? sizeof(double) : 0);
     100  const size_t CELL_SIZE = CELL_ARRAY_LENGTH * sizeof(double);
     101  const size_t CELL_MASK = CELL_SIZE - 1;
     102  const size_t CELLS_PER_BLOCK = (BLOCK_SIZE * 8 - sizeof(uint32_t) * 8 - sizeof(void *) * 8 - 2 * (7 + 3 * 8)) / (CELL_SIZE * 8 + 2);
     103  const size_t BITMAP_SIZE = (CELLS_PER_BLOCK + 7) / 8;
     104  const size_t BITMAP_WORDS = (BITMAP_SIZE + 3) / sizeof(uint32_t);
     105 
     106  struct CollectorBitmap {
     107    uint32_t bits[BITMAP_WORDS];
     108    bool get(size_t n) const { return !!(bits[n >> 5] & (1 << (n & 0x1F))); }
     109    void set(size_t n) { bits[n >> 5] |= (1 << (n & 0x1F)); }
     110    void clear(size_t n) { bits[n >> 5] &= ~(1 << (n & 0x1F)); }
     111    void clearAll() { memset(bits, 0, sizeof(bits)); }
     112  };
     113 
     114  struct CollectorCell {
     115    union {
     116      double memory[CELL_ARRAY_LENGTH];
     117      struct {
     118        void* zeroIfFree;
     119        ptrdiff_t next;
     120      } freeCell;
     121    } u;
     122  };
     123
     124  struct CollectorBlock {
     125    CollectorCell cells[CELLS_PER_BLOCK];
     126    uint32_t usedCells;
     127    CollectorCell* freeList;
     128    CollectorBitmap marked;
     129    CollectorBitmap collectOnMainThreadOnly;
     130  };
     131
     132  inline const CollectorBlock* Collector::cellBlock(const JSCell* cell)
     133  {
     134    return reinterpret_cast<const CollectorBlock*>(reinterpret_cast<uintptr_t>(cell) & BLOCK_MASK);
     135  }
     136
     137  inline CollectorBlock* Collector::cellBlock(JSCell* cell)
     138  {
     139    return const_cast<CollectorBlock*>(cellBlock(const_cast<const JSCell*>(cell)));
     140  }
     141
     142  inline size_t Collector::cellOffset(const JSCell* cell)
     143  {
     144    return (reinterpret_cast<uintptr_t>(cell) & BLOCK_OFFSET_MASK) / CELL_SIZE;
     145  }
     146
     147  inline bool Collector::isCellMarked(const JSCell* cell)
     148  {
     149    return cellBlock(cell)->marked.get(cellOffset(cell));
     150  }
     151
     152  inline void Collector::markCell(JSCell* cell)
     153  {
     154    cellBlock(cell)->marked.set(cellOffset(cell));
     155  }
     156
    77157} // namespace KJS
    78158
Note: See TracChangeset for help on using the changeset viewer.