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

Commit e1fb198

Browse files
tim-dlangdlang-bot
authored andcommitted
Fix issue 21070: -profile=gc makes the program much slower
Replacing the call to GC.stats with a new function, which only returns the needed information, makes the program fast again.
1 parent f777cfb commit e1fb198

File tree

9 files changed

+69
-2
lines changed

9 files changed

+69
-2
lines changed

changelog/faster_profilegc.dd

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
`core.memory.GC.allocatedInCurrentThread()` was added, which makes `-profile=gc` faster
2+
3+
The new function `core.memory.GC.allocatedInCurrentThread()` returns
4+
the same as `core.memory.GC.stats().allocatedInCurrentThread`, but
5+
is faster, because it avoids calculating other statistics.
6+
It is used for `-profile=gc` and makes it faster, too.

src/core/gc/gcinterface.d

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,4 +188,11 @@ interface GC
188188
*
189189
*/
190190
bool inFinalizer() nothrow @nogc @safe;
191+
192+
/**
193+
* Returns the number of bytes allocated for the current thread
194+
* since program start. It is the same as
195+
* GC.stats().allocatedInCurrentThread, but faster.
196+
*/
197+
ulong allocatedInCurrentThread() nothrow;
191198
}

src/core/memory.d

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ private
151151
extern (C) BlkInfo_ gc_query( void* p ) pure nothrow;
152152
extern (C) GC.Stats gc_stats ( ) nothrow @nogc;
153153
extern (C) GC.ProfileStats gc_profileStats ( ) nothrow @nogc @safe;
154+
extern (C) ulong gc_allocatedInCurrentThread( ) nothrow;
154155

155156
extern (C) void gc_addRoot(const void* p ) nothrow @nogc;
156157
extern (C) void gc_addRange(const void* p, size_t sz, const TypeInfo ti = null ) nothrow @nogc;
@@ -1045,6 +1046,32 @@ struct GC
10451046
r.destroy;
10461047
assert(Resource.outcome == Outcome.calledManually);
10471048
}
1049+
1050+
/**
1051+
* Returns the number of bytes allocated for the current thread
1052+
* since program start. It is the same as
1053+
* GC.stats().allocatedInCurrentThread, but faster.
1054+
*/
1055+
static ulong allocatedInCurrentThread() nothrow
1056+
{
1057+
return gc_allocatedInCurrentThread();
1058+
}
1059+
1060+
/// Using allocatedInCurrentThread
1061+
nothrow unittest
1062+
{
1063+
ulong currentlyAllocated = GC.allocatedInCurrentThread();
1064+
struct DataStruct
1065+
{
1066+
long l1;
1067+
long l2;
1068+
long l3;
1069+
long l4;
1070+
}
1071+
DataStruct* unused = new DataStruct;
1072+
assert(GC.allocatedInCurrentThread() == currentlyAllocated + 32);
1073+
assert(GC.stats().allocatedInCurrentThread == currentlyAllocated + 32);
1074+
}
10481075
}
10491076

10501077
/**

src/gc/impl/conservative/gc.d

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,13 @@ class ConservativeGC : GC
10751075
return ret;
10761076
}
10771077

1078+
1079+
ulong allocatedInCurrentThread() nothrow
1080+
{
1081+
return bytesAllocated;
1082+
}
1083+
1084+
10781085
//
10791086
//
10801087
//

src/gc/impl/manual/gc.d

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,4 +272,9 @@ class ManualGC : GC
272272
{
273273
return false;
274274
}
275+
276+
ulong allocatedInCurrentThread() nothrow
277+
{
278+
return typeof(return).init;
279+
}
275280
}

src/gc/impl/proto/gc.d

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,9 @@ class ProtoGC : GC
240240
{
241241
return false;
242242
}
243+
244+
ulong allocatedInCurrentThread() nothrow
245+
{
246+
return stats().allocatedInCurrentThread;
247+
}
243248
}

src/gc/proxy.d

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,11 @@ extern (C)
253253
return instance.inFinalizer();
254254
}
255255

256+
ulong gc_allocatedInCurrentThread() nothrow
257+
{
258+
return instance.allocatedInCurrentThread();
259+
}
260+
256261
GC gc_getProxy() nothrow
257262
{
258263
return instance;

src/rt/tracegc.d

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,11 @@ enum accumulator = q{
7878
);
7979
}
8080

81-
ulong currentlyAllocated = GC.stats().allocatedInCurrentThread;
81+
ulong currentlyAllocated = GC.allocatedInCurrentThread;
8282

8383
scope(exit)
8484
{
85-
ulong size = GC.stats().allocatedInCurrentThread - currentlyAllocated;
85+
ulong size = GC.allocatedInCurrentThread - currentlyAllocated;
8686
if (size > 0)
8787
accumulate(file, line, funcname, name, size);
8888
}

test/init_fini/src/custom_gc.d

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,11 @@ nothrow @nogc:
173173
return false;
174174
}
175175

176+
ulong allocatedInCurrentThread() nothrow
177+
{
178+
return stats().allocatedInCurrentThread;
179+
}
180+
176181
private:
177182
// doesn't care for alignment
178183
static void* sentinelAdd(void* p, size_t value)

0 commit comments

Comments
 (0)