# HG changeset patch # User dcubed # Date 1574259002 18000 # Node ID 14fa9e70ae712e8993d1b92c847b94796488cd54 # Parent 0c2e1808f800951754992523c48651b3e4cad7a5 8230876: baseline cleanups from Async Monitor Deflation v2.0[789] Reviewed-by: dholmes, kvn diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/cpu/x86/macroAssembler_x86.cpp --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp Wed Nov 20 09:10:02 2019 -0500 @@ -1532,7 +1532,7 @@ Label L_rtm_retry, L_decrement_retry, L_on_abort; int owner_offset = OM_OFFSET_NO_MONITOR_VALUE_TAG(owner); - // Without cast to int32_t a movptr will destroy r10 which is typically obj + // Without cast to int32_t this style of movptr will destroy r10 which is typically obj. movptr(Address(boxReg, 0), (int32_t)intptr_t(markWord::unused_mark().value())); movptr(boxReg, tmpReg); // Save ObjectMonitor address @@ -1602,11 +1602,11 @@ #endif // INCLUDE_RTM_OPT -// Fast_Lock and Fast_Unlock used by C2 +// fast_lock and fast_unlock used by C2 // Because the transitions from emitted code to the runtime // monitorenter/exit helper stubs are so slow it's critical that -// we inline both the stack-locking fast-path and the inflated fast path. +// we inline both the stack-locking fast path and the inflated fast path. // // See also: cmpFastLock and cmpFastUnlock. // @@ -1615,7 +1615,7 @@ // option would be to emit TrySlowEnter and TrySlowExit methods // at startup-time. These methods would accept arguments as // (rax,=Obj, rbx=Self, rcx=box, rdx=Scratch) and return success-failure -// indications in the icc.ZFlag. Fast_Lock and Fast_Unlock would simply +// indications in the icc.ZFlag. fast_lock and fast_unlock would simply // marshal the arguments and emit calls to TrySlowEnter and TrySlowExit. // In practice, however, the # of lock sites is bounded and is usually small. // Besides the call overhead, TrySlowEnter and TrySlowExit might suffer @@ -1634,8 +1634,8 @@ // // TODO: // -// * Arrange for C2 to pass "Self" into Fast_Lock and Fast_Unlock in one of the registers (scr). -// This avoids manifesting the Self pointer in the Fast_Lock and Fast_Unlock terminals. +// * Arrange for C2 to pass "Self" into fast_lock and fast_unlock in one of the registers (scr). +// This avoids manifesting the Self pointer in the fast_lock and fast_unlock terminals. // Given TLAB allocation, Self is usually manifested in a register, so passing it into // the lock operators would typically be faster than reifying Self. // @@ -1661,14 +1661,14 @@ // * use jccb and jmpb instead of jcc and jmp to improve code density. // But beware of excessive branch density on AMD Opterons. // -// * Both Fast_Lock and Fast_Unlock set the ICC.ZF to indicate success -// or failure of the fast-path. If the fast-path fails then we pass -// control to the slow-path, typically in C. In Fast_Lock and -// Fast_Unlock we often branch to DONE_LABEL, just to find that C2 +// * Both fast_lock and fast_unlock set the ICC.ZF to indicate success +// or failure of the fast path. If the fast path fails then we pass +// control to the slow path, typically in C. In fast_lock and +// fast_unlock we often branch to DONE_LABEL, just to find that C2 // will emit a conditional branch immediately after the node. // So we have branches to branches and lots of ICC.ZF games. // Instead, it might be better to have C2 pass a "FailureLabel" -// into Fast_Lock and Fast_Unlock. In the case of success, control +// into fast_lock and fast_unlock. In the case of success, control // will drop through the node. ICC.ZF is undefined at exit. // In the case of failure, the node will branch directly to the // FailureLabel @@ -1813,7 +1813,7 @@ movptr(Address(boxReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), scrReg); xorptr(boxReg, boxReg); // set icc.ZFlag = 1 to indicate success - // If the CAS fails we can either retry or pass control to the slow-path. + // If the CAS fails we can either retry or pass control to the slow path. // We use the latter tactic. // Pass the CAS result in the icc.ZFlag into DONE_LABEL // If the CAS was successful ... @@ -1821,14 +1821,13 @@ // Invariant: m->_recursions should already be 0, so we don't need to explicitly set it. // Intentional fall-through into DONE_LABEL ... #else // _LP64 - // It's inflated + // It's inflated and we use scrReg for ObjectMonitor* in this section. movq(scrReg, tmpReg); xorq(tmpReg, tmpReg); - lock(); cmpxchgptr(r15_thread, Address(scrReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner))); // Unconditionally set box->_displaced_header = markWord::unused_mark(). - // Without cast to int32_t movptr will destroy r10 which is typically obj. + // Without cast to int32_t this style of movptr will destroy r10 which is typically obj. movptr(Address(boxReg, 0), (int32_t)intptr_t(markWord::unused_mark().value())); // Intentional fall-through into DONE_LABEL ... // Propagate ICC.ZF from CAS above into DONE_LABEL. @@ -1844,9 +1843,9 @@ bind(DONE_LABEL); // At DONE_LABEL the icc ZFlag is set as follows ... - // Fast_Unlock uses the same protocol. + // fast_unlock uses the same protocol. // ZFlag == 1 -> Success - // ZFlag == 0 -> Failure - force control through the slow-path + // ZFlag == 0 -> Failure - force control through the slow path } // obj: object to unlock @@ -1855,7 +1854,7 @@ // // Some commentary on balanced locking: // -// Fast_Lock and Fast_Unlock are emitted only for provably balanced lock sites. +// fast_lock and fast_unlock are emitted only for provably balanced lock sites. // Methods that don't have provably balanced locking are forced to run in the // interpreter - such methods won't be compiled to use fast_lock and fast_unlock. // The interpreter provides two properties: @@ -1876,7 +1875,7 @@ // should not be unlocked by "normal" java-level locking and vice-versa. The specification // doesn't specify what will occur if a program engages in such mixed-mode locking, however. // Arguably given that the spec legislates the JNI case as undefined our implementation -// could reasonably *avoid* checking owner in Fast_Unlock(). +// could reasonably *avoid* checking owner in fast_unlock(). // In the interest of performance we elide m->Owner==Self check in unlock. // A perfectly viable alternative is to elide the owner check except when // Xcheck:jni is enabled. @@ -1941,7 +1940,7 @@ // a costly MEMBAR or CAS. See synchronizer.cpp for details on how // we detect and recover from the race that the 1-0 exit admits. // - // Conceptually Fast_Unlock() must execute a STST|LDST "release" barrier + // Conceptually fast_unlock() must execute a STST|LDST "release" barrier // before it STs null into _owner, releasing the lock. Updates // to data protected by the critical section must be visible before // we drop the lock (and thus before any other thread could acquire @@ -1990,6 +1989,7 @@ movptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(cxq))); orptr(boxReg, Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(EntryList))); jccb (Assembler::notZero, CheckSucc); + // Without cast to int32_t this style of movptr will destroy r10 which is typically obj. movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD); jmpb (DONE_LABEL); @@ -1998,13 +1998,14 @@ bind (CheckSucc); // The following optional optimization can be elided if necessary - // Effectively: if (succ == null) goto SlowPath + // Effectively: if (succ == null) goto slow path // The code reduces the window for a race, however, // and thus benefits performance. cmpptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(succ)), (int32_t)NULL_WORD); jccb (Assembler::zero, LGoSlowPath); xorptr(boxReg, boxReg); + // Without cast to int32_t this style of movptr will destroy r10 which is typically obj. movptr(Address(tmpReg, OM_OFFSET_NO_MONITOR_VALUE_TAG(owner)), (int32_t)NULL_WORD); // Memory barrier/fence @@ -2039,7 +2040,7 @@ // If that didn't work, then another thread grabbed the // lock so we're done (and exit was a success). jccb (Assembler::notEqual, LSuccess); - // Intentional fall-through into slow-path + // Intentional fall-through into slow path bind (LGoSlowPath); orl (boxReg, 1); // set ICC.ZF=0 to indicate failure diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/share/classfile/systemDictionary.cpp --- a/src/hotspot/share/classfile/systemDictionary.cpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/share/classfile/systemDictionary.cpp Wed Nov 20 09:10:02 2019 -0500 @@ -540,7 +540,7 @@ assert(calledholdinglock,"must hold lock for notify"); assert((lockObject() != _system_loader_lock_obj && !is_parallelCapable(lockObject)), "unexpected double_lock_wait"); ObjectSynchronizer::notifyall(lockObject, THREAD); - intptr_t recursions = ObjectSynchronizer::complete_exit(lockObject, THREAD); + intx recursions = ObjectSynchronizer::complete_exit(lockObject, THREAD); SystemDictionary_lock->wait(); SystemDictionary_lock->unlock(); ObjectSynchronizer::reenter(lockObject, recursions, THREAD); diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/share/runtime/objectMonitor.cpp --- a/src/hotspot/share/runtime/objectMonitor.cpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/share/runtime/objectMonitor.cpp Wed Nov 20 09:10:02 2019 -0500 @@ -26,6 +26,8 @@ #include "classfile/vmSymbols.hpp" #include "jfr/jfrEvents.hpp" #include "jfr/support/jfrThreadId.hpp" +#include "logging/log.hpp" +#include "logging/logStream.hpp" #include "memory/allocation.inline.hpp" #include "memory/resourceArea.hpp" #include "oops/markWord.hpp" @@ -255,7 +257,7 @@ return; } - if (Self->is_lock_owned ((address)cur)) { + if (Self->is_lock_owned((address)cur)) { assert(_recursions == 0, "internal state error"); _recursions = 1; // Commute owner from a thread-specific on-stack BasicLockObject address to @@ -275,8 +277,7 @@ // we forgo posting JVMTI events and firing DTRACE probes. if (TrySpin(Self) > 0) { assert(_owner == Self, "must be Self: owner=" INTPTR_FORMAT, p2i(_owner)); - assert(_recursions == 0, "must be 0: recursions=" INTPTR_FORMAT, - _recursions); + assert(_recursions == 0, "must be 0: recursions=" INTX_FORMAT, _recursions); assert(((oop)object())->mark() == markWord::encode(this), "object mark must match encoded this: mark=" INTPTR_FORMAT ", encoded this=" INTPTR_FORMAT, ((oop)object())->mark().value(), @@ -881,7 +882,14 @@ // way we should encounter this situation is in the presence of // unbalanced JNI locking. TODO: CheckJNICalls. // See also: CR4414101 - assert(false, "Non-balanced monitor enter/exit! Likely JNI locking"); +#ifdef ASSERT + LogStreamHandle(Error, monitorinflation) lsh; + lsh.print_cr("ERROR: ObjectMonitor::exit(): thread=" INTPTR_FORMAT + " is exiting an ObjectMonitor it does not own.", p2i(THREAD)); + lsh.print_cr("The imbalance is possibly caused by JNI locking."); + print_debug_style_on(&lsh); +#endif + assert(false, "Non-balanced monitor enter/exit!"); return; } } @@ -908,8 +916,6 @@ // release semantics: prior loads and stores from within the critical section // must not float (reorder) past the following store that drops the lock. - // On SPARC that requires MEMBAR #loadstore|#storestore. - // But of course in TSO #loadstore|#storestore is not required. OrderAccess::release_store(&_owner, (void*)NULL); // drop the lock OrderAccess::storeload(); // See if we need to wake a successor if ((intptr_t(_EntryList)|intptr_t(_cxq)) == 0 || _succ != NULL) { @@ -1106,7 +1112,7 @@ // The _owner field is not always the Thread addr even with an // inflated monitor, e.g. the monitor can be inflated by a non-owning // thread due to contention. -intptr_t ObjectMonitor::complete_exit(TRAPS) { +intx ObjectMonitor::complete_exit(TRAPS) { Thread * const Self = THREAD; assert(Self->is_Java_thread(), "Must be Java thread!"); JavaThread *jt = (JavaThread *)THREAD; @@ -1122,7 +1128,7 @@ } guarantee(Self == _owner, "complete_exit not owner"); - intptr_t save = _recursions; // record the old recursion count + intx save = _recursions; // record the old recursion count _recursions = 0; // set the recursion level to be 0 exit(true, Self); // exit the monitor guarantee(_owner != Self, "invariant"); @@ -1131,7 +1137,7 @@ // reenter() enters a lock and sets recursion count // complete_exit/reenter operate as a wait without waiting -void ObjectMonitor::reenter(intptr_t recursions, TRAPS) { +void ObjectMonitor::reenter(intx recursions, TRAPS) { Thread * const Self = THREAD; assert(Self->is_Java_thread(), "Must be Java thread!"); JavaThread *jt = (JavaThread *)THREAD; @@ -1252,7 +1258,7 @@ _Responsible = NULL; - intptr_t save = _recursions; // record the old recursion count + intx save = _recursions; // record the old recursion count _waiters++; // increment the number of waiters _recursions = 0; // set the recursion level to be 1 exit(true, Self); // exit the monitor @@ -1941,8 +1947,62 @@ void ObjectMonitor::print_on(outputStream* st) const { // The minimal things to print for markWord printing, more can be added for debugging and logging. st->print("{contentions=0x%08x,waiters=0x%08x" - ",recursions=" INTPTR_FORMAT ",owner=" INTPTR_FORMAT "}", + ",recursions=" INTX_FORMAT ",owner=" INTPTR_FORMAT "}", contentions(), waiters(), recursions(), p2i(owner())); } void ObjectMonitor::print() const { print_on(tty); } + +#ifdef ASSERT +// Print the ObjectMonitor like a debugger would: +// +// (ObjectMonitor) 0x00007fdfb6012e40 = { +// _header = 0x0000000000000001 +// _object = 0x000000070ff45fd0 +// _next_om = 0x0000000000000000 +// _pad_buf0 = { +// [0] = '\0' +// ... +// [103] = '\0' +// } +// _owner = 0x0000000000000000 +// _previous_owner_tid = 0 +// _recursions = 0 +// _EntryList = 0x0000000000000000 +// _cxq = 0x0000000000000000 +// _succ = 0x0000000000000000 +// _Responsible = 0x0000000000000000 +// _Spinner = 0 +// _SpinDuration = 5000 +// _contentions = 0 +// _WaitSet = 0x0000700009756248 +// _waiters = 1 +// _WaitSetLock = 0 +// } +// +void ObjectMonitor::print_debug_style_on(outputStream* st) const { + st->print_cr("(ObjectMonitor*) " INTPTR_FORMAT " = {", p2i(this)); + st->print_cr(" _header = " INTPTR_FORMAT, header().value()); + st->print_cr(" _object = " INTPTR_FORMAT, p2i(_object)); + st->print_cr(" _next_om = " INTPTR_FORMAT, p2i(_next_om)); + st->print_cr(" _pad_buf0 = {"); + st->print_cr(" [0] = '\\0'"); + st->print_cr(" ..."); + st->print_cr(" [%d] = '\\0'", (int)sizeof(_pad_buf0) - 1); + st->print_cr(" }"); + st->print_cr(" _owner = " INTPTR_FORMAT, p2i(_owner)); + st->print_cr(" _previous_owner_tid = " JLONG_FORMAT, _previous_owner_tid); + st->print_cr(" _recursions = " INTX_FORMAT, _recursions); + st->print_cr(" _EntryList = " INTPTR_FORMAT, p2i(_EntryList)); + st->print_cr(" _cxq = " INTPTR_FORMAT, p2i(_cxq)); + st->print_cr(" _succ = " INTPTR_FORMAT, p2i(_succ)); + st->print_cr(" _Responsible = " INTPTR_FORMAT, p2i(_Responsible)); + st->print_cr(" _Spinner = %d", _Spinner); + st->print_cr(" _SpinDuration = %d", _SpinDuration); + st->print_cr(" _contentions = %d", _contentions); + st->print_cr(" _WaitSet = " INTPTR_FORMAT, p2i(_WaitSet)); + st->print_cr(" _waiters = %d", _waiters); + st->print_cr(" _WaitSetLock = %d", _WaitSetLock); + st->print_cr("}"); +} +#endif diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/share/runtime/objectMonitor.hpp --- a/src/hotspot/share/runtime/objectMonitor.hpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/share/runtime/objectMonitor.hpp Wed Nov 20 09:10:02 2019 -0500 @@ -144,7 +144,7 @@ sizeof(ObjectMonitor *)); void* volatile _owner; // pointer to owning thread OR BasicLock volatile jlong _previous_owner_tid; // thread id of the previous owner of the monitor - volatile intptr_t _recursions; // recursion count, 0 for first entry + volatile intx _recursions; // recursion count, 0 for first entry ObjectWaiter* volatile _EntryList; // Threads blocked on entry or reentry. // The list is actually composed of WaitNodes, // acting as proxies for Threads. @@ -237,7 +237,7 @@ jint waiters() const; jint contentions() const; - intptr_t recursions() const { return _recursions; } + intx recursions() const { return _recursions; } // JVM/TI GetObjectMonitorUsage() needs this: ObjectWaiter* first_waiter() { return _WaitSet; } @@ -263,7 +263,7 @@ // _recursions == 0 _WaitSet == NULL DEBUG_ONLY(stringStream ss;) assert((is_busy() | _recursions) == 0, "freeing in-use monitor: %s, " - "recursions=" INTPTR_FORMAT, is_busy_to_string(&ss), _recursions); + "recursions=" INTX_FORMAT, is_busy_to_string(&ss), _recursions); _succ = NULL; _EntryList = NULL; _cxq = NULL; @@ -289,11 +289,14 @@ void notifyAll(TRAPS); void print() const; +#ifdef ASSERT + void print_debug_style_on(outputStream* st) const; +#endif void print_on(outputStream* st) const; // Use the following at your own risk - intptr_t complete_exit(TRAPS); - void reenter(intptr_t recursions, TRAPS); + intx complete_exit(TRAPS); + void reenter(intx recursions, TRAPS); private: void AddWaiter(ObjectWaiter* waiter); diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/share/runtime/objectMonitor.inline.hpp --- a/src/hotspot/share/runtime/objectMonitor.inline.hpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/share/runtime/objectMonitor.inline.hpp Wed Nov 20 09:10:02 2019 -0500 @@ -59,7 +59,7 @@ assert(Atomic::load(&_header).value() != 0, "must be non-zero"); assert(_contentions == 0, "must be 0: contentions=%d", _contentions); assert(_waiters == 0, "must be 0: waiters=%d", _waiters); - assert(_recursions == 0, "must be 0: recursions=" INTPTR_FORMAT, _recursions); + assert(_recursions == 0, "must be 0: recursions=" INTX_FORMAT, _recursions); assert(_object != NULL, "must be non-NULL"); assert(_owner == NULL, "must be NULL: owner=" INTPTR_FORMAT, p2i(_owner)); diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/share/runtime/synchronizer.cpp --- a/src/hotspot/share/runtime/synchronizer.cpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/share/runtime/synchronizer.cpp Wed Nov 20 09:10:02 2019 -0500 @@ -359,7 +359,7 @@ // 4) reenter lock1 with original recursion count // 5) lock lock2 // NOTE: must use heavy weight monitor to handle complete_exit/reenter() -intptr_t ObjectSynchronizer::complete_exit(Handle obj, TRAPS) { +intx ObjectSynchronizer::complete_exit(Handle obj, TRAPS) { if (UseBiasedLocking) { BiasedLocking::revoke(obj, THREAD); assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now"); @@ -371,7 +371,7 @@ } // NOTE: must use heavy weight monitor to handle complete_exit/reenter() -void ObjectSynchronizer::reenter(Handle obj, intptr_t recursion, TRAPS) { +void ObjectSynchronizer::reenter(Handle obj, intx recursions, TRAPS) { if (UseBiasedLocking) { BiasedLocking::revoke(obj, THREAD); assert(!obj->mark().has_bias_pattern(), "biases should be revoked by now"); @@ -379,7 +379,7 @@ ObjectMonitor* monitor = inflate(THREAD, obj(), inflate_cause_vm_internal); - monitor->reenter(recursion, THREAD); + monitor->reenter(recursions, THREAD); } // ----------------------------------------------------------------------------- // JNI locks on java objects @@ -1140,7 +1140,7 @@ guarantee(m->object() == NULL, "invariant"); stringStream ss; guarantee((m->is_busy() | m->_recursions) == 0, "freeing in-use monitor: " - "%s, recursions=" INTPTR_FORMAT, m->is_busy_to_string(&ss), + "%s, recursions=" INTX_FORMAT, m->is_busy_to_string(&ss), m->_recursions); // _next_om is used for both per-thread in-use and free lists so // we have to remove 'm' from the in-use list first (as needed). diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/share/runtime/synchronizer.hpp --- a/src/hotspot/share/runtime/synchronizer.hpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/share/runtime/synchronizer.hpp Wed Nov 20 09:10:02 2019 -0500 @@ -92,8 +92,8 @@ // used by classloading to free classloader object lock, // wait on an internal lock, and reclaim original lock // with original recursion count - static intptr_t complete_exit(Handle obj, TRAPS); - static void reenter (Handle obj, intptr_t recursion, TRAPS); + static intx complete_exit(Handle obj, TRAPS); + static void reenter (Handle obj, intx recursions, TRAPS); // thread-specific and global ObjectMonitor free list accessors static ObjectMonitor* om_alloc(Thread* self); @@ -209,8 +209,8 @@ void wait_uninterruptibly(TRAPS) { ObjectSynchronizer::wait_uninterruptibly(_obj, 0, CHECK); } // complete_exit gives up lock completely, returning recursion count // reenter reclaims lock with original recursion count - intptr_t complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); } - void reenter(intptr_t recursion, TRAPS) { ObjectSynchronizer::reenter(_obj, recursion, CHECK); } + intx complete_exit(TRAPS) { return ObjectSynchronizer::complete_exit(_obj, THREAD); } + void reenter(intx recursions, TRAPS) { ObjectSynchronizer::reenter(_obj, recursions, CHECK); } }; #endif // SHARE_RUNTIME_SYNCHRONIZER_HPP diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/share/runtime/threadSMR.cpp --- a/src/hotspot/share/runtime/threadSMR.cpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/share/runtime/threadSMR.cpp Wed Nov 20 09:10:02 2019 -0500 @@ -601,8 +601,6 @@ } void ThreadsList::dec_nested_handle_cnt() { - // The decrement only needs to be MO_ACQ_REL since the reference - // counter is volatile (and the hazard ptr is already NULL). Atomic::dec(&_nested_handle_cnt); } @@ -646,8 +644,6 @@ } void ThreadsList::inc_nested_handle_cnt() { - // The increment needs to be MO_SEQ_CST so that the reference counter - // update is seen before the subsequent hazard ptr update. Atomic::inc(&_nested_handle_cnt); } diff -r 0c2e1808f800 -r 14fa9e70ae71 src/hotspot/share/runtime/vmStructs.cpp --- a/src/hotspot/share/runtime/vmStructs.cpp Wed Nov 20 10:37:46 2019 +0100 +++ b/src/hotspot/share/runtime/vmStructs.cpp Wed Nov 20 09:10:02 2019 -0500 @@ -911,7 +911,7 @@ unchecked_nonstatic_field(ObjectMonitor, _owner, sizeof(void *)) /* NOTE: no type */ \ volatile_nonstatic_field(ObjectMonitor, _contentions, jint) \ volatile_nonstatic_field(ObjectMonitor, _waiters, jint) \ - volatile_nonstatic_field(ObjectMonitor, _recursions, intptr_t) \ + volatile_nonstatic_field(ObjectMonitor, _recursions, intx) \ nonstatic_field(ObjectMonitor, _next_om, ObjectMonitor*) \ volatile_nonstatic_field(BasicLock, _displaced_header, markWord) \ nonstatic_field(BasicObjectLock, _lock, BasicLock) \