Skip to content

Commit 13dce29

Browse files
committedJun 24, 2024
8334560: [PPC64]: postalloc_expand_java_dynamic_call_sched does not copy all fields
Reviewed-by: mbaesken, mdoerr
1 parent 863b2a9 commit 13dce29

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed
 

‎src/hotspot/cpu/ppc/ppc.ad

+1
Original file line numberDiff line numberDiff line change
@@ -3429,6 +3429,7 @@ encode %{
34293429
call->_oop_map = _oop_map;
34303430
call->_jvms = _jvms;
34313431
call->_jvmadj = _jvmadj;
3432+
call->_has_ea_local_in_scope = _has_ea_local_in_scope;
34323433
call->_in_rms = _in_rms;
34333434
call->_nesting = _nesting;
34343435
call->_override_symbolic_info = _override_symbolic_info;

‎test/jdk/com/sun/jdi/EATests.java

+91
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,7 @@ public static void main(String[] args) {
289289
// Relocking test cases
290290
new EARelockingSimpleTarget() .run();
291291
new EARelockingSimpleWithAccessInOtherThreadTarget() .run();
292+
new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target() .run();
292293
new EARelockingRecursiveTarget() .run();
293294
new EARelockingNestedInflatedTarget() .run();
294295
new EARelockingNestedInflated_02Target() .run();
@@ -413,6 +414,7 @@ protected void runTests() throws Exception {
413414
// Relocking test cases
414415
new EARelockingSimple() .run(this);
415416
new EARelockingSimpleWithAccessInOtherThread() .run(this);
417+
new EARelockingSimpleWithAccessInOtherThread_02_DynamicCall() .run(this);
416418
new EARelockingRecursive() .run(this);
417419
new EARelockingNestedInflated() .run(this);
418420
new EARelockingNestedInflated_02() .run(this);
@@ -1851,6 +1853,95 @@ public int getExpectedIResult() {
18511853

18521854
/////////////////////////////////////////////////////////////////////////////
18531855

1856+
// The debugger reads and publishes an object with eliminated locking to an instance field.
1857+
// A 2nd thread in the debuggee finds it there and changes its state using a synchronized method.
1858+
// Without eager relocking the accesses are unsynchronized which can be observed.
1859+
// This is a variant of EARelockingSimpleWithAccessInOtherThread with a dynamic call (not devirtualized).
1860+
class EARelockingSimpleWithAccessInOtherThread_02_DynamicCall extends EATestCaseBaseDebugger {
1861+
1862+
public void runTestCase() throws Exception {
1863+
BreakpointEvent bpe = resumeTo(TARGET_TESTCASE_BASE_NAME, "dontinline_brkpt", "()V");
1864+
printStack(bpe.thread());
1865+
String l1ClassName = EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target.SyncCounter.class.getName();
1866+
ObjectReference ctr = getLocalRef(bpe.thread().frame(2), l1ClassName, "l1");
1867+
setField(testCase, "sharedCounter", ctr);
1868+
terminateEndlessLoop();
1869+
}
1870+
}
1871+
1872+
class EARelockingSimpleWithAccessInOtherThread_02_DynamicCall_Target extends EATestCaseBaseTarget {
1873+
1874+
public static final BrkPtDispatchA[] disp =
1875+
{new BrkPtDispatchA(), new BrkPtDispatchB(), new BrkPtDispatchC(), new BrkPtDispatchD()};
1876+
1877+
public static class BrkPtDispatchA {
1878+
public EATestCaseBaseTarget testCase;
1879+
public void dontinline_brkpt() { testCase.dontinline_brkpt(); }
1880+
}
1881+
1882+
public static class BrkPtDispatchB extends BrkPtDispatchA {
1883+
@Override
1884+
public void dontinline_brkpt() { testCase.dontinline_brkpt(); }
1885+
}
1886+
1887+
public static class BrkPtDispatchC extends BrkPtDispatchA {
1888+
@Override
1889+
public void dontinline_brkpt() { testCase.dontinline_brkpt(); }
1890+
}
1891+
1892+
public static class BrkPtDispatchD extends BrkPtDispatchA {
1893+
@Override
1894+
public void dontinline_brkpt() {
1895+
testCase.dontinline_brkpt();
1896+
}
1897+
}
1898+
1899+
public static class SyncCounter {
1900+
private int val;
1901+
public synchronized int inc() { return val++; }
1902+
}
1903+
1904+
public volatile SyncCounter sharedCounter;
1905+
1906+
@Override
1907+
public void setUp() {
1908+
super.setUp();
1909+
testMethodDepth = 2;
1910+
for (BrkPtDispatchA d : disp) {
1911+
d.testCase = this;
1912+
}
1913+
doLoop = true;
1914+
new Thread(() -> {
1915+
while (doLoop) {
1916+
SyncCounter ctr = sharedCounter;
1917+
if (ctr != null) {
1918+
ctr.inc();
1919+
}
1920+
}
1921+
}).start();
1922+
}
1923+
1924+
public int dispCount;
1925+
public void dontinline_testMethod() {
1926+
SyncCounter l1 = new SyncCounter();
1927+
synchronized (l1) { // Eliminated locking
1928+
l1.inc();
1929+
// Use different types for the subsequent call to prevent devirtualization.
1930+
BrkPtDispatchA d = disp[(dispCount++) & 3];
1931+
d.dontinline_brkpt(); // Dynamic call. Debugger publishes l1 to sharedCounter.
1932+
iResult = l1.inc(); // Changes by the 2nd thread will be observed if l1
1933+
// was not relocked before passing it to the debugger.
1934+
}
1935+
}
1936+
1937+
@Override
1938+
public int getExpectedIResult() {
1939+
return 1;
1940+
}
1941+
}
1942+
1943+
/////////////////////////////////////////////////////////////////////////////
1944+
18541945
// Test recursive locking
18551946
class EARelockingRecursiveTarget extends EATestCaseBaseTarget {
18561947

0 commit comments

Comments
 (0)
Please sign in to comment.