changeset 49141:0d2b7ad907b3 condy-folding

minor tweaks to the symbolicref impl
author psandoz
date Fri, 09 Feb 2018 17:19:25 -0800
parents f211e9713517
children 193b46c5b480
files src/java.base/share/classes/java/lang/sym/ClassRef.java src/java.base/share/classes/java/lang/sym/ConstantRef.java src/java.base/share/classes/java/lang/sym/DynamicConstantRef.java src/java.base/share/classes/java/lang/sym/MethodHandleRef.java src/java.base/share/classes/java/lang/sym/MethodTypeRef.java src/java.base/share/classes/java/lang/sym/SymbolicRef.java src/java.base/share/classes/java/lang/sym/SymbolicRefs.java src/java.base/share/classes/java/lang/sym/VarHandleRef.java
diffstat 8 files changed, 66 insertions(+), 67 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/sym/ClassRef.java	Fri Feb 09 13:36:17 2018 -0500
+++ b/src/java.base/share/classes/java/lang/sym/ClassRef.java	Fri Feb 09 17:19:25 2018 -0800
@@ -54,6 +54,9 @@
      */
     private ClassRef(String descriptor) {
         // @@@ Replace validation with a lower-overhead mechanism than regex
+        // Follow the trail from MethodType.fromMethodDescriptorString to
+        // parsing code in sun/invoke/util/BytecodeDescriptor.java which could
+        // be extracted and/or shared
         if (descriptor == null
             || !TYPE_DESC.matcher(descriptor).matches())
             throw new IllegalArgumentException(String.format("%s is not a valid type descriptor", descriptor));
--- a/src/java.base/share/classes/java/lang/sym/ConstantRef.java	Fri Feb 09 13:36:17 2018 -0500
+++ b/src/java.base/share/classes/java/lang/sym/ConstantRef.java	Fri Feb 09 17:19:25 2018 -0800
@@ -29,7 +29,6 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-import java.lang.invoke.VarHandle;
 import java.util.Optional;
 
 /**
@@ -70,7 +69,6 @@
  * is an exhaustive set of subtypes: {@link String}, {@link Integer}, {@link Long},
  * {@link Float}, {@link Double}, {@link ClassRef}, {@link MethodTypeRef},
  * {@link MethodHandleRef}, and {@link DynamicConstantRef}.
- *
  * @see Constable
  * @see ConstantRef
  * @see Intrinsics
@@ -94,7 +92,7 @@
      * string that would be the target of a {@code NameAndType} constant.
      *
      * @param <T> The type of the object which this {@linkplain ConstantRef}
-     *            describes
+     * describes
      */
     interface WithTypeDescriptor<T> extends ConstantRef<T> {
         /**
@@ -113,17 +111,16 @@
      * {@link Double} should implement this interface.
      *
      * @param <T> The type of the object which this {@linkplain ConstantRef}
-     *            describes
+     * describes
      */
     interface OfSelf<T extends ConstantRef.OfSelf<T>>
             extends ConstantRef<T>, Constable<T> {
         /**
          * {@inheritDoc}
          *
-         * @implSpec This implementation returns its receiver
-         *
          * @param lookup ignored
          * @return the symbolic reference
+         * @implSpec This implementation returns its receiver
          */
         @Override
         @SuppressWarnings("unchecked")
@@ -134,10 +131,9 @@
         /**
          * {@inheritDoc}
          *
-         * @implSpec This implementation returns its receiver
-         *
          * @param lookup ignored
          * @return the symbolic reference
+         * @implSpec This implementation returns its receiver
          */
         @Override
         @SuppressWarnings("unchecked")
--- a/src/java.base/share/classes/java/lang/sym/DynamicConstantRef.java	Fri Feb 09 13:36:17 2018 -0500
+++ b/src/java.base/share/classes/java/lang/sym/DynamicConstantRef.java	Fri Feb 09 17:19:25 2018 -0800
@@ -280,36 +280,38 @@
      */
     public ConstantRef<?>[] bootstrapArgs() { return bootstrapArgs.clone(); }
 
-    private static Object[] resolveArgs(MethodHandles.Lookup lookup, ConstantRef<?>[] args) {
-        return Stream.of(args)
-                     .map(arg -> {
-                         try {
-                             return arg.resolveRef(lookup);
-                         }
-                         catch (ReflectiveOperationException e) {
-                             throw new RuntimeException(e);
-                         }
-                     })
-                     .toArray();
+    private static Object[] resolveArgs(MethodHandles.Lookup lookup, ConstantRef<?>[] args)
+            throws ReflectiveOperationException {
+        try {
+            return Stream.of(args)
+                    .map(arg -> {
+                        try {
+                            return arg.resolveRef(lookup);
+                        }
+                        catch (ReflectiveOperationException e) {
+                            throw new RuntimeException(e);
+                        }
+                    })
+                    .toArray();
+        }
+        catch (RuntimeException e) {
+            if (e.getCause() instanceof ReflectiveOperationException) {
+                throw (ReflectiveOperationException) e.getCause();
+            }
+            else {
+                throw e;
+            }
+        }
     }
 
     @SuppressWarnings("unchecked")
     public T resolveRef(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
-        try {
-            MethodHandle bsmMh = bootstrapMethod.resolveRef(lookup);
-            return (T) ConstantBootstraps.makeConstant(bsmMh,
-                                                       name,
-                                                       type.resolveRef(lookup),
-                                                       resolveArgs(lookup, bootstrapArgs),
-                                                       // TODO pass lookup
-                                                       lookup.lookupClass());
-        }
-        catch (RuntimeException|Error e) {
-            throw e;
-        }
-        catch (Throwable t) {
-            throw new RuntimeException(t);
-        }
+        return (T) ConstantBootstraps.makeConstant(bootstrapMethod.resolveRef(lookup),
+                                                   name,
+                                                   type.resolveRef(lookup),
+                                                   resolveArgs(lookup, bootstrapArgs),
+                                                   // TODO pass lookup
+                                                   lookup.lookupClass());
     }
 
     @Override
--- a/src/java.base/share/classes/java/lang/sym/MethodHandleRef.java	Fri Feb 09 13:36:17 2018 -0500
+++ b/src/java.base/share/classes/java/lang/sym/MethodHandleRef.java	Fri Feb 09 17:19:25 2018 -0800
@@ -50,13 +50,6 @@
  * A symbolic reference for a {@link MethodHandle} constant.
  */
 public final class MethodHandleRef implements ConstantRef<MethodHandle>, Constable<ConstantRef<MethodHandle>> {
-    private static final ClassRef[] INDY_BOOTSTRAP_ARGS = { ClassRef.of("java.lang.invoke.MethodHandles$Lookup"),
-                                                            ClassRef.of("java.lang.String"),
-                                                            ClassRef.of("java.lang.invoke.MethodType") };
-    private static final ClassRef[] CONDY_BOOTSTRAP_ARGS = { ClassRef.of("java.lang.invoke.MethodHandles$Lookup"),
-                                                             ClassRef.of("java.lang.String"),
-                                                             ClassRef.of("java.lang.Class") };
-
     /**
      * Kinds of method handle refs
      */
@@ -202,7 +195,7 @@
      */
     @Foldable
     public static MethodHandleRef ofDynamicCallsite(ClassRef clazz, String name, ClassRef returnType, ClassRef... paramTypes) {
-        return of(STATIC, clazz, name, MethodTypeRef.of(returnType, paramTypes).insertParameterTypes(0, INDY_BOOTSTRAP_ARGS));
+        return of(STATIC, clazz, name, MethodTypeRef.of(returnType, paramTypes).insertParameterTypes(0, SymbolicRefs.INDY_BOOTSTRAP_ARGS));
     }
 
     /**
@@ -219,7 +212,7 @@
      */
     @Foldable
     public static MethodHandleRef ofDynamicConstant(ClassRef clazz, String name, ClassRef returnType, ClassRef... paramTypes) {
-        return of(STATIC, clazz, name, MethodTypeRef.of(returnType, paramTypes).insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS));
+        return of(STATIC, clazz, name, MethodTypeRef.of(returnType, paramTypes).insertParameterTypes(0, SymbolicRefs.CONDY_BOOTSTRAP_ARGS));
     }
 
     /**
--- a/src/java.base/share/classes/java/lang/sym/MethodTypeRef.java	Fri Feb 09 13:36:17 2018 -0500
+++ b/src/java.base/share/classes/java/lang/sym/MethodTypeRef.java	Fri Feb 09 17:19:25 2018 -0800
@@ -74,7 +74,10 @@
      */
     @Foldable
     public static MethodTypeRef ofDescriptor(String descriptor) {
-        // @@@ Find a lower-overhead way of validating the descriptor
+        // @@@ Replace validation with a lower-overhead mechanism than regex
+        // Follow the trail from MethodType.fromMethodDescriptorString to
+        // parsing code in sun/invoke/util/BytecodeDescriptor.java which could
+        // be extracted and/or shared
         Matcher matcher = pattern.matcher(descriptor);
         if (!matcher.matches())
             throw new IllegalArgumentException(String.format("%s is not a valid method descriptor", descriptor));
@@ -147,7 +150,7 @@
      * @return the parameter types
      */
     public List<ClassRef> parameterList() {
-        return Arrays.asList(argTypes);
+        return List.of(argTypes);
     }
 
     /**
--- a/src/java.base/share/classes/java/lang/sym/SymbolicRef.java	Fri Feb 09 13:36:17 2018 -0500
+++ b/src/java.base/share/classes/java/lang/sym/SymbolicRef.java	Fri Feb 09 17:19:25 2018 -0800
@@ -24,12 +24,7 @@
  */
 package java.lang.sym;
 
-import java.lang.annotation.Foldable;
 import java.lang.invoke.Intrinsics;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.Optional;
 
 /**
  * A purely nominal descriptor for an object, runtime entity, or classfile entity
@@ -51,11 +46,9 @@
  * <p>Constants describing various useful symbolic references (such as {@link ClassRef}
  * constants for platform classes) can be found in {@link SymbolicRefs}.
  *
- *
  * @apiNote In the future, if the Java language permits, {@linkplain SymbolicRef}
  * may become a {@code sealed} interface, which would prohibit subclassing except by
  * explicitly permitted types.
- *
  * @see Constable
  * @see ConstantRef
  * @see Intrinsics
--- a/src/java.base/share/classes/java/lang/sym/SymbolicRefs.java	Fri Feb 09 13:36:17 2018 -0500
+++ b/src/java.base/share/classes/java/lang/sym/SymbolicRefs.java	Fri Feb 09 17:19:25 2018 -0800
@@ -195,6 +195,17 @@
     @Foldable
     static final ClassRef CR_ConstantBootstraps = ClassRef.of("java.lang.invoke.ConstantBootstraps");
 
+    // Used by MethodHandleRef, but initialized here before reference to
+    // MethodHandleRef to avoid static initalization circularities
+    static final ClassRef[] INDY_BOOTSTRAP_ARGS = {
+            SymbolicRefs.CR_MethodHandles_Lookup,
+            SymbolicRefs.CR_String,
+            SymbolicRefs.CR_MethodType };
+    static final ClassRef[] CONDY_BOOTSTRAP_ARGS = {
+            SymbolicRefs.CR_MethodHandles_Lookup,
+            SymbolicRefs.CR_String,
+            SymbolicRefs.CR_Class };
+
     /** {@link MethodHandleRef} representing {@link ConstantBootstraps#primitiveClass(Lookup, String, Class)} */
     @Foldable
     public static final MethodHandleRef BSM_PRIMITIVE_CLASS
--- a/src/java.base/share/classes/java/lang/sym/VarHandleRef.java	Fri Feb 09 13:36:17 2018 -0500
+++ b/src/java.base/share/classes/java/lang/sym/VarHandleRef.java	Fri Feb 09 17:19:25 2018 -0800
@@ -29,6 +29,7 @@
 import java.lang.invoke.VarHandle;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.NoSuchElementException;
 import java.util.Objects;
 import java.util.Optional;
 
@@ -194,23 +195,20 @@
 
     @Override
     public Optional<ConstantRef<ConstantRef<VarHandle>>> toSymbolicRef(MethodHandles.Lookup lookup) {
-        var declaringClassRefRef = declaringClass.toSymbolicRef(lookup);
-        if (!declaringClassRefRef.isPresent())
+        try {
+            ArrayList<ConstantRef<?>> args = new ArrayList<>();
+            args.add(kind.refFactory);
+            args.add(declaringClass.toSymbolicRef(lookup).orElseThrow());
+            if (kind != Kind.ARRAY) {
+                args.add(name());
+                args.add(varType.toSymbolicRef(lookup).orElseThrow());
+            }
+            return Optional.of(DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, name(),
+                                                     SymbolicRefs.CR_VarHandleRef,
+                                                     args.toArray(EMPTY_ARGS)));
+        } catch (NoSuchElementException e) {
             return Optional.empty();
-
-        ArrayList<ConstantRef<?>> args = new ArrayList<>();
-        args.add(kind.refFactory);
-        args.add(declaringClassRefRef.get());
-        if (kind != Kind.ARRAY) {
-            args.add(name());
-            var varTypeRefRef = varType.toSymbolicRef(lookup);
-            if (!varTypeRefRef.isPresent())
-                return Optional.empty();
-            args.add(varTypeRefRef.get());
         }
-        return Optional.of(DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, name(),
-                                                 SymbolicRefs.CR_VarHandleRef,
-                                                 args.toArray(EMPTY_ARGS)));
     }
 
     @Override