Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8184271

Time related C1 intrinsics produce inconsistent results when floating around

    Details

    • Subcomponent:
    • Resolved In Build:
      b21
    • Verification:
      Verified

      Backports

        Description

        FULL PRODUCT VERSION :
        java version "1.8.0_131"
        Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
        Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

        FULL OS VERSION :
        - RHEL 7.3 Linux xxx.gs.com 3.10.0-514.16.1.el7.x86_64 #1 SMP Fri Mar 10 13:12:32 EST 2017 x86_64 x86_64 x86_64 GNU/Linux
        - Ubuntu 17.10 with 4.12 kernel
        - This is platform-agnostic

        A DESCRIPTION OF THE PROBLEM :
        C1 emits instructions in a sequence that violates program order when performing OSR + inlining code from the affected method.
        This seems to be a subtle edge-case as referring the impacted value in checkResult() or using assert instead of "if" results in correct behavior.
        Looking at the sequence of instructions emitted by C1 in this case (with PrintAssembly) clearly shows that C2 code produces valid instruction order whereas C1 does not.
        Reducing inline level to 1 or disabling tiered compilation results in correct program behavior.

        THE PROBLEM WAS REPRODUCIBLE WITH -Xint FLAG: No

        THE PROBLEM WAS REPRODUCIBLE WITH -server FLAG: Yes

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Just run the following class with default java args.
        It is also reproducible with manually inlined timeInvocation() + local variables inlined, but the provided example is clearer to work with.


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        Should exit without printing anything.
        Prints "should not get here ..." contrary to the expected behavior. Neither javac nor any of the JIT compilers should reorder capturing nanoTime value as there is a direct data dependency on the result of their subtraction.
        The fact that System.nanoTime() return monotonic values guarantees result consistency.
        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        public class C1_OSR_Inline_Bug {

            public static void main(String[] args) {
                for (int i = 0; i < 100_000; i++) {
                    timeInvocation();
                }
            }

            private static void timeInvocation() {
                final long start = System.nanoTime();
                final long end = System.nanoTime();
                checkResult(end - start);
            }

            private static void checkResult(final long l) {
                if (l < 0) {
                    System.out.println("should not get here " + l); // removing reference to l parameter here "fixes" the bug
                    System.exit(0);
                }
            }
        }

        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        Reducing inline level to 1 or disabling tiered compilation result in correct program behavior.
        The same applies to running in interpreted mode.

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  thartmann Tobias Hartmann
                  Reporter:
                  webbuggrp Webbug Group
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  7 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: