-
Sub-task
-
Resolution: Fixed
-
P3
-
8u40
-
b39
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8085768 | emb-9 | Attila Szegedi | P3 | Resolved | Fixed | team |
JDK-8065517 | 8u45 | Attila Szegedi | P3 | Resolved | Fixed | b01 |
JDK-8062733 | 8u40 | Attila Szegedi | P3 | Resolved | Fixed | b15 |
JDK-8070505 | emb-8u47 | Attila Szegedi | P3 | Resolved | Fixed | team |
(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.)
- backported by
-
JDK-8062733 Some arithmetic operations have unnecessary widening
-
- Resolved
-
-
JDK-8065517 Some arithmetic operations have unnecessary widening
-
- Resolved
-
-
JDK-8070505 Some arithmetic operations have unnecessary widening
-
- Resolved
-
-
JDK-8085768 Some arithmetic operations have unnecessary widening
-
- Resolved
-