mirror of
https://github.com/autc04/Retro68.git
synced 2024-11-29 12:50:35 +00:00
130 lines
2.4 KiB
D
130 lines
2.4 KiB
D
|
/**
|
||
|
* Contains a bitfield used by the GC.
|
||
|
*
|
||
|
* Copyright: Copyright Digital Mars 2005 - 2013.
|
||
|
* License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
|
||
|
* Authors: Walter Bright, David Friedman, Sean Kelly
|
||
|
*/
|
||
|
|
||
|
/* Copyright Digital Mars 2005 - 2013.
|
||
|
* Distributed under the Boost Software License, Version 1.0.
|
||
|
* (See accompanying file LICENSE or copy at
|
||
|
* http://www.boost.org/LICENSE_1_0.txt)
|
||
|
*/
|
||
|
module gc.bits;
|
||
|
|
||
|
|
||
|
import core.bitop;
|
||
|
import core.stdc.string;
|
||
|
import core.stdc.stdlib;
|
||
|
import core.exception : onOutOfMemoryError;
|
||
|
|
||
|
struct GCBits
|
||
|
{
|
||
|
alias size_t wordtype;
|
||
|
|
||
|
enum BITS_PER_WORD = (wordtype.sizeof * 8);
|
||
|
enum BITS_SHIFT = (wordtype.sizeof == 8 ? 6 : 5);
|
||
|
enum BITS_MASK = (BITS_PER_WORD - 1);
|
||
|
enum BITS_1 = cast(wordtype)1;
|
||
|
|
||
|
wordtype* data;
|
||
|
size_t nbits;
|
||
|
|
||
|
void Dtor() nothrow
|
||
|
{
|
||
|
if (data)
|
||
|
{
|
||
|
free(data);
|
||
|
data = null;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void alloc(size_t nbits) nothrow
|
||
|
{
|
||
|
this.nbits = nbits;
|
||
|
data = cast(typeof(data[0])*)calloc(nwords, data[0].sizeof);
|
||
|
if (!data)
|
||
|
onOutOfMemoryError();
|
||
|
}
|
||
|
|
||
|
wordtype test(size_t i) const nothrow
|
||
|
in
|
||
|
{
|
||
|
assert(i < nbits);
|
||
|
}
|
||
|
body
|
||
|
{
|
||
|
return core.bitop.bt(data, i);
|
||
|
}
|
||
|
|
||
|
int set(size_t i) nothrow
|
||
|
in
|
||
|
{
|
||
|
assert(i < nbits);
|
||
|
}
|
||
|
body
|
||
|
{
|
||
|
return core.bitop.bts(data, i);
|
||
|
}
|
||
|
|
||
|
int clear(size_t i) nothrow
|
||
|
in
|
||
|
{
|
||
|
assert(i <= nbits);
|
||
|
}
|
||
|
body
|
||
|
{
|
||
|
return core.bitop.btr(data, i);
|
||
|
}
|
||
|
|
||
|
void zero() nothrow
|
||
|
{
|
||
|
memset(data, 0, nwords * wordtype.sizeof);
|
||
|
}
|
||
|
|
||
|
void copy(GCBits *f) nothrow
|
||
|
in
|
||
|
{
|
||
|
assert(nwords == f.nwords);
|
||
|
}
|
||
|
body
|
||
|
{
|
||
|
memcpy(data, f.data, nwords * wordtype.sizeof);
|
||
|
}
|
||
|
|
||
|
@property size_t nwords() const pure nothrow
|
||
|
{
|
||
|
return (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
unittest
|
||
|
{
|
||
|
GCBits b;
|
||
|
|
||
|
b.alloc(786);
|
||
|
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));
|
||
|
assert(b.test(0));
|
||
|
b.zero();
|
||
|
assert(!b.test(785));
|
||
|
assert(!b.test(0));
|
||
|
|
||
|
GCBits b2;
|
||
|
b2.alloc(786);
|
||
|
b2.set(38);
|
||
|
b.copy(&b2);
|
||
|
assert(b.test(38));
|
||
|
b2.Dtor();
|
||
|
b.Dtor();
|
||
|
}
|