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.");
|
||||
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");
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
x
Reference in New Issue
Block a user