X-Git-Url: https://git.llucax.com/software/dgc/cdgc.git/blobdiff_plain/004b7e95d7c07045ff197463abf3eab1e9d353ac..7b736090719c6f08e286b246d9b7509413716fcf:/rt/gc/cdgc/bits.d diff --git a/rt/gc/cdgc/bits.d b/rt/gc/cdgc/bits.d index 67eb2df..7c06c83 100644 --- a/rt/gc/cdgc/bits.d +++ b/rt/gc/cdgc/bits.d @@ -26,7 +26,9 @@ 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(); @@ -34,6 +36,7 @@ private extern (C) void onOutOfMemoryError(); version (DigitalMars) { version = bitops; + import std.intrinsic; } else version (GNU) { @@ -58,11 +61,21 @@ struct GCBits 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; } } @@ -70,16 +83,15 @@ struct GCBits 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(); } @@ -136,14 +148,13 @@ struct GCBits } } 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; } @@ -151,13 +162,24 @@ struct GCBits 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) @@ -167,13 +189,7 @@ struct GCBits } 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() @@ -216,3 +232,6 @@ unittest b.Dtor(); } + + +// vim: set et sw=4 sts=4 :