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 89b72209f0e34eebeed4fa1e62a67ff38370234c
Author: Daniel Sun <sun...@apache.org>
AuthorDate: Sat May 24 11:37:44 2025 +0900

    GROOVY-11640: GC pause by Metadata GC Threshold for weeks then turned to 
Full GC
---
 .../org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java  |  6 ++++++
 .../java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java | 13 +++++++++++--
 2 files changed, 17 insertions(+), 2 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..e93e423633 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java
@@ -47,6 +47,7 @@ public class CacheableCallSite extends MutableCallSite {
     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..647aff2e27 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java
@@ -50,6 +50,8 @@ import java.util.stream.Stream;
 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_FALLBACK_CUTOFF = 
SystemUtil.getLongSafe("groovy.indy.fallback.cutoff", 1_000L);
+
 
     /**
      * flags for method and property calls
@@ -327,8 +329,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 optimizing and deoptimizing frequently
+                    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