Skip to content

Commit bc50120

Browse files
committed
[GR-44043] Avoid storing the RubyLanguage Cleaner in image heap for SVM
PullRequest: truffleruby/3644
2 parents 04fd96a + a3e9b02 commit bc50120

File tree

1 file changed

+38
-3
lines changed

1 file changed

+38
-3
lines changed

src/main/java/org/truffleruby/RubyLanguage.java

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,7 @@ private RubyThread getOrCreateForeignThread(RubyContext context, Thread thread)
231231

232232
@CompilationFinal public boolean singleContext = true;
233233
@CompilationFinal public Optional<RubyContext> contextIfSingleContext;
234+
private int numberOfContexts = 0;
234235

235236
public final CyclicAssumption traceFuncUnusedAssumption = new CyclicAssumption("set_trace_func is not used");
236237

@@ -245,8 +246,10 @@ private RubyThread getOrCreateForeignThread(RubyContext context, Thread thread)
245246
public final SymbolTable symbolTable;
246247
public final KeywordArgumentsDescriptorManager keywordArgumentsDescriptorManager = new KeywordArgumentsDescriptorManager();
247248
public final FrozenStringLiterals frozenStringLiterals;
248-
public final Cleaner cleaner = Cleaner.create();
249249

250+
// GR-44025: We store the cleanerThread explicitly here to make it a clear image building failure if it would still be set.
251+
public Thread cleanerThread = null;
252+
@CompilationFinal public Cleaner cleaner = null;
250253

251254
public volatile ValueWrapperManager.HandleBlockWeakReference[] handleBlockSharedMap = new ValueWrapperManager.HandleBlockWeakReference[0];
252255
public final ValueWrapperManager.HandleBlockAllocator handleBlockAllocator = new ValueWrapperManager.HandleBlockAllocator();
@@ -422,6 +425,9 @@ public RubyContext createContext(Env env) {
422425
Metrics.initializeOption();
423426

424427
synchronized (this) {
428+
numberOfContexts++;
429+
setupCleaner();
430+
425431
if (this.options == null) { // First context
426432
this.allocationReporter = env.lookup(AllocationReporter.class);
427433
this.options = new LanguageOptions(env, env.getOptions(), singleContext);
@@ -461,8 +467,12 @@ protected void initializeContext(RubyContext context) {
461467
try {
462468
Metrics.printTime("before-initialize-context");
463469
context.initialize();
470+
464471
if (context.isPreInitializing()) {
465-
setRubyHome(context.getEnv(), null);
472+
synchronized (this) {
473+
setRubyHome(context.getEnv(), null);
474+
resetCleaner();
475+
}
466476
}
467477
Metrics.printTime("after-initialize-context");
468478
} catch (Throwable e) {
@@ -493,7 +503,10 @@ protected boolean patchContext(RubyContext context, Env newEnv) {
493503
return false;
494504
}
495505

496-
setRubyHome(newEnv, findRubyHome());
506+
synchronized (this) {
507+
setRubyHome(newEnv, findRubyHome());
508+
setupCleaner();
509+
}
497510

498511
boolean patched = context.patchContext(newEnv);
499512
Metrics.printTime("after-patch-context");
@@ -514,6 +527,14 @@ protected void disposeContext(RubyContext context) {
514527
if (options.COVERAGE_GLOBAL) {
515528
coverageManager.print(this, System.out);
516529
}
530+
531+
synchronized (this) {
532+
// GR-28354: Workaround for no "before CacheStore hook"
533+
numberOfContexts--;
534+
if (numberOfContexts == 0 && !singleContext) {
535+
resetCleaner();
536+
}
537+
}
517538
}
518539

519540
public static RubyContext getCurrentContext() {
@@ -653,6 +674,19 @@ protected Object getScope(RubyContext context) {
653674
return context.getTopScopeObject();
654675
}
655676

677+
private void setupCleaner() {
678+
assert Thread.holdsLock(this);
679+
if (cleaner == null) {
680+
cleaner = Cleaner.create(runnable -> this.cleanerThread = new Thread(runnable, "Ruby-Cleaner"));
681+
}
682+
}
683+
684+
private void resetCleaner() {
685+
assert Thread.holdsLock(this);
686+
cleanerThread = null;
687+
cleaner = null;
688+
}
689+
656690
public String getRubyHome() {
657691
return rubyHome;
658692
}
@@ -671,6 +705,7 @@ public String getPathRelativeToHome(String path) {
671705
}
672706

673707
private void setRubyHome(Env env, String home) {
708+
assert Thread.holdsLock(this);
674709
rubyHome = home;
675710
setRubyHomeTruffleFile(env, home);
676711
}

0 commit comments

Comments
 (0)