Showing with 33 additions and 135 deletions.
  1. +25 −127 src/gc/bits.d
  2. +8 −8 src/gc/gc.d
152 changes: 25 additions & 127 deletions src/gc/bits.d
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,6 @@ import core.stdc.string;
import core.stdc.stdlib;
import core.exception : onOutOfMemoryError;


version (DigitalMars)
{
version = bitops;
}
else version (GNU)
{
// use the unoptimized version
}
else version (D_InlineAsm_X86)
{
version = Asm86;
}

struct GCBits
{
alias size_t wordtype;
Expand All @@ -42,9 +28,8 @@ struct GCBits
enum BITS_MASK = (BITS_PER_WORD - 1);
enum BITS_1 = cast(wordtype)1;

wordtype* data = null;
size_t nwords = 0; // allocated words in data[] excluding sentinals
size_t nbits = 0; // number of bits in data[] excluding sentinals
wordtype* data;
size_t nbits;

void Dtor() nothrow
{
Expand All @@ -55,128 +40,47 @@ struct GCBits
}
}

invariant()
{
if (data)
{
assert(nwords * data[0].sizeof * 8 >= nbits);
}
}

void alloc(size_t nbits) nothrow
{
this.nbits = nbits;
nwords = (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;
data = cast(typeof(data[0])*)calloc(nwords + 2, data[0].sizeof);
data = cast(typeof(data[0])*)calloc(nwords, data[0].sizeof);
if (!data)
onOutOfMemoryError();
}

wordtype test(size_t i) nothrow
wordtype test(size_t i) const nothrow
in
{
assert(i < nbits);
}
body
{
version (none)
{
return core.bitop.bt(data + 1, i); // this is actually slower! don't use
}
else
{
//return (cast(bit *)(data + 1))[i];
return data[1 + (i >> BITS_SHIFT)] & (BITS_1 << (i & BITS_MASK));
}
return core.bitop.bt(data, i);
}

void set(size_t i) nothrow
int set(size_t i) nothrow
in
{
assert(i < nbits);
}
body
{
//(cast(bit *)(data + 1))[i] = 1;
data[1 + (i >> BITS_SHIFT)] |= (BITS_1 << (i & BITS_MASK));
return core.bitop.bts(data, i);
}

void clear(size_t i) nothrow
int clear(size_t i) nothrow
in
{
assert(i < nbits);
assert(i <= nbits);
}
body
{
//(cast(bit *)(data + 1))[i] = 0;
data[1 + (i >> BITS_SHIFT)] &= ~(BITS_1 << (i & BITS_MASK));
}

wordtype testClear(size_t i) nothrow
{
version (bitops)
{
return core.bitop.btr(data + 1, i); // this is faster!
}
else version (Asm86)
{
asm
{
naked ;
mov EAX,data[EAX] ;
mov ECX,i-4[ESP] ;
btr 4[EAX],ECX ;
sbb EAX,EAX ;
ret 4 ;
}
}
else
{
//result = (cast(bit *)(data + 1))[i];
//(cast(bit *)(data + 1))[i] = 0;

auto p = &data[1 + (i >> BITS_SHIFT)];
auto mask = (BITS_1 << (i & BITS_MASK));
auto result = *p & mask;
*p &= ~mask;
return result;
}
}

wordtype testSet(size_t i) nothrow
{
version (bitops)
{
return core.bitop.bts(data + 1, i); // this is faster!
}
else version (Asm86)
{
asm
{
naked ;
mov EAX,data[EAX] ;
mov ECX,i-4[ESP] ;
bts 4[EAX],ECX ;
sbb EAX,EAX ;
ret 4 ;
}
}
else
{
//result = (cast(bit *)(data + 1))[i];
//(cast(bit *)(data + 1))[i] = 0;

auto p = &data[1 + (i >> BITS_SHIFT)];
auto mask = (BITS_1 << (i & BITS_MASK));
auto result = *p & mask;
*p |= mask;
return result;
}
return core.bitop.btr(data, i);
}

void zero() nothrow
{
memset(data + 1, 0, nwords * wordtype.sizeof);
memset(data, 0, nwords * wordtype.sizeof);
}

void copy(GCBits *f) nothrow
Expand All @@ -186,17 +90,12 @@ struct GCBits
}
body
{
memcpy(data + 1, f.data + 1, nwords * wordtype.sizeof);
memcpy(data, f.data, nwords * wordtype.sizeof);
}

wordtype* base() nothrow
in
@property size_t nwords() const pure nothrow
{
assert(data);
}
body
{
return data + 1;
return (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;
}
}

Expand All @@ -205,27 +104,26 @@ unittest
GCBits b;

b.alloc(786);
assert(b.test(123) == 0);
assert(b.testClear(123) == 0);
b.set(123);
assert(b.test(123) != 0);
assert(b.testClear(123) != 0);
assert(b.test(123) == 0);
assert(!b.test(123));
assert(!b.clear(123));
assert(!b.set(123));
assert(b.test(123));
assert(b.clear(123));
assert(!b.test(123));

b.set(785);
b.set(0);
assert(b.test(785) != 0);
assert(b.test(0) != 0);
assert(b.test(785));
assert(b.test(0));
b.zero();
assert(b.test(785) == 0);
assert(b.test(0) == 0);
assert(!b.test(785));
assert(!b.test(0));

GCBits b2;
b2.alloc(786);
b2.set(38);
b.copy(&b2);
assert(b.test(38) != 0);
assert(b.test(38));
b2.Dtor();

b.Dtor();
}
16 changes: 8 additions & 8 deletions src/gc/gc.d
Original file line number Diff line number Diff line change
Expand Up @@ -1581,7 +1581,7 @@ struct Gcx
immutable bitstride = size / 16;

GCBits.wordtype toClear;
size_t clearStart = (biti >> GCBits.BITS_SHIFT) + 1;
size_t clearStart = biti >> GCBits.BITS_SHIFT;
size_t clearIndex;

for (; p < ptop; p += size, biti += bitstride, clearIndex += bitstride)
Expand All @@ -1594,7 +1594,7 @@ struct Gcx
toClear = 0;
}

clearStart = (biti >> GCBits.BITS_SHIFT) + 1;
clearStart = biti >> GCBits.BITS_SHIFT;
clearIndex = biti & GCBits.BITS_MASK;
}

Expand Down Expand Up @@ -2468,7 +2468,7 @@ struct Gcx
}

//debug(PRINTF) printf("\t\tmark(x%x) = %d\n", biti, pool.mark.test(biti));
if (!pool.mark.testSet(biti))
if (!pool.mark.set(biti))
{
//if (log) debug(PRINTF) printf("\t\tmarking %p\n", p);
if (!pool.noscan.test(biti))
Expand Down Expand Up @@ -2640,7 +2640,7 @@ struct Gcx
void* q = sentinel_add(p);
sentinel_Invariant(q);

if (pool.finals.nbits && pool.finals.testClear(biti))
if (pool.finals.nbits && pool.finals.clear(biti))
{
size_t size = pool.bPageOffsets[pn] * PAGESIZE - SENTINEL_EXTRA;
uint attr = getBits(pool, biti);
Expand Down Expand Up @@ -2693,7 +2693,7 @@ struct Gcx
size_t bitstride = size / 16;

GCBits.wordtype toClear;
size_t clearStart = (biti >> GCBits.BITS_SHIFT) + 1;
size_t clearStart = biti >> GCBits.BITS_SHIFT;
size_t clearIndex;

for (; p < ptop; p += size, biti += bitstride, clearIndex += bitstride)
Expand All @@ -2706,7 +2706,7 @@ struct Gcx
toClear = 0;
}

clearStart = (biti >> GCBits.BITS_SHIFT) + 1;
clearStart = biti >> GCBits.BITS_SHIFT;
clearIndex = biti & GCBits.BITS_MASK;
}

Expand Down Expand Up @@ -2895,7 +2895,7 @@ struct Gcx
{
// Calculate the mask and bit offset once and then use it to
// set all of the bits we need to set.
immutable dataIndex = 1 + (biti >> GCBits.BITS_SHIFT);
immutable dataIndex = biti >> GCBits.BITS_SHIFT;
immutable bitOffset = biti & GCBits.BITS_MASK;
immutable orWith = GCBits.BITS_1 << bitOffset;

Expand Down Expand Up @@ -2947,7 +2947,7 @@ struct Gcx
}
body
{
immutable dataIndex = 1 + (biti >> GCBits.BITS_SHIFT);
immutable dataIndex = biti >> GCBits.BITS_SHIFT;
immutable bitOffset = biti & GCBits.BITS_MASK;
immutable keep = ~(GCBits.BITS_1 << bitOffset);

Expand Down