Mercurial > projects > ldc
view lphobos/gc/gcbits.d @ 1404:11b122f92136
Now that templates instantiations are no longer emitted for all modules that
even blink at them they seem to break due to being linkonce (if compiled with
any optimization level > 0), so let's give them weak linkage instead.
The difference is that unreferenced linkonce symbols can be deleted, while
weak symbols need to be preserved.
author | Frits van Bommel <fvbommel wxs.nl> |
---|---|
date | Thu, 21 May 2009 15:23:28 +0200 |
parents | 373489eeaf90 |
children |
line wrap: on
line source
// Copyright (C) 2001-2002 by Digital Mars // All Rights Reserved // www.digitalmars.com // Written by Walter Bright /* NOTE: This file has been patched from the original DMD distribution to work with the GDC compiler. Modified by David Friedman, September 2004 */ import std.c.string; import std.c.stdlib; import std.outofmemory; import std.intrinsic; //version = Asm86; version (GNU) { // bitop intrinsics not implemented yet } else { version = bitops; } struct GCBits { const int BITS_PER_WORD = 32; const int BITS_SHIFT = 5; const int BITS_MASK = 31; uint *data = null; uint nwords = 0; // allocated words in data[] excluding sentinals uint nbits = 0; // number of bits in data[] excluding sentinals void Dtor() { if (data) { free(data); data = null; } } invariant { if (data) { assert(nwords * data[0].sizeof * 8 >= nbits); } } void alloc(uint nbits) { this.nbits = nbits; nwords = (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT; data = cast(uint *)calloc(nwords + 2, uint.sizeof); if (!data) _d_OutOfMemory(); } uint test(uint i) in { assert(i < nbits); } body { //return (cast(bit *)(data + 1))[i]; return data[1 + (i >> BITS_SHIFT)] & (1 << (i & BITS_MASK)); } void set(uint i) in { assert(i < nbits); } body { //(cast(bit *)(data + 1))[i] = 1; data[1 + (i >> BITS_SHIFT)] |= (1 << (i & BITS_MASK)); } void clear(uint i) in { assert(i < nbits); } body { //(cast(bit *)(data + 1))[i] = 0; data[1 + (i >> BITS_SHIFT)] &= ~(1 << (i & BITS_MASK)); } uint testClear(uint i) { version (bitops) { return std.intrinsic.btr(data + 1, i); } else version (Asm86) { asm { naked ; mov EAX,data[EAX] ; mov ECX,i-4[ESP] ; btr 4[EAX],ECX ; sbb EAX,EAX ; ret 4 ; } } 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; *p &= ~mask; return result; } } void zero() { memset(data + 1, 0, nwords * uint.sizeof); } void copy(GCBits *f) in { assert(nwords == f.nwords); } body { memcpy(data + 1, f.data + 1, nwords * uint.sizeof); } uint *base() in { assert(data); } body { return data + 1; } } 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); b.set(785); b.set(0); assert(b.test(785) != 0); assert(b.test(0) != 0); b.zero(); assert(b.test(785) == 0); assert(b.test(0) == 0); GCBits b2; b2.alloc(786); b2.set(38); b.copy(&b2); assert(b.test(38) != 0); b2.Dtor(); b.Dtor(); } /+ void main() { } +/