1 /** 2 * Contains a bitfield used by the GC. 3 * 4 * Copyright: Copyright Digital Mars 2005 - 2013. 5 * License: $(WEB www.boost.org/LICENSE_1_0.txt, Boost License 1.0). 6 * Authors: Walter Bright, David Friedman, Sean Kelly 7 */ 8 9 /* Copyright Digital Mars 2005 - 2013. 10 * Distributed under the Boost Software License, Version 1.0. 11 * (See accompanying file LICENSE or copy at 12 * http://www.boost.org/LICENSE_1_0.txt) 13 */ 14 module gc.bits; 15 16 17 import core.bitop; 18 import core.stdc.string; 19 import core.stdc.stdlib; 20 import core.exception : onOutOfMemoryError; 21 22 struct GCBits 23 { 24 alias size_t wordtype; 25 26 enum BITS_PER_WORD = (wordtype.sizeof * 8); 27 enum BITS_SHIFT = (wordtype.sizeof == 8 ? 6 : 5); 28 enum BITS_MASK = (BITS_PER_WORD - 1); 29 enum BITS_1 = cast(wordtype)1; 30 31 wordtype* data; 32 size_t nbits; 33 DtorGCBits34 void Dtor() nothrow 35 { 36 if (data) 37 { 38 free(data); 39 data = null; 40 } 41 } 42 allocGCBits43 void alloc(size_t nbits) nothrow 44 { 45 this.nbits = nbits; 46 data = cast(typeof(data[0])*)calloc(nwords, data[0].sizeof); 47 if (!data) 48 onOutOfMemoryError(); 49 } 50 testGCBits51 wordtype test(size_t i) const nothrow 52 in 53 { 54 assert(i < nbits); 55 } 56 body 57 { 58 return core.bitop.bt(data, i); 59 } 60 setGCBits61 int set(size_t i) nothrow 62 in 63 { 64 assert(i < nbits); 65 } 66 body 67 { 68 return core.bitop.bts(data, i); 69 } 70 clearGCBits71 int clear(size_t i) nothrow 72 in 73 { 74 assert(i <= nbits); 75 } 76 body 77 { 78 return core.bitop.btr(data, i); 79 } 80 zeroGCBits81 void zero() nothrow 82 { 83 memset(data, 0, nwords * wordtype.sizeof); 84 } 85 copyGCBits86 void copy(GCBits *f) nothrow 87 in 88 { 89 assert(nwords == f.nwords); 90 } 91 body 92 { 93 memcpy(data, f.data, nwords * wordtype.sizeof); 94 } 95 nwordsGCBits96 @property size_t nwords() const pure nothrow 97 { 98 return (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT; 99 } 100 } 101 102 unittest 103 { 104 GCBits b; 105 106 b.alloc(786); 107 assert(!b.test(123)); 108 assert(!b.clear(123)); 109 assert(!b.set(123)); 110 assert(b.test(123)); 111 assert(b.clear(123)); 112 assert(!b.test(123)); 113 114 b.set(785); 115 b.set(0); 116 assert(b.test(785)); 117 assert(b.test(0)); 118 b.zero(); 119 assert(!b.test(785)); 120 assert(!b.test(0)); 121 122 GCBits b2; 123 b2.alloc(786); 124 b2.set(38); 125 b.copy(&b2); 126 assert(b.test(38)); 127 b2.Dtor(); 128 b.Dtor(); 129 } 130