]> git.llucax.com Git - software/dgc/cdgc.git/blobdiff - rt/gc/cdgc/gc.d
Sync the pool block size cache properly
[software/dgc/cdgc.git] / rt / gc / cdgc / gc.d
index f70227b5bd5a29c0722594d7a270932d9ad68848..e53d5d13b20e35ccc2c6eb1fb7c989d03a1a44c0 100644 (file)
@@ -615,7 +615,7 @@ void mark_range(void *pbot, void *ptop, size_t* pm_bitmask)
     void **p1 = cast(void **)pbot;
     void **p2 = cast(void **)ptop;
     size_t pcache = 0;
-    uint changes = 0;
+    bool changes = false;
 
     size_t type_size = pm_bitmask[0];
     size_t* pm_bits = pm_bitmask + 1;
@@ -641,7 +641,7 @@ void mark_range(void *pbot, void *ptop, size_t* pm_bitmask)
             if (pool)
             {
                 size_t offset = cast(size_t)(p - pool.baseAddr);
-                size_t bit_i;
+                size_t bit_i = void;
                 size_t pn = offset / PAGESIZE;
                 Bins   bin = cast(Bins)pool.pagetable[pn];
 
@@ -651,7 +651,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
@@ -670,7 +670,7 @@ void mark_range(void *pbot, void *ptop, size_t* pm_bitmask)
                     if (!pool.noscan.test(bit_i))
                     {
                         pool.scan.set(bit_i);
-                        changes = 1;
+                        changes = true;
                     }
                 }
             }
@@ -1432,10 +1432,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 +1456,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 +1572,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 +1620,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 +1900,18 @@ struct Pool
     size_t cached_size;
     void* cached_ptr;
 
-    void clear_cache()
+    void clear_cache(void* ptr = null)
     {
-        this.cached_ptr = null;
-        this.cached_size = 0;
+        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 = ptr;
+        this.cached_size = size;
     }
 
     void initialize(size_t npages)