JDK-8153637 : MethodHandles.countedLoop/3 initialises loop counter to 1 instead of 0
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang.invoke
  • Affected Version: 9
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • Submitted: 2016-04-06
  • Updated: 2017-05-17
  • Resolved: 2016-04-13
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b115Fixed
Related Reports
Relates :  
Description
A loop corresponding to the following code should return 10:

int x = 0; for (int i = 0; i < 5; ++i) { x += i; } return x;

However, the loop assembled as follows returns 15:

MethodHandle iter = MethodHandles.constant(int.class, 5);
MethodHandle init = MethodHandles.constant(int.class, 0);
MethodHandle body = ...; // handle to a method int m(int c, int x) { return x + c; }
MethodHandle loop = MethodHandles.countedLoop(iter, init, body);
assertEquals(10, loop.invoke());

The reason for this is that the MHs.countedLoop/3 combinator indeed initialises the loop counter to 0, but increments it right away before the first invocation of the body handle. This should be fixable by reordering clauses, or by initialising the counter to -1.
Comments
The cleanest solution is to decrement the counter when it is passed into the body. Alternatives: * decrement counter upon initialisation - there might be cases where looping should start at very small numbers * reorder clauses to move counter update to the end of the loop - requires permutation of arguments
11-04-2016