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

Commit 58b1e1f

Browse files
committed
GC cleanup can now be configured as a DRT GC option
1 parent 92d4916 commit 58b1e1f

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed

changelog/gc_cleanup.dd

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
GC cleanup can now be configured as a DRT GC option
2+
3+
The default cleanup method for the GC is to unconditionally run a
4+
collection before runtime termination to finalize objects
5+
that are still alive and hold resources that affect system state outside
6+
the current process. This combines the worst of possible alternatives:
7+
it can cause a considerable delay and does not guarantee finalization
8+
of all objects as roots might still exist.
9+
10+
The cleanup behaviour can now be configured by a DRT option to the
11+
$(LINK2 $(ROOT_DIR)spec/garbage.html, GC configuration),
12+
e.g. by passing `--DRT-gcopt=cleanup:none` on the command
13+
line. Three options are provided:
14+
15+
$(UL
16+
$(LI collect: run a collection (the default for backward compatibility))
17+
$(LI none: do nothing)
18+
$(LI finalize: all live objects are finalized unconditionally)
19+
)
20+
21+
As usual, you can also embed the configuration into the application by
22+
redefining `rt_options`, e.g.
23+
24+
-------
25+
extern(C) __gshared string[] rt_options = [ "gcopt=cleanup:none" ];
26+
-------

src/gc/config.d

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ struct Config
2323
size_t maxPoolSize = 64; // maximum pool size (MB)
2424
size_t incPoolSize = 3; // pool size increment (MB)
2525
float heapSizeFactor = 2.0; // heap size to used memory ratio
26+
string cleanup = "collect"; // select gc cleanup method none|collect|finalize
2627

2728
@nogc nothrow:
2829

@@ -43,6 +44,7 @@ struct Config
4344
maxPoolSize:N - maximum pool size in MB (%lld)
4445
incPoolSize:N - pool size increment MB (%lld)
4546
heapSizeFactor:N - targeted heap size to used memory ratio (%g)
47+
cleanup:none|collect|finalize - how to treat live objects when terminating (collect)
4648
";
4749
printf(s.ptr, disable, profile, cast(long)initReserve, cast(long)minPoolSize,
4850
cast(long)maxPoolSize, cast(long)incPoolSize, heapSizeFactor);

src/gc/proxy.d

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,20 +79,35 @@ extern (C)
7979

8080
void gc_term()
8181
{
82-
// NOTE: There may be daemons threads still running when this routine is
83-
// called. If so, cleaning memory out from under then is a good
84-
// way to make them crash horribly. This probably doesn't matter
85-
// much since the app is supposed to be shutting down anyway, but
86-
// I'm disabling cleanup for now until I can think about it some
87-
// more.
88-
//
89-
// NOTE: Due to popular demand, this has been re-enabled. It still has
90-
// the problems mentioned above though, so I guess we'll see.
91-
9282
if (isInstanceInit)
9383
{
94-
instance.collectNoStack(); // not really a 'collect all' -- still scans
95-
// static data area, roots, and ranges.
84+
switch (config.cleanup)
85+
{
86+
default:
87+
import core.stdc.stdio : fprintf, stderr;
88+
fprintf(stderr, "Unknown GC cleanup method, please recheck ('%.*s').\n",
89+
cast(int)config.cleanup.length, config.cleanup.ptr);
90+
break;
91+
case "none":
92+
break;
93+
case "collect":
94+
// NOTE: There may be daemons threads still running when this routine is
95+
// called. If so, cleaning memory out from under then is a good
96+
// way to make them crash horribly. This probably doesn't matter
97+
// much since the app is supposed to be shutting down anyway, but
98+
// I'm disabling cleanup for now until I can think about it some
99+
// more.
100+
//
101+
// NOTE: Due to popular demand, this has been re-enabled. It still has
102+
// the problems mentioned above though, so I guess we'll see.
103+
104+
instance.collectNoStack(); // not really a 'collect all' -- still scans
105+
// static data area, roots, and ranges.
106+
break;
107+
case "finalize":
108+
instance.runFinalizers((cast(ubyte*)null)[0 .. size_t.max]);
109+
break;
110+
}
96111

97112
ManualGC.finalize(instance);
98113
ConservativeGC.finalize(instance);

0 commit comments

Comments
 (0)