changeset 49136:f211e9713517 condy-folding

Separate ConstantRef from SymbolicRef; update docs; update APIs accordingly; move 'implements Constable' down from SymRef to the various ConstantRef subtypes
author briangoetz
date Fri, 09 Feb 2018 13:36:17 -0500
parents aaf5804a4f69
children 0d2b7ad907b3
files src/java.base/share/classes/java/lang/Class.java src/java.base/share/classes/java/lang/Double.java src/java.base/share/classes/java/lang/Enum.java src/java.base/share/classes/java/lang/Float.java src/java.base/share/classes/java/lang/Integer.java src/java.base/share/classes/java/lang/Long.java src/java.base/share/classes/java/lang/String.java src/java.base/share/classes/java/lang/annotation/Foldable.java src/java.base/share/classes/java/lang/invoke/Intrinsics.java src/java.base/share/classes/java/lang/sym/ClassRef.java src/java.base/share/classes/java/lang/sym/Constable.java src/java.base/share/classes/java/lang/sym/ConstantRef.java src/java.base/share/classes/java/lang/sym/DynamicCallSiteRef.java src/java.base/share/classes/java/lang/sym/DynamicConstantRef.java src/java.base/share/classes/java/lang/sym/EnumRef.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 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java test/jdk/java/lang/sym/CondyRefTest.java test/jdk/java/lang/sym/IntrinsifiedRefTest.java test/jdk/java/lang/sym/SymbolicRefTest.java
diffstat 25 files changed, 287 insertions(+), 243 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/Class.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Class.java	Fri Feb 09 13:36:17 2018 -0500
@@ -134,7 +134,7 @@
                               GenericDeclaration,
                               Type,
                               AnnotatedElement,
-                              Constable<Class<?>> {
+                              Constable<Class<T>> {
     private static final int ANNOTATION= 0x00002000;
     private static final int ENUM      = 0x00004000;
     private static final int SYNTHETIC = 0x00001000;
--- a/src/java.base/share/classes/java/lang/Double.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Double.java	Fri Feb 09 13:36:17 2018 -0500
@@ -25,7 +25,7 @@
 
 package java.lang;
 
-import java.lang.sym.SymbolicRef;
+import java.lang.sym.ConstantRef;
 
 import jdk.internal.math.FloatingDecimal;
 import jdk.internal.math.DoubleConsts;
@@ -48,7 +48,7 @@
  * @author  Joseph D. Darcy
  * @since 1.0
  */
-public final class Double extends Number implements Comparable<Double>, SymbolicRef.OfSelf<Double> {
+public final class Double extends Number implements Comparable<Double>, ConstantRef.OfSelf<Double> {
     /**
      * A constant holding the positive infinity of type
      * {@code double}. It is equal to the value returned by
--- a/src/java.base/share/classes/java/lang/Enum.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Enum.java	Fri Feb 09 13:36:17 2018 -0500
@@ -31,10 +31,8 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamException;
 import java.lang.invoke.MethodHandles;
-import java.lang.sym.ClassRef;
 import java.lang.sym.Constable;
 import java.lang.sym.EnumRef;
-import java.lang.sym.SymbolicRef;
 import java.util.Optional;
 
 /**
--- a/src/java.base/share/classes/java/lang/Float.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Float.java	Fri Feb 09 13:36:17 2018 -0500
@@ -25,7 +25,7 @@
 
 package java.lang;
 
-import java.lang.sym.SymbolicRef;
+import java.lang.sym.ConstantRef;
 
 import jdk.internal.math.FloatingDecimal;
 import jdk.internal.HotSpotIntrinsicCandidate;
@@ -47,7 +47,7 @@
  * @author  Joseph D. Darcy
  * @since 1.0
  */
-public final class Float extends Number implements Comparable<Float>, SymbolicRef.OfSelf<Float> {
+public final class Float extends Number implements Comparable<Float>, ConstantRef.OfSelf<Float> {
     /**
      * A constant holding the positive infinity of type
      * {@code float}. It is equal to the value returned by
--- a/src/java.base/share/classes/java/lang/Integer.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Integer.java	Fri Feb 09 13:36:17 2018 -0500
@@ -26,7 +26,7 @@
 package java.lang;
 
 import java.lang.annotation.Native;
-import java.lang.sym.SymbolicRef;
+import java.lang.sym.ConstantRef;
 import java.util.Objects;
 import jdk.internal.HotSpotIntrinsicCandidate;
 import jdk.internal.misc.VM;
@@ -57,7 +57,7 @@
  * @author  Joseph D. Darcy
  * @since 1.0
  */
-public final class Integer extends Number implements Comparable<Integer>, SymbolicRef.OfSelf<Integer> {
+public final class Integer extends Number implements Comparable<Integer>, ConstantRef.OfSelf<Integer> {
     /**
      * A constant holding the minimum value an {@code int} can
      * have, -2<sup>31</sup>.
--- a/src/java.base/share/classes/java/lang/Long.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/Long.java	Fri Feb 09 13:36:17 2018 -0500
@@ -26,7 +26,7 @@
 package java.lang;
 
 import java.lang.annotation.Native;
-import java.lang.sym.SymbolicRef;
+import java.lang.sym.ConstantRef;
 import java.math.*;
 import java.util.Objects;
 import jdk.internal.HotSpotIntrinsicCandidate;
@@ -57,7 +57,7 @@
  * @author  Joseph D. Darcy
  * @since   1.0
  */
-public final class Long extends Number implements Comparable<Long>, SymbolicRef.OfSelf<Long> {
+public final class Long extends Number implements Comparable<Long>, ConstantRef.OfSelf<Long> {
     /**
      * A constant holding the minimum value a {@code long} can
      * have, -2<sup>63</sup>.
--- a/src/java.base/share/classes/java/lang/String.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/String.java	Fri Feb 09 13:36:17 2018 -0500
@@ -28,7 +28,7 @@
 import java.io.ObjectStreamField;
 import java.io.UnsupportedEncodingException;
 import java.lang.annotation.Native;
-import java.lang.sym.SymbolicRef;
+import java.lang.sym.ConstantRef;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -122,7 +122,7 @@
  */
 
 public final class String
-    implements java.io.Serializable, Comparable<String>, CharSequence, SymbolicRef.OfSelf<String> {
+    implements java.io.Serializable, Comparable<String>, CharSequence, ConstantRef.OfSelf<String> {
 
     /**
      * The value is used for character storage.
--- a/src/java.base/share/classes/java/lang/annotation/Foldable.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/annotation/Foldable.java	Fri Feb 09 13:36:17 2018 -0500
@@ -25,7 +25,7 @@
 package java.lang.annotation;
 
 import java.lang.sym.Constable;
-import java.lang.sym.SymbolicRef;
+import java.lang.sym.ConstantRef;
 import java.lang.invoke.Intrinsics;
 
 /**
@@ -33,7 +33,7 @@
  * Such a method must be a <em>pure function</em> of its inputs, all inputs
  * (including the receiver, if applied to an instance method) must be value-based
  * types, and the output must be a value-based type that is representable
- * in the constant pool ({@link Constable} or {@link SymbolicRef}).
+ * in the constant pool ({@link Constable} or {@link ConstantRef}).
  *
  * <p>For accesses of fields annotated as {@linkplain Foldable}, and invocations
  * of methods annotated as {@linkplain Foldable} whose arguments (and, for instance
@@ -43,7 +43,7 @@
  * intrinsification via methods in {@link Intrinsics}.
  *
  * @see Constable
- * @see SymbolicRef
+ * @see ConstantRef
  * @see Intrinsics
  */
 @Retention(RetentionPolicy.CLASS)
--- a/src/java.base/share/classes/java/lang/invoke/Intrinsics.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/Intrinsics.java	Fri Feb 09 13:36:17 2018 -0500
@@ -24,8 +24,8 @@
  */
 package java.lang.invoke;
 
+import java.lang.sym.ConstantRef;
 import java.lang.sym.DynamicCallSiteRef;
-import java.lang.sym.SymbolicRef;
 
 /**
  * Intrinsics
@@ -41,7 +41,7 @@
      * @param constant a constant to be ldc'ed
      * @return the constant wrapped inside the {@code Constable} object
      */
-    public static <T> T ldc(SymbolicRef<T> constant) {
+    public static <T> T ldc(ConstantRef<T> constant) {
         throw new UnsupportedOperationException("no reflective access");
     }
 
--- a/src/java.base/share/classes/java/lang/sym/ClassRef.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/ClassRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -40,7 +40,7 @@
 /**
  * A symbolic reference for a {@link Class}.
  */
-public class ClassRef implements SymbolicRef.WithTypeDescriptor<Class<?>> {
+public class ClassRef implements ConstantRef.WithTypeDescriptor<Class<?>>, Constable<ConstantRef<Class<?>>> {
     private static final Pattern TYPE_DESC = Pattern.compile("(\\[*)(V|I|J|S|B|C|F|D|Z|L[^/.\\[;][^.\\[;]*;)");
 
     private final String descriptor;
@@ -244,8 +244,8 @@
     }
 
     @Override
-    public Optional<? extends SymbolicRef<Class<?>>> toSymbolicRef(MethodHandles.Lookup lookup) {
-        return Optional.of(DynamicConstantRef.<Class<?>>of(SymbolicRefs.BSM_INVOKE, SymbolicRefs.CR_ClassRef)
+    public Optional<ConstantRef<ConstantRef<Class<?>>>> toSymbolicRef(MethodHandles.Lookup lookup) {
+        return Optional.of(DynamicConstantRef.<ConstantRef<Class<?>>>of(SymbolicRefs.BSM_INVOKE, SymbolicRefs.CR_ClassRef)
                                    .withArgs(SymbolicRefs.MHR_CLASSREF_FACTORY, descriptor));
     }
 
--- a/src/java.base/share/classes/java/lang/sym/Constable.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/Constable.java	Fri Feb 09 13:36:17 2018 -0500
@@ -27,28 +27,31 @@
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle;
 import java.util.Optional;
 
 /**
- * A type which can be stored in the constant pool of a Java classfile.
- * {@linkplain Constable} describe themselves for storage in the constant pool
- * by a {@link SymbolicRef}.  {@linkplain Constable} types include the types
- * that act as their own symbolic references ({@link String}, {@link Integer},
- * {@link Long}, {@link Float}, {@link Double}), types for which explicit
- * constant pool forms exist ({@link Class}, {@link MethodType}, and {@link MethodHandle}),
- * and other types corresponding to core language features ({@link Enum}).
+ * A type whose instances can describe themselves as a {@link ConstantRef}.
+ * {@linkplain Constable} types include those types which have native
+ * representation in the constant pool ({@link String}, {@link Integer},
+ * {@link Long}, {@link Float}, {@link Double}, {@link Class}, {@link MethodType},
+ * and {@link MethodHandle}), runtime support classes such as {@link VarHandle},
+ * and types corresponding to core language features ({@link Enum}).
  *
  * <p>The symbolic description is obtained via {@link #toSymbolicRef(MethodHandles.Lookup)}.
- * Not all instances of a {@linkplain Constable} type need be representable in
- * the constant pool; for example, direct method handles have a native form
- * in the constant pool, but the result of method handle combinators such as
- * {@link MethodHandle#asType(MethodType)} do not.  This method uses {@link Optional}
- * to represent whether or not the {@linkplain Constable} can be stored in the
- * constant pool.
+ * A {@linkplain Constable} need not be able to render all instances in the form
+ * of a {@link ConstantRef}; this method returns {@link Optional} to indicate
+ * whether such a description could be created for a particular instance.
+ * (For example, {@link MethodHandle} will produce symbolic descriptions for
+ * direct methods handles, but not necessarily for method handles resulting from
+ * method handle combinators such as {@link MethodHandle#asType(MethodType)}.)
+ *
+ * @param <T> the type of the class implementing {@linkplain Constable}
  */
 public interface Constable<T> {
     /**
-     * Return a symbolic reference for this instance, if one can be constructed.
+     * Return a symbolic constant reference for this instance, if one can be
+     * constructed.
      *
      * @implSpec This method behaves as if {@link #toSymbolicRef(MethodHandles.Lookup)}
      * were called with a lookup parameter of {@code MethodHandles.publicLookup()}.
@@ -56,14 +59,15 @@
      * @return An {@link Optional} describing the resulting symbolic reference,
      * or an empty {@link Optional} if one cannot be constructed
      */
-    default Optional<? extends SymbolicRef<T>> toSymbolicRef() {
+    default Optional<? extends ConstantRef<? super T>> toSymbolicRef() {
         return toSymbolicRef(MethodHandles.publicLookup());
     }
 
     /**
-     * Return a symbolic reference for this instance, if one can be constructed
-     * and this object (and any classes needed to construct its symbolic description)
-     * is accessible from the class described by the {@code lookup} parameter.
+     * Return a symbolic constant reference for this instance, if one can be
+     * constructed.  This object (and any classes needed to construct its
+     * symbolic description) must be accessible from the class described by the
+     * {@code lookup} parameter.
      *
      * @param lookup A {@link MethodHandles.Lookup} to be used to perform
      *               access control determinations
@@ -71,5 +75,5 @@
      * or an empty {@link Optional} if one cannot be constructed or this object
      * is not accessible from {@code lookup}
      */
-    Optional<? extends SymbolicRef<T>> toSymbolicRef(MethodHandles.Lookup lookup);
+    Optional<? extends ConstantRef<? super T>> toSymbolicRef(MethodHandles.Lookup lookup);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/ConstantRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+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.lang.invoke.VarHandle;
+import java.util.Optional;
+
+/**
+ * A {@link SymbolicRef} for an object expressible in a classfile constant pool.
+ *
+ * <p>Static constants that can appear natively in the constant pool ({@link String},
+ * {@link Integer}, {@link Long}, {@link Float}, and {@link Double}) implement
+ * {@link ConstantRef}, serving as symbolic references for themselves.
+ * Native linkable constant types ({@link Class}, {@link MethodType}, and
+ * {@link MethodHandle}) have counterpart {@linkplain ConstantRef} types:
+ * ({@link ClassRef}, {@link MethodTypeRef}, and {@link MethodHandleRef}.)
+ * Dynamic constants are represented by {@link DynamicConstantRef}.
+ *
+ * <p>APIs that perform generation or parsing of bytecode are encouraged to use
+ * {@linkplain ConstantRef} to describe the operand of an {@code ldc} instruction
+ * (including dynamic constants), the static bootstrap arguments of
+ * dynamic constants and {@code invokedynamic} instructions, and any other
+ * bytecodes or classfile structures that make use of the constant pool.
+ *
+ * <p>The {@linkplain ConstantRef} types are also used by {@link Intrinsics}
+ * to express {@code ldc} instructions.
+ *
+ * <p>Non-platform classes should not implement {@linkplain ConstantRef} directly.
+ * Instead, they should extend {@link DynamicConstantRef} (as {@link EnumRef}
+ * and {@link VarHandleRef} do.)
+ *
+ * <p>Constants can be reflectively resolved via {@link ConstantRef#resolveRef(MethodHandles.Lookup)}.
+ *
+ * <p>Constants describing various useful symbolic references (such as {@link ClassRef}
+ * constants for platform classes) can be found in {@link SymbolicRefs}.
+ *
+ * <p>Implementations of {@linkplain ConstantRef} must be
+ * <a href="../doc-files/ValueBased.html">value-based</a> classes.
+ *
+ * @apiNote In the future, if the Java language permits, {@linkplain ConstantRef}
+ * may become a {@code sealed} interface, which would prohibit subclassing except by
+ * explicitly permitted types.  Bytecode libraries can assume that the following
+ * 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
+ * @see SymbolicRefs
+ */
+public interface ConstantRef<T> extends SymbolicRef {
+    /**
+     * Resolve this reference reflectively, using a {@link MethodHandles.Lookup}
+     * to resolve any type names into classes.
+     *
+     * @param lookup The {@link MethodHandles.Lookup} to be used in name resolution
+     * @return the resolved object
+     * @throws ReflectiveOperationException if this symbolic reference refers
+     * (directly or indirectly) to a class, method, or field that cannot be
+     * resolved
+     */
+    T resolveRef(MethodHandles.Lookup lookup) throws ReflectiveOperationException;
+
+    /**
+     * A {@linkplain ConstantRef} which is associated with a type descriptor
+     * string that would be the target of a {@code NameAndType} constant.
+     *
+     * @param <T> The type of the object which this {@linkplain ConstantRef}
+     *            describes
+     */
+    interface WithTypeDescriptor<T> extends ConstantRef<T> {
+        /**
+         * Return the descriptor string associated with the object described
+         * by this symbolic reference
+         *
+         * @return the descriptor string
+         */
+        @Foldable
+        String descriptorString();
+    }
+
+    /**
+     * An object that serves as its own symbolic reference.  Only the classes
+     * {@link String}, {@link Integer}, {@link Long}, {@link Float}, and
+     * {@link Double} should implement this interface.
+     *
+     * @param <T> The type of the object which this {@linkplain ConstantRef}
+     *            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
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        default Optional<T> toSymbolicRef(MethodHandles.Lookup lookup) {
+            return Optional.of((T) this);
+        }
+
+        /**
+         * {@inheritDoc}
+         *
+         * @implSpec This implementation returns its receiver
+         *
+         * @param lookup ignored
+         * @return the symbolic reference
+         */
+        @Override
+        @SuppressWarnings("unchecked")
+        default T resolveRef(MethodHandles.Lookup lookup) {
+            return (T) this;
+        }
+    }
+}
--- a/src/java.base/share/classes/java/lang/sym/DynamicCallSiteRef.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/DynamicCallSiteRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -38,11 +38,11 @@
  * A symbolic reference for an {@code invokedynamic} call site.
  */
 @SuppressWarnings("rawtypes")
-public final class DynamicCallSiteRef implements SymbolicRef {
-    private static final SymbolicRef<?>[] EMPTY_ARGS = new SymbolicRef<?>[0];
+public final class DynamicCallSiteRef implements SymbolicRef, Constable<DynamicCallSiteRef> {
+    private static final ConstantRef<?>[] EMPTY_ARGS = new ConstantRef<?>[0];
 
     private final MethodHandleRef bootstrapMethod;
-    private final SymbolicRef<?>[] bootstrapArgs;
+    private final ConstantRef<?>[] bootstrapArgs;
     private final String name;
     private final MethodTypeRef type;
 
@@ -61,7 +61,7 @@
     private DynamicCallSiteRef(MethodHandleRef bootstrapMethod,
                                String name,
                                MethodTypeRef type,
-                               SymbolicRef<?>[] bootstrapArgs) {
+                               ConstantRef<?>[] bootstrapArgs) {
         this.name = Objects.requireNonNull(name);
         this.type = Objects.requireNonNull(type);
         this.bootstrapMethod = Objects.requireNonNull(bootstrapMethod);
@@ -85,7 +85,7 @@
      * @throws NullPointerException if any parameter is null
      */
     @Foldable
-    public static DynamicCallSiteRef ofCanonical(MethodHandleRef bootstrapMethod, String name, MethodTypeRef type, SymbolicRef<?>... bootstrapArgs) {
+    public static DynamicCallSiteRef ofCanonical(MethodHandleRef bootstrapMethod, String name, MethodTypeRef type, ConstantRef<?>... bootstrapArgs) {
         DynamicCallSiteRef ref = new DynamicCallSiteRef(bootstrapMethod, name, type, bootstrapArgs);
         return ref.canonicalize();
     }
@@ -104,7 +104,7 @@
      * @throws NullPointerException if any parameter is null
      */
     @Foldable
-    public static DynamicCallSiteRef of(MethodHandleRef bootstrapMethod, String name, MethodTypeRef type, SymbolicRef<?>... bootstrapArgs) {
+    public static DynamicCallSiteRef of(MethodHandleRef bootstrapMethod, String name, MethodTypeRef type, ConstantRef<?>... bootstrapArgs) {
         return new DynamicCallSiteRef(bootstrapMethod, name, type, bootstrapArgs);
     }
 
@@ -151,7 +151,7 @@
      * @throws NullPointerException if any parameter is null
      */
     @Foldable
-    public DynamicCallSiteRef withArgs(SymbolicRef<?>... bootstrapArgs) {
+    public DynamicCallSiteRef withArgs(ConstantRef<?>... bootstrapArgs) {
         return new DynamicCallSiteRef(bootstrapMethod, name, type, bootstrapArgs);
     }
 
@@ -208,7 +208,7 @@
      * Returns the bootstrap arguments for the {@code invokedynamic}
      * @return the bootstrap arguments for the {@code invokedynamic}
      */
-    public SymbolicRef<?>[] bootstrapArgs() { return bootstrapArgs.clone(); }
+    public ConstantRef<?>[] bootstrapArgs() { return bootstrapArgs.clone(); }
 
     /**
      * Reflectively invokes the bootstrap method, and returns a dynamic invoker
@@ -233,19 +233,14 @@
     }
 
     @Override
-    public Object resolveRef(MethodHandles.Lookup lookup) {
-        throw new UnsupportedOperationException("DynamicCallSiteRef");
-    }
-
-    @Override
-    public Optional<? extends SymbolicRef<?>> toSymbolicRef(MethodHandles.Lookup lookup) {
-        SymbolicRef<?>[] args = new SymbolicRef<?>[bootstrapArgs.length + 4];
-        args[0] = SymbolicRefs.MHR_DYNAMICCALLSITEREF_FACTORY;
+    public Optional<? extends ConstantRef<DynamicCallSiteRef>> toSymbolicRef(MethodHandles.Lookup lookup) {
+        ConstantRef<?>[] args = new ConstantRef<?>[bootstrapArgs.length + 4];
+        args[0] = SymbolicRefs.MHR_DYNAMICCONSTANTREF_FACTORY;
         args[1] = bootstrapMethod;
         args[2] = name;
         args[3] = type;
         System.arraycopy(bootstrapArgs, 0, args, 4, bootstrapArgs.length);
-        return Optional.of(DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, SymbolicRefs.CR_DynamicCallSiteRef).withArgs(args));
+        return Optional.of(DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, name, SymbolicRefs.CR_DynamicConstantRef, args));
     }
 
     @Override
--- a/src/java.base/share/classes/java/lang/sym/DynamicConstantRef.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/DynamicConstantRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -43,16 +43,16 @@
  *
  * @param <T> the type of the dynamic constant
  */
-public class DynamicConstantRef<T> implements SymbolicRef<T> {
-    private static final SymbolicRef<?>[] EMPTY_ARGS = new SymbolicRef<?>[0];
+public class DynamicConstantRef<T> implements ConstantRef<T>, Constable<ConstantRef<T>> {
+    private static final ConstantRef<?>[] EMPTY_ARGS = new ConstantRef<?>[0];
 
     private final MethodHandleRef bootstrapMethod;
-    private final SymbolicRef<?>[] bootstrapArgs;
+    private final ConstantRef<?>[] bootstrapArgs;
     private final String name;
     private final ClassRef type;
 
     @SuppressWarnings("rawtypes")
-    private static final Map<MethodHandleRef, Function<DynamicConstantRef, SymbolicRef>> canonicalMap
+    private static final Map<MethodHandleRef, Function<DynamicConstantRef, ConstantRef<?>>> canonicalMap
             = Map.ofEntries(Map.entry(SymbolicRefs.BSM_PRIMITIVE_CLASS, d -> ClassRef.ofDescriptor(d.name)),
                             Map.entry(SymbolicRefs.BSM_ENUM_CONSTANT, d -> EnumRef.of(d.type, d.name)),
                             Map.entry(SymbolicRefs.BSM_NULL_CONSTANT, d -> SymbolicRefs.NULL),
@@ -81,7 +81,7 @@
      * @throws NullPointerException if any argument is null
      * @throws IllegalArgumentException if {@code name.length()} is zero
      */
-    protected DynamicConstantRef(MethodHandleRef bootstrapMethod, String name, ClassRef type, SymbolicRef<?>[] bootstrapArgs) {
+    protected DynamicConstantRef(MethodHandleRef bootstrapMethod, String name, ClassRef type, ConstantRef<?>[] bootstrapArgs) {
         this.bootstrapMethod = requireNonNull(bootstrapMethod);
         this.name = requireNonNull(name);
         this.type = requireNonNull(type);
@@ -117,7 +117,7 @@
      * @throws NullPointerException if any argument is null
      */
     @Foldable
-    public DynamicConstantRef<T> withArgs(SymbolicRef<?>... bootstrapArgs) {
+    public DynamicConstantRef<T> withArgs(ConstantRef<?>... bootstrapArgs) {
         return new DynamicConstantRef<>(bootstrapMethod, name, type, bootstrapArgs);
     }
 
@@ -140,18 +140,18 @@
      * @throws IllegalArgumentException if {@code name.length()} is zero
      */
     @Foldable
-    public static<T> SymbolicRef<T> ofCanonical(MethodHandleRef bootstrapMethod, String name, ClassRef type, SymbolicRef<?>[] bootstrapArgs) {
+    public static<T> ConstantRef<T> ofCanonical(MethodHandleRef bootstrapMethod, String name, ClassRef type, ConstantRef<?>[] bootstrapArgs) {
         DynamicConstantRef<T> dcr = new DynamicConstantRef<>(bootstrapMethod, name, type, bootstrapArgs);
         return dcr.canonicalize();
     }
 
-    private SymbolicRef<T> canonicalize() {
+    private ConstantRef<T> canonicalize() {
         // @@@ Existing map-based approach is cute but not very robust; need to add more checking of target DCRef
         @SuppressWarnings("rawtypes")
-        Function<DynamicConstantRef, SymbolicRef> f = canonicalMap.get(bootstrapMethod);
+        Function<DynamicConstantRef, ConstantRef<?>> f = canonicalMap.get(bootstrapMethod);
         if (f != null) {
             @SuppressWarnings("unchecked")
-            SymbolicRef<T> converted = f.apply(this);
+            ConstantRef<T> converted = (ConstantRef<T>) f.apply(this);
             return converted;
         }
         return this;
@@ -173,7 +173,7 @@
      * @throws IllegalArgumentException if {@code name.length()} is zero
      */
     @Foldable
-    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, String name, ClassRef type, SymbolicRef<?>[] bootstrapArgs) {
+    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, String name, ClassRef type, ConstantRef<?>[] bootstrapArgs) {
         return new DynamicConstantRef<>(bootstrapMethod, name, type, bootstrapArgs);
     }
 
@@ -278,9 +278,9 @@
      * Returns the bootstrap arguments for this constant
      * @return the bootstrap arguments
      */
-    public SymbolicRef<?>[] bootstrapArgs() { return bootstrapArgs.clone(); }
+    public ConstantRef<?>[] bootstrapArgs() { return bootstrapArgs.clone(); }
 
-    private static Object[] resolveArgs(MethodHandles.Lookup lookup, SymbolicRef<?>[] args) {
+    private static Object[] resolveArgs(MethodHandles.Lookup lookup, ConstantRef<?>[] args) {
         return Stream.of(args)
                      .map(arg -> {
                          try {
@@ -313,14 +313,15 @@
     }
 
     @Override
-    public Optional<? extends SymbolicRef<T>> toSymbolicRef(MethodHandles.Lookup lookup) {
-        SymbolicRef<?>[] args = new SymbolicRef<?>[bootstrapArgs.length + 4];
+    public Optional<? extends ConstantRef<? super ConstantRef<T>>> toSymbolicRef(MethodHandles.Lookup lookup) {
+        ConstantRef<?>[] args = new ConstantRef<?>[bootstrapArgs.length + 4];
         args[0] = SymbolicRefs.MHR_DYNAMICCONSTANTREF_FACTORY;
         args[1] = bootstrapMethod;
         args[2] = name;
         args[3] = type;
         System.arraycopy(bootstrapArgs, 0, args, 4, bootstrapArgs.length);
-        return Optional.of(DynamicConstantRef.<T>of(SymbolicRefs.BSM_INVOKE, name, SymbolicRefs.CR_CondyRef).withArgs(args));
+        ConstantRef<ConstantRef<T>> ref = DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, name, SymbolicRefs.CR_DynamicConstantRef, args);
+        return Optional.of(ref);
     }
 
     @Override
--- a/src/java.base/share/classes/java/lang/sym/EnumRef.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/EnumRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -87,12 +87,12 @@
     }
 
     @Override
-    public Optional<? extends SymbolicRef<E>> toSymbolicRef(MethodHandles.Lookup lookup) {
-        Optional<? extends SymbolicRef<Class<?>>> classRefRef = enumClass().toSymbolicRef(lookup);
+    public Optional<ConstantRef<ConstantRef<E>>> toSymbolicRef(MethodHandles.Lookup lookup) {
+        Optional<ConstantRef<ConstantRef<Class<?>>>> classRefRef = enumClass().toSymbolicRef(lookup);
         if (!classRefRef.isPresent())
             return Optional.empty();
-        return Optional.of(DynamicConstantRef.<E>of(SymbolicRefs.BSM_INVOKE, name(), SymbolicRefs.CR_EnumRef)
-                                   .withArgs(SymbolicRefs.MHR_ENUMREF_FACTORY, classRefRef.get(), constantName()));
+        return Optional.of(DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, name(), SymbolicRefs.CR_EnumRef,
+                                                 new ConstantRef<?>[] { SymbolicRefs.MHR_ENUMREF_FACTORY, classRefRef.get(), constantName() }));
     }
 
     @Override
--- a/src/java.base/share/classes/java/lang/sym/MethodHandleRef.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/MethodHandleRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -47,9 +47,9 @@
 import static java.util.Objects.requireNonNull;
 
 /**
- * A symbolic reference for a {@link MethodHandle}.
+ * A symbolic reference for a {@link MethodHandle} constant.
  */
-public final class MethodHandleRef implements SymbolicRef<MethodHandle> {
+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") };
@@ -318,14 +318,16 @@
     }
 
     @Override
-    public Optional<? extends SymbolicRef<MethodHandle>> toSymbolicRef(MethodHandles.Lookup lookup) {
+    public Optional<ConstantRef<ConstantRef<MethodHandle>>> toSymbolicRef(MethodHandles.Lookup lookup) {
         Optional<EnumRef<Kind>> kindRef = kind.toSymbolicRef(lookup);
-        Optional<? extends SymbolicRef<Class<?>>> classRefRef = owner.toSymbolicRef(lookup);
-        Optional<? extends SymbolicRef<MethodType>> typeRefRef = type.toSymbolicRef(lookup);
+        Optional<ConstantRef<ConstantRef<Class<?>>>> classRefRef = owner.toSymbolicRef(lookup);
+        Optional<ConstantRef<ConstantRef<MethodType>>> typeRefRef = type.toSymbolicRef(lookup);
         if (!kindRef.isPresent() || !classRefRef.isPresent() || !typeRefRef.isPresent())
             return Optional.empty();
-        return Optional.of(DynamicConstantRef.<MethodHandle>of(SymbolicRefs.BSM_INVOKE, name, SymbolicRefs.CR_MethodHandleRef)
-                                   .withArgs(SymbolicRefs.MHR_METHODHANDLEREF_FACTORY, kindRef.get(), classRefRef.get(), name, typeRefRef.get()));
+        ConstantRef<?>[] args = {SymbolicRefs.MHR_METHODHANDLEREF_FACTORY, kindRef.get(),
+                                 classRefRef.get(), name, typeRefRef.get()};
+        return Optional.of(DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, name,
+                                                 SymbolicRefs.CR_MethodHandleRef, args));
     }
 
     @Override
--- a/src/java.base/share/classes/java/lang/sym/MethodTypeRef.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/MethodTypeRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -39,9 +39,9 @@
 import static java.util.Objects.requireNonNull;
 
 /**
- * A symbolic reference for a {@linkplain MethodType}.
+ * A symbolic reference for a {@linkplain MethodType} constant.
  */
-public final class MethodTypeRef implements SymbolicRef.WithTypeDescriptor<MethodType> {
+public final class MethodTypeRef implements ConstantRef.WithTypeDescriptor<MethodType>, Constable<ConstantRef<MethodType>> {
     private static final Pattern TYPE_DESC = Pattern.compile("(\\[*)(V|I|J|S|B|C|F|D|Z|L[^/.\\[;][^.\\[;]*;)");
     private static Pattern pattern = Pattern.compile("\\((.*)\\)(.*)");
 
@@ -238,9 +238,9 @@
     }
 
     @Override
-    public Optional<? extends SymbolicRef<MethodType>> toSymbolicRef(MethodHandles.Lookup lookup) {
-        return Optional.of(DynamicConstantRef.<MethodType>of(SymbolicRefs.BSM_INVOKE, SymbolicRefs.CR_MethodTypeRef)
-                                   .withArgs(SymbolicRefs.MHR_METHODTYPEREF_FACTORY, descriptorString()));
+    public Optional<ConstantRef<ConstantRef<MethodType>>> toSymbolicRef(MethodHandles.Lookup lookup) {
+        ConstantRef<?>[] args = new ConstantRef<?>[] { SymbolicRefs.MHR_METHODTYPEREF_FACTORY, descriptorString() };
+        return Optional.of(DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, "_", SymbolicRefs.CR_MethodTypeRef, args));
     }
 
     @Override
--- a/src/java.base/share/classes/java/lang/sym/SymbolicRef.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/SymbolicRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -32,135 +32,35 @@
 import java.util.Optional;
 
 /**
- * A purely nominal descriptor for a constant value expressible in a classfile
- * constant pool or other classfile structure.
- *
- * <p> Native constant types that don't require linkage ({@link String}, {@link
- * Integer}, {@link Long}, {@link Float}, and {@link Double}) implement
- * {@linkplain SymbolicRef.OfSelf}, indicating that they serve as their own
- * symbolic reference.  Native linkable constant types ({@link
- * Class}, {@link MethodType}, and {@link MethodHandle}) have counterpart
- * {@linkplain SymbolicRef} types: ({@link ClassRef}, {@link MethodTypeRef},
- * and {@link MethodHandleRef}.)  Dynamic constants are represented by
- * {@link DynamicConstantRef}.
+ * A purely nominal descriptor for an object, runtime entity, or classfile entity
+ * such as a constant pool entry or classfile attribute. Like names in the
+ * constant pool of a class, names of classes contained in a {@linkplain SymbolicRef}
+ * are independent of a class loader.
  *
  * <p>APIs that perform generation or parsing of bytecode are encouraged to use
- * {@linkplain SymbolicRef} to describe the operand of an {@code ldc} instruction
- * (including dynamic constants), the static bootstrap arguments of
- * {@code invokedynamic} instructions and dynamic constants, and other bytecodes
- * or classfile structures that make use of the constant pool (such as describing
- * the supertypes of a class or the types of a field.)
+ * {@linkplain SymbolicRef} to describe classfile structures where appropriate,
+ * especially the {@link ConstantRef} types that describe elements to be stored
+ * in the constant pool.
  *
  * <p>The {@linkplain SymbolicRef} types are also used by the {@link Intrinsics}
  * API to express {@code ldc} and {@code invokedynamic} instructions.
  *
- * <p>Like names in the constant pool of a class, names in a {@linkplain SymbolicRef}
- * are independent of a class loader.  When the nominal contents of a
- * {@linkplain SymbolicRef} are written to a classfile, they will be interpreted
- * relative to the class loader loading that class, just like any other names
- * appearing in the constant pool.
- *
- * <p>Symbolic references can be reflectively resolved via
- * {@link SymbolicRef#resolveRef(MethodHandles.Lookup)}.
- *
- * <p>Symbolic references may themselves be described symbolically, and therefore
- * stored in the constant pool.  {@linkplain SymbolicRef} implements {@link Constable}
- * for this reason.
+ * <p>Implementations of {@linkplain SymbolicRef} must be
+ * <a href="../doc-files/ValueBased.html">value-based</a> classes.
  *
  * <p>Constants describing various useful symbolic references (such as {@link ClassRef}
  * constants for platform classes) can be found in {@link SymbolicRefs}.
  *
- * <p>Non-platform classes should not implement {@linkplain SymbolicRef} directly.
- * Instead, they should extend {@link DynamicConstantRef}.
- *
- * <p>Implementations of {@linkplain SymbolicRef} must be
- * <a href="../doc-files/ValueBased.html">value-based</a> classes.
  *
  * @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.
  *
- * @param <T> The type of the object which this {@linkplain SymbolicRef}
- *            describes
  * @see Constable
+ * @see ConstantRef
  * @see Intrinsics
  * @see SymbolicRefs
  */
-public interface SymbolicRef<T> extends Constable<T> {
+public interface SymbolicRef {
 
-    /**
-     * Resolve this symbolic reference reflectively, using a {@link MethodHandles.Lookup}
-     * to resolve any type names into classes.
-     *
-     * @param lookup The {@link MethodHandles.Lookup} to be used in name resolution
-     * @return the resolved object
-     * @throws ReflectiveOperationException if this symbolic reference refers
-     * (directly or indirectly) to a class, method, or field that cannot be
-     * resolved
-     */
-    T resolveRef(MethodHandles.Lookup lookup) throws ReflectiveOperationException;
-
-    /**
-     *  Returns a symbolic reference that describes this symbolic reference.
-     *
-     * @param lookup ignored
-     * @return the symbolic reference
-     */
-    Optional<? extends SymbolicRef<T>> toSymbolicRef(MethodHandles.Lookup lookup);
-
-    /**
-     * A {@linkplain SymbolicRef} which is associated with a type descriptor
-     * string that would be the target of a {@code NameAndType} constant.
-     *
-     * @param <T> The type of the object which this {@linkplain SymbolicRef}
-     *            describes
-     */
-    interface WithTypeDescriptor<T> extends SymbolicRef<T> {
-        /**
-         * Return the descriptor string associated with the object described
-         * by this symbolic reference
-         *
-         * @return the descriptor string
-         */
-        @Foldable
-        String descriptorString();
-    }
-
-    /**
-     * An object that serves as its own symbolic reference.  Only the classes
-     * {@link String}, {@link Integer}, {@link Long}, {@link Float}, and
-     * {@link Double} should implement this interface.
-     *
-     * @param <T> The type of the object which this {@linkplain SymbolicRef}
-     *            describes
-     */
-    interface OfSelf<T extends SymbolicRef<T>> extends SymbolicRef<T>, Constable<T> {
-        /**
-         * {@inheritDoc}
-         *
-         * @implSpec This implementation returns its receiver
-         *
-         * @param lookup ignored
-         * @return the symbolic reference
-         */
-        @Override
-        @SuppressWarnings("unchecked")
-        default Optional<T> toSymbolicRef(MethodHandles.Lookup lookup) {
-            return Optional.of((T) this);
-        }
-
-        /**
-         * {@inheritDoc}
-         *
-         * @implSpec This implementation returns its receiver
-         *
-         * @param lookup ignored
-         * @return the symbolic reference
-         */
-        @Override
-        @SuppressWarnings("unchecked")
-        default T resolveRef(MethodHandles.Lookup lookup) {
-            return (T) this;
-        }
-    }
 }
--- a/src/java.base/share/classes/java/lang/sym/SymbolicRefs.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/SymbolicRefs.java	Fri Feb 09 13:36:17 2018 -0500
@@ -185,7 +185,7 @@
 
     /** {@link ClassRef} representing {@link DynamicConstantRef} */
     @Foldable
-    static final ClassRef CR_CondyRef = ClassRef.of("java.lang.sym.DynamicConstantRef");
+    static final ClassRef CR_DynamicConstantRef = ClassRef.of("java.lang.sym.DynamicConstantRef");
 
     /** {@link ClassRef} representing {@link DynamicCallSiteRef} */
     @Foldable
@@ -268,7 +268,7 @@
 
     /** Symbolic reference representing the constant {@code null} */
     @Foldable
-    public static final SymbolicRef<?> NULL = DynamicConstantRef.of(SymbolicRefs.BSM_NULL_CONSTANT, SymbolicRefs.CR_Object);
+    public static final ConstantRef<?> NULL = DynamicConstantRef.of(SymbolicRefs.BSM_NULL_CONSTANT, SymbolicRefs.CR_Object);
 
     /** {@link MethodHandleRef} representing the factory method {@link ClassRef#ofDescriptor(String)} */
     @Foldable
@@ -306,15 +306,9 @@
     static final MethodHandleRef MHR_VARHANDLEREF_ARRAY_FACTORY
             = MethodHandleRef.of(Kind.STATIC, CR_VarHandleRef, "ofArray", CR_VarHandleRef, CR_ClassRef);
 
-    /** {@link MethodHandleRef} representing the factory method {@link DynamicConstantRef#of(MethodHandleRef, String, ClassRef, SymbolicRef[])} */
+    /** {@link MethodHandleRef} representing the factory method {@link DynamicConstantRef#of(MethodHandleRef, String, ClassRef, ConstantRef[])} */
     @Foldable
     static final MethodHandleRef MHR_DYNAMICCONSTANTREF_FACTORY
-            = MethodHandleRef.of(Kind.STATIC, CR_CondyRef, "of",
-                                 CR_CondyRef, CR_MethodHandleRef, CR_String, CR_ClassRef, CR_SymbolicRef.array());
-
-    /** {@link MethodHandleRef} representing the factory method {@link DynamicCallSiteRef#of(MethodHandleRef, String, MethodTypeRef, SymbolicRef[])} */
-    @Foldable
-    static final MethodHandleRef MHR_DYNAMICCALLSITEREF_FACTORY
-            = MethodHandleRef.of(Kind.STATIC, CR_DynamicCallSiteRef, "of",
-                                 CR_DynamicCallSiteRef, CR_MethodHandleRef, CR_String, CR_MethodTypeRef, CR_SymbolicRef.array());
+            = MethodHandleRef.of(Kind.STATIC, CR_DynamicConstantRef, "of",
+                                 CR_DynamicConstantRef, CR_MethodHandleRef, CR_String, CR_ClassRef, CR_SymbolicRef.array());
 }
--- a/src/java.base/share/classes/java/lang/sym/VarHandleRef.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/java.base/share/classes/java/lang/sym/VarHandleRef.java	Fri Feb 09 13:36:17 2018 -0500
@@ -33,11 +33,12 @@
 import java.util.Optional;
 
 /**
- * A symbolic reference for a {@link VarHandle}.
+ * A symbolic reference for a {@link VarHandle} constant.
  */
-public final class VarHandleRef extends DynamicConstantRef<VarHandle> {
+public final class VarHandleRef extends DynamicConstantRef<VarHandle>
+        implements Constable<ConstantRef<VarHandle>> {
 
-    private static final SymbolicRef<?>[] EMPTY_ARGS = new SymbolicRef<?>[0];
+    private static final ConstantRef<?>[] EMPTY_ARGS = new ConstantRef<?>[0];
 
     /**
      * Kinds of variable handle refs
@@ -55,7 +56,7 @@
             this.refFactory = refFactory;
         }
 
-        List<SymbolicRef<?>> toBSMArgs(ClassRef declaringClass, String name, ClassRef varType) {
+        List<ConstantRef<?>> toBSMArgs(ClassRef declaringClass, String name, ClassRef varType) {
             switch (this) {
                 case FIELD:
                 case STATIC_FIELD:
@@ -192,12 +193,12 @@
     }
 
     @Override
-    public Optional<? extends SymbolicRef<VarHandle>> toSymbolicRef(MethodHandles.Lookup lookup) {
+    public Optional<ConstantRef<ConstantRef<VarHandle>>> toSymbolicRef(MethodHandles.Lookup lookup) {
         var declaringClassRefRef = declaringClass.toSymbolicRef(lookup);
         if (!declaringClassRefRef.isPresent())
             return Optional.empty();
 
-        var args = new ArrayList<SymbolicRef<?>>();
+        ArrayList<ConstantRef<?>> args = new ArrayList<>();
         args.add(kind.refFactory);
         args.add(declaringClassRefRef.get());
         if (kind != Kind.ARRAY) {
@@ -207,8 +208,9 @@
                 return Optional.empty();
             args.add(varTypeRefRef.get());
         }
-        return Optional.of(DynamicConstantRef.<VarHandle>of(SymbolicRefs.BSM_INVOKE, name(), SymbolicRefs.CR_VarHandleRef)
-                                   .withArgs(args.toArray(EMPTY_ARGS)));
+        return Optional.of(DynamicConstantRef.of(SymbolicRefs.BSM_INVOKE, name(),
+                                                 SymbolicRefs.CR_VarHandleRef,
+                                                 args.toArray(EMPTY_ARGS)));
     }
 
     @Override
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Feb 09 13:36:17 2018 -0500
@@ -173,7 +173,6 @@
     public final Type methodHandlesLookupType;
     public final Type classRefType;
     public final Type dynamicConstantRefType;
-    public final Type symbolicRefType;
     public final Type intrinsicsType;
     public final Type methodTypeType;
     public final Type foldableType;
@@ -501,7 +500,6 @@
         methodHandleType = enterClass("java.lang.invoke.MethodHandle");
         methodHandlesLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup");
         dynamicConstantRefType = enterClass("java.lang.sym.DynamicConstantRef");
-        symbolicRefType = enterClass("java.lang.sym.SymbolicRef");
         classRefType = enterClass("java.lang.sym.ClassRef");
         intrinsicsType = enterClass("java.lang.invoke.Intrinsics");
         methodTypeType = enterClass("java.lang.invoke.MethodType");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Fri Feb 09 13:36:17 2018 -0500
@@ -93,10 +93,9 @@
             methodHandleRefClass = Class.forName("java.lang.sym.MethodHandleRef", false, null);
             methodTypeRefClass = Class.forName("java.lang.sym.MethodTypeRef", false, null);
             classRefClass = Class.forName("java.lang.sym.ClassRef", false, null);
-            constantRefClass = Class.forName("java.lang.sym.SymbolicRef", false, null);
+            constantRefClass = Class.forName("java.lang.sym.ConstantRef", false, null);
             dynamicCallsiteRefClass = Class.forName("java.lang.sym.DynamicCallSiteRef", false, null);
             dynamicConstantClass = Class.forName("java.lang.sym.DynamicConstantRef", false, null);
-            symbolicRefClass = Class.forName("java.lang.sym.SymbolicRef", false, null);
             symRefs = Class.forName("java.lang.sym.SymbolicRefs", false, null);
         } catch (ClassNotFoundException ex) {
             methodHandleRefClass = null;
@@ -106,7 +105,6 @@
             dynamicCallsiteRefClass = null;
             dynamicConstantClass = null;
             symRefs = null;
-            symbolicRefClass = null;
         }
     }
 
@@ -275,8 +273,8 @@
     public Optional<DynamicFieldSymbol> getDynamicFieldSymbol(JCTree tree, Object constant, Env<AttrContext> attrEnv) {
         if (constant != null) {
             if (!canMakeItToConstantValue(tree.type) &&
-                symbolicRefClass.isInstance(constant)) {
-                constant = ((Optional<?>)invokeMethodReflectively(symbolicRefClass, constant, "toSymbolicRef")).get();
+                constantRefClass.isInstance(constant)) {
+                constant = ((Optional<?>)invokeMethodReflectively(constant.getClass(), constant, "toSymbolicRef")).get();
                 // now this should be a condy that the compiler can understand
                 // a Pool.ConstantDynamic
                 Object condyOb = convertConstant(tree, attrEnv, constant, attrEnv.enclClass.sym.packge().modle);
@@ -430,7 +428,6 @@
     public Class<?> constantRefClass;
     public Class<?> dynamicCallsiteRefClass;
     public Class<?> dynamicConstantClass;
-    public Class<?> symbolicRefClass;
     public Class<?> symRefs;
 
     public boolean canMakeItToConstantValue(Type t) {
--- a/test/jdk/java/lang/sym/CondyRefTest.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/test/jdk/java/lang/sym/CondyRefTest.java	Fri Feb 09 13:36:17 2018 -0500
@@ -26,6 +26,7 @@
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.VarHandle;
 import java.lang.sym.ClassRef;
+import java.lang.sym.ConstantRef;
 import java.lang.sym.DynamicConstantRef;
 import java.lang.sym.EnumRef;
 import java.lang.sym.MethodHandleRef;
@@ -53,7 +54,7 @@
  */
 @Test
 public class CondyRefTest extends SymbolicRefTest {
-    private final static SymbolicRef[] EMPTY_ARGS = new SymbolicRef[0];
+    private final static ConstantRef<?>[] EMPTY_ARGS = new ConstantRef<?>[0];
     private final static ClassRef CR_ConstantBootstraps = ClassRef.of("java.lang.invoke.ConstantBootstraps");
 
     private static<T> void testDCR(DynamicConstantRef<T> r, T c) throws ReflectiveOperationException {
@@ -163,9 +164,9 @@
         assertEquals(3, ints[2]);
     }
 
-    private<T> void assertLifted(SymbolicRef<T> prototype,
+    private<T> void assertLifted(ConstantRef<T> prototype,
                                  DynamicConstantRef<T> nonCanonical,
-                                 SymbolicRef<T> canonical) {
+                                 ConstantRef<T> canonical) {
         Class<?> clazz = prototype.getClass();
 
         assertTrue(canonical != nonCanonical);
@@ -200,14 +201,14 @@
 
         ClassRef testClass = ClassRef.of("CondyRefTest").inner("MyClass");
         assertLifted(VarHandleRef.ofStaticField(testClass, "sf", CR_int),
-                     DynamicConstantRef.of(SymbolicRefs.BSM_VARHANDLE_STATIC_FIELD, "sf", CR_VarHandle, new SymbolicRef<?>[] {testClass, "sf", CR_int }),
-                     DynamicConstantRef.ofCanonical(SymbolicRefs.BSM_VARHANDLE_STATIC_FIELD, "sf", CR_VarHandle, new SymbolicRef<?>[] {testClass, "sf", CR_int }));
+                     DynamicConstantRef.of(SymbolicRefs.BSM_VARHANDLE_STATIC_FIELD, "sf", CR_VarHandle, new ConstantRef<?>[] {testClass, "sf", CR_int }),
+                     DynamicConstantRef.ofCanonical(SymbolicRefs.BSM_VARHANDLE_STATIC_FIELD, "sf", CR_VarHandle, new ConstantRef<?>[] {testClass, "sf", CR_int }));
         assertLifted(VarHandleRef.ofField(testClass, "f", CR_int),
-                     DynamicConstantRef.of(SymbolicRefs.BSM_VARHANDLE_FIELD, "f", CR_VarHandle, new SymbolicRef<?>[] {testClass, "f", CR_int }),
-                     DynamicConstantRef.ofCanonical(SymbolicRefs.BSM_VARHANDLE_FIELD, "f", CR_VarHandle, new SymbolicRef<?>[] {testClass, "f", CR_int }));
+                     DynamicConstantRef.of(SymbolicRefs.BSM_VARHANDLE_FIELD, "f", CR_VarHandle, new ConstantRef<?>[] {testClass, "f", CR_int }),
+                     DynamicConstantRef.ofCanonical(SymbolicRefs.BSM_VARHANDLE_FIELD, "f", CR_VarHandle, new ConstantRef<?>[] {testClass, "f", CR_int }));
         assertLifted(VarHandleRef.ofArray(CR_int.array()),
-                     DynamicConstantRef.of(SymbolicRefs.BSM_VARHANDLE_ARRAY, "_", CR_VarHandle, new SymbolicRef<?>[] {CR_int.array() }),
-                     DynamicConstantRef.ofCanonical(SymbolicRefs.BSM_VARHANDLE_ARRAY, "_", CR_VarHandle, new SymbolicRef<?>[] {CR_int.array() }));
+                     DynamicConstantRef.of(SymbolicRefs.BSM_VARHANDLE_ARRAY, "_", CR_VarHandle, new ConstantRef<?>[] {CR_int.array() }),
+                     DynamicConstantRef.ofCanonical(SymbolicRefs.BSM_VARHANDLE_ARRAY, "_", CR_VarHandle, new ConstantRef<?>[] {CR_int.array() }));
     }
 
 }
--- a/test/jdk/java/lang/sym/IntrinsifiedRefTest.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/test/jdk/java/lang/sym/IntrinsifiedRefTest.java	Fri Feb 09 13:36:17 2018 -0500
@@ -27,10 +27,10 @@
 import java.lang.invoke.MethodType;
 import java.lang.sym.ClassRef;
 import java.lang.sym.Constable;
+import java.lang.sym.ConstantRef;
 import java.lang.sym.EnumRef;
 import java.lang.sym.MethodHandleRef;
 import java.lang.sym.MethodTypeRef;
-import java.lang.sym.SymbolicRef;
 import java.lang.sym.SymbolicRefs;
 import java.util.function.Supplier;
 
@@ -82,13 +82,13 @@
 
 
 
-    private static <T extends Constable> void assertIntrinsic(SymbolicRef<T> ref, T intrinsified, T target) throws ReflectiveOperationException {
+    private static <T extends Constable> void assertIntrinsic(ConstantRef<T> ref, T intrinsified, T target) throws ReflectiveOperationException {
         assertEquals(target, intrinsified);
         assertEquals(ref.resolveRef(LOOKUP), intrinsified);
         assertEquals(intrinsified.toSymbolicRef(LOOKUP).orElseThrow(), ref);
     }
 
-    private static<T extends Constable> void assertIntrinsicFail(SymbolicRef<T> ref, Supplier<T> supplier, Class<? extends Throwable> exception) {
+    private static<T extends Constable> void assertIntrinsicFail(ConstantRef<T> ref, Supplier<T> supplier, Class<? extends Throwable> exception) {
         try {
             T t = supplier.get();
             fail("Expected failure resolving " + ref);
--- a/test/jdk/java/lang/sym/SymbolicRefTest.java	Thu Feb 08 22:06:03 2018 +0100
+++ b/test/jdk/java/lang/sym/SymbolicRefTest.java	Fri Feb 09 13:36:17 2018 -0500
@@ -28,11 +28,14 @@
 import java.lang.invoke.MethodHandleInfo;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.lang.reflect.Method;
 import java.lang.sym.ClassRef;
 import java.lang.sym.Constable;
+import java.lang.sym.ConstantRef;
 import java.lang.sym.SymbolicRef;
 import java.lang.sym.SymbolicRefs;
 import java.util.List;
+import java.util.Optional;
 import java.util.stream.Stream;
 
 import static org.testng.Assert.assertEquals;
@@ -89,14 +92,15 @@
         return ClassRef.ofDescriptor(c.toDescriptorString());
     }
 
-    static<T> void testSymbolicRef(SymbolicRef<T> ref) throws ReflectiveOperationException {
+    static<T> void testSymbolicRef(ConstantRef<T> ref) throws ReflectiveOperationException {
         // Round trip sym -> resolve -> toSymbolicRef
-        SymbolicRef<T> s = ((Constable<T>) ref.resolveRef(LOOKUP)).toSymbolicRef(LOOKUP).orElseThrow();
+        ConstantRef<? super ConstantRef<T>> s = ((Constable<ConstantRef<T>>) ref.resolveRef(LOOKUP)).toSymbolicRef(LOOKUP).orElseThrow();
         assertEquals(ref, s);
 
         // Round trip sym -> quoted sym -> resolve
-        SymbolicRef<? extends SymbolicRef<T>> ssr = (SymbolicRef<? extends SymbolicRef<T>>) ref.toSymbolicRef(LOOKUP).orElseThrow();
-        SymbolicRef<T> sr = ssr.resolveRef(LOOKUP);
+        Method m = ref.getClass().getMethod("toSymbolicRef", MethodHandles.Lookup.class);
+        Optional<ConstantRef<ConstantRef<T>>> opt = (Optional<ConstantRef<ConstantRef<T>>>) m.invoke(ref, LOOKUP);
+        ConstantRef<T> sr = opt.orElseThrow().resolveRef(LOOKUP);
         assertEquals(sr, ref);
     }
 }