Skip to content

Commit 8f2456e

Browse files
Boris Ulasevichchrishcole
Boris Ulasevich
andcommitted
8267042: bug in monitor locking/unlocking on ARM32 C1 due to uninitialized BasicObjectLock::_displaced_header
Co-authored-by: Chris Cole <chris@sageembedded.com> Reviewed-by: dsamersoff
1 parent 5ae9a12 commit 8f2456e

File tree

3 files changed

+176
-4
lines changed

3 files changed

+176
-4
lines changed

src/hotspot/cpu/arm/c1_MacroAssembler_arm.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -234,8 +234,9 @@ int C1_MacroAssembler::lock_object(Register hdr, Register obj,
234234
// -2- test (hdr - SP) if the low two bits are 0
235235
sub(tmp2, hdr, SP, eq);
236236
movs(tmp2, AsmOperand(tmp2, lsr, exact_log2(os::vm_page_size())), eq);
237-
// If 'eq' then OK for recursive fast locking: store 0 into a lock record.
238-
str(tmp2, Address(disp_hdr, mark_offset), eq);
237+
// If still 'eq' then recursive locking OK
238+
// set to zero if recursive lock, set to non zero otherwise (see discussion in JDK-8267042)
239+
str(tmp2, Address(disp_hdr, mark_offset));
239240
b(fast_lock_done, eq);
240241
// else need slow case
241242
b(slow_case);

src/hotspot/cpu/arm/sharedRuntime_arm.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,8 +1180,9 @@ nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
11801180
// -2- test (hdr - SP) if the low two bits are 0
11811181
__ sub(Rtemp, mark, SP, eq);
11821182
__ movs(Rtemp, AsmOperand(Rtemp, lsr, exact_log2(os::vm_page_size())), eq);
1183-
// If still 'eq' then recursive locking OK: set displaced header to 0
1184-
__ str(Rtemp, Address(disp_hdr, BasicLock::displaced_header_offset_in_bytes()), eq);
1183+
// If still 'eq' then recursive locking OK
1184+
// set to zero if recursive lock, set to non zero otherwise (see discussion in JDK-8267042)
1185+
__ str(Rtemp, Address(disp_hdr, BasicLock::displaced_header_offset_in_bytes()));
11851186
__ b(lock_done, eq);
11861187
__ b(slow_lock);
11871188

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
package compiler.c1;
25+
26+
import java.io.IOException;
27+
import java.io.InterruptedIOException;
28+
29+
/*
30+
* @test
31+
* @author Chris Cole
32+
* @bug 8267042
33+
* @summary missing displaced_header initialization causes hangup
34+
* @run main/othervm -XX:+TieredCompilation -XX:TieredStopAtLevel=1
35+
* -XX:-BackgroundCompilation -XX:CompileThreshold=1
36+
* -XX:CompileOnly=compiler.c1.Test8267042::write
37+
* compiler.c1.Test8267042
38+
*/
39+
public class Test8267042 {
40+
41+
private static int DATA_SIZE = 4;
42+
43+
private char buffer;
44+
private boolean empty = true;
45+
46+
public static void main(String[] args) {
47+
Test8267042 test = new Test8267042();
48+
test.run();
49+
}
50+
51+
private void run() {
52+
System.out.println("Starting test");
53+
54+
Thread writeThread = new Thread(new Runnable() {
55+
@Override
56+
public void run() {
57+
char data[] = new char[DATA_SIZE];
58+
try {
59+
write(data, 0, data.length);
60+
} catch (IOException e) {
61+
e.printStackTrace();
62+
}
63+
}
64+
});
65+
writeThread.setDaemon(true);
66+
writeThread.start();
67+
68+
Thread readThread = new Thread(new Runnable() {
69+
@Override
70+
public void run() {
71+
try {
72+
for (int i = 0; i < DATA_SIZE; i++) {
73+
read();
74+
}
75+
} catch (IOException e) {
76+
e.printStackTrace();
77+
}
78+
}
79+
});
80+
readThread.setDaemon(true);
81+
readThread.start();
82+
83+
try {
84+
writeThread.join(5000);
85+
if (writeThread.isAlive()) {
86+
throw new InternalError("write thread deadlocked");
87+
}
88+
readThread.join(5000);
89+
if (readThread.isAlive()) {
90+
throw new InternalError("read thread deadlocked");
91+
}
92+
} catch (InterruptedException e) {
93+
throw new InternalError("unexpected InterrruptedException while waiting to join threads", e);
94+
}
95+
System.out.println("Test passed");
96+
}
97+
98+
synchronized void write(char data[], int offset, int length) throws IOException {
99+
while (--length >= 0) {
100+
getZeroOnStack(offset);
101+
write(data[offset++]);
102+
}
103+
}
104+
105+
synchronized void write(int c) throws IOException {
106+
while (!empty) {
107+
try {
108+
wait(1000);
109+
} catch (InterruptedException e) {
110+
throw new InterruptedIOException();
111+
}
112+
}
113+
buffer = (char) c;
114+
empty = false;
115+
notifyAll();
116+
}
117+
118+
public synchronized int read() throws IOException {
119+
while (empty) {
120+
try {
121+
System.out.println("read() before wait");
122+
wait(1000);
123+
System.out.println("read() after wait");
124+
} catch (InterruptedException e) {
125+
throw new InterruptedIOException();
126+
}
127+
}
128+
int value = buffer;
129+
empty = true;
130+
notifyAll();
131+
return value;
132+
}
133+
134+
private void getZeroOnStack(int offset) {
135+
int l1;
136+
int l2;
137+
int l3;
138+
int l4;
139+
int l5;
140+
int l6;
141+
int l7;
142+
int l8;
143+
int l9;
144+
int l10;
145+
int l11;
146+
int l12;
147+
int l13;
148+
int l14;
149+
int l15;
150+
int l16;
151+
152+
l1 = 0;
153+
l2 = 0;
154+
l3 = 0;
155+
l4 = 0;
156+
l5 = 0;
157+
l6 = 0;
158+
l7 = 0;
159+
l8 = 0;
160+
l9 = 0;
161+
l10 = 0;
162+
l11 = 0;
163+
l12 = 0;
164+
l13 = 0;
165+
l14 = 0;
166+
l15 = 0;
167+
l16 = 0;
168+
}
169+
}
170+

0 commit comments

Comments
 (0)