--- old/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java 2015-01-20 21:59:45.000000000 +0300 +++ new/src/java.base/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java 2015-01-20 21:59:45.000000000 +0300 @@ -616,6 +616,17 @@ return g.loadMethod(g.generateCustomizedCodeBytes()); } + /** Determines whether a LambdaForm being compiled contains an intrinsic of some particular type. */ + private boolean containsIntrinsic(MethodHandleImpl.Intrinsic intr) { + for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) { + Name name = lambdaForm.names[i]; + if (name.function.intrinsicName() == intr) { + return true; + } + } + return false; + } + /** * Generate an invoker method for the passed {@link LambdaForm}. */ @@ -628,6 +639,12 @@ // Mark this method as a compiled LambdaForm mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true); + if (PROFILE_GWT && containsIntrinsic(MethodHandleImpl.Intrinsic.SELECT_ALTERNATIVE)) { + // For now, mark only GWT LambdaForms as @Shared. + // TODO: consider marking other non-customized LambdaForms as @Shared + mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Shared;", true); + } + if (lambdaForm.forceInline) { // Force inlining of this invoker method. mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true); @@ -635,7 +652,6 @@ mv.visitAnnotation("Ljava/lang/invoke/DontInline;", true); } - // iterate over the form's names, generating bytecode instructions for each // start iterating at the first name following the arguments Name onStack = null; @@ -1005,6 +1021,11 @@ // load test result emitPushArgument(selectAlternativeName, 0); + if (PROFILE_GWT) { + emitPushArgument(selectAlternativeName, 3); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, MHI, "profileBranch", "(Z[I)Z", false); + } + // if_icmpne L_fallback mv.visitJumpInsn(Opcodes.IFEQ, L_fallback);