8337318: Deoptimization::relock_objects fails assert(monitor->owner() == Thread::current()) failed: must be

Co-authored-by: Richard Reingruber <rrich@openjdk.org>
Reviewed-by: rrich, dholmes, shade, pchilanomate
This commit is contained in:
Coleen Phillimore 2024-08-13 11:48:50 +00:00
parent fbe4cc96e2
commit ff8a9f9267
2 changed files with 84 additions and 3 deletions

View File

@ -596,8 +596,8 @@ bool ObjectSynchronizer::enter_fast_impl(Handle obj, BasicLock* lock, JavaThread
log_info(monitorinflation)("LockStack capacity exceeded, inflating.");
ObjectMonitor* monitor = inflate_for(locking_thread, lock_stack.bottom(), inflate_cause_vm_internal);
assert(monitor->owner() == Thread::current(), "must be owner=" PTR_FORMAT " current=" PTR_FORMAT " mark=" PTR_FORMAT,
p2i(monitor->owner()), p2i(Thread::current()), monitor->object()->mark_acquire().value());
assert(monitor->owner() == locking_thread, "must be owner=" PTR_FORMAT " locking_thread=" PTR_FORMAT " mark=" PTR_FORMAT,
p2i(monitor->owner()), p2i(locking_thread), monitor->object()->mark_acquire().value());
assert(!lock_stack.is_full(), "must have made room here");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020 SAP SE. All rights reserved.
* Copyright (c) 2020, 2024 SAP SE. 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
@ -288,6 +288,7 @@ class EATestsTarget {
// Relocking test cases
new EARelockingSimpleTarget() .run();
new EARelockingWithManyLightweightLocksTarget() .run();
new EARelockingSimpleWithAccessInOtherThreadTarget() .run();
new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target() .run();
new EARelockingRecursiveTarget() .run();
@ -413,6 +414,7 @@ public class EATests extends TestScaffold {
// Relocking test cases
new EARelockingSimple() .run(this);
new EARelockingWithManyLightweightLocks() .run(this);
new EARelockingSimpleWithAccessInOtherThread() .run(this);
new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall() .run(this);
new EARelockingRecursive() .run(this);
@ -1797,6 +1799,85 @@ class EARelockingSimpleTarget extends EATestCaseBaseTarget {
/////////////////////////////////////////////////////////////////////////////
/**
* Like {@link EARelockingSimple}. The difference is that there are many
* lightweight locked objects when the relocking is done. With
* <code>-XX:LockingMode=2</code> the lock stack of the thread will be full
* because of this.
*/
class EARelockingWithManyLightweightLocks extends EATestCaseBaseDebugger {
public void runTestCase() throws Exception {
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
printStack(bpe.thread());
@SuppressWarnings("unused")
ObjectReference o = getLocalRef(bpe.thread().frame(1), XYVAL_NAME, "l1");
}
}
class EARelockingWithManyLightweightLocksTarget extends EATestCaseBaseTarget {
static class Lock {
}
public static Lock L0, L1, L2, L3, L4, L5, L6, L7, L8, L9;
void allocateLocks() {
L0 = new Lock();
L1 = new Lock();
L2 = new Lock();
L3 = new Lock();
L4 = new Lock();
L5 = new Lock();
L6 = new Lock();
L7 = new Lock();
L8 = new Lock();
L9 = new Lock();
}
@Override
public void setUp() {
super.setUp();
allocateLocks();
}
@Override
public void warmupDone() {
super.warmupDone();
allocateLocks(); // get rid of already inflated ones
}
public void dontinline_testMethod() {
XYVal l1 = new XYVal(4, 2);
synchronized(L0) {
synchronized(L1) {
synchronized(L2) {
synchronized(L3) {
synchronized(L4) {
synchronized(L5) {
synchronized(L6) {
synchronized(L7) {
synchronized(L8) {
synchronized(L9) {
synchronized (l1) {
dontinline_brkpt();
}
}
}
}
}
}
}
}
}
}
}
}
}
/////////////////////////////////////////////////////////////////////////////
// The debugger reads and publishes an object with eliminated locking to an instance field.
// A 2nd thread in the debuggee finds it there and changes its state using a synchronized method.
// Without eager relocking the accesses are unsynchronized which can be observed.