changeset 50929:a5ca4f50cb3b condy-folding

manual merge with jep-334
author vromero
date Sat, 02 Jun 2018 20:13:08 -0700
parents 8702994c0314 05169a7b9350
children 9b942e8bd2ca
files src/java.base/share/classes/java/lang/Class.java src/java.base/share/classes/java/lang/Enum.java src/java.base/share/classes/java/lang/invoke/VarHandle.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 test/jdk/java/lang/invoke/constant/ClassRefTest.java test/jdk/java/lang/invoke/constant/IndyRefTest.java test/jdk/java/lang/invoke/constant/MethodHandleRefTest.java
diffstat 24 files changed, 227 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/Class.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Class.java	Sat Jun 02 20:13:08 2018 -0700
@@ -3864,6 +3864,7 @@
      * will have identical descriptor strings.
      *
      * @return the type descriptor representation
+     * @jvms 4.3.2 Field Descriptors
      */
     @Override
     public String descriptorString() {
--- a/src/java.base/share/classes/java/lang/Enum.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Enum.java	Sat Jun 02 20:13:08 2018 -0700
@@ -292,6 +292,7 @@
          * @param constantType a {@link ClassDesc} describing the {@code enum} class
          * @param constantName the name of the enum constant, as per JVMS 4.2.2
          * @throws NullPointerException if any argument is null
+         * @jvms 4.2.2 Unqualified Names
          */
         private EnumDesc(ClassDesc constantType, String constantName) {
             super(ConstantDescs.BSM_ENUM_CONSTANT, requireNonNull(constantName), requireNonNull(constantType));
@@ -305,6 +306,7 @@
          * @param constantName the name of the enum constant, as per JVMS 4.2.2
          * @return the nominal descriptor
          * @throws NullPointerException if any argument is null
+         * @jvms 4.2.2 Unqualified Names
          */
         public static<E extends Enum<E>> EnumDesc<E> of(ClassDesc enumClass,
                                                         String constantName) {
@@ -335,6 +337,7 @@
          *                        per JVMS 4.3.2
          * @param constantName The name of the {@code enum} constant
          * @return the {@linkplain EnumDesc}
+         * @jvms 4.3.2 Field Descriptors
          */
         public static EnumDesc<?> constantBootstrap(MethodHandles.Lookup lookup, String name, Class<ClassDesc> clazz,
                                                     String classDescriptor, String constantName) {
--- a/src/java.base/share/classes/java/lang/invoke/FieldTypeDescriptor.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/FieldTypeDescriptor.java	Sat Jun 02 20:13:08 2018 -0700
@@ -4,6 +4,7 @@
  * Represents a field type descriptor, as per JVMS 4.3.2.
  *
  * @param <F> the class implementing {@linkplain FieldTypeDescriptor}
+ * @jvms 4.3.2 Field Descriptors
  */
 public interface FieldTypeDescriptor<F extends FieldTypeDescriptor<F>> extends TypeDescriptor {
     /**
--- a/src/java.base/share/classes/java/lang/invoke/MethodTypeDescriptor.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/MethodTypeDescriptor.java	Sat Jun 02 20:13:08 2018 -0700
@@ -7,6 +7,7 @@
  *
  * @param <F> the type representing field type descriptors
  * @param <M> the class implementing {@linkplain MethodTypeDescriptor}
+ * @jvms 4.3.3 Method Descriptors
  */
 public interface MethodTypeDescriptor<F extends FieldTypeDescriptor<F>, M extends MethodTypeDescriptor<F, M>>
         extends TypeDescriptor {
--- a/src/java.base/share/classes/java/lang/invoke/TypeDescriptor.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/TypeDescriptor.java	Sat Jun 02 20:13:08 2018 -0700
@@ -2,6 +2,8 @@
 
 /**
  * An entity that has a field or method type descriptor, as per JVMS 4.3.2 or 4.3.3.
+ * @jvms 4.3.2 Field Descriptors
+ * @jvms 4.3.3 Method Descriptors
  */
 public interface TypeDescriptor {
     /**
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Sat Jun 02 20:13:08 2018 -0700
@@ -2150,13 +2150,13 @@
                 this.descFactory = descFactory;
             }
 
-            List<ConstantDesc<?>> toBSMArgs(ClassDesc declaringClass, String name, ClassDesc varType) {
+            ConstantDesc<?>[] toBSMArgs(ClassDesc declaringClass, String name, ClassDesc varType) {
                 switch (this) {
                     case FIELD:
                     case STATIC_FIELD:
-                        return List.of(declaringClass, name, varType);
+                        return new ConstantDesc<?>[] { declaringClass, name, varType };
                     case ARRAY:
-                        return List.of(declaringClass);
+                        return new ConstantDesc<?>[] { declaringClass };
                     default:
                         throw new InternalError("Cannot reach here");
                 }
@@ -2178,11 +2178,12 @@
          *                       for field var handles
          * @param varType a {@link ClassDesc} describing the type of the variable
          * @throws NullPointerException if any required argument is null
+         * @jvms 4.2.2 Unqualified Names
          */
         private VarHandleDesc(Kind kind, String name, ClassDesc declaringClass, ClassDesc varType) {
             super(kind.bootstrapMethod, name,
                   ConstantDescs.CR_VarHandle,
-                  kind.toBSMArgs(declaringClass, name, varType).toArray(ConstantUtils.EMPTY_CONSTANTDESC));
+                  kind.toBSMArgs(declaringClass, name, varType));
             this.kind = kind;
             this.declaringClass = declaringClass;
             this.varType = varType;
@@ -2198,6 +2199,7 @@
          * @param fieldType a {@link ClassDesc} describing the type of the field
          * @return the {@linkplain VarHandleDesc}
          * @throws NullPointerException if any of the arguments are null
+         * @jvms 4.2.2 Unqualified Names
          */
         public static VarHandleDesc ofField(ClassDesc declaringClass, String name, ClassDesc fieldType) {
             Objects.requireNonNull(declaringClass);
@@ -2216,6 +2218,7 @@
          * @param fieldType a {@link ClassDesc} describing the type of the field
          * @return the {@linkplain VarHandleDesc}
          * @throws NullPointerException if any of the arguments are null
+         * @jvms 4.2.2 Unqualified Names
          */
         public static VarHandleDesc ofStaticField(ClassDesc declaringClass, String name, ClassDesc fieldType) {
             Objects.requireNonNull(declaringClass);
--- a/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -106,6 +106,7 @@
      * @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) {
@@ -137,7 +138,7 @@
     @Foldable
     default ClassDesc arrayType(int rank) {
         if (rank <= 0)
-            throw new IllegalArgumentException();
+            throw new IllegalArgumentException("rank: " + rank);
         return ClassDesc.ofDescriptor("[".repeat(rank) + descriptorString());
     }
 
@@ -242,13 +243,13 @@
      * @return the human-readable name
      */
     default String displayName() {
-        if (descriptorString().length() == 1)
+        if (isPrimitive())
             return Wrapper.forBasicType(descriptorString().charAt(0)).primitiveSimpleName();
-        else if (descriptorString().startsWith("L")) {
+        else if (isClassOrInterface()) {
             return descriptorString().substring(Math.max(1, descriptorString().lastIndexOf('/') + 1),
                                                 descriptorString().length() - 1);
         }
-        else if (descriptorString().startsWith(("["))) {
+        else if (isArray()) {
             int depth = ConstantUtils.arrayDepth(descriptorString());
             ClassDesc c = this;
             for (int i=0; i<depth; i++)
@@ -263,6 +264,7 @@
      * 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	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/Constable.java	Sat Jun 02 20:13:08 2018 -0700
@@ -58,6 +58,8 @@
  * (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
  */
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -51,6 +51,7 @@
      *                   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);
@@ -74,12 +75,12 @@
         for (int i=0; i<depth; i++)
             c = c.componentType();
 
-        if (c.descriptorString().length() == 1)
+        if (c.isPrimitive())
             return lookup.findClass(descriptorString());
         else {
             Class<?> clazz = lookup.findClass(internalToBinary(dropFirstAndLastChar(c.descriptorString())));
             for (int i = 0; i < depth; i++)
-                clazz = Array.newInstance(clazz, 0).getClass();
+                clazz = clazz.arrayType();
             return clazz;
         }
     }
@@ -99,6 +100,7 @@
      * @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) {
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -85,6 +85,7 @@
  * @see Intrinsics
  * @see ConstantDescs
  *
+ * @jvms 4.4 The Constant Pool
  */
 public interface ConstantDesc<T> {
     /**
@@ -98,6 +99,8 @@
      * @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	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantDescs.java	Sat Jun 02 20:13:08 2018 -0700
@@ -395,6 +395,7 @@
      * @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,
@@ -415,6 +416,7 @@
      * @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,
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -66,6 +66,7 @@
      * 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)
@@ -205,6 +206,9 @@
      * @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) {
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodTypeDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodTypeDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -68,6 +68,7 @@
      * @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) {
@@ -164,6 +165,7 @@
      * @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) {
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java	Sat Jun 02 20:13:08 2018 -0700
@@ -24,11 +24,8 @@
  */
 package java.lang.invoke.constant;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Optional;
-import java.util.Set;
+import java.util.*;
+import static java.util.Objects.requireNonNull;
 
 /**
  * Helper methods for the implementation of {@code java.lang.invoke.constant}.
@@ -55,6 +52,7 @@
      * @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++) {
@@ -112,6 +110,9 @@
     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;
--- a/src/java.base/share/classes/java/lang/invoke/constant/DynamicCallSiteDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/DynamicCallSiteDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -70,6 +70,7 @@
      * @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,
@@ -101,6 +102,7 @@
      * @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,
@@ -181,6 +183,7 @@
      * @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,
@@ -188,11 +191,6 @@
         return new DynamicCallSiteDesc(bootstrapMethod, invocationName, invocationType, bootstrapArgs);
     }
 
-    private DynamicCallSiteDesc canonicalize() {
-        // @@@ MethodDesc
-        return this;
-    }
-
     /**
      * Returns the invocation name that would appear in the {@code NameAndType}
      * operand of the {@code invokedynamic}.
--- a/src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -91,6 +91,7 @@
      * @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,
@@ -153,6 +154,7 @@
      * @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,
@@ -182,6 +184,7 @@
      * @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,
@@ -208,6 +211,7 @@
      * @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,
@@ -251,6 +255,7 @@
      * @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,
@@ -326,30 +331,6 @@
         return List.of(bootstrapArgs);
     }
 
-    private static Object[] resolveArgs(MethodHandles.Lookup lookup, ConstantDesc<?>[] args)
-            throws ReflectiveOperationException {
-        try {
-            return Stream.of(args)
-                    .map(arg -> {
-                        try {
-                            return arg.resolveConstantDesc(lookup);
-                        }
-                        catch (ReflectiveOperationException e) {
-                            throw new RuntimeException(e);
-                        }
-                    })
-                    .toArray();
-        }
-        catch (RuntimeException e) {
-            if (e.getCause() instanceof ReflectiveOperationException) {
-                throw (ReflectiveOperationException) e.getCause();
-            }
-            else {
-                throw e;
-            }
-        }
-    }
-
     @SuppressWarnings("unchecked")
     public T resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
         // TODO replace with public supported method
@@ -360,12 +341,13 @@
                 throw new BootstrapMethodError(
                         "Invalid bootstrap method declared for resolving a dynamic constant: " + bootstrapMethod);
             }
-            Object[] staticArgs = resolveArgs(lookup, bootstrapArgs);
-            Object[] bsmArgs = new Object[3 + staticArgs.length];
+            Object[] bsmArgs = new Object[3 + bootstrapArgs.length];
             bsmArgs[0] = lookup;
             bsmArgs[1] = constantName;
             bsmArgs[2] = constantType.resolveConstantDesc(lookup);
-            System.arraycopy(staticArgs, 0, bsmArgs, 3, staticArgs.length);
+            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;
@@ -406,6 +388,9 @@
      *                     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,
--- a/src/java.base/share/classes/java/lang/invoke/constant/MethodHandleDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/MethodHandleDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -107,6 +107,7 @@
      * @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,
@@ -138,6 +139,8 @@
      * 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,
@@ -171,6 +174,7 @@
      *                                    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,
@@ -193,6 +197,7 @@
      * @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,
--- a/src/java.base/share/classes/java/lang/invoke/constant/MethodTypeDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/MethodTypeDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -50,6 +50,7 @@
      * @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) {
@@ -170,6 +171,7 @@
      * 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",
--- a/src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java	Sat Jun 02 20:13:08 2018 -0700
@@ -48,6 +48,7 @@
      * 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);
--- a/src/java.base/share/classes/java/lang/invoke/constant/package-info.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/package-info.java	Sat Jun 02 20:13:08 2018 -0700
@@ -90,7 +90,7 @@
  * 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/test/jdk/java/lang/invoke/constant/ClassRefTest.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/test/jdk/java/lang/invoke/constant/ClassRefTest.java	Sat Jun 02 20:13:08 2018 -0700
@@ -26,6 +26,7 @@
 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;
@@ -239,7 +240,17 @@
             }
         }
 
-        ClassDesc barDesc = ClassDesc.of("Bar");
+        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");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/invoke/constant/ConstantUtilsTest.java	Sat Jun 02 20:13:08 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.invoke.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.invoke.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
+        }
+    }
+}
--- a/test/jdk/java/lang/invoke/constant/IndyRefTest.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/test/jdk/java/lang/invoke/constant/IndyRefTest.java	Sat Jun 02 20:13:08 2018 -0700
@@ -38,6 +38,7 @@
 
 import static java.lang.invoke.constant.ConstantDescs.*;
 import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotEquals;
 
 /**
  * @test
@@ -63,11 +64,54 @@
         CallSite cs = csd.resolveCallSiteDesc(MethodHandles.lookup());
         MethodHandle target = cs.getTarget();
         assertEquals("Foo", target.invoke());
+        assertEquals("wooga", csd.invocationName());
 
-        DynamicCallSiteDesc csd2 = DynamicCallSiteDesc.of(mh, "wooga", MethodTypeDesc.of(CR_String), "Bar");
+        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));
     }
 }
-
--- a/test/jdk/java/lang/invoke/constant/MethodHandleRefTest.java	Fri Jun 01 16:21:03 2018 +0200
+++ b/test/jdk/java/lang/invoke/constant/MethodHandleRefTest.java	Sat Jun 02 20:13:08 2018 -0700
@@ -45,6 +45,7 @@
 import static java.lang.invoke.constant.MethodHandleDesc.Kind.SETTER;
 import static java.lang.invoke.constant.MethodHandleDesc.Kind.STATIC_GETTER;
 import static java.lang.invoke.constant.MethodHandleDesc.Kind.STATIC_SETTER;
+import static java.lang.invoke.constant.MethodHandleDesc.Kind.VIRTUAL;
 import static java.lang.invoke.constant.ConstantDescs.CR_Integer;
 import static java.lang.invoke.constant.ConstantDescs.CR_List;
 import static java.lang.invoke.constant.ConstantDescs.CR_Object;
@@ -128,10 +129,11 @@
     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));
+        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);
@@ -265,6 +267,11 @@
         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();