8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
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 jdk.internal.vm.annotation.DontInline;
29 import jdk.internal.vm.annotation.Stable;
30 import sun.invoke.util.Wrapper;
31
32 import java.lang.annotation.ElementType;
33 import java.lang.annotation.Retention;
34 import java.lang.annotation.RetentionPolicy;
35 import java.lang.annotation.Target;
36 import java.lang.reflect.Method;
37 import java.util.Arrays;
38 import java.util.HashMap;
39
40 import static java.lang.invoke.LambdaForm.BasicType.*;
41 import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
42 import static java.lang.invoke.MethodHandleStatics.debugEnabled;
43 import static java.lang.invoke.MethodHandleStatics.newInternalError;
44
45 /**
46 * The symbolic, non-executable form of a method handle's invocation semantics.
47 * It consists of a series of names.
48 * The first N (N=arity) names are parameters,
49 * while any remaining names are temporary values.
50 * Each temporary specifies the application of a function to some arguments.
51 * The functions are method handles, while the arguments are mixes of
52 * constant values and local names.
53 * The result of the lambda is defined as one of the names, often the last one.
54 * <p>
55 * Here is an approximate grammar:
56 * <blockquote><pre>{@code
57 * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
58 * ArgName = "a" N ":" T
59 * TempName = "t" N ":" T "=" Function "(" Argument* ");"
60 * Function = ConstantValue
61 * Argument = NameRef | ConstantValue
62 * Result = NameRef | "void"
63 * NameRef = "a" N | "t" N
379 return buf.toString();
380 }
381 return debugName;
382 }
383
384 private static boolean namesOK(int arity, Name[] names) {
385 for (int i = 0; i < names.length; i++) {
386 Name n = names[i];
387 assert(n != null) : "n is null";
388 if (i < arity)
389 assert( n.isParam()) : n + " is not param at " + i;
390 else
391 assert(!n.isParam()) : n + " is param at " + i;
392 }
393 return true;
394 }
395
396 /** Customize LambdaForm for a particular MethodHandle */
397 LambdaForm customize(MethodHandle mh) {
398 LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh);
399 if (COMPILE_THRESHOLD > 0 && isCompiled) {
400 // If shared LambdaForm has been compiled, compile customized version as well.
401 customForm.compileToBytecode();
402 }
403 customForm.transformCache = this; // LambdaFormEditor should always use uncustomized form.
404 return customForm;
405 }
406
407 /** Get uncustomized flavor of the LambdaForm */
408 LambdaForm uncustomize() {
409 if (customized == null) {
410 return this;
411 }
412 assert(transformCache != null); // Customized LambdaForm should always has a link to uncustomized version.
413 LambdaForm uncustomizedForm = (LambdaForm)transformCache;
414 if (COMPILE_THRESHOLD > 0 && isCompiled) {
415 // If customized LambdaForm has been compiled, compile uncustomized version as well.
416 uncustomizedForm.compileToBytecode();
417 }
418 return uncustomizedForm;
419 }
420
421 /** Renumber and/or replace params so that they are interned and canonically numbered.
422 * @return maximum argument list length among the names (since we have to pass over them anyway)
423 */
424 private int normalize() {
425 Name[] oldNames = null;
426 int maxOutArity = 0;
427 int changesStart = 0;
428 for (int i = 0; i < names.length; i++) {
429 Name n = names[i];
430 if (!n.initIndex(i)) {
431 if (oldNames == null) {
432 oldNames = names.clone();
433 changesStart = i;
434 }
700 * a generic LF with a more specialized one, on the same MH,
701 * if (a) the MH is frequently executed and (b) the MH cannot
702 * be inlined into a containing caller, such as an invokedynamic.
703 *
704 * Compiled LFs that are no longer used should be GC-able.
705 * If they contain non-BCP references, they should be properly
706 * interlinked with the class loader(s) that their embedded types
707 * depend on. This probably means that reusable compiled LFs
708 * will be tabulated (indexed) on relevant class loaders,
709 * or else that the tables that cache them will have weak links.
710 */
711
712 /**
713 * Make this LF directly executable, as part of a MethodHandle.
714 * Invariant: Every MH which is invoked must prepare its LF
715 * before invocation.
716 * (In principle, the JVM could do this very lazily,
717 * as a sort of pre-invocation linkage step.)
718 */
719 public void prepare() {
720 if (COMPILE_THRESHOLD == 0 && !isCompiled) {
721 compileToBytecode();
722 }
723 if (this.vmentry != null) {
724 // already prepared (e.g., a primitive DMH invoker form)
725 return;
726 }
727 MethodType mtype = methodType();
728 LambdaForm prep = mtype.form().cachedLambdaForm(MethodTypeForm.LF_INTERPRET);
729 if (prep == null) {
730 assert (isValidSignature(basicTypeSignature()));
731 prep = new LambdaForm(mtype);
732 prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(mtype);
733 prep = mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep);
734 }
735 this.vmentry = prep.vmentry;
736 // TO DO: Maybe add invokeGeneric, invokeWithArguments
737 }
738
739 /** Generate optimizable bytecode for this form. */
740 MemberName compileToBytecode() {
741 if (vmentry != null && isCompiled) {
742 return vmentry; // already compiled somehow
743 }
744 MethodType invokerType = methodType();
745 assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType));
746 try {
747 vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this, invokerType);
748 if (TRACE_INTERPRETER)
749 traceInterpreter("compileToBytecode", this);
750 isCompiled = true;
751 return vmentry;
752 } catch (Error | Exception ex) {
753 throw newInternalError(this.toString(), ex);
754 }
755 }
756
757 private static void computeInitialPreparedForms() {
758 // Find all predefined invokers and associate them with canonical empty lambda forms.
759 for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {
760 if (!m.isStatic() || !m.isPackage()) continue;
761 MethodType mt = m.getMethodType();
762 if (mt.parameterCount() > 0 &&
763 mt.parameterType(0) == MethodHandle.class &&
764 m.getName().startsWith("interpret_")) {
765 String sig = null;
766 assert((sig = basicTypeSignature(mt)) != null &&
767 m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
768 LambdaForm form = new LambdaForm(mt);
769 form.vmentry = m;
770 form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form);
771 }
772 }
773 }
839 private static boolean checkInt(Class<?> type, Object x) {
840 assert(x instanceof Integer);
841 if (type == int.class) return true;
842 Wrapper w = Wrapper.forBasicType(type);
843 assert(w.isSubwordOrInt());
844 Object x1 = Wrapper.INT.wrap(w.wrap(x));
845 return x.equals(x1);
846 }
847 private static boolean checkRef(Class<?> type, Object x) {
848 assert(!type.isPrimitive());
849 if (x == null) return true;
850 if (type.isInterface()) return true;
851 return type.isInstance(x);
852 }
853
854 /** If the invocation count hits the threshold we spin bytecodes and call that subsequently. */
855 private static final int COMPILE_THRESHOLD;
856 static {
857 COMPILE_THRESHOLD = Math.max(-1, MethodHandleStatics.COMPILE_THRESHOLD);
858 }
859 private int invocationCounter = 0;
860
861 @Hidden
862 @DontInline
863 /** Interpretively invoke this form on the given arguments. */
864 Object interpretWithArguments(Object... argumentValues) throws Throwable {
865 if (TRACE_INTERPRETER)
866 return interpretWithArgumentsTracing(argumentValues);
867 checkInvocationCounter();
868 assert(arityCheck(argumentValues));
869 Object[] values = Arrays.copyOf(argumentValues, names.length);
870 for (int i = argumentValues.length; i < values.length; i++) {
871 values[i] = interpretName(names[i], values);
872 }
873 Object rv = (result < 0) ? null : values[result];
874 assert(resultCheck(argumentValues, rv));
875 return rv;
876 }
877
878 @Hidden
879 @DontInline
880 /** Evaluate a single Name within this form, applying its function to its arguments. */
881 Object interpretName(Name name, Object[] values) throws Throwable {
882 if (TRACE_INTERPRETER)
883 traceInterpreter("| interpretName", name.debugString(), (Object[]) null);
884 Object[] arguments = Arrays.copyOf(name.arguments, name.arguments.length, Object[].class);
885 for (int i = 0; i < arguments.length; i++) {
886 Object a = arguments[i];
887 if (a instanceof Name) {
888 int i2 = ((Name)a).index();
889 assert(names[i2] == a);
890 a = values[i2];
891 arguments[i] = a;
892 }
893 }
894 return name.function.invokeWithArguments(arguments);
895 }
896
897 private void checkInvocationCounter() {
898 if (COMPILE_THRESHOLD != 0 &&
899 invocationCounter < COMPILE_THRESHOLD) {
900 invocationCounter++; // benign race
901 if (invocationCounter >= COMPILE_THRESHOLD) {
902 // Replace vmentry with a bytecode version of this LF.
903 compileToBytecode();
904 }
905 }
906 }
907 Object interpretWithArgumentsTracing(Object... argumentValues) throws Throwable {
908 traceInterpreter("[ interpretWithArguments", this, argumentValues);
909 if (invocationCounter < COMPILE_THRESHOLD) {
910 int ctr = invocationCounter++; // benign race
911 traceInterpreter("| invocationCounter", ctr);
912 if (invocationCounter >= COMPILE_THRESHOLD) {
913 compileToBytecode();
914 }
915 }
916 Object rval;
917 try {
918 assert(arityCheck(argumentValues));
919 Object[] values = Arrays.copyOf(argumentValues, names.length);
920 for (int i = argumentValues.length; i < values.length; i++) {
921 values[i] = interpretName(names[i], values);
922 }
923 rval = (result < 0) ? null : values[result];
924 } catch (Throwable ex) {
925 traceInterpreter("] throw =>", ex);
926 throw ex;
927 }
928 traceInterpreter("] return =>", rval);
929 return rval;
|
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
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 jdk.internal.perf.PerfCounter;
29 import jdk.internal.vm.annotation.DontInline;
30 import jdk.internal.vm.annotation.Stable;
31 import sun.invoke.util.Wrapper;
32
33 import java.lang.annotation.ElementType;
34 import java.lang.annotation.Retention;
35 import java.lang.annotation.RetentionPolicy;
36 import java.lang.annotation.Target;
37 import java.lang.reflect.Method;
38 import java.util.Arrays;
39 import java.util.HashMap;
40
41 import static java.lang.invoke.LambdaForm.BasicType.*;
42 import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
43 import static java.lang.invoke.MethodHandleStatics.*;
44
45 /**
46 * The symbolic, non-executable form of a method handle's invocation semantics.
47 * It consists of a series of names.
48 * The first N (N=arity) names are parameters,
49 * while any remaining names are temporary values.
50 * Each temporary specifies the application of a function to some arguments.
51 * The functions are method handles, while the arguments are mixes of
52 * constant values and local names.
53 * The result of the lambda is defined as one of the names, often the last one.
54 * <p>
55 * Here is an approximate grammar:
56 * <blockquote><pre>{@code
57 * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
58 * ArgName = "a" N ":" T
59 * TempName = "t" N ":" T "=" Function "(" Argument* ");"
60 * Function = ConstantValue
61 * Argument = NameRef | ConstantValue
62 * Result = NameRef | "void"
63 * NameRef = "a" N | "t" N
379 return buf.toString();
380 }
381 return debugName;
382 }
383
384 private static boolean namesOK(int arity, Name[] names) {
385 for (int i = 0; i < names.length; i++) {
386 Name n = names[i];
387 assert(n != null) : "n is null";
388 if (i < arity)
389 assert( n.isParam()) : n + " is not param at " + i;
390 else
391 assert(!n.isParam()) : n + " is param at " + i;
392 }
393 return true;
394 }
395
396 /** Customize LambdaForm for a particular MethodHandle */
397 LambdaForm customize(MethodHandle mh) {
398 LambdaForm customForm = new LambdaForm(debugName, arity, names, result, forceInline, mh);
399 if (COMPILE_THRESHOLD >= 0 && isCompiled) {
400 // If shared LambdaForm has been compiled, compile customized version as well.
401 customForm.compileToBytecode();
402 }
403 customForm.transformCache = this; // LambdaFormEditor should always use uncustomized form.
404 return customForm;
405 }
406
407 /** Get uncustomized flavor of the LambdaForm */
408 LambdaForm uncustomize() {
409 if (customized == null) {
410 return this;
411 }
412 assert(transformCache != null); // Customized LambdaForm should always has a link to uncustomized version.
413 LambdaForm uncustomizedForm = (LambdaForm)transformCache;
414 if (COMPILE_THRESHOLD >= 0 && isCompiled) {
415 // If customized LambdaForm has been compiled, compile uncustomized version as well.
416 uncustomizedForm.compileToBytecode();
417 }
418 return uncustomizedForm;
419 }
420
421 /** Renumber and/or replace params so that they are interned and canonically numbered.
422 * @return maximum argument list length among the names (since we have to pass over them anyway)
423 */
424 private int normalize() {
425 Name[] oldNames = null;
426 int maxOutArity = 0;
427 int changesStart = 0;
428 for (int i = 0; i < names.length; i++) {
429 Name n = names[i];
430 if (!n.initIndex(i)) {
431 if (oldNames == null) {
432 oldNames = names.clone();
433 changesStart = i;
434 }
700 * a generic LF with a more specialized one, on the same MH,
701 * if (a) the MH is frequently executed and (b) the MH cannot
702 * be inlined into a containing caller, such as an invokedynamic.
703 *
704 * Compiled LFs that are no longer used should be GC-able.
705 * If they contain non-BCP references, they should be properly
706 * interlinked with the class loader(s) that their embedded types
707 * depend on. This probably means that reusable compiled LFs
708 * will be tabulated (indexed) on relevant class loaders,
709 * or else that the tables that cache them will have weak links.
710 */
711
712 /**
713 * Make this LF directly executable, as part of a MethodHandle.
714 * Invariant: Every MH which is invoked must prepare its LF
715 * before invocation.
716 * (In principle, the JVM could do this very lazily,
717 * as a sort of pre-invocation linkage step.)
718 */
719 public void prepare() {
720 if (COMPILE_THRESHOLD == 0 && !forceInterpretation() && !isCompiled) {
721 compileToBytecode();
722 }
723 if (this.vmentry != null) {
724 // already prepared (e.g., a primitive DMH invoker form)
725 return;
726 }
727 MethodType mtype = methodType();
728 LambdaForm prep = mtype.form().cachedLambdaForm(MethodTypeForm.LF_INTERPRET);
729 if (prep == null) {
730 assert (isValidSignature(basicTypeSignature()));
731 prep = new LambdaForm(mtype);
732 prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(mtype);
733 prep = mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep);
734 }
735 this.vmentry = prep.vmentry;
736 // TO DO: Maybe add invokeGeneric, invokeWithArguments
737 }
738
739 private static final PerfCounter LF_FAILED =
740 PerfCounter.newPerfCounter("java.lang.invoke.failedLambdaFormCompilations");
741
742 /** Generate optimizable bytecode for this form. */
743 void compileToBytecode() {
744 if (forceInterpretation()) {
745 return; // this should not be compiled
746 }
747 if (vmentry != null && isCompiled) {
748 return; // already compiled somehow
749 }
750 MethodType invokerType = methodType();
751 assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType));
752 try {
753 vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this, invokerType);
754 if (TRACE_INTERPRETER)
755 traceInterpreter("compileToBytecode", this);
756 isCompiled = true;
757 } catch (InvokerBytecodeGenerator.BytecodeGenerationException bge) {
758 // bytecode generation failed - mark this LambdaForm as to be run in interpretation mode only
759 invocationCounter = -1;
760 LF_FAILED.increment();
761 if (LOG_LF_COMPILATION_FAILURE) {
762 System.out.println("LambdaForm compilation failed: " + this);
763 bge.printStackTrace(System.out);
764 }
765 } catch (Error | Exception e) {
766 throw newInternalError(this.toString(), e);
767 }
768 }
769
770 private static void computeInitialPreparedForms() {
771 // Find all predefined invokers and associate them with canonical empty lambda forms.
772 for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {
773 if (!m.isStatic() || !m.isPackage()) continue;
774 MethodType mt = m.getMethodType();
775 if (mt.parameterCount() > 0 &&
776 mt.parameterType(0) == MethodHandle.class &&
777 m.getName().startsWith("interpret_")) {
778 String sig = null;
779 assert((sig = basicTypeSignature(mt)) != null &&
780 m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
781 LambdaForm form = new LambdaForm(mt);
782 form.vmentry = m;
783 form = mt.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, form);
784 }
785 }
786 }
852 private static boolean checkInt(Class<?> type, Object x) {
853 assert(x instanceof Integer);
854 if (type == int.class) return true;
855 Wrapper w = Wrapper.forBasicType(type);
856 assert(w.isSubwordOrInt());
857 Object x1 = Wrapper.INT.wrap(w.wrap(x));
858 return x.equals(x1);
859 }
860 private static boolean checkRef(Class<?> type, Object x) {
861 assert(!type.isPrimitive());
862 if (x == null) return true;
863 if (type.isInterface()) return true;
864 return type.isInstance(x);
865 }
866
867 /** If the invocation count hits the threshold we spin bytecodes and call that subsequently. */
868 private static final int COMPILE_THRESHOLD;
869 static {
870 COMPILE_THRESHOLD = Math.max(-1, MethodHandleStatics.COMPILE_THRESHOLD);
871 }
872 private int invocationCounter = 0; // a value of -1 indicates LambdaForm interpretation mode forever
873
874 private boolean forceInterpretation() {
875 return invocationCounter == -1;
876 }
877
878 @Hidden
879 @DontInline
880 /** Interpretively invoke this form on the given arguments. */
881 Object interpretWithArguments(Object... argumentValues) throws Throwable {
882 if (TRACE_INTERPRETER)
883 return interpretWithArgumentsTracing(argumentValues);
884 checkInvocationCounter();
885 assert(arityCheck(argumentValues));
886 Object[] values = Arrays.copyOf(argumentValues, names.length);
887 for (int i = argumentValues.length; i < values.length; i++) {
888 values[i] = interpretName(names[i], values);
889 }
890 Object rv = (result < 0) ? null : values[result];
891 assert(resultCheck(argumentValues, rv));
892 return rv;
893 }
894
895 @Hidden
896 @DontInline
897 /** Evaluate a single Name within this form, applying its function to its arguments. */
898 Object interpretName(Name name, Object[] values) throws Throwable {
899 if (TRACE_INTERPRETER)
900 traceInterpreter("| interpretName", name.debugString(), (Object[]) null);
901 Object[] arguments = Arrays.copyOf(name.arguments, name.arguments.length, Object[].class);
902 for (int i = 0; i < arguments.length; i++) {
903 Object a = arguments[i];
904 if (a instanceof Name) {
905 int i2 = ((Name)a).index();
906 assert(names[i2] == a);
907 a = values[i2];
908 arguments[i] = a;
909 }
910 }
911 return name.function.invokeWithArguments(arguments);
912 }
913
914 private void checkInvocationCounter() {
915 if (COMPILE_THRESHOLD != 0 &&
916 !forceInterpretation() && invocationCounter < COMPILE_THRESHOLD) {
917 invocationCounter++; // benign race
918 if (invocationCounter >= COMPILE_THRESHOLD) {
919 // Replace vmentry with a bytecode version of this LF.
920 compileToBytecode();
921 }
922 }
923 }
924 Object interpretWithArgumentsTracing(Object... argumentValues) throws Throwable {
925 traceInterpreter("[ interpretWithArguments", this, argumentValues);
926 if (!forceInterpretation() && invocationCounter < COMPILE_THRESHOLD) {
927 int ctr = invocationCounter++; // benign race
928 traceInterpreter("| invocationCounter", ctr);
929 if (invocationCounter >= COMPILE_THRESHOLD) {
930 compileToBytecode();
931 }
932 }
933 Object rval;
934 try {
935 assert(arityCheck(argumentValues));
936 Object[] values = Arrays.copyOf(argumentValues, names.length);
937 for (int i = argumentValues.length; i < values.length; i++) {
938 values[i] = interpretName(names[i], values);
939 }
940 rval = (result < 0) ? null : values[result];
941 } catch (Throwable ex) {
942 traceInterpreter("] throw =>", ex);
943 throw ex;
944 }
945 traceInterpreter("] return =>", rval);
946 return rval;
|