]> git.llucax.com Git - software/dgc/cdgc.git/blobdiff - rt/gc/cdgc/gc.d
Avoid output duplication because of FILE* buffers
[software/dgc/cdgc.git] / rt / gc / cdgc / gc.d
index 3122215731cf726809ed8ac9abef0ad0ed5ba5f0..96c6a86360d24277f0456ea9038f17580f90864d 100644 (file)
@@ -50,6 +50,7 @@ import opts = rt.gc.cdgc.opts;
 
 import cstdlib = tango.stdc.stdlib;
 import cstring = tango.stdc.string;
+import cstdio = tango.stdc.stdio;
 
 /*
  * This is a small optimization that proved it's usefulness. For small chunks
@@ -307,6 +308,8 @@ BlkInfo getInfo(void* p)
         return BlkInfo.init;
     BlkInfo info;
     info.base = pool.findBase(p);
+    if (info.base is null)
+        return BlkInfo.init;
     info.size = pool.findSize(info.base);
     info.attr = getAttr(pool, cast(size_t)(info.base - pool.baseAddr) / 16u);
     if (has_pointermap(info.attr)) {
@@ -651,7 +654,7 @@ void mark_range(void *pbot, void *ptop, size_t* pm_bitmask)
 
                 // Adjust bit to be at start of allocated memory block
                 if (bin <= B_PAGE)
-                    bit_i = (offset & notbinsize[bin]) >> 4;
+                    bit_i = (offset & notbinsize[bin]) / 16;
                 else if (bin == B_PAGEPLUS)
                 {
                     do
@@ -784,6 +787,7 @@ size_t fullcollect(void *stackTop)
     gc.stats.world_stopped();
 
     if (opts.options.fork) {
+        cstdio.fflush(null); // avoid duplicated FILE* output
         os.pid_t child_pid = os.fork();
         assert (child_pid != -1); // don't accept errors in non-release mode
         switch (child_pid) {
@@ -822,9 +826,6 @@ void mark(void *stackTop)
 {
     debug(COLLECT_PRINTF) printf("\tmark()\n");
 
-    gc.p_cache = null;
-    gc.size_cache = 0;
-
     gc.any_changes = false;
     for (size_t n = 0; n < gc.pools.length; n++)
     {
@@ -970,6 +971,8 @@ size_t sweep()
 {
     // Free up everything not marked
     debug(COLLECT_PRINTF) printf("\tsweep\n");
+    gc.p_cache = null;
+    gc.size_cache = 0;
     size_t freedpages = 0;
     size_t freed = 0;
     for (size_t n = 0; n < gc.pools.length; n++)
@@ -999,7 +1002,7 @@ version(none) // BUG: doesn't work because freebits() must also be cleared
                 {
                     for (; p < ptop; p += size, bit_i += bit_stride)
                     {
-                        if (pool.finals.nbits && pool.finals.testClear(bit_i)) {
+                        if (pool.finals.testClear(bit_i)) {
                             if (opts.options.sentinel)
                                 rt_finalize(sentinel_add(p), false/*gc.no_stack > 0*/);
                             else
@@ -1023,7 +1026,7 @@ version(none) // BUG: doesn't work because freebits() must also be cleared
                             sentinel_Invariant(sentinel_add(p));
 
                         pool.freebits.set(bit_i);
-                        if (pool.finals.nbits && pool.finals.testClear(bit_i)) {
+                        if (pool.finals.testClear(bit_i)) {
                             if (opts.options.sentinel)
                                 rt_finalize(sentinel_add(p), false/*gc.no_stack > 0*/);
                             else
@@ -1046,7 +1049,7 @@ version(none) // BUG: doesn't work because freebits() must also be cleared
                     byte *p = pool.baseAddr + pn * PAGESIZE;
                     if (opts.options.sentinel)
                         sentinel_Invariant(sentinel_add(p));
-                    if (pool.finals.nbits && pool.finals.testClear(bit_i)) {
+                    if (pool.finals.testClear(bit_i)) {
                         if (opts.options.sentinel)
                             rt_finalize(sentinel_add(p), false/*gc.no_stack > 0*/);
                         else
@@ -1149,14 +1152,11 @@ in
 body
 {
     uint attrs;
-
-    if (pool.finals.nbits &&
-        pool.finals.test(bit_i))
+    if (pool.finals.test(bit_i))
         attrs |= BlkAttr.FINALIZE;
     if (pool.noscan.test(bit_i))
         attrs |= BlkAttr.NO_SCAN;
-//        if (pool.nomove.nbits &&
-//            pool.nomove.test(bit_i))
+//        if (pool.nomove.test(bit_i))
 //            attrs |= BlkAttr.NO_MOVE;
     return attrs;
 }
@@ -1174,8 +1174,6 @@ body
 {
     if (mask & BlkAttr.FINALIZE)
     {
-        if (!pool.finals.nbits)
-            pool.finals.alloc(pool.mark.nbits);
         pool.finals.set(bit_i);
     }
     if (mask & BlkAttr.NO_SCAN)
@@ -1201,7 +1199,7 @@ in
 }
 body
 {
-    if (mask & BlkAttr.FINALIZE && pool.finals.nbits)
+    if (mask & BlkAttr.FINALIZE)
         pool.finals.clear(bit_i);
     if (mask & BlkAttr.NO_SCAN)
         pool.noscan.clear(bit_i);
@@ -1432,10 +1430,13 @@ private void *realloc(void *p, size_t size, uint attrs,
                         memset(p + size - pm_bitmask_size, 0xF2,
                                 blk_size - size - pm_bitmask_size);
                     pool.freePages(pagenum + newsz, psz - newsz);
+                    auto new_blk_size = (PAGESIZE * newsz);
+                    // update the size cache, assuming that is very likely the
+                    // size of this block will be queried in the near future
+                    pool.update_cache(p, new_blk_size);
                     if (has_pm) {
-                        auto end_of_blk = cast(size_t**)(
-                                blk_base_addr + (PAGESIZE * newsz) -
-                                pm_bitmask_size);
+                        auto end_of_blk = cast(size_t**)(blk_base_addr +
+                                new_blk_size - pm_bitmask_size);
                         *end_of_blk = pm_bitmask;
                     }
                     return p;
@@ -1453,10 +1454,14 @@ private void *realloc(void *p, size_t size, uint attrs,
                                         - pm_bitmask_size);
                             memset(pool.pagetable + pagenum +
                                     psz, B_PAGEPLUS, newsz - psz);
+                            auto new_blk_size = (PAGESIZE * newsz);
+                            // update the size cache, assuming that is very
+                            // likely the size of this block will be queried in
+                            // the near future
+                            pool.update_cache(p, new_blk_size);
                             if (has_pm) {
                                 auto end_of_blk = cast(size_t**)(
-                                        blk_base_addr +
-                                        (PAGESIZE * newsz) -
+                                        blk_base_addr + new_blk_size -
                                         pm_bitmask_size);
                                 *end_of_blk = pm_bitmask;
                             }
@@ -1565,6 +1570,9 @@ body
     memset(pool.pagetable + pagenum + psz, B_PAGEPLUS, sz);
     gc.p_cache = null;
     gc.size_cache = 0;
+    // update the size cache, assuming that is very likely the size of this
+    // block will be queried in the near future
+    pool.update_cache(p, new_size);
 
     if (has_pm) {
         new_size -= size_t.sizeof;
@@ -1610,6 +1618,8 @@ private void free(void *p)
         if (opts.options.mem_stomp)
             memset(p, 0xF2, npages * PAGESIZE);
         pool.freePages(pagenum, npages);
+        // just in case we were caching this pointer
+        pool.clear_cache(p);
     }
     else
     {
@@ -1888,10 +1898,18 @@ struct Pool
     size_t cached_size;
     void* cached_ptr;
 
-    void clear_cache()
+    void clear_cache(void* ptr = null)
+    {
+        if (ptr is null || ptr is this.cached_ptr) {
+            this.cached_ptr = null;
+            this.cached_size = 0;
+        }
+    }
+
+    void update_cache(void* ptr, size_t size)
     {
-        this.cached_ptr = null;
-        this.cached_size = 0;
+        this.cached_ptr = ptr;
+        this.cached_size = size;
     }
 
     void initialize(size_t npages)