changeset 50932:9b942e8bd2ca condy-folding

moving package j.l.i.constant to j.l.constant
author vromero
date Mon, 04 Jun 2018 14:59:22 -0700
parents a5ca4f50cb3b
children 36192f15b20d
files src/java.base/share/classes/java/lang/Class.java src/java.base/share/classes/java/lang/Double.java src/java.base/share/classes/java/lang/Enum.java src/java.base/share/classes/java/lang/Float.java src/java.base/share/classes/java/lang/Integer.java src/java.base/share/classes/java/lang/Long.java src/java.base/share/classes/java/lang/String.java src/java.base/share/classes/java/lang/constant/AsTypeMethodHandleDesc.java src/java.base/share/classes/java/lang/constant/ClassDesc.java src/java.base/share/classes/java/lang/constant/Constable.java src/java.base/share/classes/java/lang/constant/ConstantClassDesc.java src/java.base/share/classes/java/lang/constant/ConstantDesc.java src/java.base/share/classes/java/lang/constant/ConstantDescs.java src/java.base/share/classes/java/lang/constant/ConstantMethodHandleDesc.java src/java.base/share/classes/java/lang/constant/ConstantMethodTypeDesc.java src/java.base/share/classes/java/lang/constant/ConstantUtils.java src/java.base/share/classes/java/lang/constant/DynamicCallSiteDesc.java src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java src/java.base/share/classes/java/lang/constant/MethodHandleDesc.java src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java src/java.base/share/classes/java/lang/constant/PrimitiveClassDesc.java src/java.base/share/classes/java/lang/constant/package-info.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/MethodType.java src/java.base/share/classes/java/lang/invoke/VarHandle.java src/java.base/share/classes/java/lang/invoke/constant/AsTypeMethodHandleDesc.java src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java src/java.base/share/classes/java/lang/invoke/constant/Constable.java src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java src/java.base/share/classes/java/lang/invoke/constant/ConstantDesc.java src/java.base/share/classes/java/lang/invoke/constant/ConstantDescs.java src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodTypeDesc.java src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java src/java.base/share/classes/java/lang/invoke/constant/DynamicCallSiteDesc.java src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java src/java.base/share/classes/java/lang/invoke/constant/MethodHandleDesc.java src/java.base/share/classes/java/lang/invoke/constant/MethodTypeDesc.java src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java src/java.base/share/classes/java/lang/invoke/constant/package-info.java src/java.base/share/classes/jdk/internal/lang/annotation/Foldable.java src/java.base/share/classes/module-info.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java test/jdk/java/lang/constant/ClassRefTest.java test/jdk/java/lang/constant/CondyRefTest.java test/jdk/java/lang/constant/ConstantUtilsTest.java test/jdk/java/lang/constant/IndyRefTest.java test/jdk/java/lang/constant/IntrinsifiedRefTest.java test/jdk/java/lang/constant/MethodHandleRefTest.java test/jdk/java/lang/constant/MethodTypeRefTest.java test/jdk/java/lang/constant/SymbolicRefTest.java test/jdk/java/lang/constant/TypeDescriptorTest.java test/jdk/java/lang/invoke/ConstantRefBootstrapsTest.java test/jdk/java/lang/invoke/constant/ClassRefTest.java test/jdk/java/lang/invoke/constant/CondyRefTest.java test/jdk/java/lang/invoke/constant/ConstantUtilsTest.java test/jdk/java/lang/invoke/constant/IndyRefTest.java test/jdk/java/lang/invoke/constant/IntrinsifiedRefTest.java test/jdk/java/lang/invoke/constant/MethodHandleRefTest.java test/jdk/java/lang/invoke/constant/MethodTypeRefTest.java test/jdk/java/lang/invoke/constant/SymbolicRefTest.java test/jdk/java/lang/invoke/constant/TypeDescriptorTest.java test/langtools/jdk/javadoc/doclet/testClassTree/TestClassTree.java test/langtools/jdk/jshell/TypeNameTest.java test/langtools/tools/javac/T8187978/FilterOutCandidatesForDiagnosticsTest.out test/langtools/tools/javac/condy/CheckForCondyDuplicatesTest.java test/langtools/tools/javac/generics/inference/EagerReturnTypeResolution/EagerReturnTypeResolutionTestb.out test/langtools/tools/javac/specialConstantFolding/CheckForCorrectMRefTest.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/IndyLinkageErrorTest.out test/langtools/tools/javac/specialConstantFolding/IndyNegativeTest01.java test/langtools/tools/javac/specialConstantFolding/IndyPositiveTest01.java test/langtools/tools/javac/specialConstantFolding/IntrinsicsTest.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/TwoVisitsAreNeededCauseOfForwardRefTest.java test/langtools/tools/javac/specialConstantFolding/checkMethodTypeShape/MethodTypeNegTest.java test/langtools/tools/javac/specialConstantFolding/checkMethodTypeShape/MethodTypeNegTest.out test/langtools/tools/javac/specialConstantFolding/dead_code_elimination/DontDoDCEOfConstableTest.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/WarningIfClassOrMemberNotFound2.java test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfClassOrMemberNotFound3.java test/langtools/tools/javac/specialConstantFolding/warningNotFoundOrIncorrect/WarningIfMemberIncorrect.java test/langtools/tools/javac/varargs/6806876/T6806876.out
diffstat 110 files changed, 5129 insertions(+), 5131 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/Class.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Class.java	Mon Jun 04 14:59:22 2018 -0700
@@ -26,9 +26,8 @@
 package java.lang;
 
 import java.lang.annotation.Annotation;
-import java.lang.invoke.constant.ClassDesc;
+import java.lang.constant.ClassDesc;
 import java.lang.invoke.FieldTypeDescriptor;
-import java.lang.invoke.constant.ConstantDesc;
 import java.lang.module.ModuleReader;
 import java.lang.ref.SoftReference;
 import java.io.IOException;
@@ -49,7 +48,7 @@
 import java.lang.reflect.Proxy;
 import java.lang.reflect.Type;
 import java.lang.reflect.TypeVariable;
-import java.lang.invoke.constant.Constable;
+import java.lang.constant.Constable;
 import java.net.URL;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
--- a/src/java.base/share/classes/java/lang/Double.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Double.java	Mon Jun 04 14:59:22 2018 -0700
@@ -26,8 +26,8 @@
 package java.lang;
 
 import java.lang.invoke.MethodHandles;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
 import java.util.Optional;
 
 import jdk.internal.math.FloatingDecimal;
--- a/src/java.base/share/classes/java/lang/Enum.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Enum.java	Mon Jun 04 14:59:22 2018 -0700
@@ -31,16 +31,16 @@
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamException;
 import java.lang.invoke.MethodHandles;
-import java.lang.invoke.constant.ClassDesc;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
-import java.lang.invoke.constant.ConstantDescs;
-import java.lang.invoke.constant.DynamicConstantDesc;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.DynamicConstantDesc;
 import java.util.Optional;
 
-import static java.lang.invoke.constant.ConstantDescs.BSM_ENUMDESC;
-import static java.lang.invoke.constant.ConstantDescs.CR_EnumDesc;
-import static java.lang.invoke.constant.ConstantUtils.validateMemberName;
+import static java.lang.constant.ConstantDescs.BSM_ENUMDESC;
+import static java.lang.constant.ConstantDescs.CR_EnumDesc;
+import static java.lang.constant.ConstantUtils.validateMemberName;
 import static java.util.Objects.requireNonNull;
 
 /**
--- a/src/java.base/share/classes/java/lang/Float.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Float.java	Mon Jun 04 14:59:22 2018 -0700
@@ -26,8 +26,8 @@
 package java.lang;
 
 import java.lang.invoke.MethodHandles;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
 import java.util.Optional;
 
 import jdk.internal.math.FloatingDecimal;
--- a/src/java.base/share/classes/java/lang/Integer.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Integer.java	Mon Jun 04 14:59:22 2018 -0700
@@ -27,8 +27,8 @@
 
 import java.lang.annotation.Native;
 import java.lang.invoke.MethodHandles;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
 import java.util.Objects;
 import java.util.Optional;
 
--- a/src/java.base/share/classes/java/lang/Long.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/Long.java	Mon Jun 04 14:59:22 2018 -0700
@@ -27,8 +27,8 @@
 
 import java.lang.annotation.Native;
 import java.lang.invoke.MethodHandles;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
 import java.math.*;
 import java.util.Objects;
 import java.util.Optional;
--- a/src/java.base/share/classes/java/lang/String.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/String.java	Mon Jun 04 14:59:22 2018 -0700
@@ -29,8 +29,8 @@
 import java.io.UnsupportedEncodingException;
 import java.lang.annotation.Native;
 import java.lang.invoke.MethodHandles;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
 import java.nio.charset.Charset;
 import java.util.ArrayList;
 import java.util.Arrays;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/AsTypeMethodHandleDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import jdk.internal.lang.annotation.Foldable;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.Optional;
+
+import static java.lang.constant.ConstantDescs.BSM_INVOKE;
+import static java.lang.constant.ConstantDescs.CR_MethodHandle;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
+ * {@link MethodHandle} constant that performs a {@link MethodHandle#asType(MethodType)}
+ * adaptation on another {@link MethodHandle}.
+ */
+final class AsTypeMethodHandleDesc extends DynamicConstantDesc<MethodHandle>
+        implements MethodHandleDesc {
+
+    private final MethodHandleDesc underlying;
+    private final MethodTypeDesc type;
+
+    AsTypeMethodHandleDesc(MethodHandleDesc underlying, MethodTypeDesc type) {
+        super(BSM_INVOKE, ConstantDescs.DEFAULT_NAME, CR_MethodHandle,
+              ConstantDescs.MHR_METHODHANDLE_ASTYPE, underlying, type);
+        this.underlying = requireNonNull(underlying);
+        this.type = requireNonNull(type);
+    }
+
+    @Override
+    @Foldable
+    public MethodTypeDesc methodType() {
+        return type;
+    }
+
+    @Override
+    public MethodHandle resolveConstantDesc(MethodHandles.Lookup lookup)
+            throws ReflectiveOperationException {
+        MethodHandle handle = underlying.resolveConstantDesc(lookup);
+        MethodType methodType = type.resolveConstantDesc(lookup);
+        return handle.asType(methodType);
+    }
+
+    @Override
+    public Optional<? extends ConstantDesc<ConstantDesc<MethodHandle>>> describeConstable() {
+        return ConstantUtils.symbolizeHelper(ConstantDescs.MHR_METHODHANDLEDESC_ASTYPE, ConstantDescs.CR_MethodHandleDesc,
+                                             underlying, type);
+    }
+
+    @Override
+    public String toString() {
+        return  String.format("%s.asType%s", underlying.toString(), type.displayDescriptor());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/ClassDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import jdk.internal.lang.annotation.Foldable;
+import java.lang.invoke.FieldTypeDescriptor;
+
+import java.util.stream.Stream;
+
+import sun.invoke.util.Wrapper;
+
+import static java.lang.constant.ConstantUtils.binaryToInternal;
+import static java.lang.constant.ConstantUtils.dropLastChar;
+import static java.lang.constant.ConstantUtils.internalToBinary;
+import static java.lang.constant.ConstantUtils.validateMemberName;
+import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.joining;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
+ * {@link Class} constant.
+ *
+ * <p>For common system types, including all the primitive types, there are
+ * predefined {@linkplain ClassDesc} constants in {@link ConstantDescs}.  To create
+ * a {@linkplain ClassDesc} for a class or interface type, use {@link #of} or
+ * {@link #ofDescriptor(String)}; to create a {@linkplain ClassDesc} for an array
+ * type, use {@link #ofDescriptor(String)}, or first obtain a
+ * {@linkplain ClassDesc} for the component type and then call the {@link #arrayType()}
+ * or {@link #arrayType(int)} methods.
+ *
+ * @see ConstantDescs
+ */
+public interface ClassDesc
+        extends ConstantDesc<Class<?>>,
+                Constable<ConstantDesc<Class<?>>>,
+                FieldTypeDescriptor<ClassDesc> {
+
+    /**
+     * Create a {@linkplain ClassDesc} given the name of a class or interface
+     * type, such as {@code "java.lang.String"}.  (To create a descriptor for an
+     * array type, either use {@link #ofDescriptor(String)}
+     * or {@link #arrayType()}; to create a descriptor for a primitive type, use
+     * {@link #ofDescriptor(String)} or use the predefined constants in
+     * {@link ConstantDescs}).
+     *
+     * @param name the fully qualified (dot-separated) binary class name
+     * @return a {@linkplain ClassDesc} describing the desired class
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IllegalArgumentException if the name string is not in the
+     * correct format
+     */
+    @Foldable
+    static ClassDesc of(String name) {
+        ConstantUtils.validateBinaryClassName(requireNonNull(name));
+        return ClassDesc.ofDescriptor("L" + binaryToInternal(name) + ";");
+    }
+
+    /**
+     * Create a {@linkplain ClassDesc} given a package name and an unqualified
+     * class name.
+     *
+     * @param packageName the package name (dot-separated)
+     * @param className the unqualified class name
+     * @return a {@linkplain ClassDesc} describing the desired class
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IllegalArgumentException if the package name or class name are
+     * not in the correct format
+     */
+    @Foldable
+    static ClassDesc of(String packageName, String className) {
+        ConstantUtils.validateBinaryClassName(requireNonNull(packageName));
+        validateMemberName(requireNonNull(className));
+        return ofDescriptor(String.format("L%s%s%s;",
+                                          binaryToInternal(packageName),
+                                          (packageName.length() > 0 ? "/" : ""),
+                                          className));
+    }
+
+    /**
+     * Create a {@linkplain ClassDesc} given a descriptor string.
+     *
+     * @param descriptor a field descriptor string, as per JVMS 4.3.2
+     * @return a {@linkplain ClassDesc} describing the desired class
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IllegalArgumentException if the name string is not in the
+     * correct format
+     * @jvms 4.3.2 Field Descriptors
+     */
+    @Foldable
+    static ClassDesc ofDescriptor(String descriptor) {
+        requireNonNull(descriptor);
+        return (descriptor.length() == 1)
+               ? new PrimitiveClassDesc(descriptor)
+               : new ConstantClassDesc(descriptor);
+    }
+
+    /**
+     * Create a {@linkplain ClassDesc} for an array type whose component type
+     * is described by this {@linkplain ClassDesc}.
+     *
+     * @return a {@linkplain ClassDesc} describing the array type
+     */
+    @Foldable
+    default ClassDesc arrayType() {
+        return arrayType(1);
+    }
+
+    /**
+     * Create a {@linkplain ClassDesc} for an array type of the specified rank,
+     * whose component type is described by this {@linkplain ClassDesc}.
+     *
+     * @param rank the rank of the array
+     * @return a {@linkplain ClassDesc} describing the array type
+     * @throws IllegalArgumentException if the rank is zero or negative
+     */
+    @Foldable
+    default ClassDesc arrayType(int rank) {
+        if (rank <= 0)
+            throw new IllegalArgumentException("rank: " + rank);
+        return ClassDesc.ofDescriptor("[".repeat(rank) + descriptorString());
+    }
+
+    /**
+     * Create a {@linkplain ClassDesc} for an inner class of the class or
+     * interface type described by this {@linkplain ClassDesc}.
+     *
+     * @param innerName the unqualified name of the inner class
+     * @return a {@linkplain ClassDesc} describing the inner class
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IllegalStateException if this {@linkplain ClassDesc} does not
+     * describe a class or interface type
+     */
+    @Foldable
+    default ClassDesc inner(String innerName) {
+        validateMemberName(innerName);
+        if (!isClassOrInterface())
+            throw new IllegalStateException("Outer class is not a class or interface type");
+        return ClassDesc.ofDescriptor(String.format("%s$%s;", dropLastChar(descriptorString()), innerName));
+    }
+
+    /**
+     * Create a {@linkplain ClassDesc} for an inner class of the class or
+     * interface type described by this {@linkplain ClassDesc}.
+     *
+     * @param firstInnerName the unqualified name of the first level of inner class
+     * @param moreInnerNames the unqualified name(s) of the remaining levels of
+     *                       inner class
+     * @return a {@linkplain ClassDesc} describing the inner class
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IllegalStateException if this {@linkplain ClassDesc} does not
+     * describe a class or interface type
+     */
+    @Foldable
+    default ClassDesc inner(String firstInnerName, String... moreInnerNames) {
+        if (!isClassOrInterface())
+            throw new IllegalStateException("Outer class is not a class or interface type");
+        return moreInnerNames.length == 0
+               ? inner(firstInnerName)
+               : inner(firstInnerName + Stream.of(moreInnerNames).collect(joining("$", "$", "")));
+    }
+
+    /**
+     * Returns whether this {@linkplain ClassDesc} describes an array type.
+     *
+     * @return whether this {@linkplain ClassDesc} describes an array type
+     */
+    default boolean isArray() {
+        return descriptorString().startsWith("[");
+    }
+
+    /**
+     * Returns whether this {@linkplain ClassDesc} describes a primitive type.
+     *
+     * @return whether this {@linkplain ClassDesc} describes a primitive type
+     */
+    default boolean isPrimitive() {
+        return descriptorString().length() == 1;
+    }
+
+    /**
+     * Returns whether this {@linkplain ClassDesc} describes a class or interface type.
+     *
+     * @return whether this {@linkplain ClassDesc} describes a class or interface type
+     */
+    default boolean isClassOrInterface() {
+        return descriptorString().startsWith("L");
+    }
+
+    /**
+     * Returns the component type of this {@linkplain ClassDesc}, if it describes
+     * an array type, or {@code null} otherwise.
+     *
+     * @return a {@linkplain ClassDesc} describing the component type, or {@code null}
+     * if this descriptor does not describe an array type
+     */
+    @Foldable
+    default ClassDesc componentType() {
+        return isArray() ? ClassDesc.ofDescriptor(descriptorString().substring(1)) : null;
+    }
+
+    /**
+     * Returns the package name of this {@linkplain ClassDesc}, if it describes
+     * a class or interface type.
+     *
+     * @return the package name, or the empty string if the class is in the
+     * default package
+     * @throws IllegalStateException if this {@linkplain ClassDesc} does not
+     * describe a class or interface type
+     */
+    default String packageName() {
+        if (!isClassOrInterface())
+            throw new IllegalStateException("not a class or interface");
+        String className = internalToBinary(ConstantUtils.dropFirstAndLastChar(descriptorString()));
+        int index = className.lastIndexOf('.');
+        return (index == -1) ? "" : className.substring(0, index);
+    }
+
+    /**
+     * Returns a human-readable name for the type described by this descriptor.
+     *
+     * @return the human-readable name
+     */
+    default String displayName() {
+        if (isPrimitive())
+            return Wrapper.forBasicType(descriptorString().charAt(0)).primitiveSimpleName();
+        else if (isClassOrInterface()) {
+            return descriptorString().substring(Math.max(1, descriptorString().lastIndexOf('/') + 1),
+                                                descriptorString().length() - 1);
+        }
+        else if (isArray()) {
+            int depth = ConstantUtils.arrayDepth(descriptorString());
+            ClassDesc c = this;
+            for (int i=0; i<depth; i++)
+                c = c.componentType();
+            return c.displayName() + "[]".repeat(depth);
+        }
+        else
+            throw new IllegalStateException(descriptorString());
+    }
+
+    /**
+     * Return a field type descriptor string for this type, as per JVMS 4.3.2
+     *
+     * @return the descriptor string
+     * @jvms 4.3.2 Field Descriptors
+     */
+    @Foldable
+    String descriptorString();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/Constable.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle;
+import java.util.Optional;
+
+/**
+ * Represents a type which is <em>constable</em>.  A constable type is one whose
+ * values are constants that can be represented in the constant pool of a Java
+ * classfile as described in JVMS 4.4, and whose instances can describe themselves
+ * nominally as a {@link ConstantDesc}.
+ *
+ * <p>Some constable types have a native representation in the constant pool:
+ * {@link String}, {@link Integer}, {@link Long}, {@link Float},
+ * {@link Double}, {@link Class}, {@link MethodType}, and {@link MethodHandle}.
+ * The types {@link String}, {@link Integer}, {@link Long}, {@link Float},
+ * and {@link Double} serve as their own nominal descriptors; {@link Class},
+ * {@link MethodType}, and {@link MethodHandle} have corresponding nominal
+ * descriptors {@link ClassDesc}, {@link MethodTypeDesc}, and {@link MethodHandleDesc}.
+ *
+ * <p>Other reference types can be constable if their instances can describe
+ * themselves in nominal form as a {@link ConstantDesc}. Examples in the Java SE
+ * Platform API are types that support Java language features such as {@link Enum},
+ * and runtime support classes such as {@link VarHandle}.  These are typically
+ * described with a {@link DynamicConstantDesc}, which describes dynamically
+ * generated constants (JVMS 4.4.10).
+ *
+ * <p>The nominal form of an instance of a constable type is obtained via
+ * {@link #describeConstable()}. A {@linkplain Constable} need
+ * not be able to (or may choose not to) describe all its instances in the form of
+ * a {@link ConstantDesc}; this method returns an {@link Optional} that can be
+ * empty to indicate that a nominal descriptor could not be created for an instance.
+ * (For example, {@link MethodHandle} will produce nominal descriptors for direct
+ * method handles, but not necessarily those produced by method handles
+ * combinators.)
+ * @jvms 4.4 The Constant Pool
+ * @jvms 4.4.10 The CONSTANT_InvokeDynamic_info Structure
+ *
+ * @param <T> the type of the constant value
+ */
+public interface Constable<T> {
+    /**
+     * Return a nominal descriptor for this instance, if one can be
+     * constructed, or an empty {@link Optional} if one cannot be.
+     *
+     * @return An {@link Optional} containing the resulting nominal descriptor,
+     * or an empty {@link Optional} if one cannot be constructed.
+     */
+    Optional<? extends ConstantDesc<T>> describeConstable();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/ConstantClassDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Objects;
+import java.util.Optional;
+
+import static java.lang.constant.ConstantDescs.BSM_CLASSDESC;
+import static java.lang.constant.ConstantDescs.CR_ClassDesc;
+import static java.lang.constant.ConstantUtils.dropFirstAndLastChar;
+import static java.lang.constant.ConstantUtils.internalToBinary;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a class,
+ * interface, or array type.  A {@linkplain ConstantClassDesc} corresponds to a
+ * {@code Constant_Class_info} entry in the constant pool of a classfile.
+ */
+public final class ConstantClassDesc implements ClassDesc {
+    private final String descriptor;
+
+    /**
+     * Create a {@linkplain ClassDesc} from a descriptor string for a class or
+     * interface type
+     *
+     * @param descriptor a field descriptor string for a class or interface type,
+     *                   as per JVMS 4.3.2
+     * @throws IllegalArgumentException if the descriptor string is not a valid
+     * field descriptor string, or does not describe a class or interface type
+     * @jvms 4.3.2 Field Descriptors
+     */
+    ConstantClassDesc(String descriptor) {
+        requireNonNull(descriptor);
+        int len = ConstantUtils.matchSig(descriptor, 0, descriptor.length());
+        if (len == 0 || len == 1
+            || len != descriptor.length())
+            throw new IllegalArgumentException(String.format("not a valid reference type descriptor: %s", descriptor));
+        this.descriptor = descriptor;
+    }
+
+    @Override
+    public String descriptorString() {
+        return descriptor;
+    }
+
+    @Override
+    public Class<?> resolveConstantDesc(MethodHandles.Lookup lookup)
+            throws ReflectiveOperationException {
+        ClassDesc c = this;
+        int depth = ConstantUtils.arrayDepth(descriptorString());
+        for (int i=0; i<depth; i++)
+            c = c.componentType();
+
+        if (c.isPrimitive())
+            return lookup.findClass(descriptorString());
+        else {
+            Class<?> clazz = lookup.findClass(internalToBinary(dropFirstAndLastChar(c.descriptorString())));
+            for (int i = 0; i < depth; i++)
+                clazz = clazz.arrayType();
+            return clazz;
+        }
+    }
+
+    @Override
+    public Optional<? extends ConstantDesc<ConstantDesc<Class<?>>>> describeConstable() {
+        return Optional.of(DynamicConstantDesc.<ConstantDesc<Class<?>>>of(BSM_CLASSDESC, CR_ClassDesc)
+                                   .withArgs(descriptor));
+    }
+
+    /**
+     * Constant bootstrap method for representing a {@linkplain ClassDesc} in
+     * the constant pool of a classfile.
+     *
+     * @param lookup ignored
+     * @param name ignored
+     * @param clazz ignored
+     * @param descriptor a field descriptor string for the class, as per JVMS 4.3.2
+     * @return the {@linkplain ClassDesc}
+     * @jvms 4.3.2 Field Descriptors
+     */
+    public static ClassDesc constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
+                                              String descriptor) {
+        return ClassDesc.ofDescriptor(descriptor);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ClassDesc constant = (ClassDesc) o;
+        return Objects.equals(descriptor, constant.descriptorString());
+    }
+
+    @Override
+    public int hashCode() {
+        return descriptor != null ? descriptor.hashCode() : 0;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("ClassDesc[%s]", displayName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/ConstantDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.lang.invoke.Intrinsics;
+import java.lang.Enum.EnumDesc;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle.VarHandleDesc;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a loadable
+ * constant value, as defined in JVMS 4.4. Such a descriptor can be resolved via
+ * {@link ConstantDesc#resolveConstantDesc(MethodHandles.Lookup)} to yield the
+ * constant value itself.
+ *
+ * <p>Class names in a nominal descriptor, like class names in the constant pool
+ * of a classfile, must be interpreted with respect to a particular to a class
+ * loader, which is not part of the nominal descriptor.
+ *
+ * <p>Static constants that are expressible natively in the constant pool ({@link String},
+ * {@link Integer}, {@link Long}, {@link Float}, and {@link Double}) implement
+ * {@link ConstantDesc}, and serve as nominal descriptors for themselves.
+ * Native linkable constants ({@link Class}, {@link MethodType}, and
+ * {@link MethodHandle}) have counterpart {@linkplain ConstantDesc} types:
+ * {@link ClassDesc}, {@link MethodTypeDesc}, and {@link MethodHandleDesc}.
+ * Other constants are represented by subtypes of {@link DynamicConstantDesc}.
+ *
+ * <p>APIs that perform generation or parsing of bytecode are encouraged to use
+ * {@linkplain ConstantDesc} to describe the operand of an {@code ldc} instruction
+ * (including dynamic constants), the static bootstrap arguments of
+ * dynamic constants and {@code invokedynamic} instructions, and other
+ * bytecodes or classfile structures that make use of the constant pool.
+ *
+ * <p>The {@linkplain ConstantDesc} types are also used by {@link Intrinsics}
+ * to express {@code ldc} instructions.
+ *
+ * <p>Constants describing various common constants (such as {@link ClassDesc}
+ * instances for platform types) can be found in {@link ConstantDescs}.
+ *
+ * <p>Implementations of {@linkplain ConstantDesc} must be
+ * <a href="../doc-files/ValueBased.html">value-based</a> classes.
+ *
+ * <p>Non-platform classes should not implement {@linkplain ConstantDesc} directly.
+ * Instead, they should extend {@link DynamicConstantDesc} (as {@link EnumDesc}
+ * and {@link VarHandleDesc} do.)
+ *
+ * <p>Nominal descriptors should be compared using the
+ * {@link Object#equals(Object)} method. There is no guarantee that any
+ * particular entity will always be represented by the same descriptor instance.
+ *
+ * @apiNote In the future, if the Java language permits, {@linkplain ConstantDesc}
+ * may become a {@code sealed} interface, which would prohibit subclassing except by
+ * explicitly permitted types.  Clients can assume that the following
+ * set of concrete subtypes is exhaustive: {@link String}, {@link Integer},
+ * {@link Long}, {@link Float}, {@link Double}, {@link ConstantClassDesc},
+ * {@link ConstantMethodTypeDesc}, {@link ConstantMethodHandleDesc}, and
+ * {@link DynamicConstantDesc}; this list may be extended to reflect future
+ * changes to the constant pool format as defined in JVMS 4.4.
+ *
+ * @see Constable
+ * @see Intrinsics
+ * @see ConstantDescs
+ *
+ * @jvms 4.4 The Constant Pool
+ */
+public interface ConstantDesc<T> {
+    /**
+     * Resolve this descriptor reflectively, emulating the resolution behavior
+     * of JVMS 5.4.3 and the access control behavior of JVMS 5.4.4.  The resolution
+     * and access control context is provided by the {@link MethodHandles.Lookup}
+     * parameter.  No caching of the resulting value is performed.
+     *
+     * @param lookup The {@link MethodHandles.Lookup} to provide name resolution
+     *               and access control context
+     * @return the resolved constant value
+     * @throws ReflectiveOperationException if a class, method, or field
+     * could not be reflectively resolved in the course of resolution
+     * @jvms 5.4.3 Resolution
+     * @jvms 5.4.4 Access Control
+     */
+    T resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/ConstantDescs.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import jdk.internal.lang.annotation.Foldable;
+
+import java.lang.Enum.EnumDesc;
+import java.lang.invoke.CallSite;
+import java.lang.invoke.ConstantBootstraps;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.VarHandle;
+import java.lang.invoke.VarHandle.VarHandleDesc;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static java.lang.constant.MethodHandleDesc.Kind.STATIC;
+
+/**
+ * Predefined values of <a href="package-summary.html#nominal">nominal descriptor</a>
+ * for common constants, including descriptors for primitive class types and
+ * other common platform types, and descriptors for method handles for standard
+ * bootstrap methods.
+ *
+ * @see ConstantDesc
+ */
+public final class ConstantDescs {
+    // No instances
+    private ConstantDescs() { }
+
+    /** Invocation name to use when no name is needed, such as the name of a
+     * constructor, or the invocation name of a dynamic constant or dynamic
+     * callsite when the bootstrap is known to ignore the invocation name.
+     */
+    public static final String DEFAULT_NAME = "_";
+
+    // Don't change the order of these declarations!
+
+    /** {@link ClassDesc} representing {@link Object} */
+    @Foldable
+    public static final ClassDesc CR_Object = ClassDesc.of("java.lang.Object");
+
+    /** {@link ClassDesc} representing {@link String} */
+    @Foldable
+    public static final ClassDesc CR_String = ClassDesc.of("java.lang.String");
+
+    /** {@link ClassDesc} representing {@link Class} */
+    @Foldable
+    public static final ClassDesc CR_Class = ClassDesc.of("java.lang.Class");
+
+    /** {@link ClassDesc} representing {@link Number} */
+    @Foldable
+    public static final ClassDesc CR_Number = ClassDesc.of("java.lang.Number");
+
+    /** {@link ClassDesc} representing {@link Integer} */
+    @Foldable
+    public static final ClassDesc CR_Integer = ClassDesc.of("java.lang.Integer");
+
+    /** {@link ClassDesc} representing {@link Long} */
+    @Foldable
+    public static final ClassDesc CR_Long = ClassDesc.of("java.lang.Long");
+
+    /** {@link ClassDesc} representing {@link Float} */
+    @Foldable
+    public static final ClassDesc CR_Float = ClassDesc.of("java.lang.Float");
+
+    /** {@link ClassDesc} representing {@link Double} */
+    @Foldable
+    public static final ClassDesc CR_Double = ClassDesc.of("java.lang.Double");
+
+    /** {@link ClassDesc} representing {@link Short} */
+    @Foldable
+    public static final ClassDesc CR_Short = ClassDesc.of("java.lang.Short");
+
+    /** {@link ClassDesc} representing {@link Byte} */
+    @Foldable
+    public static final ClassDesc CR_Byte = ClassDesc.of("java.lang.Byte");
+
+    /** {@link ClassDesc} representing {@link Character} */
+    @Foldable
+    public static final ClassDesc CR_Character = ClassDesc.of("java.lang.Character");
+
+    /** {@link ClassDesc} representing {@link Boolean} */
+    @Foldable
+    public static final ClassDesc CR_Boolean = ClassDesc.of("java.lang.Boolean");
+
+    /** {@link ClassDesc} representing {@link Void} */
+    @Foldable
+    public static final ClassDesc CR_Void = ClassDesc.of("java.lang.Void");
+
+    /** {@link ClassDesc} representing {@link Throwable} */
+    @Foldable
+    public static final ClassDesc CR_Throwable = ClassDesc.of("java.lang.Throwable");
+
+    /** {@link ClassDesc} representing {@link Exception} */
+    @Foldable
+    public static final ClassDesc CR_Exception = ClassDesc.of("java.lang.Exception");
+
+    /** {@link ClassDesc} representing {@link Enum} */
+    @Foldable
+    public static final ClassDesc CR_Enum = ClassDesc.of("java.lang.Enum");
+
+    /** {@link ClassDesc} representing {@link VarHandle} */
+    @Foldable
+    public static final ClassDesc CR_VarHandle = ClassDesc.of("java.lang.invoke.VarHandle");
+
+    /** {@link ClassDesc} representing {@link MethodHandles} */
+    @Foldable
+    public static final ClassDesc CR_MethodHandles = ClassDesc.of("java.lang.invoke.MethodHandles");
+
+    /** {@link ClassDesc} representing {@link MethodHandles.Lookup} */
+    @Foldable
+    public static final ClassDesc CR_MethodHandles_Lookup = CR_MethodHandles.inner("Lookup");
+
+    /** {@link ClassDesc} representing {@link MethodHandle} */
+    @Foldable
+    public static final ClassDesc CR_MethodHandle = ClassDesc.of("java.lang.invoke.MethodHandle");
+
+    /** {@link ClassDesc} representing {@link MethodType} */
+    @Foldable
+    public static final ClassDesc CR_MethodType = ClassDesc.of("java.lang.invoke.MethodType");
+
+    /** {@link ClassDesc} representing {@link CallSite} */
+    @Foldable
+    public static final ClassDesc CR_CallSite = ClassDesc.of("java.lang.invoke.CallSite");
+
+    /** {@link ClassDesc} representing {@link Collection} */
+    @Foldable
+    public static final ClassDesc CR_Collection = ClassDesc.of("java.util.Collection");
+
+    /** {@link ClassDesc} representing {@link List} */
+    @Foldable
+    public static final ClassDesc CR_List = ClassDesc.of("java.util.List");
+
+    /** {@link ClassDesc} representing {@link Set} */
+    @Foldable
+    public static final ClassDesc CR_Set = ClassDesc.of("java.util.Set");
+
+    /** {@link ClassDesc} representing {@link Map} */
+    @Foldable
+    public static final ClassDesc CR_Map = ClassDesc.of("java.util.Map");
+
+    /** {@link ClassDesc} representing {@link ConstantDesc} */
+    @Foldable
+    public static final ClassDesc CR_ConstantDesc = ClassDesc.of("java.lang.constant.ConstantDesc");
+
+    /** {@link ClassDesc} representing {@link ClassDesc} */
+    @Foldable
+    public static final ClassDesc CR_ClassDesc = ClassDesc.of("java.lang.constant.ClassDesc");
+
+    /** {@link ClassDesc} representing {@link EnumDesc} */
+    @Foldable
+    public static final ClassDesc CR_EnumDesc = CR_Enum.inner("EnumDesc");
+
+    /** {@link ClassDesc} representing {@link MethodTypeDesc} */
+    @Foldable
+    public static final ClassDesc CR_MethodTypeDesc = ClassDesc.of("java.lang.constant.MethodTypeDesc");
+
+    /** {@link ClassDesc} representing {@link ConstantClassDesc} */
+    public static final ClassDesc CR_ConstantClassDesc = ClassDesc.of("java.lang.constant.ConstantClassDesc");
+
+    /** {@link ClassDesc} representing {@link ConstantMethodTypeDesc} */
+    @Foldable
+    public static final ClassDesc CR_ConstantMethodTypeDesc = ClassDesc.of("java.lang.constant.ConstantMethodTypeDesc");
+
+    /** {@link ClassDesc} representing {@link MethodHandleDesc} */
+    @Foldable
+    public static final ClassDesc CR_MethodHandleDesc = ClassDesc.of("java.lang.constant.MethodHandleDesc");
+
+    /** {@link ClassDesc} representing {@link ConstantMethodHandleDesc} */
+    @Foldable
+    public static final ClassDesc CR_ConstantMethodHandleDesc = ClassDesc.of("java.lang.constant.ConstantMethodHandleDesc");
+
+    /** {@link ClassDesc} representing {@link VarHandleDesc} */
+    @Foldable
+    public static final ClassDesc CR_VarHandleDesc = CR_VarHandle.inner("VarHandleDesc");
+
+    /** {@link ClassDesc} representing {@link MethodHandleDesc.Kind} */
+    @Foldable
+    public static final ClassDesc CR_MethodHandleDesc_Kind = CR_MethodHandleDesc.inner("Kind");
+
+    /** {@link ClassDesc} representing {@link DynamicConstantDesc} */
+    @Foldable
+    public static final ClassDesc CR_DynamicConstantDesc = ClassDesc.of("java.lang.constant.DynamicConstantDesc");
+
+    /** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */
+    @Foldable
+    public static final ClassDesc CR_DynamicCallSiteDesc = ClassDesc.of("java.lang.constant.DynamicCallSiteDesc");
+
+    /** {@link ClassDesc} representing {@link ConstantBootstraps} */
+    @Foldable
+    public static final ClassDesc CR_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
+
+    // Used by MethodHandleDesc, but initialized here before reference to
+    // MethodHandleDesc to avoid static initalization circularities
+    /* non-public */ static final ClassDesc[] INDY_BOOTSTRAP_ARGS = {
+            ConstantDescs.CR_MethodHandles_Lookup,
+            ConstantDescs.CR_String,
+            ConstantDescs.CR_MethodType };
+
+    /* non-public */ static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = {
+            ConstantDescs.CR_MethodHandles_Lookup,
+            ConstantDescs.CR_String,
+            ConstantDescs.CR_Class };
+
+    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#primitiveClass(Lookup, String, Class)} */
+    @Foldable
+    public static final ConstantMethodHandleDesc BSM_PRIMITIVE_CLASS
+            = ofConstantBootstrap(CR_ConstantBootstraps, "primitiveClass",
+                                  CR_Class);
+
+    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#enumConstant(Lookup, String, Class)} */
+    @Foldable
+    public static final ConstantMethodHandleDesc BSM_ENUM_CONSTANT
+            = ofConstantBootstrap(CR_ConstantBootstraps, "enumConstant",
+                                  CR_Enum);
+
+    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#nullConstant(Lookup, String, Class)} */
+    @Foldable
+    public static final ConstantMethodHandleDesc BSM_NULL_CONSTANT
+            = ofConstantBootstrap(CR_ConstantBootstraps, "nullConstant",
+                                  ConstantDescs.CR_Object);
+
+    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#fieldVarHandle(Lookup, String, Class, Class, Class)} */
+    @Foldable
+    public static final ConstantMethodHandleDesc BSM_VARHANDLE_FIELD
+            = ofConstantBootstrap(CR_ConstantBootstraps, "fieldVarHandle",
+                                  CR_VarHandle, CR_Class, CR_Class);
+
+    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#staticFieldVarHandle(Lookup, String, Class, Class, Class)} */
+    @Foldable
+    public static final ConstantMethodHandleDesc BSM_VARHANDLE_STATIC_FIELD
+            = ofConstantBootstrap(CR_ConstantBootstraps, "staticFieldVarHandle",
+                                  CR_VarHandle, CR_Class, CR_Class);
+
+    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#arrayVarHandle(Lookup, String, Class, Class)} */
+    @Foldable
+    public static final ConstantMethodHandleDesc BSM_VARHANDLE_ARRAY
+            = ofConstantBootstrap(CR_ConstantBootstraps, "arrayVarHandle",
+                                  CR_VarHandle, CR_Class);
+
+    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#invoke(Lookup, String, Class, MethodHandle, Object...)} */
+    @Foldable
+    public static final ConstantMethodHandleDesc BSM_INVOKE
+            = ofConstantBootstrap(CR_ConstantBootstraps, "invoke",
+                                  CR_Object, CR_MethodHandle, CR_Object.arrayType());
+
+    /** {@link ClassDesc} representing the primitive type {@code int} */
+    @Foldable
+    public static final ClassDesc CR_int = ClassDesc.ofDescriptor("I");
+
+    /** {@link ClassDesc} representing the primitive type {@code long} */
+    @Foldable
+    public static final ClassDesc CR_long = ClassDesc.ofDescriptor("J");
+
+    /** {@link ClassDesc} representing the primitive type {@code float} */
+    @Foldable
+    public static final ClassDesc CR_float = ClassDesc.ofDescriptor("F");
+
+    /** {@link ClassDesc} representing the primitive type {@code double} */
+    @Foldable
+    public static final ClassDesc CR_double = ClassDesc.ofDescriptor("D");
+
+    /** {@link ClassDesc} representing the primitive type {@code short} */
+    @Foldable
+    public static final ClassDesc CR_short = ClassDesc.ofDescriptor("S");
+
+    /** {@link ClassDesc} representing the primitive type {@code byte} */
+    @Foldable
+    public static final ClassDesc CR_byte = ClassDesc.ofDescriptor("B");
+
+    /** {@link ClassDesc} representing the primitive type {@code char} */
+    @Foldable
+    public static final ClassDesc CR_char = ClassDesc.ofDescriptor("C");
+
+    /** {@link ClassDesc} representing the primitive type {@code boolean} */
+    @Foldable
+    public static final ClassDesc CR_boolean = ClassDesc.ofDescriptor("Z");
+
+    /** {@link ClassDesc} representing the primitive type {@code void} */
+    @Foldable
+    public static final ClassDesc CR_void = ClassDesc.ofDescriptor("V");
+
+    /** Nominal descriptor representing the constant {@code null} */
+    @Foldable
+    public static final ConstantDesc<?> NULL
+            = DynamicConstantDesc.of(ConstantDescs.BSM_NULL_CONSTANT,
+                                     ConstantDescs.CR_Object);
+
+    // Used by XxxDesc classes, but need to be here to avoid bootstrap cycles
+    static final ConstantMethodHandleDesc MHR_METHODTYPEDESC_FACTORY
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_MethodTypeDesc, "ofDescriptor",
+                                  CR_MethodTypeDesc, CR_String);
+
+    static final ConstantMethodHandleDesc MHR_CLASSDESC_FACTORY
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_ClassDesc, "ofDescriptor",
+                                  CR_ClassDesc, CR_String);
+
+    static final ConstantMethodHandleDesc MHR_METHODHANDLEDESC_FACTORY
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_MethodHandleDesc, "of",
+                                  CR_MethodHandleDesc, CR_MethodHandleDesc_Kind, CR_ClassDesc, CR_String, CR_MethodTypeDesc);
+
+    static final ConstantMethodHandleDesc MHR_METHODHANDLE_ASTYPE
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_MethodHandle, "asType",
+                                  CR_MethodHandle, CR_MethodType);
+
+    static final ConstantMethodHandleDesc MHR_METHODHANDLEDESC_ASTYPE
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_MethodHandleDesc, "asType",
+                                  CR_MethodHandleDesc, CR_MethodTypeDesc);
+
+    static final ConstantMethodHandleDesc MHR_DYNAMICCONSTANTDESC_FACTORY
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_DynamicConstantDesc, "of",
+                                  CR_DynamicConstantDesc, CR_MethodHandleDesc, CR_String, CR_ClassDesc);
+
+    static final ConstantMethodHandleDesc MHR_DYNAMICCONSTANTDESC_WITHARGS
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_DynamicConstantDesc, "withArgs",
+                                  CR_DynamicConstantDesc, CR_ConstantDesc.arrayType());
+
+    static final ConstantMethodHandleDesc MHR_ENUMDESC_FACTORY
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_EnumDesc, "of",
+                                  CR_EnumDesc, CR_ClassDesc, CR_String);
+
+    /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofField(Lookup, String, Class, Class, String, Class)} */
+    public static final ConstantMethodHandleDesc MHR_VARHANDLEDESC_OFFIELD
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofField",
+                                  CR_VarHandleDesc, CR_ClassDesc, CR_String, CR_ClassDesc);
+    /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofStaticField(Lookup, String, Class, Class, String, Class)} */
+    public static final ConstantMethodHandleDesc MHR_VARHANDLEDESC_OFSTATIC
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofStaticField",
+                                  CR_VarHandleDesc, CR_ClassDesc, CR_String, CR_ClassDesc);
+
+    /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofArray(Lookup, String, Class, Class, Class)} */
+    public static final ConstantMethodHandleDesc MHR_VARHANDLEDESC_OFARRAY
+            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofArray",
+                                  CR_VarHandleDesc, CR_ClassDesc);
+
+    static final ConstantMethodHandleDesc BSM_CLASSDESC
+            = ConstantDescs.ofConstantBootstrap(CR_ConstantClassDesc,
+                                                "constantBootstrap", CR_ClassDesc, CR_String);
+
+    static final ConstantMethodHandleDesc BSM_METHODTYPEDESC
+            = ConstantDescs.ofConstantBootstrap(CR_ConstantMethodTypeDesc,
+                                                "constantBootstrap", CR_ConstantMethodTypeDesc, CR_String);
+
+    static final ConstantMethodHandleDesc BSM_METHODHANDLEDESC
+            = ConstantDescs.ofConstantBootstrap(CR_ConstantMethodHandleDesc,
+                                                "constantBootstrap", CR_ConstantMethodHandleDesc,
+                                                CR_String, CR_String, CR_String, CR_String);
+
+    /** {@link MethodHandleDesc} representing {@link EnumDesc#constantBootstrap(Lookup, String, Class, String, String)} */
+    public static final ConstantMethodHandleDesc BSM_ENUMDESC
+            = ConstantDescs.ofConstantBootstrap(CR_EnumDesc, "constantBootstrap", CR_EnumDesc, CR_String, CR_String);
+
+    static final ConstantMethodHandleDesc BSM_DYNAMICCONSTANTDESC
+            = ConstantDescs.ofConstantBootstrap(CR_DynamicConstantDesc,
+                                                "constantBootstrap",
+                                                CR_DynamicConstantDesc,
+                                                CR_String, CR_String, CR_String, CR_String, CR_String, CR_ConstantDesc.arrayType());
+
+
+    /**
+     * Return a {@link MethodHandleDesc} corresponding to a bootstrap method for
+     * an {@code invokedynamic} callsite, which is a static method whose leading
+     * parameter types are {@code Lookup}, {@code String}, and {@code MethodType}.
+     *
+     * @param clazz the class declaring the method
+     * @param name the name of the method, as per JVMS 4.2.2
+     * @param returnType the return type of the method
+     * @param paramTypes the types of the static bootstrap arguments, if any
+     * @return the {@link MethodHandleDesc}
+     * @throws NullPointerException if any of the arguments are null
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    public static ConstantMethodHandleDesc ofCallsiteBootstrap(ClassDesc clazz,
+                                                               String name,
+                                                               ClassDesc returnType,
+                                                               ClassDesc... paramTypes) {
+        return MethodHandleDesc.of(STATIC, clazz, name, MethodTypeDesc.of(returnType, paramTypes).insertParameterTypes(0, INDY_BOOTSTRAP_ARGS));
+    }
+
+    /**
+     * Return a {@link MethodHandleDesc} corresponding to a bootstrap method for a
+     * dynamic constant, which is a static method whose leading arguments are
+     * {@code Lookup}, {@code String}, and {@code Class}.
+     *
+     * @param clazz the class declaring the method
+     * @param name the name of the method, as per JVMS 4.2.2
+     * @param returnType the return type of the method
+     * @param paramTypes the types of the static bootstrap arguments, if any
+     * @return the {@link MethodHandleDesc}
+     * @throws NullPointerException if any of the arguments are null
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    public static ConstantMethodHandleDesc ofConstantBootstrap(ClassDesc clazz,
+                                                               String name,
+                                                               ClassDesc returnType,
+                                                               ClassDesc... paramTypes) {
+        return MethodHandleDesc.of(STATIC, clazz, name, MethodTypeDesc.of(returnType, paramTypes).insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/ConstantMethodHandleDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,240 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.Objects;
+import java.util.Optional;
+
+import jdk.internal.lang.annotation.Foldable;
+
+import static java.lang.constant.ConstantDescs.BSM_METHODHANDLEDESC;
+import static java.lang.constant.ConstantDescs.CR_ConstantMethodHandleDesc;
+import static java.lang.constant.ConstantUtils.validateClassOrInterface;
+import static java.lang.constant.ConstantUtils.validateMemberName;
+import static java.lang.constant.MethodHandleDesc.Kind.CONSTRUCTOR;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a direct
+ * {@link MethodHandle}.  A {@linkplain ConstantMethodHandleDesc} corresponds to
+ * a {@code Constant_MethodHandle_info} entry in the constant pool of a classfile.
+ */
+public final class ConstantMethodHandleDesc implements MethodHandleDesc {
+
+    private final Kind kind;
+    private final ClassDesc owner;
+    private final String name;
+    private final MethodTypeDesc type;
+
+    /**
+     * Construct a {@linkplain ConstantMethodHandleDesc} for a method or field
+     * from a kind, owner, name, and type
+     *
+     * @param kind the kind of the method handle
+     * @param owner the declaring class or interface for the method
+     * @param name the name of the method (ignored if {@code kind} is
+     * {@code CONSTRUCTOR}), as per JVMS 4.2.2
+     * @param type the type of the method
+     * @throws NullPointerException if any non-ignored argument is null
+     * @throws IllegalArgumentException if {@code kind} describes a field accessor,
+     * and {@code type} is not consistent with that kind of field accessor, or if
+     * {@code kind} describes a constructor, and the return type of {@code type}
+     * is not {@code void}
+     * @jvms 4.2.2 Unqualified Names
+     */
+    ConstantMethodHandleDesc(Kind kind, ClassDesc owner, String name, MethodTypeDesc type) {
+        if (kind == CONSTRUCTOR)
+            name = "<init>";
+
+        requireNonNull(kind);
+        validateClassOrInterface(requireNonNull(owner));
+        validateMemberName(requireNonNull(name));
+        requireNonNull(type);
+
+        switch (kind) {
+            case CONSTRUCTOR: validateConstructor(type); break;
+            case GETTER: validateFieldType(type, false, true); break;
+            case SETTER: validateFieldType(type, true, true); break;
+            case STATIC_GETTER: validateFieldType(type, false, false); break;
+            case STATIC_SETTER: validateFieldType(type, true, false); break;
+        }
+
+        this.kind = kind;
+        this.owner = owner;
+        this.name = name;
+        this.type = type;
+    }
+
+    private static void validateFieldType(MethodTypeDesc type, boolean isSetter, boolean isVirtual) {
+        boolean isVoid = type.returnType().descriptorString().equals("V");
+        int expectedParams = (isSetter ? 1 : 0) + (isVirtual ? 1 : 0);
+        if (isVoid != isSetter
+            || type.parameterCount() != expectedParams
+            || (isVirtual && type.parameterType(0).isPrimitive())) {
+            String expectedType = String.format("(%s%s)%s", (isVirtual ? "R" : ""),
+                                                (isSetter ? "T" : ""), (isSetter ? "V" : "T"));
+            throw new IllegalArgumentException(String.format("Expected type of %s for getter, found %s", expectedType, type));
+        }
+    }
+
+    private static void validateConstructor(MethodTypeDesc type) {
+        if (!type.returnType().descriptorString().equals("V")) {
+            throw new IllegalArgumentException(String.format("Expected type of (T*)V for constructor, found %s", type));
+        }
+    }
+
+    /**
+     * Return the {@code kind} of the method handle described by this nominal
+     * descriptor.
+     *
+     * @return the {@link Kind}
+     */
+    @Foldable
+    public Kind kind() { return kind; }
+
+    /**
+     * Return the {@code refKind} of the method handle described by this nominal
+     * reference, as defined by {@link MethodHandleInfo}.
+     *
+     * @return the reference kind
+     */
+    @Foldable
+    public int refKind() { return kind.refKind; }
+
+    /**
+     * Return a {@link ClassDesc} describing the class declaring the
+     * method or field described by this nominal descriptor.
+     *
+     * @return the class declaring the method or field
+     */
+    @Foldable
+    public ClassDesc owner() {
+        return owner;
+    }
+
+    /**
+     * Return the name of the method or field described by this nominal descriptor.
+     *
+     * @return the name of the method or field
+     */
+    @Foldable
+    public String methodName() {
+        return name;
+    }
+
+    /**
+     * Return a {@link MethodTypeDesc} describing the invocation type of the
+     * method handle described by this nominal descriptor
+     *
+     * @return the method type
+     */
+    @Foldable
+    public MethodTypeDesc methodType() {
+        return type;
+    }
+
+    public MethodHandle resolveConstantDesc(MethodHandles.Lookup lookup)
+            throws ReflectiveOperationException {
+        Class<?> resolvedOwner = owner.resolveConstantDesc(lookup);
+        MethodType resolvedType = this.type.resolveConstantDesc(lookup);
+        switch (kind) {
+            case STATIC:
+                return lookup.findStatic(resolvedOwner, name, resolvedType);
+            case INTERFACE_VIRTUAL:
+            case VIRTUAL:
+                return lookup.findVirtual(resolvedOwner, name, resolvedType);
+            case SPECIAL:
+                return lookup.findSpecial(resolvedOwner, name, resolvedType, lookup.lookupClass());
+            case CONSTRUCTOR:
+                return lookup.findConstructor(resolvedOwner, resolvedType);
+            case GETTER:
+                return lookup.findGetter(resolvedOwner, name, resolvedType.returnType());
+            case STATIC_GETTER:
+                return lookup.findStaticGetter(resolvedOwner, name, resolvedType.returnType());
+            case SETTER:
+                return lookup.findSetter(resolvedOwner, name, resolvedType.parameterType(1));
+            case STATIC_SETTER:
+                return lookup.findStaticSetter(resolvedOwner, name, resolvedType.parameterType(0));
+            default:
+                throw new IllegalStateException(kind.name());
+        }
+    }
+
+    @Override
+    public Optional<? extends ConstantDesc<ConstantDesc<MethodHandle>>> describeConstable() {
+        return Optional.of(DynamicConstantDesc.<ConstantDesc<MethodHandle>>of(BSM_METHODHANDLEDESC, CR_ConstantMethodHandleDesc)
+                                              .withArgs(kind.toString(), owner.descriptorString(), name, type.descriptorString()));
+    }
+
+    /**
+     * Constant bootstrap method for representing a {@linkplain MethodHandleDesc} in
+     * the constant pool of a classfile.
+     *
+     * @param lookup ignored
+     * @param name ignored
+     * @param clazz ignored
+     * @param bsmKindName The name of an {@code enum} constant from {@link Kind}
+     * @param memberOwner A field type descriptor for the class declaring the
+     *                 method, field, or constructor, as per JVMS 4.3.2
+     * @param memberName The name of the method or field, as per JVMS 4.2.2
+     * @param memberType A method type descriptor for the method handle being
+     *                described, as per JVMS 4.3.3
+     * @return the {@linkplain MethodHandleDesc}
+     * @jvms 4.2.2 Unqualified Names
+     * @jvms 4.3.2 Field Descriptors
+     * @jvms 4.3.3 Method Descriptors
+     */
+    public static ConstantMethodHandleDesc constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
+                                                     String bsmKindName, String memberOwner, String memberName, String memberType) {
+        return MethodHandleDesc.of(MethodHandleDesc.Kind.valueOf(bsmKindName),
+                                   ClassDesc.ofDescriptor(memberOwner), memberName,
+                                   MethodTypeDesc.ofDescriptor(memberType));
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        ConstantMethodHandleDesc desc = (ConstantMethodHandleDesc) o;
+        return kind == desc.kind &&
+               Objects.equals(owner, desc.owner) &&
+               Objects.equals(name, desc.name) &&
+               Objects.equals(type, desc.type);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(kind, owner, name, type);
+    }
+
+    @Override
+    public String toString() {
+        return String.format("MethodHandleDesc[%s/%s::%s%s]", kind, owner.displayName(), name, type.displayDescriptor());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/ConstantMethodTypeDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+
+import jdk.internal.lang.annotation.Foldable;
+
+import static java.lang.constant.ConstantDescs.BSM_METHODTYPEDESC;
+import static java.lang.constant.ConstantDescs.CR_ConstantMethodTypeDesc;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
+ * {@link MethodType}.  A {@linkplain ConstantMethodTypeDesc} corresponds to a
+ * {@code Constant_MethodType_info} entry in the constant pool of a classfile.
+ */
+public final class ConstantMethodTypeDesc implements MethodTypeDesc {
+    private final ClassDesc returnType;
+    private final ClassDesc[] argTypes;
+
+    /**
+     * Construct a {@linkplain MethodTypeDesc} with the specified return type
+     * and parameter types
+     *
+     * @param returnType a {@link ClassDesc} describing the return type
+     * @param argTypes {@link ClassDesc}s describing the parameter types
+     */
+    ConstantMethodTypeDesc(ClassDesc returnType, ClassDesc[] argTypes) {
+        this.returnType = requireNonNull(returnType);
+        this.argTypes = requireNonNull(argTypes);
+
+        for (ClassDesc cr : argTypes)
+            if (cr.isPrimitive() && cr.descriptorString().equals("V"))
+                throw new IllegalArgumentException("Void parameters not permitted");
+    }
+
+    /**
+     * Create a {@linkplain ConstantMethodTypeDesc} given a method descriptor string.
+     *
+     * @param descriptor the method descriptor string, as per JVMS 4.3.3
+     * @return a {@linkplain ConstantMethodTypeDesc} describing the desired method type
+     * @throws IllegalArgumentException if the descriptor string is not a valid
+     * method descriptor
+     * @jvms 4.3.3 Method Descriptors
+     */
+    @Foldable
+    static ConstantMethodTypeDesc ofDescriptor(String descriptor) {
+        requireNonNull(descriptor);
+        List<String> types = ConstantUtils.parseMethodDescriptor(descriptor);
+        ClassDesc[] paramTypes = types.stream().skip(1).map(ClassDesc::ofDescriptor).toArray(ClassDesc[]::new);
+        return new ConstantMethodTypeDesc(ClassDesc.ofDescriptor(types.get(0)), paramTypes);
+    }
+
+    @Foldable
+    @Override
+    public ClassDesc returnType() {
+        return returnType;
+    }
+
+    @Foldable
+    @Override
+    public int parameterCount() {
+        return argTypes.length;
+    }
+
+    @Foldable
+    @Override
+    public ClassDesc parameterType(int index) {
+        return argTypes[index];
+    }
+
+    @Override
+    public List<ClassDesc> parameterList() {
+        return List.of(argTypes);
+    }
+
+    @Override
+    public ClassDesc[] parameterArray() {
+        return argTypes.clone();
+    }
+
+    @Foldable
+    @Override
+    public MethodTypeDesc changeReturnType(ClassDesc returnType) {
+        return MethodTypeDesc.of(returnType, argTypes);
+    }
+
+    @Foldable
+    @Override
+    public MethodTypeDesc changeParameterType(int index, ClassDesc paramType) {
+        ClassDesc[] newArgs = argTypes.clone();
+        newArgs[index] = paramType;
+        return MethodTypeDesc.of(returnType, newArgs);
+    }
+
+    @Foldable
+    @Override
+    public MethodTypeDesc 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));
+        ClassDesc[] newArgs = new ClassDesc[argTypes.length - (end - start)];
+        System.arraycopy(argTypes, 0, newArgs, 0, start);
+        System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
+        return MethodTypeDesc.of(returnType, newArgs);
+    }
+
+    @Foldable
+    @Override
+    public MethodTypeDesc insertParameterTypes(int pos, ClassDesc... paramTypes) {
+        if (pos < 0 || pos > argTypes.length)
+            throw new IndexOutOfBoundsException(pos);
+        ClassDesc[] newArgs = new ClassDesc[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 MethodTypeDesc.of(returnType, newArgs);
+    }
+
+    @Override
+    public MethodType resolveConstantDesc(MethodHandles.Lookup lookup) {
+        return MethodType.fromMethodDescriptorString(descriptorString(), lookup.lookupClass().getClassLoader());
+    }
+
+    @Override
+    public Optional<? extends ConstantDesc<ConstantDesc<MethodType>>> describeConstable() {
+        return Optional.of(DynamicConstantDesc.<ConstantDesc<MethodType>>of(BSM_METHODTYPEDESC, CR_ConstantMethodTypeDesc)
+                                   .withArgs(descriptorString()));
+    }
+
+    /**
+     * Constant bootstrap method for representing a {@linkplain MethodTypeDesc} in
+     * the constant pool of a classfile.
+     *
+     * @param lookup ignored
+     * @param name ignored
+     * @param clazz ignored
+     * @param descriptor a method descriptor string for the method type, as per JVMS 4.3.3
+     * @return the {@linkplain MethodTypeDesc}
+     * @jvms 4.3.3 Method Descriptors
+     */
+    public static ConstantMethodTypeDesc constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
+                                                   String descriptor) {
+        return (ConstantMethodTypeDesc)MethodTypeDesc.ofDescriptor(descriptor);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        ConstantMethodTypeDesc constant = (ConstantMethodTypeDesc) o;
+
+        return returnType.equals(constant.returnType)
+               && Arrays.equals(argTypes, constant.argTypes);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = returnType.hashCode();
+        result = 31 * result + Arrays.hashCode(argTypes);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("MethodTypeDesc[%s]", displayDescriptor());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/ConstantUtils.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.util.*;
+import static java.util.Objects.requireNonNull;
+
+/**
+ * Helper methods for the implementation of {@code java.lang.constant}.
+ */
+public class ConstantUtils {
+    /** an empty constant descriptor */
+    public static final ConstantDesc<?>[] EMPTY_CONSTANTDESC = new ConstantDesc<?>[0];
+    static final Constable<?>[] EMPTY_CONSTABLE = new Constable<?>[0];
+
+    private static final Set<String> pointyNames = Set.of("<init>", "<clinit>");
+
+    static String validateBinaryClassName(String name) {
+        for (int i=0; i<name.length(); i++) {
+            char ch = name.charAt(i);
+            if (ch == ';' || ch == '[' || ch == '/')
+                throw new IllegalArgumentException("Invalid class name: " + name);
+        }
+        return name;
+    }
+
+    /**
+     * validates a member name
+     * @param name the name of the member
+     * @return the name passed if valid
+     */
+    public static String validateMemberName(String name) {
+        requireNonNull(name);
+        if (name.length() == 0)
+            throw new IllegalArgumentException("zero-length member name");
+        for (int i=0; i<name.length(); i++) {
+            char ch = name.charAt(i);
+            if (ch == '.' || ch == ';' || ch == '[' || ch == '/')
+                throw new IllegalArgumentException("Invalid member name: " + name);
+            if (ch == '<' || ch == '>') {
+                if (!pointyNames.contains(name))
+                    throw new IllegalArgumentException("Invalid member name: " + name);
+            }
+        }
+        return name;
+    }
+
+    static void validateClassOrInterface(ClassDesc clazz) {
+        if (!clazz.isClassOrInterface())
+            throw new IllegalArgumentException("not a class or interface type: " + clazz);
+    }
+
+    static int arrayDepth(String descriptorString) {
+        int depth = 0;
+        while (descriptorString.charAt(depth) == '[')
+            depth++;
+        return depth;
+    }
+
+    static String binaryToInternal(String name) {
+        return name.replace('.', '/');
+    }
+
+    static String internalToBinary(String name) {
+        return name.replace('/', '.');
+    }
+
+    static String dropLastChar(String s) {
+        return s.substring(0, s.length() - 1);
+    }
+
+    static String dropFirstAndLastChar(String s) {
+        return s.substring(1, s.length() - 1);
+    }
+
+    /**
+     * Produce an {@code Optional<DynamicConstantDesc<T>>} describing the invocation
+     * of the specified bootstrap with the specified arguments.  The arguments will
+     * be converted to nominal descriptors using the provided lookup.  Helper
+     * method for implementing {@link Constable#describeConstable()}.
+     *
+     * @param <T> the type of the resulting constant
+     * @param bootstrap nominal descriptor for the bootstrap method
+     * @param type nominal descriptor for the type of the resulting constant
+     * @param args nominal descriptors for the bootstrap arguments
+     * @return the nominal descriptor for the dynamic constant
+     */
+    public static<T> Optional<DynamicConstantDesc<T>> symbolizeHelper(MethodHandleDesc bootstrap,
+                                                               ClassDesc type,
+                                                               Constable<?>... args) {
+        requireNonNull(bootstrap);
+        requireNonNull(type);
+        requireNonNull(args);
+        try {
+            ConstantDesc<?>[] quotedArgs = new ConstantDesc<?>[args.length + 1];
+            quotedArgs[0] = bootstrap;
+            for (int i=0; i<args.length; i++)
+                quotedArgs[i+1] = args[i].describeConstable().orElseThrow();
+            return Optional.of(DynamicConstantDesc.of(ConstantDescs.BSM_INVOKE, ConstantDescs.DEFAULT_NAME,
+                                                      type, quotedArgs));
+        }
+        catch (NoSuchElementException e) {
+            return Optional.empty();
+        }
+    }
+
+    /**
+     * Parse a method descriptor string, and return a list of field descriptor
+     * strings, return type first, then parameter types
+     *
+     * @param descriptor the descriptor string
+     * @return the list of types
+     * @throws IllegalArgumentException if the descriptor string is not valid
+     */
+    static List<String> parseMethodDescriptor(String descriptor) {
+        int cur = 0, end = descriptor.length();
+        ArrayList<String> ptypes = new ArrayList<>();
+
+        if (cur >= end || descriptor.charAt(cur) != '(')
+            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
+
+        ++cur;  // skip '('
+        while (cur < end && descriptor.charAt(cur) != ')') {
+            int len = matchSig(descriptor, cur, end);
+            if (len == 0 || descriptor.charAt(cur) == 'V')
+                throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
+            ptypes.add(descriptor.substring(cur, cur + len));
+            cur += len;
+        }
+        if (cur >= end)
+            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
+        ++cur;  // skip ')'
+
+        int rLen = matchSig(descriptor, cur, end);
+        if (rLen == 0 || cur + rLen != end)
+            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
+        ptypes.add(0, descriptor.substring(cur, cur + rLen));
+        return ptypes;
+    }
+
+    /**
+     * Validate that the characters at [start, end) within the provided string
+     * describe a valid field type descriptor.
+     *
+     * @param str the descriptor string
+     * @param start the starting index into the string
+     * @param end the ending index within the string
+     * @return the length of the descriptor, or 0 if it is not a descriptor
+     * @throws IllegalArgumentException if the descriptor string is not valid
+     */
+    static int matchSig(String str, int start, int end) {
+        if (start >= end || start >= str.length() || end > str.length())
+            return 0;
+        char c = str.charAt(start);
+        if (c == 'L') {
+            int endc = str.indexOf(';', start);
+            int badc = str.indexOf('.', start);
+            if (badc >= 0 && badc < endc)
+                return 0;
+            badc = str.indexOf('[', start);
+            if (badc >= 0 && badc < endc)
+                return 0;
+            return (endc < 0) ? 0 : endc - start + 1;
+        } else if (c == '[') {
+            int t = matchSig(str, start+1, end);
+            return (t > 0) ? t + 1 : 0;
+        } else {
+            return ("IJCSBFDZV".indexOf(c) >= 0) ? 1 : 0;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/DynamicCallSiteDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import jdk.internal.lang.annotation.Foldable;
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.stream.Stream;
+
+import static java.lang.constant.ConstantDescs.CR_String;
+import static java.lang.constant.ConstantUtils.EMPTY_CONSTANTDESC;
+import static java.lang.constant.ConstantUtils.validateMemberName;
+import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.joining;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for an
+ * {@code invokedynamic} call site.
+ *
+ * <p>Concrete subtypes of {@linkplain DynamicCallSiteDesc} must be
+ * <a href="../doc-files/ValueBased.html">value-based</a>.
+ */
+public class DynamicCallSiteDesc {
+
+    private final ConstantMethodHandleDesc bootstrapMethod;
+    private final ConstantDesc<?>[] bootstrapArgs;
+    private final String invocationName;
+    private final MethodTypeDesc invocationType;
+
+    /**
+     * Create a nominal descriptor for an {@code invokedynamic} call site.
+     *
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the {@code invokedynamic}
+     * @param invocationName The name that would appear in the {@code NameAndType}
+     *                       operand of the {@code invokedynamic}, as per
+     *                       JVMS 4.2.2
+     * @param invocationType a {@link MethodTypeDesc} describing the invocation
+     *                       type that would appear in the {@code NameAndType}
+     *                       operand of the {@code invokedynamic}
+     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
+     *                      to the bootstrap, that would appear in the
+     *                      {@code BootstrapMethods} attribute
+     * @throws NullPointerException if any parameter is null
+     * @throws IllegalArgumentException if the invocation name has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    private DynamicCallSiteDesc(ConstantMethodHandleDesc bootstrapMethod,
+                                String invocationName,
+                                MethodTypeDesc invocationType,
+                                ConstantDesc<?>[] bootstrapArgs) {
+        this.invocationName = validateMemberName(requireNonNull(invocationName));
+        this.invocationType = requireNonNull(invocationType);
+        this.bootstrapMethod = requireNonNull(bootstrapMethod);
+        this.bootstrapArgs = requireNonNull(bootstrapArgs.clone());
+        if (invocationName.length() == 0)
+            throw new IllegalArgumentException("Illegal invocation name: " + invocationName);
+    }
+
+    /**
+     * Create a nominal descriptor for an {@code invokedynamic} call site.
+     *
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the {@code invokedynamic}
+     * @param invocationName The name that would appear in the {@code NameAndType}
+     *                       operand of the {@code invokedynamic}, as per
+     *                       JVMS 4.2.2
+     * @param invocationType a {@link MethodTypeDesc} describing the invocation
+     *                       type that would appear in the {@code NameAndType}
+     *                       operand of the {@code invokedynamic}
+     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
+     *                      to the bootstrap, that would appear in the
+     *                      {@code BootstrapMethods} attribute
+     * @return the nominal descriptor
+     * @throws NullPointerException if any parameter is null
+     * @throws IllegalArgumentException if the invocation name has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    public static DynamicCallSiteDesc of(ConstantMethodHandleDesc bootstrapMethod,
+                                         String invocationName,
+                                         MethodTypeDesc invocationType,
+                                         ConstantDesc<?>... bootstrapArgs) {
+        return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, bootstrapArgs);
+    }
+
+    /**
+     * Create a nominal descriptor for an {@code invokedynamic} call site whose
+     * bootstrap method has no static arguments.
+     *
+     * @param bootstrapMethod The bootstrap method for the {@code invokedynamic}
+     * @param invocationName The invocationName that would appear in the
+     * {@code NameAndType} operand of the {@code invokedynamic}
+     * @param invocationType The invocation invocationType that would appear
+     * in the {@code NameAndType} operand of the {@code invokedynamic}
+     * @return the nominal descriptor
+     * @throws NullPointerException if any parameter is null
+     */
+    @Foldable
+    public static DynamicCallSiteDesc of(ConstantMethodHandleDesc bootstrapMethod,
+                                         String invocationName,
+                                         MethodTypeDesc invocationType) {
+        return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, EMPTY_CONSTANTDESC);
+    }
+
+    /**
+     * Create a nominal descriptor for an {@code invokedynamic} call site whose
+     * bootstrap method has no static arguments and for which the name parameter
+     * is {@link ConstantDescs#DEFAULT_NAME}.
+     *
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the {@code invokedynamic}
+     * @param invocationType a {@link MethodTypeDesc} describing the invocation
+     *                       type that would appear in the {@code NameAndType}
+     *                       operand of the {@code invokedynamic}
+     * @return the nominal descriptor
+     * @throws NullPointerException if any parameter is null
+     * @throws IllegalArgumentException if the invocation name has the incorrect
+     * format
+     */
+    @Foldable
+    public static DynamicCallSiteDesc of(ConstantMethodHandleDesc bootstrapMethod,
+                                         MethodTypeDesc invocationType) {
+        return of(bootstrapMethod, ConstantDescs.DEFAULT_NAME, invocationType);
+    }
+
+    /**
+     * Return a nominal descriptor for an {@code invokedynamic} call site whose
+     * bootstrap method, name, and invocation type are the same as this one, but
+     * with the specified bootstrap arguments.
+     *
+     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
+     *                      to the bootstrap, that would appear in the
+     *                      {@code BootstrapMethods} attribute
+     * @return the nominal descriptor
+     * @throws NullPointerException if any parameter is null
+     */
+    @Foldable
+    public DynamicCallSiteDesc withArgs(ConstantDesc<?>... bootstrapArgs) {
+        return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, bootstrapArgs);
+    }
+
+    /**
+     * Return a nominal descriptor for an {@code invokedynamic} call site whose
+     * bootstrap and bootstrap arguments are the same as this one, but with the
+     * specified invocationName and invocation invocationType
+     *
+     * @param invocationName The name that would appear in the {@code NameAndType}
+     *                       operand of the {@code invokedynamic}, as per
+     *                       JVMS 4.2.2
+     * @param invocationType a {@link MethodTypeDesc} describing the invocation
+     *                       type that would appear in the {@code NameAndType}
+     *                       operand of the {@code invokedynamic}
+     * @return the nominal descriptor
+     * @throws NullPointerException if any parameter is null
+     * @throws IllegalArgumentException if the invocation name has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    public DynamicCallSiteDesc withNameAndType(String invocationName,
+                                               MethodTypeDesc invocationType) {
+        return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, bootstrapArgs);
+    }
+
+    /**
+     * Returns the invocation name that would appear in the {@code NameAndType}
+     * operand of the {@code invokedynamic}.
+     * \
+     * @return the invocation name
+     */
+    @Foldable
+    public String invocationName() {
+        return invocationName;
+    }
+
+    /**
+     * Returns a {@link MethodTypeDesc} describing the invocation type that
+     * would appear in the {@code NameAndType} operand of the {@code invokedynamic}.
+     *
+     * @return the invocation type
+     */
+    @Foldable
+    public MethodTypeDesc invocationType() {
+        return invocationType;
+    }
+
+    /**
+     * Returns a {@link MethodHandleDesc} descripbing the bootstrap method for
+     * the {@code invokedynamic}.
+     *
+     * @return the bootstrap method for the {@code invokedynamic}
+     */
+    @Foldable
+    public MethodHandleDesc bootstrapMethod() { return bootstrapMethod; }
+
+    /**
+     * Returns {@link ConstantDesc}s describing the bootstrap arguments for the
+     * {@code invokedynamic}.
+     *
+     * @return the bootstrap arguments for the {@code invokedynamic}
+     */
+    public ConstantDesc<?>[] bootstrapArgs() { return bootstrapArgs.clone(); }
+
+    /**
+     * Reflectively invokes the bootstrap method with the specified arguments,
+     * and return the resulting {@link CallSite}
+     *
+     * @param lookup The {@link MethodHandles.Lookup} used to resolve class names
+     * @return the {@link CallSite}
+     * @throws Throwable if any exception is thrown by the bootstrap method
+     */
+    public CallSite resolveCallSiteDesc(MethodHandles.Lookup lookup) throws Throwable {
+        assert bootstrapMethod.methodType().parameterType(1).equals(CR_String);
+        MethodHandle bsm = bootstrapMethod.resolveConstantDesc(lookup);
+        Object[] args = new Object[bootstrapArgs.length + 3];
+        args[0] = lookup;
+        args[1] = invocationName;
+        args[2] = invocationType.resolveConstantDesc(lookup);
+        System.arraycopy(bootstrapArgs, 0, args, 3, bootstrapArgs.length);
+        return (CallSite) bsm.invokeWithArguments(args);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        DynamicCallSiteDesc specifier = (DynamicCallSiteDesc) o;
+        return Objects.equals(bootstrapMethod, specifier.bootstrapMethod) &&
+               Arrays.equals(bootstrapArgs, specifier.bootstrapArgs) &&
+               Objects.equals(invocationName, specifier.invocationName) &&
+               Objects.equals(invocationType, specifier.invocationType);
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(bootstrapMethod, invocationName, invocationType);
+        result = 31 * result + Arrays.hashCode(bootstrapArgs);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("DynamicCallSiteDesc[%s::%s(%s%s):%s]",
+                             bootstrapMethod.owner().displayName(),
+                             bootstrapMethod.methodName(),
+                             invocationName.equals(ConstantDescs.DEFAULT_NAME) ? "" : invocationName + "/",
+                             Stream.of(bootstrapArgs).map(Object::toString).collect(joining(",")),
+                             invocationType.displayDescriptor());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,496 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.lang.Enum.EnumDesc;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.lang.invoke.VarHandle.VarHandleDesc;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.function.Function;
+import java.util.stream.Stream;
+
+import jdk.internal.lang.annotation.Foldable;
+
+import static java.lang.constant.ConstantDescs.BSM_DYNAMICCONSTANTDESC;
+import static java.lang.constant.ConstantDescs.CR_Class;
+import static java.lang.constant.ConstantDescs.CR_DynamicConstantDesc;
+import static java.lang.constant.ConstantDescs.CR_VarHandle;
+import static java.lang.constant.ConstantUtils.validateMemberName;
+import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.joining;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
+ * dynamic constant (one described in the constant pool with
+ * {@code Constant_Dynamic_info}.)
+ *
+ * <p>Concrete subtypes of {@linkplain DynamicConstantDesc} must be
+ * <a href="../doc-files/ValueBased.html">value-based</a>.
+ *
+ * @param <T> the type of the dynamic constant
+ */
+public abstract class DynamicConstantDesc<T>
+        implements ConstantDesc<T>, Constable<ConstantDesc<T>> {
+
+    private final ConstantMethodHandleDesc bootstrapMethod;
+    private final ConstantDesc<?>[] bootstrapArgs;
+    private final String constantName;
+    private final ClassDesc constantType;
+
+    private static final Map<MethodHandleDesc, Function<DynamicConstantDesc<?>, ConstantDesc<?>>> canonicalMap
+            = Map.ofEntries(Map.entry(ConstantDescs.BSM_PRIMITIVE_CLASS, DynamicConstantDesc::canonicalizePrimitiveClass),
+                            Map.entry(ConstantDescs.BSM_ENUM_CONSTANT, DynamicConstantDesc::canonicalizeEnum),
+                            Map.entry(ConstantDescs.BSM_NULL_CONSTANT, DynamicConstantDesc::canonicalizeNull),
+                            Map.entry(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, DynamicConstantDesc::canonicalizeStaticFieldVarHandle),
+                            Map.entry(ConstantDescs.BSM_VARHANDLE_FIELD, DynamicConstantDesc::canonicalizeFieldVarHandle),
+                            Map.entry(ConstantDescs.BSM_VARHANDLE_ARRAY, DynamicConstantDesc::canonicalizeArrayVarHandle)
+    );
+
+    /**
+     * Create a nominal descriptor for a dynamic constant.
+     *
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the constant
+     * @param constantName The name that would appear in the {@code NameAndType}
+     *                     operand of the {@code LDC} for this constant, as per
+     *                     JVMS 4.2.2
+     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
+     *                     that would appear in the {@code NameAndType} operand
+     *                     of the {@code LDC} for this constant
+     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
+     *                      to the bootstrap, that would appear in the
+     *                      {@code BootstrapMethods} attribute
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if the {@code name} has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    protected DynamicConstantDesc(ConstantMethodHandleDesc bootstrapMethod,
+                                  String constantName,
+                                  ClassDesc constantType,
+                                  ConstantDesc<?>... bootstrapArgs) {
+        this.bootstrapMethod = requireNonNull(bootstrapMethod);
+        this.constantName = validateMemberName(requireNonNull(constantName));
+        this.constantType = requireNonNull(constantType);
+        this.bootstrapArgs = requireNonNull(bootstrapArgs).clone();
+
+        if (constantName.length() == 0)
+            throw new IllegalArgumentException("Illegal invocation name: " + constantName);
+    }
+
+    /**
+     * Return a nominal 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 {@link ConstantDesc}s describing the static arguments
+     *                      to the bootstrap, that would appear in the
+     *                      {@code BootstrapMethods} attribute
+     * @return the nominal descriptor
+     * @throws NullPointerException if any argument is null
+     */
+    @Foldable
+    public DynamicConstantDesc<T> withArgs(ConstantDesc<?>... bootstrapArgs) {
+        return DynamicConstantDesc.of(bootstrapMethod, constantName, constantType, bootstrapArgs);
+    }
+
+    /**
+     * Return a nominal descriptor for a dynamic constant, transforming it into
+     * a more specific type if the constant bootstrap is a well-known one and a
+     * more specific nominal descriptor type (e.g., ClassDesc) is available.
+     *
+     * <p>Classes whose {@link Constable#describeConstable()} method produces
+     * a {@linkplain DynamicConstantDesc} with a well-known bootstrap including
+     * {@link Class} (for instances describing primitive types), {@link Enum},
+     * and {@link VarHandle}.
+     *
+     * <p>Bytecode-reading APIs that process the constant pool and wish to expose
+     * entries as {@link ConstantDesc} to their callers should generally use this
+     * method in preference to {@link #of(ConstantMethodHandleDesc, String, ClassDesc, ConstantDesc[])}
+     * because this may result in a more specific type that can be provided to
+     * callers.
+     *
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the constant
+     * @param constantName The name that would appear in the {@code NameAndType}
+     *                     operand of the {@code LDC} for this constant, as per
+     *                     JVMS 4.2.2
+     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
+     *                     that would appear in the {@code NameAndType} operand
+     *                     of the {@code LDC} for this constant
+     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
+     *                      to the bootstrap, that would appear in the
+     *                      {@code BootstrapMethods} attribute
+     * @return the nominal descriptor
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if the {@code name} has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    public static<T> ConstantDesc<T> ofCanonical(ConstantMethodHandleDesc bootstrapMethod,
+                                                 String constantName,
+                                                 ClassDesc constantType,
+                                                 ConstantDesc<?>[] bootstrapArgs) {
+        return DynamicConstantDesc.<T>of(bootstrapMethod, constantName, constantType, bootstrapArgs)
+                .tryCanonicalize();
+    }
+
+    /**
+     * Return a nominal descriptor for a dynamic constant.
+     *
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the constant
+     * @param constantName The name that would appear in the {@code NameAndType}
+     *                     operand of the {@code LDC} for this constant, as per
+     *                     JVMS 4.2.2
+     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
+     *                     that would appear in the {@code NameAndType} operand
+     *                     of the {@code LDC} for this constant
+     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
+     *                      to the bootstrap, that would appear in the
+     *                      {@code BootstrapMethods} attribute
+     * @return the nominal descriptor
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if the {@code name} has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod,
+                                               String constantName,
+                                               ClassDesc constantType,
+                                               ConstantDesc<?>[] bootstrapArgs) {
+        return new DynamicConstantDesc<>(bootstrapMethod, constantName, constantType, bootstrapArgs) {};
+    }
+
+    /**
+     * Return a nominal descriptor for a dynamic constant whose bootstrap has
+     * no static arguments.
+     *
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the constant
+     * @param constantName The name that would appear in the {@code NameAndType}
+     *                     operand of the {@code LDC} for this constant, as per
+     *                     JVMS 4.2.2
+     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
+     *                     that would appear in the {@code NameAndType} operand
+     *                     of the {@code LDC} for this constant
+     * @return the nominal descriptor
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if the {@code name} has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod,
+                                               String constantName,
+                                               ClassDesc constantType) {
+        return DynamicConstantDesc.of(bootstrapMethod, constantName, constantType, ConstantUtils.EMPTY_CONSTANTDESC);
+    }
+
+    /**
+     * Return a nominal descriptor for a dynamic constant whose bootstrap has
+     * no static arguments, and for which the name parameter
+     * is {@link ConstantDescs#DEFAULT_NAME}.
+     *
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the constant
+     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
+     *                     that would appear in the {@code NameAndType} operand
+     *                     of the {@code LDC} for this constant
+     * @return the nominal descriptor
+     * @throws NullPointerException if any argument is null
+     */
+    @Foldable
+    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod,
+                                               ClassDesc constantType) {
+        return of(bootstrapMethod, ConstantDescs.DEFAULT_NAME, constantType);
+    }
+
+    /**
+     * Return a nominal descriptor for a dynamic constant whose bootstrap has
+     * no static arguments, and whose type parameter is always the same as the
+     * bootstrap method return type.
+     *
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the constant
+     * @param constantName The name that would appear in the {@code NameAndType}
+     *                     operand of the {@code LDC} for this constant, as per
+     *                     JVMS 4.2.2
+     * @return the nominal descriptor
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if the {@code name} has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod,
+                                               String constantName) {
+        return of(bootstrapMethod, constantName, bootstrapMethod.methodType().returnType());
+    }
+
+    /**
+     * Return a nominal descriptor for a dynamic constant whose bootstrap has
+     * no static arguments, whose name parameter is {@link ConstantDescs#DEFAULT_NAME},
+     * and whose type parameter is always the same as the bootstrap method return type.
+     *
+     * @param <T> the type of the dynamic constant
+     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
+     *                        bootstrap method for the constant
+     * @return the nominal descriptor
+     * @throws NullPointerException if any argument is null
+     * @throws IllegalArgumentException if the {@code name} has the incorrect
+     * format
+     */
+    @Foldable
+    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod) {
+        return of(bootstrapMethod, ConstantDescs.DEFAULT_NAME);
+    }
+
+    /**
+     * Returns The name that would appear in the {@code NameAndType} operand
+     *             of the {@code LDC} for this constant
+     *
+     * @return the constant name
+     */
+    @Foldable
+    public String constantName() {
+        return constantName;
+    }
+
+    /**
+     * Returns a {@link ClassDesc} describing the type that would appear in the
+     * {@code NameAndType} operand of the {@code LDC} for this constant.
+     *
+     * @return the constant type
+     */
+    @Foldable
+    public ClassDesc constantType() {
+        return constantType;
+    }
+
+    /**
+     * Returns a {@link MethodHandleDesc} describing the bootstrap method for
+     * this constant
+     *
+     * @return the bootstrap method
+     */
+    @Foldable
+    public ConstantMethodHandleDesc bootstrapMethod() {
+        return bootstrapMethod;
+    }
+
+    /**
+     * Returns the bootstrap arguments for this constant
+     * @return the bootstrap arguments
+     */
+    public ConstantDesc<?>[] bootstrapArgs() {
+        return bootstrapArgs.clone();
+    }
+
+    /**
+     * Returns the bootstrap arguments for this constant as a {@link List}
+     *
+     * @return a {@link List} of the bootstrap arguments, described as {@link ConstantDesc}
+     */
+    public List<ConstantDesc<?>> bootstrapArgsList() {
+        return List.of(bootstrapArgs);
+    }
+
+    @SuppressWarnings("unchecked")
+    public T resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
+        // TODO replace with public supported method
+        try {
+            MethodHandle bsm = bootstrapMethod.resolveConstantDesc(lookup);
+            if (bsm.type().parameterCount() < 2 ||
+                !MethodHandles.Lookup.class.isAssignableFrom(bsm.type().parameterType(0))) {
+                throw new BootstrapMethodError(
+                        "Invalid bootstrap method declared for resolving a dynamic constant: " + bootstrapMethod);
+            }
+            Object[] bsmArgs = new Object[3 + bootstrapArgs.length];
+            bsmArgs[0] = lookup;
+            bsmArgs[1] = constantName;
+            bsmArgs[2] = constantType.resolveConstantDesc(lookup);
+            for (int i = 0; i < bootstrapArgs.length; i++)
+                bsmArgs[3 + i] = bootstrapArgs[i].resolveConstantDesc(lookup);
+
+            return (T) bsm.invokeWithArguments(bsmArgs);
+        } catch (Error e) {
+            throw e;
+        } catch (Throwable t) {
+            throw new BootstrapMethodError(t);
+        }
+    }
+
+    @Override
+    public Optional<? extends ConstantDesc<ConstantDesc<T>>> describeConstable() {
+        ConstantDesc<?>[] args = new ConstantDesc<?>[bootstrapArgs.length + 5];
+        args[0] = bootstrapMethod.owner().descriptorString();
+        args[1] = bootstrapMethod.methodName();
+        args[2] = bootstrapMethod.methodType().descriptorString();
+        args[3] = constantName;
+        args[4] = constantType.descriptorString();
+        System.arraycopy(bootstrapArgs, 0, args, 5, bootstrapArgs.length);
+        return Optional.of(DynamicConstantDesc.of(BSM_DYNAMICCONSTANTDESC, ConstantDescs.DEFAULT_NAME,
+                                                  CR_DynamicConstantDesc, args));
+    }
+
+    /**
+     * Constant bootstrap method for representing a {@linkplain DynamicConstantDesc}
+     * in the constant pool of a classfile.
+     *
+     * @param lookup ignored
+     * @param name ignored
+     * @param clazz ignored
+     * @param bsmOwner A field type descriptor for the class declaring the
+     *                 bootstrap method, as per JVMS 4.3.2
+     * @param bsmName The name of the bootstrap method, as per JVMS 4.2.2
+     * @param bsmDesc A method type descriptor for bootstrap method, as per JVMS 4.3.3
+     * @param constantName The name that would appear in the {@code NameAndType}
+     *                     operand of the {@code LDC} for this constant, as per
+     *                     JVMS 4.2.2
+     * @param constantType a field type descriptor string describing the type
+     *                     that would appear in the {@code NameAndType} operand
+     *                     of the {@code LDC} for this constant, as per JVMS 4.3.2
+     * @param args The static arguments to the bootstrap method
+     * @return the {@linkplain DynamicConstantDesc}
+     * @jvms 4.2.2 Unqualified Names
+     * @jvms 4.3.2 Field Descriptors
+     * @jvms 4.3.3 Method Descriptors
+     */
+    public static DynamicConstantDesc<?> constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
+                                                           String bsmOwner, String bsmName, String bsmDesc,
+                                                           String constantName, String constantType,
+                                                           ConstantDesc<?>... args) {
+        return DynamicConstantDesc.of(MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC,
+                                                          ClassDesc.ofDescriptor(bsmOwner), bsmName,
+                                                          MethodTypeDesc.ofDescriptor(bsmDesc)),
+                                      constantName, ClassDesc.ofDescriptor(constantType), args);
+
+    }
+
+    private ConstantDesc<T> tryCanonicalize() {
+        Function<DynamicConstantDesc<?>, ConstantDesc<?>> f = canonicalMap.get(bootstrapMethod);
+        if (f != null) {
+            try {
+                @SuppressWarnings("unchecked")
+                ConstantDesc<T> converted = (ConstantDesc<T>) f.apply(this);
+                return converted;
+            }
+            catch (Throwable t) {
+                return this;
+            }
+        }
+        return this;
+    }
+
+    private static ConstantDesc<?> canonicalizeNull(DynamicConstantDesc<?> desc) {
+        if (desc.bootstrapArgs.length != 0)
+            return desc;
+        return ConstantDescs.NULL;
+    }
+
+    private static ConstantDesc<?> canonicalizeEnum(DynamicConstantDesc<?> desc) {
+        if (desc.bootstrapArgs.length != 0
+            || desc.constantName == null)
+            return desc;
+        return EnumDesc.of(desc.constantType, desc.constantName);
+    }
+
+    private static ConstantDesc<?> canonicalizePrimitiveClass(DynamicConstantDesc<?> desc) {
+        if (desc.bootstrapArgs.length != 0
+            || !desc.constantType().equals(CR_Class)
+            || desc.constantName == null)
+            return desc;
+        return ClassDesc.ofDescriptor(desc.constantName);
+    }
+
+    private static ConstantDesc<?> canonicalizeStaticFieldVarHandle(DynamicConstantDesc<?> desc) {
+        if (desc.bootstrapArgs.length != 3
+            || !desc.constantType().equals(CR_VarHandle))
+            return desc;
+        return VarHandleDesc.ofStaticField((ClassDesc) desc.bootstrapArgs[0],
+                                           (String) desc.bootstrapArgs[1],
+                                           (ClassDesc) desc.bootstrapArgs[2]);
+    }
+
+    private static ConstantDesc<?> canonicalizeFieldVarHandle(DynamicConstantDesc<?> desc) {
+        if (desc.bootstrapArgs.length != 3
+            || !desc.constantType().equals(CR_VarHandle))
+            return desc;
+        return VarHandleDesc.ofField((ClassDesc) desc.bootstrapArgs[0],
+                                     (String) desc.bootstrapArgs[1],
+                                     (ClassDesc) desc.bootstrapArgs[2]);
+    }
+
+    private static ConstantDesc<?> canonicalizeArrayVarHandle(DynamicConstantDesc<?> desc) {
+        if (desc.bootstrapArgs.length != 1
+            || !desc.constantType().equals(CR_VarHandle))
+            return desc;
+        return VarHandleDesc.ofArray((ClassDesc) desc.bootstrapArgs[0]);
+    }
+
+    // @@@ To eventually support in canonicalization: DCR with BSM=MHR_METHODHANDLEDESC_ASTYPE becomes AsTypeMHDesc
+
+    @Override
+    public final boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof DynamicConstantDesc)) return false;
+        DynamicConstantDesc<?> desc = (DynamicConstantDesc<?>) o;
+        return Objects.equals(bootstrapMethod, desc.bootstrapMethod) &&
+               Arrays.equals(bootstrapArgs, desc.bootstrapArgs) &&
+               Objects.equals(constantName, desc.constantName) &&
+               Objects.equals(constantType, desc.constantType);
+    }
+
+    @Override
+    public final int hashCode() {
+        int result = Objects.hash(bootstrapMethod, constantName, constantType);
+        result = 31 * result + Arrays.hashCode(bootstrapArgs);
+        return result;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("DynamicConstantDesc[%s::%s(%s%s)%s]",
+                             bootstrapMethod.owner().displayName(),
+                             bootstrapMethod.methodName(),
+                             constantName.equals(ConstantDescs.DEFAULT_NAME) ? "" : constantName + "/",
+                             Stream.of(bootstrapArgs).map(Object::toString).collect(joining(",")),
+                             constantType.displayName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/MethodHandleDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,256 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodType;
+
+import jdk.internal.lang.annotation.Foldable;
+
+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.constant.ConstantDescs.CR_void;
+import static java.lang.constant.MethodHandleDesc.Kind.CONSTRUCTOR;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
+ * {@link MethodHandle} constant.
+ */
+public interface MethodHandleDesc
+        extends ConstantDesc<MethodHandle>, Constable<ConstantDesc<MethodHandle>> {
+    /**
+     * Kinds of method handles that can be described with {@linkplain MethodHandleDesc}.
+     */
+    public enum Kind {
+        /** A method handle for a method invoked as with {@code invokestatic} */
+        @Foldable STATIC(REF_invokeStatic),
+        /** A method handle for a method invoked as with {@code invokevirtual} */
+        @Foldable VIRTUAL(REF_invokeVirtual),
+        /** A method handle for a method invoked as with {@code invokeinterface} */
+        @Foldable INTERFACE_VIRTUAL(REF_invokeInterface),
+        /** A method handle for a method invoked as with {@code invokespecial} */
+        @Foldable SPECIAL(REF_invokeSpecial),
+        /** A method handle for a constructor */
+        @Foldable CONSTRUCTOR(REF_newInvokeSpecial),
+        /** A method handle for a read accessor for an instance field  */
+        @Foldable GETTER(REF_getField),
+        /** A method handle for a write accessor for an instance field  */
+        @Foldable SETTER(REF_putField),
+        /** A method handle for a read accessor for a static field  */
+        @Foldable STATIC_GETTER(REF_getStatic),
+        /** A method handle for a write accessor for a static field  */
+        @Foldable STATIC_SETTER(REF_putStatic);
+
+        /** The corresponding {@code refKind} value for this kind of method handle,
+         * as defined by {@link MethodHandleInfo}
+         */
+        public final int refKind;
+
+        Kind(int refKind) {
+            this.refKind = refKind;
+        }
+    }
+
+
+    /**
+     * Create a {@linkplain MethodHandleDesc} corresponding to an invocation of a
+     * declared method, invocation of a constructor, or access to a field.
+     *
+     * <p>If {@code kind} is {@code CONSTRUCTOR}, the name is ignored and the return
+     * type of the invocation type must be {@code void}.  If {@code kind} corresponds
+     * to a field access, the invocation type must be consistent with that kind
+     * of field access and the type of the field; instance field accessors must
+     * take a leading receiver parameter, getters must return the type of the
+     * field, setters must take a new value for the field and return {@code void}.
+     *
+     * <p>For constructor and field access, the methods {@link #ofField(Kind, ClassDesc, String, ClassDesc)}
+     * and {@link #ofConstructor(ClassDesc, ClassDesc...)} may be more convenient.
+     *
+     * @param kind The kind of method handle to be described
+     * @param clazz a {@link ClassDesc} describing the class containing the
+     *              method, constructor, or field
+     * @param name the name of the method or field (ignored if {@code kind} is
+     * {@code CONSTRUCTOR}), as per JVMS 4.2.2
+     * @param type a {@link MethodTypeDesc} describing the invocation type of
+     *             the method handle
+     * @return the {@linkplain MethodHandleDesc}
+     * @throws NullPointerException if any non-ignored arguments are null
+     * @throws IllegalArgumentException if the {@code name} has the incorrect
+     * format
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    static ConstantMethodHandleDesc of(Kind kind,
+                                       ClassDesc clazz,
+                                       String name,
+                                       MethodTypeDesc type) {
+        return new ConstantMethodHandleDesc(kind, clazz, name, type);
+    }
+
+    /**
+     * Create a {@linkplain MethodHandleDesc} corresponding to an invocation of a
+     * declared method, invocation of a constructor, or access to a field.
+     *
+     * <p>If {@code kind} is {@code CONSTRUCTOR}, the name is ignored and the return
+     * type of the invocation type must be {@code void}.  If {@code kind} corresponds
+     * to a field access, the invocation type must be consistent with that kind
+     * of field access and the type of the field; instance field accessors must
+     * take a leading receiver parameter, getters must return the type of the
+     * field, setters must take a new value for the field and return {@code void}.
+     * The method {@link #ofField(Kind, ClassDesc, String, ClassDesc)} will construct
+     * the appropriate invocation given the type of the field.
+     *
+     * @param kind The kind of method handle to be described
+     * @param clazz a {@link ClassDesc} describing the class containing the
+     *              method, constructor, or field
+     * @param name the name of the method or field (ignored if {@code kind} is
+     * {@code CONSTRUCTOR}), as per JVMS 4.2.2
+     * @param descriptorString a method descriptor string for the invocation type
+     * of the method handle, as per JVMS 4.3.3
+     * @return the {@linkplain MethodHandleDesc}
+     * @throws NullPointerException if any of the non-ignored arguments are null
+     * @jvms 4.2.2 Unqualified Names
+     * @jvms 4.3.3 Method Descriptors
+     */
+    @Foldable
+    static ConstantMethodHandleDesc of(Kind kind,
+                                       ClassDesc clazz,
+                                       String name,
+                                       String descriptorString) {
+        return of(kind, clazz, name, MethodTypeDesc.ofDescriptor(descriptorString));
+    }
+
+    /**
+     * Create a {@linkplain MethodHandleDesc} corresponding to an invocation of a
+     * declared method, invocation of a constructor, or access to a field.
+     *
+     * <p>If {@code kind} is {@code CONSTRUCTOR}, the name is ignored and the return
+     * type of the invocation type must be {@code void}.  If {@code kind} corresponds
+     * to a field access, the invocation type must be consistent with that kind
+     * of field access and the type of the field; instance field accessors must
+     * take a leading receiver parameter, getters must return the type of the
+     * field, setters must take a new value for the field and return {@code void}.
+     * The method {@link #ofField(Kind, ClassDesc, String, ClassDesc)} will construct
+     * the appropriate invocation given the type of the field.
+     *
+     * @param kind The kind of method handle to be described
+     * @param clazz a {@link ClassDesc} describing the class containing the
+     *              method, constructor, or field
+     * @param name the name of the method or field (ignored if {@code kind} is
+     * {@code CONSTRUCTOR}), as per JVMS 4.2.2
+     * @param returnType a {@link ClassDesc} describing the return type of the
+     *                   method handle
+     * @param paramTypes {@link ClassDesc}s describing the parameter types of
+     *                                    the method handle
+     * @return the {@linkplain MethodHandleDesc}
+     * @throws NullPointerException if any of the non-ignored arguments are null
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    static ConstantMethodHandleDesc of(Kind kind,
+                                       ClassDesc clazz,
+                                       String name,
+                                       ClassDesc returnType,
+                                       ClassDesc... paramTypes) {
+        return of(kind, clazz, name, MethodTypeDesc.of(returnType, paramTypes));
+    }
+
+    /**
+     * Create a {@linkplain MethodHandleDesc} corresponding to a method handle
+     * that accesses a field.
+     *
+     * @param kind the kind of the method handle to be described; must be one of {@code GETTER},
+     *             {@code SETTER}, {@code STATIC_GETTER}, or {@code STATIC_SETTER}
+     * @param clazz a {@link ClassDesc} describing the class containing the
+     *              method, constructor, or field
+     * @param fieldName the name of the field, as per JVMS 4.2.2
+     * @param fieldType a {@link ClassDesc} describing the type of the field
+     * @return the {@linkplain MethodHandleDesc}
+     * @throws NullPointerException if any of the arguments are null
+     * @jvms 4.2.2 Unqualified Names
+     */
+    @Foldable
+    static ConstantMethodHandleDesc ofField(Kind kind,
+                                            ClassDesc clazz,
+                                            String fieldName,
+                                            ClassDesc fieldType) {
+        MethodTypeDesc mtr;
+        switch (kind) {
+            case GETTER: mtr = MethodTypeDesc.of(fieldType, clazz); break;
+            case SETTER: mtr = MethodTypeDesc.of(CR_void, clazz, fieldType); break;
+            case STATIC_GETTER: mtr = MethodTypeDesc.of(fieldType); break;
+            case STATIC_SETTER: mtr = MethodTypeDesc.of(CR_void, fieldType); break;
+            default:
+                throw new IllegalArgumentException(kind.toString());
+        }
+        return MethodHandleDesc.of(kind, clazz, fieldName, mtr);
+    }
+
+    /**
+     * Return a {@linkplain MethodHandleDesc} corresponding to invocation of a constructor
+     *
+     * @param clazz a {@link ClassDesc} describing the class containing the
+     *              method, constructor, or field
+     * @param paramTypes {@link ClassDesc}s describing the parameter types of
+     *                   the constructor
+     * @return the {@linkplain MethodHandleDesc}
+     * @throws NullPointerException if any of the arguments are null
+     */
+    @Foldable
+    static ConstantMethodHandleDesc ofConstructor(ClassDesc clazz,
+                                                  ClassDesc... paramTypes) {
+        return MethodHandleDesc.of(CONSTRUCTOR, clazz, ConstantDescs.DEFAULT_NAME,
+                                   MethodTypeDesc.of(CR_void, paramTypes));
+    }
+
+    /**
+     * Return a {@linkplain MethodHandleDesc} that describes this method handle
+     * adapted to a different type, as if by {@link MethodHandle#asType(MethodType)}.
+     *
+     * @param type a {@link MethodHandleDesc} describing the new method type
+     * @return a {@linkplain MethodHandleDesc} for the adapted method handle
+     */
+    @Foldable
+    default MethodHandleDesc asType(MethodTypeDesc type) {
+        return (methodType().equals(type)) ? this : new AsTypeMethodHandleDesc(this, type);
+    }
+
+    /**
+     * Return a {@link MethodTypeDesc} describing the type of the method handle
+     * described by this nominal descriptor
+     *
+     * @return a {@linkplain MethodHandleDesc} describing the method handle type
+     */
+    @Foldable
+    MethodTypeDesc methodType();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,197 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import jdk.internal.lang.annotation.Foldable;
+
+import java.lang.invoke.MethodType;
+import java.lang.invoke.MethodTypeDescriptor;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
+ * {@linkplain MethodType} constant.
+ */
+public interface MethodTypeDesc
+        extends ConstantDesc<MethodType>,
+                Constable<ConstantDesc<MethodType>>,
+                MethodTypeDescriptor<ClassDesc, MethodTypeDesc> {
+    /**
+     * Create a {@linkplain MethodTypeDesc} given a method descriptor string
+     *
+     * @param descriptor a method descriptor string, as per JVMS 4.3.3
+     * @return a {@linkplain MethodTypeDesc} describing the desired method type
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IllegalArgumentException if the descriptor string is not a valid
+     * method descriptor
+     * @jvms 4.3.3 Method Descriptors
+     */
+    @Foldable
+    static MethodTypeDesc ofDescriptor(String descriptor) {
+        return ConstantMethodTypeDesc.ofDescriptor(descriptor);
+    }
+
+    /**
+     * Returns a {@linkplain MethodTypeDesc} given the return type and parameter
+     * types.
+     *
+     * @param returnDesc a {@linkplain ClassDesc} describing the return type
+     * @param paramDescs {@linkplain ClassDesc}s describing the argument types
+     * @return a {@linkplain MethodTypeDesc} describing the desired method type
+     * @throws NullPointerException if any argument is {@code null}
+     */
+    @Foldable
+    static MethodTypeDesc of(ClassDesc returnDesc, ClassDesc... paramDescs) {
+        return new ConstantMethodTypeDesc(returnDesc, paramDescs);
+    }
+
+    /**
+     * Get the return type of the method type described by this {@linkplain MethodTypeDesc}
+     *
+     * @return a {@link ClassDesc} describing the return type of the method type
+     */
+    @Foldable
+    ClassDesc returnType();
+
+    /**
+     * Get the number of parameters of the method type described by
+     * this {@linkplain MethodTypeDesc}
+     * @return the number of parameters
+     */
+    @Foldable
+    int parameterCount();
+
+    /**
+     * Get the parameter type of the {@code index}'th parameter of the method type
+     * described by this {@linkplain MethodTypeDesc}
+     *
+     * @param index the index of the parameter to retrieve
+     * @return a {@link ClassDesc} describing the desired parameter type
+     * @throws IndexOutOfBoundsException if the index is outside the half-open
+     * range {[0, parameterCount())}
+     */
+    @Foldable
+    ClassDesc parameterType(int index);
+
+    /**
+     * Get the parameter types as a {@link List}.
+     *
+     * @return a {@link List} of {@link ClassDesc} describing the parameter types
+     */
+    List<ClassDesc> parameterList();
+
+    /**
+     * Get the parameter types as an array.
+     *
+     * @return an array of {@link ClassDesc} describing the parameter types
+     */
+    ClassDesc[] parameterArray();
+
+    /**
+     * Return a {@linkplain MethodTypeDesc} that is identical to
+     * this one, except with the specified return type.
+     *
+     * @param returnType a {@link ClassDesc} describing the new return type
+     * @return a {@linkplain MethodTypeDesc} describing the desired method type
+     * @throws NullPointerException if any argument is {@code null}
+     */
+    @Foldable
+    MethodTypeDesc changeReturnType(ClassDesc returnType);
+
+    /**
+     * Return a {@linkplain MethodTypeDesc} that is identical to this one,
+     * except that a single parameter type has been changed to the specified type.
+     *
+     * @param index the index of the parameter to change
+     * @param paramType a {@link ClassDesc} describing the new parameter type
+     * @return a {@linkplain MethodTypeDesc} describing the desired method type
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IndexOutOfBoundsException if the index is outside the half-open
+     * range {[0, parameterCount)}
+     */
+    @Foldable
+    MethodTypeDesc changeParameterType(int index, ClassDesc paramType);
+
+    /**
+     * Return a {@linkplain MethodTypeDesc} that is identical to this one,
+     * except that a range of parameter types have been removed.
+     *
+     * @param start the index of the first parameter to remove
+     * @param end the index after the last parameter to remove
+     * @return a {@linkplain MethodTypeDesc} describing the desired method type
+     * @throws IndexOutOfBoundsException if {@code start} is outside the half-open
+     * range {[0, parameterCount)}, or {@code end} is outside the closed range
+     * {@code [0, parameterCount]}
+     */
+    @Foldable
+    MethodTypeDesc dropParameterTypes(int start, int end);
+
+    /**
+     * Return a {@linkplain MethodTypeDesc} that is identical to this one,
+     * except that a range of additional parameter types have been inserted.
+     *
+     * @param pos the index at which to insert the first inserted parameter
+     * @param paramTypes {@link ClassDesc}s describing the new parameter types
+     *                   to insert
+     * @return a {@linkplain MethodTypeDesc} describing the desired method type
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IndexOutOfBoundsException if {@code pos} is outside the closed
+     * range {[0, parameterCount]}
+     */
+    @Foldable
+    MethodTypeDesc insertParameterTypes(int pos, ClassDesc... paramTypes);
+
+    /**
+     * Return the method type descriptor string, as per JVMS 4.3.3.
+     *
+     * @return the method type descriptor string
+     * @jvms 4.3.3 Method Descriptors
+     */
+    default String descriptorString() {
+        return String.format("(%s)%s",
+                             Stream.of(parameterArray())
+                                   .map(ClassDesc::descriptorString)
+                                   .collect(Collectors.joining()),
+                             returnType().descriptorString());
+    }
+
+    /**
+     * Return a human-readable descriptor for this method type, using the
+     * canonical names for parameter and return types
+     *
+     * @return the human-readable descriptor for this method type
+     */
+    default String displayDescriptor() {
+        return String.format("(%s)%s",
+                             Stream.of(parameterArray())
+                                   .map(ClassDesc::displayName)
+                                   .collect(Collectors.joining(",")),
+                             returnType().displayName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/PrimitiveClassDesc.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2018, 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.constant;
+
+import java.lang.invoke.MethodHandles;
+import java.util.Optional;
+
+import sun.invoke.util.Wrapper;
+
+import static java.util.Objects.requireNonNull;
+
+/**
+ * A <a href="package-summary.html#nominal">nominal descriptor</a> for the class
+ * constant corresponding to a primitive type (e.g., {@code int.class}).
+ */
+final class PrimitiveClassDesc
+        extends DynamicConstantDesc<Class<?>> implements ClassDesc {
+
+    private final String descriptor;
+
+    /**
+     * Create a {@linkplain ClassDesc} given a descriptor string for a primitive
+     * type.
+     *
+     * @param descriptor the descriptor string, which must be a one-character
+     * string corresponding to one of the nine base types as per JVMS 4.3
+     * @throws IllegalArgumentException if the descriptor string does not
+     * describe a valid primitive type
+     * @jvms 4.3 Descriptors
+     */
+    PrimitiveClassDesc(String descriptor) {
+        super(ConstantDescs.BSM_PRIMITIVE_CLASS, requireNonNull(descriptor), ConstantDescs.CR_Class);
+        if (descriptor.length() != 1
+            || "VIJCSBFDZ".indexOf(descriptor.charAt(0)) < 0)
+            throw new IllegalArgumentException(String.format("not a valid primitive type descriptor: %s", descriptor));
+        this.descriptor = descriptor;
+    }
+
+    @Override
+    public String descriptorString() {
+        return descriptor;
+    }
+
+    @Override
+    public Class<?> resolveConstantDesc(MethodHandles.Lookup lookup) {
+        return Wrapper.forBasicType(descriptorString().charAt(0)).primitiveType();
+    }
+
+    @Override
+    public Optional<? extends ConstantDesc<ConstantDesc<Class<?>>>> describeConstable() {
+        return ConstantUtils.symbolizeHelper(ConstantDescs.MHR_CLASSDESC_FACTORY, ConstantDescs.CR_ClassDesc, descriptorString());
+    }
+
+    @Override
+    public String toString() {
+        return String.format("PrimitiveClassDesc[%s]", displayName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/constant/package-info.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+/**
+ * Classes and interfaces to represent <em>nominal descriptors</em> for run-time
+ * entities such as classes or method handles, and classfile entities such as
+ * constant pool entries or {@code invokedynamic} call sites.  These classes
+ * are suitable for use in bytecode reading and writing APIs, {@code invokedynamic}
+ * bootstraps, bytecode intrinsic APIs (such as {@link java.lang.invoke.Intrinsics#ldc(ConstantDesc)}),
+ * and compile-time or link-time program analysis tools.
+ *
+ * <p>Every API that reads and writes bytecode instructions needs to model the
+ * operands to these instructions and other classfile structures (such as entries
+ * in the bootstrap methods table or stack maps, which frequently reference
+ * entries in the classfile constant pool.) Such entries can denote values of
+ * fundamental types, such as strings or integers; parts of a program, such as
+ * classes or method handles; or values of arbitrary user-defined types.  The
+ * {@link java.lang.constant.ConstantDesc} hierarchy provides a representation of
+ * constant pool entries in nominal form that is convenient for APIs to model
+ * operands of bytecode instructions.
+ *
+ * <h2><a id="nominal"></a>Nominal Descriptors</h2>
+ *
+ * <p>A {@link java.lang.constant.ConstantDesc} is a description of a constant
+ * value.  Such a description is the <em>nominal form</em> of the constant value;
+ * it is not the value itself, but rather a "recipe" for describing the value,
+ * storing the value in a constant pool entry, or reconstituting the value given
+ * a class loading context.  Every {@link java.lang.constant.ConstantDesc}
+ * knows how to <em>resolve</em> itself -- compute the value that it describes --
+ * via {@link java.lang.constant.ConstantDesc#resolveConstantDesc(java.lang.invoke.MethodHandles.Lookup)}.
+ * This allows an API which accepts {@link java.lang.constant.ConstantDesc}
+ * objects to evaluate them reflectively, provided that the classes and methods
+ * referenced in their nominal description are present and accessible.
+ *
+ * <p>The subtypes of of {@link java.lang.constant.ConstantDesc} describe various kinds
+ * of constant values.  For each type of loadable constant pool entry defined in JVMS 4.4,
+ * there is a corresponding subtype of {@link java.lang.constant.ConstantDesc}:
+ * {@link java.lang.constant.ConstantClassDesc}, {@link java.lang.constant.ConstantMethodTypeDesc},
+ * {@link java.lang.constant.ConstantMethodHandleDesc}, {@link java.lang.String},
+ * {@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Float},
+ * {@link java.lang.Double}, and {@link java.lang.constant.DynamicConstantDesc}.  These classes
+ * provides type-specific accessor methods to extract the nominal information for
+ * that kind of constant.  When a bytecode-writing API encounters a {@link java.lang.constant.ConstantDesc},
+ * it should examine it to see which of these types it is, cast it, extract
+ * its nominal information, and generate the corresponding entry to the constant pool.
+ * When a bytecode-reading API encounters a constant pool entry, it can
+ * convert it to the appropriate type of nominal descriptor.  For dynamic
+ * constants, bytecode-reading APIs may wish to use the factory
+ * {@link java.lang.constant.DynamicConstantDesc#ofCanonical(ConstantMethodHandleDesc, java.lang.String, ClassDesc, ConstantDesc[])},
+ * which will inspect the bootstrap and, for well-known bootstraps, return
+ * a more specific subtype of {@link java.lang.constant.DynamicConstantDesc}, such as
+ * {@link java.lang.Enum.EnumDesc}.
+ *
+ * <p>Another way to obtain the nominal description of a value is to ask the value
+ * itself.  A {@link java.lang.constant.Constable} is a type whose values
+ * can describe themselves in nominal form as a {@link java.lang.constant.ConstantDesc}.
+ * Fundamental types such as {@link java.lang.String} and {@link java.lang.Class}
+ * implement {@link java.lang.constant.Constable}, as can user-defined
+ * classes.  Entities that generate classfiles (such as compilers) can introspect
+ * over constable objects to obtain a more efficient way to represent their values
+ * in classfiles.
+ *
+ * <p>This package also includes {@link java.lang.constant.DynamicCallSiteDesc},
+ * which represents a (non-loadable) {@code Constant_InvokeDynamic_info} constant
+ * pool entry.  It describes the bootstrap method, invocation name and type,
+ * and bootstrap arguments associated with an {@code invokedynamic} instruction.
+ * It is also suitable for describing {@code invokedynamic} call sites in bytecode
+ * reading and writing APIs, and and is used by the
+ * {@link java.lang.invoke.Intrinsics#invokedynamic(DynamicCallSiteDesc, java.lang.Object...)}
+ * API for expressing {@code invokedynamic} call sites in Java source files.
+ * @jvms 4.4 The Constant Pool
+ */
+package java.lang.constant;
+
--- a/src/java.base/share/classes/java/lang/invoke/Intrinsics.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/Intrinsics.java	Mon Jun 04 14:59:22 2018 -0700
@@ -24,8 +24,8 @@
  */
 package java.lang.invoke;
 
-import java.lang.invoke.constant.ConstantDesc;
-import java.lang.invoke.constant.DynamicCallSiteDesc;
+import java.lang.constant.ConstantDesc;
+import java.lang.constant.DynamicCallSiteDesc;
 
 /**
  * Intrinsics
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Mon Jun 04 14:59:22 2018 -0700
@@ -28,11 +28,11 @@
 
 import jdk.internal.HotSpotIntrinsicCandidate;
 
-import java.lang.invoke.constant.ClassDesc;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
-import java.lang.invoke.constant.MethodHandleDesc;
-import java.lang.invoke.constant.MethodTypeDesc;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
+import java.lang.constant.MethodHandleDesc;
+import java.lang.constant.MethodTypeDesc;
 import java.util.Arrays;
 import java.util.Objects;
 import java.util.Optional;
--- a/src/java.base/share/classes/java/lang/invoke/MethodType.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java	Mon Jun 04 14:59:22 2018 -0700
@@ -25,9 +25,9 @@
 
 package java.lang.invoke;
 
-import java.lang.invoke.constant.ClassDesc;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.MethodTypeDesc;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.MethodTypeDesc;
 import java.lang.ref.Reference;
 import java.lang.ref.ReferenceQueue;
 import java.lang.ref.WeakReference;
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Mon Jun 04 14:59:22 2018 -0700
@@ -30,13 +30,13 @@
 import jdk.internal.vm.annotation.ForceInline;
 import jdk.internal.vm.annotation.Stable;
 
-import java.lang.invoke.constant.ClassDesc;
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
-import java.lang.invoke.constant.ConstantDescs;
-import java.lang.invoke.constant.ConstantMethodHandleDesc;
-import java.lang.invoke.constant.ConstantUtils;
-import java.lang.invoke.constant.DynamicConstantDesc;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.ConstantMethodHandleDesc;
+import java.lang.constant.ConstantUtils;
+import java.lang.constant.DynamicConstantDesc;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -46,7 +46,7 @@
 import java.util.function.Function;
 
 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
-import static java.lang.invoke.constant.ConstantDescs.CR_VarHandleDesc;
+import static java.lang.constant.ConstantDescs.CR_VarHandleDesc;
 
 /**
  * A VarHandle is a dynamically strongly typed reference to a variable, or to a
--- a/src/java.base/share/classes/java/lang/invoke/constant/AsTypeMethodHandleDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import jdk.internal.lang.annotation.Foldable;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.Optional;
-
-import static java.lang.invoke.constant.ConstantDescs.BSM_INVOKE;
-import static java.lang.invoke.constant.ConstantDescs.CR_MethodHandle;
-import static java.util.Objects.requireNonNull;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
- * {@link MethodHandle} constant that performs a {@link MethodHandle#asType(MethodType)}
- * adaptation on another {@link MethodHandle}.
- */
-final class AsTypeMethodHandleDesc extends DynamicConstantDesc<MethodHandle>
-        implements MethodHandleDesc {
-
-    private final MethodHandleDesc underlying;
-    private final MethodTypeDesc type;
-
-    AsTypeMethodHandleDesc(MethodHandleDesc underlying, MethodTypeDesc type) {
-        super(BSM_INVOKE, ConstantDescs.DEFAULT_NAME, CR_MethodHandle,
-              ConstantDescs.MHR_METHODHANDLE_ASTYPE, underlying, type);
-        this.underlying = requireNonNull(underlying);
-        this.type = requireNonNull(type);
-    }
-
-    @Override
-    @Foldable
-    public MethodTypeDesc methodType() {
-        return type;
-    }
-
-    @Override
-    public MethodHandle resolveConstantDesc(MethodHandles.Lookup lookup)
-            throws ReflectiveOperationException {
-        MethodHandle handle = underlying.resolveConstantDesc(lookup);
-        MethodType methodType = type.resolveConstantDesc(lookup);
-        return handle.asType(methodType);
-    }
-
-    @Override
-    public Optional<? extends ConstantDesc<ConstantDesc<MethodHandle>>> describeConstable() {
-        return ConstantUtils.symbolizeHelper(ConstantDescs.MHR_METHODHANDLEDESC_ASTYPE, ConstantDescs.CR_MethodHandleDesc,
-                                             underlying, type);
-    }
-
-    @Override
-    public String toString() {
-        return  String.format("%s.asType%s", underlying.toString(), type.displayDescriptor());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,271 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import jdk.internal.lang.annotation.Foldable;
-import java.lang.invoke.FieldTypeDescriptor;
-
-import java.util.stream.Stream;
-
-import sun.invoke.util.Wrapper;
-
-import static java.lang.invoke.constant.ConstantUtils.binaryToInternal;
-import static java.lang.invoke.constant.ConstantUtils.dropLastChar;
-import static java.lang.invoke.constant.ConstantUtils.internalToBinary;
-import static java.lang.invoke.constant.ConstantUtils.validateMemberName;
-import static java.util.Objects.requireNonNull;
-import static java.util.stream.Collectors.joining;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
- * {@link Class} constant.
- *
- * <p>For common system types, including all the primitive types, there are
- * predefined {@linkplain ClassDesc} constants in {@link ConstantDescs}.  To create
- * a {@linkplain ClassDesc} for a class or interface type, use {@link #of} or
- * {@link #ofDescriptor(String)}; to create a {@linkplain ClassDesc} for an array
- * type, use {@link #ofDescriptor(String)}, or first obtain a
- * {@linkplain ClassDesc} for the component type and then call the {@link #arrayType()}
- * or {@link #arrayType(int)} methods.
- *
- * @see ConstantDescs
- */
-public interface ClassDesc
-        extends ConstantDesc<Class<?>>,
-                Constable<ConstantDesc<Class<?>>>,
-                FieldTypeDescriptor<ClassDesc> {
-
-    /**
-     * Create a {@linkplain ClassDesc} given the name of a class or interface
-     * type, such as {@code "java.lang.String"}.  (To create a descriptor for an
-     * array type, either use {@link #ofDescriptor(String)}
-     * or {@link #arrayType()}; to create a descriptor for a primitive type, use
-     * {@link #ofDescriptor(String)} or use the predefined constants in
-     * {@link ConstantDescs}).
-     *
-     * @param name the fully qualified (dot-separated) binary class name
-     * @return a {@linkplain ClassDesc} describing the desired class
-     * @throws NullPointerException if any argument is {@code null}
-     * @throws IllegalArgumentException if the name string is not in the
-     * correct format
-     */
-    @Foldable
-    static ClassDesc of(String name) {
-        ConstantUtils.validateBinaryClassName(requireNonNull(name));
-        return ClassDesc.ofDescriptor("L" + binaryToInternal(name) + ";");
-    }
-
-    /**
-     * Create a {@linkplain ClassDesc} given a package name and an unqualified
-     * class name.
-     *
-     * @param packageName the package name (dot-separated)
-     * @param className the unqualified class name
-     * @return a {@linkplain ClassDesc} describing the desired class
-     * @throws NullPointerException if any argument is {@code null}
-     * @throws IllegalArgumentException if the package name or class name are
-     * not in the correct format
-     */
-    @Foldable
-    static ClassDesc of(String packageName, String className) {
-        ConstantUtils.validateBinaryClassName(requireNonNull(packageName));
-        validateMemberName(requireNonNull(className));
-        return ofDescriptor(String.format("L%s%s%s;",
-                                          binaryToInternal(packageName),
-                                          (packageName.length() > 0 ? "/" : ""),
-                                          className));
-    }
-
-    /**
-     * Create a {@linkplain ClassDesc} given a descriptor string.
-     *
-     * @param descriptor a field descriptor string, as per JVMS 4.3.2
-     * @return a {@linkplain ClassDesc} describing the desired class
-     * @throws NullPointerException if any argument is {@code null}
-     * @throws IllegalArgumentException if the name string is not in the
-     * correct format
-     * @jvms 4.3.2 Field Descriptors
-     */
-    @Foldable
-    static ClassDesc ofDescriptor(String descriptor) {
-        requireNonNull(descriptor);
-        return (descriptor.length() == 1)
-               ? new PrimitiveClassDesc(descriptor)
-               : new ConstantClassDesc(descriptor);
-    }
-
-    /**
-     * Create a {@linkplain ClassDesc} for an array type whose component type
-     * is described by this {@linkplain ClassDesc}.
-     *
-     * @return a {@linkplain ClassDesc} describing the array type
-     */
-    @Foldable
-    default ClassDesc arrayType() {
-        return arrayType(1);
-    }
-
-    /**
-     * Create a {@linkplain ClassDesc} for an array type of the specified rank,
-     * whose component type is described by this {@linkplain ClassDesc}.
-     *
-     * @param rank the rank of the array
-     * @return a {@linkplain ClassDesc} describing the array type
-     * @throws IllegalArgumentException if the rank is zero or negative
-     */
-    @Foldable
-    default ClassDesc arrayType(int rank) {
-        if (rank <= 0)
-            throw new IllegalArgumentException("rank: " + rank);
-        return ClassDesc.ofDescriptor("[".repeat(rank) + descriptorString());
-    }
-
-    /**
-     * Create a {@linkplain ClassDesc} for an inner class of the class or
-     * interface type described by this {@linkplain ClassDesc}.
-     *
-     * @param innerName the unqualified name of the inner class
-     * @return a {@linkplain ClassDesc} describing the inner class
-     * @throws NullPointerException if any argument is {@code null}
-     * @throws IllegalStateException if this {@linkplain ClassDesc} does not
-     * describe a class or interface type
-     */
-    @Foldable
-    default ClassDesc inner(String innerName) {
-        validateMemberName(innerName);
-        if (!isClassOrInterface())
-            throw new IllegalStateException("Outer class is not a class or interface type");
-        return ClassDesc.ofDescriptor(String.format("%s$%s;", dropLastChar(descriptorString()), innerName));
-    }
-
-    /**
-     * Create a {@linkplain ClassDesc} for an inner class of the class or
-     * interface type described by this {@linkplain ClassDesc}.
-     *
-     * @param firstInnerName the unqualified name of the first level of inner class
-     * @param moreInnerNames the unqualified name(s) of the remaining levels of
-     *                       inner class
-     * @return a {@linkplain ClassDesc} describing the inner class
-     * @throws NullPointerException if any argument is {@code null}
-     * @throws IllegalStateException if this {@linkplain ClassDesc} does not
-     * describe a class or interface type
-     */
-    @Foldable
-    default ClassDesc inner(String firstInnerName, String... moreInnerNames) {
-        if (!isClassOrInterface())
-            throw new IllegalStateException("Outer class is not a class or interface type");
-        return moreInnerNames.length == 0
-               ? inner(firstInnerName)
-               : inner(firstInnerName + Stream.of(moreInnerNames).collect(joining("$", "$", "")));
-    }
-
-    /**
-     * Returns whether this {@linkplain ClassDesc} describes an array type.
-     *
-     * @return whether this {@linkplain ClassDesc} describes an array type
-     */
-    default boolean isArray() {
-        return descriptorString().startsWith("[");
-    }
-
-    /**
-     * Returns whether this {@linkplain ClassDesc} describes a primitive type.
-     *
-     * @return whether this {@linkplain ClassDesc} describes a primitive type
-     */
-    default boolean isPrimitive() {
-        return descriptorString().length() == 1;
-    }
-
-    /**
-     * Returns whether this {@linkplain ClassDesc} describes a class or interface type.
-     *
-     * @return whether this {@linkplain ClassDesc} describes a class or interface type
-     */
-    default boolean isClassOrInterface() {
-        return descriptorString().startsWith("L");
-    }
-
-    /**
-     * Returns the component type of this {@linkplain ClassDesc}, if it describes
-     * an array type, or {@code null} otherwise.
-     *
-     * @return a {@linkplain ClassDesc} describing the component type, or {@code null}
-     * if this descriptor does not describe an array type
-     */
-    @Foldable
-    default ClassDesc componentType() {
-        return isArray() ? ClassDesc.ofDescriptor(descriptorString().substring(1)) : null;
-    }
-
-    /**
-     * Returns the package name of this {@linkplain ClassDesc}, if it describes
-     * a class or interface type.
-     *
-     * @return the package name, or the empty string if the class is in the
-     * default package
-     * @throws IllegalStateException if this {@linkplain ClassDesc} does not
-     * describe a class or interface type
-     */
-    default String packageName() {
-        if (!isClassOrInterface())
-            throw new IllegalStateException("not a class or interface");
-        String className = internalToBinary(ConstantUtils.dropFirstAndLastChar(descriptorString()));
-        int index = className.lastIndexOf('.');
-        return (index == -1) ? "" : className.substring(0, index);
-    }
-
-    /**
-     * Returns a human-readable name for the type described by this descriptor.
-     *
-     * @return the human-readable name
-     */
-    default String displayName() {
-        if (isPrimitive())
-            return Wrapper.forBasicType(descriptorString().charAt(0)).primitiveSimpleName();
-        else if (isClassOrInterface()) {
-            return descriptorString().substring(Math.max(1, descriptorString().lastIndexOf('/') + 1),
-                                                descriptorString().length() - 1);
-        }
-        else if (isArray()) {
-            int depth = ConstantUtils.arrayDepth(descriptorString());
-            ClassDesc c = this;
-            for (int i=0; i<depth; i++)
-                c = c.componentType();
-            return c.displayName() + "[]".repeat(depth);
-        }
-        else
-            throw new IllegalStateException(descriptorString());
-    }
-
-    /**
-     * Return a field type descriptor string for this type, as per JVMS 4.3.2
-     *
-     * @return the descriptor string
-     * @jvms 4.3.2 Field Descriptors
-     */
-    @Foldable
-    String descriptorString();
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/Constable.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import java.lang.invoke.VarHandle;
-import java.util.Optional;
-
-/**
- * Represents a type which is <em>constable</em>.  A constable type is one whose
- * values are constants that can be represented in the constant pool of a Java
- * classfile as described in JVMS 4.4, and whose instances can describe themselves
- * nominally as a {@link ConstantDesc}.
- *
- * <p>Some constable types have a native representation in the constant pool:
- * {@link String}, {@link Integer}, {@link Long}, {@link Float},
- * {@link Double}, {@link Class}, {@link MethodType}, and {@link MethodHandle}.
- * The types {@link String}, {@link Integer}, {@link Long}, {@link Float},
- * and {@link Double} serve as their own nominal descriptors; {@link Class},
- * {@link MethodType}, and {@link MethodHandle} have corresponding nominal
- * descriptors {@link ClassDesc}, {@link MethodTypeDesc}, and {@link MethodHandleDesc}.
- *
- * <p>Other reference types can be constable if their instances can describe
- * themselves in nominal form as a {@link ConstantDesc}. Examples in the Java SE
- * Platform API are types that support Java language features such as {@link Enum},
- * and runtime support classes such as {@link VarHandle}.  These are typically
- * described with a {@link DynamicConstantDesc}, which describes dynamically
- * generated constants (JVMS 4.4.10).
- *
- * <p>The nominal form of an instance of a constable type is obtained via
- * {@link #describeConstable()}. A {@linkplain Constable} need
- * not be able to (or may choose not to) describe all its instances in the form of
- * a {@link ConstantDesc}; this method returns an {@link Optional} that can be
- * empty to indicate that a nominal descriptor could not be created for an instance.
- * (For example, {@link MethodHandle} will produce nominal descriptors for direct
- * method handles, but not necessarily those produced by method handles
- * combinators.)
- * @jvms 4.4 The Constant Pool
- * @jvms 4.4.10 The CONSTANT_InvokeDynamic_info Structure
- *
- * @param <T> the type of the constant value
- */
-public interface Constable<T> {
-    /**
-     * Return a nominal descriptor for this instance, if one can be
-     * constructed, or an empty {@link Optional} if one cannot be.
-     *
-     * @return An {@link Optional} containing the resulting nominal descriptor,
-     * or an empty {@link Optional} if one cannot be constructed.
-     */
-    Optional<? extends ConstantDesc<T>> describeConstable();
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,128 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.lang.invoke.MethodHandles;
-import java.lang.reflect.Array;
-import java.util.Objects;
-import java.util.Optional;
-
-import static java.lang.invoke.constant.ConstantDescs.BSM_CLASSDESC;
-import static java.lang.invoke.constant.ConstantDescs.CR_ClassDesc;
-import static java.lang.invoke.constant.ConstantUtils.dropFirstAndLastChar;
-import static java.lang.invoke.constant.ConstantUtils.internalToBinary;
-import static java.util.Objects.requireNonNull;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a class,
- * interface, or array type.  A {@linkplain ConstantClassDesc} corresponds to a
- * {@code Constant_Class_info} entry in the constant pool of a classfile.
- */
-public final class ConstantClassDesc implements ClassDesc {
-    private final String descriptor;
-
-    /**
-     * Create a {@linkplain ClassDesc} from a descriptor string for a class or
-     * interface type
-     *
-     * @param descriptor a field descriptor string for a class or interface type,
-     *                   as per JVMS 4.3.2
-     * @throws IllegalArgumentException if the descriptor string is not a valid
-     * field descriptor string, or does not describe a class or interface type
-     * @jvms 4.3.2 Field Descriptors
-     */
-    ConstantClassDesc(String descriptor) {
-        requireNonNull(descriptor);
-        int len = ConstantUtils.matchSig(descriptor, 0, descriptor.length());
-        if (len == 0 || len == 1
-            || len != descriptor.length())
-            throw new IllegalArgumentException(String.format("not a valid reference type descriptor: %s", descriptor));
-        this.descriptor = descriptor;
-    }
-
-    @Override
-    public String descriptorString() {
-        return descriptor;
-    }
-
-    @Override
-    public Class<?> resolveConstantDesc(MethodHandles.Lookup lookup)
-            throws ReflectiveOperationException {
-        ClassDesc c = this;
-        int depth = ConstantUtils.arrayDepth(descriptorString());
-        for (int i=0; i<depth; i++)
-            c = c.componentType();
-
-        if (c.isPrimitive())
-            return lookup.findClass(descriptorString());
-        else {
-            Class<?> clazz = lookup.findClass(internalToBinary(dropFirstAndLastChar(c.descriptorString())));
-            for (int i = 0; i < depth; i++)
-                clazz = clazz.arrayType();
-            return clazz;
-        }
-    }
-
-    @Override
-    public Optional<? extends ConstantDesc<ConstantDesc<Class<?>>>> describeConstable() {
-        return Optional.of(DynamicConstantDesc.<ConstantDesc<Class<?>>>of(BSM_CLASSDESC, CR_ClassDesc)
-                                   .withArgs(descriptor));
-    }
-
-    /**
-     * Constant bootstrap method for representing a {@linkplain ClassDesc} in
-     * the constant pool of a classfile.
-     *
-     * @param lookup ignored
-     * @param name ignored
-     * @param clazz ignored
-     * @param descriptor a field descriptor string for the class, as per JVMS 4.3.2
-     * @return the {@linkplain ClassDesc}
-     * @jvms 4.3.2 Field Descriptors
-     */
-    public static ClassDesc constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
-                                              String descriptor) {
-        return ClassDesc.ofDescriptor(descriptor);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ClassDesc constant = (ClassDesc) o;
-        return Objects.equals(descriptor, constant.descriptorString());
-    }
-
-    @Override
-    public int hashCode() {
-        return descriptor != null ? descriptor.hashCode() : 0;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("ClassDesc[%s]", displayName());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.lang.invoke.Intrinsics;
-import java.lang.Enum.EnumDesc;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.invoke.VarHandle.VarHandleDesc;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a loadable
- * constant value, as defined in JVMS 4.4. Such a descriptor can be resolved via
- * {@link ConstantDesc#resolveConstantDesc(MethodHandles.Lookup)} to yield the
- * constant value itself.
- *
- * <p>Class names in a nominal descriptor, like class names in the constant pool
- * of a classfile, must be interpreted with respect to a particular to a class
- * loader, which is not part of the nominal descriptor.
- *
- * <p>Static constants that are expressible natively in the constant pool ({@link String},
- * {@link Integer}, {@link Long}, {@link Float}, and {@link Double}) implement
- * {@link ConstantDesc}, and serve as nominal descriptors for themselves.
- * Native linkable constants ({@link Class}, {@link MethodType}, and
- * {@link MethodHandle}) have counterpart {@linkplain ConstantDesc} types:
- * {@link ClassDesc}, {@link MethodTypeDesc}, and {@link MethodHandleDesc}.
- * Other constants are represented by subtypes of {@link DynamicConstantDesc}.
- *
- * <p>APIs that perform generation or parsing of bytecode are encouraged to use
- * {@linkplain ConstantDesc} to describe the operand of an {@code ldc} instruction
- * (including dynamic constants), the static bootstrap arguments of
- * dynamic constants and {@code invokedynamic} instructions, and other
- * bytecodes or classfile structures that make use of the constant pool.
- *
- * <p>The {@linkplain ConstantDesc} types are also used by {@link Intrinsics}
- * to express {@code ldc} instructions.
- *
- * <p>Constants describing various common constants (such as {@link ClassDesc}
- * instances for platform types) can be found in {@link ConstantDescs}.
- *
- * <p>Implementations of {@linkplain ConstantDesc} must be
- * <a href="../doc-files/ValueBased.html">value-based</a> classes.
- *
- * <p>Non-platform classes should not implement {@linkplain ConstantDesc} directly.
- * Instead, they should extend {@link DynamicConstantDesc} (as {@link EnumDesc}
- * and {@link VarHandleDesc} do.)
- *
- * <p>Nominal descriptors should be compared using the
- * {@link Object#equals(Object)} method. There is no guarantee that any
- * particular entity will always be represented by the same descriptor instance.
- *
- * @apiNote In the future, if the Java language permits, {@linkplain ConstantDesc}
- * may become a {@code sealed} interface, which would prohibit subclassing except by
- * explicitly permitted types.  Clients can assume that the following
- * set of concrete subtypes is exhaustive: {@link String}, {@link Integer},
- * {@link Long}, {@link Float}, {@link Double}, {@link ConstantClassDesc},
- * {@link ConstantMethodTypeDesc}, {@link ConstantMethodHandleDesc}, and
- * {@link DynamicConstantDesc}; this list may be extended to reflect future
- * changes to the constant pool format as defined in JVMS 4.4.
- *
- * @see Constable
- * @see Intrinsics
- * @see ConstantDescs
- *
- * @jvms 4.4 The Constant Pool
- */
-public interface ConstantDesc<T> {
-    /**
-     * Resolve this descriptor reflectively, emulating the resolution behavior
-     * of JVMS 5.4.3 and the access control behavior of JVMS 5.4.4.  The resolution
-     * and access control context is provided by the {@link MethodHandles.Lookup}
-     * parameter.  No caching of the resulting value is performed.
-     *
-     * @param lookup The {@link MethodHandles.Lookup} to provide name resolution
-     *               and access control context
-     * @return the resolved constant value
-     * @throws ReflectiveOperationException if a class, method, or field
-     * could not be reflectively resolved in the course of resolution
-     * @jvms 5.4.3 Resolution
-     * @jvms 5.4.4 Access Control
-     */
-    T resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException;
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantDescs.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,428 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import jdk.internal.lang.annotation.Foldable;
-
-import java.lang.Enum.EnumDesc;
-import java.lang.invoke.CallSite;
-import java.lang.invoke.ConstantBootstraps;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodHandles.Lookup;
-import java.lang.invoke.MethodType;
-import java.lang.invoke.VarHandle;
-import java.lang.invoke.VarHandle.VarHandleDesc;
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static java.lang.invoke.constant.MethodHandleDesc.Kind.STATIC;
-
-/**
- * Predefined values of <a href="package-summary.html#nominal">nominal descriptor</a>
- * for common constants, including descriptors for primitive class types and
- * other common platform types, and descriptors for method handles for standard
- * bootstrap methods.
- *
- * @see ConstantDesc
- */
-public final class ConstantDescs {
-    // No instances
-    private ConstantDescs() { }
-
-    /** Invocation name to use when no name is needed, such as the name of a
-     * constructor, or the invocation name of a dynamic constant or dynamic
-     * callsite when the bootstrap is known to ignore the invocation name.
-     */
-    public static final String DEFAULT_NAME = "_";
-
-    // Don't change the order of these declarations!
-
-    /** {@link ClassDesc} representing {@link Object} */
-    @Foldable
-    public static final ClassDesc CR_Object = ClassDesc.of("java.lang.Object");
-
-    /** {@link ClassDesc} representing {@link String} */
-    @Foldable
-    public static final ClassDesc CR_String = ClassDesc.of("java.lang.String");
-
-    /** {@link ClassDesc} representing {@link Class} */
-    @Foldable
-    public static final ClassDesc CR_Class = ClassDesc.of("java.lang.Class");
-
-    /** {@link ClassDesc} representing {@link Number} */
-    @Foldable
-    public static final ClassDesc CR_Number = ClassDesc.of("java.lang.Number");
-
-    /** {@link ClassDesc} representing {@link Integer} */
-    @Foldable
-    public static final ClassDesc CR_Integer = ClassDesc.of("java.lang.Integer");
-
-    /** {@link ClassDesc} representing {@link Long} */
-    @Foldable
-    public static final ClassDesc CR_Long = ClassDesc.of("java.lang.Long");
-
-    /** {@link ClassDesc} representing {@link Float} */
-    @Foldable
-    public static final ClassDesc CR_Float = ClassDesc.of("java.lang.Float");
-
-    /** {@link ClassDesc} representing {@link Double} */
-    @Foldable
-    public static final ClassDesc CR_Double = ClassDesc.of("java.lang.Double");
-
-    /** {@link ClassDesc} representing {@link Short} */
-    @Foldable
-    public static final ClassDesc CR_Short = ClassDesc.of("java.lang.Short");
-
-    /** {@link ClassDesc} representing {@link Byte} */
-    @Foldable
-    public static final ClassDesc CR_Byte = ClassDesc.of("java.lang.Byte");
-
-    /** {@link ClassDesc} representing {@link Character} */
-    @Foldable
-    public static final ClassDesc CR_Character = ClassDesc.of("java.lang.Character");
-
-    /** {@link ClassDesc} representing {@link Boolean} */
-    @Foldable
-    public static final ClassDesc CR_Boolean = ClassDesc.of("java.lang.Boolean");
-
-    /** {@link ClassDesc} representing {@link Void} */
-    @Foldable
-    public static final ClassDesc CR_Void = ClassDesc.of("java.lang.Void");
-
-    /** {@link ClassDesc} representing {@link Throwable} */
-    @Foldable
-    public static final ClassDesc CR_Throwable = ClassDesc.of("java.lang.Throwable");
-
-    /** {@link ClassDesc} representing {@link Exception} */
-    @Foldable
-    public static final ClassDesc CR_Exception = ClassDesc.of("java.lang.Exception");
-
-    /** {@link ClassDesc} representing {@link Enum} */
-    @Foldable
-    public static final ClassDesc CR_Enum = ClassDesc.of("java.lang.Enum");
-
-    /** {@link ClassDesc} representing {@link VarHandle} */
-    @Foldable
-    public static final ClassDesc CR_VarHandle = ClassDesc.of("java.lang.invoke.VarHandle");
-
-    /** {@link ClassDesc} representing {@link MethodHandles} */
-    @Foldable
-    public static final ClassDesc CR_MethodHandles = ClassDesc.of("java.lang.invoke.MethodHandles");
-
-    /** {@link ClassDesc} representing {@link MethodHandles.Lookup} */
-    @Foldable
-    public static final ClassDesc CR_MethodHandles_Lookup = CR_MethodHandles.inner("Lookup");
-
-    /** {@link ClassDesc} representing {@link MethodHandle} */
-    @Foldable
-    public static final ClassDesc CR_MethodHandle = ClassDesc.of("java.lang.invoke.MethodHandle");
-
-    /** {@link ClassDesc} representing {@link MethodType} */
-    @Foldable
-    public static final ClassDesc CR_MethodType = ClassDesc.of("java.lang.invoke.MethodType");
-
-    /** {@link ClassDesc} representing {@link CallSite} */
-    @Foldable
-    public static final ClassDesc CR_CallSite = ClassDesc.of("java.lang.invoke.CallSite");
-
-    /** {@link ClassDesc} representing {@link Collection} */
-    @Foldable
-    public static final ClassDesc CR_Collection = ClassDesc.of("java.util.Collection");
-
-    /** {@link ClassDesc} representing {@link List} */
-    @Foldable
-    public static final ClassDesc CR_List = ClassDesc.of("java.util.List");
-
-    /** {@link ClassDesc} representing {@link Set} */
-    @Foldable
-    public static final ClassDesc CR_Set = ClassDesc.of("java.util.Set");
-
-    /** {@link ClassDesc} representing {@link Map} */
-    @Foldable
-    public static final ClassDesc CR_Map = ClassDesc.of("java.util.Map");
-
-    /** {@link ClassDesc} representing {@link ConstantDesc} */
-    @Foldable
-    public static final ClassDesc CR_ConstantDesc = ClassDesc.of("java.lang.invoke.constant.ConstantDesc");
-
-    /** {@link ClassDesc} representing {@link ClassDesc} */
-    @Foldable
-    public static final ClassDesc CR_ClassDesc = ClassDesc.of("java.lang.invoke.constant.ClassDesc");
-
-    /** {@link ClassDesc} representing {@link EnumDesc} */
-    @Foldable
-    public static final ClassDesc CR_EnumDesc = CR_Enum.inner("EnumDesc");
-
-    /** {@link ClassDesc} representing {@link MethodTypeDesc} */
-    @Foldable
-    public static final ClassDesc CR_MethodTypeDesc = ClassDesc.of("java.lang.invoke.constant.MethodTypeDesc");
-
-    /** {@link ClassDesc} representing {@link ConstantClassDesc} */
-    public static final ClassDesc CR_ConstantClassDesc = ClassDesc.of("java.lang.invoke.constant.ConstantClassDesc");
-
-    /** {@link ClassDesc} representing {@link ConstantMethodTypeDesc} */
-    @Foldable
-    public static final ClassDesc CR_ConstantMethodTypeDesc = ClassDesc.of("java.lang.invoke.constant.ConstantMethodTypeDesc");
-
-    /** {@link ClassDesc} representing {@link MethodHandleDesc} */
-    @Foldable
-    public static final ClassDesc CR_MethodHandleDesc = ClassDesc.of("java.lang.invoke.constant.MethodHandleDesc");
-
-    /** {@link ClassDesc} representing {@link ConstantMethodHandleDesc} */
-    @Foldable
-    public static final ClassDesc CR_ConstantMethodHandleDesc = ClassDesc.of("java.lang.invoke.constant.ConstantMethodHandleDesc");
-
-    /** {@link ClassDesc} representing {@link VarHandleDesc} */
-    @Foldable
-    public static final ClassDesc CR_VarHandleDesc = CR_VarHandle.inner("VarHandleDesc");
-
-    /** {@link ClassDesc} representing {@link MethodHandleDesc.Kind} */
-    @Foldable
-    public static final ClassDesc CR_MethodHandleDesc_Kind = CR_MethodHandleDesc.inner("Kind");
-
-    /** {@link ClassDesc} representing {@link DynamicConstantDesc} */
-    @Foldable
-    public static final ClassDesc CR_DynamicConstantDesc = ClassDesc.of("java.lang.invoke.constant.DynamicConstantDesc");
-
-    /** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */
-    @Foldable
-    public static final ClassDesc CR_DynamicCallSiteDesc = ClassDesc.of("java.lang.invoke.constant.DynamicCallSiteDesc");
-
-    /** {@link ClassDesc} representing {@link ConstantBootstraps} */
-    @Foldable
-    public static final ClassDesc CR_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
-
-    // Used by MethodHandleDesc, but initialized here before reference to
-    // MethodHandleDesc to avoid static initalization circularities
-    /* non-public */ static final ClassDesc[] INDY_BOOTSTRAP_ARGS = {
-            ConstantDescs.CR_MethodHandles_Lookup,
-            ConstantDescs.CR_String,
-            ConstantDescs.CR_MethodType };
-
-    /* non-public */ static final ClassDesc[] CONDY_BOOTSTRAP_ARGS = {
-            ConstantDescs.CR_MethodHandles_Lookup,
-            ConstantDescs.CR_String,
-            ConstantDescs.CR_Class };
-
-    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#primitiveClass(Lookup, String, Class)} */
-    @Foldable
-    public static final ConstantMethodHandleDesc BSM_PRIMITIVE_CLASS
-            = ofConstantBootstrap(CR_ConstantBootstraps, "primitiveClass",
-                                  CR_Class);
-
-    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#enumConstant(Lookup, String, Class)} */
-    @Foldable
-    public static final ConstantMethodHandleDesc BSM_ENUM_CONSTANT
-            = ofConstantBootstrap(CR_ConstantBootstraps, "enumConstant",
-                                  CR_Enum);
-
-    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#nullConstant(Lookup, String, Class)} */
-    @Foldable
-    public static final ConstantMethodHandleDesc BSM_NULL_CONSTANT
-            = ofConstantBootstrap(CR_ConstantBootstraps, "nullConstant",
-                                  ConstantDescs.CR_Object);
-
-    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#fieldVarHandle(Lookup, String, Class, Class, Class)} */
-    @Foldable
-    public static final ConstantMethodHandleDesc BSM_VARHANDLE_FIELD
-            = ofConstantBootstrap(CR_ConstantBootstraps, "fieldVarHandle",
-                                  CR_VarHandle, CR_Class, CR_Class);
-
-    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#staticFieldVarHandle(Lookup, String, Class, Class, Class)} */
-    @Foldable
-    public static final ConstantMethodHandleDesc BSM_VARHANDLE_STATIC_FIELD
-            = ofConstantBootstrap(CR_ConstantBootstraps, "staticFieldVarHandle",
-                                  CR_VarHandle, CR_Class, CR_Class);
-
-    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#arrayVarHandle(Lookup, String, Class, Class)} */
-    @Foldable
-    public static final ConstantMethodHandleDesc BSM_VARHANDLE_ARRAY
-            = ofConstantBootstrap(CR_ConstantBootstraps, "arrayVarHandle",
-                                  CR_VarHandle, CR_Class);
-
-    /** {@link MethodHandleDesc} representing {@link ConstantBootstraps#invoke(Lookup, String, Class, MethodHandle, Object...)} */
-    @Foldable
-    public static final ConstantMethodHandleDesc BSM_INVOKE
-            = ofConstantBootstrap(CR_ConstantBootstraps, "invoke",
-                                  CR_Object, CR_MethodHandle, CR_Object.arrayType());
-
-    /** {@link ClassDesc} representing the primitive type {@code int} */
-    @Foldable
-    public static final ClassDesc CR_int = ClassDesc.ofDescriptor("I");
-
-    /** {@link ClassDesc} representing the primitive type {@code long} */
-    @Foldable
-    public static final ClassDesc CR_long = ClassDesc.ofDescriptor("J");
-
-    /** {@link ClassDesc} representing the primitive type {@code float} */
-    @Foldable
-    public static final ClassDesc CR_float = ClassDesc.ofDescriptor("F");
-
-    /** {@link ClassDesc} representing the primitive type {@code double} */
-    @Foldable
-    public static final ClassDesc CR_double = ClassDesc.ofDescriptor("D");
-
-    /** {@link ClassDesc} representing the primitive type {@code short} */
-    @Foldable
-    public static final ClassDesc CR_short = ClassDesc.ofDescriptor("S");
-
-    /** {@link ClassDesc} representing the primitive type {@code byte} */
-    @Foldable
-    public static final ClassDesc CR_byte = ClassDesc.ofDescriptor("B");
-
-    /** {@link ClassDesc} representing the primitive type {@code char} */
-    @Foldable
-    public static final ClassDesc CR_char = ClassDesc.ofDescriptor("C");
-
-    /** {@link ClassDesc} representing the primitive type {@code boolean} */
-    @Foldable
-    public static final ClassDesc CR_boolean = ClassDesc.ofDescriptor("Z");
-
-    /** {@link ClassDesc} representing the primitive type {@code void} */
-    @Foldable
-    public static final ClassDesc CR_void = ClassDesc.ofDescriptor("V");
-
-    /** Nominal descriptor representing the constant {@code null} */
-    @Foldable
-    public static final ConstantDesc<?> NULL
-            = DynamicConstantDesc.of(ConstantDescs.BSM_NULL_CONSTANT,
-                                     ConstantDescs.CR_Object);
-
-    // Used by XxxDesc classes, but need to be here to avoid bootstrap cycles
-    static final ConstantMethodHandleDesc MHR_METHODTYPEDESC_FACTORY
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_MethodTypeDesc, "ofDescriptor",
-                                  CR_MethodTypeDesc, CR_String);
-
-    static final ConstantMethodHandleDesc MHR_CLASSDESC_FACTORY
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_ClassDesc, "ofDescriptor",
-                                  CR_ClassDesc, CR_String);
-
-    static final ConstantMethodHandleDesc MHR_METHODHANDLEDESC_FACTORY
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_MethodHandleDesc, "of",
-                                  CR_MethodHandleDesc, CR_MethodHandleDesc_Kind, CR_ClassDesc, CR_String, CR_MethodTypeDesc);
-
-    static final ConstantMethodHandleDesc MHR_METHODHANDLE_ASTYPE
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_MethodHandle, "asType",
-                                  CR_MethodHandle, CR_MethodType);
-
-    static final ConstantMethodHandleDesc MHR_METHODHANDLEDESC_ASTYPE
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_MethodHandleDesc, "asType",
-                                  CR_MethodHandleDesc, CR_MethodTypeDesc);
-
-    static final ConstantMethodHandleDesc MHR_DYNAMICCONSTANTDESC_FACTORY
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_DynamicConstantDesc, "of",
-                                  CR_DynamicConstantDesc, CR_MethodHandleDesc, CR_String, CR_ClassDesc);
-
-    static final ConstantMethodHandleDesc MHR_DYNAMICCONSTANTDESC_WITHARGS
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_DynamicConstantDesc, "withArgs",
-                                  CR_DynamicConstantDesc, CR_ConstantDesc.arrayType());
-
-    static final ConstantMethodHandleDesc MHR_ENUMDESC_FACTORY
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_EnumDesc, "of",
-                                  CR_EnumDesc, CR_ClassDesc, CR_String);
-
-    /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofField(Lookup, String, Class, Class, String, Class)} */
-    public static final ConstantMethodHandleDesc MHR_VARHANDLEDESC_OFFIELD
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofField",
-                                  CR_VarHandleDesc, CR_ClassDesc, CR_String, CR_ClassDesc);
-    /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofStaticField(Lookup, String, Class, Class, String, Class)} */
-    public static final ConstantMethodHandleDesc MHR_VARHANDLEDESC_OFSTATIC
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofStaticField",
-                                  CR_VarHandleDesc, CR_ClassDesc, CR_String, CR_ClassDesc);
-
-    /** {@link MethodHandleDesc} representing {@link VarHandleDesc#ofArray(Lookup, String, Class, Class, Class)} */
-    public static final ConstantMethodHandleDesc MHR_VARHANDLEDESC_OFARRAY
-            = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_VarHandleDesc, "ofArray",
-                                  CR_VarHandleDesc, CR_ClassDesc);
-
-    static final ConstantMethodHandleDesc BSM_CLASSDESC
-            = ConstantDescs.ofConstantBootstrap(CR_ConstantClassDesc,
-                                                "constantBootstrap", CR_ClassDesc, CR_String);
-
-    static final ConstantMethodHandleDesc BSM_METHODTYPEDESC
-            = ConstantDescs.ofConstantBootstrap(CR_ConstantMethodTypeDesc,
-                                                "constantBootstrap", CR_ConstantMethodTypeDesc, CR_String);
-
-    static final ConstantMethodHandleDesc BSM_METHODHANDLEDESC
-            = ConstantDescs.ofConstantBootstrap(CR_ConstantMethodHandleDesc,
-                                                "constantBootstrap", CR_ConstantMethodHandleDesc,
-                                                CR_String, CR_String, CR_String, CR_String);
-
-    /** {@link MethodHandleDesc} representing {@link EnumDesc#constantBootstrap(Lookup, String, Class, String, String)} */
-    public static final ConstantMethodHandleDesc BSM_ENUMDESC
-            = ConstantDescs.ofConstantBootstrap(CR_EnumDesc, "constantBootstrap", CR_EnumDesc, CR_String, CR_String);
-
-    static final ConstantMethodHandleDesc BSM_DYNAMICCONSTANTDESC
-            = ConstantDescs.ofConstantBootstrap(CR_DynamicConstantDesc,
-                                                "constantBootstrap",
-                                                CR_DynamicConstantDesc,
-                                                CR_String, CR_String, CR_String, CR_String, CR_String, CR_ConstantDesc.arrayType());
-
-
-    /**
-     * Return a {@link MethodHandleDesc} corresponding to a bootstrap method for
-     * an {@code invokedynamic} callsite, which is a static method whose leading
-     * parameter types are {@code Lookup}, {@code String}, and {@code MethodType}.
-     *
-     * @param clazz the class declaring the method
-     * @param name the name of the method, as per JVMS 4.2.2
-     * @param returnType the return type of the method
-     * @param paramTypes the types of the static bootstrap arguments, if any
-     * @return the {@link MethodHandleDesc}
-     * @throws NullPointerException if any of the arguments are null
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    public static ConstantMethodHandleDesc ofCallsiteBootstrap(ClassDesc clazz,
-                                                               String name,
-                                                               ClassDesc returnType,
-                                                               ClassDesc... paramTypes) {
-        return MethodHandleDesc.of(STATIC, clazz, name, MethodTypeDesc.of(returnType, paramTypes).insertParameterTypes(0, INDY_BOOTSTRAP_ARGS));
-    }
-
-    /**
-     * Return a {@link MethodHandleDesc} corresponding to a bootstrap method for a
-     * dynamic constant, which is a static method whose leading arguments are
-     * {@code Lookup}, {@code String}, and {@code Class}.
-     *
-     * @param clazz the class declaring the method
-     * @param name the name of the method, as per JVMS 4.2.2
-     * @param returnType the return type of the method
-     * @param paramTypes the types of the static bootstrap arguments, if any
-     * @return the {@link MethodHandleDesc}
-     * @throws NullPointerException if any of the arguments are null
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    public static ConstantMethodHandleDesc ofConstantBootstrap(ClassDesc clazz,
-                                                               String name,
-                                                               ClassDesc returnType,
-                                                               ClassDesc... paramTypes) {
-        return MethodHandleDesc.of(STATIC, clazz, name, MethodTypeDesc.of(returnType, paramTypes).insertParameterTypes(0, CONDY_BOOTSTRAP_ARGS));
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandleInfo;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.Objects;
-import java.util.Optional;
-
-import jdk.internal.lang.annotation.Foldable;
-
-import static java.lang.invoke.constant.ConstantDescs.BSM_METHODHANDLEDESC;
-import static java.lang.invoke.constant.ConstantDescs.CR_ConstantMethodHandleDesc;
-import static java.lang.invoke.constant.ConstantUtils.validateClassOrInterface;
-import static java.lang.invoke.constant.ConstantUtils.validateMemberName;
-import static java.lang.invoke.constant.MethodHandleDesc.Kind.CONSTRUCTOR;
-import static java.util.Objects.requireNonNull;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a direct
- * {@link MethodHandle}.  A {@linkplain ConstantMethodHandleDesc} corresponds to
- * a {@code Constant_MethodHandle_info} entry in the constant pool of a classfile.
- */
-public final class ConstantMethodHandleDesc implements MethodHandleDesc {
-
-    private final Kind kind;
-    private final ClassDesc owner;
-    private final String name;
-    private final MethodTypeDesc type;
-
-    /**
-     * Construct a {@linkplain ConstantMethodHandleDesc} for a method or field
-     * from a kind, owner, name, and type
-     *
-     * @param kind the kind of the method handle
-     * @param owner the declaring class or interface for the method
-     * @param name the name of the method (ignored if {@code kind} is
-     * {@code CONSTRUCTOR}), as per JVMS 4.2.2
-     * @param type the type of the method
-     * @throws NullPointerException if any non-ignored argument is null
-     * @throws IllegalArgumentException if {@code kind} describes a field accessor,
-     * and {@code type} is not consistent with that kind of field accessor, or if
-     * {@code kind} describes a constructor, and the return type of {@code type}
-     * is not {@code void}
-     * @jvms 4.2.2 Unqualified Names
-     */
-    ConstantMethodHandleDesc(Kind kind, ClassDesc owner, String name, MethodTypeDesc type) {
-        if (kind == CONSTRUCTOR)
-            name = "<init>";
-
-        requireNonNull(kind);
-        validateClassOrInterface(requireNonNull(owner));
-        validateMemberName(requireNonNull(name));
-        requireNonNull(type);
-
-        switch (kind) {
-            case CONSTRUCTOR: validateConstructor(type); break;
-            case GETTER: validateFieldType(type, false, true); break;
-            case SETTER: validateFieldType(type, true, true); break;
-            case STATIC_GETTER: validateFieldType(type, false, false); break;
-            case STATIC_SETTER: validateFieldType(type, true, false); break;
-        }
-
-        this.kind = kind;
-        this.owner = owner;
-        this.name = name;
-        this.type = type;
-    }
-
-    private static void validateFieldType(MethodTypeDesc type, boolean isSetter, boolean isVirtual) {
-        boolean isVoid = type.returnType().descriptorString().equals("V");
-        int expectedParams = (isSetter ? 1 : 0) + (isVirtual ? 1 : 0);
-        if (isVoid != isSetter
-            || type.parameterCount() != expectedParams
-            || (isVirtual && type.parameterType(0).isPrimitive())) {
-            String expectedType = String.format("(%s%s)%s", (isVirtual ? "R" : ""),
-                                                (isSetter ? "T" : ""), (isSetter ? "V" : "T"));
-            throw new IllegalArgumentException(String.format("Expected type of %s for getter, found %s", expectedType, type));
-        }
-    }
-
-    private static void validateConstructor(MethodTypeDesc type) {
-        if (!type.returnType().descriptorString().equals("V")) {
-            throw new IllegalArgumentException(String.format("Expected type of (T*)V for constructor, found %s", type));
-        }
-    }
-
-    /**
-     * Return the {@code kind} of the method handle described by this nominal
-     * descriptor.
-     *
-     * @return the {@link Kind}
-     */
-    @Foldable
-    public Kind kind() { return kind; }
-
-    /**
-     * Return the {@code refKind} of the method handle described by this nominal
-     * reference, as defined by {@link MethodHandleInfo}.
-     *
-     * @return the reference kind
-     */
-    @Foldable
-    public int refKind() { return kind.refKind; }
-
-    /**
-     * Return a {@link ClassDesc} describing the class declaring the
-     * method or field described by this nominal descriptor.
-     *
-     * @return the class declaring the method or field
-     */
-    @Foldable
-    public ClassDesc owner() {
-        return owner;
-    }
-
-    /**
-     * Return the name of the method or field described by this nominal descriptor.
-     *
-     * @return the name of the method or field
-     */
-    @Foldable
-    public String methodName() {
-        return name;
-    }
-
-    /**
-     * Return a {@link MethodTypeDesc} describing the invocation type of the
-     * method handle described by this nominal descriptor
-     *
-     * @return the method type
-     */
-    @Foldable
-    public MethodTypeDesc methodType() {
-        return type;
-    }
-
-    public MethodHandle resolveConstantDesc(MethodHandles.Lookup lookup)
-            throws ReflectiveOperationException {
-        Class<?> resolvedOwner = owner.resolveConstantDesc(lookup);
-        MethodType resolvedType = this.type.resolveConstantDesc(lookup);
-        switch (kind) {
-            case STATIC:
-                return lookup.findStatic(resolvedOwner, name, resolvedType);
-            case INTERFACE_VIRTUAL:
-            case VIRTUAL:
-                return lookup.findVirtual(resolvedOwner, name, resolvedType);
-            case SPECIAL:
-                return lookup.findSpecial(resolvedOwner, name, resolvedType, lookup.lookupClass());
-            case CONSTRUCTOR:
-                return lookup.findConstructor(resolvedOwner, resolvedType);
-            case GETTER:
-                return lookup.findGetter(resolvedOwner, name, resolvedType.returnType());
-            case STATIC_GETTER:
-                return lookup.findStaticGetter(resolvedOwner, name, resolvedType.returnType());
-            case SETTER:
-                return lookup.findSetter(resolvedOwner, name, resolvedType.parameterType(1));
-            case STATIC_SETTER:
-                return lookup.findStaticSetter(resolvedOwner, name, resolvedType.parameterType(0));
-            default:
-                throw new IllegalStateException(kind.name());
-        }
-    }
-
-    @Override
-    public Optional<? extends ConstantDesc<ConstantDesc<MethodHandle>>> describeConstable() {
-        return Optional.of(DynamicConstantDesc.<ConstantDesc<MethodHandle>>of(BSM_METHODHANDLEDESC, CR_ConstantMethodHandleDesc)
-                                              .withArgs(kind.toString(), owner.descriptorString(), name, type.descriptorString()));
-    }
-
-    /**
-     * Constant bootstrap method for representing a {@linkplain MethodHandleDesc} in
-     * the constant pool of a classfile.
-     *
-     * @param lookup ignored
-     * @param name ignored
-     * @param clazz ignored
-     * @param bsmKindName The name of an {@code enum} constant from {@link Kind}
-     * @param memberOwner A field type descriptor for the class declaring the
-     *                 method, field, or constructor, as per JVMS 4.3.2
-     * @param memberName The name of the method or field, as per JVMS 4.2.2
-     * @param memberType A method type descriptor for the method handle being
-     *                described, as per JVMS 4.3.3
-     * @return the {@linkplain MethodHandleDesc}
-     * @jvms 4.2.2 Unqualified Names
-     * @jvms 4.3.2 Field Descriptors
-     * @jvms 4.3.3 Method Descriptors
-     */
-    public static ConstantMethodHandleDesc constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
-                                                     String bsmKindName, String memberOwner, String memberName, String memberType) {
-        return MethodHandleDesc.of(MethodHandleDesc.Kind.valueOf(bsmKindName),
-                                   ClassDesc.ofDescriptor(memberOwner), memberName,
-                                   MethodTypeDesc.ofDescriptor(memberType));
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        ConstantMethodHandleDesc desc = (ConstantMethodHandleDesc) o;
-        return kind == desc.kind &&
-               Objects.equals(owner, desc.owner) &&
-               Objects.equals(name, desc.name) &&
-               Objects.equals(type, desc.type);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(kind, owner, name, type);
-    }
-
-    @Override
-    public String toString() {
-        return String.format("MethodHandleDesc[%s/%s::%s%s]", kind, owner.displayName(), name, type.displayDescriptor());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodTypeDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-
-import jdk.internal.lang.annotation.Foldable;
-
-import static java.lang.invoke.constant.ConstantDescs.BSM_METHODTYPEDESC;
-import static java.lang.invoke.constant.ConstantDescs.CR_ConstantMethodTypeDesc;
-import static java.util.Objects.requireNonNull;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
- * {@link MethodType}.  A {@linkplain ConstantMethodTypeDesc} corresponds to a
- * {@code Constant_MethodType_info} entry in the constant pool of a classfile.
- */
-public final class ConstantMethodTypeDesc implements MethodTypeDesc {
-    private final ClassDesc returnType;
-    private final ClassDesc[] argTypes;
-
-    /**
-     * Construct a {@linkplain MethodTypeDesc} with the specified return type
-     * and parameter types
-     *
-     * @param returnType a {@link ClassDesc} describing the return type
-     * @param argTypes {@link ClassDesc}s describing the parameter types
-     */
-    ConstantMethodTypeDesc(ClassDesc returnType, ClassDesc[] argTypes) {
-        this.returnType = requireNonNull(returnType);
-        this.argTypes = requireNonNull(argTypes);
-
-        for (ClassDesc cr : argTypes)
-            if (cr.isPrimitive() && cr.descriptorString().equals("V"))
-                throw new IllegalArgumentException("Void parameters not permitted");
-    }
-
-    /**
-     * Create a {@linkplain ConstantMethodTypeDesc} given a method descriptor string.
-     *
-     * @param descriptor the method descriptor string, as per JVMS 4.3.3
-     * @return a {@linkplain ConstantMethodTypeDesc} describing the desired method type
-     * @throws IllegalArgumentException if the descriptor string is not a valid
-     * method descriptor
-     * @jvms 4.3.3 Method Descriptors
-     */
-    @Foldable
-    static ConstantMethodTypeDesc ofDescriptor(String descriptor) {
-        requireNonNull(descriptor);
-        List<String> types = ConstantUtils.parseMethodDescriptor(descriptor);
-        ClassDesc[] paramTypes = types.stream().skip(1).map(ClassDesc::ofDescriptor).toArray(ClassDesc[]::new);
-        return new ConstantMethodTypeDesc(ClassDesc.ofDescriptor(types.get(0)), paramTypes);
-    }
-
-    @Foldable
-    @Override
-    public ClassDesc returnType() {
-        return returnType;
-    }
-
-    @Foldable
-    @Override
-    public int parameterCount() {
-        return argTypes.length;
-    }
-
-    @Foldable
-    @Override
-    public ClassDesc parameterType(int index) {
-        return argTypes[index];
-    }
-
-    @Override
-    public List<ClassDesc> parameterList() {
-        return List.of(argTypes);
-    }
-
-    @Override
-    public ClassDesc[] parameterArray() {
-        return argTypes.clone();
-    }
-
-    @Foldable
-    @Override
-    public MethodTypeDesc changeReturnType(ClassDesc returnType) {
-        return MethodTypeDesc.of(returnType, argTypes);
-    }
-
-    @Foldable
-    @Override
-    public MethodTypeDesc changeParameterType(int index, ClassDesc paramType) {
-        ClassDesc[] newArgs = argTypes.clone();
-        newArgs[index] = paramType;
-        return MethodTypeDesc.of(returnType, newArgs);
-    }
-
-    @Foldable
-    @Override
-    public MethodTypeDesc 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));
-        ClassDesc[] newArgs = new ClassDesc[argTypes.length - (end - start)];
-        System.arraycopy(argTypes, 0, newArgs, 0, start);
-        System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
-        return MethodTypeDesc.of(returnType, newArgs);
-    }
-
-    @Foldable
-    @Override
-    public MethodTypeDesc insertParameterTypes(int pos, ClassDesc... paramTypes) {
-        if (pos < 0 || pos > argTypes.length)
-            throw new IndexOutOfBoundsException(pos);
-        ClassDesc[] newArgs = new ClassDesc[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 MethodTypeDesc.of(returnType, newArgs);
-    }
-
-    @Override
-    public MethodType resolveConstantDesc(MethodHandles.Lookup lookup) {
-        return MethodType.fromMethodDescriptorString(descriptorString(), lookup.lookupClass().getClassLoader());
-    }
-
-    @Override
-    public Optional<? extends ConstantDesc<ConstantDesc<MethodType>>> describeConstable() {
-        return Optional.of(DynamicConstantDesc.<ConstantDesc<MethodType>>of(BSM_METHODTYPEDESC, CR_ConstantMethodTypeDesc)
-                                   .withArgs(descriptorString()));
-    }
-
-    /**
-     * Constant bootstrap method for representing a {@linkplain MethodTypeDesc} in
-     * the constant pool of a classfile.
-     *
-     * @param lookup ignored
-     * @param name ignored
-     * @param clazz ignored
-     * @param descriptor a method descriptor string for the method type, as per JVMS 4.3.3
-     * @return the {@linkplain MethodTypeDesc}
-     * @jvms 4.3.3 Method Descriptors
-     */
-    public static ConstantMethodTypeDesc constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
-                                                   String descriptor) {
-        return (ConstantMethodTypeDesc)MethodTypeDesc.ofDescriptor(descriptor);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-
-        ConstantMethodTypeDesc constant = (ConstantMethodTypeDesc) o;
-
-        return returnType.equals(constant.returnType)
-               && Arrays.equals(argTypes, constant.argTypes);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = returnType.hashCode();
-        result = 31 * result + Arrays.hashCode(argTypes);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("MethodTypeDesc[%s]", displayDescriptor());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.util.*;
-import static java.util.Objects.requireNonNull;
-
-/**
- * Helper methods for the implementation of {@code java.lang.invoke.constant}.
- */
-public class ConstantUtils {
-    /** an empty constant descriptor */
-    public static final ConstantDesc<?>[] EMPTY_CONSTANTDESC = new ConstantDesc<?>[0];
-    static final Constable<?>[] EMPTY_CONSTABLE = new Constable<?>[0];
-
-    private static final Set<String> pointyNames = Set.of("<init>", "<clinit>");
-
-    static String validateBinaryClassName(String name) {
-        for (int i=0; i<name.length(); i++) {
-            char ch = name.charAt(i);
-            if (ch == ';' || ch == '[' || ch == '/')
-                throw new IllegalArgumentException("Invalid class name: " + name);
-        }
-        return name;
-    }
-
-    /**
-     * validates a member name
-     * @param name the name of the member
-     * @return the name passed if valid
-     */
-    public static String validateMemberName(String name) {
-        requireNonNull(name);
-        if (name.length() == 0)
-            throw new IllegalArgumentException("zero-length member name");
-        for (int i=0; i<name.length(); i++) {
-            char ch = name.charAt(i);
-            if (ch == '.' || ch == ';' || ch == '[' || ch == '/')
-                throw new IllegalArgumentException("Invalid member name: " + name);
-            if (ch == '<' || ch == '>') {
-                if (!pointyNames.contains(name))
-                    throw new IllegalArgumentException("Invalid member name: " + name);
-            }
-        }
-        return name;
-    }
-
-    static void validateClassOrInterface(ClassDesc clazz) {
-        if (!clazz.isClassOrInterface())
-            throw new IllegalArgumentException("not a class or interface type: " + clazz);
-    }
-
-    static int arrayDepth(String descriptorString) {
-        int depth = 0;
-        while (descriptorString.charAt(depth) == '[')
-            depth++;
-        return depth;
-    }
-
-    static String binaryToInternal(String name) {
-        return name.replace('.', '/');
-    }
-
-    static String internalToBinary(String name) {
-        return name.replace('/', '.');
-    }
-
-    static String dropLastChar(String s) {
-        return s.substring(0, s.length() - 1);
-    }
-
-    static String dropFirstAndLastChar(String s) {
-        return s.substring(1, s.length() - 1);
-    }
-
-    /**
-     * Produce an {@code Optional<DynamicConstantDesc<T>>} describing the invocation
-     * of the specified bootstrap with the specified arguments.  The arguments will
-     * be converted to nominal descriptors using the provided lookup.  Helper
-     * method for implementing {@link Constable#describeConstable()}.
-     *
-     * @param <T> the type of the resulting constant
-     * @param bootstrap nominal descriptor for the bootstrap method
-     * @param type nominal descriptor for the type of the resulting constant
-     * @param args nominal descriptors for the bootstrap arguments
-     * @return the nominal descriptor for the dynamic constant
-     */
-    public static<T> Optional<DynamicConstantDesc<T>> symbolizeHelper(MethodHandleDesc bootstrap,
-                                                               ClassDesc type,
-                                                               Constable<?>... args) {
-        requireNonNull(bootstrap);
-        requireNonNull(type);
-        requireNonNull(args);
-        try {
-            ConstantDesc<?>[] quotedArgs = new ConstantDesc<?>[args.length + 1];
-            quotedArgs[0] = bootstrap;
-            for (int i=0; i<args.length; i++)
-                quotedArgs[i+1] = args[i].describeConstable().orElseThrow();
-            return Optional.of(DynamicConstantDesc.of(ConstantDescs.BSM_INVOKE, ConstantDescs.DEFAULT_NAME,
-                                                      type, quotedArgs));
-        }
-        catch (NoSuchElementException e) {
-            return Optional.empty();
-        }
-    }
-
-    /**
-     * Parse a method descriptor string, and return a list of field descriptor
-     * strings, return type first, then parameter types
-     *
-     * @param descriptor the descriptor string
-     * @return the list of types
-     * @throws IllegalArgumentException if the descriptor string is not valid
-     */
-    static List<String> parseMethodDescriptor(String descriptor) {
-        int cur = 0, end = descriptor.length();
-        ArrayList<String> ptypes = new ArrayList<>();
-
-        if (cur >= end || descriptor.charAt(cur) != '(')
-            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
-
-        ++cur;  // skip '('
-        while (cur < end && descriptor.charAt(cur) != ')') {
-            int len = matchSig(descriptor, cur, end);
-            if (len == 0 || descriptor.charAt(cur) == 'V')
-                throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
-            ptypes.add(descriptor.substring(cur, cur + len));
-            cur += len;
-        }
-        if (cur >= end)
-            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
-        ++cur;  // skip ')'
-
-        int rLen = matchSig(descriptor, cur, end);
-        if (rLen == 0 || cur + rLen != end)
-            throw new IllegalArgumentException("Bad method descriptor: " + descriptor);
-        ptypes.add(0, descriptor.substring(cur, cur + rLen));
-        return ptypes;
-    }
-
-    /**
-     * Validate that the characters at [start, end) within the provided string
-     * describe a valid field type descriptor.
-     *
-     * @param str the descriptor string
-     * @param start the starting index into the string
-     * @param end the ending index within the string
-     * @return the length of the descriptor, or 0 if it is not a descriptor
-     * @throws IllegalArgumentException if the descriptor string is not valid
-     */
-    static int matchSig(String str, int start, int end) {
-        if (start >= end || start >= str.length() || end > str.length())
-            return 0;
-        char c = str.charAt(start);
-        if (c == 'L') {
-            int endc = str.indexOf(';', start);
-            int badc = str.indexOf('.', start);
-            if (badc >= 0 && badc < endc)
-                return 0;
-            badc = str.indexOf('[', start);
-            if (badc >= 0 && badc < endc)
-                return 0;
-            return (endc < 0) ? 0 : endc - start + 1;
-        } else if (c == '[') {
-            int t = matchSig(str, start+1, end);
-            return (t > 0) ? t + 1 : 0;
-        } else {
-            return ("IJCSBFDZV".indexOf(c) >= 0) ? 1 : 0;
-        }
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/DynamicCallSiteDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,279 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import jdk.internal.lang.annotation.Foldable;
-
-import java.lang.invoke.CallSite;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.util.Arrays;
-import java.util.Objects;
-import java.util.stream.Stream;
-
-import static java.lang.invoke.constant.ConstantDescs.CR_String;
-import static java.lang.invoke.constant.ConstantUtils.EMPTY_CONSTANTDESC;
-import static java.lang.invoke.constant.ConstantUtils.validateMemberName;
-import static java.util.Objects.requireNonNull;
-import static java.util.stream.Collectors.joining;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for an
- * {@code invokedynamic} call site.
- *
- * <p>Concrete subtypes of {@linkplain DynamicCallSiteDesc} must be
- * <a href="../doc-files/ValueBased.html">value-based</a>.
- */
-public class DynamicCallSiteDesc {
-
-    private final ConstantMethodHandleDesc bootstrapMethod;
-    private final ConstantDesc<?>[] bootstrapArgs;
-    private final String invocationName;
-    private final MethodTypeDesc invocationType;
-
-    /**
-     * Create a nominal descriptor for an {@code invokedynamic} call site.
-     *
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the {@code invokedynamic}
-     * @param invocationName The name that would appear in the {@code NameAndType}
-     *                       operand of the {@code invokedynamic}, as per
-     *                       JVMS 4.2.2
-     * @param invocationType a {@link MethodTypeDesc} describing the invocation
-     *                       type that would appear in the {@code NameAndType}
-     *                       operand of the {@code invokedynamic}
-     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
-     *                      to the bootstrap, that would appear in the
-     *                      {@code BootstrapMethods} attribute
-     * @throws NullPointerException if any parameter is null
-     * @throws IllegalArgumentException if the invocation name has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    private DynamicCallSiteDesc(ConstantMethodHandleDesc bootstrapMethod,
-                                String invocationName,
-                                MethodTypeDesc invocationType,
-                                ConstantDesc<?>[] bootstrapArgs) {
-        this.invocationName = validateMemberName(requireNonNull(invocationName));
-        this.invocationType = requireNonNull(invocationType);
-        this.bootstrapMethod = requireNonNull(bootstrapMethod);
-        this.bootstrapArgs = requireNonNull(bootstrapArgs.clone());
-        if (invocationName.length() == 0)
-            throw new IllegalArgumentException("Illegal invocation name: " + invocationName);
-    }
-
-    /**
-     * Create a nominal descriptor for an {@code invokedynamic} call site.
-     *
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the {@code invokedynamic}
-     * @param invocationName The name that would appear in the {@code NameAndType}
-     *                       operand of the {@code invokedynamic}, as per
-     *                       JVMS 4.2.2
-     * @param invocationType a {@link MethodTypeDesc} describing the invocation
-     *                       type that would appear in the {@code NameAndType}
-     *                       operand of the {@code invokedynamic}
-     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
-     *                      to the bootstrap, that would appear in the
-     *                      {@code BootstrapMethods} attribute
-     * @return the nominal descriptor
-     * @throws NullPointerException if any parameter is null
-     * @throws IllegalArgumentException if the invocation name has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    public static DynamicCallSiteDesc of(ConstantMethodHandleDesc bootstrapMethod,
-                                         String invocationName,
-                                         MethodTypeDesc invocationType,
-                                         ConstantDesc<?>... bootstrapArgs) {
-        return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, bootstrapArgs);
-    }
-
-    /**
-     * Create a nominal descriptor for an {@code invokedynamic} call site whose
-     * bootstrap method has no static arguments.
-     *
-     * @param bootstrapMethod The bootstrap method for the {@code invokedynamic}
-     * @param invocationName The invocationName that would appear in the
-     * {@code NameAndType} operand of the {@code invokedynamic}
-     * @param invocationType The invocation invocationType that would appear
-     * in the {@code NameAndType} operand of the {@code invokedynamic}
-     * @return the nominal descriptor
-     * @throws NullPointerException if any parameter is null
-     */
-    @Foldable
-    public static DynamicCallSiteDesc of(ConstantMethodHandleDesc bootstrapMethod,
-                                         String invocationName,
-                                         MethodTypeDesc invocationType) {
-        return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, EMPTY_CONSTANTDESC);
-    }
-
-    /**
-     * Create a nominal descriptor for an {@code invokedynamic} call site whose
-     * bootstrap method has no static arguments and for which the name parameter
-     * is {@link ConstantDescs#DEFAULT_NAME}.
-     *
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the {@code invokedynamic}
-     * @param invocationType a {@link MethodTypeDesc} describing the invocation
-     *                       type that would appear in the {@code NameAndType}
-     *                       operand of the {@code invokedynamic}
-     * @return the nominal descriptor
-     * @throws NullPointerException if any parameter is null
-     * @throws IllegalArgumentException if the invocation name has the incorrect
-     * format
-     */
-    @Foldable
-    public static DynamicCallSiteDesc of(ConstantMethodHandleDesc bootstrapMethod,
-                                         MethodTypeDesc invocationType) {
-        return of(bootstrapMethod, ConstantDescs.DEFAULT_NAME, invocationType);
-    }
-
-    /**
-     * Return a nominal descriptor for an {@code invokedynamic} call site whose
-     * bootstrap method, name, and invocation type are the same as this one, but
-     * with the specified bootstrap arguments.
-     *
-     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
-     *                      to the bootstrap, that would appear in the
-     *                      {@code BootstrapMethods} attribute
-     * @return the nominal descriptor
-     * @throws NullPointerException if any parameter is null
-     */
-    @Foldable
-    public DynamicCallSiteDesc withArgs(ConstantDesc<?>... bootstrapArgs) {
-        return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, bootstrapArgs);
-    }
-
-    /**
-     * Return a nominal descriptor for an {@code invokedynamic} call site whose
-     * bootstrap and bootstrap arguments are the same as this one, but with the
-     * specified invocationName and invocation invocationType
-     *
-     * @param invocationName The name that would appear in the {@code NameAndType}
-     *                       operand of the {@code invokedynamic}, as per
-     *                       JVMS 4.2.2
-     * @param invocationType a {@link MethodTypeDesc} describing the invocation
-     *                       type that would appear in the {@code NameAndType}
-     *                       operand of the {@code invokedynamic}
-     * @return the nominal descriptor
-     * @throws NullPointerException if any parameter is null
-     * @throws IllegalArgumentException if the invocation name has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    public DynamicCallSiteDesc withNameAndType(String invocationName,
-                                               MethodTypeDesc invocationType) {
-        return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, bootstrapArgs);
-    }
-
-    /**
-     * Returns the invocation name that would appear in the {@code NameAndType}
-     * operand of the {@code invokedynamic}.
-     * \
-     * @return the invocation name
-     */
-    @Foldable
-    public String invocationName() {
-        return invocationName;
-    }
-
-    /**
-     * Returns a {@link MethodTypeDesc} describing the invocation type that
-     * would appear in the {@code NameAndType} operand of the {@code invokedynamic}.
-     *
-     * @return the invocation type
-     */
-    @Foldable
-    public MethodTypeDesc invocationType() {
-        return invocationType;
-    }
-
-    /**
-     * Returns a {@link MethodHandleDesc} descripbing the bootstrap method for
-     * the {@code invokedynamic}.
-     *
-     * @return the bootstrap method for the {@code invokedynamic}
-     */
-    @Foldable
-    public MethodHandleDesc bootstrapMethod() { return bootstrapMethod; }
-
-    /**
-     * Returns {@link ConstantDesc}s describing the bootstrap arguments for the
-     * {@code invokedynamic}.
-     *
-     * @return the bootstrap arguments for the {@code invokedynamic}
-     */
-    public ConstantDesc<?>[] bootstrapArgs() { return bootstrapArgs.clone(); }
-
-    /**
-     * Reflectively invokes the bootstrap method with the specified arguments,
-     * and return the resulting {@link CallSite}
-     *
-     * @param lookup The {@link MethodHandles.Lookup} used to resolve class names
-     * @return the {@link CallSite}
-     * @throws Throwable if any exception is thrown by the bootstrap method
-     */
-    public CallSite resolveCallSiteDesc(MethodHandles.Lookup lookup) throws Throwable {
-        assert bootstrapMethod.methodType().parameterType(1).equals(CR_String);
-        MethodHandle bsm = bootstrapMethod.resolveConstantDesc(lookup);
-        Object[] args = new Object[bootstrapArgs.length + 3];
-        args[0] = lookup;
-        args[1] = invocationName;
-        args[2] = invocationType.resolveConstantDesc(lookup);
-        System.arraycopy(bootstrapArgs, 0, args, 3, bootstrapArgs.length);
-        return (CallSite) bsm.invokeWithArguments(args);
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) return true;
-        if (o == null || getClass() != o.getClass()) return false;
-        DynamicCallSiteDesc specifier = (DynamicCallSiteDesc) o;
-        return Objects.equals(bootstrapMethod, specifier.bootstrapMethod) &&
-               Arrays.equals(bootstrapArgs, specifier.bootstrapArgs) &&
-               Objects.equals(invocationName, specifier.invocationName) &&
-               Objects.equals(invocationType, specifier.invocationType);
-    }
-
-    @Override
-    public int hashCode() {
-        int result = Objects.hash(bootstrapMethod, invocationName, invocationType);
-        result = 31 * result + Arrays.hashCode(bootstrapArgs);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("DynamicCallSiteDesc[%s::%s(%s%s):%s]",
-                             bootstrapMethod.owner().displayName(),
-                             bootstrapMethod.methodName(),
-                             invocationName.equals(ConstantDescs.DEFAULT_NAME) ? "" : invocationName + "/",
-                             Stream.of(bootstrapArgs).map(Object::toString).collect(joining(",")),
-                             invocationType.displayDescriptor());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,496 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.lang.Enum.EnumDesc;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.VarHandle;
-import java.lang.invoke.VarHandle.VarHandleDesc;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.function.Function;
-import java.util.stream.Stream;
-
-import jdk.internal.lang.annotation.Foldable;
-
-import static java.lang.invoke.constant.ConstantDescs.BSM_DYNAMICCONSTANTDESC;
-import static java.lang.invoke.constant.ConstantDescs.CR_Class;
-import static java.lang.invoke.constant.ConstantDescs.CR_DynamicConstantDesc;
-import static java.lang.invoke.constant.ConstantDescs.CR_VarHandle;
-import static java.lang.invoke.constant.ConstantUtils.validateMemberName;
-import static java.util.Objects.requireNonNull;
-import static java.util.stream.Collectors.joining;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
- * dynamic constant (one described in the constant pool with
- * {@code Constant_Dynamic_info}.)
- *
- * <p>Concrete subtypes of {@linkplain DynamicConstantDesc} must be
- * <a href="../doc-files/ValueBased.html">value-based</a>.
- *
- * @param <T> the type of the dynamic constant
- */
-public abstract class DynamicConstantDesc<T>
-        implements ConstantDesc<T>, Constable<ConstantDesc<T>> {
-
-    private final ConstantMethodHandleDesc bootstrapMethod;
-    private final ConstantDesc<?>[] bootstrapArgs;
-    private final String constantName;
-    private final ClassDesc constantType;
-
-    private static final Map<MethodHandleDesc, Function<DynamicConstantDesc<?>, ConstantDesc<?>>> canonicalMap
-            = Map.ofEntries(Map.entry(ConstantDescs.BSM_PRIMITIVE_CLASS, DynamicConstantDesc::canonicalizePrimitiveClass),
-                            Map.entry(ConstantDescs.BSM_ENUM_CONSTANT, DynamicConstantDesc::canonicalizeEnum),
-                            Map.entry(ConstantDescs.BSM_NULL_CONSTANT, DynamicConstantDesc::canonicalizeNull),
-                            Map.entry(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, DynamicConstantDesc::canonicalizeStaticFieldVarHandle),
-                            Map.entry(ConstantDescs.BSM_VARHANDLE_FIELD, DynamicConstantDesc::canonicalizeFieldVarHandle),
-                            Map.entry(ConstantDescs.BSM_VARHANDLE_ARRAY, DynamicConstantDesc::canonicalizeArrayVarHandle)
-    );
-
-    /**
-     * Create a nominal descriptor for a dynamic constant.
-     *
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the constant
-     * @param constantName The name that would appear in the {@code NameAndType}
-     *                     operand of the {@code LDC} for this constant, as per
-     *                     JVMS 4.2.2
-     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
-     *                     that would appear in the {@code NameAndType} operand
-     *                     of the {@code LDC} for this constant
-     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
-     *                      to the bootstrap, that would appear in the
-     *                      {@code BootstrapMethods} attribute
-     * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if the {@code name} has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    protected DynamicConstantDesc(ConstantMethodHandleDesc bootstrapMethod,
-                                  String constantName,
-                                  ClassDesc constantType,
-                                  ConstantDesc<?>... bootstrapArgs) {
-        this.bootstrapMethod = requireNonNull(bootstrapMethod);
-        this.constantName = validateMemberName(requireNonNull(constantName));
-        this.constantType = requireNonNull(constantType);
-        this.bootstrapArgs = requireNonNull(bootstrapArgs).clone();
-
-        if (constantName.length() == 0)
-            throw new IllegalArgumentException("Illegal invocation name: " + constantName);
-    }
-
-    /**
-     * Return a nominal 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 {@link ConstantDesc}s describing the static arguments
-     *                      to the bootstrap, that would appear in the
-     *                      {@code BootstrapMethods} attribute
-     * @return the nominal descriptor
-     * @throws NullPointerException if any argument is null
-     */
-    @Foldable
-    public DynamicConstantDesc<T> withArgs(ConstantDesc<?>... bootstrapArgs) {
-        return DynamicConstantDesc.of(bootstrapMethod, constantName, constantType, bootstrapArgs);
-    }
-
-    /**
-     * Return a nominal descriptor for a dynamic constant, transforming it into
-     * a more specific type if the constant bootstrap is a well-known one and a
-     * more specific nominal descriptor type (e.g., ClassDesc) is available.
-     *
-     * <p>Classes whose {@link Constable#describeConstable()} method produces
-     * a {@linkplain DynamicConstantDesc} with a well-known bootstrap including
-     * {@link Class} (for instances describing primitive types), {@link Enum},
-     * and {@link VarHandle}.
-     *
-     * <p>Bytecode-reading APIs that process the constant pool and wish to expose
-     * entries as {@link ConstantDesc} to their callers should generally use this
-     * method in preference to {@link #of(ConstantMethodHandleDesc, String, ClassDesc, ConstantDesc[])}
-     * because this may result in a more specific type that can be provided to
-     * callers.
-     *
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the constant
-     * @param constantName The name that would appear in the {@code NameAndType}
-     *                     operand of the {@code LDC} for this constant, as per
-     *                     JVMS 4.2.2
-     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
-     *                     that would appear in the {@code NameAndType} operand
-     *                     of the {@code LDC} for this constant
-     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
-     *                      to the bootstrap, that would appear in the
-     *                      {@code BootstrapMethods} attribute
-     * @return the nominal descriptor
-     * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if the {@code name} has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    public static<T> ConstantDesc<T> ofCanonical(ConstantMethodHandleDesc bootstrapMethod,
-                                                 String constantName,
-                                                 ClassDesc constantType,
-                                                 ConstantDesc<?>[] bootstrapArgs) {
-        return DynamicConstantDesc.<T>of(bootstrapMethod, constantName, constantType, bootstrapArgs)
-                .tryCanonicalize();
-    }
-
-    /**
-     * Return a nominal descriptor for a dynamic constant.
-     *
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the constant
-     * @param constantName The name that would appear in the {@code NameAndType}
-     *                     operand of the {@code LDC} for this constant, as per
-     *                     JVMS 4.2.2
-     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
-     *                     that would appear in the {@code NameAndType} operand
-     *                     of the {@code LDC} for this constant
-     * @param bootstrapArgs {@link ConstantDesc}s describing the static arguments
-     *                      to the bootstrap, that would appear in the
-     *                      {@code BootstrapMethods} attribute
-     * @return the nominal descriptor
-     * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if the {@code name} has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod,
-                                               String constantName,
-                                               ClassDesc constantType,
-                                               ConstantDesc<?>[] bootstrapArgs) {
-        return new DynamicConstantDesc<>(bootstrapMethod, constantName, constantType, bootstrapArgs) {};
-    }
-
-    /**
-     * Return a nominal descriptor for a dynamic constant whose bootstrap has
-     * no static arguments.
-     *
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the constant
-     * @param constantName The name that would appear in the {@code NameAndType}
-     *                     operand of the {@code LDC} for this constant, as per
-     *                     JVMS 4.2.2
-     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
-     *                     that would appear in the {@code NameAndType} operand
-     *                     of the {@code LDC} for this constant
-     * @return the nominal descriptor
-     * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if the {@code name} has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod,
-                                               String constantName,
-                                               ClassDesc constantType) {
-        return DynamicConstantDesc.of(bootstrapMethod, constantName, constantType, ConstantUtils.EMPTY_CONSTANTDESC);
-    }
-
-    /**
-     * Return a nominal descriptor for a dynamic constant whose bootstrap has
-     * no static arguments, and for which the name parameter
-     * is {@link ConstantDescs#DEFAULT_NAME}.
-     *
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the constant
-     * @param constantType a {@link ConstantMethodHandleDesc} describing the type
-     *                     that would appear in the {@code NameAndType} operand
-     *                     of the {@code LDC} for this constant
-     * @return the nominal descriptor
-     * @throws NullPointerException if any argument is null
-     */
-    @Foldable
-    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod,
-                                               ClassDesc constantType) {
-        return of(bootstrapMethod, ConstantDescs.DEFAULT_NAME, constantType);
-    }
-
-    /**
-     * Return a nominal descriptor for a dynamic constant whose bootstrap has
-     * no static arguments, and whose type parameter is always the same as the
-     * bootstrap method return type.
-     *
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the constant
-     * @param constantName The name that would appear in the {@code NameAndType}
-     *                     operand of the {@code LDC} for this constant, as per
-     *                     JVMS 4.2.2
-     * @return the nominal descriptor
-     * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if the {@code name} has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod,
-                                               String constantName) {
-        return of(bootstrapMethod, constantName, bootstrapMethod.methodType().returnType());
-    }
-
-    /**
-     * Return a nominal descriptor for a dynamic constant whose bootstrap has
-     * no static arguments, whose name parameter is {@link ConstantDescs#DEFAULT_NAME},
-     * and whose type parameter is always the same as the bootstrap method return type.
-     *
-     * @param <T> the type of the dynamic constant
-     * @param bootstrapMethod a {@link ConstantMethodHandleDesc} describing the
-     *                        bootstrap method for the constant
-     * @return the nominal descriptor
-     * @throws NullPointerException if any argument is null
-     * @throws IllegalArgumentException if the {@code name} has the incorrect
-     * format
-     */
-    @Foldable
-    public static<T> DynamicConstantDesc<T> of(ConstantMethodHandleDesc bootstrapMethod) {
-        return of(bootstrapMethod, ConstantDescs.DEFAULT_NAME);
-    }
-
-    /**
-     * Returns The name that would appear in the {@code NameAndType} operand
-     *             of the {@code LDC} for this constant
-     *
-     * @return the constant name
-     */
-    @Foldable
-    public String constantName() {
-        return constantName;
-    }
-
-    /**
-     * Returns a {@link ClassDesc} describing the type that would appear in the
-     * {@code NameAndType} operand of the {@code LDC} for this constant.
-     *
-     * @return the constant type
-     */
-    @Foldable
-    public ClassDesc constantType() {
-        return constantType;
-    }
-
-    /**
-     * Returns a {@link MethodHandleDesc} describing the bootstrap method for
-     * this constant
-     *
-     * @return the bootstrap method
-     */
-    @Foldable
-    public ConstantMethodHandleDesc bootstrapMethod() {
-        return bootstrapMethod;
-    }
-
-    /**
-     * Returns the bootstrap arguments for this constant
-     * @return the bootstrap arguments
-     */
-    public ConstantDesc<?>[] bootstrapArgs() {
-        return bootstrapArgs.clone();
-    }
-
-    /**
-     * Returns the bootstrap arguments for this constant as a {@link List}
-     *
-     * @return a {@link List} of the bootstrap arguments, described as {@link ConstantDesc}
-     */
-    public List<ConstantDesc<?>> bootstrapArgsList() {
-        return List.of(bootstrapArgs);
-    }
-
-    @SuppressWarnings("unchecked")
-    public T resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
-        // TODO replace with public supported method
-        try {
-            MethodHandle bsm = bootstrapMethod.resolveConstantDesc(lookup);
-            if (bsm.type().parameterCount() < 2 ||
-                !MethodHandles.Lookup.class.isAssignableFrom(bsm.type().parameterType(0))) {
-                throw new BootstrapMethodError(
-                        "Invalid bootstrap method declared for resolving a dynamic constant: " + bootstrapMethod);
-            }
-            Object[] bsmArgs = new Object[3 + bootstrapArgs.length];
-            bsmArgs[0] = lookup;
-            bsmArgs[1] = constantName;
-            bsmArgs[2] = constantType.resolveConstantDesc(lookup);
-            for (int i = 0; i < bootstrapArgs.length; i++)
-                bsmArgs[3 + i] = bootstrapArgs[i].resolveConstantDesc(lookup);
-
-            return (T) bsm.invokeWithArguments(bsmArgs);
-        } catch (Error e) {
-            throw e;
-        } catch (Throwable t) {
-            throw new BootstrapMethodError(t);
-        }
-    }
-
-    @Override
-    public Optional<? extends ConstantDesc<ConstantDesc<T>>> describeConstable() {
-        ConstantDesc<?>[] args = new ConstantDesc<?>[bootstrapArgs.length + 5];
-        args[0] = bootstrapMethod.owner().descriptorString();
-        args[1] = bootstrapMethod.methodName();
-        args[2] = bootstrapMethod.methodType().descriptorString();
-        args[3] = constantName;
-        args[4] = constantType.descriptorString();
-        System.arraycopy(bootstrapArgs, 0, args, 5, bootstrapArgs.length);
-        return Optional.of(DynamicConstantDesc.of(BSM_DYNAMICCONSTANTDESC, ConstantDescs.DEFAULT_NAME,
-                                                  CR_DynamicConstantDesc, args));
-    }
-
-    /**
-     * Constant bootstrap method for representing a {@linkplain DynamicConstantDesc}
-     * in the constant pool of a classfile.
-     *
-     * @param lookup ignored
-     * @param name ignored
-     * @param clazz ignored
-     * @param bsmOwner A field type descriptor for the class declaring the
-     *                 bootstrap method, as per JVMS 4.3.2
-     * @param bsmName The name of the bootstrap method, as per JVMS 4.2.2
-     * @param bsmDesc A method type descriptor for bootstrap method, as per JVMS 4.3.3
-     * @param constantName The name that would appear in the {@code NameAndType}
-     *                     operand of the {@code LDC} for this constant, as per
-     *                     JVMS 4.2.2
-     * @param constantType a field type descriptor string describing the type
-     *                     that would appear in the {@code NameAndType} operand
-     *                     of the {@code LDC} for this constant, as per JVMS 4.3.2
-     * @param args The static arguments to the bootstrap method
-     * @return the {@linkplain DynamicConstantDesc}
-     * @jvms 4.2.2 Unqualified Names
-     * @jvms 4.3.2 Field Descriptors
-     * @jvms 4.3.3 Method Descriptors
-     */
-    public static DynamicConstantDesc<?> constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
-                                                           String bsmOwner, String bsmName, String bsmDesc,
-                                                           String constantName, String constantType,
-                                                           ConstantDesc<?>... args) {
-        return DynamicConstantDesc.of(MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC,
-                                                          ClassDesc.ofDescriptor(bsmOwner), bsmName,
-                                                          MethodTypeDesc.ofDescriptor(bsmDesc)),
-                                      constantName, ClassDesc.ofDescriptor(constantType), args);
-
-    }
-
-    private ConstantDesc<T> tryCanonicalize() {
-        Function<DynamicConstantDesc<?>, ConstantDesc<?>> f = canonicalMap.get(bootstrapMethod);
-        if (f != null) {
-            try {
-                @SuppressWarnings("unchecked")
-                ConstantDesc<T> converted = (ConstantDesc<T>) f.apply(this);
-                return converted;
-            }
-            catch (Throwable t) {
-                return this;
-            }
-        }
-        return this;
-    }
-
-    private static ConstantDesc<?> canonicalizeNull(DynamicConstantDesc<?> desc) {
-        if (desc.bootstrapArgs.length != 0)
-            return desc;
-        return ConstantDescs.NULL;
-    }
-
-    private static ConstantDesc<?> canonicalizeEnum(DynamicConstantDesc<?> desc) {
-        if (desc.bootstrapArgs.length != 0
-            || desc.constantName == null)
-            return desc;
-        return EnumDesc.of(desc.constantType, desc.constantName);
-    }
-
-    private static ConstantDesc<?> canonicalizePrimitiveClass(DynamicConstantDesc<?> desc) {
-        if (desc.bootstrapArgs.length != 0
-            || !desc.constantType().equals(CR_Class)
-            || desc.constantName == null)
-            return desc;
-        return ClassDesc.ofDescriptor(desc.constantName);
-    }
-
-    private static ConstantDesc<?> canonicalizeStaticFieldVarHandle(DynamicConstantDesc<?> desc) {
-        if (desc.bootstrapArgs.length != 3
-            || !desc.constantType().equals(CR_VarHandle))
-            return desc;
-        return VarHandleDesc.ofStaticField((ClassDesc) desc.bootstrapArgs[0],
-                                           (String) desc.bootstrapArgs[1],
-                                           (ClassDesc) desc.bootstrapArgs[2]);
-    }
-
-    private static ConstantDesc<?> canonicalizeFieldVarHandle(DynamicConstantDesc<?> desc) {
-        if (desc.bootstrapArgs.length != 3
-            || !desc.constantType().equals(CR_VarHandle))
-            return desc;
-        return VarHandleDesc.ofField((ClassDesc) desc.bootstrapArgs[0],
-                                     (String) desc.bootstrapArgs[1],
-                                     (ClassDesc) desc.bootstrapArgs[2]);
-    }
-
-    private static ConstantDesc<?> canonicalizeArrayVarHandle(DynamicConstantDesc<?> desc) {
-        if (desc.bootstrapArgs.length != 1
-            || !desc.constantType().equals(CR_VarHandle))
-            return desc;
-        return VarHandleDesc.ofArray((ClassDesc) desc.bootstrapArgs[0]);
-    }
-
-    // @@@ To eventually support in canonicalization: DCR with BSM=MHR_METHODHANDLEDESC_ASTYPE becomes AsTypeMHDesc
-
-    @Override
-    public final boolean equals(Object o) {
-        if (this == o) return true;
-        if (!(o instanceof DynamicConstantDesc)) return false;
-        DynamicConstantDesc<?> desc = (DynamicConstantDesc<?>) o;
-        return Objects.equals(bootstrapMethod, desc.bootstrapMethod) &&
-               Arrays.equals(bootstrapArgs, desc.bootstrapArgs) &&
-               Objects.equals(constantName, desc.constantName) &&
-               Objects.equals(constantType, desc.constantType);
-    }
-
-    @Override
-    public final int hashCode() {
-        int result = Objects.hash(bootstrapMethod, constantName, constantType);
-        result = 31 * result + Arrays.hashCode(bootstrapArgs);
-        return result;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("DynamicConstantDesc[%s::%s(%s%s)%s]",
-                             bootstrapMethod.owner().displayName(),
-                             bootstrapMethod.methodName(),
-                             constantName.equals(ConstantDescs.DEFAULT_NAME) ? "" : constantName + "/",
-                             Stream.of(bootstrapArgs).map(Object::toString).collect(joining(",")),
-                             constantType.displayName());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/MethodHandleDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandleInfo;
-import java.lang.invoke.MethodType;
-
-import jdk.internal.lang.annotation.Foldable;
-
-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.constant.ConstantDescs.CR_void;
-import static java.lang.invoke.constant.MethodHandleDesc.Kind.CONSTRUCTOR;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
- * {@link MethodHandle} constant.
- */
-public interface MethodHandleDesc
-        extends ConstantDesc<MethodHandle>, Constable<ConstantDesc<MethodHandle>> {
-    /**
-     * Kinds of method handles that can be described with {@linkplain MethodHandleDesc}.
-     */
-    public enum Kind {
-        /** A method handle for a method invoked as with {@code invokestatic} */
-        @Foldable STATIC(REF_invokeStatic),
-        /** A method handle for a method invoked as with {@code invokevirtual} */
-        @Foldable VIRTUAL(REF_invokeVirtual),
-        /** A method handle for a method invoked as with {@code invokeinterface} */
-        @Foldable INTERFACE_VIRTUAL(REF_invokeInterface),
-        /** A method handle for a method invoked as with {@code invokespecial} */
-        @Foldable SPECIAL(REF_invokeSpecial),
-        /** A method handle for a constructor */
-        @Foldable CONSTRUCTOR(REF_newInvokeSpecial),
-        /** A method handle for a read accessor for an instance field  */
-        @Foldable GETTER(REF_getField),
-        /** A method handle for a write accessor for an instance field  */
-        @Foldable SETTER(REF_putField),
-        /** A method handle for a read accessor for a static field  */
-        @Foldable STATIC_GETTER(REF_getStatic),
-        /** A method handle for a write accessor for a static field  */
-        @Foldable STATIC_SETTER(REF_putStatic);
-
-        /** The corresponding {@code refKind} value for this kind of method handle,
-         * as defined by {@link MethodHandleInfo}
-         */
-        public final int refKind;
-
-        Kind(int refKind) {
-            this.refKind = refKind;
-        }
-    }
-
-
-    /**
-     * Create a {@linkplain MethodHandleDesc} corresponding to an invocation of a
-     * declared method, invocation of a constructor, or access to a field.
-     *
-     * <p>If {@code kind} is {@code CONSTRUCTOR}, the name is ignored and the return
-     * type of the invocation type must be {@code void}.  If {@code kind} corresponds
-     * to a field access, the invocation type must be consistent with that kind
-     * of field access and the type of the field; instance field accessors must
-     * take a leading receiver parameter, getters must return the type of the
-     * field, setters must take a new value for the field and return {@code void}.
-     *
-     * <p>For constructor and field access, the methods {@link #ofField(Kind, ClassDesc, String, ClassDesc)}
-     * and {@link #ofConstructor(ClassDesc, ClassDesc...)} may be more convenient.
-     *
-     * @param kind The kind of method handle to be described
-     * @param clazz a {@link ClassDesc} describing the class containing the
-     *              method, constructor, or field
-     * @param name the name of the method or field (ignored if {@code kind} is
-     * {@code CONSTRUCTOR}), as per JVMS 4.2.2
-     * @param type a {@link MethodTypeDesc} describing the invocation type of
-     *             the method handle
-     * @return the {@linkplain MethodHandleDesc}
-     * @throws NullPointerException if any non-ignored arguments are null
-     * @throws IllegalArgumentException if the {@code name} has the incorrect
-     * format
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    static ConstantMethodHandleDesc of(Kind kind,
-                                       ClassDesc clazz,
-                                       String name,
-                                       MethodTypeDesc type) {
-        return new ConstantMethodHandleDesc(kind, clazz, name, type);
-    }
-
-    /**
-     * Create a {@linkplain MethodHandleDesc} corresponding to an invocation of a
-     * declared method, invocation of a constructor, or access to a field.
-     *
-     * <p>If {@code kind} is {@code CONSTRUCTOR}, the name is ignored and the return
-     * type of the invocation type must be {@code void}.  If {@code kind} corresponds
-     * to a field access, the invocation type must be consistent with that kind
-     * of field access and the type of the field; instance field accessors must
-     * take a leading receiver parameter, getters must return the type of the
-     * field, setters must take a new value for the field and return {@code void}.
-     * The method {@link #ofField(Kind, ClassDesc, String, ClassDesc)} will construct
-     * the appropriate invocation given the type of the field.
-     *
-     * @param kind The kind of method handle to be described
-     * @param clazz a {@link ClassDesc} describing the class containing the
-     *              method, constructor, or field
-     * @param name the name of the method or field (ignored if {@code kind} is
-     * {@code CONSTRUCTOR}), as per JVMS 4.2.2
-     * @param descriptorString a method descriptor string for the invocation type
-     * of the method handle, as per JVMS 4.3.3
-     * @return the {@linkplain MethodHandleDesc}
-     * @throws NullPointerException if any of the non-ignored arguments are null
-     * @jvms 4.2.2 Unqualified Names
-     * @jvms 4.3.3 Method Descriptors
-     */
-    @Foldable
-    static ConstantMethodHandleDesc of(Kind kind,
-                                       ClassDesc clazz,
-                                       String name,
-                                       String descriptorString) {
-        return of(kind, clazz, name, MethodTypeDesc.ofDescriptor(descriptorString));
-    }
-
-    /**
-     * Create a {@linkplain MethodHandleDesc} corresponding to an invocation of a
-     * declared method, invocation of a constructor, or access to a field.
-     *
-     * <p>If {@code kind} is {@code CONSTRUCTOR}, the name is ignored and the return
-     * type of the invocation type must be {@code void}.  If {@code kind} corresponds
-     * to a field access, the invocation type must be consistent with that kind
-     * of field access and the type of the field; instance field accessors must
-     * take a leading receiver parameter, getters must return the type of the
-     * field, setters must take a new value for the field and return {@code void}.
-     * The method {@link #ofField(Kind, ClassDesc, String, ClassDesc)} will construct
-     * the appropriate invocation given the type of the field.
-     *
-     * @param kind The kind of method handle to be described
-     * @param clazz a {@link ClassDesc} describing the class containing the
-     *              method, constructor, or field
-     * @param name the name of the method or field (ignored if {@code kind} is
-     * {@code CONSTRUCTOR}), as per JVMS 4.2.2
-     * @param returnType a {@link ClassDesc} describing the return type of the
-     *                   method handle
-     * @param paramTypes {@link ClassDesc}s describing the parameter types of
-     *                                    the method handle
-     * @return the {@linkplain MethodHandleDesc}
-     * @throws NullPointerException if any of the non-ignored arguments are null
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    static ConstantMethodHandleDesc of(Kind kind,
-                                       ClassDesc clazz,
-                                       String name,
-                                       ClassDesc returnType,
-                                       ClassDesc... paramTypes) {
-        return of(kind, clazz, name, MethodTypeDesc.of(returnType, paramTypes));
-    }
-
-    /**
-     * Create a {@linkplain MethodHandleDesc} corresponding to a method handle
-     * that accesses a field.
-     *
-     * @param kind the kind of the method handle to be described; must be one of {@code GETTER},
-     *             {@code SETTER}, {@code STATIC_GETTER}, or {@code STATIC_SETTER}
-     * @param clazz a {@link ClassDesc} describing the class containing the
-     *              method, constructor, or field
-     * @param fieldName the name of the field, as per JVMS 4.2.2
-     * @param fieldType a {@link ClassDesc} describing the type of the field
-     * @return the {@linkplain MethodHandleDesc}
-     * @throws NullPointerException if any of the arguments are null
-     * @jvms 4.2.2 Unqualified Names
-     */
-    @Foldable
-    static ConstantMethodHandleDesc ofField(Kind kind,
-                                            ClassDesc clazz,
-                                            String fieldName,
-                                            ClassDesc fieldType) {
-        MethodTypeDesc mtr;
-        switch (kind) {
-            case GETTER: mtr = MethodTypeDesc.of(fieldType, clazz); break;
-            case SETTER: mtr = MethodTypeDesc.of(CR_void, clazz, fieldType); break;
-            case STATIC_GETTER: mtr = MethodTypeDesc.of(fieldType); break;
-            case STATIC_SETTER: mtr = MethodTypeDesc.of(CR_void, fieldType); break;
-            default:
-                throw new IllegalArgumentException(kind.toString());
-        }
-        return MethodHandleDesc.of(kind, clazz, fieldName, mtr);
-    }
-
-    /**
-     * Return a {@linkplain MethodHandleDesc} corresponding to invocation of a constructor
-     *
-     * @param clazz a {@link ClassDesc} describing the class containing the
-     *              method, constructor, or field
-     * @param paramTypes {@link ClassDesc}s describing the parameter types of
-     *                   the constructor
-     * @return the {@linkplain MethodHandleDesc}
-     * @throws NullPointerException if any of the arguments are null
-     */
-    @Foldable
-    static ConstantMethodHandleDesc ofConstructor(ClassDesc clazz,
-                                                  ClassDesc... paramTypes) {
-        return MethodHandleDesc.of(CONSTRUCTOR, clazz, ConstantDescs.DEFAULT_NAME,
-                                   MethodTypeDesc.of(CR_void, paramTypes));
-    }
-
-    /**
-     * Return a {@linkplain MethodHandleDesc} that describes this method handle
-     * adapted to a different type, as if by {@link MethodHandle#asType(MethodType)}.
-     *
-     * @param type a {@link MethodHandleDesc} describing the new method type
-     * @return a {@linkplain MethodHandleDesc} for the adapted method handle
-     */
-    @Foldable
-    default MethodHandleDesc asType(MethodTypeDesc type) {
-        return (methodType().equals(type)) ? this : new AsTypeMethodHandleDesc(this, type);
-    }
-
-    /**
-     * Return a {@link MethodTypeDesc} describing the type of the method handle
-     * described by this nominal descriptor
-     *
-     * @return a {@linkplain MethodHandleDesc} describing the method handle type
-     */
-    @Foldable
-    MethodTypeDesc methodType();
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/MethodTypeDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import jdk.internal.lang.annotation.Foldable;
-
-import java.lang.invoke.MethodType;
-import java.lang.invoke.MethodTypeDescriptor;
-import java.util.List;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for a
- * {@linkplain MethodType} constant.
- */
-public interface MethodTypeDesc
-        extends ConstantDesc<MethodType>,
-                Constable<ConstantDesc<MethodType>>,
-                MethodTypeDescriptor<ClassDesc, MethodTypeDesc> {
-    /**
-     * Create a {@linkplain MethodTypeDesc} given a method descriptor string
-     *
-     * @param descriptor a method descriptor string, as per JVMS 4.3.3
-     * @return a {@linkplain MethodTypeDesc} describing the desired method type
-     * @throws NullPointerException if any argument is {@code null}
-     * @throws IllegalArgumentException if the descriptor string is not a valid
-     * method descriptor
-     * @jvms 4.3.3 Method Descriptors
-     */
-    @Foldable
-    static MethodTypeDesc ofDescriptor(String descriptor) {
-        return ConstantMethodTypeDesc.ofDescriptor(descriptor);
-    }
-
-    /**
-     * Returns a {@linkplain MethodTypeDesc} given the return type and parameter
-     * types.
-     *
-     * @param returnDesc a {@linkplain ClassDesc} describing the return type
-     * @param paramDescs {@linkplain ClassDesc}s describing the argument types
-     * @return a {@linkplain MethodTypeDesc} describing the desired method type
-     * @throws NullPointerException if any argument is {@code null}
-     */
-    @Foldable
-    static MethodTypeDesc of(ClassDesc returnDesc, ClassDesc... paramDescs) {
-        return new ConstantMethodTypeDesc(returnDesc, paramDescs);
-    }
-
-    /**
-     * Get the return type of the method type described by this {@linkplain MethodTypeDesc}
-     *
-     * @return a {@link ClassDesc} describing the return type of the method type
-     */
-    @Foldable
-    ClassDesc returnType();
-
-    /**
-     * Get the number of parameters of the method type described by
-     * this {@linkplain MethodTypeDesc}
-     * @return the number of parameters
-     */
-    @Foldable
-    int parameterCount();
-
-    /**
-     * Get the parameter type of the {@code index}'th parameter of the method type
-     * described by this {@linkplain MethodTypeDesc}
-     *
-     * @param index the index of the parameter to retrieve
-     * @return a {@link ClassDesc} describing the desired parameter type
-     * @throws IndexOutOfBoundsException if the index is outside the half-open
-     * range {[0, parameterCount())}
-     */
-    @Foldable
-    ClassDesc parameterType(int index);
-
-    /**
-     * Get the parameter types as a {@link List}.
-     *
-     * @return a {@link List} of {@link ClassDesc} describing the parameter types
-     */
-    List<ClassDesc> parameterList();
-
-    /**
-     * Get the parameter types as an array.
-     *
-     * @return an array of {@link ClassDesc} describing the parameter types
-     */
-    ClassDesc[] parameterArray();
-
-    /**
-     * Return a {@linkplain MethodTypeDesc} that is identical to
-     * this one, except with the specified return type.
-     *
-     * @param returnType a {@link ClassDesc} describing the new return type
-     * @return a {@linkplain MethodTypeDesc} describing the desired method type
-     * @throws NullPointerException if any argument is {@code null}
-     */
-    @Foldable
-    MethodTypeDesc changeReturnType(ClassDesc returnType);
-
-    /**
-     * Return a {@linkplain MethodTypeDesc} that is identical to this one,
-     * except that a single parameter type has been changed to the specified type.
-     *
-     * @param index the index of the parameter to change
-     * @param paramType a {@link ClassDesc} describing the new parameter type
-     * @return a {@linkplain MethodTypeDesc} describing the desired method type
-     * @throws NullPointerException if any argument is {@code null}
-     * @throws IndexOutOfBoundsException if the index is outside the half-open
-     * range {[0, parameterCount)}
-     */
-    @Foldable
-    MethodTypeDesc changeParameterType(int index, ClassDesc paramType);
-
-    /**
-     * Return a {@linkplain MethodTypeDesc} that is identical to this one,
-     * except that a range of parameter types have been removed.
-     *
-     * @param start the index of the first parameter to remove
-     * @param end the index after the last parameter to remove
-     * @return a {@linkplain MethodTypeDesc} describing the desired method type
-     * @throws IndexOutOfBoundsException if {@code start} is outside the half-open
-     * range {[0, parameterCount)}, or {@code end} is outside the closed range
-     * {@code [0, parameterCount]}
-     */
-    @Foldable
-    MethodTypeDesc dropParameterTypes(int start, int end);
-
-    /**
-     * Return a {@linkplain MethodTypeDesc} that is identical to this one,
-     * except that a range of additional parameter types have been inserted.
-     *
-     * @param pos the index at which to insert the first inserted parameter
-     * @param paramTypes {@link ClassDesc}s describing the new parameter types
-     *                   to insert
-     * @return a {@linkplain MethodTypeDesc} describing the desired method type
-     * @throws NullPointerException if any argument is {@code null}
-     * @throws IndexOutOfBoundsException if {@code pos} is outside the closed
-     * range {[0, parameterCount]}
-     */
-    @Foldable
-    MethodTypeDesc insertParameterTypes(int pos, ClassDesc... paramTypes);
-
-    /**
-     * Return the method type descriptor string, as per JVMS 4.3.3.
-     *
-     * @return the method type descriptor string
-     * @jvms 4.3.3 Method Descriptors
-     */
-    default String descriptorString() {
-        return String.format("(%s)%s",
-                             Stream.of(parameterArray())
-                                   .map(ClassDesc::descriptorString)
-                                   .collect(Collectors.joining()),
-                             returnType().descriptorString());
-    }
-
-    /**
-     * Return a human-readable descriptor for this method type, using the
-     * canonical names for parameter and return types
-     *
-     * @return the human-readable descriptor for this method type
-     */
-    default String displayDescriptor() {
-        return String.format("(%s)%s",
-                             Stream.of(parameterArray())
-                                   .map(ClassDesc::displayName)
-                                   .collect(Collectors.joining(",")),
-                             returnType().displayName());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2018, 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.constant;
-
-import java.lang.invoke.MethodHandles;
-import java.util.Optional;
-
-import sun.invoke.util.Wrapper;
-
-import static java.util.Objects.requireNonNull;
-
-/**
- * A <a href="package-summary.html#nominal">nominal descriptor</a> for the class
- * constant corresponding to a primitive type (e.g., {@code int.class}).
- */
-final class PrimitiveClassDesc
-        extends DynamicConstantDesc<Class<?>> implements ClassDesc {
-
-    private final String descriptor;
-
-    /**
-     * Create a {@linkplain ClassDesc} given a descriptor string for a primitive
-     * type.
-     *
-     * @param descriptor the descriptor string, which must be a one-character
-     * string corresponding to one of the nine base types as per JVMS 4.3
-     * @throws IllegalArgumentException if the descriptor string does not
-     * describe a valid primitive type
-     * @jvms 4.3 Descriptors
-     */
-    PrimitiveClassDesc(String descriptor) {
-        super(ConstantDescs.BSM_PRIMITIVE_CLASS, requireNonNull(descriptor), ConstantDescs.CR_Class);
-        if (descriptor.length() != 1
-            || "VIJCSBFDZ".indexOf(descriptor.charAt(0)) < 0)
-            throw new IllegalArgumentException(String.format("not a valid primitive type descriptor: %s", descriptor));
-        this.descriptor = descriptor;
-    }
-
-    @Override
-    public String descriptorString() {
-        return descriptor;
-    }
-
-    @Override
-    public Class<?> resolveConstantDesc(MethodHandles.Lookup lookup) {
-        return Wrapper.forBasicType(descriptorString().charAt(0)).primitiveType();
-    }
-
-    @Override
-    public Optional<? extends ConstantDesc<ConstantDesc<Class<?>>>> describeConstable() {
-        return ConstantUtils.symbolizeHelper(ConstantDescs.MHR_CLASSDESC_FACTORY, ConstantDescs.CR_ClassDesc, descriptorString());
-    }
-
-    @Override
-    public String toString() {
-        return String.format("PrimitiveClassDesc[%s]", displayName());
-    }
-}
--- a/src/java.base/share/classes/java/lang/invoke/constant/package-info.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +0,0 @@
-/*
- * Copyright (c) 2018, 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.
- */
-
-/**
- * Classes and interfaces to represent <em>nominal descriptors</em> for run-time
- * entities such as classes or method handles, and classfile entities such as
- * constant pool entries or {@code invokedynamic} call sites.  These classes
- * are suitable for use in bytecode reading and writing APIs, {@code invokedynamic}
- * bootstraps, bytecode intrinsic APIs (such as {@link java.lang.invoke.Intrinsics#ldc(ConstantDesc)}),
- * and compile-time or link-time program analysis tools.
- *
- * <p>Every API that reads and writes bytecode instructions needs to model the
- * operands to these instructions and other classfile structures (such as entries
- * in the bootstrap methods table or stack maps, which frequently reference
- * entries in the classfile constant pool.) Such entries can denote values of
- * fundamental types, such as strings or integers; parts of a program, such as
- * classes or method handles; or values of arbitrary user-defined types.  The
- * {@link java.lang.invoke.constant.ConstantDesc} hierarchy provides a representation of
- * constant pool entries in nominal form that is convenient for APIs to model
- * operands of bytecode instructions.
- *
- * <h2><a id="nominal"></a>Nominal Descriptors</h2>
- *
- * <p>A {@link java.lang.invoke.constant.ConstantDesc} is a description of a constant
- * value.  Such a description is the <em>nominal form</em> of the constant value;
- * it is not the value itself, but rather a "recipe" for describing the value,
- * storing the value in a constant pool entry, or reconstituting the value given
- * a class loading context.  Every {@link java.lang.invoke.constant.ConstantDesc}
- * knows how to <em>resolve</em> itself -- compute the value that it describes --
- * via {@link java.lang.invoke.constant.ConstantDesc#resolveConstantDesc(java.lang.invoke.MethodHandles.Lookup)}.
- * This allows an API which accepts {@link java.lang.invoke.constant.ConstantDesc}
- * objects to evaluate them reflectively, provided that the classes and methods
- * referenced in their nominal description are present and accessible.
- *
- * <p>The subtypes of of {@link java.lang.invoke.constant.ConstantDesc} describe various kinds
- * of constant values.  For each type of loadable constant pool entry defined in JVMS 4.4,
- * there is a corresponding subtype of {@link java.lang.invoke.constant.ConstantDesc}:
- * {@link java.lang.invoke.constant.ConstantClassDesc}, {@link java.lang.invoke.constant.ConstantMethodTypeDesc},
- * {@link java.lang.invoke.constant.ConstantMethodHandleDesc}, {@link java.lang.String},
- * {@link java.lang.Integer}, {@link java.lang.Long}, {@link java.lang.Float},
- * {@link java.lang.Double}, and {@link java.lang.invoke.constant.DynamicConstantDesc}.  These classes
- * provides type-specific accessor methods to extract the nominal information for
- * that kind of constant.  When a bytecode-writing API encounters a {@link java.lang.invoke.constant.ConstantDesc},
- * it should examine it to see which of these types it is, cast it, extract
- * its nominal information, and generate the corresponding entry to the constant pool.
- * When a bytecode-reading API encounters a constant pool entry, it can
- * convert it to the appropriate type of nominal descriptor.  For dynamic
- * constants, bytecode-reading APIs may wish to use the factory
- * {@link java.lang.invoke.constant.DynamicConstantDesc#ofCanonical(ConstantMethodHandleDesc, java.lang.String, ClassDesc, ConstantDesc[])},
- * which will inspect the bootstrap and, for well-known bootstraps, return
- * a more specific subtype of {@link java.lang.invoke.constant.DynamicConstantDesc}, such as
- * {@link java.lang.Enum.EnumDesc}.
- *
- * <p>Another way to obtain the nominal description of a value is to ask the value
- * itself.  A {@link java.lang.invoke.constant.Constable} is a type whose values
- * can describe themselves in nominal form as a {@link java.lang.invoke.constant.ConstantDesc}.
- * Fundamental types such as {@link java.lang.String} and {@link java.lang.Class}
- * implement {@link java.lang.invoke.constant.Constable}, as can user-defined
- * classes.  Entities that generate classfiles (such as compilers) can introspect
- * over constable objects to obtain a more efficient way to represent their values
- * in classfiles.
- *
- * <p>This package also includes {@link java.lang.invoke.constant.DynamicCallSiteDesc},
- * which represents a (non-loadable) {@code Constant_InvokeDynamic_info} constant
- * pool entry.  It describes the bootstrap method, invocation name and type,
- * and bootstrap arguments associated with an {@code invokedynamic} instruction.
- * It is also suitable for describing {@code invokedynamic} call sites in bytecode
- * reading and writing APIs, and and is used by the
- * {@link java.lang.invoke.Intrinsics#invokedynamic(DynamicCallSiteDesc, java.lang.Object...)}
- * API for expressing {@code invokedynamic} call sites in Java source files.
- * @jvms 4.4 The Constant Pool
- */
-package java.lang.invoke.constant;
-
--- a/src/java.base/share/classes/jdk/internal/lang/annotation/Foldable.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/jdk/internal/lang/annotation/Foldable.java	Mon Jun 04 14:59:22 2018 -0700
@@ -26,8 +26,8 @@
 
 import java.lang.annotation.*;
 
-import java.lang.invoke.constant.Constable;
-import java.lang.invoke.constant.ConstantDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
 import java.lang.invoke.Intrinsics;
 
 /**
--- a/src/java.base/share/classes/module-info.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/java.base/share/classes/module-info.java	Mon Jun 04 14:59:22 2018 -0700
@@ -83,7 +83,7 @@
     exports java.lang.module;
     exports java.lang.ref;
     exports java.lang.reflect;
-    exports java.lang.invoke.constant;
+    exports java.lang.constant;
     exports java.math;
     exports java.net;
     exports java.net.spi;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Mon Jun 04 14:59:22 2018 -0700
@@ -100,14 +100,14 @@
         log = Log.instance(context);
         constablesVisitor = ConstablesVisitor.instance(context);
         try {
-            directMethodHandleRefClass = Class.forName("java.lang.invoke.constant.ConstantMethodHandleDesc", false, null);
-            methodTypeRefClass = Class.forName("java.lang.invoke.constant.MethodTypeDesc", false, null);
-            classRefClass = Class.forName("java.lang.invoke.constant.ClassDesc", false, null);
-            constantRefClass = Class.forName("java.lang.invoke.constant.ConstantDesc", false, null);
-            constableClass = Class.forName("java.lang.invoke.constant.Constable", false, null);
-            dynamicCallsiteRefClass = Class.forName("java.lang.invoke.constant.DynamicCallSiteDesc", false, null);
-            dynamicConstantClass = Class.forName("java.lang.invoke.constant.DynamicConstantDesc", false, null);
-            symRefs = Class.forName("java.lang.invoke.constant.ConstantDescs", false, null);
+            directMethodHandleRefClass = Class.forName("java.lang.constant.ConstantMethodHandleDesc", false, null);
+            methodTypeRefClass = Class.forName("java.lang.constant.MethodTypeDesc", false, null);
+            classRefClass = Class.forName("java.lang.constant.ClassDesc", false, null);
+            constantRefClass = Class.forName("java.lang.constant.ConstantDesc", false, null);
+            constableClass = Class.forName("java.lang.constant.Constable", false, null);
+            dynamicCallsiteRefClass = Class.forName("java.lang.constant.DynamicCallSiteDesc", false, null);
+            dynamicConstantClass = Class.forName("java.lang.constant.DynamicConstantDesc", false, null);
+            symRefs = Class.forName("java.lang.constant.ConstantDescs", false, null);
         } catch (ClassNotFoundException ex) {
             directMethodHandleRefClass = null;
             methodTypeRefClass = null;
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriterImpl.java	Mon Jun 04 14:59:22 2018 -0700
@@ -77,7 +77,7 @@
 
     private static final Set<String> suppressImplementingSet
             = Set.of( "java.lang.Cloneable",
-                    "java.lang.invoke.constant.Constable",
+                    "java.lang.constant.Constable",
                     "java.io.Serializable");
 
     protected final TypeElement typeElement;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/ClassRefTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,268 @@
+/*
+ * 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.
+ */
+
+import java.lang.invoke.MethodHandles;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.ConstantUtils;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * @test
+ * @compile -XDfolding=false ClassRefTest.java
+ * @run testng ClassRefTest
+ * @summary unit tests for java.lang.constant.ClassDesc
+ */
+@Test
+public class ClassRefTest extends SymbolicRefTest {
+
+    private void testClassRef(ClassDesc r) throws ReflectiveOperationException {
+        testSymbolicRef(r);
+
+        // Test descriptor accessor, factory, equals
+        assertEquals(r, ClassDesc.ofDescriptor(r.descriptorString()));
+
+        if (!r.descriptorString().equals("V")) {
+            assertEquals(r, r.arrayType().componentType());
+            // Commutativity: array -> resolve -> componentType -> toSymbolic
+            assertEquals(r, r.arrayType().resolveConstantDesc(LOOKUP).getComponentType().describeConstable().orElseThrow());
+            // Commutativity: resolve -> array -> toSymbolic -> component type
+            assertEquals(r, Array.newInstance(r.resolveConstantDesc(LOOKUP), 0).getClass().describeConstable().orElseThrow().componentType());
+        }
+
+        if (r.isArray()) {
+            assertEquals(r, r.componentType().arrayType());
+            assertEquals(r, r.resolveConstantDesc(LOOKUP).getComponentType().describeConstable().orElseThrow().arrayType());
+            assertEquals(r, Array.newInstance(r.componentType().resolveConstantDesc(LOOKUP), 0).getClass().describeConstable().orElseThrow());
+        }
+    }
+
+    private void testClassRef(ClassDesc r, Class<?> c) throws ReflectiveOperationException {
+        testClassRef(r);
+
+        assertEquals(r.resolveConstantDesc(LOOKUP), c);
+        assertEquals(c.describeConstable().orElseThrow(), r);
+        assertEquals(ClassDesc.ofDescriptor(c.descriptorString()), r);
+    }
+
+    public void testSymbolicRefsConstants() throws ReflectiveOperationException {
+        int tested = 0;
+        Field[] fields = ConstantDescs.class.getDeclaredFields();
+        for (Field f : fields) {
+            try {
+                if (f.getType().equals(ClassDesc.class)
+                    && ((f.getModifiers() & Modifier.STATIC) != 0)
+                    && ((f.getModifiers() & Modifier.PUBLIC) != 0)) {
+                    ClassDesc cr = (ClassDesc) f.get(null);
+                    Class c = cr.resolveConstantDesc(MethodHandles.lookup());
+                    testClassRef(cr, c);
+                    ++tested;
+                }
+            }
+            catch (Throwable e) {
+                System.out.println(e.getMessage());
+                fail("Error testing field " + f.getName(), e);
+            }
+        }
+
+        assertTrue(tested > 0);
+    }
+
+    public void testPrimitiveClassRef() throws ReflectiveOperationException {
+        for (Primitives p : Primitives.values()) {
+            List<ClassDesc> refs = List.of(ClassDesc.ofDescriptor(p.descriptor),
+                                           p.classRef,
+                                           (ClassDesc) p.clazz.describeConstable().orElseThrow());
+            for (ClassDesc c : refs) {
+                testClassRef(c, p.clazz);
+                assertTrue(c.isPrimitive());
+                assertEquals(p.descriptor, c.descriptorString());
+                assertEquals(p.name, c.displayName());
+                refs.forEach(cc -> assertEquals(c, cc));
+                if (p != Primitives.VOID) {
+                    testClassRef(c.arrayType(), p.arrayClass);
+                    assertEquals(c, ((ClassDesc) p.arrayClass.describeConstable().orElseThrow()).componentType());
+                    assertEquals(c, p.classRef.arrayType().componentType());
+                }
+            }
+
+            for (Primitives other : Primitives.values()) {
+                ClassDesc otherDescr = ClassDesc.ofDescriptor(other.descriptor);
+                if (p != other)
+                    refs.forEach(c -> assertNotEquals(c, otherDescr));
+                else
+                    refs.forEach(c -> assertEquals(c, otherDescr));
+            }
+        }
+    }
+
+    public void testSimpleClassRef() throws ReflectiveOperationException {
+
+        List<ClassDesc> stringClassRefs = Arrays.asList(ClassDesc.ofDescriptor("Ljava/lang/String;"),
+                                                        ClassDesc.of("java.lang", "String"),
+                                                        ClassDesc.of("java.lang.String"),
+                                                        ClassDesc.of("java.lang.String").arrayType().componentType(),
+                                                        String.class.describeConstable().orElseThrow());
+        for (ClassDesc r : stringClassRefs) {
+            testClassRef(r, String.class);
+            assertFalse(r.isPrimitive());
+            assertEquals("Ljava/lang/String;", r.descriptorString());
+            assertEquals("String", r.displayName());
+            assertEquals(r.arrayType().resolveConstantDesc(LOOKUP), String[].class);
+            stringClassRefs.forEach(rr -> assertEquals(r, rr));
+        }
+
+        testClassRef(ClassDesc.of("java.lang.String").arrayType(), String[].class);
+        testClassRef(ClassDesc.of("java.util.Map").inner("Entry"), Map.Entry.class);
+
+        ClassDesc thisClassRef = ClassDesc.ofDescriptor("LClassRefTest;");
+        assertEquals(thisClassRef, ClassDesc.of("", "ClassRefTest"));
+        assertEquals(thisClassRef, ClassDesc.of("ClassRefTest"));
+        assertEquals(thisClassRef.displayName(), "ClassRefTest");
+        testClassRef(thisClassRef, ClassRefTest.class);
+    }
+
+    private void testBadPackageName(ClassDesc cr) {
+        try {
+            cr.packageName();
+            fail("");
+        } catch (IllegalStateException e) {
+            // good
+        }
+    }
+
+    public void testPackageName() {
+        assertEquals("com.foo", ClassDesc.of("com.foo.Bar").packageName());
+        assertEquals("com.foo", ClassDesc.of("com.foo.Bar").inner("Baz").packageName());
+        assertEquals("", ClassDesc.of("Bar").packageName());
+        assertEquals("", ClassDesc.of("Bar").inner("Baz").packageName());
+
+        testBadPackageName(ConstantDescs.CR_int);
+        testBadPackageName(ConstantDescs.CR_int.arrayType());
+        testBadPackageName(ConstantDescs.CR_String.arrayType());
+        testBadPackageName(ClassDesc.of("Bar").arrayType());
+    }
+
+    private void testBadArrayRank(ClassDesc cr) {
+        try {
+            cr.arrayType(-1);
+            fail("");
+        } catch (IllegalArgumentException e) {
+            // good
+        }
+    }
+
+    public void testArrayClassRef() throws ReflectiveOperationException {
+        for (String d : basicDescs) {
+            ClassDesc a0 = ClassDesc.ofDescriptor(d);
+            ClassDesc a1 = a0.arrayType();
+            ClassDesc a2 = a1.arrayType();
+
+            testClassRef(a0);
+            testClassRef(a1);
+            testClassRef(a2);
+            assertFalse(a0.isArray());
+            assertTrue(a1.isArray());
+            assertTrue(a2.isArray());
+            assertFalse(a1.isPrimitive());
+            assertFalse(a2.isPrimitive());
+            assertEquals(a0.descriptorString(), d);
+            assertEquals(a1.descriptorString(), "[" + a0.descriptorString());
+            assertEquals(a2.descriptorString(), "[[" + a0.descriptorString());
+
+            assertNull(a0.componentType());
+            assertEquals(a0, a1.componentType());
+            assertEquals(a1, a2.componentType());
+
+            assertNotEquals(a0, a1);
+            assertNotEquals(a1, a2);
+
+            assertEquals(a1, ClassDesc.ofDescriptor("[" + d));
+            assertEquals(a2, ClassDesc.ofDescriptor("[[" + d));
+            assertEquals(classToDescriptor(a0.resolveConstantDesc(LOOKUP)), a0.descriptorString());
+            assertEquals(classToDescriptor(a1.resolveConstantDesc(LOOKUP)), a1.descriptorString());
+            assertEquals(classToDescriptor(a2.resolveConstantDesc(LOOKUP)), a2.descriptorString());
+
+            testBadArrayRank(ConstantDescs.CR_int);
+            testBadArrayRank(ConstantDescs.CR_String);
+            testBadArrayRank(ClassDesc.of("Bar"));
+        }
+    }
+
+    public void testBadClassRefs() {
+        List<String> badDescriptors = List.of("II", "I;", "Q", "L",
+                                              "java.lang.String", "[]", "Ljava/lang/String",
+                                              "Ljava.lang.String;", "java/lang/String");
+
+        for (String d : badDescriptors) {
+            try {
+                ClassDesc constant = ClassDesc.ofDescriptor(d);
+                fail(d);
+            }
+            catch (IllegalArgumentException e) {
+                // good
+            }
+        }
+
+        List<String> badBinaryNames = List.of("I;", "[]", "Ljava/lang/String",
+                "Ljava.lang.String;", "java/lang/String");
+        for (String d : badBinaryNames) {
+            try {
+                ClassDesc constant = ClassDesc.of(d);
+                fail(d);
+            } catch (IllegalArgumentException e) {
+                // good
+            }
+        }
+
+        for (Primitives p : Primitives.values()) {
+            testBadInnerClasses(ClassDesc.ofDescriptor(p.descriptor), "any");
+            testBadInnerClasses(ClassDesc.ofDescriptor(p.descriptor), "any", "other");
+        }
+    }
+
+    private void testBadInnerClasses(ClassDesc cr, String firstInnerName, String... moreInnerNames) {
+        try {
+            cr.inner(firstInnerName, moreInnerNames);
+            fail("");
+        } catch (IllegalStateException e) {
+            // good
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/CondyRefTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,215 @@
+/*
+ * 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.
+ */
+
+import java.lang.Enum.EnumDesc;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.VarHandle;
+import java.lang.invoke.VarHandle.VarHandleDesc;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.ConstantDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.ConstantMethodHandleDesc;
+import java.lang.constant.DynamicConstantDesc;
+import java.lang.constant.MethodHandleDesc;
+
+import org.testng.annotations.Test;
+
+import static java.lang.constant.ConstantDescs.CR_MethodHandle;
+import static java.lang.constant.ConstantDescs.CR_Object;
+import static java.lang.constant.ConstantDescs.CR_String;
+import static java.lang.constant.ConstantDescs.CR_VarHandle;
+import static java.lang.constant.ConstantDescs.CR_int;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @test
+ * @compile -XDfolding=false CondyRefTest.java
+ * @run testng CondyRefTest
+ * @summary unit tests for java.lang.constant.CondyRefTest
+ */
+@Test
+public class CondyRefTest extends SymbolicRefTest {
+    private final static ConstantDesc<?>[] EMPTY_ARGS = new ConstantDesc<?>[0];
+    private final static ClassDesc CR_ConstantBootstraps = ClassDesc.of("java.lang.invoke.ConstantBootstraps");
+
+    private static<T> void testDCR(DynamicConstantDesc<T> r, T c) throws ReflectiveOperationException {
+        assertEquals(r, DynamicConstantDesc.of(r.bootstrapMethod(), r.constantName(), r.constantType(), r.bootstrapArgs()));
+        assertEquals(r.resolveConstantDesc(LOOKUP), c);
+    }
+
+    private void testVarHandleRef(DynamicConstantDesc<VarHandle> r, VarHandle vh) throws ReflectiveOperationException  {
+        testSymbolicRef(r);
+        assertEquals(r.resolveConstantDesc(LOOKUP), vh);
+        assertEquals(vh.describeConstable().orElseThrow(), r);
+    }
+
+    private static<E extends Enum<E>> void testEnumRef(EnumDesc<E> r, E e) throws ReflectiveOperationException {
+        testSymbolicRef(r);
+
+        assertEquals(r, EnumDesc.of(r.constantType(), r.constantName()));
+        assertEquals(r.resolveConstantDesc(LOOKUP), e);
+    }
+
+    public void testNullConstant() throws ReflectiveOperationException {
+        DynamicConstantDesc<?> r = (DynamicConstantDesc<?>) ConstantDescs.NULL;
+        assertEquals(r, DynamicConstantDesc.of(r.bootstrapMethod(), r.constantName(), r.constantType(), r.bootstrapArgs()));
+        assertNull(r.resolveConstantDesc(LOOKUP));
+    }
+
+    static String concatBSM(MethodHandles.Lookup lookup, String name, Class<?> type, String a, String b) {
+        return a + b;
+    }
+
+    public void testDynamicConstant() throws ReflectiveOperationException {
+        ConstantMethodHandleDesc bsmRef = ConstantDescs.ofConstantBootstrap(ClassDesc.of("CondyRefTest"), "concatBSM",
+                                                                            CR_String, CR_String, CR_String);
+        DynamicConstantDesc<String> r = DynamicConstantDesc.<String>of(bsmRef).withArgs("foo", "bar");
+        testDCR(r, "foobar");
+    }
+
+    public void testNested() throws Throwable {
+        ConstantMethodHandleDesc invoker = ConstantDescs.ofConstantBootstrap(CR_ConstantBootstraps, "invoke", CR_Object, CR_MethodHandle, CR_Object.arrayType());
+        ConstantMethodHandleDesc format = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_String, "format", CR_String, CR_String, CR_Object.arrayType());
+
+        String s = (String) invoker.resolveConstantDesc(LOOKUP)
+                                   .invoke(LOOKUP, "", String.class,
+                                           format.resolveConstantDesc(LOOKUP), "%s%s", "moo", "cow");
+        assertEquals(s, "moocow");
+
+        DynamicConstantDesc<String> ref = DynamicConstantDesc.<String>of(invoker).withArgs(format, "%s%s", "moo", "cow");
+        testDCR(ref, "moocow");
+
+        DynamicConstantDesc<String> ref2 = DynamicConstantDesc.<String>of(invoker).withArgs(format, "%s%s", ref, "cow");
+        testDCR(ref2, "moocowcow");
+    }
+
+    enum MyEnum { A, B, C }
+
+    public void testEnumRef() throws ReflectiveOperationException {
+        ClassDesc enumClass = ClassDesc.of("CondyRefTest").inner("MyEnum");
+
+        testEnumRef(EnumDesc.of(enumClass, "A"), MyEnum.A);
+        testEnumRef(EnumDesc.of(enumClass, "B"), MyEnum.B);
+        testEnumRef(EnumDesc.of(enumClass, "C"), MyEnum.C);
+    }
+
+    static class MyClass {
+        static int sf;
+        int f;
+    }
+
+    public void testVarHandles() throws ReflectiveOperationException {
+        ClassDesc testClass = ClassDesc.of("CondyRefTest").inner("MyClass");
+        MyClass instance = new MyClass();
+
+        // static varHandle
+        VarHandleDesc vhc = VarHandleDesc.ofStaticField(testClass, "sf", CR_int);
+        VarHandle varHandle = LOOKUP.findStaticVarHandle(MyClass.class, "sf", int.class);
+        testVarHandleRef(vhc, varHandle);
+
+        assertEquals(varHandle.varType(), int.class);
+        varHandle.set(8);
+        assertEquals(8, (int) varHandle.get());
+        assertEquals(MyClass.sf, 8);
+
+        // static varHandle
+        vhc = VarHandleDesc.ofField(testClass, "f", CR_int);
+        varHandle = LOOKUP.findVarHandle(MyClass.class, "f", int.class);
+        testVarHandleRef(vhc, varHandle);
+
+        assertEquals(varHandle.varType(), int.class);
+        varHandle.set(instance, 9);
+        assertEquals(9, (int) varHandle.get(instance));
+        assertEquals(instance.f, 9);
+
+        vhc = VarHandleDesc.ofArray(CR_int.arrayType());
+        varHandle = MethodHandles.arrayElementVarHandle(int[].class);
+        testVarHandleRef(vhc, varHandle);
+
+        int[] ints = new int[3];
+        varHandle.set(ints, 0, 1);
+        varHandle.set(ints, 1, 2);
+        varHandle.set(ints, 2, 3);
+
+        assertEquals(1, varHandle.get(ints, 0));
+        assertEquals(2, varHandle.get(ints, 1));
+        assertEquals(3, varHandle.get(ints, 2));
+        assertEquals(1, ints[0]);
+        assertEquals(2, ints[1]);
+        assertEquals(3, ints[2]);
+    }
+
+    private<T> void assertLifted(ConstantDesc<T> prototype,
+                                 DynamicConstantDesc<T> nonCanonical,
+                                 ConstantDesc<T> canonical) {
+        Class<?> clazz = prototype.getClass();
+
+        assertTrue(canonical != nonCanonical);
+        assertTrue(clazz.isAssignableFrom(canonical.getClass()));
+        assertFalse(clazz.isAssignableFrom(nonCanonical.getClass()));
+        assertTrue(prototype.equals(canonical));
+        assertTrue(canonical.equals(prototype));
+        if (prototype instanceof DynamicConstantDesc) {
+            assertTrue(canonical.equals(nonCanonical));
+            assertTrue(nonCanonical.equals(canonical));
+            assertTrue(prototype.equals(nonCanonical));
+            assertTrue(nonCanonical.equals(prototype));
+        }
+    }
+
+    public void testLifting() {
+        DynamicConstantDesc<Object> unliftedNull = DynamicConstantDesc.of(ConstantDescs.BSM_NULL_CONSTANT, "_", CR_Object, EMPTY_ARGS);
+        assertEquals(ConstantDescs.NULL, unliftedNull);
+        assertTrue(ConstantDescs.NULL != unliftedNull);
+        assertTrue(ConstantDescs.NULL == DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_NULL_CONSTANT, "_", CR_Object, EMPTY_ARGS));
+        assertTrue(ConstantDescs.NULL == DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_NULL_CONSTANT, "_", CR_String, EMPTY_ARGS));
+        assertTrue(ConstantDescs.NULL == DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_NULL_CONSTANT, "wahoo", CR_Object, EMPTY_ARGS));
+
+        assertLifted(CR_int,
+                     DynamicConstantDesc.of(ConstantDescs.BSM_PRIMITIVE_CLASS, "I", ConstantDescs.CR_Class, EMPTY_ARGS),
+                     DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_PRIMITIVE_CLASS, "I", ConstantDescs.CR_Class, EMPTY_ARGS));
+
+        ClassDesc enumClass = ClassDesc.of("CondyRefTest").inner("MyEnum");
+        assertLifted(EnumDesc.of(enumClass, "A"),
+                     DynamicConstantDesc.of(ConstantDescs.BSM_ENUM_CONSTANT, "A", enumClass, EMPTY_ARGS),
+                     DynamicConstantDesc.<MyEnum>ofCanonical(ConstantDescs.BSM_ENUM_CONSTANT, "A", enumClass, EMPTY_ARGS));
+
+        ClassDesc testClass = ClassDesc.of("CondyRefTest").inner("MyClass");
+        assertLifted(VarHandleDesc.ofStaticField(testClass, "sf", CR_int),
+                     DynamicConstantDesc.of(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, "sf", CR_VarHandle, new ConstantDesc<?>[] {testClass, "sf", CR_int }),
+                     DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_STATIC_FIELD, "sf", CR_VarHandle, new ConstantDesc<?>[] {testClass, "sf", CR_int }));
+        assertLifted(VarHandleDesc.ofField(testClass, "f", CR_int),
+                     DynamicConstantDesc.of(ConstantDescs.BSM_VARHANDLE_FIELD, "f", CR_VarHandle, new ConstantDesc<?>[] {testClass, "f", CR_int }),
+                     DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_FIELD, "f", CR_VarHandle, new ConstantDesc<?>[] {testClass, "f", CR_int }));
+        assertLifted(VarHandleDesc.ofArray(CR_int.arrayType()),
+                     DynamicConstantDesc.of(ConstantDescs.BSM_VARHANDLE_ARRAY, "_", CR_VarHandle, new ConstantDesc<?>[] {CR_int.arrayType() }),
+                     DynamicConstantDesc.ofCanonical(ConstantDescs.BSM_VARHANDLE_ARRAY, "_", CR_VarHandle, new ConstantDesc<?>[] {CR_int.arrayType() }));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/ConstantUtilsTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+import java.lang.invoke.*;
+import java.lang.constant.*;
+import java.util.*;
+
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.*;
+
+/**
+ * @test
+ * @compile -XDfolding=false ConstantUtilsTest.java
+ * @run testng ConstantUtilsTest
+ * @summary unit tests for methods of java.lang.constant.ConstantUtils that are not covered by other unit tests
+ */
+@Test
+public class ConstantUtilsTest {
+    private static ClassDesc thisClass = ClassDesc.of("MethodHandleRefTest");
+
+    public void testValidateMemberName() {
+        try {
+            ConstantUtils.validateMemberName(null);
+            fail("");
+        } catch (NullPointerException e) {
+            // good
+        }
+
+        try {
+            ConstantUtils.validateMemberName("");
+            fail("");
+        } catch (IllegalArgumentException e) {
+            // good
+        }
+
+        List<String> badNames = List.of(".", ";", "[", "/", "<", ">");
+        for (String n : badNames) {
+            try {
+                ConstantUtils.validateMemberName(n);
+                fail(n);
+            } catch (IllegalArgumentException e) {
+                // good
+            }
+        }
+    }
+
+    public void testSymbolizeHelper() {
+        ConstantMethodHandleDesc mh = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, ConstantDescs.CR_String, "isEmpty", "()Z");
+        try {
+            ConstantUtils.symbolizeHelper(mh, null, "");
+            fail("");
+        } catch (NullPointerException e) {
+            // good
+        }
+
+        try {
+            ConstantUtils.symbolizeHelper(null, ConstantDescs.CR_ClassDesc, "");
+            fail("");
+        } catch (NullPointerException e) {
+            // good
+        }
+
+        try {
+            ConstantUtils.symbolizeHelper(null, null, "");
+            fail("");
+        } catch (NullPointerException e) {
+            // good
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/IndyRefTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.ConstantMethodHandleDesc;
+import java.lang.constant.DynamicCallSiteDesc;
+import java.lang.constant.MethodHandleDesc;
+import java.lang.constant.MethodTypeDesc;
+
+import org.testng.annotations.Test;
+
+import static java.lang.constant.ConstantDescs.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
+
+/**
+ * @test
+ * @compile -XDfolding=false IndyRefTest.java
+ * @run testng IndyRefTest
+ * @summary unit tests for java.lang.constant.IndyRefTest
+ */
+@Test
+public class IndyRefTest {
+    public static CallSite bootstrap(MethodHandles.Lookup lookup, String name, MethodType type,
+                                     Object... args) {
+        if (args.length == 0)
+            return new ConstantCallSite(MethodHandles.constant(String.class, "Foo"));
+        else
+            return new ConstantCallSite(MethodHandles.constant(String.class, (String) args[0]));
+    }
+
+    public void testIndyRef() throws Throwable {
+        ClassDesc c = ClassDesc.of("IndyRefTest");
+        MethodTypeDesc mt = MethodTypeDesc.of(CR_CallSite, CR_MethodHandles_Lookup, CR_String, CR_MethodType, CR_Object.arrayType());
+        ConstantMethodHandleDesc mh = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, c, "bootstrap", mt);
+        DynamicCallSiteDesc csd = DynamicCallSiteDesc.of(mh, "wooga", MethodTypeDesc.of(CR_String));
+        CallSite cs = csd.resolveCallSiteDesc(MethodHandles.lookup());
+        MethodHandle target = cs.getTarget();
+        assertEquals("Foo", target.invoke());
+        assertEquals("wooga", csd.invocationName());
+
+        DynamicCallSiteDesc csd2 = DynamicCallSiteDesc.of(mh, "foo", MethodTypeDesc.of(CR_String), "Bar");
+        CallSite cs2 = csd2.resolveCallSiteDesc(MethodHandles.lookup());
+        MethodHandle target2 = cs2.getTarget();
+        assertEquals("Bar", target2.invoke());
+        assertEquals("foo", csd2.invocationName());
+
+        DynamicCallSiteDesc csd3 = DynamicCallSiteDesc.of(mh, MethodTypeDesc.of(CR_String));
+        CallSite cs3 = csd.resolveCallSiteDesc(MethodHandles.lookup());
+        MethodHandle target3 = cs3.getTarget();
+        assertEquals("Foo", target3.invoke());
+        assertEquals("_", csd3.invocationName());
+
+        DynamicCallSiteDesc csd4 = DynamicCallSiteDesc.of(mh, "foo", MethodTypeDesc.of(CR_String)).withArgs("Bar");
+        CallSite cs4 = csd4.resolveCallSiteDesc(MethodHandles.lookup());
+        MethodHandle target4 = cs4.getTarget();
+        assertEquals("Bar", target4.invoke());
+
+        DynamicCallSiteDesc csd5 = DynamicCallSiteDesc.of(mh, MethodTypeDesc.of(CR_String, CR_String))
+                .withNameAndType("foo", MethodTypeDesc.of(CR_String)).withArgs("Bar");
+        CallSite cs5 = csd5.resolveCallSiteDesc(MethodHandles.lookup());
+        MethodHandle target5 = cs5.getTarget();
+        assertEquals("Bar", target5.invoke());
+        assertEquals("foo", csd5.invocationName());
+    }
+
+    public void testEqualsHashToString() throws Throwable {
+        ClassDesc c = ClassDesc.of("IndyRefTest");
+        MethodTypeDesc mt = MethodTypeDesc.of(CR_CallSite, CR_MethodHandles_Lookup, CR_String, CR_MethodType, CR_Object.arrayType());
+        ConstantMethodHandleDesc mh = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, c, "bootstrap", mt);
+
+        DynamicCallSiteDesc csd1 = DynamicCallSiteDesc.of(mh, "wooga", MethodTypeDesc.of(CR_String));
+        DynamicCallSiteDesc csd2 = DynamicCallSiteDesc.of(mh, "wooga", MethodTypeDesc.of(CR_String));
+        DynamicCallSiteDesc csd3 = DynamicCallSiteDesc.of(mh, "foo", MethodTypeDesc.of(CR_String));
+        assertEquals(csd1, csd2);
+        assertEquals(csd1.hashCode(), csd2.hashCode());
+        assertNotEquals(csd1, csd3);
+        assertNotEquals(csd1.hashCode(), csd3.hashCode());
+
+        assertEquals(csd1.toString(), "DynamicCallSiteDesc[IndyRefTest::bootstrap(wooga/):()String]");
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testEmptyInvocationName() throws Throwable {
+        ClassDesc c = ClassDesc.of("IndyRefTest");
+        MethodTypeDesc mt = MethodTypeDesc.of(CR_CallSite, CR_MethodHandles_Lookup, CR_String, CR_MethodType, CR_Object.arrayType());
+        ConstantMethodHandleDesc mh = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, c, "bootstrap", mt);
+        DynamicCallSiteDesc csd1 = DynamicCallSiteDesc.of(mh, "", MethodTypeDesc.of(CR_String));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/IntrinsifiedRefTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 2018, 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.
+ */
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.Enum.EnumDesc;
+import java.lang.constant.MethodHandleDesc;
+import java.lang.constant.MethodTypeDesc;
+import java.util.function.Supplier;
+
+import org.testng.annotations.Test;
+
+import static java.lang.invoke.Intrinsics.ldc;
+import static java.lang.constant.MethodHandleDesc.Kind.GETTER;
+import static java.lang.constant.MethodHandleDesc.Kind.SETTER;
+import static java.lang.constant.MethodHandleDesc.Kind.STATIC_GETTER;
+import static java.lang.constant.MethodHandleDesc.Kind.STATIC_SETTER;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.fail;
+
+/**
+ * @test
+ * @compile IntrinsifiedRefTest.java
+ * @run testng IntrinsifiedRefTest
+ * @summary Integration test for intrinsification of XxxRef
+ */
+@Test
+public class IntrinsifiedRefTest {
+    public static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+    private static final ClassDesc CR_THIS = ClassDesc.of("IntrinsifiedRefTest");
+    private static final ClassDesc CR_TESTCLASS = CR_THIS.inner("TestClass");
+    private static final ClassDesc CR_TESTINTF = CR_THIS.inner("TestInterface");
+    private static final ClassDesc CR_TESTSUPERCLASS = CR_THIS.inner("TestSuperclass");
+    private static final ClassDesc CR_TESTENUM = CR_THIS.inner("TestEnum");
+    private static final String NONEXISTENT_CLASS = "foo.Bar";
+    private static final String INACCESSIBLE_CLASS = "java.lang.invoke.DirectMethodHandle";
+
+    private static final MethodHandleDesc MHR_TESTCLASS_CTOR = MethodHandleDesc.of(MethodHandleDesc.Kind.CONSTRUCTOR, CR_TESTCLASS, "<ignored!>", MethodTypeDesc.ofDescriptor("()V"));
+    private static final MethodHandleDesc MHR_TESTCLASS_SM = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_TESTCLASS, "sm", "(I)I");
+    private static final MethodHandleDesc MHR_TESTINTF_SM = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_TESTINTF, "sm", "(I)I");
+    private static final MethodHandleDesc MHR_TESTCLASS_M = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_TESTCLASS, "m", MethodTypeDesc.ofDescriptor("(I)I"));
+    private static final MethodHandleDesc MHR_TESTINTF_M = MethodHandleDesc.of(MethodHandleDesc.Kind.INTERFACE_VIRTUAL, CR_TESTINTF, "m", MethodTypeDesc.ofDescriptor("(I)I"));
+    private static final MethodHandleDesc MHR_TESTCLASS_PM_SPECIAL = MethodHandleDesc.of(MethodHandleDesc.Kind.SPECIAL, CR_TESTCLASS, "pm", MethodTypeDesc.ofDescriptor("(I)I"));
+    private static final MethodHandleDesc MHR_TESTINTF_PM_SPECIAL = MethodHandleDesc.of(MethodHandleDesc.Kind.SPECIAL, CR_TESTINTF, "pm", MethodTypeDesc.ofDescriptor("(I)I"));
+    private static final MethodHandleDesc MHR_TESTCLASS_PSM = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_TESTCLASS, "psm", MethodTypeDesc.ofDescriptor("(I)I"));
+    private static final MethodHandleDesc MHR_TESTINTF_PSM = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_TESTINTF, "psm", MethodTypeDesc.ofDescriptor("(I)I"));
+    private static final MethodHandleDesc MHR_TESTSUPER_M_SPECIAL = MethodHandleDesc.of(MethodHandleDesc.Kind.SPECIAL, CR_TESTSUPERCLASS, "m", "(I)I");
+    private static final MethodHandleDesc MHR_TESTINTF_M_SPECIAL = MethodHandleDesc.of(MethodHandleDesc.Kind.SPECIAL, CR_TESTINTF, "m", "(I)I");
+    private static final MethodHandleDesc MHR_TESTCLASS_SF_SETTER = MethodHandleDesc.ofField(STATIC_SETTER, CR_TESTCLASS, "sf", ConstantDescs.CR_int);
+    private static final MethodHandleDesc MHR_TESTCLASS_SF_GETTER = MethodHandleDesc.ofField(STATIC_GETTER, CR_TESTCLASS, "sf", ConstantDescs.CR_int);
+    private static final MethodHandleDesc MHR_TESTINTF_SF_GETTER = MethodHandleDesc.ofField(STATIC_GETTER, CR_TESTINTF, "sf", ConstantDescs.CR_int);
+    private static final MethodHandleDesc MHR_TESTCLASS_F_SETTER = MethodHandleDesc.ofField(SETTER, CR_TESTCLASS, "f", ConstantDescs.CR_int);
+    private static final MethodHandleDesc MHR_TESTCLASS_F_GETTER = MethodHandleDesc.ofField(GETTER, CR_TESTCLASS, "f", ConstantDescs.CR_int);
+
+
+
+    private static <T extends Constable> void assertIntrinsic(ConstantDesc<T> ref, T intrinsified, T target) throws ReflectiveOperationException {
+        assertEquals(target, intrinsified);
+        assertEquals(ref.resolveConstantDesc(LOOKUP), intrinsified);
+        assertEquals(intrinsified.describeConstable().orElseThrow(), ref);
+    }
+
+    private static<T extends Constable> void assertIntrinsicFail(ConstantDesc<T> ref, Supplier<T> supplier, Class<? extends Throwable> exception) {
+        try {
+            T t = supplier.get();
+            fail("Expected failure resolving " + ref);
+        } catch (Throwable e) {
+            if (exception.isAssignableFrom(e.getClass()))
+                return;
+            else if (e instanceof BootstrapMethodError) {
+                Throwable cause = e.getCause();
+                if (cause != null && exception.isAssignableFrom(cause.getClass()))
+                    return;
+            }
+            fail(String.format("Expected %s, found %s for %s", exception, e.getClass(), ref));
+        }
+    }
+
+    public void testLdcClass() throws ReflectiveOperationException {
+        ClassDesc cr1 = ClassDesc.ofDescriptor("Ljava/lang/String;");
+        ClassDesc cr2 = ClassDesc.of("java.lang.String");
+        ClassDesc cr3 = ClassDesc.of("java.lang", "String");
+
+        assertIntrinsic(cr1, ldc(cr1), String.class);
+        assertIntrinsic(cr2, ldc(cr2), String.class);
+        assertIntrinsic(cr3, ldc(cr3), String.class);
+
+        ClassDesc cr4 = ClassDesc.ofDescriptor("[Ljava/lang/String;");
+        ClassDesc cr5 = cr2.arrayType();
+        assertIntrinsic(cr4, ldc(cr4), String[].class);
+        assertIntrinsic(cr5, ldc(cr5), String[].class);
+
+        ClassDesc cr6 = ClassDesc.ofDescriptor("I");
+        assertIntrinsic(cr6, ldc(cr6), int.class);
+        assertIntrinsic(ConstantDescs.CR_int, ldc(ConstantDescs.CR_int), int.class);
+
+        ClassDesc cr7 = ClassDesc.ofDescriptor("[I");
+        ClassDesc cr8 = ConstantDescs.CR_int.arrayType();
+        assertIntrinsic(cr7, ldc(cr7), int[].class);
+        assertIntrinsic(cr8, ldc(cr8), int[].class);
+    }
+
+    public void negLdcClass() {
+        ClassDesc cr = ClassDesc.of(NONEXISTENT_CLASS);
+        assertIntrinsicFail(cr, () -> ldc(cr), NoClassDefFoundError.class);
+
+        ClassDesc cr2 = ClassDesc.of(INACCESSIBLE_CLASS);
+        assertIntrinsicFail(cr2, () -> ldc(cr2), IllegalAccessError.class);
+    }
+
+    public void testLdcMethodType() throws ReflectiveOperationException {
+        MethodTypeDesc mtr1 = MethodTypeDesc.ofDescriptor("()V");
+        MethodTypeDesc mtr2 = MethodTypeDesc.of(ConstantDescs.CR_void);
+        assertIntrinsic(mtr1, ldc(mtr1), MethodType.methodType(void.class));
+        assertIntrinsic(mtr2, ldc(mtr2), MethodType.methodType(void.class));
+
+        MethodTypeDesc mtr3 = MethodTypeDesc.ofDescriptor("(I)I");
+        MethodTypeDesc mtr4 = MethodTypeDesc.of(ConstantDescs.CR_int, ConstantDescs.CR_int);
+        assertIntrinsic(mtr3, ldc(mtr3), MethodType.methodType(int.class, int.class));
+        assertIntrinsic(mtr4, ldc(mtr4), MethodType.methodType(int.class, int.class));
+
+        MethodTypeDesc mtr5 = MethodTypeDesc.ofDescriptor("(Ljava/lang/String;)Ljava/lang/String;");
+        MethodTypeDesc mtr6 = MethodTypeDesc.of(ConstantDescs.CR_String, ConstantDescs.CR_String);
+        assertIntrinsic(mtr5, ldc(mtr5), MethodType.methodType(String.class, String.class));
+        assertIntrinsic(mtr6, ldc(mtr6), MethodType.methodType(String.class, String.class));
+
+        MethodTypeDesc mtr7 = MethodTypeDesc.ofDescriptor("([I)[Ljava/lang/String;");
+        assertIntrinsic(mtr7, ldc(mtr7), MethodType.methodType(String[].class, int[].class));
+    }
+
+    public void negLdcMethodType() {
+        MethodTypeDesc mtr1 = MethodTypeDesc.of(ClassDesc.of(NONEXISTENT_CLASS));
+        assertIntrinsicFail(mtr1, () -> ldc(mtr1), NoClassDefFoundError.class);
+
+        MethodTypeDesc mtr2 = MethodTypeDesc.of(ClassDesc.of(INACCESSIBLE_CLASS));
+        assertIntrinsicFail(mtr2, () -> ldc(mtr2), IllegalAccessError.class);
+    }
+
+    public void testLdcEnum() throws ReflectiveOperationException {
+        EnumDesc<TestEnum> enr1 = EnumDesc.of(CR_TESTENUM, "A");
+        assertIntrinsic(enr1, ldc(enr1), TestEnum.A);
+
+        EnumDesc<TestEnum> enr2 = EnumDesc.of(CR_TESTENUM, "B");
+        assertIntrinsic(enr2, ldc(enr2), TestEnum.B);
+    }
+
+    public void negLdcEnum() {
+        EnumDesc<TestEnum> enr1 = EnumDesc.of(CR_TESTENUM, "C");
+        assertIntrinsicFail(enr1, () -> ldc(enr1), IllegalArgumentException.class);
+
+        EnumDesc<TestEnum> enr2 = EnumDesc.of(ClassDesc.of(NONEXISTENT_CLASS), "A");
+        assertIntrinsicFail(enr2, () -> ldc(enr2), NoClassDefFoundError.class);
+
+        EnumDesc<TestEnum> enr3 = EnumDesc.of(CR_THIS, "A");
+        assertIntrinsicFail(enr3, () -> ldc(enr3), IllegalArgumentException.class);
+
+        EnumDesc<TestEnum> enr4 = EnumDesc.of(ClassDesc.of(INACCESSIBLE_CLASS), "A");
+        assertIntrinsicFail(enr4, () -> ldc(enr4), IllegalAccessError.class);
+    }
+
+    public void testLdcSelfConstants() throws ReflectiveOperationException {
+        assertIntrinsic("Foo", ldc("Foo"), "Foo");
+        assertIntrinsic(1, ldc(1), 1);
+        assertIntrinsic(1L, ldc(1L), 1L);
+        assertIntrinsic(2.0f, ldc(2.0f), 2.0f);
+        assertIntrinsic(3.0d, ldc(3.0d), 3.0d);
+    }
+
+    public void testLdcMethodHandleFromInner() throws Throwable {
+        TestClass.ldcMethodHandleFromInner();
+        TestClass.negLdcMethodHandleFromInner();
+        TestInterface.testLdcMethodHandleFromIntf(new TestInterface(){});
+    }
+
+    public void testLdcMethodHandle() throws Throwable {
+        TestClass instance = (TestClass) ldc(MHR_TESTCLASS_CTOR).invokeExact();
+
+        assertEquals(5, (int) ldc(MHR_TESTCLASS_SM).invokeExact(5));
+        assertEquals(0, (int) ldc(MHR_TESTINTF_SM).invokeExact(5));
+
+        assertEquals(5, (int) ldc(MHR_TESTCLASS_M).invokeExact(instance, 5));
+        assertEquals(5, (int) ldc(MHR_TESTINTF_M).invoke(instance, 5));
+
+        ldc(MHR_TESTCLASS_SF_SETTER).invokeExact(8);
+        assertEquals(TestClass.sf, 8);
+        assertEquals(8, (int) ldc(MHR_TESTCLASS_SF_GETTER).invokeExact());
+
+        assertEquals(3, (int) ldc(MHR_TESTINTF_SF_GETTER).invokeExact());
+
+        ldc(MHR_TESTCLASS_F_SETTER).invokeExact(instance, 9); assertEquals(instance.f, 9);
+        assertEquals(9, (int) ldc(MHR_TESTCLASS_F_GETTER).invokeExact(instance));
+    }
+
+    public void negLdcMethodHandle() {
+        // Accessible classes, inaccessible methods
+        assertIntrinsicFail(MHR_TESTCLASS_PM_SPECIAL, () -> ldc(MHR_TESTCLASS_PM_SPECIAL), IllegalAccessError.class);
+        assertIntrinsicFail(MHR_TESTINTF_PM_SPECIAL, () -> ldc(MHR_TESTINTF_PM_SPECIAL), IllegalAccessError.class);
+        assertIntrinsicFail(MHR_TESTCLASS_PSM, () -> ldc(MHR_TESTCLASS_PSM), IllegalAccessError.class);
+        assertIntrinsicFail(MHR_TESTINTF_PSM, () -> ldc(MHR_TESTINTF_PSM), IllegalAccessError.class);
+
+        // Accessible class and method, but illegal super access
+        assertIntrinsicFail(MHR_TESTSUPER_M_SPECIAL, () -> ldc(MHR_TESTSUPER_M_SPECIAL), IllegalAccessError.class);
+        assertIntrinsicFail(MHR_TESTINTF_M_SPECIAL, () -> ldc(MHR_TESTINTF_M_SPECIAL), IncompatibleClassChangeError.class);
+
+        // Method kind mismatches -- intf, virtual, static
+        MethodHandleDesc intfMethodAsVirtual = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_TESTINTF, "m", MethodTypeDesc.ofDescriptor("(I)I"));
+        MethodHandleDesc intfMethodAsStatic = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_TESTINTF, "m", MethodTypeDesc.ofDescriptor("(I)I"));
+        MethodHandleDesc virtualMethodAsIntf = MethodHandleDesc.of(MethodHandleDesc.Kind.INTERFACE_VIRTUAL, CR_TESTCLASS, "m", MethodTypeDesc.ofDescriptor("(I)I"));
+        MethodHandleDesc virtualMethodAsStatic = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_TESTCLASS, "m", MethodTypeDesc.ofDescriptor("(I)I"));
+        MethodHandleDesc staticMethodAsVirtual = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_TESTCLASS, "sm", MethodTypeDesc.ofDescriptor("(I)I"));
+        MethodHandleDesc staticMethodAsIntf = MethodHandleDesc.of(MethodHandleDesc.Kind.INTERFACE_VIRTUAL, CR_TESTINTF, "sm", MethodTypeDesc.ofDescriptor("(I)I"));
+
+        assertIntrinsicFail(intfMethodAsVirtual, () -> ldc(intfMethodAsVirtual), IncompatibleClassChangeError.class);
+        assertIntrinsicFail(intfMethodAsStatic, () -> ldc(intfMethodAsStatic), IncompatibleClassChangeError.class);
+        assertIntrinsicFail(virtualMethodAsIntf, () -> ldc(virtualMethodAsIntf), IncompatibleClassChangeError.class);
+        assertIntrinsicFail(virtualMethodAsStatic, () -> ldc(virtualMethodAsStatic), IncompatibleClassChangeError.class);
+        assertIntrinsicFail(staticMethodAsVirtual, () -> ldc(staticMethodAsVirtual), IncompatibleClassChangeError.class);
+        assertIntrinsicFail(staticMethodAsIntf, () -> ldc(staticMethodAsIntf), IncompatibleClassChangeError.class);
+
+        // Field kind mismatch -- instance/static
+        MethodHandleDesc staticFieldAsInstance = MethodHandleDesc.ofField(MethodHandleDesc.Kind.GETTER, CR_TESTCLASS, "sf", ConstantDescs.CR_int);
+        MethodHandleDesc instanceFieldAsStatic = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC_GETTER, CR_TESTCLASS, "f", ConstantDescs.CR_int);
+
+        assertIntrinsicFail(staticFieldAsInstance, () -> ldc(staticFieldAsInstance), IncompatibleClassChangeError.class);
+        assertIntrinsicFail(instanceFieldAsStatic, () -> ldc(instanceFieldAsStatic), IncompatibleClassChangeError.class);
+
+        // Setter for final field
+        MethodHandleDesc finalStaticSetter = MethodHandleDesc.ofField(MethodHandleDesc.Kind.STATIC_SETTER, CR_TESTCLASS, "sff", ConstantDescs.CR_int);
+        MethodHandleDesc finalSetter = MethodHandleDesc.ofField(MethodHandleDesc.Kind.SETTER, CR_TESTCLASS, "ff", ConstantDescs.CR_int);
+
+        assertIntrinsicFail(finalStaticSetter, () -> ldc(finalStaticSetter), IllegalAccessError.class);
+        assertIntrinsicFail(finalSetter, () -> ldc(finalSetter), IllegalAccessError.class);
+
+        // Nonexistent owner
+        MethodHandleDesc r1 = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ClassDesc.of(NONEXISTENT_CLASS), "m", "()V");
+        assertIntrinsicFail(r1, () -> ldc(r1), NoClassDefFoundError.class);
+
+        // Inaccessible owner
+        MethodHandleDesc r2 = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ClassDesc.of(INACCESSIBLE_CLASS), "m", "()V");
+        assertIntrinsicFail(r2, () -> ldc(r2), IllegalAccessError.class);
+
+        // Nonexistent method, ctor, field
+        MethodHandleDesc r3 = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_TESTCLASS, "nonexistent", "()V");
+        MethodHandleDesc r4 = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_TESTCLASS, "nonexistent", "()V");
+        MethodHandleDesc r5 = MethodHandleDesc.of(MethodHandleDesc.Kind.CONSTRUCTOR, CR_TESTCLASS, "<ignored>", "(I)V");
+        MethodHandleDesc r6 = MethodHandleDesc.ofField(MethodHandleDesc.Kind.GETTER, CR_TESTCLASS, "nonexistent", ConstantDescs.CR_int);
+        MethodHandleDesc r7 = MethodHandleDesc.ofField(MethodHandleDesc.Kind.SETTER, CR_TESTCLASS, "nonexistent", ConstantDescs.CR_int);
+        MethodHandleDesc r8 = MethodHandleDesc.ofField(MethodHandleDesc.Kind.STATIC_GETTER, CR_TESTCLASS, "nonexistent", ConstantDescs.CR_int);
+        MethodHandleDesc r9 = MethodHandleDesc.ofField(MethodHandleDesc.Kind.STATIC_SETTER, CR_TESTCLASS, "nonexistent", ConstantDescs.CR_int);
+
+        assertIntrinsicFail(r3, () -> ldc(r3), NoSuchMethodError.class);
+        assertIntrinsicFail(r4, () -> ldc(r4), NoSuchMethodError.class);
+        assertIntrinsicFail(r5, () -> ldc(r5), NoSuchMethodError.class);
+        assertIntrinsicFail(r6, () -> ldc(r6), NoSuchFieldError.class);
+        assertIntrinsicFail(r7, () -> ldc(r7), NoSuchFieldError.class);
+        assertIntrinsicFail(r8, () -> ldc(r8), NoSuchFieldError.class);
+        assertIntrinsicFail(r9, () -> ldc(r9), NoSuchFieldError.class);
+    }
+
+    public void testLdcDynamicConstants() throws ReflectiveOperationException {
+        assertNull(ldc(ConstantDescs.NULL));
+        assertIntrinsic(ConstantDescs.CR_int, ldc(ConstantDescs.CR_int), int.class);
+        // @@@ VarHandle
+        // @@@ invoke (including multiple deep)
+    }
+
+    public void negLdcDynamicConstants() {
+        // @@@ negative tests for nonexistent/inaccessible bootstrap
+        // @@@ negative tests for bootstrap parameter mismatch
+    }
+
+    private enum TestEnum {
+        A, B;
+    }
+
+    private interface TestInterface {
+        public static final int sf = 3;
+
+        static int sm(int x) { return 0; }
+        default int m(int x) { return 0; }
+        private int pm(int x) { return 1; }
+        private static int psm(int x) { return 2; }
+
+        static void testLdcMethodHandleFromIntf(TestInterface testInterface) throws Throwable {
+            assertEquals(1, ldc(MHR_TESTINTF_PM_SPECIAL).invoke(testInterface, 1));
+            assertEquals(2, ldc(MHR_TESTINTF_PSM).invoke(1));
+        }
+    }
+
+    private static class TestSuperclass {
+        public int m(int x) { return -1; }
+    }
+
+    private static class TestClass extends TestSuperclass implements TestInterface {
+
+        static final int sff = 7;
+        static final int ff = 8;
+
+        static int sf;
+        int f;
+
+        public TestClass()  {}
+
+        public static int sm(int x) { return x; }
+        public int m(int x) { return x; }
+        private static int psm(int x) { return x; }
+        private int pm(int x) { return x; }
+
+        private static void negLdcMethodHandleFromInner() {
+            // When we have nestmates, these will probably start succeeding,
+            // at which point we will need to find new negative tests for super-access.
+            assertIntrinsicFail(MHR_TESTINTF_PM_SPECIAL, () -> ldc(MHR_TESTINTF_PM_SPECIAL), IllegalAccessError.class);
+            assertIntrinsicFail(MHR_TESTINTF_PSM, () -> ldc(MHR_TESTINTF_PSM), IllegalAccessError.class);
+        }
+
+        private static void ldcMethodHandleFromInner() throws Throwable {
+            TestClass instance = (TestClass) ldc(MHR_TESTCLASS_CTOR).invokeExact();
+
+            assertEquals(-1, (int) ldc(MHR_TESTSUPER_M_SPECIAL).invokeExact(instance, 5));
+            assertEquals(0, (int) ldc(MHR_TESTINTF_M_SPECIAL).invokeExact(instance, 5));
+
+            assertEquals(5, (int) ldc(MHR_TESTCLASS_PM_SPECIAL).invokeExact(instance, 5));
+
+            assertEquals(5, (int) ldc(MHR_TESTCLASS_PSM).invokeExact(5));
+        }
+
+    }
+
+    private static int privateStaticMethod(int i) {
+        return i;
+    }
+
+    private int privateMethod(int i) {
+        return i;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/MethodHandleRefTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,325 @@
+/*
+ * 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.
+ */
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandleInfo;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.WrongMethodTypeException;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.ConstantMethodHandleDesc;
+import java.lang.constant.MethodHandleDesc;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.lang.constant.MethodTypeDesc;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Supplier;
+
+import org.testng.annotations.Test;
+
+import static java.lang.constant.MethodHandleDesc.Kind.GETTER;
+import static java.lang.constant.MethodHandleDesc.Kind.SETTER;
+import static java.lang.constant.MethodHandleDesc.Kind.STATIC_GETTER;
+import static java.lang.constant.MethodHandleDesc.Kind.STATIC_SETTER;
+import static java.lang.constant.MethodHandleDesc.Kind.VIRTUAL;
+import static java.lang.constant.ConstantDescs.CR_Integer;
+import static java.lang.constant.ConstantDescs.CR_List;
+import static java.lang.constant.ConstantDescs.CR_Object;
+import static java.lang.constant.ConstantDescs.CR_String;
+import static java.lang.constant.ConstantDescs.CR_int;
+import static java.lang.constant.ConstantDescs.CR_void;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/**
+ * @test
+ * @compile -XDfolding=false MethodHandleRefTest.java
+ * @run testng MethodHandleRefTest
+ * @summary unit tests for java.lang.constant.MethodHandleDesc
+ */
+@Test
+public class MethodHandleRefTest extends SymbolicRefTest {
+    private static ClassDesc thisClass = ClassDesc.of("MethodHandleRefTest");
+    private static ClassDesc testClass = thisClass.inner("TestClass");
+    private static ClassDesc testInterface = thisClass.inner("TestInterface");
+    private static ClassDesc testSuperclass = thisClass.inner("TestSuperclass");
+
+
+    private static void assertMHEquals(MethodHandle a, MethodHandle b) {
+        MethodHandleInfo ia = LOOKUP.revealDirect(a);
+        MethodHandleInfo ib = LOOKUP.revealDirect(b);
+        assertEquals(ia.getDeclaringClass(), ib.getDeclaringClass());
+        assertEquals(ia.getName(), ib.getName());
+        assertEquals(ia.getMethodType(), ib.getMethodType());
+        assertEquals(ia.getReferenceKind(), ib.getReferenceKind());
+    }
+
+    private void testMethodHandleRef(MethodHandleDesc r) throws ReflectiveOperationException {
+        if (r instanceof ConstantMethodHandleDesc) {
+            testSymbolicRef(r);
+
+            ConstantMethodHandleDesc rr = (ConstantMethodHandleDesc) r;
+            assertEquals(r, MethodHandleDesc.of(rr.kind(), rr.owner(), rr.methodName(), r.methodType()));
+        }
+        else {
+            testSymbolicRefForwardOnly(r);
+        }
+    }
+
+    private void testMethodHandleRef(MethodHandleDesc r, MethodHandle mh) throws ReflectiveOperationException {
+        testMethodHandleRef(r);
+
+        assertMHEquals(r.resolveConstantDesc(LOOKUP), mh);
+        assertEquals(mh.describeConstable().orElseThrow(), r);
+
+        // compare extractable properties: refKind, owner, name, type
+        MethodHandleInfo mhi = LOOKUP.revealDirect(mh);
+        ConstantMethodHandleDesc rr = (ConstantMethodHandleDesc) r;
+        assertEquals(mhi.getDeclaringClass().descriptorString(), rr.owner().descriptorString());
+        assertEquals(mhi.getName(), rr.methodName());
+        assertEquals(mhi.getReferenceKind(), rr.kind().refKind);
+        assertEquals(mhi.getMethodType().toMethodDescriptorString(), r.methodType().descriptorString());
+    }
+
+    public void testSimpleMHs() throws ReflectiveOperationException {
+        testMethodHandleRef(MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_String, "isEmpty", "()Z"),
+                            LOOKUP.findVirtual(String.class, "isEmpty", MethodType.fromMethodDescriptorString("()Z", null)));
+        testMethodHandleRef(MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_String, "format", CR_String, CR_String, CR_Object.arrayType()),
+                            LOOKUP.findStatic(String.class, "format", MethodType.methodType(String.class, String.class, Object[].class)));
+        testMethodHandleRef(MethodHandleDesc.of(MethodHandleDesc.Kind.INTERFACE_VIRTUAL, CR_List, "isEmpty", "()Z"),
+                            LOOKUP.findVirtual(List.class, "isEmpty", MethodType.fromMethodDescriptorString("()Z", null)));
+        testMethodHandleRef(MethodHandleDesc.of(MethodHandleDesc.Kind.CONSTRUCTOR, ClassDesc.of("java.util.ArrayList"), "<init>", CR_void),
+                            LOOKUP.findConstructor(ArrayList.class, MethodType.methodType(void.class)));
+        testMethodHandleRef(MethodHandleDesc.ofConstructor(ClassDesc.of("java.util.ArrayList")),
+                            LOOKUP.findConstructor(ArrayList.class, MethodType.methodType(void.class)));
+        // bad constructor non void return type
+        try {
+            MethodHandleDesc.of(MethodHandleDesc.Kind.CONSTRUCTOR, ClassDesc.of("java.util.ArrayList"), "<init>", CR_int);
+            fail("should have failed: non void return type for constructor");
+        } catch (IllegalArgumentException ex) {
+            // good
+        }
+    }
+
+    public void testAsType() throws Throwable {
+        MethodHandleDesc mhr = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ClassDesc.of("java.lang.Integer"), "valueOf",
+                                                   MethodTypeDesc.of(CR_Integer, CR_int));
+        MethodHandleDesc takesInteger = mhr.asType(MethodTypeDesc.of(CR_Integer, CR_Integer));
+        testMethodHandleRef(takesInteger);
+        MethodHandle mh1 = takesInteger.resolveConstantDesc(LOOKUP);
+        assertEquals((Integer) 3, (Integer) mh1.invokeExact((Integer) 3));
+        assertEquals(takesInteger.toString(), "MethodHandleDesc[STATIC/Integer::valueOf(int)Integer].asType(Integer)Integer");
+
+        try {
+            Integer i = (Integer) mh1.invokeExact(3);
+            fail("Expected WMTE");
+        }
+        catch (WrongMethodTypeException ignored) { }
+
+        MethodHandleDesc takesInt = takesInteger.asType(MethodTypeDesc.of(CR_Integer, CR_int));
+        testMethodHandleRef(takesInt);
+        MethodHandle mh2 = takesInt.resolveConstantDesc(LOOKUP);
+        assertEquals((Integer) 3, (Integer) mh2.invokeExact(3));
+
+        try {
+            Integer i = (Integer) mh2.invokeExact((Integer) 3);
+            fail("Expected WMTE");
+        }
+        catch (WrongMethodTypeException ignored) { }
+
+        // @@@ Test short-circuit optimization
+        // @@@ Test varargs adaptation
+        // @@@ Test bad adaptations and assert runtime error on resolution
+        // @@@ Test intrinsification of adapted MH
+    }
+
+    public void testMethodHandleRef() throws Throwable {
+        MethodHandleDesc ctorRef = MethodHandleDesc.of(MethodHandleDesc.Kind.CONSTRUCTOR, testClass, "<ignored!>", CR_void);
+        MethodHandleDesc staticMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, testClass, "sm", "(I)I");
+        MethodHandleDesc staticIMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, testInterface, "sm", "(I)I");
+        MethodHandleDesc instanceMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, testClass, "m", "(I)I");
+        MethodHandleDesc instanceIMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.INTERFACE_VIRTUAL, testInterface, "m", "(I)I");
+        MethodHandleDesc superMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.SPECIAL, testSuperclass, "m", "(I)I");
+        MethodHandleDesc superIMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.SPECIAL, testInterface, "m", "(I)I");
+        MethodHandleDesc privateMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.SPECIAL, testClass, "pm", "(I)I");
+        MethodHandleDesc privateIMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.SPECIAL, testInterface, "pm", "(I)I");
+        MethodHandleDesc privateStaticMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, testClass, "psm", "(I)I");
+        MethodHandleDesc privateStaticIMethodRef = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, testInterface, "psm", "(I)I");
+
+        for (MethodHandleDesc r : List.of(ctorRef, staticMethodRef, staticIMethodRef, instanceMethodRef, instanceIMethodRef))
+            testMethodHandleRef(r);
+
+        TestClass instance = (TestClass) ctorRef.resolveConstantDesc(LOOKUP).invokeExact();
+        TestClass instance2 = (TestClass) ctorRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact();
+        TestInterface instanceI = instance;
+
+        assertTrue(instance != instance2);
+
+        assertEquals(5, (int) staticMethodRef.resolveConstantDesc(LOOKUP).invokeExact(5));
+        assertEquals(5, (int) staticMethodRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(5));
+        assertEquals(0, (int) staticIMethodRef.resolveConstantDesc(LOOKUP).invokeExact(5));
+        assertEquals(0, (int) staticIMethodRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(5));
+
+        assertEquals(5, (int) instanceMethodRef.resolveConstantDesc(LOOKUP).invokeExact(instance, 5));
+        assertEquals(5, (int) instanceMethodRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(instance, 5));
+        assertEquals(5, (int) instanceIMethodRef.resolveConstantDesc(LOOKUP).invokeExact(instanceI, 5));
+        assertEquals(5, (int) instanceIMethodRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(instanceI, 5));
+
+        try { superMethodRef.resolveConstantDesc(LOOKUP); fail(); }
+        catch (IllegalAccessException e) { /* expected */ }
+        assertEquals(-1, (int) superMethodRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(instance, 5));
+
+        try { superIMethodRef.resolveConstantDesc(LOOKUP); fail(); }
+        catch (IllegalAccessException e) { /* expected */ }
+        assertEquals(0, (int) superIMethodRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(instance, 5));
+
+        try { privateMethodRef.resolveConstantDesc(LOOKUP); fail(); }
+        catch (IllegalAccessException e) { /* expected */ }
+        assertEquals(5, (int) privateMethodRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(instance, 5));
+
+        try { privateIMethodRef.resolveConstantDesc(LOOKUP); fail(); }
+        catch (IllegalAccessException e) { /* expected */ }
+        try { privateIMethodRef.resolveConstantDesc(TestClass.LOOKUP); fail(); }
+        catch (IllegalAccessException e) { /* expected */ }
+        assertEquals(0, (int) privateIMethodRef.resolveConstantDesc(TestInterface.LOOKUP).invokeExact(instanceI, 5));
+
+        try { privateStaticMethodRef.resolveConstantDesc(LOOKUP); fail(); }
+        catch (IllegalAccessException e) { /* expected */ }
+        assertEquals(5, (int) privateStaticMethodRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(5));
+
+        try { privateStaticIMethodRef.resolveConstantDesc(LOOKUP); fail(); }
+        catch (IllegalAccessException e) { /* expected */ }
+        try { privateStaticIMethodRef.resolveConstantDesc(TestClass.LOOKUP); fail(); }
+        catch (IllegalAccessException e) { /* expected */ }
+        assertEquals(0, (int) privateStaticIMethodRef.resolveConstantDesc(TestInterface.LOOKUP).invokeExact(5));
+
+        MethodHandleDesc staticSetterRef = MethodHandleDesc.ofField(STATIC_SETTER, testClass, "sf", CR_int);
+        MethodHandleDesc staticGetterRef = MethodHandleDesc.ofField(STATIC_GETTER, testClass, "sf", CR_int);
+        MethodHandleDesc staticGetterIRef = MethodHandleDesc.ofField(STATIC_GETTER, testInterface, "sf", CR_int);
+        MethodHandleDesc setterRef = MethodHandleDesc.ofField(SETTER, testClass, "f", CR_int);
+        MethodHandleDesc getterRef = MethodHandleDesc.ofField(GETTER, testClass, "f", CR_int);
+
+        for (MethodHandleDesc r : List.of(staticSetterRef, staticGetterRef, staticGetterIRef, setterRef, getterRef))
+            testMethodHandleRef(r);
+
+        staticSetterRef.resolveConstantDesc(LOOKUP).invokeExact(6); assertEquals(TestClass.sf, 6);
+        assertEquals(6, (int) staticGetterRef.resolveConstantDesc(LOOKUP).invokeExact());
+        assertEquals(6, (int) staticGetterRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact());
+        staticSetterRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(7); assertEquals(TestClass.sf, 7);
+        assertEquals(7, (int) staticGetterRef.resolveConstantDesc(LOOKUP).invokeExact());
+        assertEquals(7, (int) staticGetterRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact());
+
+        assertEquals(3, (int) staticGetterIRef.resolveConstantDesc(LOOKUP).invokeExact());
+        assertEquals(3, (int) staticGetterIRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact());
+
+        setterRef.resolveConstantDesc(LOOKUP).invokeExact(instance, 6); assertEquals(instance.f, 6);
+        assertEquals(6, (int) getterRef.resolveConstantDesc(LOOKUP).invokeExact(instance));
+        assertEquals(6, (int) getterRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(instance));
+        setterRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(instance, 7); assertEquals(instance.f, 7);
+        assertEquals(7, (int) getterRef.resolveConstantDesc(LOOKUP).invokeExact(instance));
+        assertEquals(7, (int) getterRef.resolveConstantDesc(TestClass.LOOKUP).invokeExact(instance));
+    }
+
+    private void assertBadArgs(Supplier<MethodHandleDesc> supplier, String s) {
+        try {
+            MethodHandleDesc r = supplier.get();
+            fail("Expected failure for " + s);
+        }
+        catch (IllegalArgumentException e) {
+            // succeed
+        }
+    }
+
+    public void testBadFieldMHs() {
+        List<String> badGetterDescs = List.of("()V", "(Ljava/lang/Object;)V", "(I)I", "(Ljava/lang/Object;I)I");
+        List<String> badStaticGetterDescs = List.of("()V", "(Ljava/lang/Object;)I", "(I)I", "(Ljava/lang/Object;I)I");
+        List<String> badSetterDescs = List.of("()V", "(I)V", "(Ljava/lang/Object;)V", "(Ljava/lang/Object;I)I", "(Ljava/lang/Object;II)V");
+        List<String> badStaticSetterDescs = List.of("()V", "(II)V", "()I");
+
+        badGetterDescs.forEach(s -> assertBadArgs(() -> MethodHandleDesc.of(GETTER, thisClass, "x", s), s));
+        badSetterDescs.forEach(s -> assertBadArgs(() -> MethodHandleDesc.of(SETTER, thisClass, "x", s), s));
+        badStaticGetterDescs.forEach(s -> assertBadArgs(() -> MethodHandleDesc.of(STATIC_GETTER, thisClass, "x", s), s));
+        badStaticSetterDescs.forEach(s -> assertBadArgs(() -> MethodHandleDesc.of(STATIC_SETTER, thisClass, "x", s), s));
+    }
+
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testBadOwners() {
+        MethodHandleDesc.of(VIRTUAL, ClassDesc.ofDescriptor("I"), "x", MethodTypeDesc.ofDescriptor("()I"));
+    }
+
+    public void testSymbolicRefsConstants() throws ReflectiveOperationException {
+        int tested = 0;
+        Field[] fields = ConstantDescs.class.getDeclaredFields();
+        for (Field f : fields) {
+            try {
+                if (f.getType().equals(ConstantMethodHandleDesc.class)
+                    && ((f.getModifiers() & Modifier.STATIC) != 0)
+                    && ((f.getModifiers() & Modifier.PUBLIC) != 0)) {
+                    MethodHandleDesc r = (MethodHandleDesc) f.get(null);
+                    MethodHandle m = r.resolveConstantDesc(MethodHandles.lookup());
+                    testMethodHandleRef(r, m);
+                    ++tested;
+                }
+            }
+            catch (Throwable e) {
+                fail("Error testing field " + f.getName(), e);
+            }
+        }
+
+        assertTrue(tested > 0);
+    }
+
+    private interface TestInterface {
+        public static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+        public static final int sf = 3;
+
+        static int sm(int  x) { return 0; }
+        default int m(int x) { return 0; }
+        private int pm(int x) { return 0; }
+        private static int psm(int x) { return 0; }
+    }
+
+    private static class TestSuperclass {
+        public int m(int x) { return -1; }
+    }
+
+    private static class TestClass extends TestSuperclass implements TestInterface {
+        public static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+        static int sf;
+        int f;
+
+        public TestClass()  {}
+
+        public static int sm(int x) { return x; }
+        public int m(int x) { return x; }
+        private static int psm(int x) { return x; }
+        private int pm(int x) { return x; }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/MethodTypeRefTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+import java.lang.invoke.MethodType;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.MethodTypeDesc;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
+import org.testng.annotations.Test;
+
+import static java.lang.constant.ConstantDescs.CR_int;
+import static java.lang.constant.ConstantDescs.CR_void;
+import static java.util.stream.Collectors.joining;
+import static java.util.stream.Collectors.toList;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+/**
+ * @test
+ * @compile -XDfolding=false MethodTypeRefTest.java
+ * @run testng MethodTypeRefTest
+ * @summary unit tests for java.lang.constant.MethodTypeRef
+ */
+@Test
+public class MethodTypeRefTest extends SymbolicRefTest {
+
+    private void testMethodTypeRef(MethodTypeDesc r) throws ReflectiveOperationException {
+        testSymbolicRef(r);
+
+        // Tests accessors (rType, pType, pCount, pList, pArray, descriptorString),
+        // factories (ofDescriptor, of), equals
+        assertEquals(r, MethodTypeDesc.ofDescriptor(r.descriptorString()));
+        assertEquals(r, MethodTypeDesc.of(r.returnType(), r.parameterArray()));
+        assertEquals(r, MethodTypeDesc.of(r.returnType(), r.parameterList().toArray(new ClassDesc[0])));
+        assertEquals(r, MethodTypeDesc.of(r.returnType(), r.parameterList().stream().toArray(ClassDesc[]::new)));
+        assertEquals(r, MethodTypeDesc.of(r.returnType(), IntStream.range(0, r.parameterCount())
+                                                                   .mapToObj(r::parameterType)
+                                                                   .toArray(ClassDesc[]::new)));
+    }
+
+    private void testMethodTypeRef(MethodTypeDesc r, MethodType mt) throws ReflectiveOperationException {
+        testMethodTypeRef(r);
+
+        assertEquals(r.resolveConstantDesc(LOOKUP), mt);
+        assertEquals(mt.describeConstable().get(), r);
+
+        assertEquals(r.descriptorString(), mt.toMethodDescriptorString());
+        assertEquals(r.parameterCount(), mt.parameterCount());
+        assertEquals(r.parameterList(), mt.parameterList().stream().map(SymbolicRefTest::classToRef).collect(toList()));
+        assertEquals(r.parameterArray(), Stream.of(mt.parameterArray()).map(SymbolicRefTest::classToRef).toArray(ClassDesc[]::new));
+        for (int i=0; i<r.parameterCount(); i++)
+            assertEquals(r.parameterType(i), classToRef(mt.parameterType(i)));
+        assertEquals(r.returnType(), classToRef(mt.returnType()));
+    }
+
+    private void assertMethodType(ClassDesc returnType,
+                                  ClassDesc... paramTypes) throws ReflectiveOperationException {
+        String descriptor = Stream.of(paramTypes).map(ClassDesc::descriptorString).collect(joining("", "(", ")"))
+                            + returnType.descriptorString();
+        MethodTypeDesc mtRef = MethodTypeDesc.of(returnType, paramTypes);
+
+        // MTRef accessors
+        assertEquals(descriptor, mtRef.descriptorString());
+        assertEquals(returnType, mtRef.returnType());
+        assertEquals(paramTypes, mtRef.parameterArray());
+        assertEquals(Arrays.asList(paramTypes), mtRef.parameterList());
+        assertEquals(paramTypes.length, mtRef.parameterCount());
+        for (int i=0; i<paramTypes.length; i++)
+            assertEquals(paramTypes[i], mtRef.parameterType(i));
+
+        // Consistency between MT and MTRef
+        MethodType mt = MethodType.fromMethodDescriptorString(descriptor, null);
+        testMethodTypeRef(mtRef, mt);
+
+        // changeReturnType
+        for (String r : returnDescs) {
+            ClassDesc rc = ClassDesc.ofDescriptor(r);
+            MethodTypeDesc newRef = mtRef.changeReturnType(rc);
+            assertEquals(newRef, MethodTypeDesc.of(rc, paramTypes));
+            testMethodTypeRef(newRef, mt.changeReturnType(rc.resolveConstantDesc(LOOKUP)));
+        }
+
+        // changeParamType
+        for (int i=0; i<paramTypes.length; i++) {
+            for (String p : paramDescs) {
+                ClassDesc pc = ClassDesc.ofDescriptor(p);
+                ClassDesc[] ps = paramTypes.clone();
+                ps[i] = pc;
+                MethodTypeDesc newRef = mtRef.changeParameterType(i, pc);
+                assertEquals(newRef, MethodTypeDesc.of(returnType, ps));
+                testMethodTypeRef(newRef, mt.changeParameterType(i, pc.resolveConstantDesc(LOOKUP)));
+            }
+        }
+
+        // dropParamType
+        for (int i=0; i<paramTypes.length; i++) {
+            int k = i;
+            ClassDesc[] ps = IntStream.range(0, paramTypes.length)
+                                      .filter(j -> j != k)
+                                      .mapToObj(j -> paramTypes[j])
+                                      .toArray(ClassDesc[]::new);
+            MethodTypeDesc newRef = mtRef.dropParameterTypes(i, i + 1);
+            assertEquals(newRef, MethodTypeDesc.of(returnType, ps));
+            testMethodTypeRef(newRef, mt.dropParameterTypes(i, i+1));
+        }
+
+        badDropParametersTypes(CR_void, paramDescs);
+
+        // addParam
+        for (int i=0; i <= paramTypes.length; i++) {
+            for (ClassDesc p : paramTypes) {
+                int k = i;
+                ClassDesc[] ps = IntStream.range(0, paramTypes.length + 1)
+                                          .mapToObj(j -> (j < k) ? paramTypes[j] : (j == k) ? p : paramTypes[j-1])
+                                          .toArray(ClassDesc[]::new);
+                MethodTypeDesc newRef = mtRef.insertParameterTypes(i, p);
+                assertEquals(newRef, MethodTypeDesc.of(returnType, ps));
+                testMethodTypeRef(newRef, mt.insertParameterTypes(i, p.resolveConstantDesc(LOOKUP)));
+            }
+        }
+
+        badInsertParametersTypes(CR_void, paramDescs);
+    }
+
+    private void badInsertParametersTypes(ClassDesc returnType, String... paramDescTypes) {
+        ClassDesc[] paramTypes =
+                IntStream.rangeClosed(0, paramDescTypes.length - 1)
+                        .mapToObj(i -> ClassDesc.ofDescriptor(paramDescTypes[i])).toArray(ClassDesc[]::new);
+        MethodTypeDesc mtRef = MethodTypeDesc.of(returnType, paramTypes);
+        try {
+            MethodTypeDesc newRef = mtRef.insertParameterTypes(-1, paramTypes);
+            fail("pos < 0 should have failed");
+        } catch (IndexOutOfBoundsException ex) {
+            // good
+        }
+
+        try {
+            MethodTypeDesc newRef = mtRef.insertParameterTypes(paramTypes.length + 1, paramTypes);
+            fail("pos > current arguments length should have failed");
+        } catch (IndexOutOfBoundsException ex) {
+            // good
+        }
+    }
+
+    private void badDropParametersTypes(ClassDesc returnType, String... paramDescTypes) {
+        ClassDesc[] paramTypes =
+                IntStream.rangeClosed(0, paramDescTypes.length - 1)
+                        .mapToObj(i -> ClassDesc.ofDescriptor(paramDescTypes[i])).toArray(ClassDesc[]::new);
+        MethodTypeDesc mtRef = MethodTypeDesc.of(returnType, paramTypes);
+        try {
+            MethodTypeDesc newRef = mtRef.dropParameterTypes(-1, 0);
+            fail("start index < 0 should have failed");
+        } catch (IndexOutOfBoundsException ex) {
+            // good
+        }
+
+        try {
+            MethodTypeDesc newRef = mtRef.dropParameterTypes(paramTypes.length, 0);
+            fail("start index = arguments.length should have failed");
+        } catch (IndexOutOfBoundsException ex) {
+            // good
+        }
+
+        try {
+            MethodTypeDesc newRef = mtRef.dropParameterTypes(paramTypes.length + 1, 0);
+            fail("start index > arguments.length should have failed");
+        } catch (IndexOutOfBoundsException ex) {
+            // good
+        }
+
+        try {
+            MethodTypeDesc newRef = mtRef.dropParameterTypes(0, paramTypes.length + 1);
+            fail("end index > arguments.length should have failed");
+        } catch (IndexOutOfBoundsException ex) {
+            // good
+        }
+
+        try {
+            MethodTypeDesc newRef = mtRef.dropParameterTypes(1, 0);
+            fail("start index > end index should have failed");
+        } catch (IllegalArgumentException ex) {
+            // good
+        }
+    }
+
+    public void testMethodTypeRef() throws ReflectiveOperationException {
+        for (String r : returnDescs) {
+            assertMethodType(ClassDesc.ofDescriptor(r));
+            for (String p1 : paramDescs) {
+                assertMethodType(ClassDesc.ofDescriptor(r), ClassDesc.ofDescriptor(p1));
+                for (String p2 : paramDescs) {
+                    assertMethodType(ClassDesc.ofDescriptor(r), ClassDesc.ofDescriptor(p1), ClassDesc.ofDescriptor(p2));
+                }
+            }
+        }
+    }
+
+    public void testBadMethodTypeRefs() {
+        List<String> badDescriptors = List.of("()II", "()I;", "(I;)", "(I)", "()L", "(V)V",
+                                              "(java.lang.String)V", "()[]", "(Ljava/lang/String)V",
+                                              "(Ljava.lang.String;)V", "(java/lang/String)V");
+
+        for (String d : badDescriptors) {
+            try {
+                MethodTypeDesc r = MethodTypeDesc.ofDescriptor(d);
+                fail(d);
+            }
+            catch (IllegalArgumentException e) {
+                // good
+            }
+        }
+
+        // try with void arguments, this will stress another code path in particular
+        // ConstantMethodTypeDesc::init
+        try {
+            MethodTypeDesc r = MethodTypeDesc.of(CR_int, CR_void);
+            fail("can't reach here");
+        }
+        catch (IllegalArgumentException e) {
+            // good
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/SymbolicRefTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+
+import java.lang.Class;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.Constable;
+import java.lang.constant.ConstantDesc;
+import java.lang.constant.ConstantDescs;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
+
+import static org.testng.Assert.assertEquals;
+
+/**
+ * Base class for XxxRef tests
+ */
+public abstract class SymbolicRefTest {
+
+    public static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+    static List<String> someRefs = List.of("Ljava/lang/String;", "Ljava/util/List;");
+    static String[] basicDescs = Stream.concat(Stream.of(Primitives.values())
+                                                     .filter(p -> p != Primitives.VOID)
+                                                     .map(p -> p.descriptor),
+                                               someRefs.stream())
+                                       .toArray(String[]::new);
+    static String[] paramDescs = Stream.of(basicDescs)
+                                       .flatMap(d -> Stream.of(d, "[" + d))
+                                       .toArray(String[]::new);
+    static String[] returnDescs = Stream.concat(Stream.of(paramDescs), Stream.of("V")).toArray(String[]::new);
+
+    enum Primitives {
+        INT("I", "int", int.class, int[].class, ConstantDescs.CR_int),
+        LONG("J", "long", long.class, long[].class, ConstantDescs.CR_long),
+        SHORT("S", "short", short.class, short[].class, ConstantDescs.CR_short),
+        BYTE("B", "byte", byte.class, byte[].class, ConstantDescs.CR_byte),
+        CHAR("C", "char", char.class, char[].class, ConstantDescs.CR_char),
+        FLOAT("F", "float", float.class, float[].class, ConstantDescs.CR_float),
+        DOUBLE("D", "double", double.class, double[].class, ConstantDescs.CR_double),
+        BOOLEAN("Z", "boolean", boolean.class, boolean[].class, ConstantDescs.CR_boolean),
+        VOID("V", "void", void.class, null, ConstantDescs.CR_void);
+
+        public final String descriptor;
+        public final String name;
+        public final Class<?> clazz;
+        public final Class<?> arrayClass;
+        public final ClassDesc classRef;
+
+        Primitives(String descriptor, String name, Class<?> clazz, Class<?> arrayClass, ClassDesc ref) {
+            this.descriptor = descriptor;
+            this.name = name;
+            this.clazz = clazz;
+            this.arrayClass = arrayClass;
+            classRef = ref;
+        }
+    }
+
+    static String classToDescriptor(Class<?> clazz) {
+        return MethodType.methodType(clazz).toMethodDescriptorString().substring(2);
+    }
+
+    static ClassDesc classToRef(Class<?> c) {
+        return ClassDesc.ofDescriptor(c.descriptorString());
+    }
+
+    static<T> void testSymbolicRef(ConstantDesc<T> ref) throws ReflectiveOperationException {
+        testSymbolicRef(ref, false);
+    }
+
+    static<T> void testSymbolicRefForwardOnly(ConstantDesc<T> ref) throws ReflectiveOperationException {
+        testSymbolicRef(ref, true);
+    }
+
+    private static<T> void testSymbolicRef(ConstantDesc<T> ref, boolean forwardOnly) throws ReflectiveOperationException {
+        if (!forwardOnly) {
+            // Round trip sym -> resolve -> toSymbolicRef
+            ConstantDesc<? super ConstantDesc<T>> s = ((Constable<ConstantDesc<T>>) ref.resolveConstantDesc(LOOKUP)).describeConstable().orElseThrow();
+            assertEquals(ref, s);
+        }
+
+        // Round trip sym -> quoted sym -> resolve
+        Optional<ConstantDesc<ConstantDesc<T>>> opt = (Optional<ConstantDesc<ConstantDesc<T>>>) ((Constable) ref).describeConstable();
+        ConstantDesc<T> sr = opt.orElseThrow().resolveConstantDesc(LOOKUP);
+        assertEquals(sr, ref);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/constant/TypeDescriptorTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -0,0 +1,87 @@
+/*
+ * 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.
+ */
+
+import java.lang.invoke.FieldTypeDescriptor;
+import java.lang.constant.ClassDesc;
+
+import org.testng.annotations.Test;
+
+import static java.lang.constant.ConstantDescs.*;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNull;
+import static org.testng.Assert.assertTrue;
+
+/**
+ * @test
+ * @compile -XDfolding=false TypeDescriptorTest.java
+ * @run testng TypeDescriptorTest
+ * @summary unit tests for implementations of java.lang.invoke.TypeDescriptor
+ */
+@Test
+public class TypeDescriptorTest {
+    private<F extends FieldTypeDescriptor<F>> void testArray(F f, boolean isArray, F component, F array) {
+        if (isArray) {
+            assertTrue(f.isArray());
+            assertEquals(f.arrayType(), array);
+            assertEquals(f.componentType(), component);
+        }
+        else {
+            assertFalse(f.isArray());
+            assertEquals(f.arrayType(), array);
+            assertNull(f.componentType());
+        }
+    }
+
+    public void testClass() {
+        testArray(int.class, false, null, int[].class);
+        testArray(int[].class, true, int.class, int[][].class);
+        testArray(int[][].class, true, int[].class, int[][][].class);
+        testArray(String.class, false, null, String[].class);
+        testArray(String[].class, true, String.class, String[][].class);
+        testArray(String[][].class, true, String[].class, String[][][].class);
+
+        assertTrue(int.class.isPrimitive());
+        assertFalse(int[].class.isPrimitive());
+        assertFalse(String.class.isPrimitive());
+        assertFalse(String[].class.isPrimitive());
+    }
+
+    public void testClassDesc() {
+
+        testArray(CR_int, false, null, CR_int.arrayType());
+        testArray(CR_int.arrayType(), true, CR_int, CR_int.arrayType(2));
+        testArray(CR_int.arrayType(2), true, CR_int.arrayType(), CR_int.arrayType(3));
+        testArray(CR_String, false, null, CR_String.arrayType());
+        testArray(CR_String.arrayType(), true, CR_String, CR_String.arrayType(2));
+        testArray(CR_String.arrayType(2), true, CR_String.arrayType(), CR_String.arrayType(3));
+
+        assertTrue(CR_int.isPrimitive());
+        assertFalse(CR_int.arrayType().isPrimitive());
+        assertFalse(CR_String.isPrimitive());
+        assertFalse(CR_String.arrayType().isPrimitive());
+    }
+
+}
--- a/test/jdk/java/lang/invoke/ConstantRefBootstrapsTest.java	Sat Jun 02 20:13:08 2018 -0700
+++ b/test/jdk/java/lang/invoke/ConstantRefBootstrapsTest.java	Mon Jun 04 14:59:22 2018 -0700
@@ -25,11 +25,11 @@
 
 import java.lang.invoke.Intrinsics;
 import java.lang.invoke.VarHandle;
-import java.lang.invoke.constant.ClassDesc;
-import java.lang.invoke.constant.ConstantDescs;
-import java.lang.invoke.constant.ConstantMethodHandleDesc;
-import java.lang.invoke.constant.DynamicConstantDesc;
-import java.lang.invoke.constant.MethodHandleDesc;
+import java.lang.constant.ClassDesc;
+import java.lang.constant.ConstantDescs;
+import java.lang.constant.ConstantMethodHandleDesc;
+import java.lang.constant.DynamicConstantDesc;
+import java.lang.constant.MethodHandleDesc;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -93,7 +93,7 @@
     public void testEnumConstant() {
         MethodHandleDesc.Kind k = Intrinsics.ldc(DynamicConstantDesc.of(
                 BSM_ENUM_CONSTANT, "STATIC",
-                ClassDesc.of("java.lang.invoke.constant.MethodHandleRef$Kind")));
+                ClassDesc.of("java.lang.constant.MethodHandleRef$Kind")));
         assertEquals(k, MethodHandleDesc.Kind.STATIC);
     }
 
--- a/test/jdk/java/lang/invoke/constant/ClassRefTest.java	Sat Jun 02 20:13:08 2018 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,268 +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.
- */
-
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.constant.ClassDesc;
-import java.lang.invoke.constant.ConstantDescs;
-import java.lang.invoke.constant.ConstantUtils;
-import java.lang.reflect.Array;
-import java.lang.reflect.Field;
-import java.lang.reflect.Modifier;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-
-import org.testng.annotations.Test;
-
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertNotEquals;
-import static org.testng.Assert.assertNull;
-import static org.testng.Assert.assertTrue;
-import static org.testng.Assert.fail;
-
-/**
- * @test
- * @compile -XDfolding=false ClassRefTest.java
- * @run testng ClassRefTest
- * @summary unit tests for java.lang.invoke.constant.ClassDesc
- */
-@Test
-public class ClassRefTest extends SymbolicRefTest {
-
-    private void testClassRef(ClassDesc r) throws ReflectiveOperationException {
-        testSymbolicRef(r);
-
-        // Test descriptor accessor, factory, equals
-        assertEquals(r, ClassDesc.ofDescriptor(r.descriptorString()));
-
-        if (!r.descriptorString().equals("V")) {
-            assertEquals(r, r.arrayType().componentType());
-            // Commutativity: array -> resolve -> componentType -> toSymbolic
-            assertEquals(r, r.arrayType().resolveConstantDesc(LOOKUP).getComponentType().describeConstable().orElseThrow());
-            // Commutativity: resolve -> array -> toSymbolic -> component type
-            assertEquals(r, Array.newInstance(r.resolveConstantDesc(LOOKUP), 0).getClass().describeConstable().orElseThrow().componentType());
-        }
-
-        if (r.isArray()) {
-            assertEquals(r, r.componentType().arrayType());
-            assertEquals(r, r.resolveConstantDesc(LOOKUP).getComponentType().describeConstable().orElseThrow().arrayType());
-            assertEquals(r, Array.newInstance(r.componentType().resolveConstantDesc(LOOKUP), 0).getClass().describeConstable().orElseThrow());
-        }
-    }
-
-    private void testClassRef(ClassDesc r, Class<?> c) throws ReflectiveOperationException {
-        testClassRef(r);
-
-        assertEquals(r.resolveConstantDesc(LOOKUP), c);
-        assertEquals(c.describeConstable().orElseThrow(), r);
-        assertEquals(ClassDesc.ofDescriptor(c.descriptorString()), r);
-    }
-
-    public void testSymbolicRefsConstants() throws ReflectiveOperationException {
-        int tested = 0;
-        Field[] fields = ConstantDescs.class.getDeclaredFields();
-        for (Field f : fields) {
-            try {
-                if (f.getType().equals(ClassDesc.class)
-                    && ((f.getModifiers() & Modifier.STATIC) != 0)
-                    && ((f.getModifiers() & Modifier.PUBLIC) != 0)) {
-                    ClassDesc cr = (ClassDesc) f.get(null);
-                    Class c = cr.resolveConstantDesc(MethodHandles.lookup());
-                    testClassRef(cr, c);
-                    ++tested;
-                }
-            }
-            catch (Throwable e) {
-                System.out.println(e.getMessage());
-                fail("Error testing field " + f.getName(), e);
-            }
-        }
-
-        assertTrue(tested > 0);
-    }
-
-    public void testPrimitiveClassRef() throws ReflectiveOperationException {
-        for (Primitives p : Primitives.values()) {
-            List<ClassDesc> refs = List.of(ClassDesc.ofDescriptor(p.descriptor),
-                                           p.classRef,
-                                           (ClassDesc) p.clazz.describeConstable().orElseThrow());
-            for (ClassDesc c : refs) {
-                testClassRef(c, p.clazz);
-                assertTrue(c.isPrimitive());
-                assertEquals(p.descriptor, c.descriptorString());
-                assertEquals(p.name, c.displayName());
-                refs.forEach(cc -> assertEquals(c, cc));
-                if (p != Primitives.VOID) {
-                    testClassRef(c.arrayType(), p.arrayClass);
-                    assertEquals(c, ((ClassDesc) p.arrayClass.describeConstable().orElseThrow()).componentType());
-                    assertEquals(c, p.classRef.arrayType().componentType());
-                }
-            }
-
-            for (Primitives other : Primitives.values()) {
-                ClassDesc otherDescr = ClassDesc.ofDescriptor(other.descriptor);
-                if (p != other)
-                    refs.forEach(c -> assertNotEquals(c, otherDescr));
-                else
-                    refs.forEach(c -> assertEquals(c, otherDescr));
-            }
-        }
-    }
-
-    public void testSimpleClassRef() throws ReflectiveOperationException {
-
-        List<ClassDesc> stringClassRefs = Arrays.asList(ClassDesc.ofDescriptor("Ljava/lang/String;"),
-                                                        ClassDesc.of("java.lang", "String"),
-                                                        ClassDesc.of("java.lang.String"),
-                                                        ClassDesc.of("java.lang.String").arrayType().componentType(),
-                                                        String.class.describeConstable().orElseThrow());
-        for (ClassDesc r : stringClassRefs) {
-            testClassRef(r, String.class);
-            assertFalse(r.isPrimitive());
-            assertEquals("Ljava/lang/String;", r.descriptorString());
-            assertEquals("String", r.displayName());
-            assertEquals(r.arrayType().resolveConstantDesc(LOOKUP), String[].class);
-            stringClassRefs.forEach(rr -> assertEquals(r, rr));
-        }
-
-        testClassRef(ClassDesc.of("java.lang.String").arrayType(), String[].class);
-        testClassRef(ClassDesc.of("java.util.Map").inner("Entry"), Map.Entry.class);
-
-        ClassDesc thisClassRef = ClassDesc.ofDescriptor("LClassRefTest;");
-        assertEquals(thisClassRef, ClassDesc.of("", "ClassRefTest"));
-        assertEquals(thisClassRef, ClassDesc.of("ClassRefTest"));
-        assertEquals(thisClassRef.displayName(), "ClassRefTest");
-        testClassRef(thisClassRef, ClassRefTest.class);
-    }
-
-    private void testBadPackageName(ClassDesc cr) {
-        try {
-            cr.packageName();
-            fail("");
-        } catch (IllegalStateException e) {
-            // good
-        }
-    }
-
-    public void testPackageName() {
-        assertEquals("com.foo", ClassDesc.of("com.foo.Bar").packageName());
-        assertEquals("com.foo", ClassDesc.of("com.foo.Bar").inner("Baz").packageName());
-        assertEquals("", ClassDesc.of("Bar").packageName());
-        assertEquals("", ClassDesc.of("Bar").inner("Baz").packageName());
-
-        testBadPackageName(ConstantDescs.CR_int);
-        testBadPackageName(ConstantDescs.CR_int.arrayType());
-        testBadPackageName(ConstantDescs.CR_String.arrayType());
-        testBadPackageName(ClassDesc.of("Bar").arrayType());
-    }
-
-    private void testBadArrayRank(ClassDesc cr) {
-        try {
-            cr.arrayType(-1);
-            fail("");
-        } catch (IllegalArgumentException e) {
-            // good
-        }
-    }
-
-    public void testArrayClassRef() throws ReflectiveOperationException {
-        for (String d : basicDescs) {
-            ClassDesc a0 = ClassDesc.ofDescriptor(d);
-            ClassDesc a1 = a0.arrayType();
-            ClassDesc a2 = a1.arrayType();
-
-            testClassRef(a0);
-            testClassRef(a1);