Avoid Native Pin when use Continuation direclty with reflection invoke

kalinshi(施慧) kalinshi at tencent.com
Tue Nov 10 12:01:56 UTC 2020


Hi All,

When use Continuation directly and invokes reflection method then yield, Continuation will be pinned.
Looking at current NativeMethod/ConstructorAccessorImpl, it only forces java accessor generated and invoke java code when executing in VirtualThread. This still Pin's if directly using Continuation.
As Pin is a state in Continuation, will it better checking if Continuation is on stack instead of checking VirtualThread? So reflection invoke will not pin/block Continuation/VirtualThread.

Following is proposed change, there is no public interface to get current continuation yet, so need adding an interface to check if there is a continuation on executing stack.

diff --git a/src/java.base/share/classes/java/lang/Continuation.java b/src/java.base/share/classes/java/lang/Continuation.java
index d92a7c9..44491f4 100644
--- a/src/java.base/share/classes/java/lang/Continuation.java
+++ b/src/java.base/share/classes/java/lang/Continuation.java
@@ -209,6 +209,15 @@ public class Continuation {
      * TBD
      * @return TBD
      */
+    public static boolean inContinuation() {
+        Continuation cont = currentCarrierThread().getContinuation();
+        return cont != null;
+    }
+
+    /**
+     * TBD
+     * @return TBD
+     */
     public StackWalker stackWalker() {
         return stackWalker(EnumSet.noneOf(StackWalker.Option.class));
     }
diff --git a/src/java.base/share/classes/jdk/internal/reflect/NativeConstructorAccessorImpl.java b/src/java.base/share/classes/jdk/internal/reflect/NativeConstructorAccessorImpl.java
index 46addb9..69fcdd5 100644
--- a/src/java.base/share/classes/jdk/internal/reflect/NativeConstructorAccessorImpl.java
+++ b/src/java.base/share/classes/jdk/internal/reflect/NativeConstructorAccessorImpl.java
@@ -51,7 +51,7 @@ class NativeConstructorAccessorImpl extends ConstructorAccessorImpl {
         // because that kind of class can't be referred to by name, hence can't
         // be found from the generated bytecode.
         if ((++numInvocations > ReflectionFactory.inflationThreshold()
-                || Thread.currentThread().isVirtual())
+                || Continuation.inContinuation())
                     && !c.getDeclaringClass().isHidden()
                     && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
 
diff --git a/src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java b/src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java
index a491485..c530aa4 100644
--- a/src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java
+++ b/src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java
@@ -49,7 +49,7 @@ class NativeMethodAccessorImpl extends MethodAccessorImpl {
         // that kind of class can't be referred to by name, hence can't be
         // found from the generated bytecode.
         if ((++numInvocations > ReflectionFactory.inflationThreshold()
-                || Thread.currentThread().isVirtual())
+                || Continuation.inContinuation())
                     && !method.getDeclaringClass().isHidden()
                     && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {


Regards
Hui


More information about the loom-dev mailing list