From c55983ced7d01676c68f4a4aaf33e0f9fc4dd23a Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Wed, 20 Nov 2024 20:26:50 +0100 Subject: [PATCH 1/5] Implement Truffle compiler control based on HotSpot's CompileBroker compilation activity --- .../compiler/TruffleCompilerRuntime.java | 27 +++++++++++++ .../runtime/OptimizedRuntimeOptions.java | 8 ++++ .../runtime/OptimizedTruffleRuntime.java | 40 ++++++++++++++++++- .../hotspot/HotSpotTruffleRuntime.java | 29 ++++++++++++++ 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java b/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java index ba144087f576..55a84938bdf1 100644 --- a/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java +++ b/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java @@ -359,4 +359,31 @@ default ResolvedJavaType resolveType(MetaAccessProvider metaAccess, String class */ boolean isSuppressedFailure(TruffleCompilable compilable, Supplier serializedException); + /** + * Represents HotSpot's compilation activity mode which is one of: + * {@code stop_compilation = 0}, {@code run_compilation = 1} or {@code shutdown_compilation = 2} + * Should be in sync with the {@code CompilerActivity} enum in {@code hotspot/share/compiler/compileBroker.hpp} + */ + enum CompilationActivityMode { + STOP_COMPILATION, + RUN_COMPILATION, + SHUTDOWN_COMPILATION; + + static public CompilationActivityMode fromInteger(int i) { + return switch (i) { + case 0 -> STOP_COMPILATION; + case 1 -> RUN_COMPILATION; + case 2 -> SHUTDOWN_COMPILATION; + default -> throw new RuntimeException("Invalid CompilationActivityMode " + i); + }; + } + } + + /** + * Returns the current host compilation activity mode which is one of: + * {@code STOP_COMPILATION}, {@code RUN_COMPILATION} or {@code SHUTDOWN_COMPILATION} + */ + default CompilationActivityMode getCompilationActivityMode() { + return CompilationActivityMode.RUN_COMPILATION; + } } diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java index 63cc586ba584..d99768259e4b 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java @@ -158,6 +158,14 @@ public ExceptionAction apply(String s) { // TODO: GR-29949 public static final OptionKey CompilerIdleDelay = new OptionKey<>(10000L); + @Option(help = "Before the Truffle runtime submits an OptimizedCallTarget for compilation, it checks for the " + + "compilation activity mode in the host VM. If the activity mode is 'STOP_COMPILATION' because " + + "of a full code cache, no new compilation requests are submitted and the compilation queue is flushed. " + + "After 'StoppedCompilationRetryDelay' milliseconds new compilations will be submitted again " + + "(which might trigger a sweep of the code cache and a reset of the compilation activity mode in the host JVM).", + usageSyntax = "", category = OptionCategory.EXPERT) + public static final OptionKey StoppedCompilationRetryDelay = new OptionKey<>(1000L); + @Option(help = "Manually set the number of compiler threads. By default, the number of compiler threads is scaled with the number of available cores on the CPU.", usageSyntax = "[1, inf)", category = OptionCategory.EXPERT, // stability = OptionStability.STABLE, sandbox = SandboxPolicy.UNTRUSTED) // public static final OptionKey CompilerThreads = new OptionKey<>(-1); diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java index 41bf7d063756..24f55428b7dd 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java @@ -41,6 +41,7 @@ package com.oracle.truffle.runtime; import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.CompilerIdleDelay; +import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.StoppedCompilationRetryDelay; import java.io.CharArrayWriter; import java.io.PrintWriter; @@ -912,10 +913,45 @@ private void notifyCompilationFailure(OptimizedCallTarget callTarget, Throwable protected void onEngineCreated(EngineData engine) { } + private long stoppedCompilationTime = 0; + private boolean logShutdownCompilations = true; + @SuppressWarnings("try") public CompilationTask submitForCompilation(OptimizedCallTarget optimizedCallTarget, boolean lastTierCompilation) { - Priority priority = new Priority(optimizedCallTarget.getCallAndLoopCount(), lastTierCompilation ? Priority.Tier.LAST : Priority.Tier.FIRST); - return getCompileQueue().submitCompilation(priority, optimizedCallTarget); + BackgroundCompileQueue queue = getCompileQueue(); + CompilationActivityMode compilationActivityMode = getCompilationActivityMode(); + if (compilationActivityMode == CompilationActivityMode.RUN_COMPILATION || + (stoppedCompilationTime != 0 && System.currentTimeMillis() - stoppedCompilationTime > optimizedCallTarget.getOptionValue(StoppedCompilationRetryDelay))) { + stoppedCompilationTime = 0; + Priority priority = new Priority(optimizedCallTarget.getCallAndLoopCount(), lastTierCompilation ? Priority.Tier.LAST : Priority.Tier.FIRST); + return queue.submitCompilation(priority, optimizedCallTarget); + } else if (compilationActivityMode == CompilationActivityMode.STOP_COMPILATION) { + if (stoppedCompilationTime == 0) { + stoppedCompilationTime = System.currentTimeMillis(); + } + // Flush the compilations queue. There's still a chance that compilation will be re-enabled + // eventually, if the hosts code cache can be cleaned up. + for (OptimizedCallTarget target : queue.getQueuedTargets(optimizedCallTarget.engine)) { + target.cancelCompilation("Compilation temporary disabled due to full code cache."); + } + } else { + // Compilation was shut down permanently because the hosts code cache ran full and + // the host was configured without support for code cache sweeping. + assert compilationActivityMode == CompilationActivityMode.SHUTDOWN_COMPILATION; + TruffleLogger logger = optimizedCallTarget.engine.getLogger("engine"); + // The logger can be null if the engine is closed. + if (logger != null && logShutdownCompilations) { + logShutdownCompilations = false; + logger.log(Level.WARNING, "Truffle host compilations permanently disabled because of full code cache. " + + "Increase the code cache size using '-XX:ReservedCodeCacheSize=' and/or run with '-XX:+UseCodeCacheFlushing -XX:+MethodFlushing'."); + } + try { + queue.shutdownAndAwaitTermination(100 /* milliseconds */); + } catch (RuntimeException re) { + // Best effort, ignore failure + } + } + return null; } @SuppressWarnings("all") diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java index c49fab962417..41c0d9856ea7 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java @@ -40,6 +40,9 @@ */ package com.oracle.truffle.runtime.hotspot; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; import java.lang.ref.Reference; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -692,4 +695,30 @@ public boolean isLibGraalCompilationEnabled() { return compilationSupport instanceof LibGraalTruffleCompilationSupport; } + static MethodHandle getCompilationActivityMode; + static { + try { + MethodType mt = MethodType.methodType(int.class); + getCompilationActivityMode = MethodHandles.lookup().findVirtual(HotSpotJVMCIRuntime.class, "getCompilationActivityMode", mt); + } catch (NoSuchMethodException | IllegalAccessException e) { + // Older JVMCI runtimes might not support `getCompilationActivityMode()` + } + } + + /** + * Returns the current host compilation activity mode which is one of: + * {@code stop_compilation = 0}, {@code run_compilation = 1} or {@code shutdown_compilation = 2} + */ + @Override + public CompilationActivityMode getCompilationActivityMode() { + int activityMode = 1; // Default is to run compilations + if (getCompilationActivityMode != null) { + try { + activityMode = (int) getCompilationActivityMode.invokeExact(HotSpotJVMCIRuntime.runtime()); + } catch (Throwable t) { + // Ignore and go with the default mode + } + } + return CompilationActivityMode.fromInteger(activityMode); + } } From 4208437adee23c3c02ba5d9537b29353aa910103 Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Mon, 25 Nov 2024 15:55:01 +0100 Subject: [PATCH 2/5] Updated according to reviewer's requests --- .../compiler/TruffleCompilerRuntime.java | 28 ------- .../runtime/BackgroundCompileQueue.java | 5 +- .../oracle/truffle/runtime/EngineData.java | 3 + .../truffle/runtime/OptimizedCallTarget.java | 62 +++++++++++++++ .../runtime/OptimizedRuntimeOptions.java | 7 +- .../runtime/OptimizedTruffleRuntime.java | 78 ++++++++++--------- .../hotspot/HotSpotTruffleRuntime.java | 11 +-- 7 files changed, 120 insertions(+), 74 deletions(-) diff --git a/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java b/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java index 55a84938bdf1..75669f9ac3c7 100644 --- a/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java +++ b/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java @@ -358,32 +358,4 @@ default ResolvedJavaType resolveType(MetaAccessProvider metaAccess, String class * silent. */ boolean isSuppressedFailure(TruffleCompilable compilable, Supplier serializedException); - - /** - * Represents HotSpot's compilation activity mode which is one of: - * {@code stop_compilation = 0}, {@code run_compilation = 1} or {@code shutdown_compilation = 2} - * Should be in sync with the {@code CompilerActivity} enum in {@code hotspot/share/compiler/compileBroker.hpp} - */ - enum CompilationActivityMode { - STOP_COMPILATION, - RUN_COMPILATION, - SHUTDOWN_COMPILATION; - - static public CompilationActivityMode fromInteger(int i) { - return switch (i) { - case 0 -> STOP_COMPILATION; - case 1 -> RUN_COMPILATION; - case 2 -> SHUTDOWN_COMPILATION; - default -> throw new RuntimeException("Invalid CompilationActivityMode " + i); - }; - } - } - - /** - * Returns the current host compilation activity mode which is one of: - * {@code STOP_COMPILATION}, {@code RUN_COMPILATION} or {@code SHUTDOWN_COMPILATION} - */ - default CompilationActivityMode getCompilationActivityMode() { - return CompilationActivityMode.RUN_COMPILATION; - } } diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BackgroundCompileQueue.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BackgroundCompileQueue.java index bd4009f37cfa..3dd4faa630b0 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BackgroundCompileQueue.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BackgroundCompileQueue.java @@ -218,7 +218,8 @@ public int getQueueSize() { /** * Return call targets waiting in queue. This does not include call targets currently being - * compiled. + * compiled. If {@code engine} is {@code null}, the call targets for all engines are returned, + * otherwise only the call targets belonging to {@code engine} will be returned. */ public Collection getQueuedTargets(EngineData engine) { BlockingQueue queue = this.compilationQueue; @@ -230,7 +231,7 @@ public Collection getQueuedTargets(EngineData engine) { CompilationTask.ExecutorServiceWrapper[] array = queue.toArray(new CompilationTask.ExecutorServiceWrapper[0]); for (CompilationTask.ExecutorServiceWrapper wrapper : array) { OptimizedCallTarget target = wrapper.compileTask.targetRef.get(); - if (target != null && target.engine == engine) { + if (target != null && (engine == null || target.engine == engine)) { queuedTargets.add(target); } } diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java index 250483505272..a0287a15f380 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java @@ -68,6 +68,7 @@ import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.SplittingMaxCalleeSize; import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.SplittingMaxPropagationDepth; import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.SplittingTraceEvents; +import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.StoppedCompilationRetryDelay; import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.TraceCompilation; import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.TraceCompilationDetails; import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.TraceDeoptimizeFrame; @@ -148,6 +149,7 @@ public final class EngineData { @CompilationFinal public boolean traceDeoptimizeFrame; @CompilationFinal public boolean compileAOTOnCreate; @CompilationFinal public boolean firstTierOnly; + @CompilationFinal public long stoppedCompilationRetryDelay; // compilation queue options @CompilationFinal public boolean priorityQueue; @@ -305,6 +307,7 @@ private void loadOptions(OptionValues options, SandboxPolicy sandboxPolicy) { this.firstTierOnly = options.get(Mode) == EngineModeEnum.LATENCY; this.propagateCallAndLoopCount = options.get(PropagateLoopCountToLexicalSingleCaller); this.propagateCallAndLoopCountMaxDepth = options.get(PropagateLoopCountToLexicalSingleCallerMaxDepth); + this.stoppedCompilationRetryDelay = options.get(StoppedCompilationRetryDelay); // compilation queue options priorityQueue = options.get(PriorityQueue); diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedCallTarget.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedCallTarget.java index 028aafc0fabe..c448a7cf92c6 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedCallTarget.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedCallTarget.java @@ -43,6 +43,7 @@ import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.ArrayList; +import java.util.Collection; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -51,7 +52,9 @@ import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.function.Supplier; +import java.util.logging.Level; +import com.oracle.truffle.api.TruffleLogger; import org.graalvm.options.OptionKey; import org.graalvm.options.OptionValues; @@ -855,6 +858,60 @@ final boolean isCompilationFailed() { return compilationFailed; } + final boolean isCompilationStopped() { + OptimizedTruffleRuntime.CompilationActivityMode compilationActivityMode = runtime().getCompilationActivityMode(); + long sct = runtime().stoppedCompilationTime().get(); + if (compilationActivityMode == OptimizedTruffleRuntime.CompilationActivityMode.STOP_COMPILATION) { + if (sct != 0 && System.currentTimeMillis() - sct > engine.stoppedCompilationRetryDelay) { + runtime().stoppedCompilationTime().compareAndSet(sct, 0); + // Try again every StoppedCompilationRetryDelay milliseconds to potentially trigger a code cache sweep. + compilationActivityMode = OptimizedTruffleRuntime.CompilationActivityMode.RUN_COMPILATION; + } + } + + switch (compilationActivityMode) { + case RUN_COMPILATION : { + // This is the common case - compilations are not stopped. + return false; + } + case STOP_COMPILATION : { + if (sct == 0) { + runtime().stoppedCompilationTime().compareAndSet(0, System.currentTimeMillis()); + } + // Flush the compilations queue for now. There's still a chance that compilation + // will be re-enabled eventually, if the hosts code cache can be cleaned up. + Collection targets = runtime().getCompileQueue().getQueuedTargets(null); + // If there's just a single compilation target in the queue, the chance is high that it is + // the one we've just added after the StoppedCompilationRetryDelay ran out, so keep it to + // potentially trigger a code cache sweep. + if (targets.size() > 1) { + for (OptimizedCallTarget target : targets) { + target.cancelCompilation("Compilation temporary disabled due to full code cache."); + } + } + return true; + } + case SHUTDOWN_COMPILATION : { + // Compilation was shut down permanently because the hosts code cache ran full and + // the host was configured without support for code cache sweeping. + TruffleLogger logger = engine.getLogger("engine"); + // The logger can be null if the engine is closed. + if (logger != null && runtime().logShutdownCompilations().compareAndExchange(true, false)) { + logger.log(Level.WARNING, "Truffle compilations permanently disabled because of full code cache. " + + "Increase the code cache size using '-XX:ReservedCodeCacheSize=' and/or run with '-XX:+UseCodeCacheFlushing -XX:+MethodFlushing'."); + } + try { + runtime().getCompileQueue().shutdownAndAwaitTermination(100 /* milliseconds */); + } catch (RuntimeException re) { + // Best effort, ignore failure + } + return true; + } + default : CompilerDirectives.shouldNotReachHere("Invalid compilation activity mode: " + compilationActivityMode); + } + return false; + } + /** * Returns true if the call target was already compiled or was compiled * synchronously. Returns false if compilation was not scheduled or is happening in @@ -866,6 +923,7 @@ public final boolean compile(boolean lastTierCompilation) { if (!needsCompile(lastTier)) { return true; } + if (!isSubmittedForCompilation()) { if (!acceptForCompilation()) { // do not try to compile again @@ -881,6 +939,10 @@ public final boolean compile(boolean lastTierCompilation) { return true; } + if (isCompilationStopped()) { + return false; + } + ensureInitialized(); if (!isSubmittedForCompilation()) { if (lastTier) { diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java index d99768259e4b..3ba95f646474 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java @@ -159,10 +159,11 @@ public ExceptionAction apply(String s) { public static final OptionKey CompilerIdleDelay = new OptionKey<>(10000L); @Option(help = "Before the Truffle runtime submits an OptimizedCallTarget for compilation, it checks for the " + - "compilation activity mode in the host VM. If the activity mode is 'STOP_COMPILATION' because " + - "of a full code cache, no new compilation requests are submitted and the compilation queue is flushed. " + + "compilation activity mode in the host VM. If the activity mode indicates a full code " + + "cache, no new compilation requests are submitted and the compilation queue is flushed. " + "After 'StoppedCompilationRetryDelay' milliseconds new compilations will be submitted again " + - "(which might trigger a sweep of the code cache and a reset of the compilation activity mode in the host JVM).", + "(which might trigger a sweep of the code cache and a reset of the compilation activity mode in the host JVM)." + + "The option is only supported on the HotSpot Truffle runtime. On runtimes which don't support it the option has no effect. default: 1000", usageSyntax = "", category = OptionCategory.EXPERT) public static final OptionKey StoppedCompilationRetryDelay = new OptionKey<>(1000L); diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java index 24f55428b7dd..a2e48282c235 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java @@ -64,6 +64,8 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.logging.Level; @@ -913,45 +915,23 @@ private void notifyCompilationFailure(OptimizedCallTarget callTarget, Throwable protected void onEngineCreated(EngineData engine) { } - private long stoppedCompilationTime = 0; - private boolean logShutdownCompilations = true; + + private final AtomicLong stoppedCompilationTime = new AtomicLong(0); + + public final AtomicLong stoppedCompilationTime() { + return stoppedCompilationTime; + } + + private final AtomicBoolean logShutdownCompilations = new AtomicBoolean(true); + + public final AtomicBoolean logShutdownCompilations() { + return logShutdownCompilations; + } @SuppressWarnings("try") public CompilationTask submitForCompilation(OptimizedCallTarget optimizedCallTarget, boolean lastTierCompilation) { - BackgroundCompileQueue queue = getCompileQueue(); - CompilationActivityMode compilationActivityMode = getCompilationActivityMode(); - if (compilationActivityMode == CompilationActivityMode.RUN_COMPILATION || - (stoppedCompilationTime != 0 && System.currentTimeMillis() - stoppedCompilationTime > optimizedCallTarget.getOptionValue(StoppedCompilationRetryDelay))) { - stoppedCompilationTime = 0; - Priority priority = new Priority(optimizedCallTarget.getCallAndLoopCount(), lastTierCompilation ? Priority.Tier.LAST : Priority.Tier.FIRST); - return queue.submitCompilation(priority, optimizedCallTarget); - } else if (compilationActivityMode == CompilationActivityMode.STOP_COMPILATION) { - if (stoppedCompilationTime == 0) { - stoppedCompilationTime = System.currentTimeMillis(); - } - // Flush the compilations queue. There's still a chance that compilation will be re-enabled - // eventually, if the hosts code cache can be cleaned up. - for (OptimizedCallTarget target : queue.getQueuedTargets(optimizedCallTarget.engine)) { - target.cancelCompilation("Compilation temporary disabled due to full code cache."); - } - } else { - // Compilation was shut down permanently because the hosts code cache ran full and - // the host was configured without support for code cache sweeping. - assert compilationActivityMode == CompilationActivityMode.SHUTDOWN_COMPILATION; - TruffleLogger logger = optimizedCallTarget.engine.getLogger("engine"); - // The logger can be null if the engine is closed. - if (logger != null && logShutdownCompilations) { - logShutdownCompilations = false; - logger.log(Level.WARNING, "Truffle host compilations permanently disabled because of full code cache. " + - "Increase the code cache size using '-XX:ReservedCodeCacheSize=' and/or run with '-XX:+UseCodeCacheFlushing -XX:+MethodFlushing'."); - } - try { - queue.shutdownAndAwaitTermination(100 /* milliseconds */); - } catch (RuntimeException re) { - // Best effort, ignore failure - } - } - return null; + Priority priority = new Priority(optimizedCallTarget.getCallAndLoopCount(), lastTierCompilation ? Priority.Tier.LAST : Priority.Tier.FIRST); + return getCompileQueue().submitCompilation(priority, optimizedCallTarget); } @SuppressWarnings("all") @@ -1519,4 +1499,30 @@ static OptionCategory matchCategory(TruffleCompilerOptionDescriptor d) { } } + /** + * Represents HotSpot's compilation activity mode which is one of: + * {@code stop_compilation = 0}, {@code run_compilation = 1} or {@code shutdown_compilation = 2} + * Should be in sync with the {@code CompilerActivity} enum in {@code hotspot/share/compiler/compileBroker.hpp} + */ + public enum CompilationActivityMode { + STOP_COMPILATION, + RUN_COMPILATION, + SHUTDOWN_COMPILATION; + + static public CompilationActivityMode fromInteger(int i) { + return switch (i) { + case 0 -> STOP_COMPILATION; + case 1 -> RUN_COMPILATION; + case 2 -> SHUTDOWN_COMPILATION; + default -> throw new RuntimeException("Invalid CompilationActivityMode " + i); + }; + } + } + + /** + * Returns the current host compilation activity mode. The default is to run compilations. + */ + public CompilationActivityMode getCompilationActivityMode() { + return CompilationActivityMode.RUN_COMPILATION; + } } diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java index 41c0d9856ea7..e143ceb63394 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java @@ -695,19 +695,20 @@ public boolean isLibGraalCompilationEnabled() { return compilationSupport instanceof LibGraalTruffleCompilationSupport; } - static MethodHandle getCompilationActivityMode; + static final MethodHandle getCompilationActivityMode; static { + MethodHandle mHandle = null; try { MethodType mt = MethodType.methodType(int.class); - getCompilationActivityMode = MethodHandles.lookup().findVirtual(HotSpotJVMCIRuntime.class, "getCompilationActivityMode", mt); + mHandle = MethodHandles.lookup().findVirtual(HotSpotJVMCIRuntime.class, "getCompilationActivityMode", mt); } catch (NoSuchMethodException | IllegalAccessException e) { // Older JVMCI runtimes might not support `getCompilationActivityMode()` } + getCompilationActivityMode = mHandle; } /** - * Returns the current host compilation activity mode which is one of: - * {@code stop_compilation = 0}, {@code run_compilation = 1} or {@code shutdown_compilation = 2} + * Returns the current host compilation activity mode based on HotSpot's code cache state. */ @Override public CompilationActivityMode getCompilationActivityMode() { @@ -716,7 +717,7 @@ public CompilationActivityMode getCompilationActivityMode() { try { activityMode = (int) getCompilationActivityMode.invokeExact(HotSpotJVMCIRuntime.runtime()); } catch (Throwable t) { - // Ignore and go with the default mode + throw new RuntimeException("Can't get HotSpot's compilation activity mode", t); } } return CompilationActivityMode.fromInteger(activityMode); From 8d1285e2614ff332c5a78187c0eab2d6d15bb6a5 Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Tue, 26 Nov 2024 20:19:50 +0100 Subject: [PATCH 3/5] Remove unused import --- .../src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java | 1 - 1 file changed, 1 deletion(-) diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java index a2e48282c235..3fc095573242 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java @@ -41,7 +41,6 @@ package com.oracle.truffle.runtime; import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.CompilerIdleDelay; -import static com.oracle.truffle.runtime.OptimizedRuntimeOptions.StoppedCompilationRetryDelay; import java.io.CharArrayWriter; import java.io.PrintWriter; From 0ae44fe1e628b67e1dfd1dfabaf1da43237f4116 Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Sat, 30 Nov 2024 00:54:46 +0100 Subject: [PATCH 4/5] Updated according to second review round --- .../compiler/TruffleCompilerRuntime.java | 2 +- .../runtime/BackgroundCompileQueue.java | 2 +- .../oracle/truffle/runtime/EngineData.java | 11 ++++ .../truffle/runtime/OptimizedCallTarget.java | 62 +++++++++++-------- .../runtime/OptimizedRuntimeOptions.java | 18 +++--- .../runtime/OptimizedTruffleRuntime.java | 16 ++--- .../hotspot/HotSpotTruffleRuntime.java | 2 +- 7 files changed, 62 insertions(+), 51 deletions(-) diff --git a/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java b/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java index 75669f9ac3c7..3c4f55021354 100644 --- a/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java +++ b/truffle/src/com.oracle.truffle.compiler/src/com/oracle/truffle/compiler/TruffleCompilerRuntime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BackgroundCompileQueue.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BackgroundCompileQueue.java index 3dd4faa630b0..05ac69f120a0 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BackgroundCompileQueue.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/BackgroundCompileQueue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java index a0287a15f380..3d5067b663f8 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java @@ -86,6 +86,7 @@ import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import java.util.logging.Level; @@ -495,6 +496,16 @@ public TruffleLogger getLogger(String loggerId) { return polyglotEngine != null ? loggerFactory.apply(loggerId) : null; } + private final AtomicBoolean logShutdownCompilations = new AtomicBoolean(true); + + /** + * Only log compilation shutdowns (see {@code OptimizedCallTarget.isCompilationStopped()}) once + * per engine. + */ + public final AtomicBoolean logShutdownCompilations() { + return logShutdownCompilations; + } + @SuppressWarnings("static-method") public void mergeLoadedSources(Source[] sources) { OptimizedRuntimeAccessor.SOURCE.mergeLoadedSources(sources); diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedCallTarget.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedCallTarget.java index c448a7cf92c6..6335471962e5 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedCallTarget.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedCallTarget.java @@ -84,6 +84,7 @@ import com.oracle.truffle.api.nodes.RootNode; import com.oracle.truffle.compiler.TruffleCompilable; import com.oracle.truffle.runtime.OptimizedRuntimeOptions.ExceptionAction; +import com.oracle.truffle.runtime.OptimizedTruffleRuntime.CompilationActivityMode; import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.SpeculationLog; @@ -858,58 +859,60 @@ final boolean isCompilationFailed() { return compilationFailed; } - final boolean isCompilationStopped() { - OptimizedTruffleRuntime.CompilationActivityMode compilationActivityMode = runtime().getCompilationActivityMode(); + final CompilationActivityMode getCompilationActivityMode() { + CompilationActivityMode compilationActivityMode = runtime().getCompilationActivityMode(); long sct = runtime().stoppedCompilationTime().get(); - if (compilationActivityMode == OptimizedTruffleRuntime.CompilationActivityMode.STOP_COMPILATION) { + if (compilationActivityMode == CompilationActivityMode.STOP_COMPILATION) { if (sct != 0 && System.currentTimeMillis() - sct > engine.stoppedCompilationRetryDelay) { runtime().stoppedCompilationTime().compareAndSet(sct, 0); - // Try again every StoppedCompilationRetryDelay milliseconds to potentially trigger a code cache sweep. - compilationActivityMode = OptimizedTruffleRuntime.CompilationActivityMode.RUN_COMPILATION; + // Try again every StoppedCompilationRetryDelay milliseconds to potentially trigger + // a code cache sweep. + compilationActivityMode = CompilationActivityMode.RUN_COMPILATION; } } switch (compilationActivityMode) { - case RUN_COMPILATION : { + case RUN_COMPILATION: { // This is the common case - compilations are not stopped. - return false; + return CompilationActivityMode.RUN_COMPILATION; } - case STOP_COMPILATION : { + case STOP_COMPILATION: { if (sct == 0) { runtime().stoppedCompilationTime().compareAndSet(0, System.currentTimeMillis()); } // Flush the compilations queue for now. There's still a chance that compilation // will be re-enabled eventually, if the hosts code cache can be cleaned up. Collection targets = runtime().getCompileQueue().getQueuedTargets(null); - // If there's just a single compilation target in the queue, the chance is high that it is - // the one we've just added after the StoppedCompilationRetryDelay ran out, so keep it to - // potentially trigger a code cache sweep. + // If there's just a single compilation target in the queue, the chance is high that + // it is the one we've just added after the StoppedCompilationRetryDelay ran out, so + // keep it to potentially trigger a code cache sweep. if (targets.size() > 1) { for (OptimizedCallTarget target : targets) { target.cancelCompilation("Compilation temporary disabled due to full code cache."); } } - return true; + return CompilationActivityMode.STOP_COMPILATION; } - case SHUTDOWN_COMPILATION : { + case SHUTDOWN_COMPILATION: { // Compilation was shut down permanently because the hosts code cache ran full and // the host was configured without support for code cache sweeping. TruffleLogger logger = engine.getLogger("engine"); // The logger can be null if the engine is closed. - if (logger != null && runtime().logShutdownCompilations().compareAndExchange(true, false)) { - logger.log(Level.WARNING, "Truffle compilations permanently disabled because of full code cache. " + - "Increase the code cache size using '-XX:ReservedCodeCacheSize=' and/or run with '-XX:+UseCodeCacheFlushing -XX:+MethodFlushing'."); + if (logger != null && engine.logShutdownCompilations().compareAndExchange(true, false)) { + logger.log(Level.WARNING, "Truffle compilations permanently disabled because of full code cache. " + + "Increase the code cache size using '-XX:ReservedCodeCacheSize=' and/or run with '-XX:+UseCodeCacheFlushing -XX:+MethodFlushing'."); } - try { - runtime().getCompileQueue().shutdownAndAwaitTermination(100 /* milliseconds */); - } catch (RuntimeException re) { - // Best effort, ignore failure + // Flush the compilation queue and mark all methods as not compilable. + for (OptimizedCallTarget target : runtime().getCompileQueue().getQueuedTargets(null)) { + target.cancelCompilation("Compilation permanently disabled due to full code cache."); + target.compilationFailed = true; } - return true; + return CompilationActivityMode.SHUTDOWN_COMPILATION; } - default : CompilerDirectives.shouldNotReachHere("Invalid compilation activity mode: " + compilationActivityMode); + default: + CompilerDirectives.shouldNotReachHere("Invalid compilation activity mode: " + compilationActivityMode); } - return false; + return CompilationActivityMode.RUN_COMPILATION; } /** @@ -931,6 +934,15 @@ public final boolean compile(boolean lastTierCompilation) { return false; } + CompilationActivityMode cam = getCompilationActivityMode(); + if (cam != CompilationActivityMode.RUN_COMPILATION) { + if (cam == CompilationActivityMode.SHUTDOWN_COMPILATION) { + // Compilation was shut down permanently. + compilationFailed = true; + } + return false; + } + CompilationTask task = null; // Do not try to compile this target concurrently, // but do not block other threads if compilation is not asynchronous. @@ -939,10 +951,6 @@ public final boolean compile(boolean lastTierCompilation) { return true; } - if (isCompilationStopped()) { - return false; - } - ensureInitialized(); if (!isSubmittedForCompilation()) { if (lastTier) { diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java index 3ba95f646474..6ea147cb42ca 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedRuntimeOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -158,14 +158,14 @@ public ExceptionAction apply(String s) { // TODO: GR-29949 public static final OptionKey CompilerIdleDelay = new OptionKey<>(10000L); - @Option(help = "Before the Truffle runtime submits an OptimizedCallTarget for compilation, it checks for the " + - "compilation activity mode in the host VM. If the activity mode indicates a full code " + - "cache, no new compilation requests are submitted and the compilation queue is flushed. " + - "After 'StoppedCompilationRetryDelay' milliseconds new compilations will be submitted again " + - "(which might trigger a sweep of the code cache and a reset of the compilation activity mode in the host JVM)." + - "The option is only supported on the HotSpot Truffle runtime. On runtimes which don't support it the option has no effect. default: 1000", - usageSyntax = "", category = OptionCategory.EXPERT) - public static final OptionKey StoppedCompilationRetryDelay = new OptionKey<>(1000L); + @Option(help = "Before the Truffle runtime submits an OptimizedCallTarget for compilation, it checks for the compilation " + + "activity mode in the host VM. If the activity mode indicates a full code cache, no new compilation " + + "requests are submitted and the compilation queue is flushed. After 'StoppedCompilationRetryDelay' " + + "milliseconds new compilations will be submitted again (which might trigger a sweep of the code " + + "cache and a reset of the compilation activity mode in the host JVM). The option is only supported on " + + "the HotSpot Truffle runtime. On runtimes which don't support it the option has no effect. default: 5000", // + usageSyntax = "", category = OptionCategory.EXPERT) // + public static final OptionKey StoppedCompilationRetryDelay = new OptionKey<>(5000L); @Option(help = "Manually set the number of compiler threads. By default, the number of compiler threads is scaled with the number of available cores on the CPU.", usageSyntax = "[1, inf)", category = OptionCategory.EXPERT, // stability = OptionStability.STABLE, sandbox = SandboxPolicy.UNTRUSTED) // diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java index 3fc095573242..4641cbd44839 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -63,7 +63,6 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.function.Supplier; @@ -914,19 +913,12 @@ private void notifyCompilationFailure(OptimizedCallTarget callTarget, Throwable protected void onEngineCreated(EngineData engine) { } - private final AtomicLong stoppedCompilationTime = new AtomicLong(0); public final AtomicLong stoppedCompilationTime() { return stoppedCompilationTime; } - private final AtomicBoolean logShutdownCompilations = new AtomicBoolean(true); - - public final AtomicBoolean logShutdownCompilations() { - return logShutdownCompilations; - } - @SuppressWarnings("try") public CompilationTask submitForCompilation(OptimizedCallTarget optimizedCallTarget, boolean lastTierCompilation) { Priority priority = new Priority(optimizedCallTarget.getCallAndLoopCount(), lastTierCompilation ? Priority.Tier.LAST : Priority.Tier.FIRST); @@ -1499,9 +1491,9 @@ static OptionCategory matchCategory(TruffleCompilerOptionDescriptor d) { } /** - * Represents HotSpot's compilation activity mode which is one of: - * {@code stop_compilation = 0}, {@code run_compilation = 1} or {@code shutdown_compilation = 2} - * Should be in sync with the {@code CompilerActivity} enum in {@code hotspot/share/compiler/compileBroker.hpp} + * Represents HotSpot's compilation activity mode which is one of: {@code stop_compilation = 0}, + * {@code run_compilation = 1} or {@code shutdown_compilation = 2} Should be in sync with the + * {@code CompilerActivity} enum in {@code hotspot/share/compiler/compileBroker.hpp} */ public enum CompilationActivityMode { STOP_COMPILATION, diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java index e143ceb63394..4743b430cd76 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/hotspot/HotSpotTruffleRuntime.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 From acdb24aa5fde8b1e431a5ce902ee0e50dd36fe4d Mon Sep 17 00:00:00 2001 From: Volker Simonis Date: Sat, 30 Nov 2024 14:11:35 +0100 Subject: [PATCH 5/5] Fixed checkstyle errors --- .../src/com/oracle/truffle/runtime/EngineData.java | 2 +- .../com/oracle/truffle/runtime/OptimizedTruffleRuntime.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java index 3d5067b663f8..09f0fa9d373f 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/EngineData.java @@ -502,7 +502,7 @@ public TruffleLogger getLogger(String loggerId) { * Only log compilation shutdowns (see {@code OptimizedCallTarget.isCompilationStopped()}) once * per engine. */ - public final AtomicBoolean logShutdownCompilations() { + public AtomicBoolean logShutdownCompilations() { return logShutdownCompilations; } diff --git a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java index 4641cbd44839..1d9f6eba845a 100644 --- a/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java +++ b/truffle/src/com.oracle.truffle.runtime/src/com/oracle/truffle/runtime/OptimizedTruffleRuntime.java @@ -1492,15 +1492,15 @@ static OptionCategory matchCategory(TruffleCompilerOptionDescriptor d) { /** * Represents HotSpot's compilation activity mode which is one of: {@code stop_compilation = 0}, - * {@code run_compilation = 1} or {@code shutdown_compilation = 2} Should be in sync with the - * {@code CompilerActivity} enum in {@code hotspot/share/compiler/compileBroker.hpp} + * {@code run_compilation = 1} or {@code shutdown_compilation = 2}. Should be in sync with the + * {@code CompilerActivity} enum in {@code hotspot/share/compiler/compileBroker.hpp}. */ public enum CompilationActivityMode { STOP_COMPILATION, RUN_COMPILATION, SHUTDOWN_COMPILATION; - static public CompilationActivityMode fromInteger(int i) { + public static CompilationActivityMode fromInteger(int i) { return switch (i) { case 0 -> STOP_COMPILATION; case 1 -> RUN_COMPILATION;