This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY-11640
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit d0c6c2f1a5f111319082cf6481dd07fd35753b61
Author: Daniel Sun <[email protected]>
AuthorDate: Sat May 24 17:43:42 2025 +0900

    GROOVY-11640: GC pause by Metadata GC Threshold for weeks then turned to 
Full GC
---
 .../codehaus/groovy/vmplugin/v8/CacheableCallSite.java   |  8 +++++++-
 .../org/codehaus/groovy/vmplugin/v8/IndyInterface.java   | 16 ++++++++++++----
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java 
b/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java
index 58a6dfac5f..73527d5227 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java
@@ -41,12 +41,13 @@ import java.util.logging.Logger;
  * @since 3.0.0
  */
 public class CacheableCallSite extends MutableCallSite {
-    private static final int CACHE_SIZE = 
SystemUtil.getIntegerSafe("groovy.indy.callsite.cache.size", 4);
+    private static final int CACHE_SIZE = 
SystemUtil.getIntegerSafe("groovy.indy.callsite.cache.size", 8);
     private static final float LOAD_FACTOR = 0.75f;
     private static final int INITIAL_CAPACITY = (int) Math.ceil(CACHE_SIZE / 
LOAD_FACTOR) + 1;
     private final MethodHandles.Lookup lookup;
     private volatile SoftReference<MethodHandleWrapper> 
latestHitMethodHandleWrapperSoftReference = null;
     private final AtomicLong fallbackCount = new AtomicLong();
+    private final AtomicLong fallbackRound = new AtomicLong();
     private MethodHandle defaultTarget;
     private MethodHandle fallbackTarget;
     private final Map<String, SoftReference<MethodHandleWrapper>> lruCache =
@@ -119,6 +120,11 @@ public class CacheableCallSite extends MutableCallSite {
 
     public void resetFallbackCount() {
         fallbackCount.set(0);
+        fallbackRound.incrementAndGet();
+    }
+
+    public AtomicLong getFallbackRound() {
+        return fallbackRound;
     }
 
     public MethodHandle getDefaultTarget() {
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java 
b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java
index 606328a1ea..d17fca15fe 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java
@@ -48,8 +48,9 @@ import java.util.stream.Stream;
  * methods and classes.
  */
 public class IndyInterface {
-    private static final long INDY_OPTIMIZE_THRESHOLD = 
SystemUtil.getLongSafe("groovy.indy.optimize.threshold", 10_000L);
-    private static final long INDY_FALLBACK_THRESHOLD = 
SystemUtil.getLongSafe("groovy.indy.fallback.threshold", 10_000L);
+    private static final long INDY_OPTIMIZE_THRESHOLD = 
SystemUtil.getLongSafe("groovy.indy.optimize.threshold", 1_000L);
+    private static final long INDY_FALLBACK_THRESHOLD = 
SystemUtil.getLongSafe("groovy.indy.fallback.threshold", 1_000L);
+    private static final long INDY_FALLBACK_CUTOFF = 
SystemUtil.getLongSafe("groovy.indy.fallback.cutoff", 100L);
 
     /**
      * flags for method and property calls
@@ -327,8 +328,15 @@ public class IndyInterface {
         }
 
         if (mhw.isCanSetTarget() && (callSite.getTarget() != 
mhw.getTargetMethodHandle()) && (mhw.getLatestHitCount() > 
INDY_OPTIMIZE_THRESHOLD)) {
-            callSite.setTarget(mhw.getTargetMethodHandle());
-            if (LOG_ENABLED) LOG.info("call site target set, preparing outside 
invocation");
+            if (callSite.getFallbackRound().get() > INDY_FALLBACK_CUTOFF) {
+                if (callSite.getTarget() != callSite.getDefaultTarget()) {
+                    // reset the call site target to default forever to avoid 
JIT deoptimization storm further
+                    callSite.setTarget(callSite.getDefaultTarget());
+                }
+            } else {
+                callSite.setTarget(mhw.getTargetMethodHandle());
+                if (LOG_ENABLED) LOG.info("call site target set, preparing 
outside invocation");
+            }
 
             mhw.resetLatestHitCount();
         }

Reply via email to