Details
Backports
Issue  Fix Version  Assignee  Priority  Status  Resolution  Resolved In Build 

JDK8085768  emb9  Attila Szegedi  P3  Resolved  Fixed  team 
JDK8065517  8u45  Attila Szegedi  P3  Resolved  Fixed  b01 
JDK8062733  8u40  Attila Szegedi  P3  Resolved  Fixed  b15 
JDK8070505  emb8u47  Attila Szegedi  P3  Resolved  Fixed  team 
Description
(x + y) (with x and y being ints), when they result is coerced to int (e.g. if used as (x + y) >> 1) should be simply emitted as:
ILOAD x
ILOAD y
IADD
As coercing the result to int will mask any overflow, so overflows are in this case okay. Unfortunately, what we see instead is
ILOAD x
I2L
ILOAD y
I2L
LADD
JSType.toInt32(J)I
which is especially problematic as toInt32 is a bit slower as it has special handling for long values with magnitude over 2^53.
Similarly, integer division and modulo operations, when their result is itself coerced to int will end up being
ILOAD x
I2D
ILOAD y
I2D
DDIV (or DREM)
JSType.toInt32(D)I
where toInt32 is similarly costly due to special semantics for values larger than 2^53 (that, nevertheless, can never manifest themselves here).
It's important to note though that we can't just naively replace the above with:
ILOAD x
ILOAD y
IDIV (or IREM)
because in the special case of y == 0, JS semantics requires a 0 value as (x/0)0 === 0 in JS, while IDIV and IREM throw an ArithmeticException for dividing by zero. For this reason, we need methods in JSType named divZero and remZero that'll handle this special case, and rather emit
ILOAD x
ILOAD y
INVOKESTATIC JSType.divZero(II)I (or remZero)
(Finally, multiplication and subtraction don't suffer from these issues.)
ILOAD x
ILOAD y
IADD
As coercing the result to int will mask any overflow, so overflows are in this case okay. Unfortunately, what we see instead is
ILOAD x
I2L
ILOAD y
I2L
LADD
JSType.toInt32(J)I
which is especially problematic as toInt32 is a bit slower as it has special handling for long values with magnitude over 2^53.
Similarly, integer division and modulo operations, when their result is itself coerced to int will end up being
ILOAD x
I2D
ILOAD y
I2D
DDIV (or DREM)
JSType.toInt32(D)I
where toInt32 is similarly costly due to special semantics for values larger than 2^53 (that, nevertheless, can never manifest themselves here).
It's important to note though that we can't just naively replace the above with:
ILOAD x
ILOAD y
IDIV (or IREM)
because in the special case of y == 0, JS semantics requires a 0 value as (x/0)0 === 0 in JS, while IDIV and IREM throw an ArithmeticException for dividing by zero. For this reason, we need methods in JSType named divZero and remZero that'll handle this special case, and rather emit
ILOAD x
ILOAD y
INVOKESTATIC JSType.divZero(II)I (or remZero)
(Finally, multiplication and subtraction don't suffer from these issues.)
Attachments
Issue Links
 backported by

JDK8062733 Some arithmetic operations have unnecessary widening
 Resolved

JDK8065517 Some arithmetic operations have unnecessary widening
 Resolved

JDK8070505 Some arithmetic operations have unnecessary widening
 Resolved

JDK8085768 Some arithmetic operations have unnecessary widening
 Resolved