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:
parent
fbe4cc96e2
commit
ff8a9f9267
@ -596,8 +596,8 @@ bool ObjectSynchronizer::enter_fast_impl(Handle obj, BasicLock* lock, JavaThread
|
|||||||
|
|
||||||
log_info(monitorinflation)("LockStack capacity exceeded, inflating.");
|
log_info(monitorinflation)("LockStack capacity exceeded, inflating.");
|
||||||
ObjectMonitor* monitor = inflate_for(locking_thread, lock_stack.bottom(), inflate_cause_vm_internal);
|
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,
|
assert(monitor->owner() == locking_thread, "must be owner=" PTR_FORMAT " locking_thread=" PTR_FORMAT " mark=" PTR_FORMAT,
|
||||||
p2i(monitor->owner()), p2i(Thread::current()), monitor->object()->mark_acquire().value());
|
p2i(monitor->owner()), p2i(locking_thread), monitor->object()->mark_acquire().value());
|
||||||
assert(!lock_stack.is_full(), "must have made room here");
|
assert(!lock_stack.is_full(), "must have made room here");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -288,6 +288,7 @@ class EATestsTarget {
|
|||||||
|
|
||||||
// Relocking test cases
|
// Relocking test cases
|
||||||
new EARelockingSimpleTarget() .run();
|
new EARelockingSimpleTarget() .run();
|
||||||
|
new EARelockingWithManyLightweightLocksTarget() .run();
|
||||||
new EARelockingSimpleWithAccessInOtherThreadTarget() .run();
|
new EARelockingSimpleWithAccessInOtherThreadTarget() .run();
|
||||||
new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target() .run();
|
new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target() .run();
|
||||||
new EARelockingRecursiveTarget() .run();
|
new EARelockingRecursiveTarget() .run();
|
||||||
@ -413,6 +414,7 @@ public class EATests extends TestScaffold {
|
|||||||
|
|
||||||
// Relocking test cases
|
// Relocking test cases
|
||||||
new EARelockingSimple() .run(this);
|
new EARelockingSimple() .run(this);
|
||||||
|
new EARelockingWithManyLightweightLocks() .run(this);
|
||||||
new EARelockingSimpleWithAccessInOtherThread() .run(this);
|
new EARelockingSimpleWithAccessInOtherThread() .run(this);
|
||||||
new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall() .run(this);
|
new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall() .run(this);
|
||||||
new EARelockingRecursive() .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.
|
// 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.
|
// 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.
|
// Without eager relocking the accesses are unsynchronized which can be observed.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user