jdk/src/share/classes/java/lang/invoke/LambdaForm.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot-comp Sdiff jdk/src/share/classes/java/lang/invoke

jdk/src/share/classes/java/lang/invoke/LambdaForm.java

Print this page
rev 7928 : imported patch stable


  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import java.lang.annotation.*;
  29 import java.lang.reflect.Method;
  30 import java.util.Map;
  31 import java.util.List;
  32 import java.util.Arrays;
  33 import java.util.ArrayList;
  34 import java.util.HashMap;
  35 import java.util.concurrent.ConcurrentHashMap;
  36 import sun.invoke.util.Wrapper;

  37 import static java.lang.invoke.MethodHandleStatics.*;
  38 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  39 import java.lang.reflect.Field;
  40 import java.util.Objects;
  41 
  42 /**
  43  * The symbolic, non-executable form of a method handle's invocation semantics.
  44  * It consists of a series of names.
  45  * The first N (N=arity) names are parameters,
  46  * while any remaining names are temporary values.
  47  * Each temporary specifies the application of a function to some arguments.
  48  * The functions are method handles, while the arguments are mixes of
  49  * constant values and local names.
  50  * The result of the lambda is defined as one of the names, often the last one.
  51  * <p>
  52  * Here is an approximate grammar:
  53  * <pre>
  54  * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
  55  * ArgName = "a" N ":" T
  56  * TempName = "t" N ":" T "=" Function "(" Argument* ");"


 103  * (a0:L, a1:L)=>{ t2:L = FilterMethodHandle#filter(a0);
 104  *                 t3:L = MethodHandle#invoke(t2, a1);
 105  *                 t4:L = FilterMethodHandle#target(a0);
 106  *                 t5:L = MethodHandle#invoke(t4, t3); t5 }
 107  *     == general invoker for unary filterArgument combination
 108  * (a0:L, a1:L)=>{ ...(same as previous example)...
 109  *                 t5:L = MethodHandle#invoke(t4, t3, a1); t5 }
 110  *     == general invoker for unary/unary foldArgument combination
 111  * (a0:L, a1:I)=>{ t2:I = identity(long).asType((int)->long)(a1); t2 }
 112  *     == invoker for identity method handle which performs i2l
 113  * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
 114  *                 t3:L = Class#cast(t2,a1); t3 }
 115  *     == invoker for identity method handle which performs cast
 116  * </pre>
 117  * <p>
 118  * @author John Rose, JSR 292 EG
 119  */
 120 class LambdaForm {
 121     final int arity;
 122     final int result;
 123     final Name[] names;
 124     final String debugName;
 125     MemberName vmentry;   // low-level behavior, or null if not yet prepared
 126     private boolean isCompiled;
 127 
 128     // Caches for common structural transforms:
 129     LambdaForm[] bindCache;
 130 
 131     public static final int VOID_RESULT = -1, LAST_RESULT = -2;
 132 
 133     LambdaForm(String debugName,
 134                int arity, Name[] names, int result) {
 135         assert(namesOK(arity, names));
 136         this.arity = arity;
 137         this.result = fixResult(result, names);
 138         this.names = names.clone();
 139         this.debugName = debugName;
 140         normalize();
 141     }
 142 
 143     LambdaForm(String debugName,


 954                 for (int k = i+1; k < names2.length; k++) {
 955                     names2[k] = names2[k].replaceName(n, n2);
 956                 }
 957             }
 958         }
 959         return new LambdaForm(debugName, arity2, names2, result2);
 960     }
 961 
 962     static boolean permutedTypesMatch(int[] reorder, char[] types, Name[] names, int skip) {
 963         int inTypes = types.length;
 964         int outArgs = reorder.length;
 965         for (int i = 0; i < outArgs; i++) {
 966             assert(names[skip+i].isParam());
 967             assert(names[skip+i].type == types[reorder[i]]);
 968         }
 969         return true;
 970     }
 971 
 972     static class NamedFunction {
 973         final MemberName member;
 974         MethodHandle resolvedHandle;
 975         MethodHandle invoker;
 976 
 977         NamedFunction(MethodHandle resolvedHandle) {
 978             this(resolvedHandle.internalMemberName(), resolvedHandle);
 979         }
 980         NamedFunction(MemberName member, MethodHandle resolvedHandle) {
 981             this.member = member;
 982             //resolvedHandle = eraseSubwordTypes(resolvedHandle);
 983             this.resolvedHandle = resolvedHandle;
 984         }
 985 
 986         // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc.
 987         // Any LambdaForm containing such a member is not interpretable.
 988         // This is OK, since all such LFs are prepared with special primitive vmentry points.
 989         // And even without the resolvedHandle, the name can still be compiled and optimized.
 990         NamedFunction(Method method) {
 991             this(new MemberName(method));
 992         }
 993         NamedFunction(Field field) {
 994             this(new MemberName(field));
 995         }


1250             btypes[i] = basicType(types.get(i));
1251         }
1252         return btypes;
1253     }
1254     public static String basicTypeSignature(MethodType type) {
1255         char[] sig = new char[type.parameterCount() + 2];
1256         int sigp = 0;
1257         for (Class<?> pt : type.parameterList()) {
1258             sig[sigp++] = basicType(pt);
1259         }
1260         sig[sigp++] = '_';
1261         sig[sigp++] = basicType(type.returnType());
1262         assert(sigp == sig.length);
1263         return String.valueOf(sig);
1264     }
1265 
1266     static final class Name {
1267         final char type;
1268         private short index;
1269         final NamedFunction function;
1270         final Object[] arguments;
1271 
1272         private Name(int index, char type, NamedFunction function, Object[] arguments) {
1273             this.index = (short)index;
1274             this.type = type;
1275             this.function = function;
1276             this.arguments = arguments;
1277             assert(this.index == index);
1278         }
1279         Name(MethodHandle function, Object... arguments) {
1280             this(new NamedFunction(function), arguments);
1281         }
1282         Name(MemberName function, Object... arguments) {
1283             this(new NamedFunction(function), arguments);
1284         }
1285         Name(NamedFunction function, Object... arguments) {
1286             this(-1, function.returnType(), function, arguments = arguments.clone());
1287             assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString();
1288             for (int i = 0; i < arguments.length; i++)
1289                 assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString();
1290         }




  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import java.lang.annotation.*;
  29 import java.lang.reflect.Method;
  30 import java.util.Map;
  31 import java.util.List;
  32 import java.util.Arrays;
  33 import java.util.ArrayList;
  34 import java.util.HashMap;
  35 import java.util.concurrent.ConcurrentHashMap;
  36 import sun.invoke.util.Wrapper;
  37 import sun.invoke.Stable;
  38 import static java.lang.invoke.MethodHandleStatics.*;
  39 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  40 import java.lang.reflect.Field;
  41 import java.util.Objects;
  42 
  43 /**
  44  * The symbolic, non-executable form of a method handle's invocation semantics.
  45  * It consists of a series of names.
  46  * The first N (N=arity) names are parameters,
  47  * while any remaining names are temporary values.
  48  * Each temporary specifies the application of a function to some arguments.
  49  * The functions are method handles, while the arguments are mixes of
  50  * constant values and local names.
  51  * The result of the lambda is defined as one of the names, often the last one.
  52  * <p>
  53  * Here is an approximate grammar:
  54  * <pre>
  55  * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
  56  * ArgName = "a" N ":" T
  57  * TempName = "t" N ":" T "=" Function "(" Argument* ");"


 104  * (a0:L, a1:L)=>{ t2:L = FilterMethodHandle#filter(a0);
 105  *                 t3:L = MethodHandle#invoke(t2, a1);
 106  *                 t4:L = FilterMethodHandle#target(a0);
 107  *                 t5:L = MethodHandle#invoke(t4, t3); t5 }
 108  *     == general invoker for unary filterArgument combination
 109  * (a0:L, a1:L)=>{ ...(same as previous example)...
 110  *                 t5:L = MethodHandle#invoke(t4, t3, a1); t5 }
 111  *     == general invoker for unary/unary foldArgument combination
 112  * (a0:L, a1:I)=>{ t2:I = identity(long).asType((int)->long)(a1); t2 }
 113  *     == invoker for identity method handle which performs i2l
 114  * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
 115  *                 t3:L = Class#cast(t2,a1); t3 }
 116  *     == invoker for identity method handle which performs cast
 117  * </pre>
 118  * <p>
 119  * @author John Rose, JSR 292 EG
 120  */
 121 class LambdaForm {
 122     final int arity;
 123     final int result;
 124     @Stable final Name[] names;
 125     final String debugName;
 126     MemberName vmentry;   // low-level behavior, or null if not yet prepared
 127     private boolean isCompiled;
 128 
 129     // Caches for common structural transforms:
 130     LambdaForm[] bindCache;
 131 
 132     public static final int VOID_RESULT = -1, LAST_RESULT = -2;
 133 
 134     LambdaForm(String debugName,
 135                int arity, Name[] names, int result) {
 136         assert(namesOK(arity, names));
 137         this.arity = arity;
 138         this.result = fixResult(result, names);
 139         this.names = names.clone();
 140         this.debugName = debugName;
 141         normalize();
 142     }
 143 
 144     LambdaForm(String debugName,


 955                 for (int k = i+1; k < names2.length; k++) {
 956                     names2[k] = names2[k].replaceName(n, n2);
 957                 }
 958             }
 959         }
 960         return new LambdaForm(debugName, arity2, names2, result2);
 961     }
 962 
 963     static boolean permutedTypesMatch(int[] reorder, char[] types, Name[] names, int skip) {
 964         int inTypes = types.length;
 965         int outArgs = reorder.length;
 966         for (int i = 0; i < outArgs; i++) {
 967             assert(names[skip+i].isParam());
 968             assert(names[skip+i].type == types[reorder[i]]);
 969         }
 970         return true;
 971     }
 972 
 973     static class NamedFunction {
 974         final MemberName member;
 975         @Stable MethodHandle resolvedHandle;
 976         @Stable MethodHandle invoker;
 977 
 978         NamedFunction(MethodHandle resolvedHandle) {
 979             this(resolvedHandle.internalMemberName(), resolvedHandle);
 980         }
 981         NamedFunction(MemberName member, MethodHandle resolvedHandle) {
 982             this.member = member;
 983             //resolvedHandle = eraseSubwordTypes(resolvedHandle);
 984             this.resolvedHandle = resolvedHandle;
 985         }
 986 
 987         // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc.
 988         // Any LambdaForm containing such a member is not interpretable.
 989         // This is OK, since all such LFs are prepared with special primitive vmentry points.
 990         // And even without the resolvedHandle, the name can still be compiled and optimized.
 991         NamedFunction(Method method) {
 992             this(new MemberName(method));
 993         }
 994         NamedFunction(Field field) {
 995             this(new MemberName(field));
 996         }


1251             btypes[i] = basicType(types.get(i));
1252         }
1253         return btypes;
1254     }
1255     public static String basicTypeSignature(MethodType type) {
1256         char[] sig = new char[type.parameterCount() + 2];
1257         int sigp = 0;
1258         for (Class<?> pt : type.parameterList()) {
1259             sig[sigp++] = basicType(pt);
1260         }
1261         sig[sigp++] = '_';
1262         sig[sigp++] = basicType(type.returnType());
1263         assert(sigp == sig.length);
1264         return String.valueOf(sig);
1265     }
1266 
1267     static final class Name {
1268         final char type;
1269         private short index;
1270         final NamedFunction function;
1271         @Stable final Object[] arguments;
1272 
1273         private Name(int index, char type, NamedFunction function, Object[] arguments) {
1274             this.index = (short)index;
1275             this.type = type;
1276             this.function = function;
1277             this.arguments = arguments;
1278             assert(this.index == index);
1279         }
1280         Name(MethodHandle function, Object... arguments) {
1281             this(new NamedFunction(function), arguments);
1282         }
1283         Name(MemberName function, Object... arguments) {
1284             this(new NamedFunction(function), arguments);
1285         }
1286         Name(NamedFunction function, Object... arguments) {
1287             this(-1, function.returnType(), function, arguments = arguments.clone());
1288             assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString();
1289             for (int i = 0; i < arguments.length; i++)
1290                 assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString();
1291         }


jdk/src/share/classes/java/lang/invoke/LambdaForm.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File