]> git.llucax.com Git - software/dgc/cdgc.git/blobdiff - rt/gc/cdgc/stats.d
stats: Add more type information to malloc logging
[software/dgc/cdgc.git] / rt / gc / cdgc / stats.d
index 562d955467df1cc7e288255f4475718c08160308..036d748c5d9f03d8419aec9106eb2c85e982fdf0 100644 (file)
@@ -123,12 +123,16 @@ struct MallocInfo
     double timestamp = -1.0;
     /// Time spent in the malloc() call (in seconds).
     double time = -1.0;
+    /// Address of the pointer returned by malloc.
+    void* ptr = null;
     /// Memory requested by the malloc() call (in bytes).
     size_t size = 0;
     /// Memory attributes as BlkAttr flags.
     uint attr = 0;
     /// True if this malloc() triggered a collection.
     bool collected = false;
+    /// Address of the pointer map bitmask.
+    size_t* ptrmap = null;
 }
 
 
@@ -202,12 +206,12 @@ private:
                 if (bin < .gc.B_PAGE)
                 {
                     size_t size = .gc.binsize[bin];
-                    size_t bitstride = size / 16;
-                    size_t bitbase = pn * (.gc.PAGESIZE / 16);
-                    size_t bittop = bitbase + (.gc.PAGESIZE / 16);
-                    for (auto biti = bitbase; biti < bittop; biti += bitstride)
+                    size_t attrstride = size / 16;
+                    size_t attrbase = pn * (.gc.PAGESIZE / 16);
+                    size_t attrtop = attrbase + (.gc.PAGESIZE / 16);
+                    for (auto attri = attrbase; attri < attrtop; attri += attrstride)
                     {
-                        if (pool.freebits.test(biti))
+                        if (pool.freebits.test(attri))
                             mem_info.free += size;
                         else
                             mem_info.used += size; // TODO: wasted
@@ -233,16 +237,27 @@ private:
     {
         if (this.mallocs_file is null)
             return;
+        auto ptrmap = this.malloc_info.ptrmap;
+        auto ptrmask_offset = (ptrmap[0] - 1) / (size_t.sizeof * 8) + 1;
         cstdio.fprintf(this.mallocs_file,
-                "%f,%f,%zu,%zu,%zu,%zu,%zu\n",
-                //0  1   2   3   4   5   6
+                "%f,%f,%p,%zu,%zu,%zu,%zu,%zu,%p,%zu,%0*zX,%0*zX\n",
+                //0  1   2   3   4   5   6  7  8   9    10    11
                 this.malloc_info.timestamp,                   // 0
                 this.malloc_info.time,                        // 1
-                this.malloc_info.size,                        // 2
-                this.malloc_info.collected ? 1u : 0u,         // 3
-                this.malloc_info.attr & .gc.BlkAttr.FINALIZE, // 4
-                this.malloc_info.attr & .gc.BlkAttr.NO_SCAN,  // 5
-                this.malloc_info.attr & .gc.BlkAttr.NO_MOVE); // 6
+                this.malloc_info.ptr,                         // 2
+                this.malloc_info.size,                        // 3
+                this.malloc_info.collected ? 1u : 0u,         // 4
+                this.malloc_info.attr & .gc.BlkAttr.FINALIZE, // 5
+                this.malloc_info.attr & .gc.BlkAttr.NO_SCAN,  // 6
+                this.malloc_info.attr & .gc.BlkAttr.NO_MOVE,  // 7
+                ptrmap,                                       // 8
+                ptrmap[0] * size_t.sizeof,                    // 9
+                size_t.sizeof,                                // fill length
+                ptrmap[1],                                    // 10
+                size_t.sizeof,                                // fill length
+                ptrmap[1 + ptrmask_offset]);                  // 11
+        // TODO: make it an option
+        cstdio.fflush(this.mallocs_file);
     }
 
     void print_collection()
@@ -264,6 +279,8 @@ private:
                 this.collection_info.after.free,          // 9
                 this.collection_info.after.wasted,        // 10
                 this.collection_info.after.overhead);     // 11
+        // TODO: make it an option
+        cstdio.fflush(this.collections_file);
     }
 
 
@@ -284,8 +301,10 @@ public:
             this_.active = true;
             this_.mallocs_file = this_.start_file(
                     options.malloc_stats_file.ptr,
-                    "Timestamp,Time,Size,Collection triggered,"
-                    "Finalize,No scan,No move\n");
+                    "Timestamp,Time,Pointer,Size,Collection triggered,"
+                    "Finalize,No scan,No move,Pointer map,Type size,"
+                    "Pointer map scan bitmask (first word, hexa),"
+                    "Pointer map pointer bitmask (first word, hexa)\n");
         }
         // collection
         if (options.collect_stats_file[0] != '\0') {
@@ -309,7 +328,8 @@ public:
     }
 
     /// Inform the start of an allocation.
-    void malloc_started(size_t size, uint attr)
+    // TODO: store/use type information
+    void malloc_started(size_t size, uint attr, size_t* ptrmap_bitmask)
     {
         if (!this.active)
             return;
@@ -321,6 +341,7 @@ public:
         this.malloc_info.time = now;
         this.malloc_info.size = size;
         this.malloc_info.attr = attr;
+        this.malloc_info.ptrmap = ptrmap_bitmask;
         // this.malloc_info.collected is filled in malloc_finished()
         // collection
         this.collection_info = this.collection_info.init;
@@ -329,7 +350,7 @@ public:
     }
 
     /// Inform the end of an allocation.
-    void malloc_finished()
+    void malloc_finished(void* ptr)
     {
         if (!this.active)
             return;
@@ -339,6 +360,7 @@ public:
         this.malloc_info.time = now - this.malloc_info.time;
         if (collected)
             this.malloc_info.collected = true;
+        this.malloc_info.ptr = ptr;
         this.print_malloc();
         if (!collected)
             return;