# HG changeset patch
# User Andrew John Hughes <gnu_andrew@member.fsf.org>
# Date 1599349088 -3600
#      Sun Sep 06 00:38:08 2020 +0100
# Node ID b73ff161ed0a57a46fdb3ed51291e39c67d880f5
# Parent  412a170785df4e95fef3622d66910b90ad2245c8
8152358, PR3800: code and comment cleanups found during the hunt for 8077392

diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp openjdk/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
--- openjdk.orig/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	2021-07-16 05:52:52.000000000 +0100
+++ openjdk/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp	2021-07-27 18:21:08.551555444 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -315,7 +315,7 @@
   Register OSR_buf = osrBufferPointer()->as_pointer_register();
   { assert(frame::interpreter_frame_monitor_size() == BasicObjectLock::size(), "adjust code below");
     int monitor_offset = BytesPerWord * method()->max_locals() +
-      (2 * BytesPerWord) * (number_of_locks - 1);
+      (BasicObjectLock::size() * BytesPerWord) * (number_of_locks - 1);
     // SharedRuntime::OSR_migration_begin() packs BasicObjectLocks in
     // the OSR buffer using 2 word entries: first the lock and then
     // the oop.
diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
--- openjdk.orig/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	2021-07-16 05:52:52.000000000 +0100
+++ openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp	2021-07-27 18:21:08.551555444 +0100
@@ -722,7 +722,7 @@
     // Save (object->mark() | 1) into BasicLock's displaced header
     movptr(Address(lock_reg, mark_offset), swap_reg);
 
-    assert(lock_offset == 0, "displached header must be first word in BasicObjectLock");
+    assert(lock_offset == 0, "displaced header must be first word in BasicObjectLock");
     if (os::is_MP()) {
       lock();
     }
@@ -811,7 +811,7 @@
     if (os::is_MP()) lock();
     cmpxchgptr(header_reg, Address(obj_reg, 0));
 
-    // zero for recursive case
+    // zero for simple unlock of a stack-lock case
     jcc(Assembler::zero, done);
 
     // Call the runtime routine for slow case.
diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
--- openjdk.orig/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	2021-07-16 05:52:52.000000000 +0100
+++ openjdk/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp	2021-07-27 18:21:08.551555444 +0100
@@ -725,7 +725,7 @@
     movptr(Address(lock_reg, mark_offset), swap_reg);
 
     assert(lock_offset == 0,
-           "displached header must be first word in BasicObjectLock");
+           "displaced header must be first word in BasicObjectLock");
 
     if (os::is_MP()) lock();
     cmpxchgptr(lock_reg, Address(obj_reg, 0));
@@ -778,7 +778,7 @@
 // Kills:
 //      rax
 //      c_rarg0, c_rarg1, c_rarg2, c_rarg3, ... (param regs)
-//      rscratch1, rscratch2 (scratch regs)
+//      rscratch1 (scratch reg)
 void InterpreterMacroAssembler::unlock_object(Register lock_reg) {
   assert(lock_reg == c_rarg1, "The argument is only for looks. It must be rarg1");
 
@@ -823,7 +823,7 @@
     if (os::is_MP()) lock();
     cmpxchgptr(header_reg, Address(obj_reg, 0));
 
-    // zero for recursive case
+    // zero for simple unlock of a stack-lock case
     jcc(Assembler::zero, done);
 
     // Call the runtime routine for slow case.
diff -Nru openjdk.orig/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp openjdk/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp
--- openjdk.orig/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	2021-07-16 05:52:52.000000000 +0100
+++ openjdk/hotspot/src/cpu/x86/vm/macroAssembler_x86.cpp	2021-07-27 18:21:08.552555455 +0100
@@ -1080,7 +1080,7 @@
   }
   assert(markOopDesc::age_shift == markOopDesc::lock_bits + markOopDesc::biased_lock_bits, "biased locking makes assumptions about bit layout");
   Address mark_addr      (obj_reg, oopDesc::mark_offset_in_bytes());
-  Address saved_mark_addr(lock_reg, 0);
+  NOT_LP64( Address saved_mark_addr(lock_reg, 0); )
 
   if (PrintBiasedLockingStatistics && counters == NULL) {
     counters = BiasedLocking::counters();
@@ -1701,7 +1701,7 @@
                                RTMLockingCounters* stack_rtm_counters,
                                Metadata* method_data,
                                bool use_rtm, bool profile_rtm) {
-  // Ensure the register assignents are disjoint
+  // Ensure the register assignments are disjoint
   assert(tmpReg == rax, "");
 
   if (use_rtm) {
diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/biasedLocking.cpp openjdk/hotspot/src/share/vm/runtime/biasedLocking.cpp
--- openjdk.orig/hotspot/src/share/vm/runtime/biasedLocking.cpp	2021-07-16 05:52:52.000000000 +0100
+++ openjdk/hotspot/src/share/vm/runtime/biasedLocking.cpp	2021-07-27 18:21:08.552555455 +0100
@@ -151,8 +151,13 @@
   if (!mark->has_bias_pattern()) {
     if (TraceBiasedLocking) {
       ResourceMark rm;
-      tty->print_cr("  (Skipping revocation of object of type %s because it's no longer biased)",
-                    obj->klass()->external_name());
+      tty->print_cr("  (Skipping revocation of object " INTPTR_FORMAT
+                    ", mark " INTPTR_FORMAT ", type %s"
+                    ", requesting thread " INTPTR_FORMAT
+                    " because it's no longer biased)",
+                    p2i((void *)obj), (intptr_t) mark,
+                    obj->klass()->external_name(),
+                    (intptr_t) requesting_thread);
     }
     return BiasedLocking::NOT_BIASED;
   }
@@ -163,8 +168,15 @@
 
   if (TraceBiasedLocking && (Verbose || !is_bulk)) {
     ResourceMark rm;
-    tty->print_cr("Revoking bias of object " INTPTR_FORMAT " , mark " INTPTR_FORMAT " , type %s , prototype header " INTPTR_FORMAT " , allow rebias %d , requesting thread " INTPTR_FORMAT,
-                  p2i((void *)obj), (intptr_t) mark, obj->klass()->external_name(), (intptr_t) obj->klass()->prototype_header(), (allow_rebias ? 1 : 0), (intptr_t) requesting_thread);
+    tty->print_cr("Revoking bias of object " INTPTR_FORMAT ", mark "
+                  INTPTR_FORMAT ", type %s, prototype header " INTPTR_FORMAT
+                  ", allow rebias %d, requesting thread " INTPTR_FORMAT,
+                  p2i((void *)obj),
+                  (intptr_t) mark,
+                  obj->klass()->external_name(),
+                  (intptr_t) obj->klass()->prototype_header(),
+                  (allow_rebias ? 1 : 0),
+                  (intptr_t) requesting_thread);
   }
 
   JavaThread* biased_thread = mark->biased_locker();
@@ -200,11 +212,17 @@
       obj->set_mark(unbiased_prototype);
     }
     if (TraceBiasedLocking && (Verbose || !is_bulk)) {
-      tty->print_cr("  Revoked bias of object biased toward dead thread");
+      tty->print_cr("  Revoked bias of object biased toward dead thread ("
+                              PTR_FORMAT ")", p2i(biased_thread));
     }
     return BiasedLocking::BIAS_REVOKED;
   }
 
+  if (TraceBiasedLocking && (Verbose || !is_bulk)) {
+    tty->print_cr("  Revoked bias of object biased toward live thread ("
+                  PTR_FORMAT ")", p2i(biased_thread));
+  }
+
   // Thread owning bias is alive.
   // Check to see whether it currently owns the lock and, if so,
   // write down the needed displaced headers to the thread's stack.
diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/objectMonitor.cpp openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp
--- openjdk.orig/hotspot/src/share/vm/runtime/objectMonitor.cpp	2021-07-16 05:52:52.000000000 +0100
+++ openjdk/hotspot/src/share/vm/runtime/objectMonitor.cpp	2021-07-27 18:21:08.553555466 +0100
@@ -929,7 +929,7 @@
 // ~~~~~~~~
 // ::exit() uses a canonical 1-1 idiom with a MEMBAR although some of
 // the fast-path operators have been optimized so the common ::exit()
-// operation is 1-0.  See i486.ad fast_unlock(), for instance.
+// operation is 1-0, e.g., see macroAssembler_x86.cpp: fast_unlock().
 // The code emitted by fast_unlock() elides the usual MEMBAR.  This
 // greatly improves latency -- MEMBAR and CAS having considerable local
 // latency on modern processors -- but at the cost of "stranding".  Absent the
@@ -942,7 +942,7 @@
 //
 // The CAS() in enter provides for safety and exclusion, while the CAS or
 // MEMBAR in exit provides for progress and avoids stranding.  1-0 locking
-// eliminates the CAS/MEMBAR from the exist path, but it admits stranding.
+// eliminates the CAS/MEMBAR from the exit path, but it admits stranding.
 // We detect and recover from stranding with timers.
 //
 // If a thread transiently strands it'll park until (a) another
diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/os.cpp openjdk/hotspot/src/share/vm/runtime/os.cpp
--- openjdk.orig/hotspot/src/share/vm/runtime/os.cpp	2021-07-27 18:15:29.116737492 +0100
+++ openjdk/hotspot/src/share/vm/runtime/os.cpp	2021-07-27 18:21:08.553555466 +0100
@@ -1287,7 +1287,8 @@
   // We initialize the serialization page shift count here
   // We assume a cache line size of 64 bytes
   assert(SerializePageShiftCount == count,
-         "thread size changed, fix SerializePageShiftCount constant");
+         err_msg("JavaThread size changed; "
+                 "SerializePageShiftCount constant should be %d", count));
   set_serialize_page_mask((uintptr_t)(vm_page_size() - sizeof(int32_t)));
 }
 
diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/sharedRuntime.cpp openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp
--- openjdk.orig/hotspot/src/share/vm/runtime/sharedRuntime.cpp	2021-07-16 05:52:52.000000000 +0100
+++ openjdk/hotspot/src/share/vm/runtime/sharedRuntime.cpp	2021-07-27 18:21:08.553555466 +0100
@@ -2974,7 +2974,7 @@
   Method* moop = fr.interpreter_frame_method();
   int max_locals = moop->max_locals();
   // Allocate temp buffer, 1 word per local & 2 per active monitor
-  int buf_size_words = max_locals + active_monitor_count*2;
+  int buf_size_words = max_locals + active_monitor_count * BasicObjectLock::size();
   intptr_t *buf = NEW_C_HEAP_ARRAY(intptr_t,buf_size_words, mtCode);
 
   // Copy the locals.  Order is preserved so that loading of longs works.
diff -Nru openjdk.orig/hotspot/src/share/vm/runtime/synchronizer.cpp openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp
--- openjdk.orig/hotspot/src/share/vm/runtime/synchronizer.cpp	2021-07-16 05:52:52.000000000 +0100
+++ openjdk/hotspot/src/share/vm/runtime/synchronizer.cpp	2021-07-27 18:24:49.538937794 +0100
@@ -184,38 +184,52 @@
 }
 
 void ObjectSynchronizer::fast_exit(oop object, BasicLock* lock, TRAPS) {
-  assert(!object->mark()->has_bias_pattern(), "should not see bias pattern here");
-  // if displaced header is null, the previous enter is recursive enter, no-op
+  markOop mark = object->mark();
+  // We cannot check for Biased Locking if we are racing an inflation.
+  assert(mark == markOopDesc::INFLATING() ||
+         !mark->has_bias_pattern(), "should not see bias pattern here");
+
   markOop dhw = lock->displaced_header();
-  markOop mark ;
   if (dhw == NULL) {
-     // Recursive stack-lock.
-     // Diagnostics -- Could be: stack-locked, inflating, inflated.
-     mark = object->mark() ;
-     assert (!mark->is_neutral(), "invariant") ;
-     if (mark->has_locker() && mark != markOopDesc::INFLATING()) {
-        assert(THREAD->is_lock_owned((address)mark->locker()), "invariant") ;
-     }
-     if (mark->has_monitor()) {
-        ObjectMonitor * m = mark->monitor() ;
-        assert(((oop)(m->object()))->mark() == mark, "invariant") ;
-        assert(m->is_entered(THREAD), "invariant") ;
+    // If the displaced header is NULL, then this exit matches up with
+    // a recursive enter. No real work to do here except for diagnostics.
+#ifndef PRODUCT
+    if (mark != markOopDesc::INFLATING()) {
+      // Only do diagnostics if we are not racing an inflation. Simply
+      // exiting a recursive enter of a Java Monitor that is being
+      // inflated is safe; see the has_monitor() comment below.
+      assert(!mark->is_neutral(), "invariant");
+      assert(!mark->has_locker() ||
+             THREAD->is_lock_owned((address)mark->locker()), "invariant");
+      if (mark->has_monitor()) {
+        // The BasicLock's displaced_header is marked as a recursive
+        // enter and we have an inflated Java Monitor (ObjectMonitor).
+        // This is a special case where the Java Monitor was inflated
+        // after this thread entered the stack-lock recursively. When a
+        // Java Monitor is inflated, we cannot safely walk the Java
+        // Monitor owner's stack and update the BasicLocks because a
+        // Java Monitor can be asynchronously inflated by a thread that
+        // does not own the Java Monitor.
+        ObjectMonitor * m = mark->monitor();
+        assert(((oop)(m->object()))->mark() == mark, "invariant");
+        assert(m->is_entered(THREAD), "invariant");
+      }
      }
-     return ;
+#endif
+     return;
   }
 
-  mark = object->mark() ;
-
-  // If the object is stack-locked by the current thread, try to
-  // swing the displaced header from the box back to the mark.
   if (mark == (markOop) lock) {
-     assert (dhw->is_neutral(), "invariant") ;
-     if ((markOop) Atomic::cmpxchg_ptr (dhw, object->mark_addr(), mark) == mark) {
-        TEVENT (fast_exit: release stacklock) ;
-        return;
-     }
+    // If the object is stack-locked by the current thread, try to
+    // swing the displaced header from the BasicLock back to the mark.
+    assert (dhw->is_neutral(), "invariant") ;
+    if ((markOop) Atomic::cmpxchg_ptr(dhw, object->mark_addr(), mark) == mark) {
+      TEVENT(fast_exit: release stack-lock);
+      return;
+    }
   }
 
+  // We have to take the slow-path of possible inflation and then exit.
   ObjectSynchronizer::inflate(THREAD,
                               object,
                               inflate_cause_vm_internal)->exit(true, THREAD);
