]> git.llucax.com Git - software/dgc/cdgc.git/commitdiff
Add a one element cache to Pool.findSize()
authorLeandro Lucarella <llucax@gmail.com>
Mon, 2 Aug 2010 03:03:43 +0000 (00:03 -0300)
committerLeandro Lucarella <llucax@gmail.com>
Fri, 6 Aug 2010 01:28:50 +0000 (22:28 -0300)
Caching the last findSize() result for big objects gives a huge saving in
programs with a lot of array appending.

rt/gc/cdgc/gc.d

index 1df824cdaf38ff5a3baa911f7a9076250d60c285..b62d1bee948aad941e047f69ad5e1af95f376903 100644 (file)
@@ -939,6 +939,7 @@ size_t fullcollect(void *stackTop)
     for (n = 0; n < gc.pools.length; n++)
     {
         pool = gc.pools[n];
+        pool.clear_cache();
         uint*  bbase = pool.mark.base();
         size_t pn;
         for (pn = 0; pn < pool.npages; pn++, bbase += PAGESIZE / (32 * 16))
@@ -1842,6 +1843,15 @@ struct Pool
     size_t npages;
     ubyte* pagetable;
 
+    /// Cache for findSize()
+    size_t cached_size;
+    void* cached_ptr;
+
+    void clear_cache()
+    {
+        this.cached_ptr = null;
+        this.cached_size = 0;
+    }
 
     void initialize(size_t npages)
     {
@@ -1998,10 +2008,15 @@ struct Pool
         Bins bin = cast(Bins)this.pagetable[pagenum];
         if (bin != B_PAGE)
             return binsize[bin];
-        for (size_t i = pagenum + 1; i < this.npages; i++)
+        if (this.cached_ptr == p)
+            return this.cached_size;
+        size_t i = pagenum + 1;
+        for (; i < this.npages; i++)
             if (this.pagetable[i] != B_PAGEPLUS)
-                return (i - pagenum) * PAGESIZE;
-        return (this.npages - pagenum) * PAGESIZE;
+                break;
+        this.cached_ptr = p;
+        this.cached_size = (i - pagenum) * PAGESIZE;
+        return this.cached_size;
     }