module rt.gc.cdgc.bits;
-import rt.gc.cdgc.libc;
+import os = rt.gc.cdgc.os;
+
+import cstring = tango.stdc.string;
private extern (C) void onOutOfMemoryError();
size_t nwords = 0; // allocated words in data[] excluding sentinals
size_t nbits = 0; // number of bits in data[] excluding sentinals
- void Dtor()
+ /// Get the number of bytes needed to store nbits bits
+ size_t data_size()
+ {
+ return (nwords + 2) * uint.sizeof; // +2 for sentinels
+ }
+
+ void Dtor(os.Vis vis = os.Vis.PRIV)
{
+ // Even when os.dealloc() can be called with a null pointer, the extra
+ // call might be significant. On hard GC benchmarks making the test for
+ // null here (i.e. not making the call) can reduce the GC time by
+ // almost ~5%.
if (data)
{
- free(data);
+ os.dealloc(data, data_size, vis);
data = null;
}
}
invariant
{
if (data)
- {
- assert(nwords * data[0].sizeof * 8 >= nbits);
- }
+ assert (nwords ==
+ ((nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT));
}
- void alloc(size_t nbits)
+ void alloc(size_t nbits, os.Vis vis = os.Vis.PRIV)
{
this.nbits = nbits;
- nwords = (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;
- data = cast(uint*)calloc(nwords + 2, uint.sizeof);
+ this.nwords = (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;
+ this.data = cast(uint*) os.alloc(data_size, vis);
if (!data)
onOutOfMemoryError();
}
}
}
else
- { uint result;
-
+ {
//result = (cast(bit *)(data + 1))[i];
//(cast(bit *)(data + 1))[i] = 0;
uint* p = &data[1 + (i >> BITS_SHIFT)];
uint mask = (1 << (i & BITS_MASK));
- result = *p & mask;
+ uint result = *p & mask;
*p &= ~mask;
return result;
}
void zero()
{
- version(MEMCPY_NON_SIG_SAFE) {
- uint * d1=data+1,dEnd=d1+nwords;
- for (;d1!=dEnd;++d1)
- *d1=0u;
- } else {
- memset(data + 1, 0, nwords * uint.sizeof);
- }
+ cstring.memset(data + 1, 0, nwords * uint.sizeof);
+ }
+
+ void set_all()
+ {
+ cstring.memset(data + 1, 0xff, nwords * uint.sizeof);
+ }
+
+ void set_group(size_t base, size_t nbits)
+ in
+ {
+ }
+ body
+ {
+ assert ((base % 8) == 0);
+ assert ((nbits % 8) == 0);
+ size_t nbytes = nbits / 8;
+ cstring.memset(data + 1 + (base >> BITS_SHIFT), 0xff, nbytes);
}
void copy(GCBits *f)
}
body
{
- version(MEMCPY_NON_SIG_SAFE) {
- uint * d1=data+1,d2=f.data+1,dEnd=d1+nwords;
- for (;d1!=dEnd;++d1,++d2)
- *d1=*d2;
- } else {
- memcpy(data + 1, f.data + 1, nwords * uint.sizeof);
- }
+ cstring.memcpy(data + 1, f.data + 1, nwords * uint.sizeof);
}
uint* base()
b.Dtor();
}
+
+
+// vim: set et sw=4 sts=4 :