Skip to content

Commit e6a65a2

Browse files
committed
cgen: guard shared-library GC divisor tuning behind GC_is_init_called (#27555)
In a `-shared -gc boehm` library loaded into a process that already initialized Boehm (e.g. with GC_FREE_SPACE_DIVISOR=2), the library's GC_set_free_space_divisor ran before its own GC_INIT(), which is a no-op once GC is up and so never re-reads the env var. That silently clobbered the host's process-wide divisor and defeated the advertised env override. Only tune the divisor when the library is the one bringing up the collector. The main-executable path is unchanged: it owns its GC.
1 parent 18f4ad4 commit e6a65a2

2 files changed

Lines changed: 11 additions & 1 deletion

File tree

vlib/v/gen/c/cmain.v

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,13 @@ fn (mut g Gen) gen_shared_library_boehm_init() {
198198
if g.pref.gc_mode in [.boehm_full_opt, .boehm_incr_opt] {
199199
// See gen_boehm_gc_init: rarer stop-the-world pauses for the opt modes,
200200
// overridable via the `GC_FREE_SPACE_DIVISOR` env var (issue #27555).
201-
g.writeln('\tGC_set_free_space_divisor(1);')
201+
// Only tune when this library is the one bringing up the collector. If the
202+
// host process already initialized Boehm, the local GC_INIT() below is a
203+
// no-op that will not re-read the env var, so setting the divisor here would
204+
// silently override the host's process-wide value (and its env override).
205+
g.writeln('\tif (!GC_is_init_called()) {')
206+
g.writeln('\t\tGC_set_free_space_divisor(1);')
207+
g.writeln('\t}')
202208
}
203209
g.writeln('\tGC_INIT();')
204210
g.writeln('\tGC_register_displacement(sizeof(void*));')

vlib/v/gen/c/coutput_test.v

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,10 @@ fn test_user_defined_windows_dllmain_disables_generated_entrypoint() {
579579
ensure_compilation_succeeded(compilation, cmd)
580580
assert compilation.output.contains('void _vinit_caller() {')
581581
assert compilation.output.contains('GC_set_pages_executable(0);')
582+
// The shared-library GC tuning (issue #27555) must stay guarded, so loading
583+
// the library into an already-GC-initialized host does not clobber the host's
584+
// process-wide free-space divisor (its local GC_INIT() would be a no-op).
585+
assert compilation.output.contains('if (!GC_is_init_called()) {')
582586
assert compilation.output.contains('GC_INIT();')
583587
assert compilation.output.contains('DllMain(')
584588
assert compilation.output.contains('_vinit_caller();')

0 commit comments

Comments
 (0)