changeset 50508:1ecd754523c6 condy-folding

removing Lookup argument from describeConstable() and adding FieldDescriptor, MethodDescriptor and TypeDescriptor
author vromero
date Fri, 04 May 2018 11:20:25 -0700
parents 97341d327bc2
children 3e41ca0d8cfd
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/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/X-VarHandle.java.template 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/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/DynamicConstantDesc.java src/java.base/share/classes/java/lang/invoke/constant/EnumDesc.java src/java.base/share/classes/java/lang/invoke/constant/FieldDescriptor.java src/java.base/share/classes/java/lang/invoke/constant/MethodDescriptor.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/TypeDescriptor.java src/java.base/share/classes/java/lang/invoke/constant/VarHandleDesc.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java test/langtools/tools/javac/specialConstantFolding/IndyLinkageErrorTest.java test/langtools/tools/javac/specialConstantFolding/IndyNegativeTest01.java test/langtools/tools/javac/specialConstantFolding/IndyPositiveTest01.java test/langtools/tools/javac/specialConstantFolding/IntrinsicsTest.java
diffstat 32 files changed, 258 insertions(+), 129 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/Class.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Class.java	Fri May 04 11:20:25 2018 -0700
@@ -28,6 +28,7 @@
 import java.lang.annotation.Annotation;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.constant.ClassDesc;
+import java.lang.invoke.constant.FieldDescriptor;
 import java.lang.module.ModuleReader;
 import java.lang.ref.SoftReference;
 import java.io.IOException;
@@ -134,6 +135,7 @@
                               GenericDeclaration,
                               Type,
                               AnnotatedElement,
+                              FieldDescriptor<Class<?>>,
                               Constable<Class<T>> {
     private static final int ANNOTATION= 0x00002000;
     private static final int ENUM      = 0x00004000;
@@ -259,29 +261,6 @@
     }
 
     /**
-     * Produces a bytecode descriptor representation of the class.
-     * <p>
-     * Note that this is not a strict inverse of {@link #forName};
-     * two distinct classes which share a common name but have different class loaders
-     * will appear identical when viewed within descriptor strings.
-     * <p>
-     * This method is included for the benefit of applications that must
-     * generate bytecode.
-     *
-     * @return the bytecode type descriptor representation
-     */
-    public String toDescriptorString() {
-        if (isPrimitive())
-            return new String(new char[] {Wrapper.forPrimitiveType(this).basicTypeChar()});
-        else if (isArray()) {
-            return "[" + componentType.toDescriptorString();
-        }
-        else {
-            return "L" + getName().replace('.', '/') + ";";
-        }
-    }
-
-    /**
      * Returns the {@code Class} object associated with the class or
      * interface with the given string name.  Invoking this method is
      * equivalent to:
@@ -3853,13 +3832,41 @@
          return TypeAnnotationParser.buildAnnotatedInterfaces(getRawTypeAnnotations(), getConstantPool(), this);
     }
 
+    /**
+     * Produce the type descriptor string for this class as per JVMS 4.3.2.
+     * <p>
+     * Note that this is not a strict inverse of {@link #forName};
+     * distinct classes which share a common name but have different class loaders
+     * will have identical descriptor strings.
+     *
+     * @return the type descriptor representation
+     */
     @Override
-    public Optional<ClassDesc> describeConstable(MethodHandles.Lookup lookup) {
-        try {
-            return Optional.of(ClassDesc.ofDescriptor(lookup.accessClass(this).toDescriptorString()));
+    public String descriptorString() {
+        if (isPrimitive())
+            return new String(new char[] {Wrapper.forPrimitiveType(this).basicTypeChar()});
+        else if (isArray()) {
+            return "[" + componentType.descriptorString();
         }
-        catch (IllegalAccessException e) {
-            return Optional.empty();
+        else {
+            return "L" + getName().replace('.', '/') + ";";
         }
     }
+
+    @Override
+    public Class<?> componentType() {
+        if (!isArray())
+            throw new IllegalStateException("not an array class");
+        return componentType;
+    }
+
+    @Override
+    public Class<?> arrayType() {
+        return Array.newInstance(this, 0).getClass();
+    }
+
+    @Override
+    public Optional<ClassDesc> describeConstable() {
+        return Optional.of(ClassDesc.ofDescriptor(descriptorString()));
+    }
 }
--- a/src/java.base/share/classes/java/lang/Double.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Double.java	Fri May 04 11:20:25 2018 -0700
@@ -1080,11 +1080,10 @@
      * Returns a symbolic constant reference for this instance, which is
      * the instance itself.
      *
-     * @param lookup ignored
      * @return the {@linkplain Double} instance
      */
     @Override
-    public Optional<ConstantDesc<Double>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<ConstantDesc<Double>> describeConstable() {
         return Optional.of(this);
     }
 
--- a/src/java.base/share/classes/java/lang/Enum.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Enum.java	Fri May 04 11:20:25 2018 -0700
@@ -30,7 +30,6 @@
 import java.io.InvalidObjectException;
 import java.io.ObjectInputStream;
 import java.io.ObjectStreamException;
-import java.lang.invoke.MethodHandles;
 import java.lang.invoke.constant.Constable;
 import java.lang.invoke.constant.ConstantDesc;
 import java.lang.invoke.constant.EnumDesc;
@@ -213,16 +212,14 @@
      * nominal description) must be accessible from the class described by the
      * {@code lookup} parameter.
      *
-     * @param lookup A {@link MethodHandles.Lookup} to be used to perform
-     *               access control determinations
      * @return An {@link Optional} containing the resulting nominal descriptor,
      * or an empty {@link Optional} if one cannot be constructed or this object
      * is not accessible from {@code lookup}
      */
     @Override
-    public final Optional<? extends ConstantDesc<? super E>> describeConstable(MethodHandles.Lookup lookup) {
+    public final Optional<? extends ConstantDesc<? super E>> describeConstable() {
         return getDeclaringClass()
-                .describeConstable(lookup)
+                .describeConstable()
                 .map(c -> EnumDesc.of(c, name));
     }
 
--- a/src/java.base/share/classes/java/lang/Float.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Float.java	Fri May 04 11:20:25 2018 -0700
@@ -992,11 +992,10 @@
      * Returns a symbolic constant reference for this instance, which is
      * the instance itself.
      *
-     * @param lookup ignored
      * @return the {@linkplain Float} instance
      */
     @Override
-    public Optional<ConstantDesc<Float>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<ConstantDesc<Float>> describeConstable() {
         return Optional.of(this);
     }
 
--- a/src/java.base/share/classes/java/lang/Integer.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Integer.java	Fri May 04 11:20:25 2018 -0700
@@ -1827,11 +1827,10 @@
      * Returns a symbolic constant reference for this instance, which is
      * the instance itself.
      *
-     * @param lookup ignored
      * @return the {@linkplain Integer} instance
      */
     @Override
-    public Optional<ConstantDesc<Integer>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<ConstantDesc<Integer>> describeConstable() {
         return Optional.of(this);
     }
 
--- a/src/java.base/share/classes/java/lang/Long.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/Long.java	Fri May 04 11:20:25 2018 -0700
@@ -1973,11 +1973,10 @@
      * Returns a symbolic constant reference for this instance, which is
      * the instance itself.
      *
-     * @param lookup ignored
      * @return the {@linkplain Long} instance
      */
     @Override
-    public Optional<ConstantDesc<Long>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<ConstantDesc<Long>> describeConstable() {
         return Optional.of(this);
     }
 
--- a/src/java.base/share/classes/java/lang/String.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/String.java	Fri May 04 11:20:25 2018 -0700
@@ -3190,11 +3190,10 @@
      * Returns a symbolic constant reference for this instance, which is
      * the instance itself.
      *
-     * @param lookup ignored
      * @return the {@linkplain String} instance
      */
     @Override
-    public Optional<ConstantDesc<String>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<ConstantDesc<String>> describeConstable() {
         return Optional.of(this);
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/MethodHandle.java	Fri May 04 11:20:25 2018 -0700
@@ -38,6 +38,7 @@
 
 import static java.lang.invoke.MethodHandleInfo.*;
 import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
 
 /**
  * A method handle is a typed, directly executable reference to an underlying method,
@@ -1515,15 +1516,15 @@
     }
 
     @Override
-    public Optional<MethodHandleDesc> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<MethodHandleDesc> describeConstable() {
         MethodHandleInfo info;
         ClassDesc owner;
         String name;
         MethodTypeDesc type;
         try {
-            info = lookup.revealDirect(this);
-            owner = info.getDeclaringClass().describeConstable(lookup).orElseThrow();
-            type = info.getMethodType().describeConstable(lookup).orElseThrow();
+            info = IMPL_LOOKUP.revealDirect(this);
+            owner = info.getDeclaringClass().describeConstable().orElseThrow();
+            type = info.getMethodType().describeConstable().orElseThrow();
             name = info.getName();
         }
         catch (Exception e) {
--- a/src/java.base/share/classes/java/lang/invoke/MethodType.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java	Fri May 04 11:20:25 2018 -0700
@@ -28,6 +28,7 @@
 import jdk.internal.vm.annotation.Stable;
 import sun.invoke.util.Wrapper;
 
+import java.lang.invoke.constant.MethodDescriptor;
 import java.lang.invoke.constant.MethodTypeDesc;
 import java.lang.ref.WeakReference;
 import java.lang.ref.Reference;
@@ -99,7 +100,10 @@
  * @since 1.7
  */
 public final
-class MethodType implements Constable<MethodType>, java.io.Serializable {
+class MethodType
+        implements Constable<MethodType>,
+                   MethodDescriptor<Class<?>, MethodType>,
+                   java.io.Serializable {
     private static final long serialVersionUID = 292L;  // {rtype, {ptype...}}
 
     // The rtype and ptypes fields define the structural identity of the method type:
@@ -1167,16 +1171,21 @@
         return desc;
     }
 
+    @Override
+    public String descriptorString() {
+        return toMethodDescriptorString();
+    }
+
     /*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
         return BytecodeDescriptor.unparse(cls);
     }
 
     @Override
-    public Optional<MethodTypeDesc> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<MethodTypeDesc> describeConstable() {
         try {
-            return Optional.of(MethodTypeDesc.of(returnType().describeConstable(lookup).orElseThrow(),
+            return Optional.of(MethodTypeDesc.of(returnType().describeConstable().orElseThrow(),
                                                  Stream.of(parameterArray())
-                                                      .map(p -> p.describeConstable(lookup).orElseThrow())
+                                                      .map(p -> p.describeConstable().orElseThrow())
                                                       .toArray(ClassDesc[]::new)));
         }
         catch (NoSuchElementException e) {
--- a/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/VarHandle.java	Fri May 04 11:20:25 2018 -0700
@@ -1985,7 +1985,7 @@
     }
 
     @Override
-    public Optional<VarHandleDesc> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<VarHandleDesc> describeConstable() {
         // partial function for field and array only
         return Optional.empty();
     }
--- a/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/X-VarHandle.java.template	Fri May 04 11:20:25 2018 -0700
@@ -75,9 +75,9 @@
         }
 
         @Override
-        public Optional<VarHandleDesc> describeConstable(MethodHandles.Lookup lookup) {
-            var receiverTypeRef = receiverType.describeConstable(lookup);
-            var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable(lookup);
+        public Optional<VarHandleDesc> describeConstable() {
+            var receiverTypeRef = receiverType.describeConstable();
+            var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable();
             if (!receiverTypeRef.isPresent() || !fieldTypeRef.isPresent())
                 return Optional.empty();
 
@@ -360,14 +360,14 @@
         }
 
         @Override
-        public Optional<VarHandleDesc> describeConstable(MethodHandles.Lookup lookup) {
-            var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable(lookup);
+        public Optional<VarHandleDesc> describeConstable() {
+            var fieldTypeRef = {#if[Object]?fieldType:$type$.class}.describeConstable();
             if (!fieldTypeRef.isPresent())
                 return Optional.empty();
 
             var staticField = VarHandles.getStaticFieldFromBaseAndOffset(
                 base, fieldOffset, {#if[Object]?fieldType:$type$.class});
-            var receiverTypeRef = staticField.getDeclaringClass().describeConstable(lookup);
+            var receiverTypeRef = staticField.getDeclaringClass().describeConstable();
             if (!receiverTypeRef.isPresent())
                 return Optional.empty();
             return Optional.of(VarHandleDesc.ofStaticField(receiverTypeRef.get(), staticField.getName(), fieldTypeRef.get()));
@@ -638,8 +638,8 @@
         }
 
         @Override
-        public Optional<VarHandleDesc> describeConstable(MethodHandles.Lookup lookup) {
-            var arrayTypeRef = {#if[Object]?arrayType:$type$[].class}.describeConstable(lookup);
+        public Optional<VarHandleDesc> describeConstable() {
+            var arrayTypeRef = {#if[Object]?arrayType:$type$[].class}.describeConstable();
             if (!arrayTypeRef.isPresent())
                 return Optional.empty();
 
--- a/src/java.base/share/classes/java/lang/invoke/constant/AsTypeMethodHandleDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/AsTypeMethodHandleDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -68,8 +68,8 @@
     }
 
     @Override
-    public Optional<? extends ConstantDesc<? super ConstantDesc<MethodHandle>>> describeConstable(MethodHandles.Lookup lookup) {
-        return ConstantUtils.symbolizeHelper(lookup, ConstantDescs.MHR_METHODHANDLEDESC_ASTYPE, ConstantDescs.CR_MethodHandleDesc,
+    public Optional<? extends ConstantDesc<? super ConstantDesc<MethodHandle>>> describeConstable() {
+        return ConstantUtils.symbolizeHelper(ConstantDescs.MHR_METHODHANDLEDESC_ASTYPE, ConstantDescs.CR_MethodHandleDesc,
                                              underlying, type);
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ClassDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -46,13 +46,15 @@
  * 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 #array()}
- * or {@link #array(int)} methods.
+ * {@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<?>>> {
+        extends ConstantDesc<Class<?>>,
+                Constable<ConstantDesc<Class<?>>>,
+                FieldDescriptor<ClassDesc> {
 
     /**
      * Create a {@linkplain ClassDesc} given a class name.
@@ -114,8 +116,8 @@
      * @return a {@linkplain ClassDesc} describing the array type
      */
     @Foldable
-    default ClassDesc array() {
-        return array(1);
+    default ClassDesc arrayType() {
+        return arrayType(1);
     }
 
     /**
@@ -127,7 +129,7 @@
      * @throws IllegalArgumentException if the rank is zero or negative
      */
     @Foldable
-    default ClassDesc array(int rank) {
+    default ClassDesc arrayType(int rank) {
         if (rank <= 0)
             throw new IllegalArgumentException();
         return ClassDesc.ofDescriptor("[".repeat(rank) + descriptorString());
--- a/src/java.base/share/classes/java/lang/invoke/constant/Constable.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/Constable.java	Fri May 04 11:20:25 2018 -0700
@@ -25,7 +25,6 @@
 package java.lang.invoke.constant;
 
 import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
 import java.lang.invoke.VarHandle;
 import java.util.Optional;
@@ -52,7 +51,7 @@
  * generated constants (JVMS 4.4.10).
  *
  * <p>The nominal form of an instance of a constable type is obtained via
- * {@link #describeConstable(MethodHandles.Lookup)}. A {@linkplain Constable} need
+ * {@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.
@@ -67,27 +66,8 @@
      * Return a nominal descriptor for this instance, if one can be
      * constructed.
      *
-     * @implSpec This method behaves as if {@link #describeConstable(MethodHandles.Lookup)}
-     * were called with a lookup parameter of {@link MethodHandles#publicLookup()}.
-     *
      * @return An {@link Optional} containing the resulting nominal descriptor,
-     * or an empty {@link Optional} if one cannot be constructed
+     * or an empty {@link Optional} if one cannot be constructed.
      */
-    default Optional<? extends ConstantDesc<? super T>> describeConstable() {
-        return describeConstable(MethodHandles.publicLookup());
-    }
-
-    /**
-     * Return a nominal descriptor for this instance, if one can be
-     * constructed.  This object (and any classes needed to construct its
-     * nominal description) must be accessible from the class described by the
-     * {@code lookup} parameter.
-     *
-     * @param lookup A {@link MethodHandles.Lookup} to be used to perform
-     *               access control determinations
-     * @return An {@link Optional} containing the resulting nominal descriptor,
-     * or an empty {@link Optional} if one cannot be constructed or this object
-     * is not accessible from {@code lookup}
-     */
-    Optional<? extends ConstantDesc<? super T>> describeConstable(MethodHandles.Lookup lookup);
+    Optional<? extends ConstantDesc<? super T>> describeConstable();
 }
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantClassDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -34,7 +34,6 @@
 
 import static java.lang.invoke.constant.ConstantDescs.BSM_CLASSDESC;
 import static java.lang.invoke.constant.ConstantDescs.CR_ClassDesc;
-import static java.lang.invoke.constant.ConstantDescs.CR_String;
 import static java.lang.invoke.constant.ConstantUtils.dropFirstAndLastChar;
 import static java.lang.invoke.constant.ConstantUtils.internalToBinary;
 import static java.util.Objects.requireNonNull;
@@ -96,7 +95,7 @@
     }
 
     @Override
-    public Optional<? extends ConstantDesc<? super ConstantDesc<Class<?>>>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<? extends ConstantDesc<? super ConstantDesc<Class<?>>>> describeConstable() {
         return Optional.of(DynamicConstantDesc.of(BSM_CLASSDESC, CR_ClassDesc).withArgs(descriptor));
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantDescs.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantDescs.java	Fri May 04 11:20:25 2018 -0700
@@ -264,7 +264,7 @@
     @Foldable
     public static final ConstantMethodHandleDesc BSM_INVOKE
             = ofConstantBootstrap(CR_ConstantBootstraps, "invoke",
-                                  CR_Object, CR_MethodHandle, CR_Object.array());
+                                  CR_Object, CR_MethodHandle, CR_Object.arrayType());
 
     /** {@link ClassDesc} representing the primitive type {@code int} */
     @Foldable
@@ -335,7 +335,7 @@
 
     static final ConstantMethodHandleDesc MHR_DYNAMICCONSTANTDESC_WITHARGS
             = MethodHandleDesc.of(MethodHandleDesc.Kind.VIRTUAL, CR_DynamicConstantDesc, "withArgs",
-                                  CR_DynamicConstantDesc, CR_ConstantDesc.array());
+                                  CR_DynamicConstantDesc, CR_ConstantDesc.arrayType());
 
     static final ConstantMethodHandleDesc MHR_ENUMDESC_FACTORY
             = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, CR_EnumDesc, "of",
@@ -374,7 +374,7 @@
             = ConstantDescs.ofConstantBootstrap(ClassDesc.of("java.lang.invoke.constant", "DynamicConstantDesc"),
                                                 "constantBootstrap",
                                                 CR_DynamicConstantDesc,
-                                                CR_String, CR_String, CR_String, CR_String, CR_String, CR_ConstantDesc.array());
+                                                CR_String, CR_String, CR_String, CR_String, CR_String, CR_ConstantDesc.arrayType());
 
 
     /**
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodHandleDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -35,7 +35,6 @@
 
 import static java.lang.invoke.constant.ConstantDescs.BSM_METHODHANDLEDESC;
 import static java.lang.invoke.constant.ConstantDescs.CR_ConstantMethodHandleDesc;
-import static java.lang.invoke.constant.ConstantDescs.CR_MethodHandleDesc;
 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;
@@ -187,7 +186,7 @@
     }
 
     @Override
-    public Optional<? extends ConstantDesc<? super ConstantDesc<MethodHandle>>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<? extends ConstantDesc<? super ConstantDesc<MethodHandle>>> describeConstable() {
         return Optional.of(DynamicConstantDesc.of(BSM_METHODHANDLEDESC, CR_ConstantMethodHandleDesc)
                                               .withArgs(kind.toString(), owner.descriptorString(), name, type.descriptorString()));
     }
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodTypeDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantMethodTypeDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -37,8 +37,6 @@
 
 import static java.lang.invoke.constant.ConstantDescs.BSM_METHODTYPEDESC;
 import static java.lang.invoke.constant.ConstantDescs.CR_ConstantMethodTypeDesc;
-import static java.lang.invoke.constant.ConstantDescs.CR_MethodTypeDesc;
-import static java.lang.invoke.constant.ConstantDescs.CR_String;
 import static java.util.Objects.requireNonNull;
 
 /**
@@ -179,7 +177,7 @@
     }
 
     @Override
-    public Optional<? extends ConstantDesc<? super ConstantDesc<MethodType>>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<? extends ConstantDesc<? super ConstantDesc<MethodType>>> describeConstable() {
         return Optional.of(DynamicConstantDesc.of(BSM_METHODTYPEDESC, CR_ConstantMethodTypeDesc).withArgs(descriptorString()));
     }
 
--- a/src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/ConstantUtils.java	Fri May 04 11:20:25 2018 -0700
@@ -24,7 +24,6 @@
  */
 package java.lang.invoke.constant;
 
-import java.lang.invoke.MethodHandles;
 import java.util.NoSuchElementException;
 import java.util.Optional;
 import java.util.Set;
@@ -96,25 +95,22 @@
      * 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 DynamicConstantDesc#describeConstable(MethodHandles.Lookup)}.
+     * method for implementing {@link Constable#describeConstable()}.
      *
-     * @param lookup A {@link MethodHandles.Lookup} to be used to perform
-     *               access control determinations
+     * @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
-     * @param <T> the type of the resulting constant
      * @return the nominal descriptor for the dynamic constant
      */
-    static<T> Optional<DynamicConstantDesc<T>> symbolizeHelper(MethodHandles.Lookup lookup,
-                                                               MethodHandleDesc bootstrap,
+    static<T> Optional<DynamicConstantDesc<T>> symbolizeHelper(MethodHandleDesc bootstrap,
                                                                ClassDesc type,
                                                                Constable<?>... 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(lookup).orElseThrow();
+                quotedArgs[i+1] = args[i].describeConstable().orElseThrow();
             return Optional.of(DynamicConstantDesc.of(ConstantDescs.BSM_INVOKE, ConstantDescs.DEFAULT_NAME,
                                                       type, quotedArgs));
         }
--- a/src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/DynamicConstantDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -39,10 +39,7 @@
 
 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_ConstantDesc;
 import static java.lang.invoke.constant.ConstantDescs.CR_DynamicConstantDesc;
-import static java.lang.invoke.constant.ConstantDescs.CR_Enum;
-import static java.lang.invoke.constant.ConstantDescs.CR_String;
 import static java.lang.invoke.constant.ConstantDescs.CR_VarHandle;
 import static java.lang.invoke.constant.ConstantUtils.validateMemberName;
 import static java.util.Objects.requireNonNull;
@@ -376,7 +373,7 @@
     }
 
     @Override
-    public Optional<? extends ConstantDesc<? super ConstantDesc<T>>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<? extends ConstantDesc<? super ConstantDesc<T>>> describeConstable() {
         ConstantDesc<?>[] args = new ConstantDesc<?>[bootstrapArgs.length + 5];
         args[0] = bootstrapMethod.owner().descriptorString();
         args[1] = bootstrapMethod.methodName();
--- a/src/java.base/share/classes/java/lang/invoke/constant/EnumDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/EnumDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -31,7 +31,6 @@
 
 import static java.lang.invoke.constant.ConstantDescs.BSM_ENUMDESC;
 import static java.lang.invoke.constant.ConstantDescs.CR_EnumDesc;
-import static java.lang.invoke.constant.ConstantDescs.CR_String;
 import static java.lang.invoke.constant.ConstantUtils.validateMemberName;
 import static java.util.Objects.requireNonNull;
 
@@ -78,7 +77,7 @@
     }
 
     @Override
-    public Optional<? extends ConstantDesc<? super ConstantDesc<E>>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<? extends ConstantDesc<? super ConstantDesc<E>>> describeConstable() {
         return Optional.of(DynamicConstantDesc.of(BSM_ENUMDESC, CR_EnumDesc)
                                               .withArgs(constantType().descriptorString(), constantName()));
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/constant/FieldDescriptor.java	Fri May 04 11:20:25 2018 -0700
@@ -0,0 +1,35 @@
+package java.lang.invoke.constant;
+
+/**
+ * Represents a field type descriptor, as per JVMS 4.3.2.
+ *
+ * @param <F> the class implementing {@linkplain FieldDescriptor}
+ */
+public interface FieldDescriptor<F extends FieldDescriptor<F>> extends TypeDescriptor {
+    /**
+     * Does this field descriptor describe an array type?
+     * @return whether this field descriptor describes an array type
+     */
+    boolean isArray();
+
+    /**
+     * Does this field descriptor describe a primitive type?
+     * @return whether this field descriptor describes a primitive type
+     */
+    boolean isPrimitive();
+
+    /**
+     * If this field descriptor describes an array type, return
+     * a descriptor for its component type.
+     * @return the component type
+     * @throws IllegalStateException if this descriptor does not describe an array type
+     */
+    F componentType();
+
+    /**
+     * Return a descriptor for the array type whose component type is described by this
+     * descriptor
+     * @return the descriptor for the array type
+     */
+    F arrayType();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/constant/MethodDescriptor.java	Fri May 04 11:20:25 2018 -0700
@@ -0,0 +1,101 @@
+package java.lang.invoke.constant;
+
+import java.util.List;
+
+/**
+ * Represents a method type descriptor, as per JVMS 4.3.3
+ *
+ * @param <F> the type representing field type descriptors
+ * @param <M> the class implementing {@linkplain MethodDescriptor}
+ */
+public interface MethodDescriptor<F extends FieldDescriptor<F>, M extends MethodDescriptor<F, M>>
+        extends TypeDescriptor {
+
+    /**
+     * Return the number of parameters in the method type
+     * @return the number of parameters
+     */
+    int parameterCount();
+
+    /**
+     * Return a field descriptor describing the requested parameter of the method type
+     * described by this descriptor
+     * @param i the index of the parameter
+     * @return a field descriptor for the requested parameter type
+     * @throws IndexOutOfBoundsException if the index is outside the half-open
+     * range {[0, parameterCount)}
+     */
+    F parameterType(int i);
+
+    /**
+     * Return a field descriptor describing the return type of the method type described
+     * by this descriptor
+     * @return a field descriptor for the return type
+     */
+    F returnType();
+
+    /**
+     * Return an array of field descriptors for the parameter types of the method type
+     * described by this descriptor
+     * @return field descriptors for the parameter types
+     */
+    F[] parameterArray();
+
+    /**
+     * Return a list of field descriptors for the parameter types of the method type
+     * described by this descriptor
+     * @return field descriptors for the parameter types
+     */
+    List<F> parameterList();
+
+    /**
+     * Return a method descriptor that is identical to this one, except that the return
+     * type has been changed to the specified type
+     *
+     * @param newReturn a field descriptor for the new return type
+     * @throws NullPointerException if any argument is {@code null}
+     * @return the new method descriptor
+     */
+    M changeReturnType(F newReturn);
+
+    /**
+     * Return a method descriptor 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 field descriptor describing the new parameter type
+     * @return the new method descriptor
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IndexOutOfBoundsException if the index is outside the half-open
+     * range {[0, parameterCount)}
+     */
+    M changeParameterType(int index, F paramType);
+
+    /**
+     * Return a method descriptor 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 the new method descriptor
+     * @throws IndexOutOfBoundsException if {@code start} is outside the half-open
+     * range {[0, parameterCount)}, or {@code end} is outside the closed range
+     * {@code [0, parameterCount]}
+     */
+    M dropParameterTypes(int start, int end);
+
+    /**
+     * Return a method descriptor 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 field descriptors describing the new parameter types
+     *                   to insert
+     * @return the new method descriptor
+     * @throws NullPointerException if any argument is {@code null}
+     * @throws IndexOutOfBoundsException if {@code pos} is outside the closed
+     * range {[0, parameterCount]}
+     */
+    @SuppressWarnings("unchecked")
+    M insertParameterTypes(int pos, F... paramTypes);
+}
--- a/src/java.base/share/classes/java/lang/invoke/constant/MethodTypeDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/MethodTypeDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -38,7 +38,9 @@
  * {@linkplain MethodType} constant.
  */
 public interface MethodTypeDesc
-        extends ConstantDesc<MethodType>, Constable<ConstantDesc<MethodType>> {
+        extends ConstantDesc<MethodType>,
+                Constable<ConstantDesc<MethodType>>,
+                MethodDescriptor<ClassDesc, MethodTypeDesc> {
     /**
      * Create a {@linkplain MethodTypeDesc} given a method descriptor string
      *
--- a/src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/PrimitiveClassDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -67,8 +67,8 @@
     }
 
     @Override
-    public Optional<? extends ConstantDesc<? super ConstantDesc<Class<?>>>> describeConstable(MethodHandles.Lookup lookup) {
-        return ConstantUtils.symbolizeHelper(lookup, ConstantDescs.MHR_CLASSDESC_FACTORY, ConstantDescs.CR_ClassDesc, descriptorString());
+    public Optional<? extends ConstantDesc<? super ConstantDesc<Class<?>>>> describeConstable() {
+        return ConstantUtils.symbolizeHelper(ConstantDescs.MHR_CLASSDESC_FACTORY, ConstantDescs.CR_ClassDesc, descriptorString());
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/invoke/constant/TypeDescriptor.java	Fri May 04 11:20:25 2018 -0700
@@ -0,0 +1,12 @@
+package java.lang.invoke.constant;
+
+/**
+ * An entity that has a field or method type descriptor, as per JVMS 4.3.2 or 4.3.3.
+ */
+public interface TypeDescriptor {
+    /**
+     * Return the type descriptor for this instance, which may be a field or method type descriptor.
+     * @return the type descriptor
+     */
+    String descriptorString();
+}
--- a/src/java.base/share/classes/java/lang/invoke/constant/VarHandleDesc.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/java.base/share/classes/java/lang/invoke/constant/VarHandleDesc.java	Fri May 04 11:20:25 2018 -0700
@@ -181,12 +181,12 @@
     }
 
     @Override
-    public Optional<? extends ConstantDesc<? super ConstantDesc<VarHandle>>> describeConstable(MethodHandles.Lookup lookup) {
+    public Optional<? extends ConstantDesc<? super ConstantDesc<VarHandle>>> describeConstable() {
         Constable<?>[] args =
                 (kind == Kind.ARRAY)
                 ? new Constable<?>[] { declaringClass }
                 : new Constable<?>[] { declaringClass, constantName(), varType };
-        return ConstantUtils.symbolizeHelper(lookup, kind.descFactory, CR_VarHandleDesc, args);
+        return ConstantUtils.symbolizeHelper(kind.descFactory, CR_VarHandleDesc, args);
     }
 
     @Override
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Thu May 03 22:07:06 2018 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Constables.java	Fri May 04 11:20:25 2018 -0700
@@ -286,7 +286,7 @@
         if (constant != null) {
             if (!canMakeItToConstantValue(tree.type) &&
                 constableClass.isInstance(constant)) {
-                Optional<?> optional = ((Optional<?>)invokeMethodReflectively(constant.getClass(), constant, "describeConstable"));
+                Optional<?> optional = ((Optional<?>)invokeMethodReflectively(constableClass, constant, "describeConstable"));
                 if (!optional.isPresent()) {
                     return Optional.empty();
                 }
--- a/test/langtools/tools/javac/specialConstantFolding/IndyLinkageErrorTest.java	Thu May 03 22:07:06 2018 +0200
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyLinkageErrorTest.java	Fri May 04 11:20:25 2018 -0700
@@ -15,7 +15,7 @@
                 ConstantDescs.CR_String,
                 ConstantDescs.CR_MethodType,
                 ConstantDescs.CR_String,
-                ConstantDescs.CR_Object.array()
+                ConstantDescs.CR_Object.arrayType()
         );
         ConstantMethodHandleDesc mh = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ClassDesc.ofDescriptor("Ljava/lang/invoke/StringConcatFactory;"),
                                                           "makeConcatWithConstants", methodTypeForMethodHandle);
--- a/test/langtools/tools/javac/specialConstantFolding/IndyNegativeTest01.java	Thu May 03 22:07:06 2018 +0200
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyNegativeTest01.java	Fri May 04 11:20:25 2018 -0700
@@ -16,7 +16,7 @@
                 ConstantDescs.CR_String,
                 ConstantDescs.CR_MethodType,
                 ConstantDescs.CR_String,
-                ConstantDescs.CR_Object.array()
+                ConstantDescs.CR_Object.arrayType()
         );
         ConstantMethodHandleDesc mh = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ClassDesc.ofDescriptor("Ljava/lang/invoke/StringConcatFactory;"),
                                                           "makeConcatWithConstants", methodTypeForMethodHandle);
--- a/test/langtools/tools/javac/specialConstantFolding/IndyPositiveTest01.java	Thu May 03 22:07:06 2018 +0200
+++ b/test/langtools/tools/javac/specialConstantFolding/IndyPositiveTest01.java	Fri May 04 11:20:25 2018 -0700
@@ -46,7 +46,7 @@
                 ConstantDescs.CR_String,
                 ConstantDescs.CR_MethodType,
                 ConstantDescs.CR_String,
-                ConstantDescs.CR_Object.array()
+                ConstantDescs.CR_Object.arrayType()
         );
         ConstantMethodHandleDesc mh = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ClassDesc.ofDescriptor("Ljava/lang/invoke/StringConcatFactory;"),
                                                           "makeConcatWithConstants", methodTypeForMethodHandle);
--- a/test/langtools/tools/javac/specialConstantFolding/IntrinsicsTest.java	Thu May 03 22:07:06 2018 +0200
+++ b/test/langtools/tools/javac/specialConstantFolding/IntrinsicsTest.java	Fri May 04 11:20:25 2018 -0700
@@ -115,11 +115,11 @@
     public void testClassCombinators() {
         ClassDesc cs = ClassDesc.ofDescriptor("Ljava/lang/String;");
         assertEquals(String.class, Intrinsics.ldc(cs));
-        assertEquals(String[].class, Intrinsics.ldc(cs.array()));
+        assertEquals(String[].class, Intrinsics.ldc(cs.arrayType()));
 
-        assertEquals(String[][].class, Intrinsics.ldc(cs.array().array()));
-        assertEquals(String.class, Intrinsics.ldc(cs.array().componentType()));
-        assertEquals(String[].class, Intrinsics.ldc(cs.array().array().componentType()));
+        assertEquals(String[][].class, Intrinsics.ldc(cs.arrayType().arrayType()));
+        assertEquals(String.class, Intrinsics.ldc(cs.arrayType().componentType()));
+        assertEquals(String[].class, Intrinsics.ldc(cs.arrayType().arrayType().componentType()));
     }
 
     public void testMethodTypeCombinators() {
@@ -142,7 +142,7 @@
 
     public void testInterfaceSpecial() throws Throwable {
         MethodHandleDesc mhr = MethodHandleDesc.of(MethodHandleDesc.Kind.STATIC, ConstantDescs.CR_List, "of",
-                                                   MethodTypeDesc.of(ConstantDescs.CR_List, ConstantDescs.CR_Object.array()));
+                                                   MethodTypeDesc.of(ConstantDescs.CR_List, ConstantDescs.CR_Object.arrayType()));
         MethodHandle mh = Intrinsics.ldc(mhr);
         assertEquals(List.of("a", "b"), (List<String>) mh.invoke("a", "b"));
     }