XMLWordPrintable

    • Icon: Sub-task Sub-task
    • Resolution: Fixed
    • Icon: P3 P3
    • 9
    • 8u40
    • core-libs
    • b39
    • generic
    • generic

        (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.)

              attila Attila Szegedi
              attila Attila Szegedi
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: