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

[Lilliput/JDK17] Optimize anonymous owner fix-up path

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Fixed
    • Icon: P4 P4
    • repo-lilliput
    • repo-lilliput
    • hotspot
    • None
    • x86, x86_64, aarch64
    • generic

      This relates to the fast-locking implementation that is used in Lilliput. When exiting an ObjectMonitor, we need to check if that monitor is owned 'anonymously' (that means, another thread inflated that monitor and because it doesn't know who is the owner, it sets the owner to anonymous. The exiting thread knows that it must be itself, and needs to fix the owner and properly exit it). In the C2 fast-path of unlocking, we need to deal with this. Current solution is rather clunky:

           Label L;
            __ ldr(disp_hdr, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
            __ cmp(disp_hdr, (unsigned char)(intptr_t) ANONYMOUS_OWNER);
            __ br(Assembler::NE, L);
            __ tst(oop, oop); // Indicate failure at cont -- dive into slow-path.
            __ b(cont);
            __ bind(L);

      In other words, it checks for ANONYMOUS_OWNER, and branches to a label if not equal, and otherwise jumps to the end of the locking. The reason why we need to do this is because the C2 locking code is peculiar: at the exit of the code block, if zero-flag is set, it means the locking was successful, otherwise (if ZF=0), it branches out into the slow-path. (This part is implemented in C2 IR. Yes, it is very ugly.)

      This is not only ugly but also a performance concern: Static branch prediction in most CPUs expect forward branches to be not taken, and the fall-through path to be taken, and hence this would cause misprediction on the branch.

      With a little bit of changing around the ANONYMOUS_OWNER and DEFLATER_MARKER, we can change the code to much simpler version:

            __ ldr(disp_hdr, Address(tmp, ObjectMonitor::owner_offset_in_bytes()));
            __ tbnz(disp_hdr, (unsigned char)(intptr_t) ANONYMOUS_OWNER, cont);

      This only branches out when the owner is anonymous *AND* exits correctly with ZF=0 to indicate failure. The prerequisite is that DEFLATER_MARKER must not have its lowest bit set. I changed that marker to just '2'. It fullfills the two prerequisites: It must not be a valid pointer and it must not have its lowest bit set.

      The big advantage is that this doesn't mispredict and is thus more efficient.

            rkennke Roman Kennke
            rkennke Roman Kennke
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: