]> git.llucax.com Git - software/dgc/cdgc.git/blobdiff - rt/gc/cdgc/bits.d
Don't leak weak pointers
[software/dgc/cdgc.git] / rt / gc / cdgc / bits.d
index 4d2536275f2bd133217d5a639ca6ced3b1ba7971..7c06c83f4834751bcc39d28845a02367406299ec 100644 (file)
@@ -26,7 +26,8 @@
 
 module rt.gc.cdgc.bits;
 
 
 module rt.gc.cdgc.bits;
 
-import cstdlib = tango.stdc.stdlib;
+import os = rt.gc.cdgc.os;
+
 import cstring = tango.stdc.string;
 
 private extern (C) void onOutOfMemoryError();
 import cstring = tango.stdc.string;
 
 private extern (C) void onOutOfMemoryError();
@@ -60,15 +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
 
     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()
     {
     {
-        // Even when free() 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%.
+        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)
         {
         if (data)
         {
-            cstdlib.free(data);
+            os.dealloc(data, data_size, vis);
             data = null;
         }
     }
             data = null;
         }
     }
@@ -76,16 +83,15 @@ struct GCBits
     invariant
     {
         if (data)
     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;
     {
         this.nbits = nbits;
-        nwords = (nbits + (BITS_PER_WORD - 1)) >> BITS_SHIFT;
-        data = cast(uint*)cstdlib.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();
     }
         if (!data)
             onOutOfMemoryError();
     }
@@ -156,13 +162,24 @@ struct GCBits
 
     void zero()
     {
 
     void zero()
     {
-        version(MEMCPY_NON_SIG_SAFE) {
-            uint * d1=data+1,dEnd=d1+nwords;
-            for (;d1!=dEnd;++d1)
-                *d1=0u;
-        } else {
-            cstring.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)
     }
 
     void copy(GCBits *f)
@@ -172,13 +189,7 @@ struct GCBits
     }
     body
     {
     }
     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 {
-            cstring.memcpy(data + 1, f.data + 1, nwords * uint.sizeof);
-        }
+        cstring.memcpy(data + 1, f.data + 1, nwords * uint.sizeof);
     }
 
     uint* base()
     }
 
     uint* base()