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();