1 module d.gc.bin; 2 3 enum InvalidBinID = 0xff; 4 5 struct Bin { 6 import d.gc.run; 7 RunDesc* current; 8 9 import d.gc.rbtree; 10 RBTree!(RunDesc, addrRunCmp) runTree; 11 } 12 13 struct BinInfo { 14 ushort itemSize; 15 ushort slots; 16 ubyte needPages; 17 ubyte shift; 18 ushort mul; 19 20 this(ushort itemSize, ubyte shift, ubyte needPages, ushort slots) { 21 this.itemSize = itemSize; 22 this.slots = slots; 23 this.needPages = needPages; 24 this.shift = cast(ubyte) (shift + 17); 25 26 // XXX: out contract 27 assert(this.shift == (this.shift & MaxShiftMask)); 28 29 auto tag = (itemSize >> shift) & 0x03; 30 auto mulIndices = getMulIndices(); 31 this.mul = mulIndices[tag]; 32 } 33 34 uint computeIndex(uint offset) const { 35 return (offset * mul) >> shift; 36 } 37 } 38 39 // FIXME: For some reason, this is crashing. 40 // enum MaxShiftMask = cast(uint) ((size_t.sizeof * 8) - 1); 41 enum MaxShiftMask = 63; 42 43 /** 44 * This is a bunch of magic values used to avoid requiring 45 * division to find the index of an item within a run. 46 * 47 * Computed using finddivisor.d 48 */ 49 auto getMulIndices() { 50 ushort[4] mul; 51 mul[0] = 32768; 52 mul[1] = 26215; 53 mul[2] = 21846; 54 mul[3] = 18725; 55 return mul; 56 } 57 58 import d.gc.sizeclass; 59 immutable BinInfo[ClassCount.Small] binInfos = getBinInfos();