JDK-8152559 : MethodHandles.countedLoop(MH, MH, MH, MH) implementation doesn't fit 'implementation requirements'
  • Type: Sub-task
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-03-23
  • Updated: 2016-04-26
  • Resolved: 2016-04-26
Description
According to documentation,
The implementation of this method is equivalent to:

 MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
     MethodHandle returnVar = dropArguments(identity(init.type().returnType()), 0, int.class, int.class);
     // assume MH_increment and MH_lessThan are handles to x+1 and x<y of type int
     MethodHandle[]
         indexVar = {start, MH_increment}, // i = start; i = i+1
         loopLimit = {end, null, MH_lessThan, returnVar }, // i<end
         bodyClause = {init, dropArguments(body, 1, int.class)};  // v = body(i, v);
     return loop(indexVar, loopLimit, bodyClause);
 }

Please, observe attached example. In this example handles for 'x+1' and 'x+y' was created as f(x) and f(x,y). In the case of 'prohibited' functions combination, they throws IAE. But these exceptions have slightly different messages:

found non-effectively identical parameter type lists:
step: [MethodHandle(int,int)int, null, MethodHandle(Lambdaman,int,int)String]
pred: [null, MethodHandle(int,int)boolean, null]
fini: [null, MethodHandle(int,int,String)String, null] (common parameter sequence: [int, int, class java.lang.String, class java.lang.String])



and


found non-effectively identical parameter type lists:
step: [MethodHandle(int)int, null, MethodHandle(Lambdaman,int,int)String]
pred: [null, MethodHandle(int,int)boolean, null]

The difference is in the first argument list of 'step'.

Current jdk9 implementation reference to 'x+1' is f(x,limit)=x+1. It seems this is the origin of difference. 
So, 'implementation requirements' code is not  equals to jdk9 implementation. 

Was found on jdk9b108, jdk9b109, jdk9b110.
Test development in progress, tck_red will be added after test development is completed.
Example is in attachment.
Comments
The following implSpec section (to replace the original one for MHs.countedLoop/4) addresses this issue. This will be pushed with JDK-8151179. * @implSpec The implementation of this method is equivalent to (excluding error handling): * <blockquote><pre>{@code * MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) { * MethodHandle returnVar = dropArguments(identity(init.type().returnType()), 0, int.class, int.class); * // assume MH_increment, MH_predicate, and MH_decrement are handles to implementation-internal methods with * // the following semantics: * // MH_increment: (int counter, int limit) -> counter + 1 * // MH_predicate: (int counter, int limit) -> x <= y * // MH_decrement: (int x) -> x - 1 * MethodHandle[] * indexVar = {start, MH_increment}, // i = start; i = i+1 * loopLimit = {end, null, MH_predicate, returnVar }, // i<end * bodyClause = {init, * filterArgument(dropArguments(body, 1, int.class), 0, MH_decrement}; // v = body(i-1, v) * return loop(indexVar, loopLimit, bodyClause); * } * }</pre></blockquote>
26-04-2016