changeset 48622:534504612399 condy-folding

Move symbolic ref classes from JLI to java.lang.sym; rename ConstantRef to SymbolicRef; reincarnate Constable as 'can be represented with a symbolic ref'; support canonicalization of known bootstraps in DynamicConstantRef
author briangoetz
date Fri, 22 Dec 2017 13:06:32 -0500
parents 7984d0be344d
children 812478fb30e5
files make/CompileJavaModules.gmk 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/TrackableConstant.java src/java.base/share/classes/java/lang/invoke/BootstrapSpecifier.java src/java.base/share/classes/java/lang/invoke/ClassRef.java src/java.base/share/classes/java/lang/invoke/Constables.java src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java src/java.base/share/classes/java/lang/invoke/ConstantRef.java src/java.base/share/classes/java/lang/invoke/DynamicConstantRef.java src/java.base/share/classes/java/lang/invoke/Intrinsics.java src/java.base/share/classes/java/lang/invoke/MethodHandle.java src/java.base/share/classes/java/lang/invoke/MethodHandleRef.java src/java.base/share/classes/java/lang/invoke/MethodType.java src/java.base/share/classes/java/lang/invoke/MethodTypeRef.java src/java.base/share/classes/java/lang/sym/BootstrapSpecifier.java src/java.base/share/classes/java/lang/sym/ClassRef.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/NamedClassRef.java src/java.base/share/classes/java/lang/sym/PrimitiveClassRef.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/module-info.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/invoke/ConstablesTest.java test/jdk/java/lang/invoke/ConstantRefBootstrapsTest.java test/jdk/java/lang/invoke/IntrinsicsTest.java test/langtools/tools/javac/specialConstantFolding/CondyCodeGenerationTest.java test/langtools/tools/javac/specialConstantFolding/CrashWithPrimitiveArgumentsTest.java test/langtools/tools/javac/specialConstantFolding/DontCompileIfSymbolCantBeFoundTest.java test/langtools/tools/javac/specialConstantFolding/EffectivelyFinalTestNeg.java test/langtools/tools/javac/specialConstantFolding/IndyCodeGenerationTest.java test/langtools/tools/javac/specialConstantFolding/IndyCrashTest.java test/langtools/tools/javac/specialConstantFolding/IndyLinkageErrorTest.java test/langtools/tools/javac/specialConstantFolding/IndyNegativeTest01.java test/langtools/tools/javac/specialConstantFolding/IndyPositiveTest01.java test/langtools/tools/javac/specialConstantFolding/LDCNegativeTest.java test/langtools/tools/javac/specialConstantFolding/MultipleBSMEntriesTest.java test/langtools/tools/javac/specialConstantFolding/ReflectiveErrorTest.java test/langtools/tools/javac/specialConstantFolding/ReflectiveErrorTest.out test/langtools/tools/javac/specialConstantFolding/ReportIncorrectMHForIndyTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantDefinitions.java test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantFoldingOfMethodTypeDiffContextsTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantPropagationTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/EffectivelyFinalTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindConstructorTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindGetterTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindMethodWithGenericArgumentsTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindSetterTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticGetterTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticSetterTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindVirtualTest01.java test/langtools/tools/javac/specialConstantFolding/harness/tests/FindVirtualTest02.java test/langtools/tools/javac/specialConstantFolding/harness/tests/InstanceTrackableMethodsTest.java test/langtools/tools/javac/specialConstantFolding/harness/tests/StringFoldingTest.java test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound.java test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.java
diffstat 67 files changed, 2225 insertions(+), 1775 deletions(-) [+]
line wrap: on
line diff
--- a/make/CompileJavaModules.gmk	Wed Dec 20 11:56:26 2017 +0100
+++ b/make/CompileJavaModules.gmk	Fri Dec 22 13:06:32 2017 -0500
@@ -42,7 +42,7 @@
 
 ################################################################################
 
-java.base_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*,-java.lang.invoke' -XDstringConcat=inline
+java.base_ADD_JAVAC_FLAGS += -Xdoclint:all/protected,-reference '-Xdoclint/package:java.*,javax.*,-java.lang.sym' -XDstringConcat=inline
 java.base_COPY += .icu .dat .spp content-types.properties hijrah-config-islamic-umalqura.properties
 java.base_CLEAN += intrinsic.properties
 
--- a/src/java.base/share/classes/java/lang/Class.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/Class.java	Fri Dec 22 13:06:32 2017 -0500
@@ -26,6 +26,7 @@
 package java.lang;
 
 import java.lang.annotation.Annotation;
+import java.lang.invoke.MethodHandles;
 import java.lang.module.ModuleReader;
 import java.lang.ref.SoftReference;
 import java.io.IOException;
@@ -46,6 +47,8 @@
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
+import java.lang.sym.ClassRef;
+import java.lang.sym.Constable;
 import java.net.URL;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -58,6 +61,7 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.StringJoiner;
 
 import jdk.internal.HotSpotIntrinsicCandidate;
@@ -129,7 +133,8 @@
 public final class Class<T> implements java.io.Serializable,
                               GenericDeclaration,
                               Type,
-                              AnnotatedElement {
+                              AnnotatedElement,
+                              Constable<Class<?>, ClassRef> {
     private static final int ANNOTATION= 0x00002000;
     private static final int ENUM      = 0x00004000;
     private static final int SYNTHETIC = 0x00001000;
@@ -3847,4 +3852,9 @@
     public AnnotatedType[] getAnnotatedInterfaces() {
          return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
     }
+
+    @Override
+    public Optional<ClassRef> toSymbolicRef(MethodHandles.Lookup lookup) {
+        return Optional.of(ClassRef.ofDescriptor(toDescriptorString()));
+    }
 }
--- a/src/java.base/share/classes/java/lang/Double.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/Double.java	Fri Dec 22 13:06:32 2017 -0500
@@ -25,7 +25,7 @@
 
 package java.lang;
 
-import java.lang.invoke.ConstantRef;
+import java.lang.sym.SymbolicRef;
 
 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>, ConstantRef<Double> {
+public final class Double extends Number implements Comparable<Double>, SymbolicRef.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	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/Enum.java	Fri Dec 22 13:06:32 2017 -0500
@@ -30,6 +30,12 @@
 import java.io.InvalidObjectException;
 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;
 
 /**
  * This is the common base class of all Java language enumeration types.
@@ -55,7 +61,7 @@
 @SuppressWarnings("serial") // No serialVersionUID needed due to
                             // special-casing of enum types.
 public abstract class Enum<E extends Enum<E>>
-        implements Comparable<E>, Serializable {
+        implements Constable<E, EnumRef<E>>, Comparable<E>, Serializable {
     /**
      * The name of this enum constant, as declared in the enum declaration.
      * Most programmers should use the {@link #toString} method rather than
@@ -202,6 +208,13 @@
         return (zuper == Enum.class) ? (Class<E>)clazz : (Class<E>)zuper;
     }
 
+    @Override
+    public Optional<EnumRef<E>> toSymbolicRef(MethodHandles.Lookup lookup) {
+        return getDeclaringClass()
+                .toSymbolicRef(lookup)
+                .map(c -> EnumRef.of(c, name));
+    }
+
     /**
      * Returns the enum constant of the specified enum type with the
      * specified name.  The name must match exactly an identifier used
--- a/src/java.base/share/classes/java/lang/Float.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/Float.java	Fri Dec 22 13:06:32 2017 -0500
@@ -25,7 +25,7 @@
 
 package java.lang;
 
-import java.lang.invoke.ConstantRef;
+import java.lang.sym.SymbolicRef;
 
 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>, ConstantRef<Float> {
+public final class Float extends Number implements Comparable<Float>, SymbolicRef.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	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/Integer.java	Fri Dec 22 13:06:32 2017 -0500
@@ -26,7 +26,7 @@
 package java.lang;
 
 import java.lang.annotation.Native;
-import java.lang.invoke.ConstantRef;
+import java.lang.sym.SymbolicRef;
 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>, ConstantRef<Integer> {
+public final class Integer extends Number implements Comparable<Integer>, SymbolicRef.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	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/Long.java	Fri Dec 22 13:06:32 2017 -0500
@@ -26,7 +26,7 @@
 package java.lang;
 
 import java.lang.annotation.Native;
-import java.lang.invoke.ConstantRef;
+import java.lang.sym.SymbolicRef;
 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>, ConstantRef<Long> {
+public final class Long extends Number implements Comparable<Long>, SymbolicRef.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	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/String.java	Fri Dec 22 13:06:32 2017 -0500
@@ -25,11 +25,10 @@
 
 package java.lang;
 
-import java.lang.invoke.ConstantRef;
-
 import java.io.ObjectStreamField;
 import java.io.UnsupportedEncodingException;
 import java.lang.annotation.Native;
+import java.lang.sym.SymbolicRef;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -123,7 +122,7 @@
  */
 
 public final class String
-    implements java.io.Serializable, Comparable<String>, CharSequence, ConstantRef<String> {
+    implements java.io.Serializable, Comparable<String>, CharSequence, SymbolicRef.OfSelf<String> {
 
     /**
      * The value is used for character storage.
@@ -1780,7 +1779,7 @@
      * @param   src         the characters being searched.
      * @param   srcCoder    coder handles the mapping between bytes/chars
      * @param   srcCount    count of the source string.
-     * @param   tgt         the characters being searched for.
+     * @param   tgtStr      the characters being searched for.
      * @param   fromIndex   the index to begin searching from.
      */
     static int lastIndexOf(byte[] src, byte srcCoder, int srcCount,
--- a/src/java.base/share/classes/java/lang/annotation/TrackableConstant.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/annotation/TrackableConstant.java	Fri Dec 22 13:06:32 2017 -0500
@@ -24,19 +24,17 @@
  */
 package java.lang.annotation;
 
-import java.lang.invoke.ConstantRef;
-import java.lang.invoke.Constables;
+import java.lang.sym.SymbolicRef;
 import java.lang.invoke.Intrinsics;
 
 /**
- * Identifies a {@link ConstantRef}-yielding factory method or combinator
- * in {@link java.lang.invoke.Constables}.  For invocations of methods
+ * Identifies a {@link SymbolicRef}-yielding factory method or combinator.
+ * For invocations of methods
  * annotated as {@linkplain TrackableConstant} whose arguments (and, for instance
  * methods, the receiver) are all constant expressions, the compiler will track
  * the result as a constant expression, for possible intrinsification.
  *
- * @see ConstantRef
- * @see Constables
+ * @see SymbolicRef
  * @see Intrinsics
  */
 @Retention(RetentionPolicy.CLASS)
--- a/src/java.base/share/classes/java/lang/invoke/BootstrapSpecifier.java	Wed Dec 20 11:56:26 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-/*
- * 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.invoke;
-
-import java.lang.annotation.TrackableConstant;
-import java.util.Arrays;
-import java.util.Objects;
-
-/**
- * A descriptor for an {@code invokedynamic} invocation
- */
-public final class BootstrapSpecifier {
-    private final MethodHandleRef bootstrapMethod;
-    private final ConstantRef<?>[] bootstrapArgs;
-
-    private BootstrapSpecifier(MethodHandleRef bootstrapMethod, ConstantRef<?>... bootstrapArgs) {
-        this.bootstrapMethod = Objects.requireNonNull(bootstrapMethod);
-        this.bootstrapArgs = Objects.requireNonNull(bootstrapArgs.clone());
-    }
-
-    /**
-     * Create a descriptor for an {@code invokedynamic} invocation.
-     * @param bootstrapMethod the bootstrap method for the {@code invokedynamic}
-     * @param bootstrapArgs the bootstrap arguments for the {@code invokedynamic}
-     * @return the descriptor
-     */
-    @TrackableConstant
-    public static BootstrapSpecifier of(MethodHandleRef bootstrapMethod, ConstantRef<?>... bootstrapArgs) {
-        return new BootstrapSpecifier(bootstrapMethod, bootstrapArgs);
-    }
-
-    /**
-     * Returns the bootstrap method for the {@code invokedynamic}
-     * @return the bootstrap method for the {@code invokedynamic}
-     */
-    @TrackableConstant
-    public MethodHandleRef method() { return bootstrapMethod; }
-
-    /**
-     * Returns the bootstrap arguments for the {@code invokedynamic}
-     * @return the bootstrap arguments for the {@code invokedynamic}
-     */
-    public ConstantRef<?>[] arguments() { return bootstrapArgs.clone(); }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        BootstrapSpecifier specifier = (BootstrapSpecifier) o;
-        return Objects.equals(bootstrapMethod, specifier.bootstrapMethod) &&
-               Arrays.equals(bootstrapArgs, specifier.bootstrapArgs);
-    }
-
-    @Override
-    public int hashCode() {
-
-        int result = Objects.hash(bootstrapMethod);
-        result = 31 * result + Arrays.hashCode(bootstrapArgs);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("BootstrapSpecifier[%s,%s]", bootstrapMethod, Arrays.toString(bootstrapArgs));
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/ClassRef.java	Wed Dec 20 11:56:26 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,298 +0,0 @@
-/*
- * 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.invoke;
-
-import sun.invoke.util.Wrapper;
-
-import java.lang.annotation.TrackableConstant;
-import java.lang.reflect.Array;
-import java.util.regex.Pattern;
-import java.util.stream.Stream;
-
-import static java.util.stream.Collectors.joining;
-
-/**
- * A descriptor for a {@linkplain Class} constant.
- */
-public final class ClassRef implements ConstantRef.WithTypeDescriptor<Class<?>> {
-    private static final Pattern TYPE_DESC = Pattern.compile("(\\[*)(V|I|J|S|B|C|F|D|Z|L[^/.\\[;][^.\\[;]*;)");
-
-    /**  ClassRef representing the primitive type int */
-    @TrackableConstant public static final ClassRef CR_int = ClassRef.ofDescriptor("I");
-    /**  ClassRef representing the primitive type long */
-    @TrackableConstant public static final ClassRef CR_long = ClassRef.ofDescriptor("J");
-    /**  ClassRef representing the primitive type float */
-    @TrackableConstant public static final ClassRef CR_float = ClassRef.ofDescriptor("F");
-    /**  ClassRef representing the primitive type double */
-    @TrackableConstant public static final ClassRef CR_double = ClassRef.ofDescriptor("D");
-    /**  ClassRef representing the primitive type short */
-    @TrackableConstant public static final ClassRef CR_short = ClassRef.ofDescriptor("S");
-    /**  ClassRef representing the primitive type byte */
-    @TrackableConstant public static final ClassRef CR_byte = ClassRef.ofDescriptor("B");
-    /**  ClassRef representing the primitive type char */
-    @TrackableConstant public static final ClassRef CR_char = ClassRef.ofDescriptor("C");
-    /**  ClassRef representing the primitive type boolean */
-    @TrackableConstant public static final ClassRef CR_boolean = ClassRef.ofDescriptor("Z");
-    /**  ClassRef representing the void type */
-    @TrackableConstant public static final ClassRef CR_void = ClassRef.ofDescriptor("V");
-
-    /**  ClassRef representing the class java.lang.Object */
-    @TrackableConstant public static final ClassRef CR_Object = ClassRef.of("java.lang.Object");
-    /**  ClassRef representing the class java.lang.String */
-    @TrackableConstant public static final ClassRef CR_String = ClassRef.of("java.lang.String");
-    /**  ClassRef representing the class java.lang.Class */
-    @TrackableConstant public static final ClassRef CR_Class = ClassRef.of("java.lang.Class");
-    /**  ClassRef representing the class java.lang.Number */
-    @TrackableConstant public static final ClassRef CR_Number = ClassRef.of("java.lang.Number");
-    /**  ClassRef representing the class java.lang.Integer */
-    @TrackableConstant public static final ClassRef CR_Integer = ClassRef.of("java.lang.Integer");
-    /**  ClassRef representing the class java.lang.Long */
-    @TrackableConstant public static final ClassRef CR_Long = ClassRef.of("java.lang.Long");
-    /**  ClassRef representing the class java.lang.Float */
-    @TrackableConstant public static final ClassRef CR_Float = ClassRef.of("java.lang.Float");
-    /**  ClassRef representing the class java.lang.Double */
-    @TrackableConstant public static final ClassRef CR_Double = ClassRef.of("java.lang.Double");
-    /**  ClassRef representing the class java.lang.Short */
-    @TrackableConstant public static final ClassRef CR_Short = ClassRef.of("java.lang.Short");
-    /**  ClassRef representing the class java.lang.Byte */
-    @TrackableConstant public static final ClassRef CR_Byte = ClassRef.of("java.lang.Byte");
-    /**  ClassRef representing the class java.lang.Character */
-    @TrackableConstant public static final ClassRef CR_Character = ClassRef.of("java.lang.Character");
-    /**  ClassRef representing the class java.lang.Boolean */
-    @TrackableConstant public static final ClassRef CR_Boolean = ClassRef.of("java.lang.Boolean");
-    /**  ClassRef representing the class java.lang.Void */
-    @TrackableConstant public static final ClassRef CR_Void = ClassRef.of("java.lang.Void");
-    /**  ClassRef representing the class java.lang.Throwable */
-    @TrackableConstant public static final ClassRef CR_Throwable = ClassRef.of("java.lang.Throwable");
-    /**  ClassRef representing the class java.lang.Exception */
-    @TrackableConstant public static final ClassRef CR_Exception = ClassRef.of("java.lang.Exception");
-    /**  ClassRef representing the class java.lang.Enum */
-    @TrackableConstant public static final ClassRef CR_Enum = ClassRef.of("java.lang.Enum");
-
-    /**  ClassRef representing the class java.lang.invoke.VarHandle */
-    @TrackableConstant public static final ClassRef CR_VarHandle = ClassRef.of("java.lang.invoke.VarHandle");
-    /**  ClassRef representing the class java.lang.invoke.MethodHandles */
-    @TrackableConstant public static final ClassRef CR_MethodHandles = ClassRef.of("java.lang.invoke.MethodHandles");
-    /**  ClassRef representing the class java.lang.invoke.MethodHandle */
-    @TrackableConstant public static final ClassRef CR_MethodHandle = ClassRef.of("java.lang.invoke.MethodHandle");
-    /**  ClassRef representing the class java.lang.invoke.MethodType */
-    @TrackableConstant public static final ClassRef CR_MethodType = ClassRef.of("java.lang.invoke.MethodType");
-    /**  ClassRef representing the class java.lang.invoke.CallSite */
-    @TrackableConstant public static final ClassRef CR_CallSite = ClassRef.of("java.lang.invoke.CallSite");
-    /**  ClassRef representing the class java.lang.invoke.MethodHandles.Lookup */
-    @TrackableConstant public static final ClassRef CR_Lookup = CR_MethodHandles.inner("Lookup");
-
-    /**  ClassRef representing the interface java.util.Collection */
-    @TrackableConstant public static final ClassRef CR_Collection = ClassRef.of("java.util.Collection");
-    /**  ClassRef representing the interface java.util.List */
-    @TrackableConstant public static final ClassRef CR_List = ClassRef.of("java.util.List");
-    /**  ClassRef representing the interface java.util.Set */
-    @TrackableConstant public static final ClassRef CR_Set = ClassRef.of("java.util.Set");
-    /**  ClassRef representing the interface java.util.Map */
-    @TrackableConstant public static final ClassRef CR_Map = ClassRef.of("java.util.Map");
-
-    private final String descriptor;
-
-    private ClassRef(String descriptor) {
-        if (!TYPE_DESC.matcher(descriptor).matches())
-            throw new IllegalArgumentException(String.format("%s is not a valid type descriptor", descriptor));
-        this.descriptor = descriptor;
-    }
-
-    /**
-     * Create a {@linkplain ClassRef} from a dot-separated class name
-     *
-     * @param name the class name
-     * @return a {@linkplain ClassRef} describing the desired class
-     * @throws IllegalArgumentException if the name string does not
-     * describe a valid class name
-     */
-    @TrackableConstant
-    public static ClassRef of(String name) {
-        return ClassRef.ofDescriptor("L" + name.replace('.', '/') + ";");
-    }
-
-    /**
-     * Create a {@linkplain ClassRef} from a dot-separated package name and a class name
-     *
-     * @param packageName the package name, dot-separated
-     * @param className the the class name
-     * @return a {@linkplain ClassRef} describing the desired class
-     * @throws IllegalArgumentException if the package name or class name are not in the correct format
-     */
-    @TrackableConstant
-    public static ClassRef of(String packageName, String className) {
-        return ofDescriptor("L" + packageName.replace('.', '/') + (packageName.length() > 0 ? "/" : "") + className + ";");
-    }
-
-    /**
-     * Create a {@linkplain ClassRef} from a descriptor string.
-     *
-     * @param descriptor the descriptor string
-     * @return a {@linkplain ClassRef} describing the desired class
-     * @throws IllegalArgumentException if the descriptor string does not
-     * describe a valid class descriptor
-     */
-    @TrackableConstant
-    public static ClassRef ofDescriptor(String descriptor) {
-        return new ClassRef(descriptor);
-    }
-
-    /**
-     * Create a {@linkplain ClassRef} describing an array of the type
-     * described by this {@linkplain ClassRef}
-     *
-     * @return a {@linkplain ClassRef} describing an array type
-     */
-    @TrackableConstant
-    public ClassRef array() {
-        return ofDescriptor("[" + descriptor);
-    }
-
-    /**
-     * Create a {@linkplain ClassRef} describing an inner class of the
-     * non-array reference type described by this {@linkplain ClassRef}
-     */
-    @TrackableConstant
-    public ClassRef inner(String innerName) {
-        if (!descriptor.startsWith("L"))
-            throw new IllegalStateException("Outer class is not a non-array reference type");
-        return ClassRef.ofDescriptor(descriptor.substring(0, descriptor.length() - 1) + "$" + innerName + ";");
-    }
-
-    /**
-     * Create a {@linkplain ClassRef} describing an inner class of the
-     * non-array reference type described by this {@linkplain ClassRef}
-     */
-    @TrackableConstant
-    public ClassRef inner(String firstInnerName, String... moreInnerNames) {
-        if (!descriptor.startsWith("L"))
-            throw new IllegalStateException("Outer class is not a non-array reference type");
-        return moreInnerNames.length == 0
-               ? inner(firstInnerName)
-               : ClassRef.ofDescriptor(descriptor.substring(0, descriptor.length() - 1) + "$" + firstInnerName
-                                       + Stream.of(moreInnerNames).collect(joining("$", "$", "")) + ";");
-    }
-        
-    /**
-     * Returns whether this {@linkplain ClassRef}
-     * describes an array type
-     * @return whether this {@linkplain ClassRef}
-     * describes an array type
-     */
-    public boolean isArray() {
-        return descriptor.startsWith("[");
-    }
-
-    /**
-     * Returns whether this {@linkplain ClassRef}
-     * describes a primitive type
-     * @return whether this {@linkplain ClassRef}
-     * describes a primitive type
-     */
-    public boolean isPrimitive() {
-        return descriptor.length() == 1;
-    }
-
-    /**
-     * The component type of this {@linkplain ClassRef} if it describes
-     * an array type, otherwise the type that it describes
-     * @return the component type of the type described by this
-     * @throws IllegalStateException if this reference does not describe an array type
-     * {@linkplain ClassRef}
-     */
-    @TrackableConstant
-    public ClassRef componentType() {
-        if (!isArray())
-            throw new IllegalStateException();
-        return ofDescriptor(descriptor.substring(1));
-    }
-
-    @Override
-    @TrackableConstant
-    public String descriptorString() {
-        return descriptor;
-    }
-
-    /**
-     * Return the canonical name of the type described by this descriptor
-     * @return the canonical name of the type described by this descriptor
-     */
-    public String canonicalName() {
-        // @@@ Arrays?
-        if (isPrimitive())
-            return Wrapper.forBasicType(descriptor.charAt(0)).primitiveSimpleName();
-        else
-            return descriptor.substring(1, descriptor.length() - 1).replace('/', '.');
-    }
-
-    /**
-     * Resolve to a Class
-     * @param lookup the lookup
-     * @return return the class
-     * @throws ReflectiveOperationException exception
-     */
-    public Class<?> resolve(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
-        if (isPrimitive())
-            return Wrapper.forBasicType(descriptor.charAt(0)).primitiveType();
-        else {
-            ClassRef comp = this;
-            int depth = 0;
-            while (comp.isArray()) {
-                ++depth;
-                comp = comp.componentType();
-            }
-            String compDescr = comp.descriptor;
-
-            if (compDescr.length() == 1)
-                return Class.forName(descriptor, true, lookup.lookupClass().getClassLoader());
-            else {
-                Class<?> clazz = Class.forName(compDescr.substring(1, compDescr.length() - 1).replace('/', '.'), true, lookup.lookupClass().getClassLoader());
-                for (int i = 0; i < depth; i++)
-                    clazz = Array.newInstance(clazz, 0).getClass();
-                return clazz;
-            }
-        }
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ClassRef constant = (ClassRef) o;
-        return descriptor != null ? descriptor.equals(constant.descriptor) : constant.descriptor == null;
-    }
-
-    @Override
-    public int hashCode() {
-        return descriptor != null ? descriptor.hashCode() : 0;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("ClassRef[%s]", descriptorString());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/Constables.java	Wed Dec 20 11:56:26 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2017, 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.invoke;
-
-import java.util.stream.Stream;
-
-/**
- * Classes for representing entries in the constant pool, which can be
- * intrinsified via methods in {@link Intrinsics}.
- */
-public class Constables {
-    static final ClassRef CLASS_CONDY = ClassRef.of("java.lang.invoke.ConstantBootstraps");
-
-    static final MethodHandleRef BSM_NULL_CONSTANT
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "nullConstant", ClassRef.CR_Object);
-    static final MethodHandleRef BSM_PRIMITIVE_CLASS
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "primitiveClass", ClassRef.CR_Class);
-    static final MethodHandleRef BSM_VARHANDLE_FIELD
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "fieldVarHandle", ClassRef.CR_VarHandle, ClassRef.CR_Class, ClassRef.CR_Class);
-    static final MethodHandleRef BSM_VARHANDLE_STATIC_FIELD
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "staticFieldVarHandle", ClassRef.CR_VarHandle, ClassRef.CR_Class, ClassRef.CR_Class);
-    static final MethodHandleRef BSM_VARHANDLE_ARRAY
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "arrayVarHandle", ClassRef.CR_VarHandle, ClassRef.CR_Class);
-
-    static final ConstantRef<?> NULL = ConstantRef.ofNull();
-
-    /**
-     * Resolve a {@link ConstantRef} relative to the provided lookup.  The {@link ConstantRef}
-     * must be one of the following types: {@link String}, {@link Integer},
-     * {@link Long}, {@link Float}, {@link Double}, {@link ClassRef},
-     * {@link MethodTypeRef}, {@link MethodHandleRef}, or {@link DynamicConstantRef}.
-     *
-     * @param c The {@link ConstantRef}
-     * @param lookup The lookup object to use
-     * @param <T> The type of the object described by the {@link ConstantRef}
-     * @return The resolved object
-     * @throws ReflectiveOperationException If there is an error resolving the
-     * constable
-     */
-    @SuppressWarnings("unchecked")
-    static<T> T resolve(ConstantRef<T> c, MethodHandles.Lookup lookup) throws ReflectiveOperationException {
-        if (c instanceof String
-            || (c instanceof Integer)
-            || (c instanceof Long)
-            || (c instanceof Float)
-            || (c instanceof Double))
-            return (T) c;
-        if (c instanceof ClassRef) {
-            return (T) ((ClassRef) c).resolve(lookup);
-        }
-        else if (c instanceof MethodTypeRef) {
-            return (T) ((MethodTypeRef) c).resolve(lookup);
-        }
-        else if (c instanceof MethodHandleRef) {
-            return (T) ((MethodHandleRef) c).resolve(lookup);
-        }
-        else if (c instanceof DynamicConstantRef) {
-            return (T) ((DynamicConstantRef) c).resolve(lookup);
-        }
-        else
-            throw new IllegalArgumentException(c.getClass().getName());
-    }
-
-    static Object[] resolveArgs(MethodHandles.Lookup lookup, ConstantRef<?>[] args) {
-        return Stream.of(args)
-                     .map(arg -> {
-                         try {
-                             return resolve(arg, lookup);
-                         }
-                         catch (ReflectiveOperationException e) {
-                             throw new RuntimeException(e);
-                         }
-                     })
-                     .toArray();
-    }
-
-    /**
-     * Returns a {@link ConstantRef}, if the argument is not a {@link ClassRef}
-     * then the argument is returned unchanged. If the argument is a {@link ClassRef}
-     * and it is a primitive {@link ClassRef}, then a fresh {@link DynamicConstantRef}
-     * corresponding to it is created and returned.
-     *
-     * @param <T> The type of the object described by the {@link ConstantRef}
-     * @param ref the given {@link ConstantRef}
-     * @return the reduced {@link ConstantRef}
-     */
-    public static<T> ConstantRef<T> reduce(ConstantRef<T> ref) {
-        if (ref instanceof ClassRef) {
-            ClassRef cr = (ClassRef) ref;
-            if (cr.isPrimitive()) {
-                return DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), cr.descriptorString());
-            }
-        }
-        return ref;
-    }
-
-    /**
-     * Convert a class literal to a descriptor string
-     * @param clazz the class literal
-     * @return the descriptor string
-     */
-    static String classToDescriptor(Class<?> clazz) {
-        return MethodType.methodType(clazz).toMethodDescriptorString().substring(2);
-    }
-}
\ No newline at end of file
--- a/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/ConstantBootstraps.java	Fri Dec 22 13:06:32 2017 -0500
@@ -42,13 +42,24 @@
 public final class ConstantBootstraps {
     // implements the upcall from the JVM, MethodHandleNatives.linkDynamicConstant:
     /*non-public*/
-    static Object makeConstant(MethodHandle bootstrapMethod,
-                               // Callee information:
-                               String name, Class<?> type,
-                               // Extra arguments for BSM, if any:
-                               Object info,
-                               // Caller information:
-                               Class<?> callerClass) {
+    /**
+     * (temporarily public)
+     * makeConstant
+     *
+     * @param bootstrapMethod doc
+     * @param name doc
+     * @param type doc
+     * @param info doc
+     * @param callerClass doc
+     * @return doc
+     */
+    /* @@@ */ public static Object makeConstant(MethodHandle bootstrapMethod,
+                                      // Callee information:
+                                      String name, Class<?> type,
+                                      // Extra arguments for BSM, if any:
+                                      Object info,
+                                      // Caller information:
+                                      Class<?> callerClass) {
         // BSMI.invoke handles all type checking and exception translation.
         // If type is not a reference type, the JVM is expecting a boxed
         // version, and will manage unboxing on the other side.
--- a/src/java.base/share/classes/java/lang/invoke/ConstantRef.java	Wed Dec 20 11:56:26 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2017, 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.invoke;
-
-import java.lang.annotation.TrackableConstant;
-
-/**
- * Purely-nominal descriptor for a constant value expressible in a classfile
- * constant pool.
- *
- * <p> Native constant types that don't require linkage ({@link String}, {@link
- * Integer}, {@link Long}, {@link Float}, and {@link Double}) implement
- * {@linkplain ConstantRef} directly. Native linkable constant types ({@link
- * Class}, {@link MethodType}, and {@link MethodHandle}) are represented as
- * {@linkplain ConstantRef} via the symbolic reference classes {@link ClassRef},
- * {@link MethodTypeRef}, and {@link MethodHandleRef}.  Dynamic constants are
- * represented by the symbolic reference type {@link DynamicConstantRef}.
- *
- * <p>APIs that deal in generation or parsing of bytecode should use
- * {@linkplain ConstantRef} to describe the operand of an {@code LDC} instruction,
- * including dynamic constants, and the static argument lists of
- * {@code invokedynamic} instructions.  The {@linkplain ConstantRef} types are also
- * used by the {@link Intrinsics} API to express {@code LDC} and
- * {@code invokedynamic} instructions.
- *
- * <p> Like names in the constant pool, names in a {@linkplain ConstantRef} are
- * independent of a class loader.  When a {@linkplain ConstantRef} is
- * intrinsified, it is interpreted relative to the class loader that loaded the
- * class in which the intrinsic appears (just like names that appear in that
- * classes constant pool.)
- *
- * @param <T> The type of the object which this {@linkplain ConstantRef}
- *            describes
- * @see Constables
- * @see Intrinsics
- * @see TrackableConstant
- */
-public interface ConstantRef<T> {
-
-    /**
-     * A {@link ConstantRef} representing a null reference
-     *
-     * @param <T> The type of the object which the resulting {@linkplain ConstantRef} describes
-     * @return the {@link ConstantRef}
-     */
-    @TrackableConstant
-    static<T> ConstantRef<T> ofNull() {
-        return DynamicConstantRef.of(BootstrapSpecifier.of(Constables.BSM_NULL_CONSTANT), ClassRef.CR_Object);
-    }
-
-    /**
-     * Construct a VarHandle for an instance field
-     * @param owner the class containing the field
-     * @param name the field name
-     * @param type the field type
-     * @return the VarHandle
-     */
-    static ConstantRef<VarHandle> fieldVarHandle(ClassRef owner, String name, ClassRef type) {
-        return DynamicConstantRef.of(
-                BootstrapSpecifier.of(Constables.BSM_VARHANDLE_FIELD, owner, type),
-                name);
-    }
-
-    /**
-     * Construct a VarHandle for a static field
-     * @param owner the class containing the field
-     * @param name the field name
-     * @param type the field type
-     * @return the VarHandle
-     */
-    static ConstantRef<VarHandle> staticFieldVarHandle(ClassRef owner, String name, ClassRef type) {
-        return DynamicConstantRef.of(
-                BootstrapSpecifier.of(Constables.BSM_VARHANDLE_STATIC_FIELD, owner, type),
-                name);
-    }
-
-    /**
-     * Construct a VarHandle for an array
-     * @param arrayClass the array class
-     * @return the VarHandle
-     */
-    static ConstantRef<VarHandle> arrayVarHandle(ClassRef arrayClass) {
-        return DynamicConstantRef.of(
-                BootstrapSpecifier.of(Constables.BSM_VARHANDLE_ARRAY, arrayClass));
-    }
-
-    /**
-     * 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 to which this constant pool entry resolves
-     */
-    public interface WithTypeDescriptor<T> extends ConstantRef<T> {
-        /**
-         * Return the descriptor string associated with this constant pool entry
-         *
-         * @return the descriptor string
-         */
-        String descriptorString();
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/DynamicConstantRef.java	Wed Dec 20 11:56:26 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,207 +0,0 @@
-/*
- * 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.invoke;
-
-import java.lang.annotation.TrackableConstant;
-
-/**
- * A descriptor for a dynamic constant.
- */
-public final class DynamicConstantRef<T> implements ConstantRef<T> {
-    private final String name;
-    private final BootstrapSpecifier bootstrapSpecifier;
-    private final ClassRef type;
-
-    private DynamicConstantRef(BootstrapSpecifier bootstrapSpecifier, String name, ClassRef type) {
-        this.name = name;
-        this.bootstrapSpecifier = bootstrapSpecifier;
-        this.type = type;
-    }
-
-    /**
-     * Return a descriptor for a dynamic constant.
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapSpecifier the bootstrap specifier for the dynamic constant
-     * @param name the name for the dynamic constant
-     * @param type the type of the dynamic constant
-     * @return the descriptor for the dynamic constant
-     */
-    @TrackableConstant
-    public static<T> DynamicConstantRef<T> of(BootstrapSpecifier bootstrapSpecifier, String name, ClassRef type) {
-        return new DynamicConstantRef<>(bootstrapSpecifier, name, type);
-    }
-
-    /**
-     * Return a descriptor for a dynamic constant, whose name is not used by the bootstrap
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapSpecifier the bootstrap specifier for the dynamic constant
-     * @param type the type of the dynamic constant
-     * @return the descriptor for the dynamic constant
-     */
-    @TrackableConstant
-    public static<T> DynamicConstantRef<T> of(BootstrapSpecifier bootstrapSpecifier, ClassRef type) {
-        return of(bootstrapSpecifier, "_", type);
-    }
-
-    /**
-     * Return a descriptor for a dynamic constant, whose type is the same as the bootstrap return
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapSpecifier the bootstrap specifier for the dynamic constant
-     * @param name the name for the dynamic constant
-     * @return the descriptor for the dynamic constant
-     */
-    @TrackableConstant
-    public static<T> DynamicConstantRef<T> of(BootstrapSpecifier bootstrapSpecifier, String name) {
-        return of(bootstrapSpecifier, name, bootstrapSpecifier.method().type().returnType());
-    }
-
-    /**
-     * Return a descriptor for a dynamic constant, whose type is the same as the bootstrap return,
-     * and whose name is not used by the bootstrap
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapSpecifier the bootstrap specifier for the dynamic constant
-     * @return the descriptor for the dynamic constant
-     */
-    @TrackableConstant
-    public static<T> DynamicConstantRef<T> of(BootstrapSpecifier bootstrapSpecifier) {
-        return of(bootstrapSpecifier, "_");
-    }
-
-    /**
-     * Return a descriptor for a dynamic constant whose bootstrap has no static arguments.
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod the bootstrap method
-     * @param name the name for the dynamic constant
-     * @param type the type of the dynamic constant
-     * @return the descriptor for the dynamic constant
-     */
-    @TrackableConstant
-    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, String name, ClassRef type) {
-        return of(BootstrapSpecifier.of(bootstrapMethod), name, type);
-    }
-
-    /**
-     * Return a descriptor for a dynamic constant whose bootstrap has no static arguments,
-     * and whose name is ignored by the bootstrap
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod the bootstrap method
-     * @param type the type of the dynamic constant
-     * @return the descriptor for the dynamic constant
-     */
-    @TrackableConstant
-    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, ClassRef type) {
-        return of(BootstrapSpecifier.of(bootstrapMethod), type);
-    }
-
-    /**
-     * Return a descriptor for a dynamic constant whose bootstrap has no static arguments,
-     * anmd whose type is the same as the bootstrap return
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod the bootstrap method
-     * @param name the name for the dynamic constant
-     * @return the descriptor for the dynamic constant
-     */
-    @TrackableConstant
-    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, String name) {
-        return of(BootstrapSpecifier.of(bootstrapMethod), name);
-    }
-
-    /**
-     * Return a descriptor for a dynamic constant whose bootstrap has no static arguments,
-     * whose name is ignored by the bootstrap, and whose type is the same as the bootstrap return
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod the bootstrap method
-     * @return the descriptor for the dynamic constant
-     */
-    @TrackableConstant
-    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod) {
-        return of(BootstrapSpecifier.of(bootstrapMethod));
-    }
-
-    /**
-     * returns the bootstrap specifier
-     * @return the bootstrap specifier
-     */
-    @TrackableConstant
-    public BootstrapSpecifier bootstrap() {
-        return bootstrapSpecifier;
-    }
-
-    /**
-     * returns the name
-     * @return the name
-     */
-    @TrackableConstant
-    public String name() {
-        return name;
-    }
-
-    /**
-     * returns the type
-     * @return the type
-     */
-    @TrackableConstant
-    public ClassRef type() {
-        return type;
-    }
-
-    /**
-     * Returns the bootstrap method in the bootstrap specifier
-     * @return the bootstrap method in the bootstrap specifier
-     */
-    @TrackableConstant
-    public MethodHandleRef bootstrapMethod() { return bootstrapSpecifier.method(); }
-
-    /**
-     * Returns the bootstrap arguments in the bootstrap specifier
-     * @return the bootstrap arguments in the bootstrap specifier
-     */
-    public ConstantRef<?>[] bootstrapArgs() { return bootstrapSpecifier.arguments(); }
-
-    /**
-     * Resolve
-     * @param lookup the lookup
-     * @return the resolved object
-     * @throws ReflectiveOperationException exception
-     */
-    @SuppressWarnings("unchecked")
-    public T resolve(MethodHandles.Lookup lookup) {
-        try {
-            MethodHandle bsmMh = bootstrapSpecifier.method().resolve(lookup);
-            return (T) ConstantBootstraps.makeConstant(bsmMh,
-                                                       name,
-                                                       type.resolve(lookup),
-                                                       Constables.resolveArgs(lookup, bootstrapSpecifier.arguments()),
-                                                       // TODO pass lookup
-                                                       lookup.lookupClass());
-        }
-        catch (RuntimeException|Error e) {
-            throw e;
-        }
-        catch (Throwable t) {
-            throw new RuntimeException(t);
-        }
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/Intrinsics.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/Intrinsics.java	Fri Dec 22 13:06:32 2017 -0500
@@ -24,6 +24,9 @@
  */
 package java.lang.invoke;
 
+import java.lang.sym.BootstrapSpecifier;
+import java.lang.sym.SymbolicRef;
+
 /**
  * Intrinsics
  *
@@ -38,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(ConstantRef<T> constant) {
+    public static <T> T ldc(SymbolicRef<T> constant) {
         throw new UnsupportedOperationException("no reflective access");
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Fri Dec 22 13:06:32 2017 -0500
@@ -28,9 +28,15 @@
 
 import jdk.internal.HotSpotIntrinsicCandidate;
 
+import java.lang.sym.ClassRef;
+import java.lang.sym.Constable;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
 import java.util.Arrays;
 import java.util.Objects;
+import java.util.Optional;
 
+import static java.lang.invoke.MethodHandleInfo.*;
 import static java.lang.invoke.MethodHandleStatics.*;
 
 /**
@@ -425,7 +431,7 @@
  * @author John Rose, JSR 292 EG
  * @since 1.7
  */
-public abstract class MethodHandle {
+public abstract class MethodHandle implements Constable<MethodHandle, MethodHandleRef> {
 
     /**
      * Internal marker interface which distinguishes (to the Java compiler)
@@ -1508,6 +1514,46 @@
         return bindArgumentL(0, x);
     }
 
+    @Override
+    public Optional<MethodHandleRef> toSymbolicRef(MethodHandles.Lookup lookup) {
+        MethodHandleInfo info;
+        ClassRef owner;
+        String name;
+        MethodTypeRef type;
+        try {
+            info = lookup.revealDirect(this);
+            owner = info.getDeclaringClass().toSymbolicRef(lookup).get();
+            type = info.getMethodType().toSymbolicRef(lookup).get();
+            name = info.getName();
+        }
+        catch (Exception e) {
+            return Optional.empty();
+        }
+
+        switch (info.getReferenceKind()) {
+            case REF_getField:
+                return Optional.of(MethodHandleRef.ofField(MethodHandleRef.Kind.GETTER, owner, name, type.returnType()));
+            case REF_putField:
+                return Optional.of(MethodHandleRef.ofField(MethodHandleRef.Kind.SETTER, owner, name, type.returnType()));
+            case REF_getStatic:
+                return Optional.of(MethodHandleRef.ofField(MethodHandleRef.Kind.STATIC_GETTER, owner, name, type.returnType()));
+            case REF_putStatic:
+                return Optional.of(MethodHandleRef.ofField(MethodHandleRef.Kind.STATIC_SETTER, owner, name, type.returnType()));
+            case REF_invokeVirtual:
+                return Optional.of(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, owner, name, type));
+            case REF_invokeStatic:
+                return Optional.of(MethodHandleRef.of(MethodHandleRef.Kind.STATIC, owner, name, type));
+            case REF_invokeSpecial:
+                return Optional.of(MethodHandleRef.of(MethodHandleRef.Kind.SPECIAL, owner, name, type));
+            case REF_invokeInterface:
+                return Optional.of(MethodHandleRef.of(MethodHandleRef.Kind.INTERFACE_VIRTUAL, owner, name, type));
+            case REF_newInvokeSpecial:
+                return Optional.of(MethodHandleRef.of(MethodHandleRef.Kind.CONSTRUCTOR, owner, name, type));
+            default:
+                return Optional.empty();
+        }
+    }
+
     /**
      * Returns a string representation of the method handle,
      * starting with the string {@code "MethodHandle"} and
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandleRef.java	Wed Dec 20 11:56:26 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,266 +0,0 @@
-/*
- * 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.invoke;
-
-import java.lang.annotation.TrackableConstant;
-import java.util.Objects;
-
-import static java.lang.invoke.MethodHandleInfo.REF_getField;
-import static java.lang.invoke.MethodHandleInfo.REF_getStatic;
-import static java.lang.invoke.MethodHandleInfo.REF_invokeInterface;
-import static java.lang.invoke.MethodHandleInfo.REF_invokeSpecial;
-import static java.lang.invoke.MethodHandleInfo.REF_invokeStatic;
-import static java.lang.invoke.MethodHandleInfo.REF_invokeVirtual;
-import static java.lang.invoke.MethodHandleInfo.REF_newInvokeSpecial;
-import static java.lang.invoke.MethodHandleInfo.REF_putField;
-import static java.lang.invoke.MethodHandleInfo.REF_putStatic;
-import static java.lang.invoke.MethodHandleRef.Kind.STATIC;
-
-/**
- * A descriptor for a {@linkplain MethodHandle} constant.
- */
-public final class MethodHandleRef implements 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
-     */
-    public enum Kind {
-        @TrackableConstant STATIC(REF_invokeStatic),
-        @TrackableConstant VIRTUAL(REF_invokeVirtual),
-        @TrackableConstant INTERFACE_VIRTUAL(REF_invokeInterface),
-        @TrackableConstant SPECIAL(REF_invokeSpecial),
-        @TrackableConstant CONSTRUCTOR(REF_newInvokeSpecial),
-        @TrackableConstant GETTER(REF_getField),
-        @TrackableConstant SETTER(REF_putField),
-        @TrackableConstant STATIC_GETTER(REF_getStatic),
-        @TrackableConstant STATIC_SETTER(REF_putStatic);
-
-        public final int refKind;
-
-        Kind(int refKind) {
-            this.refKind = refKind;
-        }
-    }
-
-    private final Kind kind;
-    private final ClassRef owner;
-    private final String name;
-    private final MethodTypeRef type;
-
-    private MethodHandleRef(Kind kind, ClassRef owner, String name, MethodTypeRef type) {
-        this.kind = kind;
-        this.owner = owner;
-        this.name = name;
-        this.type = type;
-    }
-
-    /**
-     * Return a {@code MethodHandleRef} corresponding to an
-     * invocation of a static method
-     * @param kind One of: STATIC, VIRTUAL, INTERFACE_VIRTUAL, SPECIAL, CONSTRUCTOR
-     * @param clazz the class containing the method
-     * @param name the name of the method (ignored if kind=CONSTRUCTOR)
-     * @param type the method type of the method
-     * @return the {@code MethodHandleRef}
-     */
-    @TrackableConstant
-    public static MethodHandleRef of(Kind kind, ClassRef clazz, String name, MethodTypeRef type) {
-        switch (kind) {
-            case STATIC:
-            case VIRTUAL:
-            case INTERFACE_VIRTUAL:
-            case SPECIAL:
-                return new MethodHandleRef(kind, clazz, name, type);
-            case CONSTRUCTOR:
-                return new MethodHandleRef(kind, clazz, "<init>", type);
-            default:
-                throw new IllegalArgumentException(kind.toString());
-        }
-    }
-
-    /**
-     * Return a {@code MethodHandleRef} corresponding to an
-     * invocation of a static method
-     * @param kind One of: STATIC, VIRTUAL, INTERFACE_VIRTUAL, SPECIAL, CONSTRUCTOR
-     * @param clazz the class containing the method
-     * @param name the name of the method (ignored if kind=CONSTRUCTOR)
-     * @param descriptorString descriptor string of the method
-     * @return the {@code MethodHandleRef}
-     */
-    @TrackableConstant
-    public static MethodHandleRef of(Kind kind, ClassRef clazz, String name, String descriptorString) {
-        return of(kind, clazz, name, MethodTypeRef.ofDescriptor(descriptorString));
-    }
-
-    /**
-     * Return a {@code MethodHandleRef} corresponding to an
-     * invocation of a static method
-     * @param kind One of: STATIC, VIRTUAL, INTERFACE_VIRTUAL, SPECIAL, CONSTRUCTOR
-     * @param clazz the class containing the method
-     * @param name the name of the method (ignored if kind=CONSTRUCTOR)
-     * @param returnType the return type of the method
-     * @param paramTypes the parameter types of the method
-     * @return the {@code MethodHandleRef}
-     */
-    @TrackableConstant
-    public static MethodHandleRef of(Kind kind, ClassRef clazz, String name, ClassRef returnType, ClassRef... paramTypes) {
-        return of(kind, clazz, name, MethodTypeRef.of(returnType, paramTypes));
-    }
-
-    /**
-     * Return a {@code MethodHandleRef} corresponding to an invokedynamic bootstrap,
-     * which is a static method whose leading arguments are {@code Lookup}, {@code String}, and {@code MethodType}
-     * @param clazz the class containing the method
-     * @param name the name of the method
-     * @param returnType the return type of the method
-     * @param paramTypes the parameter types of the method
-     * @return the {@code MethodHandleRef}
-     */
-    @TrackableConstant
-    public static MethodHandleRef ofIndyBootstrap(ClassRef clazz, String name, ClassRef returnType, ClassRef... paramTypes) {
-        return of(STATIC, clazz, name, MethodTypeRef.of(returnType, paramTypes).insertParameterTypes(0, INDY_BOOTSTRAP_ARGS));
-    }
-
-    /**
-     * Return a {@code MethodHandleRef} corresponding to a constantdynamic bootstrap,
-     * which is a static method whose leading arguments are {@code Lookup}, {@code String}, and {@code Class}
-     * @param clazz the class containing the method
-     * @param name the name of the method
-     * @param returnType the return type of the method
-     * @param paramTypes the parameter types of the method
-     * @return the {@code MethodHandleRef}
-     */
-    @TrackableConstant
-    public static MethodHandleRef ofCondyBootstrap(ClassRef clazz, String name, ClassRef returnType, ClassRef... paramTypes) {
-        return of(STATIC, clazz, name, MethodTypeRef.of(returnType, paramTypes).insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS));
-    }
-
-    /**
-     * Return a {@code MethodHandleRef} corresponding to invocation
-     * of an instance field getter
-     * @param clazz the class containing the field
-     * @param name the name of the field
-     * @param type the type of the field
-     * @return the {@code MethodHandleRef}
-     */
-    @TrackableConstant
-    public static MethodHandleRef ofField(Kind kind, ClassRef clazz, String name, ClassRef type) {
-        switch (kind) {
-            case GETTER: return new MethodHandleRef(Kind.GETTER, clazz, name, MethodTypeRef.of(type, clazz));
-            case SETTER:
-                return new MethodHandleRef(Kind.SETTER, clazz, name, MethodTypeRef.of(ClassRef.CR_void, clazz, type));
-            case STATIC_GETTER: return new MethodHandleRef(Kind.STATIC_GETTER, clazz, name, MethodTypeRef.of(type));
-            case STATIC_SETTER:
-                return new MethodHandleRef(Kind.STATIC_SETTER, clazz, name, MethodTypeRef.of(ClassRef.CR_void, type));
-            default: throw new IllegalArgumentException(kind.toString());
-        }
-    }
-
-    /**
-     * Resolve to a MethodHandle
-     * @param lookup the lookup
-     * @return the MethodHandle
-     * @throws ReflectiveOperationException exception
-     */
-    public MethodHandle resolve(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
-        switch (kind) {
-            case STATIC: return lookup.findStatic(owner.resolve(lookup), name, type.resolve(lookup));
-            case INTERFACE_VIRTUAL:
-            case VIRTUAL:
-                return lookup.findVirtual(owner.resolve(lookup), name, type.resolve(lookup));
-            case SPECIAL: return lookup.findSpecial(owner.resolve(lookup), name, type.resolve(lookup), lookup.lookupClass());
-            case CONSTRUCTOR: return lookup.findConstructor(owner.resolve(lookup), type.resolve(lookup));
-            case GETTER: return lookup.findGetter(owner.resolve(lookup), name, type.resolve(lookup).returnType());
-            case STATIC_GETTER: return lookup.findStaticGetter(owner.resolve(lookup), name, type.resolve(lookup).returnType());
-            case SETTER: return lookup.findSetter(owner.resolve(lookup), name, type.resolve(lookup).parameterType(1));
-            case STATIC_SETTER: return lookup.findStaticSetter(owner.resolve(lookup), name, type.resolve(lookup).parameterType(0));
-            default: throw new IllegalStateException(kind.name());
-        }
-    }
-
-    /**
-     * Return the {@code refKind} of the method handle described by this descriptor,
-     * as defined by {@link MethodHandleInfo}
-     * @return the reference kind
-     */
-    @TrackableConstant
-    public int refKind() { return kind.refKind; }
-
-    /**
-     * Return the class in which the method described by this descriptor is
-     * declared
-     *
-     * @return the class in which the method is declared
-     */
-    @TrackableConstant
-    public ClassRef owner() {
-        return owner;
-    }
-
-    /**
-     * Return the name of the method described by this descriptor
-     * @return the name of the method
-     */
-    @TrackableConstant
-    public String name() {
-        return name;
-    }
-
-    /**
-     * Return the method type of the method described by this descriptor
-     * @return the method type
-     */
-    @TrackableConstant
-    public MethodTypeRef type() {
-        return type;
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        MethodHandleRef ref = (MethodHandleRef) o;
-        return kind == ref.kind &&
-               Objects.equals(owner, ref.owner) &&
-               Objects.equals(name, ref.name) &&
-               Objects.equals(type, ref.type);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(kind, owner, name, type);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("MethodHandleRef[kind=%s, owner=%s, name=%s, type=%s]", kind, owner, name, type);
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/MethodType.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java	Fri Dec 22 13:06:32 2017 -0500
@@ -30,10 +30,13 @@
 import java.lang.ref.WeakReference;
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
+import java.lang.sym.Constable;
+import java.lang.sym.MethodTypeRef;
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.StringJoiner;
 import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.ConcurrentHashMap;
@@ -91,7 +94,7 @@
  * @since 1.7
  */
 public final
-class MethodType implements java.io.Serializable {
+class MethodType implements Constable<MethodType, MethodTypeRef>, java.io.Serializable {
     private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
 
     // The rtype and ptypes fields define the structural identity of the method type:
@@ -1163,6 +1166,11 @@
         return BytecodeDescriptor.unparse(cls);
     }
 
+    @Override
+    public Optional<MethodTypeRef> toSymbolicRef(MethodHandles.Lookup lookup) {
+        return Optional.of(MethodTypeRef.ofDescriptor(toMethodDescriptorString()));
+    }
+
     /// Serialization.
 
     /**
--- a/src/java.base/share/classes/java/lang/invoke/MethodTypeRef.java	Wed Dec 20 11:56:26 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/*
- * 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.invoke;
-
-import java.lang.annotation.TrackableConstant;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-/**
- * A descriptor for a {@linkplain MethodType} constant.
- */
-public final class MethodTypeRef implements ConstantRef.WithTypeDescriptor<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("\\((.*)\\)(.*)");
-
-    private final ClassRef returnType;
-    private final ClassRef[] argTypes;
-
-    private MethodTypeRef(ClassRef returnType, ClassRef[] argTypes) {
-        this.returnType = returnType;
-        this.argTypes = argTypes;
-    }
-
-    /**
-     * Create a {@linkplain MethodTypeRef} from a descriptor string.
-     *
-     * @param descriptor the descriptor string
-     * @return a {@linkplain MethodTypeRef} describing the desired method type
-     * @throws IllegalArgumentException if the descriptor string does not
-     * describe a valid method descriptor
-     */
-    @TrackableConstant
-    public static MethodTypeRef ofDescriptor(String descriptor) {
-        Matcher matcher = pattern.matcher(descriptor);
-        if (!matcher.matches())
-            throw new IllegalArgumentException(String.format("%s is not a valid method descriptor", descriptor));
-        String paramTypes = matcher.group(1);
-        String returnType = matcher.group(2);
-        if (!TYPE_DESC.matcher(returnType).matches())
-            throw new IllegalArgumentException(String.format("Invalid return type %s", returnType));
-        List<String> params = new ArrayList<>();
-        matcher = TYPE_DESC.matcher(paramTypes);
-        while (matcher.regionStart() < paramTypes.length()) {
-            if (matcher.lookingAt()) {
-                params.add(matcher.group());
-                matcher.region(matcher.end(), matcher.regionEnd());
-            }
-            else
-                throw new IllegalArgumentException(String.format("Invalid parameter type: %s", paramTypes.substring(matcher.regionStart(), matcher.regionEnd())));
-        }
-        return new MethodTypeRef(ClassRef.ofDescriptor(returnType), params.stream().map(ClassRef::ofDescriptor).toArray(ClassRef[]::new));
-    }
-
-    /**
-     * Create a {@linkplain MethodTypeRef} from class constant describing
-     * the return type and parameter types.
-     *
-     * @param returnDescriptor a {@linkplain ClassRef} describing the return type
-     * @param paramDescriptors {@linkplain ClassRef}s describing the argument types type
-     * @return a {@linkplain MethodTypeRef} describing the desired method type
-     */
-    @TrackableConstant
-    public static MethodTypeRef of(ClassRef returnDescriptor, ClassRef... paramDescriptors) {
-        return new MethodTypeRef(returnDescriptor, paramDescriptors);
-    }
-
-    /**
-     * Get the return type of the method type described by this {@linkplain MethodTypeRef}
-     * @return the return type
-     */
-    @TrackableConstant
-    public ClassRef returnType() {
-        return returnType;
-    }
-
-    /**
-     * Get the number of parameters of the method type described by
-     * this {@linkplain MethodTypeRef}
-     * @return the number of parameters
-     */
-    @TrackableConstant
-    public int parameterCount() {
-        return argTypes.length;
-    }
-
-    /**
-     * Get the parameter type of the index'th parameter of the method type
-     * described by this {@linkplain MethodTypeRef}
-     *
-     * @param index the index of the parameter to retrieve
-     * @return the parameter type
-     * @throws IndexOutOfBoundsException if the index is outside the half-open
-     * range {[0, parameterCount)}
-     */
-    @TrackableConstant
-    public ClassRef parameterType(int index) {
-        return argTypes[index];
-    }
-
-    /**
-     * Get the parameter types as a {@link List}
-     *
-     * @return the parameter types
-     */
-    @TrackableConstant
-    public List<ClassRef> parameterList() {
-        return Arrays.asList(argTypes);
-    }
-
-    /**
-     * Get the parameter types as an array
-     *
-     * @return the parameter types
-     */
-    @TrackableConstant
-    public ClassRef[] parameterArray() {
-        return argTypes.clone();
-    }
-
-    /**
-     * Return a {@linkplain MethodTypeRef} that is identical to
-     * this one, except the return type is changed to the provided value
-     * @param returnType the new return type
-     * @return the new method type descriptor
-     */
-    @TrackableConstant
-    public MethodTypeRef changeReturnType(ClassRef returnType) {
-        return of(returnType, argTypes);
-    }
-
-    /**
-     * Return a {@linkplain MethodTypeRef} that is identical to this one,
-     * except that a single parameter type has been changed to the provided
-     * value
-     * @param index the index of the parameter to change
-     * @param paramType the new parameter type
-     * @return the new method type descriptor
-     * @throws IndexOutOfBoundsException if the index is outside the half-open
-     * range {[0, parameterCount)}
-     */
-    @TrackableConstant
-    public MethodTypeRef changeParameterType(int index, ClassRef paramType) {
-        ClassRef[] newArgs = argTypes.clone();
-        newArgs[index] = paramType;
-        return of(returnType, newArgs);
-    }
-
-    /**
-     * Return a {@linkplain MethodTypeRef} that is identical to this one,
-     * except that a range of parameters have been removed
-     * @param start the index of the first parameter to remove
-     * @param end the index after the last parameter to remove
-     * @return the new method type descriptor
-     * @throws IndexOutOfBoundsException if {@code start} is outside the half-open
-     * range {[0, parameterCount)}, or {@code end} is outside the closed range
-     * {@code [0, parameterCount]}
-     */
-    @TrackableConstant
-    public MethodTypeRef dropParameterTypes(int start, int end) {
-        if (start < 0 || start >= argTypes.length || end < 0 || end > argTypes.length)
-            throw new IndexOutOfBoundsException();
-        else if (start > end)
-            throw new IllegalArgumentException(String.format("Range (%d, %d) not valid for size %d", start, end, argTypes.length));
-        ClassRef[] newArgs = new ClassRef[argTypes.length - (end - start)];
-        System.arraycopy(argTypes, 0, newArgs, 0, start);
-        System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
-        return of(returnType, newArgs);
-    }
-
-    /**
-     * Return a {@linkplain MethodTypeRef} that is identical to this one,
-     * except that a range of parameters have been inserted
-     * @param pos the index at which to insert the first inserted parameter
-     * @param paramTypes the new parameter types to insert
-     * @return the new method type descriptor
-     * @throws IndexOutOfBoundsException if {@code pos} is outside the closed-open
-     * range {[0, parameterCount]}
-     */
-    @TrackableConstant
-    public MethodTypeRef insertParameterTypes(int pos, ClassRef... paramTypes) {
-        if (pos < 0 || pos > argTypes.length)
-            throw new IndexOutOfBoundsException(pos);
-        ClassRef[] newArgs = new ClassRef[argTypes.length + paramTypes.length];
-        System.arraycopy(argTypes, 0, newArgs, 0, pos);
-        System.arraycopy(paramTypes, 0, newArgs, pos, paramTypes.length);
-        System.arraycopy(argTypes, pos, newArgs, pos+paramTypes.length, argTypes.length - pos);
-        return of(returnType, newArgs);
-    }
-
-    /**
-     * Resolve to a MethodType
-     * @param lookup the lookup
-     * @return the MethodType
-     * @throws ReflectiveOperationException exception
-     */
-    public MethodType resolve(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
-        return MethodType.fromMethodDescriptorString(descriptorString(), lookup.lookupClass().getClassLoader());
-    }
-
-    @Override
-    public String descriptorString() {
-        return String.format("(%s)%s", Stream.of(argTypes).map(ClassRef::descriptorString).collect(Collectors.joining()), returnType.descriptorString());
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        MethodTypeRef constant = (MethodTypeRef) o;
-
-        return (returnType != null
-                ? returnType.equals(constant.returnType)
-                : constant.returnType == null)
-               && Arrays.equals(argTypes, constant.argTypes);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = returnType != null ? returnType.hashCode() : 0;
-        result = 31 * result + Arrays.hashCode(argTypes);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("MethodTypeConstant[%s]", descriptorString());
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/BootstrapSpecifier.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,88 @@
+/*
+ * 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.TrackableConstant;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * A descriptor for an {@code invokedynamic} invocation
+ */
+public final class BootstrapSpecifier {
+    private final MethodHandleRef bootstrapMethod;
+    private final SymbolicRef<?>[] bootstrapArgs;
+
+    private BootstrapSpecifier(MethodHandleRef bootstrapMethod, SymbolicRef<?>... bootstrapArgs) {
+        this.bootstrapMethod = Objects.requireNonNull(bootstrapMethod);
+        this.bootstrapArgs = Objects.requireNonNull(bootstrapArgs.clone());
+    }
+
+    /**
+     * Create a descriptor for an {@code invokedynamic} invocation.
+     * @param bootstrapMethod the bootstrap method for the {@code invokedynamic}
+     * @param bootstrapArgs the bootstrap arguments for the {@code invokedynamic}
+     * @return the descriptor
+     */
+    @TrackableConstant
+    public static BootstrapSpecifier of(MethodHandleRef bootstrapMethod, SymbolicRef<?>... bootstrapArgs) {
+        return new BootstrapSpecifier(bootstrapMethod, bootstrapArgs);
+    }
+
+    /**
+     * Returns the bootstrap method for the {@code invokedynamic}
+     * @return the bootstrap method for the {@code invokedynamic}
+     */
+    @TrackableConstant
+    public MethodHandleRef method() { return bootstrapMethod; }
+
+    /**
+     * Returns the bootstrap arguments for the {@code invokedynamic}
+     * @return the bootstrap arguments for the {@code invokedynamic}
+     */
+    public SymbolicRef<?>[] arguments() { return bootstrapArgs.clone(); }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        BootstrapSpecifier specifier = (BootstrapSpecifier) o;
+        return Objects.equals(bootstrapMethod, specifier.bootstrapMethod) &&
+               Arrays.equals(bootstrapArgs, specifier.bootstrapArgs);
+    }
+
+    @Override
+    public int hashCode() {
+
+        int result = Objects.hash(bootstrapMethod);
+        result = 31 * result + Arrays.hashCode(bootstrapArgs);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("BootstrapSpecifier[%s,%s]", bootstrapMethod, Arrays.toString(bootstrapArgs));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/ClassRef.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,143 @@
+/*
+ * 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.TrackableConstant;
+
+/**
+ * A descriptor for a {@linkplain Class} constant.
+ */
+public interface ClassRef extends SymbolicRef.WithTypeDescriptor<Class<?>> {
+
+    /**
+     * Create a {@linkplain ClassRef} from a dot-separated class name
+     *
+     * @param name the class name
+     * @return a {@linkplain ClassRef} describing the desired class
+     * @throws IllegalArgumentException if the name string does not
+     * describe a valid class name
+     */
+    @TrackableConstant
+    static ClassRef of(String name) {
+        return ClassRef.ofDescriptor("L" + name.replace('.', '/') + ";");
+    }
+
+    /**
+     * Create a {@linkplain ClassRef} from a dot-separated package name and a class name
+     *
+     * @param packageName the package name, dot-separated
+     * @param className the the class name
+     * @return a {@linkplain ClassRef} describing the desired class
+     * @throws IllegalArgumentException if the package name or class name are not in the correct format
+     */
+    @TrackableConstant
+    static ClassRef of(String packageName, String className) {
+        return ofDescriptor("L" + packageName.replace('.', '/') + (packageName.length() > 0 ? "/" : "") + className + ";");
+    }
+
+    /**
+     * Create a {@linkplain ClassRef} from a descriptor string.
+     *
+     * @param descriptor the descriptor string
+     * @return a {@linkplain ClassRef} describing the desired class
+     * @throws NullPointerException if the descriptor string is null
+     * @throws IllegalArgumentException if the descriptor string does not
+     * describe a valid class descriptor
+     */
+    @TrackableConstant
+    static ClassRef ofDescriptor(String descriptor) {
+        if (descriptor == null)
+            throw new NullPointerException("descriptor");
+        else if (descriptor.length() == 1)
+            return new PrimitiveClassRef(descriptor);
+        else
+            return new NamedClassRef(descriptor);
+    }
+
+    /**
+     * Create a {@linkplain ClassRef} describing an array of the type
+     * described by this {@linkplain ClassRef}
+     *
+     * @return a {@linkplain ClassRef} describing an array type
+     */
+    @TrackableConstant
+    default ClassRef array() {
+        return ClassRef.ofDescriptor("[" + descriptorString());
+    }
+
+    /**
+     * Create a {@linkplain ClassRef} describing an inner class of the
+     * non-array reference type described by this {@linkplain ClassRef}
+     */
+    @TrackableConstant
+    ClassRef inner(String innerName);
+
+    /**
+     * Create a {@linkplain ClassRef} describing an inner class of the
+     * non-array reference type described by this {@linkplain ClassRef}
+     */
+    @TrackableConstant
+    ClassRef inner(String firstInnerName, String... moreInnerNames);
+
+    /**
+     * Returns whether this {@linkplain ClassRef}
+     * describes an array type
+     * @return whether this {@linkplain ClassRef}
+     * describes an array type
+     */
+    default boolean isArray() {
+        return descriptorString().startsWith("[");
+    }
+
+    /**
+     * Returns whether this {@linkplain ClassRef}
+     * describes a primitive type
+     * @return whether this {@linkplain ClassRef}
+     * describes a primitive type
+     */
+    default boolean isPrimitive() {
+        return descriptorString().length() == 1;
+    }
+
+    /**
+     * The component type of this {@linkplain ClassRef} if it describes
+     * an array type, otherwise the type that it describes
+     * @return the component type of the type described by this
+     * @throws IllegalStateException if this reference does not describe an array type
+     * {@linkplain ClassRef}
+     */
+    @TrackableConstant
+    default ClassRef componentType() {
+        if (!isArray())
+            throw new IllegalStateException();
+        return ClassRef.ofDescriptor(descriptorString().substring(1));
+    }
+
+    /**
+     * Return the canonical name of the type described by this descriptor
+     * @return the canonical name of the type described by this descriptor
+     */
+    String canonicalName();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/DynamicConstantRef.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,241 @@
+/*
+ * 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.TrackableConstant;
+import java.lang.invoke.ConstantBootstraps;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A descriptor for a dynamic constant.
+ */
+public class DynamicConstantRef<T> implements SymbolicRef<T> {
+    private static final SymbolicRef<?>[] EMPTY_ARGS = new SymbolicRef<?>[0];
+
+    private final MethodHandleRef bootstrapMethod;
+    private final SymbolicRef<?>[] bootstrapArgs;
+    private final String name;
+    private final ClassRef type;
+
+    @SuppressWarnings("rawtypes")
+    private static final Map<MethodHandleRef, Function<DynamicConstantRef, SymbolicRef>> 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));
+
+    protected DynamicConstantRef(MethodHandleRef bootstrapMethod, String name, ClassRef type, SymbolicRef<?>[] bootstrapArgs) {
+        if (name == null || name.length() == 0)
+            throw new IllegalArgumentException("Illegal invocation name: " + name);
+        this.bootstrapMethod = requireNonNull(bootstrapMethod);
+        this.name = name;
+        this.type = requireNonNull(type);
+        this.bootstrapArgs = requireNonNull(bootstrapArgs).clone();
+    }
+
+    protected DynamicConstantRef(MethodHandleRef bootstrapMethod, String name, ClassRef type) {
+        this(bootstrapMethod, name, type, EMPTY_ARGS);
+    }
+
+    /**
+     * Return a descriptor for a dynamic constant whose bootstrap, invocation
+     * name, and invocation type are the same as this one, but with the specified
+     * bootstrap arguments
+     *
+     * @param bootstrapArgs the bootstrap arguments
+     * @return the descriptor for the dynamic constant
+     */
+    @TrackableConstant
+    public DynamicConstantRef<T> withArgs(SymbolicRef<?>... bootstrapArgs) {
+        return new DynamicConstantRef<>(bootstrapMethod, name, type, bootstrapArgs);
+    }
+
+    /**
+     * Return a descriptor for a dynamic constant.  If  the bootstrap corresponds
+     * to a well-known bootstrap, for which a higher-level constant (e.g., ClassRef)
+     * is available, then the higher-level constant will be returned
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod the bootstrap method
+     * @param name the name for the dynamic constant
+     * @param type the type of the dynamic constant
+     * @param bootstrapArgs the bootstrap arguments
+     * @return the descriptor for the symbolic reference
+     */
+    @TrackableConstant
+    public static<T> SymbolicRef<T> ofCanonical(MethodHandleRef bootstrapMethod, String name, ClassRef type, SymbolicRef<?>[] bootstrapArgs) {
+        DynamicConstantRef<T> dcr = new DynamicConstantRef<>(bootstrapMethod, name, type, bootstrapArgs);
+        return dcr.canonicalize();
+    }
+
+    private SymbolicRef<T> canonicalize() {
+        @SuppressWarnings("rawtypes")
+        Function<DynamicConstantRef, SymbolicRef> f = canonicalMap.get(bootstrapMethod);
+        if (f != null) {
+            @SuppressWarnings("unchecked")
+            SymbolicRef<T> converted = f.apply(this);
+            return converted;
+        }
+        return this;
+    }
+
+    /**
+     * Return a descriptor for a dynamic constant
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod the bootstrap method
+     * @param name the name for the dynamic constant
+     * @param type the type of the dynamic constant
+     * @param bootstrapArgs the bootstrap arguments
+     * @return the descriptor for the dynamic constant
+     */
+    @TrackableConstant
+    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, String name, ClassRef type, SymbolicRef<?>[] bootstrapArgs) {
+        return new DynamicConstantRef<>(bootstrapMethod, name, type, bootstrapArgs);
+    }
+
+    /**
+     * Return a descriptor for a dynamic constant whose bootstrap has no static arguments.
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod the bootstrap method
+     * @param name the name for the dynamic constant
+     * @param type the type of the dynamic constant
+     * @return the descriptor for the dynamic constant
+     */
+    @TrackableConstant
+    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, String name, ClassRef type) {
+        return new DynamicConstantRef<>(bootstrapMethod, name, type);
+    }
+
+    /**
+     * Return a descriptor for a dynamic constant whose bootstrap has no static arguments,
+     * and whose name is ignored by the bootstrap
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod the bootstrap method
+     * @param type the type of the dynamic constant
+     * @return the descriptor for the dynamic constant
+     */
+    @TrackableConstant
+    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, ClassRef type) {
+        return of(bootstrapMethod, "_", type);
+    }
+
+    /**
+     * Return a descriptor for a dynamic constant whose bootstrap has no static arguments,
+     * anmd whose type is the same as the bootstrap return
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod the bootstrap method
+     * @param name the name for the dynamic constant
+     * @return the descriptor for the dynamic constant
+     */
+    @TrackableConstant
+    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod, String name) {
+        return of(bootstrapMethod, name, bootstrapMethod.type().returnType());
+    }
+
+    /**
+     * Return a descriptor for a dynamic constant whose bootstrap has no static arguments,
+     * whose name is ignored by the bootstrap, and whose type is the same as the bootstrap return
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod the bootstrap method
+     * @return the descriptor for the dynamic constant
+     */
+    @TrackableConstant
+    public static<T> DynamicConstantRef<T> of(MethodHandleRef bootstrapMethod) {
+        return of(bootstrapMethod, "_");
+    }
+
+    /**
+     * returns the name
+     * @return the name
+     */
+    @TrackableConstant
+    public String name() {
+        return name;
+    }
+
+    /**
+     * returns the type
+     * @return the type
+     */
+    @TrackableConstant
+    public ClassRef type() {
+        return type;
+    }
+
+    /**
+     * Returns the bootstrap method in the bootstrap specifier
+     * @return the bootstrap method in the bootstrap specifier
+     */
+    @TrackableConstant
+    public MethodHandleRef bootstrapMethod() { return bootstrapMethod; }
+
+    /**
+     * Returns the bootstrap arguments in the bootstrap specifier
+     * @return the bootstrap arguments in the bootstrap specifier
+     */
+    public SymbolicRef<?>[] bootstrapArgs() { return bootstrapArgs.clone(); }
+
+    private static Object[] resolveArgs(MethodHandles.Lookup lookup, SymbolicRef<?>[] args) {
+        return Stream.of(args)
+                     .map(arg -> {
+                         try {
+                             return arg.resolveRef(lookup);
+                         }
+                         catch (ReflectiveOperationException e) {
+                             throw new RuntimeException(e);
+                         }
+                     })
+                     .toArray();
+    }
+
+    /**
+     * Resolve
+     * @param lookup the lookup
+     * @return the resolved object
+     * @throws ReflectiveOperationException exception
+     */
+    @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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/EnumRef.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,85 @@
+/*
+ * 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.TrackableConstant;
+import java.lang.invoke.MethodHandles;
+import java.util.Objects;
+
+/**
+ * EnumRef
+ *
+ * @author Brian Goetz
+ */
+public final class EnumRef<E extends Enum<E>> extends DynamicConstantRef<E> {
+    private final ClassRef enumClass;
+    private final String constantName;
+
+    private EnumRef(ClassRef enumClass, String constantName) {
+        super(SymbolicRefs.BSM_ENUM_CONSTANT, constantName, enumClass);
+        this.enumClass = enumClass;
+        this.constantName = constantName;
+    }
+
+    @TrackableConstant
+    public static<E extends Enum<E>> EnumRef<E> of(ClassRef enumClass, String constantName) {
+        return new EnumRef<>(enumClass, constantName);
+    }
+
+    @TrackableConstant
+    public ClassRef enumClass() {
+        return enumClass;
+    }
+
+    @TrackableConstant
+    public String constantName() {
+        return constantName;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public E resolveRef(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
+        return Enum.valueOf((Class<E>) enumClass.resolveRef(lookup), constantName);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        EnumRef<?> ref = (EnumRef<?>) o;
+        return Objects.equals(enumClass, ref.enumClass) &&
+               Objects.equals(constantName, ref.constantName);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(enumClass, constantName);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("EnumRef[%s.%s]", enumClass, constantName);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/MethodHandleRef.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,269 @@
+/*
+ * 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.TrackableConstant;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.util.Objects;
+
+import static java.lang.invoke.MethodHandleInfo.REF_getField;
+import static java.lang.invoke.MethodHandleInfo.REF_getStatic;
+import static java.lang.invoke.MethodHandleInfo.REF_invokeInterface;
+import static java.lang.invoke.MethodHandleInfo.REF_invokeSpecial;
+import static java.lang.invoke.MethodHandleInfo.REF_invokeStatic;
+import static java.lang.invoke.MethodHandleInfo.REF_invokeVirtual;
+import static java.lang.invoke.MethodHandleInfo.REF_newInvokeSpecial;
+import static java.lang.invoke.MethodHandleInfo.REF_putField;
+import static java.lang.invoke.MethodHandleInfo.REF_putStatic;
+import static java.lang.sym.MethodHandleRef.Kind.STATIC;
+
+/**
+ * A descriptor for a {@linkplain MethodHandle} constant.
+ */
+public final class MethodHandleRef implements SymbolicRef<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
+     */
+    public enum Kind {
+        @TrackableConstant STATIC(REF_invokeStatic),
+        @TrackableConstant VIRTUAL(REF_invokeVirtual),
+        @TrackableConstant INTERFACE_VIRTUAL(REF_invokeInterface),
+        @TrackableConstant SPECIAL(REF_invokeSpecial),
+        @TrackableConstant CONSTRUCTOR(REF_newInvokeSpecial),
+        @TrackableConstant GETTER(REF_getField),
+        @TrackableConstant SETTER(REF_putField),
+        @TrackableConstant STATIC_GETTER(REF_getStatic),
+        @TrackableConstant STATIC_SETTER(REF_putStatic);
+
+        public final int refKind;
+
+        Kind(int refKind) {
+            this.refKind = refKind;
+        }
+    }
+
+    private final Kind kind;
+    private final ClassRef owner;
+    private final String name;
+    private final MethodTypeRef type;
+
+    private MethodHandleRef(Kind kind, ClassRef owner, String name, MethodTypeRef type) {
+        this.kind = kind;
+        this.owner = owner;
+        this.name = name;
+        this.type = type;
+    }
+
+    /**
+     * Return a {@code MethodHandleRef} corresponding to an
+     * invocation of a static method
+     * @param kind One of: STATIC, VIRTUAL, INTERFACE_VIRTUAL, SPECIAL, CONSTRUCTOR
+     * @param clazz the class containing the method
+     * @param name the name of the method (ignored if kind=CONSTRUCTOR)
+     * @param type the method type of the method
+     * @return the {@code MethodHandleRef}
+     */
+    @TrackableConstant
+    public static MethodHandleRef of(Kind kind, ClassRef clazz, String name, MethodTypeRef type) {
+        switch (kind) {
+            case STATIC:
+            case VIRTUAL:
+            case INTERFACE_VIRTUAL:
+            case SPECIAL:
+                return new MethodHandleRef(kind, clazz, name, type);
+            case CONSTRUCTOR:
+                return new MethodHandleRef(kind, clazz, "<init>", type);
+            default:
+                throw new IllegalArgumentException(kind.toString());
+        }
+    }
+
+    /**
+     * Return a {@code MethodHandleRef} corresponding to an
+     * invocation of a static method
+     * @param kind One of: STATIC, VIRTUAL, INTERFACE_VIRTUAL, SPECIAL, CONSTRUCTOR
+     * @param clazz the class containing the method
+     * @param name the name of the method (ignored if kind=CONSTRUCTOR)
+     * @param descriptorString descriptor string of the method
+     * @return the {@code MethodHandleRef}
+     */
+    @TrackableConstant
+    public static MethodHandleRef of(Kind kind, ClassRef clazz, String name, String descriptorString) {
+        return of(kind, clazz, name, MethodTypeRef.ofDescriptor(descriptorString));
+    }
+
+    /**
+     * Return a {@code MethodHandleRef} corresponding to an
+     * invocation of a static method
+     * @param kind One of: STATIC, VIRTUAL, INTERFACE_VIRTUAL, SPECIAL, CONSTRUCTOR
+     * @param clazz the class containing the method
+     * @param name the name of the method (ignored if kind=CONSTRUCTOR)
+     * @param returnType the return type of the method
+     * @param paramTypes the parameter types of the method
+     * @return the {@code MethodHandleRef}
+     */
+    @TrackableConstant
+    public static MethodHandleRef of(Kind kind, ClassRef clazz, String name, ClassRef returnType, ClassRef... paramTypes) {
+        return of(kind, clazz, name, MethodTypeRef.of(returnType, paramTypes));
+    }
+
+    /**
+     * Return a {@code MethodHandleRef} corresponding to an invokedynamic bootstrap,
+     * which is a static method whose leading arguments are {@code Lookup}, {@code String}, and {@code MethodType}
+     * @param clazz the class containing the method
+     * @param name the name of the method
+     * @param returnType the return type of the method
+     * @param paramTypes the parameter types of the method
+     * @return the {@code MethodHandleRef}
+     */
+    @TrackableConstant
+    public static MethodHandleRef ofIndyBootstrap(ClassRef clazz, String name, ClassRef returnType, ClassRef... paramTypes) {
+        return of(STATIC, clazz, name, MethodTypeRef.of(returnType, paramTypes).insertParameterTypes(0, INDY_BOOTSTRAP_ARGS));
+    }
+
+    /**
+     * Return a {@code MethodHandleRef} corresponding to a constantdynamic bootstrap,
+     * which is a static method whose leading arguments are {@code Lookup}, {@code String}, and {@code Class}
+     * @param clazz the class containing the method
+     * @param name the name of the method
+     * @param returnType the return type of the method
+     * @param paramTypes the parameter types of the method
+     * @return the {@code MethodHandleRef}
+     */
+    @TrackableConstant
+    public static MethodHandleRef ofCondyBootstrap(ClassRef clazz, String name, ClassRef returnType, ClassRef... paramTypes) {
+        return of(STATIC, clazz, name, MethodTypeRef.of(returnType, paramTypes).insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS));
+    }
+
+    /**
+     * Return a {@code MethodHandleRef} corresponding to invocation
+     * of an instance field getter
+     * @param clazz the class containing the field
+     * @param name the name of the field
+     * @param type the type of the field
+     * @return the {@code MethodHandleRef}
+     */
+    @TrackableConstant
+    public static MethodHandleRef ofField(Kind kind, ClassRef clazz, String name, ClassRef type) {
+        switch (kind) {
+            case GETTER: return new MethodHandleRef(Kind.GETTER, clazz, name, MethodTypeRef.of(type, clazz));
+            case SETTER:
+                return new MethodHandleRef(Kind.SETTER, clazz, name, MethodTypeRef.of(SymbolicRefs.CR_void, clazz, type));
+            case STATIC_GETTER: return new MethodHandleRef(Kind.STATIC_GETTER, clazz, name, MethodTypeRef.of(type));
+            case STATIC_SETTER:
+                return new MethodHandleRef(Kind.STATIC_SETTER, clazz, name, MethodTypeRef.of(SymbolicRefs.CR_void, type));
+            default: throw new IllegalArgumentException(kind.toString());
+        }
+    }
+
+    /**
+     * Resolve to a MethodHandle
+     * @param lookup the lookup
+     * @return the MethodHandle
+     * @throws ReflectiveOperationException exception
+     */
+    public MethodHandle resolveRef(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
+        switch (kind) {
+            case STATIC: return lookup.findStatic(owner.resolveRef(lookup), name, type.resolveRef(lookup));
+            case INTERFACE_VIRTUAL:
+            case VIRTUAL:
+                return lookup.findVirtual(owner.resolveRef(lookup), name, type.resolveRef(lookup));
+            case SPECIAL: return lookup.findSpecial(owner.resolveRef(lookup), name, type.resolveRef(lookup), lookup.lookupClass());
+            case CONSTRUCTOR: return lookup.findConstructor(owner.resolveRef(lookup), type.resolveRef(lookup));
+            case GETTER: return lookup.findGetter(owner.resolveRef(lookup), name, type.resolveRef(lookup).returnType());
+            case STATIC_GETTER: return lookup.findStaticGetter(owner.resolveRef(lookup), name, type.resolveRef(lookup).returnType());
+            case SETTER: return lookup.findSetter(owner.resolveRef(lookup), name, type.resolveRef(lookup).parameterType(1));
+            case STATIC_SETTER: return lookup.findStaticSetter(owner.resolveRef(lookup), name, type.resolveRef(lookup).parameterType(0));
+            default: throw new IllegalStateException(kind.name());
+        }
+    }
+
+    /**
+     * Return the {@code refKind} of the method handle described by this descriptor,
+     * as defined by {@link MethodHandleInfo}
+     * @return the reference kind
+     */
+    @TrackableConstant
+    public int refKind() { return kind.refKind; }
+
+    /**
+     * Return the class in which the method described by this descriptor is
+     * declared
+     *
+     * @return the class in which the method is declared
+     */
+    @TrackableConstant
+    public ClassRef owner() {
+        return owner;
+    }
+
+    /**
+     * Return the name of the method described by this descriptor
+     * @return the name of the method
+     */
+    @TrackableConstant
+    public String name() {
+        return name;
+    }
+
+    /**
+     * Return the method type of the method described by this descriptor
+     * @return the method type
+     */
+    @TrackableConstant
+    public MethodTypeRef type() {
+        return type;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        MethodHandleRef ref = (MethodHandleRef) o;
+        return kind == ref.kind &&
+               Objects.equals(owner, ref.owner) &&
+               Objects.equals(name, ref.name) &&
+               Objects.equals(type, ref.type);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(kind, owner, name, type);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("MethodHandleRef[kind=%s, owner=%s, name=%s, type=%s]", kind, owner, name, type);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/MethodTypeRef.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,264 @@
+/*
+ * 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.TrackableConstant;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A descriptor for a {@linkplain MethodType} constant.
+ */
+public final class MethodTypeRef implements SymbolicRef.WithTypeDescriptor<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("\\((.*)\\)(.*)");
+
+    private final ClassRef returnType;
+    private final ClassRef[] argTypes;
+
+    private MethodTypeRef(ClassRef returnType, ClassRef[] argTypes) {
+        this.returnType = requireNonNull(returnType);
+        this.argTypes = requireNonNull(argTypes);
+    }
+
+    /**
+     * Create a {@linkplain MethodTypeRef} from a descriptor string.
+     *
+     * @param descriptor the descriptor string
+     * @return a {@linkplain MethodTypeRef} describing the desired method type
+     * @throws IllegalArgumentException if the descriptor string does not
+     * describe a valid method descriptor
+     */
+    @TrackableConstant
+    public static MethodTypeRef ofDescriptor(String descriptor) {
+        Matcher matcher = pattern.matcher(descriptor);
+        if (!matcher.matches())
+            throw new IllegalArgumentException(String.format("%s is not a valid method descriptor", descriptor));
+        String paramTypes = matcher.group(1);
+        String returnType = matcher.group(2);
+        if (!TYPE_DESC.matcher(returnType).matches())
+            throw new IllegalArgumentException(String.format("Invalid return type %s", returnType));
+        List<String> params = new ArrayList<>();
+        matcher = TYPE_DESC.matcher(paramTypes);
+        while (matcher.regionStart() < paramTypes.length()) {
+            if (matcher.lookingAt()) {
+                params.add(matcher.group());
+                matcher.region(matcher.end(), matcher.regionEnd());
+            }
+            else
+                throw new IllegalArgumentException(String.format("Invalid parameter type: %s", paramTypes.substring(matcher.regionStart(), matcher.regionEnd())));
+        }
+        return new MethodTypeRef(ClassRef.ofDescriptor(returnType), params.stream().map(ClassRef::ofDescriptor).toArray(ClassRef[]::new));
+    }
+
+    /**
+     * Create a {@linkplain MethodTypeRef} from class constant describing
+     * the return type and parameter types.
+     *
+     * @param returnDescriptor a {@linkplain ClassRef} describing the return type
+     * @param paramDescriptors {@linkplain ClassRef}s describing the argument types type
+     * @return a {@linkplain MethodTypeRef} describing the desired method type
+     */
+    @TrackableConstant
+    public static MethodTypeRef of(ClassRef returnDescriptor, ClassRef... paramDescriptors) {
+        return new MethodTypeRef(returnDescriptor, paramDescriptors);
+    }
+
+    /**
+     * Get the return type of the method type described by this {@linkplain MethodTypeRef}
+     * @return the return type
+     */
+    @TrackableConstant
+    public ClassRef returnType() {
+        return returnType;
+    }
+
+    /**
+     * Get the number of parameters of the method type described by
+     * this {@linkplain MethodTypeRef}
+     * @return the number of parameters
+     */
+    @TrackableConstant
+    public int parameterCount() {
+        return argTypes.length;
+    }
+
+    /**
+     * Get the parameter type of the index'th parameter of the method type
+     * described by this {@linkplain MethodTypeRef}
+     *
+     * @param index the index of the parameter to retrieve
+     * @return the parameter type
+     * @throws IndexOutOfBoundsException if the index is outside the half-open
+     * range {[0, parameterCount)}
+     */
+    @TrackableConstant
+    public ClassRef parameterType(int index) {
+        return argTypes[index];
+    }
+
+    /**
+     * Get the parameter types as a {@link List}
+     *
+     * @return the parameter types
+     */
+    @TrackableConstant
+    public List<ClassRef> parameterList() {
+        return Arrays.asList(argTypes);
+    }
+
+    /**
+     * Get the parameter types as an array
+     *
+     * @return the parameter types
+     */
+    @TrackableConstant
+    public ClassRef[] parameterArray() {
+        return argTypes.clone();
+    }
+
+    /**
+     * Return a {@linkplain MethodTypeRef} that is identical to
+     * this one, except the return type is changed to the provided value
+     * @param returnType the new return type
+     * @return the new method type descriptor
+     */
+    @TrackableConstant
+    public MethodTypeRef changeReturnType(ClassRef returnType) {
+        return of(returnType, argTypes);
+    }
+
+    /**
+     * Return a {@linkplain MethodTypeRef} that is identical to this one,
+     * except that a single parameter type has been changed to the provided
+     * value
+     * @param index the index of the parameter to change
+     * @param paramType the new parameter type
+     * @return the new method type descriptor
+     * @throws IndexOutOfBoundsException if the index is outside the half-open
+     * range {[0, parameterCount)}
+     */
+    @TrackableConstant
+    public MethodTypeRef changeParameterType(int index, ClassRef paramType) {
+        ClassRef[] newArgs = argTypes.clone();
+        newArgs[index] = paramType;
+        return of(returnType, newArgs);
+    }
+
+    /**
+     * Return a {@linkplain MethodTypeRef} that is identical to this one,
+     * except that a range of parameters have been removed
+     * @param start the index of the first parameter to remove
+     * @param end the index after the last parameter to remove
+     * @return the new method type descriptor
+     * @throws IndexOutOfBoundsException if {@code start} is outside the half-open
+     * range {[0, parameterCount)}, or {@code end} is outside the closed range
+     * {@code [0, parameterCount]}
+     */
+    @TrackableConstant
+    public MethodTypeRef dropParameterTypes(int start, int end) {
+        if (start < 0 || start >= argTypes.length || end < 0 || end > argTypes.length)
+            throw new IndexOutOfBoundsException();
+        else if (start > end)
+            throw new IllegalArgumentException(String.format("Range (%d, %d) not valid for size %d", start, end, argTypes.length));
+        ClassRef[] newArgs = new ClassRef[argTypes.length - (end - start)];
+        System.arraycopy(argTypes, 0, newArgs, 0, start);
+        System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
+        return of(returnType, newArgs);
+    }
+
+    /**
+     * Return a {@linkplain MethodTypeRef} that is identical to this one,
+     * except that a range of parameters have been inserted
+     * @param pos the index at which to insert the first inserted parameter
+     * @param paramTypes the new parameter types to insert
+     * @return the new method type descriptor
+     * @throws IndexOutOfBoundsException if {@code pos} is outside the closed-open
+     * range {[0, parameterCount]}
+     */
+    @TrackableConstant
+    public MethodTypeRef insertParameterTypes(int pos, ClassRef... paramTypes) {
+        if (pos < 0 || pos > argTypes.length)
+            throw new IndexOutOfBoundsException(pos);
+        ClassRef[] newArgs = new ClassRef[argTypes.length + paramTypes.length];
+        System.arraycopy(argTypes, 0, newArgs, 0, pos);
+        System.arraycopy(paramTypes, 0, newArgs, pos, paramTypes.length);
+        System.arraycopy(argTypes, pos, newArgs, pos+paramTypes.length, argTypes.length - pos);
+        return of(returnType, newArgs);
+    }
+
+    /**
+     * Resolve to a MethodType
+     * @param lookup the lookup
+     * @return the MethodType
+     * @throws ReflectiveOperationException exception
+     */
+    public MethodType resolveRef(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
+        return MethodType.fromMethodDescriptorString(descriptorString(), lookup.lookupClass().getClassLoader());
+    }
+
+    @Override
+    public String descriptorString() {
+        return String.format("(%s)%s",
+                             Stream.of(argTypes)
+                                   .map(ClassRef::descriptorString)
+                                   .collect(Collectors.joining()),
+                             returnType.descriptorString());
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MethodTypeRef constant = (MethodTypeRef) o;
+
+        return (returnType != null
+                ? returnType.equals(constant.returnType)
+                : constant.returnType == null)
+               && Arrays.equals(argTypes, constant.argTypes);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = returnType != null ? returnType.hashCode() : 0;
+        result = 31 * result + Arrays.hashCode(argTypes);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("MethodTypeConstant[%s]", descriptorString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/NamedClassRef.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,139 @@
+/*
+ * 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.TrackableConstant;
+import java.lang.invoke.ConstantBootstraps;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Array;
+import java.util.Objects;
+import java.util.regex.Pattern;
+import java.util.stream.Stream;
+
+import sun.invoke.util.Wrapper;
+
+import static java.util.stream.Collectors.joining;
+
+/**
+ * NamedClassRef
+ *
+ * @author Brian Goetz
+ */
+public final class NamedClassRef implements ClassRef {
+    static final Pattern TYPE_DESC = Pattern.compile("(\\[*)(V|I|J|S|B|C|F|D|Z|L[^/.\\[;][^.\\[;]*;)");
+
+    private final String descriptor;
+
+    NamedClassRef(String descriptor) {
+        if (descriptor == null
+            || !TYPE_DESC.matcher(descriptor).matches())
+            throw new IllegalArgumentException(String.format("%s is not a valid type descriptor", descriptor));
+        this.descriptor = descriptor;
+    }
+
+    /**
+     * Create a {@linkplain ClassRef} describing an inner class of the
+     * non-array reference type described by this {@linkplain ClassRef}
+     */
+    @TrackableConstant
+    public ClassRef inner(String innerName) {
+        if (!descriptor.startsWith("L"))
+            throw new IllegalStateException("Outer class is not a non-array reference type");
+        return ClassRef.ofDescriptor(descriptor.substring(0, descriptor.length() - 1) + "$" + innerName + ";");
+    }
+
+    /**
+     * Create a {@linkplain ClassRef} describing an inner class of the
+     * non-array reference type described by this {@linkplain ClassRef}
+     */
+    @TrackableConstant
+    public ClassRef inner(String firstInnerName, String... moreInnerNames) {
+        if (!descriptor.startsWith("L"))
+            throw new IllegalStateException("Outer class is not a non-array reference type");
+        return moreInnerNames.length == 0
+               ? inner(firstInnerName)
+               : ClassRef.ofDescriptor(descriptor.substring(0, descriptor.length() - 1) + "$" + firstInnerName
+                                       + Stream.of(moreInnerNames).collect(joining("$", "$", "")) + ";");
+    }
+
+    @Override
+    @TrackableConstant
+    public String descriptorString() {
+        return descriptor;
+    }
+
+    /**
+     * Return the canonical name of the type described by this descriptor
+     * @return the canonical name of the type described by this descriptor
+     */
+    public String canonicalName() {
+        // @@@ Arrays?
+        return descriptor.substring(1, descriptor.length() - 1).replace('/', '.');
+    }
+
+    /**
+     * Resolve to a Class
+     * @param lookup the lookup
+     * @return return the class
+     * @throws ReflectiveOperationException exception
+     */
+    public Class<?> resolveRef(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
+        ClassRef comp = this;
+        int depth = 0;
+        while (comp.isArray()) {
+            ++depth;
+            comp = comp.componentType();
+        }
+        String compDescr = comp.descriptorString();
+
+        if (compDescr.length() == 1)
+            return Class.forName(descriptor, true, lookup.lookupClass().getClassLoader());
+        else {
+            Class<?> clazz = Class.forName(compDescr.substring(1, compDescr.length() - 1).replace('/', '.'), true, lookup.lookupClass().getClassLoader());
+            for (int i = 0; i < depth; i++)
+                clazz = Array.newInstance(clazz, 0).getClass();
+            return clazz;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ClassRef constant = (ClassRef) o;
+        return Objects.equals(descriptorString(), constant.descriptorString());
+    }
+
+    @Override
+    public int hashCode() {
+        return descriptorString() != null ? descriptorString().hashCode() : 0;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("ClassRef[%s]", descriptorString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/PrimitiveClassRef.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,100 @@
+/*
+ * 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.TrackableConstant;
+import java.lang.invoke.DynamicConstant;
+import java.lang.invoke.MethodHandles;
+import java.util.Objects;
+
+import sun.invoke.util.Wrapper;
+
+/**
+ * PrimitiveClassRef
+ *
+ * @author Brian Goetz
+ */
+class PrimitiveClassRef extends DynamicConstantRef<Class<?>> implements ClassRef {
+    private final String descriptor;
+
+    PrimitiveClassRef(String descriptor) {
+        super(SymbolicRefs.BSM_PRIMITIVE_CLASS, checkDescriptor(descriptor), SymbolicRefs.CR_Class);
+        this.descriptor = descriptor;
+    }
+
+    private static String checkDescriptor(String descriptor) {
+        if (descriptor == null
+            || descriptor.length() != 1
+            || "IJCSBFDZV".indexOf(descriptor.charAt(0)) < 0)
+            throw new IllegalArgumentException("Invalid primitive type descriptor " + descriptor);
+        return descriptor;
+    }
+
+    @Override
+    public String canonicalName() {
+        return Wrapper.forBasicType(descriptor.charAt(0)).primitiveSimpleName();
+    }
+
+    @Override
+    @TrackableConstant
+    public String descriptorString() {
+        return descriptor;
+    }
+
+    @Override
+    public ClassRef inner(String innerName) {
+        throw new IllegalStateException("Outer class is not a non-array reference type");
+    }
+
+    @Override
+    public ClassRef inner(String firstInnerName, String... moreInnerNames) {
+        throw new IllegalStateException("Outer class is not a non-array reference type");
+    }
+
+    @Override
+    public Class<?> resolveRef(MethodHandles.Lookup lookup) {
+        return Wrapper.forBasicType(descriptor.charAt(0)).primitiveType();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ClassRef constant = (ClassRef) o;
+        return Objects.equals(descriptorString(), constant.descriptorString());
+    }
+
+    @Override
+    public int hashCode() {
+        return descriptorString() != null ? descriptorString().hashCode() : 0;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("ClassRef[%s]", descriptorString());
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/SymbolicRef.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2017, 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.TrackableConstant;
+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;
+
+/**
+ * Purely-nominal descriptor for a constant value expressible in a classfile
+ * constant pool.
+ *
+ * <p> Native constant types that don't require linkage ({@link String}, {@link
+ * Integer}, {@link Long}, {@link Float}, and {@link Double}) implement
+ * {@linkplain SymbolicRef} directly. Native linkable constant types ({@link
+ * Class}, {@link MethodType}, and {@link MethodHandle}) are represented as
+ * {@linkplain SymbolicRef} via the symbolic reference classes {@link ClassRef},
+ * {@link MethodTypeRef}, and {@link MethodHandleRef}.  Dynamic constants are
+ * represented by the symbolic reference type {@link DynamicConstantRef}.
+ *
+ * <p>APIs that deal in generation or parsing of bytecode should use
+ * {@linkplain SymbolicRef} to describe the operand of an {@code LDC} instruction,
+ * including dynamic constants, and the static argument lists of
+ * {@code invokedynamic} instructions.  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, names in a {@linkplain SymbolicRef} are
+ * independent of a class loader.  When a {@linkplain SymbolicRef} is
+ * intrinsified, it is interpreted relative to the class loader that loaded the
+ * class in which the intrinsic appears (just like names that appear in that
+ * classes constant pool.)
+ *
+ * @param <T> The type of the object which this {@linkplain SymbolicRef}
+ *            describes
+ * @see Intrinsics
+ * @see TrackableConstant
+ */
+public interface SymbolicRef<T> {
+
+    T resolveRef(MethodHandles.Lookup lookup) throws ReflectiveOperationException;
+
+    /**
+     * Construct a VarHandle for an instance field
+     * @param owner the class containing the field
+     * @param name the field name
+     * @param type the field type
+     * @return the VarHandle
+     */
+    static SymbolicRef<VarHandle> fieldVarHandle(ClassRef owner, String name, ClassRef type) {
+        return DynamicConstantRef.<VarHandle>of(SymbolicRefs.BSM_VARHANDLE_FIELD, name).withArgs(owner, type);
+    }
+
+    /**
+     * Construct a VarHandle for a static field
+     * @param owner the class containing the field
+     * @param name the field name
+     * @param type the field type
+     * @return the VarHandle
+     */
+    static SymbolicRef<VarHandle> staticFieldVarHandle(ClassRef owner, String name, ClassRef type) {
+        return DynamicConstantRef.<VarHandle>of(SymbolicRefs.BSM_VARHANDLE_STATIC_FIELD, name).withArgs(owner, type);
+    }
+
+    /**
+     * Construct a VarHandle for an array
+     * @param arrayClass the array class
+     * @return the VarHandle
+     */
+    static SymbolicRef<VarHandle> arrayVarHandle(ClassRef arrayClass) {
+        return DynamicConstantRef.<VarHandle>of(SymbolicRefs.BSM_VARHANDLE_ARRAY).withArgs(arrayClass);
+    }
+
+    /**
+     * 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 to which this constant pool entry resolves
+     */
+    public interface WithTypeDescriptor<T> extends SymbolicRef<T> {
+        /**
+         * Return the descriptor string associated with this constant pool entry
+         *
+         * @return the descriptor string
+         */
+        @TrackableConstant
+        String descriptorString();
+    }
+
+    /**
+     * SelfRef
+     *
+     * @author Brian Goetz
+     */
+    interface OfSelf<T extends SymbolicRef<T>> extends SymbolicRef<T>, Constable<T, T> {
+        @Override
+        @SuppressWarnings("unchecked")
+        default Optional<T> toSymbolicRef(MethodHandles.Lookup lookup) {
+            return Optional.of((T) this);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        default T resolveRef(MethodHandles.Lookup lookup) {
+            return (T) this;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/sym/SymbolicRefs.java	Fri Dec 22 13:06:32 2017 -0500
@@ -0,0 +1,196 @@
+/*
+ * 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.TrackableConstant;
+
+/**
+ * SymbolicRefs
+ *
+ * @author Brian Goetz
+ */
+public final class SymbolicRefs {
+    // Warning -- don't change the order of these declarations!
+
+    /**  ClassRef representing the class java.lang.Object */
+    @TrackableConstant
+    public static final ClassRef CR_Object = ClassRef.of("java.lang.Object");
+
+    /**  ClassRef representing the class java.lang.String */
+    @TrackableConstant
+    public static final ClassRef CR_String = ClassRef.of("java.lang.String");
+
+    /**  ClassRef representing the class java.lang.Class */
+    @TrackableConstant
+    public static final ClassRef CR_Class = ClassRef.of("java.lang.Class");
+
+    /**  ClassRef representing the class java.lang.Number */
+    @TrackableConstant
+    public static final ClassRef CR_Number = ClassRef.of("java.lang.Number");
+
+    /**  ClassRef representing the class java.lang.Integer */
+    @TrackableConstant
+    public static final ClassRef CR_Integer = ClassRef.of("java.lang.Integer");
+
+    /**  ClassRef representing the class java.lang.Long */
+    @TrackableConstant
+    public static final ClassRef CR_Long = ClassRef.of("java.lang.Long");
+
+    /**  ClassRef representing the class java.lang.Float */
+    @TrackableConstant
+    public static final ClassRef CR_Float = ClassRef.of("java.lang.Float");
+
+    /**  ClassRef representing the class java.lang.Double */
+    @TrackableConstant
+    public static final ClassRef CR_Double = ClassRef.of("java.lang.Double");
+
+    /**  ClassRef representing the class java.lang.Short */
+    @TrackableConstant
+    public static final ClassRef CR_Short = ClassRef.of("java.lang.Short");
+
+    /**  ClassRef representing the class java.lang.Byte */
+    @TrackableConstant
+    public static final ClassRef CR_Byte = ClassRef.of("java.lang.Byte");
+
+    /**  ClassRef representing the class java.lang.Character */
+    @TrackableConstant
+    public static final ClassRef CR_Character = ClassRef.of("java.lang.Character");
+
+    /**  ClassRef representing the class java.lang.Boolean */
+    @TrackableConstant
+    public static final ClassRef CR_Boolean = ClassRef.of("java.lang.Boolean");
+
+    /**  ClassRef representing the class java.lang.Void */
+    @TrackableConstant
+    public static final ClassRef CR_Void = ClassRef.of("java.lang.Void");
+
+    /**  ClassRef representing the class java.lang.Throwable */
+    @TrackableConstant
+    public static final ClassRef CR_Throwable = ClassRef.of("java.lang.Throwable");
+
+    /**  ClassRef representing the class java.lang.Exception */
+    @TrackableConstant
+    public static final ClassRef CR_Exception = ClassRef.of("java.lang.Exception");
+
+    /**  ClassRef representing the class java.lang.Enum */
+    @TrackableConstant
+    public static final ClassRef CR_Enum = ClassRef.of("java.lang.Enum");
+
+    /**  ClassRef representing the class java.lang.invoke.VarHandle */
+    @TrackableConstant
+    public static final ClassRef CR_VarHandle = ClassRef.of("java.lang.invoke.VarHandle");
+
+    /**  ClassRef representing the class java.lang.invoke.MethodHandles */
+    @TrackableConstant
+    public static final ClassRef CR_MethodHandles = ClassRef.of("java.lang.invoke.MethodHandles");
+
+    /**  ClassRef representing the class java.lang.invoke.MethodHandles.Lookup */
+    @TrackableConstant
+    public static final ClassRef CR_Lookup = CR_MethodHandles.inner("Lookup");
+
+    /**  ClassRef representing the class java.lang.invoke.MethodHandle */
+    @TrackableConstant
+    public static final ClassRef CR_MethodHandle = ClassRef.of("java.lang.invoke.MethodHandle");
+
+    /**  ClassRef representing the class java.lang.invoke.MethodType */
+    @TrackableConstant
+    public static final ClassRef CR_MethodType = ClassRef.of("java.lang.invoke.MethodType");
+
+    /**  ClassRef representing the class java.lang.invoke.CallSite */
+    @TrackableConstant
+    public static final ClassRef CR_CallSite = ClassRef.of("java.lang.invoke.CallSite");
+
+    /**  ClassRef representing the interface java.util.Collection */
+    @TrackableConstant
+    public static final ClassRef CR_Collection = ClassRef.of("java.util.Collection");
+
+    /**  ClassRef representing the interface java.util.List */
+    @TrackableConstant
+    public static final ClassRef CR_List = ClassRef.of("java.util.List");
+
+    /**  ClassRef representing the interface java.util.Set */
+    @TrackableConstant
+    public static final ClassRef CR_Set = ClassRef.of("java.util.Set");
+
+    /**  ClassRef representing the interface java.util.Map */
+    @TrackableConstant
+    public static final ClassRef CR_Map = ClassRef.of("java.util.Map");
+
+    static final ClassRef CR_ConstantBootstraps = ClassRef.of("java.lang.invoke.ConstantBootstraps");
+
+    static final MethodHandleRef BSM_PRIMITIVE_CLASS
+            = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "primitiveClass", CR_Class);
+    static final MethodHandleRef BSM_ENUM_CONSTANT
+            = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "enumConstant", CR_Enum);
+    static final MethodHandleRef BSM_NULL_CONSTANT
+            = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "nullConstant", SymbolicRefs.CR_Object);
+
+    static final MethodHandleRef BSM_VARHANDLE_FIELD
+            = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "fieldVarHandle", CR_VarHandle, CR_Class, CR_Class);
+    static final MethodHandleRef BSM_VARHANDLE_STATIC_FIELD
+            = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "staticFieldVarHandle", CR_VarHandle, CR_Class, CR_Class);
+    static final MethodHandleRef BSM_VARHANDLE_ARRAY
+            = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "arrayVarHandle", CR_VarHandle, CR_Class);
+
+    /**  ClassRef representing the primitive type int */
+    @TrackableConstant
+    public static final ClassRef CR_int = ClassRef.ofDescriptor("I");
+
+    /**  ClassRef representing the primitive type long */
+    @TrackableConstant
+    public static final ClassRef CR_long = ClassRef.ofDescriptor("J");
+
+    /**  ClassRef representing the primitive type float */
+    @TrackableConstant
+    public static final ClassRef CR_float = ClassRef.ofDescriptor("F");
+
+    /**  ClassRef representing the primitive type double */
+    @TrackableConstant
+    public static final ClassRef CR_double = ClassRef.ofDescriptor("D");
+
+    /**  ClassRef representing the primitive type short */
+    @TrackableConstant
+    public static final ClassRef CR_short = ClassRef.ofDescriptor("S");
+
+    /**  ClassRef representing the primitive type byte */
+    @TrackableConstant
+    public static final ClassRef CR_byte = ClassRef.ofDescriptor("B");
+
+    /**  ClassRef representing the primitive type char */
+    @TrackableConstant
+    public static final ClassRef CR_char = ClassRef.ofDescriptor("C");
+
+    /**  ClassRef representing the primitive type boolean */
+    @TrackableConstant
+    public static final ClassRef CR_boolean = ClassRef.ofDescriptor("Z");
+
+    /**  ClassRef representing the void type */
+    @TrackableConstant
+    public static final ClassRef CR_void = ClassRef.ofDescriptor("V");
+
+    /** Symbolic reference representing null */
+    @TrackableConstant
+    public static final SymbolicRef<?> NULL = DynamicConstantRef.of(SymbolicRefs.BSM_NULL_CONSTANT, SymbolicRefs.CR_Object);
+}
--- a/src/java.base/share/classes/module-info.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/java.base/share/classes/module-info.java	Fri Dec 22 13:06:32 2017 -0500
@@ -83,6 +83,7 @@
     exports java.lang.module;
     exports java.lang.ref;
     exports java.lang.reflect;
+    exports java.lang.sym;
     exports java.math;
     exports java.net;
     exports java.net.spi;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Fri Dec 22 13:06:32 2017 -0500
@@ -171,7 +171,6 @@
     public final Type varHandleType;
     public final Type methodHandleType;
     public final Type methodHandlesLookupType;
-    public final Type constablesType;
     public final Type dynamicConstantRefType;
     public final Type intrinsicsType;
     public final Type methodTypeType;
@@ -499,8 +498,7 @@
         varHandleType = enterClass("java.lang.invoke.VarHandle");
         methodHandleType = enterClass("java.lang.invoke.MethodHandle");
         methodHandlesLookupType = enterClass("java.lang.invoke.MethodHandles$Lookup");
-        constablesType = enterClass("java.lang.invoke.Constables");
-        dynamicConstantRefType = enterClass("java.lang.invoke.DynamicConstantRef");
+        dynamicConstantRefType = enterClass("java.lang.sym.DynamicConstantRef");
         intrinsicsType = enterClass("java.lang.invoke.Intrinsics");
         methodTypeType = enterClass("java.lang.invoke.MethodType");
         trackableConstantType = enterClass("java.lang.annotation.TrackableConstant");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Fri Dec 22 13:06:32 2017 -0500
@@ -54,7 +54,6 @@
 //import com.sun.tools.javac.comp.Resolve.BasicLookupHelper;
 import com.sun.tools.javac.jvm.ClassFile;
 import com.sun.tools.javac.jvm.Pool;
-import com.sun.tools.javac.jvm.Pool.MethodHandle.MethodHandleCheckHelper;
 import com.sun.tools.javac.resources.CompilerProperties.Errors;
 import com.sun.tools.javac.resources.CompilerProperties.Warnings;
 import com.sun.tools.javac.tree.JCTree;
@@ -64,7 +63,6 @@
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 
-import static com.sun.tools.javac.code.Flags.INTERFACE;
 import static com.sun.tools.javac.code.Flags.STATIC;
 import static com.sun.tools.javac.code.TypeTag.ARRAY;
 import static com.sun.tools.javac.tree.JCTree.Tag.SELECT;
@@ -87,21 +85,21 @@
         log = Log.instance(context);
         constablesVisitor = ConstablesVisitor.instance(context);
         try {
-            methodHandleRefClass = Class.forName("java.lang.invoke.MethodHandleRef", false, null);
-            methodTypeRefClass = Class.forName("java.lang.invoke.MethodTypeRef", false, null);
-            classRefClass = Class.forName("java.lang.invoke.ClassRef", false, null);
-            constantRefClass = Class.forName("java.lang.invoke.ConstantRef", false, null);
-            constablesClass = Class.forName("java.lang.invoke.Constables", false, null);
-            bootstrapSpecifierClass = Class.forName("java.lang.invoke.BootstrapSpecifier", false, null);
-            dynamicConstantClass = Class.forName("java.lang.invoke.DynamicConstantRef", false, null);
+            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);
+            namedClassRefClass = Class.forName("java.lang.sym.NamedClassRef", false, null);
+            constantRefClass = Class.forName("java.lang.sym.SymbolicRef", false, null);
+            bootstrapSpecifierClass = Class.forName("java.lang.sym.BootstrapSpecifier", false, null);
+            dynamicConstantClass = Class.forName("java.lang.sym.DynamicConstantRef", false, null);
         } catch (ClassNotFoundException ex) {
             methodHandleRefClass = null;
             methodTypeRefClass = null;
             constantRefClass = null;
             classRefClass = null;
+            namedClassRefClass = null;
             bootstrapSpecifierClass = null;
             dynamicConstantClass = null;
-            constablesClass = null;
         }
     }
 
@@ -299,16 +297,8 @@
         } else if (methodTypeRefClass.isInstance(constant)) {
             String descriptor = (String)invokeReflectiveMethod(methodTypeRefClass, constant, "descriptorString");
             return types.erasure(descriptorToType(descriptor, currentModule, true));
-        } else if (classRefClass.isInstance(constant)) {
+        } else if (namedClassRefClass.isInstance(constant)) {
             String descriptor = (String)invokeReflectiveMethod(classRefClass, constant, "descriptorString");
-            if ((boolean)invokeReflectiveMethod(classRefClass, constant, "isPrimitive")) {
-                if (bsmArg) {
-                    Object condy = invokeReflectiveMethod(constablesClass, null, "reduce", new Class<?>[]{constantRefClass}, new Object[]{constant});
-                    return convertConstant(tree, attrEnv, condy, currentModule);
-                } else {
-                    return rs.resolveInternalField(tree, attrEnv, boxedClass(descriptor).type, names.TYPE);
-                }
-            }
             Type type = descriptorToType(descriptor, currentModule, false);
             Symbol symToLoad;
             if (!type.hasTag(ARRAY)) {
@@ -396,16 +386,11 @@
         return result;
     }
 
-    public boolean isPrimitiveClassRef(Object constant) {
-        return classRefClass.isInstance(constant) &&
-                (boolean)invokeReflectiveMethod(classRefClass, constant, "isPrimitive");
-    }
-
     public Class<?> methodHandleRefClass;
     public Class<?> methodTypeRefClass;
     public Class<?> classRefClass;
+    public Class<?> namedClassRefClass;
     public Class<?> constantRefClass;
-    public Class<?> constablesClass;
     public Class<?> bootstrapSpecifierClass;
     public Class<?> dynamicConstantClass;
 
@@ -448,14 +433,19 @@
             Object[] arguments) {
         Method theMethod;
         try {
-            theMethod = hostClass.getDeclaredMethod(methodName, argumentTypes);
+            theMethod = hostClass.getMethod(methodName, argumentTypes);
             return theMethod.invoke(instance, arguments);
         } catch (NoSuchMethodException |
                 SecurityException |
                 IllegalAccessException |
                 IllegalArgumentException |
                 InvocationTargetException ex) {
-            log.error(Errors.ReflectiveError(methodName, hostClass.getCanonicalName(), ex.getCause().getLocalizedMessage()));
+            Throwable e = (ex.getCause() == null) ? ex : ex.getCause();
+            String msg = e.getLocalizedMessage();
+            if (msg == null)
+                msg = e.toString();
+            log.error(Errors.ReflectiveError(methodName, hostClass.getCanonicalName(), msg));
+            e.printStackTrace(System.err);
         }
         return null;
     }
--- a/test/jdk/java/lang/invoke/ConstablesTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/jdk/java/lang/invoke/ConstablesTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -22,15 +22,17 @@
  * or visit www.oracle.com if you need additional information or have any
  * questions.
  */
-import java.lang.invoke.ConstantRef;
-import java.lang.invoke.DynamicConstantRef;
+import java.lang.sym.EnumRef;
+import java.lang.sym.SymbolicRef;
+import java.lang.sym.DynamicConstantRef;
 import java.lang.invoke.Intrinsics;
-import java.lang.invoke.MethodHandleRef;
+import java.lang.sym.MethodHandleRef;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-import java.lang.invoke.ClassRef;
-import java.lang.invoke.MethodTypeRef;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodTypeRef;
 import java.lang.invoke.VarHandle;
+import java.lang.sym.SymbolicRefs;
 import java.util.Arrays;
 import java.util.List;
 import java.util.stream.IntStream;
@@ -38,11 +40,10 @@
 
 import org.testng.annotations.Test;
 
-import static java.lang.invoke.ClassRef.*;
-import static java.lang.invoke.MethodHandleRef.Kind.GETTER;
-import static java.lang.invoke.MethodHandleRef.Kind.SETTER;
-import static java.lang.invoke.MethodHandleRef.Kind.STATIC_GETTER;
-import static java.lang.invoke.MethodHandleRef.Kind.STATIC_SETTER;
+import static java.lang.sym.MethodHandleRef.Kind.GETTER;
+import static java.lang.sym.MethodHandleRef.Kind.SETTER;
+import static java.lang.sym.MethodHandleRef.Kind.STATIC_GETTER;
+import static java.lang.sym.MethodHandleRef.Kind.STATIC_SETTER;
 import static java.util.stream.Collectors.joining;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertFalse;
@@ -64,15 +65,15 @@
     public static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
 
     enum Primitives {
-        INT("I", "int", int.class, int[].class, CR_int),
-        LONG("J", "long", long.class, long[].class, CR_long),
-        SHORT("S", "short", short.class, short[].class, CR_short),
-        BYTE("B", "byte", byte.class, byte[].class, CR_byte),
-        CHAR("C", "char", char.class, char[].class, CR_char),
-        FLOAT("F", "float", float.class, float[].class, CR_float),
-        DOUBLE("D", "double", double.class, double[].class, CR_double),
-        BOOLEAN("Z", "boolean", boolean.class, boolean[].class, CR_boolean),
-        VOID("V", "void", void.class, null, CR_void);
+        INT("I", "int", int.class, int[].class, SymbolicRefs.CR_int),
+        LONG("J", "long", long.class, long[].class, SymbolicRefs.CR_long),
+        SHORT("S", "short", short.class, short[].class, SymbolicRefs.CR_short),
+        BYTE("B", "byte", byte.class, byte[].class, SymbolicRefs.CR_byte),
+        CHAR("C", "char", char.class, char[].class, SymbolicRefs.CR_char),
+        FLOAT("F", "float", float.class, float[].class, SymbolicRefs.CR_float),
+        DOUBLE("D", "double", double.class, double[].class, SymbolicRefs.CR_double),
+        BOOLEAN("Z", "boolean", boolean.class, boolean[].class, SymbolicRefs.CR_boolean),
+        VOID("V", "void", void.class, null, SymbolicRefs.CR_void);
 
         public final String descriptor;
         public final String name;
@@ -102,17 +103,17 @@
         for (Primitives p : Primitives.values()) {
             ClassRef c1 = ClassRef.ofDescriptor(p.descriptor);
             ClassRef c2 = p.classRef;
-            assertTrue(c1.isPrimitive());
-            assertTrue(c2.isPrimitive());
-            assertEquals(p.descriptor, c1.descriptorString());
-            assertEquals(p.descriptor, c2.descriptorString());
-            assertEquals(p.name, c1.canonicalName());
-            assertEquals(c1, c2);
-            assertEquals(c1.resolve(LOOKUP), p.clazz);
-            assertEquals(c2.resolve(LOOKUP), p.clazz);
-            if (p != Primitives.VOID) {
-                assertEquals(c1.array().resolve(LOOKUP), p.arrayClass);
-                assertEquals(c2.array().resolve(LOOKUP), p.arrayClass);
+            ClassRef c3 = p.clazz.toSymbolicRef().get();
+            List<ClassRef> refs = List.of(c1, c2, c3);
+            for (ClassRef c : refs) {
+                assertTrue(c.isPrimitive());
+                assertEquals(p.descriptor, c.descriptorString());
+                assertEquals(p.name, c.canonicalName());
+                assertEquals(c.resolveRef(LOOKUP), p.clazz);
+                for (ClassRef cc : refs)
+                    assertEquals(c, cc);
+                if (p != Primitives.VOID)
+                    assertEquals(c.array().resolveRef(LOOKUP), p.arrayClass);
             }
 
             for (Primitives other : Primitives.values()) {
@@ -126,22 +127,25 @@
     }
 
     public void testSimpleClassRef() throws ReflectiveOperationException {
-        String stringDesc = "Ljava/lang/String;";
-        ClassRef stringRef1 = ClassRef.ofDescriptor(stringDesc);
-        ClassRef stringRef2 = ClassRef.of("java.lang", "String");
-        ClassRef stringRef3 = ClassRef.of("java.lang.String");
+        String desc = "Ljava/lang/String;";
+        Class<?> clazz = String.class;
+        ClassRef ref1 = ClassRef.ofDescriptor(desc);
+        ClassRef ref2 = ClassRef.of("java.lang", "String");
+        ClassRef ref3 = ClassRef.of("java.lang.String");
+        ClassRef ref4 = clazz.toSymbolicRef(LOOKUP).get();
 
-        List<ClassRef> refs = Arrays.asList(stringRef1, stringRef2, stringRef3);
+        List<ClassRef> refs = Arrays.asList(ref1, ref2, ref3, ref4);
 
         refs.forEach(s -> assertFalse(s.isPrimitive()));
-        refs.forEach(s -> assertEquals(stringDesc, s.descriptorString()));
+        refs.forEach(s -> assertEquals(desc, s.descriptorString()));
         refs.forEach(s -> assertEquals("java.lang.String", s.canonicalName()));
         for (ClassRef r : refs)
-            assertEquals(r.resolve(LOOKUP), String.class);
+            assertEquals(r.resolveRef(LOOKUP), String.class);
 
-        assertEquals(stringRef1, stringRef2);
-        assertEquals(stringRef2, stringRef3);
-        assertEquals(stringRef3, stringRef1);
+        assertEquals(ref1, ref2);
+        assertEquals(ref2, ref3);
+        assertEquals(ref3, ref4);
+        assertEquals(ref4, ref1);
 
         ClassRef thisClassRef = ClassRef.ofDescriptor("LConstablesTest;");
         assertEquals(thisClassRef, ClassRef.of("", "ConstablesTest"));
@@ -180,9 +184,9 @@
 
             assertEquals(a1, ClassRef.ofDescriptor("[" + d));
             assertEquals(a2, ClassRef.ofDescriptor("[[" + d));
-            assertEquals(classToDescriptor(a0.resolve(LOOKUP)), a0.descriptorString());
-            assertEquals(classToDescriptor(a1.resolve(LOOKUP)), a1.descriptorString());
-            assertEquals(classToDescriptor(a2.resolve(LOOKUP)), a2.descriptorString());
+            assertEquals(classToDescriptor(a0.resolveRef(LOOKUP)), a0.descriptorString());
+            assertEquals(classToDescriptor(a1.resolveRef(LOOKUP)), a1.descriptorString());
+            assertEquals(classToDescriptor(a2.resolveRef(LOOKUP)), a2.descriptorString());
         }
     }
 
@@ -209,7 +213,7 @@
         ClassRef[] params = Stream.of(paramDescs).map(ClassRef::ofDescriptor).toArray(ClassRef[]::new);
 
         MethodTypeRef mtRef = MethodTypeRef.of(ret, params);
-        MethodType mt = mtRef.resolve(LOOKUP);
+        MethodType mt = mtRef.resolveRef(LOOKUP);
 
         assertEquals(mtRef, MethodTypeRef.ofDescriptor(descriptor));
         assertEquals(mt.toMethodDescriptorString(), descriptor);
@@ -225,9 +229,11 @@
         // changeReturnType
         for (String r : returnDescs) {
             ClassRef rc = ClassRef.ofDescriptor(r);
-            MethodTypeRef changed = mtRef.changeReturnType(rc);
-            assertEquals(changed, MethodTypeRef.of(rc, params));
-            assertEquals(mt.changeReturnType(rc.resolve(LOOKUP)).toMethodDescriptorString(), changed.descriptorString());
+            MethodTypeRef newRef = mtRef.changeReturnType(rc);
+            MethodType newMT = mt.changeReturnType(rc.resolveRef(LOOKUP));
+            assertEquals(newRef, MethodTypeRef.of(rc, params));
+            assertEquals(newMT.toMethodDescriptorString(), newRef.descriptorString());
+            assertEquals(newMT.toSymbolicRef(LOOKUP).get(), newRef);
         }
 
         // changeParamType
@@ -236,9 +242,11 @@
                 ClassRef pc = ClassRef.ofDescriptor(p);
                 ClassRef[] ps = params.clone();
                 ps[i] = pc;
-                MethodTypeRef changed = mtRef.changeParameterType(i, pc);
-                assertEquals(changed, MethodTypeRef.of(ret, ps));
-                assertEquals(mt.changeParameterType(i, pc.resolve(LOOKUP)).toMethodDescriptorString(), changed.descriptorString());
+                MethodTypeRef newRef = mtRef.changeParameterType(i, pc);
+                assertEquals(newRef, MethodTypeRef.of(ret, ps));
+                MethodType newMT = mt.changeParameterType(i, pc.resolveRef(LOOKUP));
+                assertEquals(newMT.toMethodDescriptorString(), newRef.descriptorString());
+                assertEquals(newMT.toSymbolicRef(LOOKUP).get(), newRef);
             }
         }
 
@@ -249,9 +257,11 @@
                                      .filter(j -> j != k)
                                      .mapToObj(j -> params[j])
                                      .toArray(ClassRef[]::new);
-            MethodTypeRef changed = mtRef.dropParameterTypes(i, i + 1);
-            assertEquals(changed, MethodTypeRef.of(ret, ps));
-            assertEquals(mt.dropParameterTypes(i, i+1).toMethodDescriptorString(), changed.descriptorString());
+            MethodTypeRef newRef = mtRef.dropParameterTypes(i, i + 1);
+            assertEquals(newRef, MethodTypeRef.of(ret, ps));
+            MethodType newMT = mt.dropParameterTypes(i, i + 1);
+            assertEquals(newMT.toMethodDescriptorString(), newRef.descriptorString());
+            assertEquals(newMT.toSymbolicRef(LOOKUP).get(), newRef);
         }
 
         // addParam
@@ -262,9 +272,11 @@
                 ClassRef[] ps = IntStream.range(0, paramDescs.length + 1)
                                          .mapToObj(j -> (j < k) ? params[j] : (j == k) ? pc : params[j-1])
                                          .toArray(ClassRef[]::new);
-                MethodTypeRef changed = mtRef.insertParameterTypes(i, pc);
-                assertEquals(changed, MethodTypeRef.of(ret, ps));
-                assertEquals(mt.insertParameterTypes(i, pc.resolve(LOOKUP)).toMethodDescriptorString(), changed.descriptorString());
+                MethodTypeRef newRef = mtRef.insertParameterTypes(i, pc);
+                MethodType newMT = mt.insertParameterTypes(i, pc.resolveRef(LOOKUP));
+                assertEquals(newRef, MethodTypeRef.of(ret, ps));
+                assertEquals(newMT.toMethodDescriptorString(), newRef.descriptorString());
+                assertEquals(newMT.toSymbolicRef(LOOKUP).get(), newRef);
             }
         }
     }
@@ -299,67 +311,67 @@
         MethodHandleRef privateStaticMethodRef = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, testClass, "psm", MethodTypeRef.ofDescriptor("(I)I"));
         MethodHandleRef privateStaticIMethodRef = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, testInterface, "psm", MethodTypeRef.ofDescriptor("(I)I"));
 
-        TestClass instance = (TestClass) ctorRef.resolve(LOOKUP).invokeExact();
-        instance = (TestClass) ctorRef.resolve(TestClass.LOOKUP).invokeExact();
+        TestClass instance = (TestClass) ctorRef.resolveRef(LOOKUP).invokeExact();
+        instance = (TestClass) ctorRef.resolveRef(TestClass.LOOKUP).invokeExact();
         TestInterface instanceI = instance;
         
-        assertEquals(5, (int) staticMethodRef.resolve(LOOKUP).invokeExact(5));
-        assertEquals(5, (int) staticMethodRef.resolve(TestClass.LOOKUP).invokeExact(5));
-        assertEquals(0, (int) staticIMethodRef.resolve(LOOKUP).invokeExact(5));
-        assertEquals(0, (int) staticIMethodRef.resolve(TestClass.LOOKUP).invokeExact(5));
+        assertEquals(5, (int) staticMethodRef.resolveRef(LOOKUP).invokeExact(5));
+        assertEquals(5, (int) staticMethodRef.resolveRef(TestClass.LOOKUP).invokeExact(5));
+        assertEquals(0, (int) staticIMethodRef.resolveRef(LOOKUP).invokeExact(5));
+        assertEquals(0, (int) staticIMethodRef.resolveRef(TestClass.LOOKUP).invokeExact(5));
         
-        assertEquals(5, (int) instanceMethodRef.resolve(LOOKUP).invokeExact(instance, 5));
-        assertEquals(5, (int) instanceMethodRef.resolve(TestClass.LOOKUP).invokeExact(instance, 5));
-        assertEquals(5, (int) instanceIMethodRef.resolve(LOOKUP).invokeExact(instanceI, 5));
-        assertEquals(5, (int) instanceIMethodRef.resolve(TestClass.LOOKUP).invokeExact(instanceI, 5));
+        assertEquals(5, (int) instanceMethodRef.resolveRef(LOOKUP).invokeExact(instance, 5));
+        assertEquals(5, (int) instanceMethodRef.resolveRef(TestClass.LOOKUP).invokeExact(instance, 5));
+        assertEquals(5, (int) instanceIMethodRef.resolveRef(LOOKUP).invokeExact(instanceI, 5));
+        assertEquals(5, (int) instanceIMethodRef.resolveRef(TestClass.LOOKUP).invokeExact(instanceI, 5));
 
-        try { superMethodRef.resolve(LOOKUP); fail(); }
+        try { superMethodRef.resolveRef(LOOKUP); fail(); }
         catch (IllegalAccessException e) { /* expected */ }
-        assertEquals(-1, (int) superMethodRef.resolve(TestClass.LOOKUP).invokeExact(instance, 5));
-        try { superIMethodRef.resolve(LOOKUP); fail(); }
+        assertEquals(-1, (int) superMethodRef.resolveRef(TestClass.LOOKUP).invokeExact(instance, 5));
+        try { superIMethodRef.resolveRef(LOOKUP); fail(); }
         catch (IllegalAccessException e) { /* expected */ }
-        assertEquals(0, (int) superIMethodRef.resolve(TestClass.LOOKUP).invokeExact(instance, 5));
+        assertEquals(0, (int) superIMethodRef.resolveRef(TestClass.LOOKUP).invokeExact(instance, 5));
         
-        try { privateMethodRef.resolve(LOOKUP); fail(); }
+        try { privateMethodRef.resolveRef(LOOKUP); fail(); }
         catch (IllegalAccessException e) { /* expected */ }
-        assertEquals(5, (int) privateMethodRef.resolve(TestClass.LOOKUP).invokeExact(instance, 5));
-        try { privateIMethodRef.resolve(LOOKUP); fail(); }
+        assertEquals(5, (int) privateMethodRef.resolveRef(TestClass.LOOKUP).invokeExact(instance, 5));
+        try { privateIMethodRef.resolveRef(LOOKUP); fail(); }
         catch (IllegalAccessException e) { /* expected */ }
-        try { privateIMethodRef.resolve(TestClass.LOOKUP); fail(); }
+        try { privateIMethodRef.resolveRef(TestClass.LOOKUP); fail(); }
         catch (IllegalAccessException e) { /* expected */ }
-        assertEquals(0, (int) privateIMethodRef.resolve(TestInterface.LOOKUP).invokeExact(instanceI, 5));
+        assertEquals(0, (int) privateIMethodRef.resolveRef(TestInterface.LOOKUP).invokeExact(instanceI, 5));
         
-        try { privateStaticMethodRef.resolve(LOOKUP); fail(); }
+        try { privateStaticMethodRef.resolveRef(LOOKUP); fail(); }
         catch (IllegalAccessException e) { /* expected */ }
-        assertEquals(5, (int) privateStaticMethodRef.resolve(TestClass.LOOKUP).invokeExact(5));
-        try { privateStaticIMethodRef.resolve(LOOKUP); fail(); }
+        assertEquals(5, (int) privateStaticMethodRef.resolveRef(TestClass.LOOKUP).invokeExact(5));
+        try { privateStaticIMethodRef.resolveRef(LOOKUP); fail(); }
         catch (IllegalAccessException e) { /* expected */ }
-        try { privateStaticIMethodRef.resolve(TestClass.LOOKUP); fail(); }
+        try { privateStaticIMethodRef.resolveRef(TestClass.LOOKUP); fail(); }
         catch (IllegalAccessException e) { /* expected */ }
-        assertEquals(0, (int) privateStaticIMethodRef.resolve(TestInterface.LOOKUP).invokeExact(5));
+        assertEquals(0, (int) privateStaticIMethodRef.resolveRef(TestInterface.LOOKUP).invokeExact(5));
 
-        MethodHandleRef staticSetterRef = MethodHandleRef.ofField(STATIC_SETTER, testClass, "sf", ClassRef.CR_int);
-        MethodHandleRef staticGetterRef = MethodHandleRef.ofField(STATIC_GETTER, testClass, "sf", ClassRef.CR_int);
-        MethodHandleRef staticGetterIRef = MethodHandleRef.ofField(STATIC_GETTER, testInterface, "sf", ClassRef.CR_int);
-        MethodHandleRef setterRef = MethodHandleRef.ofField(SETTER, testClass, "f", ClassRef.CR_int);
-        MethodHandleRef getterRef = MethodHandleRef.ofField(GETTER, testClass, "f", ClassRef.CR_int);
+        MethodHandleRef staticSetterRef = MethodHandleRef.ofField(STATIC_SETTER, testClass, "sf", SymbolicRefs.CR_int);
+        MethodHandleRef staticGetterRef = MethodHandleRef.ofField(STATIC_GETTER, testClass, "sf", SymbolicRefs.CR_int);
+        MethodHandleRef staticGetterIRef = MethodHandleRef.ofField(STATIC_GETTER, testInterface, "sf", SymbolicRefs.CR_int);
+        MethodHandleRef setterRef = MethodHandleRef.ofField(SETTER, testClass, "f", SymbolicRefs.CR_int);
+        MethodHandleRef getterRef = MethodHandleRef.ofField(GETTER, testClass, "f", SymbolicRefs.CR_int);
 
-        staticSetterRef.resolve(LOOKUP).invokeExact(6); assertEquals(TestClass.sf, 6);
-        assertEquals(6, (int) staticGetterRef.resolve(LOOKUP).invokeExact());
-        assertEquals(6, (int) staticGetterRef.resolve(TestClass.LOOKUP).invokeExact());
-        staticSetterRef.resolve(TestClass.LOOKUP).invokeExact(7); assertEquals(TestClass.sf, 7);
-        assertEquals(7, (int) staticGetterRef.resolve(LOOKUP).invokeExact());
-        assertEquals(7, (int) staticGetterRef.resolve(TestClass.LOOKUP).invokeExact());
+        staticSetterRef.resolveRef(LOOKUP).invokeExact(6); assertEquals(TestClass.sf, 6);
+        assertEquals(6, (int) staticGetterRef.resolveRef(LOOKUP).invokeExact());
+        assertEquals(6, (int) staticGetterRef.resolveRef(TestClass.LOOKUP).invokeExact());
+        staticSetterRef.resolveRef(TestClass.LOOKUP).invokeExact(7); assertEquals(TestClass.sf, 7);
+        assertEquals(7, (int) staticGetterRef.resolveRef(LOOKUP).invokeExact());
+        assertEquals(7, (int) staticGetterRef.resolveRef(TestClass.LOOKUP).invokeExact());
 
-        assertEquals(3, (int) staticGetterIRef.resolve(LOOKUP).invokeExact());
-        assertEquals(3, (int) staticGetterIRef.resolve(TestClass.LOOKUP).invokeExact());
+        assertEquals(3, (int) staticGetterIRef.resolveRef(LOOKUP).invokeExact());
+        assertEquals(3, (int) staticGetterIRef.resolveRef(TestClass.LOOKUP).invokeExact());
 
-        setterRef.resolve(LOOKUP).invokeExact(instance, 6); assertEquals(instance.f, 6);
-        assertEquals(6, (int) getterRef.resolve(LOOKUP).invokeExact(instance));
-        assertEquals(6, (int) getterRef.resolve(TestClass.LOOKUP).invokeExact(instance));
-        setterRef.resolve(TestClass.LOOKUP).invokeExact(instance, 7); assertEquals(instance.f, 7);
-        assertEquals(7, (int) getterRef.resolve(LOOKUP).invokeExact(instance));
-        assertEquals(7, (int) getterRef.resolve(TestClass.LOOKUP).invokeExact(instance));
+        setterRef.resolveRef(LOOKUP).invokeExact(instance, 6); assertEquals(instance.f, 6);
+        assertEquals(6, (int) getterRef.resolveRef(LOOKUP).invokeExact(instance));
+        assertEquals(6, (int) getterRef.resolveRef(TestClass.LOOKUP).invokeExact(instance));
+        setterRef.resolveRef(TestClass.LOOKUP).invokeExact(instance, 7); assertEquals(instance.f, 7);
+        assertEquals(7, (int) getterRef.resolveRef(LOOKUP).invokeExact(instance));
+        assertEquals(7, (int) getterRef.resolveRef(TestClass.LOOKUP).invokeExact(instance));
     }
 
     public void testVarHandles() throws ReflectiveOperationException {
@@ -368,25 +380,25 @@
         int[] ints = new int[3];
 
         // static varHandle
-        DynamicConstantRef<VarHandle> vhc = (DynamicConstantRef<VarHandle>) ConstantRef.staticFieldVarHandle(testClass, "sf", ClassRef.CR_int);
+        DynamicConstantRef<VarHandle> vhc = (DynamicConstantRef<VarHandle>) SymbolicRef.staticFieldVarHandle(testClass, "sf", SymbolicRefs.CR_int);
         MethodTypeRef methodTypeRef = vhc.bootstrapMethod().type();
         System.out.println(vhc.name() + " " + methodTypeRef.returnType() + " " + methodTypeRef.parameterList());
-        VarHandle varHandle = vhc.resolve(LOOKUP);
+        VarHandle varHandle = vhc.resolveRef(LOOKUP);
         assertEquals(varHandle.varType(), int.class);
         varHandle.set(8);
         assertEquals(8, (int) varHandle.get());
         assertEquals(TestClass.sf, 8);
 
         // static varHandle
-        vhc = (DynamicConstantRef<VarHandle>) ConstantRef.fieldVarHandle(testClass, "f", ClassRef.CR_int);
-        varHandle = vhc.resolve(LOOKUP);
+        vhc = (DynamicConstantRef<VarHandle>) SymbolicRef.fieldVarHandle(testClass, "f", SymbolicRefs.CR_int);
+        varHandle = vhc.resolveRef(LOOKUP);
         assertEquals(varHandle.varType(), int.class);
         varHandle.set(instance, 9);
         assertEquals(9, (int) varHandle.get(instance));
         assertEquals(instance.f, 9);
 
-        vhc = (DynamicConstantRef<VarHandle>) ConstantRef.arrayVarHandle(ClassRef.CR_int.array());
-        varHandle = vhc.resolve(LOOKUP);
+        vhc = (DynamicConstantRef<VarHandle>) SymbolicRef.arrayVarHandle(SymbolicRefs.CR_int.array());
+        varHandle = vhc.resolveRef(LOOKUP);
         varHandle.set(ints, 0, 1);
         varHandle.set(ints, 1, 2);
         varHandle.set(ints, 2, 3);
@@ -401,9 +413,9 @@
     }
 
     public void testMiscConstablesFactories() throws ReflectiveOperationException {
-        DynamicConstantRef<?> ofNull = (DynamicConstantRef<?>) ConstantRef.ofNull();
+        DynamicConstantRef<?> ofNull = (DynamicConstantRef<?>) SymbolicRefs.NULL;
 
-        assertNull(ofNull.resolve(LOOKUP));
+        assertNull(ofNull.resolveRef(LOOKUP));
     }
 
     public void testLdcClassRef() {
@@ -418,22 +430,22 @@
 //        assertEquals(String[].class, Intrinsics.ldc(ClassRef.of(String[].class)));
 
         assertEquals(int.class, Intrinsics.ldc(ClassRef.ofDescriptor("I")));
-        assertEquals(int.class, Intrinsics.ldc(ClassRef.CR_int));
+        assertEquals(int.class, Intrinsics.ldc(SymbolicRefs.CR_int));
 //        assertEquals(int.class, Intrinsics.ldc(ClassRef.of(int.class)));
 
         assertEquals(int[].class, Intrinsics.ldc(ClassRef.ofDescriptor("[I")));
-        assertEquals(int[].class, Intrinsics.ldc(ClassRef.CR_int.array()));
+        assertEquals(int[].class, Intrinsics.ldc(SymbolicRefs.CR_int.array()));
 //        assertEquals(int[].class, Intrinsics.ldc(ClassRef.of(int.class).arrayOf()));
     }
 
     public void testLdcMethodType() {
         assertEquals(MethodType.methodType(void.class), Intrinsics.ldc(MethodTypeRef.ofDescriptor("()V")));
-        assertEquals(MethodType.methodType(void.class), Intrinsics.ldc(MethodTypeRef.of(ClassRef.CR_void)));
+        assertEquals(MethodType.methodType(void.class), Intrinsics.ldc(MethodTypeRef.of(SymbolicRefs.CR_void)));
 
         assertEquals(MethodType.methodType(int.class, int.class),
                      Intrinsics.ldc(MethodTypeRef.ofDescriptor("(I)I")));
         assertEquals(MethodType.methodType(int.class, int.class),
-                     Intrinsics.ldc(MethodTypeRef.of(ClassRef.CR_int, ClassRef.CR_int)));
+                     Intrinsics.ldc(MethodTypeRef.of(SymbolicRefs.CR_int, SymbolicRefs.CR_int)));
 
         assertEquals(MethodType.methodType(String.class, String.class),
                      Intrinsics.ldc(MethodTypeRef.ofDescriptor("(Ljava/lang/String;)Ljava/lang/String;")));
@@ -444,6 +456,31 @@
                      Intrinsics.ldc(MethodTypeRef.ofDescriptor("([I)[Ljava/lang/String;")));
     }
 
+    public void testLifting() {
+        ClassRef CR_ConstantBootstraps = ClassRef.of("java.lang.invoke.ConstantBootstraps");
+        MethodHandleRef BSM_NULL_CONSTANT
+                = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "nullConstant", SymbolicRefs.CR_Object);
+        MethodHandleRef BSM_PRIMITIVE_CLASS
+                = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "primitiveClass", SymbolicRefs.CR_Class);
+        MethodHandleRef BSM_ENUM_CONSTANT
+                = MethodHandleRef.ofCondyBootstrap(CR_ConstantBootstraps, "enumConstant", SymbolicRefs.CR_Enum);
+
+        assertNotEquals(SymbolicRefs.NULL, DynamicConstantRef.of(BSM_NULL_CONSTANT, "_", SymbolicRefs.CR_Object, new SymbolicRef[0]));
+        assertEquals(SymbolicRefs.NULL, DynamicConstantRef.ofCanonical(BSM_NULL_CONSTANT, "_", SymbolicRefs.CR_Object, new SymbolicRef[0]));
+        assertEquals(SymbolicRefs.NULL, DynamicConstantRef.ofCanonical(BSM_NULL_CONSTANT, "_", SymbolicRefs.CR_String, new SymbolicRef[0]));
+        assertEquals(SymbolicRefs.NULL, DynamicConstantRef.ofCanonical(BSM_NULL_CONSTANT, "wahoo", SymbolicRefs.CR_Object, new SymbolicRef[0]));
+
+        assertNotEquals(SymbolicRefs.CR_int, DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, "I", SymbolicRefs.CR_Class, new SymbolicRef[0]));
+        assertEquals(SymbolicRefs.CR_int, DynamicConstantRef.<Class<?>>ofCanonical(BSM_PRIMITIVE_CLASS, "I", SymbolicRefs.CR_Class, new SymbolicRef[0]));
+
+        ClassRef enumClass = ClassRef.of("ConstablesTest").inner("MyEnum");
+        assertNotEquals(EnumRef.of(enumClass, "A"),
+                        DynamicConstantRef.of(BSM_ENUM_CONSTANT, "A", enumClass, new SymbolicRef[0]));
+        assertEquals(EnumRef.of(enumClass, "A"),
+                     DynamicConstantRef.ofCanonical(BSM_ENUM_CONSTANT, "A", enumClass, new SymbolicRef[0]));
+    }
+
+    private enum MyEnum { A, B, C }
 
     public void testLdcMethodHandle() throws Throwable {
         ldcMethodHandleTestsFromOuter();
@@ -492,11 +529,11 @@
         try { Intrinsics.ldc(privateStaticIMethodRef); fail(); }
         catch (IllegalAccessError e) { /* expected */ }
 
-        MethodHandleRef staticSetterRef = MethodHandleRef.ofField(STATIC_SETTER, testClass, "sf", ClassRef.CR_int);
-        MethodHandleRef staticGetterRef = MethodHandleRef.ofField(STATIC_GETTER, testClass, "sf", ClassRef.CR_int);
-        MethodHandleRef staticGetterIRef = MethodHandleRef.ofField(STATIC_GETTER, testInterface, "sf", ClassRef.CR_int);
-        MethodHandleRef setterRef = MethodHandleRef.ofField(SETTER, testClass, "f", ClassRef.CR_int);
-        MethodHandleRef getterRef = MethodHandleRef.ofField(GETTER, testClass, "f", ClassRef.CR_int);
+        MethodHandleRef staticSetterRef = MethodHandleRef.ofField(STATIC_SETTER, testClass, "sf", SymbolicRefs.CR_int);
+        MethodHandleRef staticGetterRef = MethodHandleRef.ofField(STATIC_GETTER, testClass, "sf", SymbolicRefs.CR_int);
+        MethodHandleRef staticGetterIRef = MethodHandleRef.ofField(STATIC_GETTER, testInterface, "sf", SymbolicRefs.CR_int);
+        MethodHandleRef setterRef = MethodHandleRef.ofField(SETTER, testClass, "f", SymbolicRefs.CR_int);
+        MethodHandleRef getterRef = MethodHandleRef.ofField(GETTER, testClass, "f", SymbolicRefs.CR_int);
 
         Intrinsics.ldc(staticSetterRef).invokeExact(8); assertEquals(TestClass.sf, 8);
         assertEquals(8, (int) Intrinsics.ldc(staticGetterRef).invokeExact());
@@ -586,11 +623,11 @@
             try { Intrinsics.ldc(privateStaticIMethodRef); fail(); }
             catch (IllegalAccessError e) { /* expected */ }
 
-            MethodHandleRef staticSetterRef = MethodHandleRef.ofField(STATIC_SETTER, testClass, "sf", ClassRef.CR_int);
-            MethodHandleRef staticGetterRef = MethodHandleRef.ofField(STATIC_GETTER, testClass, "sf", ClassRef.CR_int);
-            MethodHandleRef staticGetterIRef = MethodHandleRef.ofField(STATIC_GETTER, testInterface, "sf", ClassRef.CR_int);
-            MethodHandleRef setterRef = MethodHandleRef.ofField(SETTER, testClass, "f", ClassRef.CR_int);
-            MethodHandleRef getterRef = MethodHandleRef.ofField(GETTER, testClass, "f", ClassRef.CR_int);
+            MethodHandleRef staticSetterRef = MethodHandleRef.ofField(STATIC_SETTER, testClass, "sf", SymbolicRefs.CR_int);
+            MethodHandleRef staticGetterRef = MethodHandleRef.ofField(STATIC_GETTER, testClass, "sf", SymbolicRefs.CR_int);
+            MethodHandleRef staticGetterIRef = MethodHandleRef.ofField(STATIC_GETTER, testInterface, "sf", SymbolicRefs.CR_int);
+            MethodHandleRef setterRef = MethodHandleRef.ofField(SETTER, testClass, "f", SymbolicRefs.CR_int);
+            MethodHandleRef getterRef = MethodHandleRef.ofField(GETTER, testClass, "f", SymbolicRefs.CR_int);
 
             Intrinsics.ldc(staticSetterRef).invokeExact(10); assertEquals(TestClass.sf, 10);
             assertEquals(10, (int) Intrinsics.ldc(staticGetterRef).invokeExact());
@@ -600,6 +637,6 @@
             Intrinsics.ldc(setterRef).invokeExact(instance, 11); assertEquals(instance.f, 11);
             assertEquals(11, (int) Intrinsics.ldc(getterRef).invokeExact(instance));
         }
-        
+
     }
 }
--- a/test/jdk/java/lang/invoke/ConstantRefBootstrapsTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/jdk/java/lang/invoke/ConstantRefBootstrapsTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -23,12 +23,13 @@
  * questions.
  */
 
-import java.lang.invoke.BootstrapSpecifier;
-import java.lang.invoke.ClassRef;
-import java.lang.invoke.DynamicConstantRef;
+import java.lang.sym.BootstrapSpecifier;
+import java.lang.sym.ClassRef;
+import java.lang.sym.DynamicConstantRef;
 import java.lang.invoke.Intrinsics;
-import java.lang.invoke.MethodHandleRef;
+import java.lang.sym.MethodHandleRef;
 import java.lang.invoke.VarHandle;
+import java.lang.sym.SymbolicRefs;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -49,97 +50,82 @@
     static final ClassRef CLASS_CONDY = ClassRef.of("java.lang.invoke.ConstantBootstraps");
 
     static final MethodHandleRef BSM_NULL_CONSTANT
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "nullConstant", ClassRef.CR_Object);
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "nullConstant", SymbolicRefs.CR_Object);
     static final MethodHandleRef BSM_PRIMITIVE_CLASS
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "primitiveClass", ClassRef.CR_Class);
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "primitiveClass", SymbolicRefs.CR_Class);
     static final MethodHandleRef BSM_ENUM_CONSTANT
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "enumConstant", ClassRef.CR_Enum);
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "enumConstant", SymbolicRefs.CR_Enum);
     static final MethodHandleRef BSM_GET_STATIC_FINAL_SELF
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "getStaticFinal", ClassRef.CR_Object);
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "getStaticFinal", SymbolicRefs.CR_Object);
     static final MethodHandleRef BSM_GET_STATIC_FINAL_DECL
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "getStaticFinal", ClassRef.CR_Object, ClassRef.CR_Class);
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "getStaticFinal", SymbolicRefs.CR_Object, SymbolicRefs.CR_Class);
     static final MethodHandleRef BSM_INVOKE
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "invoke", ClassRef.CR_Object, ClassRef.CR_MethodHandle, ClassRef.CR_Object.array());
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "invoke", SymbolicRefs.CR_Object, SymbolicRefs.CR_MethodHandle, SymbolicRefs.CR_Object.array());
     static final MethodHandleRef BSM_VARHANDLE_FIELD
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "fieldVarHandle", ClassRef.CR_VarHandle, ClassRef.CR_Class, ClassRef.CR_Class);
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "fieldVarHandle", SymbolicRefs.CR_VarHandle, SymbolicRefs.CR_Class, SymbolicRefs.CR_Class);
     static final MethodHandleRef BSM_VARHANDLE_STATIC_FIELD
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "staticFieldVarHandle", ClassRef.CR_VarHandle, ClassRef.CR_Class, ClassRef.CR_Class);
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "staticFieldVarHandle", SymbolicRefs.CR_VarHandle, SymbolicRefs.CR_Class, SymbolicRefs.CR_Class);
     static final MethodHandleRef BSM_VARHANDLE_ARRAY
-            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "arrayVarHandle", ClassRef.CR_VarHandle, ClassRef.CR_Class);
+            = MethodHandleRef.ofCondyBootstrap(CLASS_CONDY, "arrayVarHandle", SymbolicRefs.CR_VarHandle, SymbolicRefs.CR_Class);
 
 
     public void testNullConstant() {
-        Object supposedlyNull = Intrinsics.ldc(DynamicConstantRef.of(BSM_NULL_CONSTANT, ClassRef.CR_Object));
+        Object supposedlyNull = Intrinsics.ldc(DynamicConstantRef.of(BSM_NULL_CONSTANT, SymbolicRefs.CR_Object));
         assertNull(supposedlyNull);
 
-        supposedlyNull = Intrinsics.ldc(DynamicConstantRef.of(BSM_NULL_CONSTANT, ClassRef.CR_MethodType));
+        supposedlyNull = Intrinsics.ldc(DynamicConstantRef.of(BSM_NULL_CONSTANT, SymbolicRefs.CR_MethodType));
         assertNull(supposedlyNull);
     }
 
 
     public void testPrimitiveClass() {
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_int.descriptorString())),
-                     int.class);
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_long.descriptorString())),
-                     long.class);
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_short.descriptorString())),
-                     short.class);
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_byte.descriptorString())),
-                     byte.class);
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_char.descriptorString())),
-                     char.class);
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_float.descriptorString())),
-                     float.class);
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_double.descriptorString())),
-                     double.class);
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_boolean.descriptorString())),
-                     boolean.class);
-        assertEquals(ldc(DynamicConstantRef.of(BootstrapSpecifier.of(BSM_PRIMITIVE_CLASS), ClassRef.CR_void.descriptorString())),
-                     void.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_int.descriptorString())), int.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_long.descriptorString())), long.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_short.descriptorString())), short.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_byte.descriptorString())), byte.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_char.descriptorString())), char.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_float.descriptorString())), float.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_double.descriptorString())), double.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_boolean.descriptorString())), boolean.class);
+        assertEquals(ldc(DynamicConstantRef.of(BSM_PRIMITIVE_CLASS, SymbolicRefs.CR_void.descriptorString())), void.class);
     }
 
 
     public void testEnumConstant() {
         MethodHandleRef.Kind k = Intrinsics.ldc(DynamicConstantRef.of(
                 BSM_ENUM_CONSTANT, "STATIC",
-                ClassRef.of("java.lang.invoke.MethodHandleRef$Kind")));
+                ClassRef.of("java.lang.sym.MethodHandleRef$Kind")));
         assertEquals(k, MethodHandleRef.Kind.STATIC);
     }
 
 
     public void testGetStaticFinalDecl() {
         DynamicConstantRef<Class<Integer>> intClass =
-                DynamicConstantRef.of(BootstrapSpecifier.of(BSM_GET_STATIC_FINAL_DECL, ClassRef.CR_Integer),
-                                      "TYPE", ClassRef.CR_Class);
+                DynamicConstantRef.<Class<Integer>>of(BSM_GET_STATIC_FINAL_DECL, "TYPE", SymbolicRefs.CR_Class).withArgs(SymbolicRefs.CR_Integer);
         Class<Integer> c = Intrinsics.ldc(intClass);
         assertEquals(c, int.class);
     }
 
     public void testGetStaticFinalSelf() {
-        DynamicConstantRef<Integer> integerMaxValue = DynamicConstantRef.of(BootstrapSpecifier.of(BSM_GET_STATIC_FINAL_SELF),
-                                                                            "MAX_VALUE", ClassRef.CR_int);
+        DynamicConstantRef<Integer> integerMaxValue = DynamicConstantRef.of(BSM_GET_STATIC_FINAL_SELF, "MAX_VALUE", SymbolicRefs.CR_int);
         int v = Intrinsics.ldc(integerMaxValue);
         assertEquals(v, Integer.MAX_VALUE);
     }
 
 
     public void testInvoke() {
-        DynamicConstantRef<List<Integer>> list = DynamicConstantRef.of(
-                BootstrapSpecifier.of(BSM_INVOKE,
-                                      MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.CR_List, "of", ClassRef.CR_List, ClassRef.CR_Object.array()),
-                                      1, 2, 3, 4),
-                ClassRef.CR_List);
+        DynamicConstantRef<List<Integer>> list 
+                = DynamicConstantRef.<List<Integer>>of(BSM_INVOKE, SymbolicRefs.CR_List)
+                .withArgs(MethodHandleRef.of(MethodHandleRef.Kind.STATIC, SymbolicRefs.CR_List, "of", SymbolicRefs.CR_List, SymbolicRefs.CR_Object.array()), 1, 2, 3, 4);
 
         List<Integer> l = ldc(list);
         assertEquals(l, List.of(1, 2, 3, 4));
     }
 
     public void testInvokeAsType() {
-        DynamicConstantRef<Integer> valueOf = DynamicConstantRef.of(
-                BootstrapSpecifier.of(BSM_INVOKE,
-                                      MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.CR_Integer, "valueOf", ClassRef.CR_Integer, ClassRef.CR_String),
-                                      "42"),
-                ClassRef.CR_int);
+        DynamicConstantRef<Integer> valueOf = DynamicConstantRef.<Integer>of(BSM_INVOKE, SymbolicRefs.CR_int)
+                .withArgs(MethodHandleRef.of(MethodHandleRef.Kind.STATIC, SymbolicRefs.CR_Integer, "valueOf", SymbolicRefs.CR_Integer, SymbolicRefs.CR_String),
+                          "42");
 
         int v = ldc(valueOf);
         assertEquals(v, 42);
@@ -147,8 +133,8 @@
 
 
     public void testVarHandleField() {
-        VarHandle fh = Intrinsics.ldc(DynamicConstantRef.of(
-                BootstrapSpecifier.of(BSM_VARHANDLE_FIELD, ClassRef.of("CondyTestHelper"), ClassRef.CR_String), "f"));
+        VarHandle fh = Intrinsics.ldc(DynamicConstantRef.<VarHandle>of(BSM_VARHANDLE_FIELD, "f")
+                                              .withArgs(ClassRef.of("CondyTestHelper"), SymbolicRefs.CR_String));
 
         CondyTestHelper instance = new CondyTestHelper();
         assertEquals(null, fh.get(instance));
@@ -157,8 +143,8 @@
     }
 
     public void testVarHandleStaticField() {
-        VarHandle sfh = Intrinsics.ldc(DynamicConstantRef.of(
-                BootstrapSpecifier.of(BSM_VARHANDLE_STATIC_FIELD, ClassRef.of("CondyTestHelper"), ClassRef.CR_String), "sf"));
+        VarHandle sfh = Intrinsics.ldc(DynamicConstantRef.<VarHandle>of(BSM_VARHANDLE_STATIC_FIELD, "sf")
+                                       .withArgs(ClassRef.of("CondyTestHelper"), SymbolicRefs.CR_String));
 
         assertEquals(null, sfh.get());
         sfh.set("42");
@@ -166,8 +152,7 @@
     }
 
     public void testVarHandleArray() {
-        VarHandle ah = Intrinsics.ldc(DynamicConstantRef.of(
-                BootstrapSpecifier.of(BSM_VARHANDLE_ARRAY, ClassRef.CR_String.array())));
+        VarHandle ah = Intrinsics.ldc(DynamicConstantRef.<VarHandle>of(BSM_VARHANDLE_ARRAY).withArgs(SymbolicRefs.CR_String.array()));
 
         String[] sa = { "A" };
         assertEquals("A", ah.get(sa, 0));
--- a/test/jdk/java/lang/invoke/IntrinsicsTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/jdk/java/lang/invoke/IntrinsicsTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -23,19 +23,20 @@
  * questions.
  */
 
-import java.lang.invoke.BootstrapSpecifier;
+import java.lang.sym.BootstrapSpecifier;
 import java.lang.invoke.CallSite;
-import java.lang.invoke.ClassRef;
+import java.lang.sym.ClassRef;
 import java.lang.invoke.ConstantCallSite;
-import java.lang.invoke.ConstantRef;
-import java.lang.invoke.DynamicConstantRef;
+import java.lang.sym.SymbolicRef;
+import java.lang.sym.DynamicConstantRef;
 import java.lang.invoke.Intrinsics;
 import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandleRef;
+import java.lang.sym.MethodHandleRef;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-import java.lang.invoke.MethodTypeRef;
+import java.lang.sym.MethodTypeRef;
 import java.lang.invoke.MutableCallSite;
+import java.lang.sym.SymbolicRefs;
 import java.util.List;
 import java.util.stream.Stream;
 
@@ -70,11 +71,11 @@
         ClassRef cc2 = ClassRef.ofDescriptor("Ljava/lang/String;");
         assertEquals(String.class, Intrinsics.ldc(cc2));
 
-        ConstantRef<String> s = "foo";
+        SymbolicRef<String> s = "foo";
         assertEquals("foo", Intrinsics.ldc(s));
 
         // @@@ Boxing should preserve IC-ness
-        ConstantRef<Integer> i = (Integer) 3;
+        SymbolicRef<Integer> i = (Integer) 3;
         assertEquals(3, (int) Intrinsics.ldc(i));
     }
 
@@ -135,17 +136,17 @@
     }
 
     public void testMethodTypeCombinators() {
-        MethodTypeRef mtc = MethodTypeRef.of(ClassRef.CR_String, ClassRef.CR_int);
+        MethodTypeRef mtc = MethodTypeRef.of(SymbolicRefs.CR_String, SymbolicRefs.CR_int);
         assertEquals(String.class, Intrinsics.ldc(mtc.returnType()));
         assertEquals(int.class, Intrinsics.ldc(mtc.parameterType(0)));
         assertEquals(String.class, Intrinsics.ldc(mtc.returnType()));
         assertEquals(MethodType.methodType(long.class, int.class),
-                     Intrinsics.ldc(mtc.changeReturnType(ClassRef.CR_long)));
+                     Intrinsics.ldc(mtc.changeReturnType(SymbolicRefs.CR_long)));
     }
 
     public void testMethodHandleCombinators() {
-        MethodHandleRef mhc = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.CR_String, "valueOf",
-                                                 MethodTypeRef.of(ClassRef.CR_String, ClassRef.CR_Object));
+        MethodHandleRef mhc = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, SymbolicRefs.CR_String, "valueOf",
+                                                 MethodTypeRef.of(SymbolicRefs.CR_String, SymbolicRefs.CR_Object));
         assertEquals(MethodType.methodType(String.class, Object.class),
                      Intrinsics.ldc(mhc.type()));
         assertEquals(String.class, Intrinsics.ldc(mhc.type().returnType()));
@@ -153,14 +154,14 @@
     }
 
     public void testInterfaceSpecial() throws Throwable {
-        MethodHandleRef mhr = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.CR_List, "of",
-                                                 MethodTypeRef.of(ClassRef.CR_List, ClassRef.CR_Object.array()));
+        MethodHandleRef mhr = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, SymbolicRefs.CR_List, "of",
+                                                 MethodTypeRef.of(SymbolicRefs.CR_List, SymbolicRefs.CR_Object.array()));
         MethodHandle mh = Intrinsics.ldc(mhr);
         assertEquals(List.of("a", "b"), (List<String>) mh.invoke("a", "b"));
     }
 
     public void testSimpleIndy() throws Throwable {
-        MethodHandleRef simpleBSM = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "simpleBSM", ClassRef.CR_CallSite);
+        MethodHandleRef simpleBSM = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "simpleBSM", SymbolicRefs.CR_CallSite);
         BootstrapSpecifier bsm = BootstrapSpecifier.of(simpleBSM);
         String result = (String) Intrinsics.invokedynamic(bsm, "foo");
         assertEquals("foo", result);
@@ -168,18 +169,18 @@
         BootstrapSpecifier bsm2 = BootstrapSpecifier.of(simpleBSM);
         assertEquals("bar", (String) Intrinsics.invokedynamic(bsm2, "bar"));
 
-        MethodHandleRef staticArgBSM = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "staticArgBSM", ClassRef.CR_CallSite, ClassRef.CR_String);
+        MethodHandleRef staticArgBSM = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "staticArgBSM", SymbolicRefs.CR_CallSite, SymbolicRefs.CR_String);
         BootstrapSpecifier bsm3 = BootstrapSpecifier.of(staticArgBSM, "bark");
         assertEquals("bark", (String) Intrinsics.invokedynamic(bsm3, "ignored"));
 
-        MethodHandleRef dynArgBSM = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "dynArgBSM", ClassRef.CR_CallSite, ClassRef.CR_String);
+        MethodHandleRef dynArgBSM = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "dynArgBSM", SymbolicRefs.CR_CallSite, SymbolicRefs.CR_String);
         BootstrapSpecifier bsm4 = BootstrapSpecifier.of(dynArgBSM, "bargle");
         assertEquals("barglefoo", (String) Intrinsics.invokedynamic(bsm4, "ignored", "foo"));
         assertEquals("barglebar", (String) Intrinsics.invokedynamic(bsm4, "ignored", "bar"));
     }
 
     public void testStatefulBSM() throws Throwable {
-        MethodHandleRef statefulBSM = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "statefulBSM", ClassRef.CR_CallSite);
+        MethodHandleRef statefulBSM = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "statefulBSM", SymbolicRefs.CR_CallSite);
         BootstrapSpecifier bsm = BootstrapSpecifier.of(statefulBSM);
         for (int i=0; i<10; i++) {
             assertEquals(i, (int) Intrinsics.invokedynamic(bsm, "ignored"));
@@ -188,17 +189,17 @@
 
     public void testCondyInIndy() throws Throwable {
         MethodHandleRef bsm = MethodHandleRef.ofIndyBootstrap(HELPER_CLASS, "staticArgBSM",
-                                                              ClassRef.CR_CallSite, ClassRef.CR_Class);
-        assertEquals(String.class, (Class) Intrinsics.invokedynamic(BootstrapSpecifier.of(bsm, ClassRef.CR_String), "ignored"));
-        assertEquals(int.class, (Class) Intrinsics.invokedynamic(BootstrapSpecifier.of(bsm, ClassRef.CR_int), "ignored"));
+                                                              SymbolicRefs.CR_CallSite, SymbolicRefs.CR_Class);
+        assertEquals(String.class, (Class) Intrinsics.invokedynamic(BootstrapSpecifier.of(bsm, SymbolicRefs.CR_String), "ignored"));
+        assertEquals(int.class, (Class) Intrinsics.invokedynamic(BootstrapSpecifier.of(bsm, SymbolicRefs.CR_int), "ignored"));
     }
 
     public void testCondyInCondy() throws Throwable {
-        MethodHandleRef bsm = MethodHandleRef.ofCondyBootstrap(HELPER_CLASS, "identityCondy", ClassRef.CR_Object, ClassRef.CR_Object);
-        assertEquals(String.class, Intrinsics.ldc(DynamicConstantRef.of(BootstrapSpecifier.of(bsm, ClassRef.CR_String), ClassRef.CR_Class)));
-        assertEquals(String.class, Intrinsics.ldc(DynamicConstantRef.of(BootstrapSpecifier.of(bsm, ClassRef.CR_String))));
-        assertEquals(int.class, Intrinsics.ldc(DynamicConstantRef.of(BootstrapSpecifier.of(bsm, ClassRef.CR_int))));
-        assertEquals("foo", Intrinsics.ldc(DynamicConstantRef.of(BootstrapSpecifier.of(bsm, "foo"))));
+        MethodHandleRef bsm = MethodHandleRef.ofCondyBootstrap(HELPER_CLASS, "identityCondy", SymbolicRefs.CR_Object, SymbolicRefs.CR_Object);
+        assertEquals(String.class, Intrinsics.ldc(DynamicConstantRef.of(bsm, SymbolicRefs.CR_Class).withArgs(SymbolicRefs.CR_String)));
+        assertEquals(String.class, Intrinsics.ldc(DynamicConstantRef.of(bsm).withArgs(SymbolicRefs.CR_String)));
+        assertEquals(int.class, Intrinsics.ldc(DynamicConstantRef.of(bsm).withArgs(SymbolicRefs.CR_int)));
+        assertEquals("foo", Intrinsics.ldc(DynamicConstantRef.of(bsm).withArgs("foo")));
     }
 
     static class IntrinsicTestHelper {
--- a/test/langtools/tools/javac/specialConstantFolding/CondyCodeGenerationTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/CondyCodeGenerationTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -30,18 +30,19 @@
  * @run main CondyCodeGenerationTest
  */
 
-import java.lang.invoke.BootstrapSpecifier;
-import java.lang.invoke.ClassRef;
-import java.lang.invoke.DynamicConstantRef;
+import java.lang.sym.BootstrapSpecifier;
+import java.lang.sym.ClassRef;
+import java.lang.sym.DynamicConstantRef;
 import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandleRef;
+import java.lang.sym.MethodHandleRef;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-import java.lang.invoke.MethodTypeRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 import java.util.StringJoiner;
 
 import static java.lang.invoke.Intrinsics.ldc;
-import static java.lang.invoke.MethodHandleRef.Kind.STATIC;
+import static java.lang.sym.MethodHandleRef.Kind.STATIC;
 
 public class CondyCodeGenerationTest {
     public static void main(String[] args) throws Throwable {
@@ -59,11 +60,11 @@
 
     String testNoStaticArgs() throws Throwable {
         MethodTypeRef methodTypeForMethodHandle = MethodTypeRef.of(
-                ClassRef.CR_String, ClassRef.CR_Lookup, ClassRef.CR_String, ClassRef.CR_Class);
+                SymbolicRefs.CR_String, SymbolicRefs.CR_Lookup, SymbolicRefs.CR_String, SymbolicRefs.CR_Class);
         MethodHandleRef mh = MethodHandleRef.of(STATIC, ClassRef.ofDescriptor("LCondyCodeGenerationTest;"),
                                                 "testNoStaticArgsBSM", methodTypeForMethodHandle);
-        BootstrapSpecifier bss = BootstrapSpecifier.of(mh);
-        DynamicConstantRef<String> condyDescr = DynamicConstantRef.of(bss, "constant-name");
+
+        DynamicConstantRef<String> condyDescr = DynamicConstantRef.<String>of(mh, "constant-name");
         return (String)ldc(condyDescr);
     }
 
@@ -74,26 +75,25 @@
 
     String testWithStaticArgs() throws Throwable {
         MethodTypeRef methodTypeForMethodHandle = MethodTypeRef.of(
-                ClassRef.CR_String,
-                ClassRef.CR_Lookup,
-                ClassRef.CR_String,
-                ClassRef.CR_Class,
-                ClassRef.CR_int,
-                ClassRef.CR_long,
-                ClassRef.CR_float,
-                ClassRef.CR_double,
-                ClassRef.CR_Class,
-                ClassRef.CR_String,
-                ClassRef.CR_MethodType,
-                ClassRef.CR_MethodHandle);
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Lookup,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Class,
+                SymbolicRefs.CR_int,
+                SymbolicRefs.CR_long,
+                SymbolicRefs.CR_float,
+                SymbolicRefs.CR_double,
+                SymbolicRefs.CR_Class,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_MethodType,
+                SymbolicRefs.CR_MethodHandle);
         MethodHandleRef mh = MethodHandleRef.of(STATIC, ClassRef.ofDescriptor("LCondyCodeGenerationTest;"),
                                                 "testWithStaticArgsBSM", methodTypeForMethodHandle);
-        BootstrapSpecifier bss = BootstrapSpecifier.of(mh, 1, 2L, 3.0f, 4.0d,
-                                                       ClassRef.CR_Number,
-                                                       "something",
-                                                       MethodTypeRef.ofDescriptor("(IJFD)V"),
-                                                       mh);
-        DynamicConstantRef<String> condyDescr = DynamicConstantRef.of(bss, "constant-name");
+        DynamicConstantRef<String> condyDescr = DynamicConstantRef.<String>of(mh, "constant-name").withArgs(1, 2L, 3.0f, 4.0d,
+                                                                                                            SymbolicRefs.CR_Number,
+                                                                                                            "something",
+                                                                                                            MethodTypeRef.ofDescriptor("(IJFD)V"),
+                                                                                                            mh);
         return (String)ldc(condyDescr);
     }
 
@@ -117,29 +117,27 @@
 
     String testWithNestedArg() throws Throwable {
         MethodTypeRef c_primitiveClassBSM_MT = MethodTypeRef.of(
-                ClassRef.CR_Class,
-                ClassRef.CR_Lookup,
-                ClassRef.CR_String,
-                ClassRef.CR_Class
+                SymbolicRefs.CR_Class,
+                SymbolicRefs.CR_Lookup,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Class
         );
         MethodHandleRef c_primitiveClassBSM_MH =
                 MethodHandleRef.of(STATIC, ClassRef.ofDescriptor("LCondyCodeGenerationTest;"),
                                    "primitiveClassBSM", c_primitiveClassBSM_MT);
-        BootstrapSpecifier bss0 = BootstrapSpecifier.of(c_primitiveClassBSM_MH);
-        DynamicConstantRef<Class> c_primitiveClassBSM_CD = DynamicConstantRef.of(bss0, "I");
+        DynamicConstantRef<Class> c_primitiveClassBSM_CD = DynamicConstantRef.of(c_primitiveClassBSM_MH, "I");
 
         MethodTypeRef methodTypeForMethodHandle = MethodTypeRef.of(
-                ClassRef.CR_String,
-                ClassRef.CR_Lookup,
-                ClassRef.CR_String,
-                ClassRef.CR_Class,
-                ClassRef.CR_Class
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Lookup,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Class,
+                SymbolicRefs.CR_Class
         );
         MethodHandleRef mh = MethodHandleRef.of(STATIC, ClassRef.ofDescriptor("LCondyCodeGenerationTest;"),
                                                 "testWithNestedArgBSM", methodTypeForMethodHandle);
-        BootstrapSpecifier bss = BootstrapSpecifier.of(mh, c_primitiveClassBSM_CD);
 
-        DynamicConstantRef<String> condyDescr = DynamicConstantRef.of(bss, "constant-name");
+        DynamicConstantRef<String> condyDescr = DynamicConstantRef.<String>of(mh, "constant-name").withArgs(c_primitiveClassBSM_CD);
         return (String)ldc(condyDescr);
     }
 
--- a/test/langtools/tools/javac/specialConstantFolding/CrashWithPrimitiveArgumentsTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/CrashWithPrimitiveArgumentsTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -28,6 +28,7 @@
  */
 
 import java.lang.invoke.*;
+import java.lang.sym.MethodTypeRef;
 
 public class CrashWithPrimitiveArgumentsTest {
     void test() {
--- a/test/langtools/tools/javac/specialConstantFolding/DontCompileIfSymbolCantBeFoundTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/DontCompileIfSymbolCantBeFoundTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -6,12 +6,16 @@
  */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 
 import static java.lang.invoke.Intrinsics.*;
-import static java.lang.invoke.MethodHandleRef.Kind.GETTER;
-import static java.lang.invoke.MethodHandleRef.Kind.SETTER;
-import static java.lang.invoke.MethodHandleRef.Kind.STATIC_GETTER;
-import static java.lang.invoke.MethodHandleRef.Kind.STATIC_SETTER;
+import static java.lang.sym.MethodHandleRef.Kind.GETTER;
+import static java.lang.sym.MethodHandleRef.Kind.SETTER;
+import static java.lang.sym.MethodHandleRef.Kind.STATIC_GETTER;
+import static java.lang.sym.MethodHandleRef.Kind.STATIC_SETTER;
 
 public class DontCompileIfSymbolCantBeFoundTest {
     void test() {
@@ -19,11 +23,11 @@
         final MethodHandle mhStatic = ldc(MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchMethod", "()Ljava/lang/String;"));
         final MethodHandle mhSpecial = ldc(MethodHandleRef.ofSpecial(ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchMethod", MethodTypeRef.ofDescriptor("()Ljava/lang/String;"), ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest")));
 
-        final MethodHandle mhStaticSetter = ldc(MethodHandleRef.ofField(STATIC_SETTER, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchField", ClassRef.CR_String));
-        final MethodHandle mhSetter = ldc(MethodHandleRef.ofField(SETTER, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchField", ClassRef.CR_String));
-        final MethodHandle mhGetter = ldc(MethodHandleRef.ofField(GETTER, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchField", ClassRef.CR_String));
-        final MethodHandle mhStaticGetter = ldc(MethodHandleRef.ofField(STATIC_GETTER, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchField", ClassRef.CR_String));
+        final MethodHandle mhStaticSetter = ldc(MethodHandleRef.ofField(STATIC_SETTER, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchField", SymbolicRefs.CR_String));
+        final MethodHandle mhSetter = ldc(MethodHandleRef.ofField(SETTER, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchField", SymbolicRefs.CR_String));
+        final MethodHandle mhGetter = ldc(MethodHandleRef.ofField(GETTER, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchField", SymbolicRefs.CR_String));
+        final MethodHandle mhStaticGetter = ldc(MethodHandleRef.ofField(STATIC_GETTER, ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), "noSuchField", SymbolicRefs.CR_String));
 
-        final MethodHandle mhNewFindConstructorTest = ldc(MethodHandleRef.ofConstructor(ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), VOID, ClassRef.CR_String));
+        final MethodHandle mhNewFindConstructorTest = ldc(MethodHandleRef.ofConstructor(ClassRef.ofDescriptor("DontCompileIfSymbolCantBeFoundTest"), VOID, SymbolicRefs.CR_String));
     }
 }
--- a/test/langtools/tools/javac/specialConstantFolding/EffectivelyFinalTestNeg.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/EffectivelyFinalTestNeg.java	Fri Dec 22 13:06:32 2017 -0500
@@ -4,7 +4,7 @@
  * @compile/fail/ref=EffectivelyFinalTestNeg.out -XDdoConstantFold -XDrawDiagnostics EffectivelyFinalTestNeg.java
  */
 
-import java.lang.invoke.*;
+import java.lang.invoke.*; import java.lang.sym.*;
 
 import static java.lang.invoke.Intrinsics.*;
 
@@ -14,20 +14,20 @@
     }
 
     void test2() throws Throwable {
-        ClassRef c1 = ClassRef.CR_String;
-        ClassRef c2 = ClassRef.CR_Integer;
+        ClassRef c1 = SymbolicRefs.CR_String;
+        ClassRef c2 = SymbolicRefs.CR_Integer;
         c1 = null;
         MethodType mt = ldc(MethodTypeRef.of(c1, c2));
     }
 
     void test2_1() throws Throwable {
-        ClassRef i = ClassRef.CR_String;
+        ClassRef i = SymbolicRefs.CR_String;
         MethodType mt = ldc(MethodTypeRef.of(i));
         i = null;
     }
 
     void test3(EffectivelyFinalTestNeg f) throws Throwable {
-        ClassRef c = ClassRef.CR_String;
+        ClassRef c = SymbolicRefs.CR_String;
         // you can't trust m1 as it depends on c1 which is not effectively final
         MethodTypeRef mt = MethodTypeRef.of(c);
         MethodHandle mh = ldc(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, ClassRef.ofDescriptor("LEffectivelyFinalTestNeg;"), "foo", mt));
@@ -35,7 +35,7 @@
     }
 
     void test4(EffectivelyFinalTestNeg f) throws Throwable {
-        ClassRef c = ClassRef.CR_String;
+        ClassRef c = SymbolicRefs.CR_String;
         // you can't trust m1 as it depends on c1 which is not effectively final
         MethodTypeRef mt = MethodTypeRef.of(c);
         final MethodHandle mh = ldc(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, ClassRef.ofDescriptor("LEffectivelyFinalTestNeg;"), "foo", mt));
@@ -45,7 +45,7 @@
     final ClassRef cField = ClassRef.ofDescriptor("LEffectivelyFinalTestNeg;");
 
     void test5(EffectivelyFinalTestNeg f) throws Throwable {
-        ClassRef c = ClassRef.CR_String;
+        ClassRef c = SymbolicRefs.CR_String;
         // you can't trust m1 as it depends on c1 which is not effectively final
         MethodTypeRef mt = MethodTypeRef.of(c);
         MethodHandle mh = ldc(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, cField, "foo", mt));
--- a/test/langtools/tools/javac/specialConstantFolding/IndyCodeGenerationTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyCodeGenerationTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -29,15 +29,16 @@
  * @run main IndyCodeGenerationTest
  */
 
-import java.lang.invoke.BootstrapSpecifier;
+import java.lang.sym.BootstrapSpecifier;
 import java.lang.invoke.CallSite;
-import java.lang.invoke.ClassRef;
+import java.lang.sym.ClassRef;
 import java.lang.invoke.ConstantCallSite;
 import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandleRef;
+import java.lang.sym.MethodHandleRef;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
-import java.lang.invoke.MethodTypeRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 import java.util.StringJoiner;
 
 import static java.lang.invoke.Intrinsics.invokedynamic;
@@ -52,24 +53,24 @@
 
     String testWithStaticArgs() throws Throwable {
         MethodTypeRef methodTypeForMethodHandle = MethodTypeRef.of(
-                ClassRef.CR_CallSite,
-                ClassRef.CR_Lookup,
-                ClassRef.CR_String,
-                ClassRef.CR_MethodType,
-                ClassRef.CR_int,
-                ClassRef.CR_long,
-                ClassRef.CR_float,
-                ClassRef.CR_double,
-                ClassRef.CR_Class,
-                ClassRef.CR_String,
-                ClassRef.CR_MethodType,
-                ClassRef.CR_MethodHandle
+                SymbolicRefs.CR_CallSite,
+                SymbolicRefs.CR_Lookup,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_MethodType,
+                SymbolicRefs.CR_int,
+                SymbolicRefs.CR_long,
+                SymbolicRefs.CR_float,
+                SymbolicRefs.CR_double,
+                SymbolicRefs.CR_Class,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_MethodType,
+                SymbolicRefs.CR_MethodHandle
         );
         MethodHandleRef mh = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.ofDescriptor("LIndyCodeGenerationTest;"),
                                                 "testWithStaticArgsBSM", methodTypeForMethodHandle);
         BootstrapSpecifier bs = BootstrapSpecifier.of(mh,
                                                       1, 2L, 3.0f, 4.0d,
-                                                      ClassRef.CR_int,
+                                                      SymbolicRefs.CR_int,
                                                       "something",
                                                       MethodTypeRef.ofDescriptor("(IJFD)V"), mh);
         return (String) invokedynamic(bs, "name");
--- a/test/langtools/tools/javac/specialConstantFolding/IndyCrashTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyCrashTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -4,7 +4,7 @@
  * @compile/fail/ref=IndyCrashTest.out -XDdoConstantFold -XDrawDiagnostics IndyCrashTest.java
  */
 
-import java.lang.invoke.*;
+import java.lang.invoke.*; import java.lang.sym.*;
 
 public class IndyCrashTest {
     static final ClassRef HELPER_CLASS = ClassRef.ofDescriptor("LIndyCrashTest$IntrinsicTestHelper;");
--- a/test/langtools/tools/javac/specialConstantFolding/IndyLinkageErrorTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyLinkageErrorTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -4,19 +4,19 @@
  * @compile/fail/ref=IndyLinkageErrorTest.out -XDdoConstantFold -XDrawDiagnostics IndyLinkageErrorTest.java
  */
 
-import java.lang.invoke.*;
+import java.lang.sym.*;
 
 import static java.lang.invoke.Intrinsics.*;
 
 public class IndyLinkageErrorTest {
     String test(String x, String y) throws Throwable {
         MethodTypeRef methodTypeForMethodHandle = MethodTypeRef.of(
-            ClassRef.CR_CallSite,
-            ClassRef.CR_Lookup,
-            ClassRef.CR_String,
-            ClassRef.CR_MethodType,
-            ClassRef.CR_String,
-            ClassRef.CR_Object.array()
+                SymbolicRefs.CR_CallSite,
+                SymbolicRefs.CR_Lookup,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_MethodType,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Object.array()
         );
         MethodHandleRef mh = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.ofDescriptor("Ljava/lang/invoke/StringConcatFactory;"),
                                                 "makeConcatWithConstants", methodTypeForMethodHandle);
--- a/test/langtools/tools/javac/specialConstantFolding/IndyNegativeTest01.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyNegativeTest01.java	Fri Dec 22 13:06:32 2017 -0500
@@ -4,19 +4,19 @@
  * @compile/fail/ref=IndyNegativeTest01.out -XDdoConstantFold -XDrawDiagnostics IndyNegativeTest01.java
  */
 
-import java.lang.invoke.*;
+import java.lang.sym.*;
 
 import static java.lang.invoke.Intrinsics.*;
 
 public class IndyNegativeTest01 {
     void test(String invokeName, String x, String y) throws Throwable {
         MethodTypeRef methodTypeForMethodHandle = MethodTypeRef.of(
-            ClassRef.CR_CallSite,
-            ClassRef.CR_Lookup,
-            ClassRef.CR_String,
-            ClassRef.CR_MethodType,
-            ClassRef.CR_String,
-            ClassRef.CR_Object.array()
+                SymbolicRefs.CR_CallSite,
+                SymbolicRefs.CR_Lookup,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_MethodType,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Object.array()
         );
         MethodHandleRef mh = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.ofDescriptor("Ljava/lang/invoke/StringConcatFactory;"),
                                                 "makeConcatWithConstants", methodTypeForMethodHandle);
--- a/test/langtools/tools/javac/specialConstantFolding/IndyPositiveTest01.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyPositiveTest01.java	Fri Dec 22 13:06:32 2017 -0500
@@ -29,7 +29,12 @@
  * @run main IndyPositiveTest01
  */
 
-import java.lang.invoke.*;
+import java.lang.sym.BootstrapSpecifier;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
+
 import com.sun.tools.javac.util.Assert;
 import static java.lang.invoke.Intrinsics.*;
 
@@ -40,12 +45,12 @@
 
     String test(String x, String y) throws Throwable {
         MethodTypeRef methodTypeForMethodHandle = MethodTypeRef.of(
-            ClassRef.CR_CallSite,
-            ClassRef.CR_Lookup,
-            ClassRef.CR_String,
-            ClassRef.CR_MethodType,
-            ClassRef.CR_String,
-            ClassRef.CR_Object.array()
+                SymbolicRefs.CR_CallSite,
+                SymbolicRefs.CR_Lookup,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_MethodType,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Object.array()
         );
         MethodHandleRef mh = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.ofDescriptor("Ljava/lang/invoke/StringConcatFactory;"),
                                                 "makeConcatWithConstants", methodTypeForMethodHandle);
--- a/test/langtools/tools/javac/specialConstantFolding/LDCNegativeTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/LDCNegativeTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -4,7 +4,7 @@
  * @compile/fail/ref=LDCNegativeTest.out -XDdoConstantFold -XDrawDiagnostics LDCNegativeTest.java
  */
 
-import java.lang.invoke.*;
+import java.lang.sym.*;
 
 import static java.lang.invoke.Intrinsics.*;
 
@@ -13,7 +13,7 @@
 
     public String x() { return ""; }
     public ClassRef c() { return null; }
-    public ClassRef d = ClassRef.CR_int;
+    public ClassRef d = SymbolicRefs.CR_int;
 
     void foo() {
         // all these fail
--- a/test/langtools/tools/javac/specialConstantFolding/MultipleBSMEntriesTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/MultipleBSMEntriesTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -34,6 +34,11 @@
 
 import java.io.File;
 import java.lang.invoke.*;
+import java.lang.sym.BootstrapSpecifier;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 import java.math.BigInteger;
 
 import com.sun.tools.classfile.*;
@@ -44,7 +49,7 @@
     // library code starts
     static class MultiplyCallSite extends MutableCallSite {
         private static final MethodTypeRef TYPE =
-                MethodTypeRef.of(ClassRef.ofDescriptor("Ljava/math/BigInteger;"), ClassRef.CR_long, ClassRef.CR_long);
+                MethodTypeRef.of(ClassRef.ofDescriptor("Ljava/math/BigInteger;"), SymbolicRefs.CR_long, SymbolicRefs.CR_long);
         private static final ClassRef ME = ClassRef.ofDescriptor("LMultipleBSMEntriesTest$MultiplyCallSite;");
 
         private static final MethodHandle FAST = Intrinsics.ldc(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, ME, "fast", TYPE));
@@ -72,7 +77,7 @@
 
     public static final BootstrapSpecifier MULT = BootstrapSpecifier.of(
             MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.ofDescriptor("LMultipleBSMEntriesTest;"), "multiplyFactory",
-                               ClassRef.CR_CallSite, ClassRef.CR_Lookup, ClassRef.CR_String, ClassRef.CR_MethodType));
+                               SymbolicRefs.CR_CallSite, SymbolicRefs.CR_Lookup, SymbolicRefs.CR_String, SymbolicRefs.CR_MethodType));
 
     public static CallSite multiplyFactory(MethodHandles.Lookup lookup, String name, MethodType type) {
         return new MultiplyCallSite(type);
--- a/test/langtools/tools/javac/specialConstantFolding/ReflectiveErrorTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/ReflectiveErrorTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -4,7 +4,7 @@
  * @compile/fail/ref=ReflectiveErrorTest.out -XDdoConstantFold -XDrawDiagnostics ReflectiveErrorTest.java
  */
 
-import java.lang.invoke.*;
+import java.lang.sym.*;
 
 public class ReflectiveErrorTest {
     // trying to use an erroneous descriptor
--- a/test/langtools/tools/javac/specialConstantFolding/ReflectiveErrorTest.out	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/ReflectiveErrorTest.out	Fri Dec 22 13:06:32 2017 -0500
@@ -1,2 +1,2 @@
-ReflectiveErrorTest.java:11:56: compiler.err.reflective.error: ofDescriptor, java.lang.invoke.MethodTypeRef, Invalid parameter type: ^
+ReflectiveErrorTest.java:11:56: compiler.err.reflective.error: ofDescriptor, java.lang.sym.MethodTypeRef, Invalid parameter type: ^
 1 error
--- a/test/langtools/tools/javac/specialConstantFolding/ReportIncorrectMHForIndyTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/ReportIncorrectMHForIndyTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -6,6 +6,11 @@
  */
 
 import java.lang.invoke.*;
+import java.lang.sym.BootstrapSpecifier;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 
 public class ReportIncorrectMHForIndyTest {
 
@@ -18,12 +23,12 @@
     String test(String x, String y) throws Throwable {
         // correct method type
         MethodTypeRef methodTypeForMethodHandle = MethodTypeRef.of(
-                ClassRef.CR_CallSite,
-                ClassRef.CR_String,  // bad argument must be of type MethodHandles.Lookup
-                ClassRef.CR_String,
-                ClassRef.CR_MethodType,
-                ClassRef.CR_String,
-                ClassRef.CR_Object.array()
+                SymbolicRefs.CR_CallSite,
+                SymbolicRefs.CR_String,  // bad argument must be of type MethodHandles.Lookup
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_MethodType,
+                SymbolicRefs.CR_String,
+                SymbolicRefs.CR_Object.array()
         );
         MethodHandleRef mh = MethodHandleRef.of(MethodHandleRef.Kind.STATIC, ClassRef.ofDescriptor("LReportIncorrectMHForIndyTest;"),
                                                 "makeConcatWithConstants", methodTypeForMethodHandle);
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantDefinitions.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantDefinitions.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,11 +1,13 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 
 import static java.lang.invoke.Intrinsics.*;
 
 @IgnoreTest
 public class ConstantDefinitions {
-    public static final MethodType mtStatic = ldc(MethodTypeRef.of(ClassRef.CR_String));
-    public final MethodType mtInstance = ldc(MethodTypeRef.of(ClassRef.CR_String));
+    public static final MethodType mtStatic = ldc(MethodTypeRef.of(SymbolicRefs.CR_String));
+    public final MethodType mtInstance = ldc(MethodTypeRef.of(SymbolicRefs.CR_String));
 }
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantFoldingOfMethodTypeDiffContextsTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantFoldingOfMethodTypeDiffContextsTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -2,6 +2,8 @@
 
 import java.io.Serializable;
 import java.lang.invoke.*;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 
 import static java.lang.invoke.Intrinsics.*;
 
@@ -22,9 +24,9 @@
 //    @InstructionInfo(bytecodePosition=9, values={"CONSTANT_MethodType_info", "(I)V"})
     @InstructionInfo(bytecodePosition=9, values={"CONSTANT_MethodType_info", "()Ljava/lang/String;"})
     void assignmentContext() {
-        MethodType mt1 = ldc(MethodTypeRef.of(ClassRef.CR_String));
-        MethodType mt2 = ldc(MethodTypeRef.of(ClassRef.CR_String, ClassRef.CR_int));
-        MethodType mt3 = ldc(MethodTypeRef.of(ClassRef.CR_void, ClassRef.CR_String, ClassRef.CR_int));
+        MethodType mt1 = ldc(MethodTypeRef.of(SymbolicRefs.CR_String));
+        MethodType mt2 = ldc(MethodTypeRef.of(SymbolicRefs.CR_String, SymbolicRefs.CR_int));
+        MethodType mt3 = ldc(MethodTypeRef.of(SymbolicRefs.CR_void, SymbolicRefs.CR_String, SymbolicRefs.CR_int));
 //        MethodType mt4 = ldc(MethodTypeRef.of(VOID, MethodTypeRef.of(ClassRef.of("Ljava/lang/String;"), INT)));
         /*  if last argument of the method below is not null no effort is done to try to constant fold
          *  the method type
@@ -38,9 +40,9 @@
 //    @InstructionInfo(bytecodePosition=28, values={"CONSTANT_MethodType_info", "(I)V"})
     @InstructionInfo(bytecodePosition=19, values={"CONSTANT_MethodType_info", "()Ljava/lang/String;"})
     void invocationContext1() {
-        foo(ldc(MethodTypeRef.of(ClassRef.CR_String)));
-        foo(ldc(MethodTypeRef.of(ClassRef.CR_String, ClassRef.CR_int)));
-        foo(ldc(MethodTypeRef.of(ClassRef.CR_void, ClassRef.CR_String, ClassRef.CR_int)));
+        foo(ldc(MethodTypeRef.of(SymbolicRefs.CR_String)));
+        foo(ldc(MethodTypeRef.of(SymbolicRefs.CR_String, SymbolicRefs.CR_int)));
+        foo(ldc(MethodTypeRef.of(SymbolicRefs.CR_void, SymbolicRefs.CR_String, SymbolicRefs.CR_int)));
 //        foo(ldc(MethodTypeRef.of(VOID, MethodTypeRef.of(ClassRef.of("Ljava/lang/String;"), INT))));
         /*  if last argument of the method below is not null no effort is done to try to constant fold
          *  the method type
@@ -54,11 +56,11 @@
 //    @InstructionInfo(bytecodePosition=24, values={"CONSTANT_MethodType_info", "(I)V"})
     @InstructionInfo(bytecodePosition=24, values={"CONSTANT_MethodType_info", "()Ljava/lang/String;"})
     void invocationContext2() {
-        MethodType mt1 = ldc(MethodTypeRef.of(ClassRef.CR_String));
+        MethodType mt1 = ldc(MethodTypeRef.of(SymbolicRefs.CR_String));
         foo(mt1);
-        MethodType mt2 = ldc(MethodTypeRef.of(ClassRef.CR_String, ClassRef.CR_int));
+        MethodType mt2 = ldc(MethodTypeRef.of(SymbolicRefs.CR_String, SymbolicRefs.CR_int));
         foo(mt2);
-        MethodType mt3 = ldc(MethodTypeRef.of(ClassRef.CR_void, ClassRef.CR_String, ClassRef.CR_int));
+        MethodType mt3 = ldc(MethodTypeRef.of(SymbolicRefs.CR_void, SymbolicRefs.CR_String, SymbolicRefs.CR_int));
         foo(mt3);
 //        MethodType mt4 = ldc(MethodTypeRef.of(VOID, MethodTypeRef.of(ClassRef.of("Ljava/lang/String;"), INT)));
 //        foo(mt4);
@@ -75,9 +77,9 @@
 //    @InstructionInfo(bytecodePosition=18, values={"CONSTANT_MethodType_info", "(I)V"})
     @InstructionInfo(bytecodePosition=9, values={"CONSTANT_MethodType_info", "()Ljava/lang/String;"})
     void castContext1() {
-        Serializable s1 = (Serializable)ldc(MethodTypeRef.of(ClassRef.CR_String));
-        Serializable s2 = (Serializable)ldc(MethodTypeRef.of(ClassRef.CR_String, ClassRef.CR_int));
-        Serializable s3 = (Serializable)ldc(MethodTypeRef.of(ClassRef.CR_void, ClassRef.CR_String, ClassRef.CR_int));
+        Serializable s1 = (Serializable)ldc(MethodTypeRef.of(SymbolicRefs.CR_String));
+        Serializable s2 = (Serializable)ldc(MethodTypeRef.of(SymbolicRefs.CR_String, SymbolicRefs.CR_int));
+        Serializable s3 = (Serializable)ldc(MethodTypeRef.of(SymbolicRefs.CR_void, SymbolicRefs.CR_String, SymbolicRefs.CR_int));
 //        Serializable s4 = (Serializable)ldc(MethodTypeRef.of(VOID, MethodTypeRef.of(ClassRef.of("Ljava/lang/String;"), INT)));
         Serializable s5 = (Serializable)ldc(MethodTypeRef.ofDescriptor("()Ljava/lang/String;"));
     }
@@ -89,11 +91,11 @@
 //    @InstructionInfo(bytecodePosition=19, values={"CONSTANT_MethodType_info", "(I)V"})
     @InstructionInfo(bytecodePosition=19, values={"CONSTANT_MethodType_info", "()Ljava/lang/String;"})
     void castContext2() {
-        MethodType m1 = ldc(MethodTypeRef.of(ClassRef.CR_String));
+        MethodType m1 = ldc(MethodTypeRef.of(SymbolicRefs.CR_String));
         Serializable s1 = (Serializable)m1;
-        MethodType m2 = ldc(MethodTypeRef.of(ClassRef.CR_String, ClassRef.CR_int));
+        MethodType m2 = ldc(MethodTypeRef.of(SymbolicRefs.CR_String, SymbolicRefs.CR_int));
         Serializable s2 = (Serializable)m2;
-        MethodType m3 = ldc(MethodTypeRef.of(ClassRef.CR_void, ClassRef.CR_String, ClassRef.CR_int));
+        MethodType m3 = ldc(MethodTypeRef.of(SymbolicRefs.CR_void, SymbolicRefs.CR_String, SymbolicRefs.CR_int));
         Serializable s3 = (Serializable)m3;
 //        MethodType m4 = ldc(MethodTypeRef.of(VOID, MethodTypeRef.of(ClassRef.of("Ljava/lang/String;"), INT)));
 //        Serializable s4 = (Serializable)m4;
@@ -107,9 +109,9 @@
 //    @InstructionInfo(bytecodePosition=28, values={"CONSTANT_MethodType_info", "(I)V"})
     @InstructionInfo(bytecodePosition=19, values={"CONSTANT_MethodType_info", "()Ljava/lang/String;"})
     void cast_plus_invocationContext() {
-        foo((MethodType)ldc(MethodTypeRef.of(ClassRef.CR_String)));
-        foo((MethodType)ldc(MethodTypeRef.of(ClassRef.CR_String, ClassRef.CR_int)));
-        foo((MethodType)ldc(MethodTypeRef.of(ClassRef.CR_void, ClassRef.CR_String, ClassRef.CR_int)));
+        foo((MethodType)ldc(MethodTypeRef.of(SymbolicRefs.CR_String)));
+        foo((MethodType)ldc(MethodTypeRef.of(SymbolicRefs.CR_String, SymbolicRefs.CR_int)));
+        foo((MethodType)ldc(MethodTypeRef.of(SymbolicRefs.CR_void, SymbolicRefs.CR_String, SymbolicRefs.CR_int)));
 //        foo((MethodType)ldc(MethodTypeRef.of(VOID, MethodTypeRef.of(ClassRef.of("Ljava/lang/String;"), INT))));
         /*  if last argument of the method below is not null no effort is done to try to constant fold
          *  the method type
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantPropagationTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/ConstantPropagationTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,8 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodTypeRef;
 
 import static java.lang.invoke.Intrinsics.*;
 
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/EffectivelyFinalTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/EffectivelyFinalTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,9 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
 
 import static java.lang.invoke.Intrinsics.*;
 
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindConstructorTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindConstructorTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,10 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 
 import static java.lang.invoke.Intrinsics.*;
 
@@ -22,7 +26,7 @@
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_newInvokeSpecial"})
     void test1() throws Throwable {
         final MethodHandle mhNewFindConstructorTest = ldc(MethodHandleRef.of(MethodHandleRef.Kind.CONSTRUCTOR, ClassRef.ofDescriptor("LFindConstructorTest;"), "<init>",
-                                                                             MethodTypeRef.of(ClassRef.CR_void)));
+                                                                             MethodTypeRef.of(SymbolicRefs.CR_void)));
         FindConstructorTest foo = (FindConstructorTest) mhNewFindConstructorTest.invokeExact();
         check(foo.toString().equals("invoking FindConstructorTest.toString()"));
     }
@@ -30,7 +34,7 @@
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_newInvokeSpecial"})
     void test2() throws Throwable {
         MethodHandle mhNewFindConstructorTest = ldc(MethodHandleRef.of(MethodHandleRef.Kind.CONSTRUCTOR, ClassRef.ofDescriptor("LFindConstructorTest;"), "<init>",
-                                                                       MethodTypeRef.of(ClassRef.CR_void)));
+                                                                       MethodTypeRef.of(SymbolicRefs.CR_void)));
         FindConstructorTest foo = (FindConstructorTest) mhNewFindConstructorTest.invokeExact();
         check(foo.toString().equals("invoking FindConstructorTest.toString()"));
     }
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindGetterTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindGetterTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,9 +1,11 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
 
 import static java.lang.invoke.Intrinsics.*;
-import static java.lang.invoke.MethodHandleRef.Kind.GETTER;
+import static java.lang.sym.MethodHandleRef.Kind.GETTER;
 
 public class FindGetterTest extends ConstantFoldingTest {
     String strField = "instance field";
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindMethodWithGenericArgumentsTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindMethodWithGenericArgumentsTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,10 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 import java.util.List;
 import static java.lang.invoke.Intrinsics.*;
 
@@ -11,6 +15,6 @@
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_invokeVirtual"})
     void test() {
         MethodHandle mh2 = ldc(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, ClassRef.ofDescriptor("LFindMethodWithGenericArgumentsTest;"), "bar",
-                                                  MethodTypeRef.of(ClassRef.CR_void, ClassRef.CR_List)));
+                                                  MethodTypeRef.of(SymbolicRefs.CR_void, SymbolicRefs.CR_List)));
     }
 }
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindSetterTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindSetterTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,9 +1,12 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.SymbolicRefs;
 
 import static java.lang.invoke.Intrinsics.*;
-import static java.lang.invoke.MethodHandleRef.Kind.SETTER;
+import static java.lang.sym.MethodHandleRef.Kind.SETTER;
 
 public class FindSetterTest extends ConstantFoldingTest {
     String strField = "instance field";
@@ -18,7 +21,7 @@
 
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_putField"})
     void test1(FindSetterTest f) throws Throwable {
-        final MethodHandle mhSetter = ldc(MethodHandleRef.ofField(SETTER, ClassRef.ofDescriptor("LFindSetterTest;"), "strField", ClassRef.CR_String));
+        final MethodHandle mhSetter = ldc(MethodHandleRef.ofField(SETTER, ClassRef.ofDescriptor("LFindSetterTest;"), "strField", SymbolicRefs.CR_String));
         mhSetter.invoke(f, "new instance field value");
         check(f.strField.equals("new instance field value"));
     }
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticGetterTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticGetterTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,9 +1,12 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.SymbolicRefs;
 
 import static java.lang.invoke.Intrinsics.*;
-import static java.lang.invoke.MethodHandleRef.Kind.STATIC_GETTER;
+import static java.lang.sym.MethodHandleRef.Kind.STATIC_GETTER;
 
 public class FindStaticGetterTest extends ConstantFoldingTest {
     static String staticStrField = "class field";
@@ -19,13 +22,13 @@
 
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_getStatic"})
     void test1() throws Throwable {
-        final MethodHandle mhStaticGetter = ldc(MethodHandleRef.ofField(STATIC_GETTER, ClassRef.ofDescriptor("LFindStaticGetterTest;"), "staticStrField", ClassRef.CR_String));
+        final MethodHandle mhStaticGetter = ldc(MethodHandleRef.ofField(STATIC_GETTER, ClassRef.ofDescriptor("LFindStaticGetterTest;"), "staticStrField", SymbolicRefs.CR_String));
         check(mhStaticGetter.invoke().toString().equals("class field"));
     }
 
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_getStatic"})
     void test2() throws Throwable {
-        MethodHandle mhStaticGetter = ldc(MethodHandleRef.ofField(STATIC_GETTER, ClassRef.ofDescriptor("LFindStaticGetterTest;"), "staticStrField", ClassRef.CR_String));
+        MethodHandle mhStaticGetter = ldc(MethodHandleRef.ofField(STATIC_GETTER, ClassRef.ofDescriptor("LFindStaticGetterTest;"), "staticStrField", SymbolicRefs.CR_String));
         check(mhStaticGetter.invoke().toString().equals("class field"));
     }
 }
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticSetterTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticSetterTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,9 +1,12 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.SymbolicRefs;
 
 import static java.lang.invoke.Intrinsics.*;
-import static java.lang.invoke.MethodHandleRef.Kind.STATIC_SETTER;
+import static java.lang.sym.MethodHandleRef.Kind.STATIC_SETTER;
 
 public class FindStaticSetterTest extends ConstantFoldingTest {
     static String staticStrField = "class field";
@@ -19,14 +22,14 @@
 
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_putStatic"})
     void test1() throws Throwable {
-        final MethodHandle mhStaticSetter = ldc(MethodHandleRef.ofField(STATIC_SETTER, ClassRef.ofDescriptor("LFindStaticSetterTest;"), "staticStrField", ClassRef.CR_String));
+        final MethodHandle mhStaticSetter = ldc(MethodHandleRef.ofField(STATIC_SETTER, ClassRef.ofDescriptor("LFindStaticSetterTest;"), "staticStrField", SymbolicRefs.CR_String));
         mhStaticSetter.invoke("new class field value");
         check(FindStaticSetterTest.staticStrField.equals("new class field value"));
     }
 
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_putStatic"})
     void test2() throws Throwable {
-        MethodHandle mhStaticSetter = ldc(MethodHandleRef.ofField(STATIC_SETTER, ClassRef.ofDescriptor("LFindStaticSetterTest;"), "staticStrField", ClassRef.CR_String));
+        MethodHandle mhStaticSetter = ldc(MethodHandleRef.ofField(STATIC_SETTER, ClassRef.ofDescriptor("LFindStaticSetterTest;"), "staticStrField", SymbolicRefs.CR_String));
         mhStaticSetter.invoke("new class field value");
         check(FindStaticSetterTest.staticStrField.equals("new class field value"));
     }
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindStaticTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,9 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
 
 import static java.lang.invoke.Intrinsics.*;
 
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindVirtualTest01.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindVirtualTest01.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,10 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
+import java.lang.sym.SymbolicRefs;
 
 import static java.lang.invoke.Intrinsics.*;
 
@@ -68,7 +72,7 @@
     @InstructionInfo(bytecodePosition=0, values={"CONSTANT_MethodHandle_info", "REF_invokeVirtual"})
     void test5(FindVirtualTest01 f) throws Throwable {
         MethodHandle mhBar = ldc(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, ClassRef.ofDescriptor("LFindVirtualTest01;"), "bar",
-                                                    MethodTypeRef.of(ClassRef.ofDescriptor("Ljava/lang/String;"), ClassRef.CR_int)));
+                                                    MethodTypeRef.of(ClassRef.ofDescriptor("Ljava/lang/String;"), SymbolicRefs.CR_int)));
         check(mhBar.invoke(f, 3).toString().equals("invoking method FindVirtualTest01.bar() with argument 3"));
     }
 }
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindVirtualTest02.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/FindVirtualTest02.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,9 @@
 /* /nodynamiccopyright/ */
 
 import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
+import java.lang.sym.MethodHandleRef;
+import java.lang.sym.MethodTypeRef;
 
 import static java.lang.invoke.Intrinsics.*;
 
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/InstanceTrackableMethodsTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/InstanceTrackableMethodsTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,6 @@
 /* /nodynamiccopyright/ */
 
-import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
 
 import static java.lang.invoke.Intrinsics.*;
 
@@ -24,7 +24,7 @@
     }
 
     @InstructionInfo(bytecodePosition=6, values={"CONSTANT_Class_info", "[Ljava/lang/String;"})
-    @InstructionInfo(bytecodePosition=14, values={"CONSTANT_Class_info", "[Ljava/lang/String;"})
+    @InstructionInfo(bytecodePosition=16, values={"CONSTANT_Class_info", "[Ljava/lang/String;"})
     void test2() {
         ClassRef stringClass = ClassRef.ofDescriptor("Ljava/lang/String;");
         Class<?> stringArrClass = ldc(stringClass.array());
--- a/test/langtools/tools/javac/specialConstantFolding/harness/tests/StringFoldingTest.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/harness/tests/StringFoldingTest.java	Fri Dec 22 13:06:32 2017 -0500
@@ -1,6 +1,6 @@
 /* /nodynamiccopyright/ */
 
-import java.lang.invoke.*;
+import java.lang.sym.ClassRef;
 
 import static java.lang.invoke.Intrinsics.*;
 
--- a/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound.java	Fri Dec 22 13:06:32 2017 -0500
@@ -4,7 +4,7 @@
  * @compile/fail/ref=WarningIfClassOrMemberNotFound.out -XDdoConstantFold -Werror -XDrawDiagnostics WarningIfClassOrMemberNotFound.java
  */
 
-import java.lang.invoke.*;
+import java.lang.invoke.*; import java.lang.sym.*;
 import static java.lang.invoke.Intrinsics.*;
 
 class WarningIfClassOrMemberNotFound {
--- a/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.java	Wed Dec 20 11:56:26 2017 +0100
+++ b/test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.java	Fri Dec 22 13:06:32 2017 -0500
@@ -4,7 +4,7 @@
  * @compile/fail/ref=WarningIfMemberIncorrect.out -XDdoConstantFold -Werror -XDrawDiagnostics WarningIfMemberIncorrect.java
  */
 
-import java.lang.invoke.*;
+import java.lang.invoke.*; import java.lang.sym.*;
 import static java.lang.invoke.Intrinsics.*;
 
 class WarningIfMemberIncorrect {
@@ -23,7 +23,7 @@
 
         // warn: wrong kind to refer to a constructor
         MethodHandle mhConstructor = ldc(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, ClassRef.ofDescriptor("LWarningIfMemberIncorrect;"), "<init>",
-                                                                             MethodTypeRef.of(ClassRef.CR_void)));
+                                                                             MethodTypeRef.of(SymbolicRefs.CR_void)));
 
         MethodHandle mh3 = ldc(MethodHandleRef.of(MethodHandleRef.Kind.VIRTUAL, ClassRef.ofDescriptor("LWarningIfMemberIncorrect$I;"), "foo", mtReturnString));
     }