Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Commit 13420ae

Browse files
committed
Modify gc_stats API to be able to select needed ones
1 parent 6f27f55 commit 13420ae

File tree

6 files changed

+92
-27
lines changed

6 files changed

+92
-27
lines changed

src/core/memory.d

Lines changed: 60 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ private
138138
}
139139

140140
extern (C) BlkInfo_ gc_query( void* p ) pure nothrow;
141-
extern (C) GC.Stats gc_stats ( ) nothrow @nogc;
141+
extern (C) GC.Stats gc_stats ( ulong fields ) nothrow @nogc;
142142

143143
extern (C) void gc_addRoot( in void* p ) nothrow @nogc;
144144
extern (C) void gc_addRange( in void* p, size_t sz, const TypeInfo ti = null ) nothrow @nogc;
@@ -170,6 +170,12 @@ struct GC
170170
size_t freeSize;
171171
}
172172

173+
/**
174+
* Auto-generated bitflag enum with values of identical names as `Stats`
175+
* struct. Optionally used to specify exact stats to calculate.
176+
*/
177+
mixin(generateFieldEnum!Stats);
178+
173179
/**
174180
* Enables automatic garbage collection behavior if collections have
175181
* previously been suspended by a call to disable. This function is
@@ -674,10 +680,16 @@ struct GC
674680
/**
675681
* Returns runtime stats for currently active GC implementation
676682
* See `core.memory.GC.Stats` for list of available metrics.
683+
*
684+
* Params:
685+
* fields = optional bit flag argument which specifies which stats need
686+
* to be calculated. By default equals to "all fields". If some field
687+
* was not requested via bit flag, its value in returned `Stats` struct
688+
* will be undefined.
677689
*/
678-
static Stats stats() nothrow
690+
static Stats stats(ulong fields = ulong.max) nothrow
679691
{
680-
return gc_stats();
692+
return gc_stats(fields);
681693
}
682694

683695
/**
@@ -1184,4 +1196,49 @@ unittest
11841196
assert(GC.addrOf(y.ptr) == null);
11851197
}
11861198

1199+
/**
1200+
For a given struct `S` generated bitflag enum with a value for each of
1201+
struct fields.
1202+
*/
1203+
private string generateFieldEnum(alias S)()
1204+
{
1205+
import core.internal.string;
1206+
1207+
string code = "enum " ~ __traits(identifier, S) ~ "Fields\n{\n";
1208+
ulong shift = 0;
1209+
char[3] buf;
1210+
1211+
foreach (idx, _; S.init.tupleof)
1212+
{
1213+
auto init = "1UL << " ~ unsignedToTempString(shift, buf);
1214+
code ~= __traits(identifier, S.tupleof[idx]) ~ " = " ~ init ~ ",\n";
1215+
++shift;
1216+
}
1217+
1218+
code ~= "}";
11871219

1220+
return code;
1221+
}
1222+
1223+
unittest
1224+
{
1225+
static struct Dummy
1226+
{
1227+
int a, b, c;
1228+
}
1229+
1230+
enum code = generateFieldEnum!Dummy();
1231+
1232+
static assert (code == "enum DummyFields
1233+
{
1234+
a = 1UL << 0,
1235+
b = 1UL << 1,
1236+
c = 1UL << 2,
1237+
}");
1238+
1239+
mixin(code);
1240+
1241+
assert(DummyFields.a == 1);
1242+
assert(DummyFields.b == 2);
1243+
assert(DummyFields.c == 4);
1244+
}

src/gc/gcinterface.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@ interface GC
146146
* Retrieve statistics about garbage collection.
147147
* Useful for debugging and tuning.
148148
*/
149-
core.memory.GC.Stats stats() nothrow;
149+
core.memory.GC.Stats stats(ulong fields) nothrow;
150150

151151
/**
152152
* add p to list of roots

src/gc/impl/conservative/gc.d

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1191,11 +1191,11 @@ class ConservativeGC : GC
11911191
}
11921192

11931193

1194-
core.memory.GC.Stats stats() nothrow
1194+
core.memory.GC.Stats stats(ulong fields) nothrow
11951195
{
11961196
typeof(return) ret;
11971197

1198-
runLocked!(getStatsNoSync, otherTime, numOthers)(ret);
1198+
runLocked!(getStatsNoSync, otherTime, numOthers)(ret, fields);
11991199

12001200
return ret;
12011201
}
@@ -1204,29 +1204,37 @@ class ConservativeGC : GC
12041204
//
12051205
//
12061206
//
1207-
private void getStatsNoSync(out core.memory.GC.Stats stats) nothrow
1207+
private void getStatsNoSync(out core.memory.GC.Stats stats, ulong fields) nothrow
12081208
{
1209-
foreach (pool; gcx.pooltable[0 .. gcx.npools])
1209+
alias Flags = core.memory.GC.StatsFields;
1210+
1211+
if ((fields & Flags.usedSize) || (fields & Flags.freeSize))
12101212
{
1211-
foreach (bin; pool.pagetable[0 .. pool.npages])
1213+
// calculates both if any is requested as it is part of the same
1214+
// iteration process
1215+
1216+
foreach (pool; gcx.pooltable[0 .. gcx.npools])
12121217
{
1213-
if (bin == B_FREE)
1214-
stats.freeSize += PAGESIZE;
1215-
else
1216-
stats.usedSize += PAGESIZE;
1218+
foreach (bin; pool.pagetable[0 .. pool.npages])
1219+
{
1220+
if (bin == B_FREE)
1221+
stats.freeSize += PAGESIZE;
1222+
else
1223+
stats.usedSize += PAGESIZE;
1224+
}
12171225
}
1218-
}
12191226

1220-
size_t freeListSize;
1221-
foreach (n; 0 .. B_PAGE)
1222-
{
1223-
immutable sz = binsize[n];
1224-
for (List *list = gcx.bucket[n]; list; list = list.next)
1225-
freeListSize += sz;
1226-
}
1227+
size_t freeListSize;
1228+
foreach (n; 0 .. B_PAGE)
1229+
{
1230+
immutable sz = binsize[n];
1231+
for (List *list = gcx.bucket[n]; list; list = list.next)
1232+
freeListSize += sz;
1233+
}
12271234

1228-
stats.usedSize -= freeListSize;
1229-
stats.freeSize += freeListSize;
1235+
stats.usedSize -= freeListSize;
1236+
stats.freeSize += freeListSize;
1237+
}
12301238
}
12311239
}
12321240

src/gc/impl/manual/gc.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ class ManualGC : GC
190190
return BlkInfo.init;
191191
}
192192

193-
core.memory.GC.Stats stats() nothrow
193+
core.memory.GC.Stats stats(ulong fields) nothrow
194194
{
195195
return typeof(return).init;
196196
}

src/gc/impl/proto/gc.d

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ class ProtoGC : GC
155155
return BlkInfo.init;
156156
}
157157

158-
core.memory.GC.Stats stats() nothrow
158+
core.memory.GC.Stats stats(ulong fields) nothrow
159159
{
160160
return typeof(return).init;
161161
}

src/gc/proxy.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,9 @@ extern (C)
184184
return instance.query( p );
185185
}
186186

187-
core.memory.GC.Stats gc_stats() nothrow
187+
core.memory.GC.Stats gc_stats(ulong fields) nothrow
188188
{
189-
return instance.stats();
189+
return instance.stats(fields);
190190
}
191191

192192
void gc_addRoot( void* p ) nothrow @nogc

0 commit comments

Comments
 (0)