changeset 56524:8e4c118cd0fd fibers

Method.invoke/Constructor.newInstance need to skip VM entry point when invoked on fiber
author alanb
date Mon, 19 Aug 2019 16:01:24 +0100
parents 39408849f6d3
children 954e771ea81c
files src/java.base/share/classes/jdk/internal/misc/Strands.java src/java.base/share/classes/jdk/internal/reflect/NativeConstructorAccessorImpl.java src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java
diffstat 3 files changed, 21 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/jdk/internal/misc/Strands.java	Sun Aug 18 09:18:42 2019 +0100
+++ b/src/java.base/share/classes/jdk/internal/misc/Strands.java	Mon Aug 19 16:01:24 2019 +0100
@@ -35,7 +35,13 @@
  */
 
 public final class Strands {
-    private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess();
+    private static final JavaLangAccess JLA;
+    static {
+        JLA = SharedSecrets.getJavaLangAccess();
+        if (JLA == null) {
+            throw new InternalError("JavaLangAccess not setup");
+        }
+    }
     private Strands() { }
 
     /**
--- a/src/java.base/share/classes/jdk/internal/reflect/NativeConstructorAccessorImpl.java	Sun Aug 18 09:18:42 2019 +0100
+++ b/src/java.base/share/classes/jdk/internal/reflect/NativeConstructorAccessorImpl.java	Mon Aug 19 16:01:24 2019 +0100
@@ -26,6 +26,9 @@
 package jdk.internal.reflect;
 
 import java.lang.reflect.*;
+
+import jdk.internal.misc.Strands;
+import jdk.internal.misc.VM;
 import sun.reflect.misc.ReflectUtil;
 
 /** Used only for the first few invocations of a Constructor;
@@ -48,8 +51,9 @@
         // We can't inflate a constructor belonging to a vm-anonymous class
         // 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()
-                && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
+        if (VM.isBooted() && (++numInvocations > ReflectionFactory.inflationThreshold()
+                || Strands.currentStrand() instanceof Fiber)
+                    && !ReflectUtil.isVMAnonymousClass(c.getDeclaringClass())) {
             ConstructorAccessorImpl acc = (ConstructorAccessorImpl)
                 new MethodAccessorGenerator().
                     generateConstructor(c.getDeclaringClass(),
@@ -57,6 +61,7 @@
                                         c.getExceptionTypes(),
                                         c.getModifiers());
             parent.setDelegate(acc);
+            return acc.newInstance(args);
         }
 
         return newInstance0(c, args);
--- a/src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java	Sun Aug 18 09:18:42 2019 +0100
+++ b/src/java.base/share/classes/jdk/internal/reflect/NativeMethodAccessorImpl.java	Mon Aug 19 16:01:24 2019 +0100
@@ -26,6 +26,9 @@
 package jdk.internal.reflect;
 
 import java.lang.reflect.*;
+
+import jdk.internal.misc.Strands;
+import jdk.internal.misc.VM;
 import sun.reflect.misc.ReflectUtil;
 
 /** Used only for the first few invocations of a Method; afterward,
@@ -46,8 +49,9 @@
         // We can't inflate methods belonging to vm-anonymous classes 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()
-                && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
+        if (VM.isBooted() && (++numInvocations > ReflectionFactory.inflationThreshold()
+                || Strands.currentStrand() instanceof Fiber)
+                    && !ReflectUtil.isVMAnonymousClass(method.getDeclaringClass())) {
             MethodAccessorImpl acc = (MethodAccessorImpl)
                 new MethodAccessorGenerator().
                     generateMethod(method.getDeclaringClass(),
@@ -57,6 +61,7 @@
                                    method.getExceptionTypes(),
                                    method.getModifiers());
             parent.setDelegate(acc);
+            return acc.invoke(obj, args);
         }
 
         return invoke0(method, obj, args);