Skip to content

Commit 89ee611

Browse files
committedOct 4, 2021
8223923: C2: Missing interference with mismatched unsafe accesses
Backport-of: 86add21a85ec57de00aecb0a18bc99567a91d0d8
1 parent f12af7e commit 89ee611

File tree

2 files changed

+82
-8
lines changed

2 files changed

+82
-8
lines changed
 

‎src/hotspot/share/opto/memnode.cpp

+9-8
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ Node* LoadNode::find_previous_arraycopy(PhaseTransform* phase, Node* ld_alloc, N
592592

593593
ArrayCopyNode* MemNode::find_array_copy_clone(PhaseTransform* phase, Node* ld_alloc, Node* mem) const {
594594
if (mem->is_Proj() && mem->in(0) != NULL && (mem->in(0)->Opcode() == Op_MemBarStoreStore ||
595-
mem->in(0)->Opcode() == Op_MemBarCPUOrder)) {
595+
mem->in(0)->Opcode() == Op_MemBarCPUOrder)) {
596596
if (ld_alloc != NULL) {
597597
// Check if there is an array copy for a clone
598598
Node* mb = mem->in(0);
@@ -1060,25 +1060,26 @@ Node* MemNode::can_see_stored_value(Node* st, PhaseTransform* phase) const {
10601060
// This is more general than load from boxing objects.
10611061
if (skip_through_membars(atp, tp, phase->C->eliminate_boxing())) {
10621062
uint alias_idx = atp->index();
1063-
bool final = !atp->is_rewritable();
10641063
Node* result = NULL;
10651064
Node* current = st;
10661065
// Skip through chains of MemBarNodes checking the MergeMems for
10671066
// new states for the slice of this load. Stop once any other
10681067
// kind of node is encountered. Loads from final memory can skip
10691068
// through any kind of MemBar but normal loads shouldn't skip
10701069
// through MemBarAcquire since the could allow them to move out of
1071-
// a synchronized region.
1070+
// a synchronized region. It is not safe to step over MemBarCPUOrder,
1071+
// because alias info above them may be inaccurate (e.g., due to
1072+
// mixed/mismatched unsafe accesses).
1073+
bool is_final_mem = !atp->is_rewritable();
10721074
while (current->is_Proj()) {
10731075
int opc = current->in(0)->Opcode();
1074-
if ((final && (opc == Op_MemBarAcquire ||
1075-
opc == Op_MemBarAcquireLock ||
1076-
opc == Op_LoadFence)) ||
1076+
if ((is_final_mem && (opc == Op_MemBarAcquire ||
1077+
opc == Op_MemBarAcquireLock ||
1078+
opc == Op_LoadFence)) ||
10771079
opc == Op_MemBarRelease ||
10781080
opc == Op_StoreFence ||
10791081
opc == Op_MemBarReleaseLock ||
1080-
opc == Op_MemBarStoreStore ||
1081-
opc == Op_MemBarCPUOrder) {
1082+
opc == Op_MemBarStoreStore) {
10821083
Node* mem = current->in(0)->in(TypeFunc::Memory);
10831084
if (mem->is_MergeMem()) {
10841085
MergeMemNode* merge = mem->as_MergeMem();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
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+
/*
25+
* @test
26+
* @bug 8223923
27+
* @modules java.base/jdk.internal.misc
28+
* @run main/othervm -Xbatch compiler.unsafe.MismatchedUnsafeAccessTest
29+
*/
30+
package compiler.unsafe;
31+
32+
import jdk.internal.misc.Unsafe;
33+
34+
public class MismatchedUnsafeAccessTest {
35+
private static final Unsafe UNSAFE = Unsafe.getUnsafe();
36+
37+
public static class Test {
38+
public int x = 0;
39+
public int y = 0;
40+
41+
public static final long offsetX;
42+
public static final long offsetY;
43+
44+
static {
45+
try {
46+
offsetX = UNSAFE.objectFieldOffset(Test.class.getField("x"));
47+
offsetY = UNSAFE.objectFieldOffset(Test.class.getField("y"));
48+
} catch (NoSuchFieldException e) {
49+
throw new InternalError(e);
50+
}
51+
// Validate offsets
52+
if (offsetX >= offsetY || offsetY - offsetX != 4) {
53+
throw new InternalError("Wrong offsets: " + offsetX + " " + offsetY);
54+
}
55+
}
56+
}
57+
58+
public static int test(long l) {
59+
Test a = new Test();
60+
UNSAFE.putLong(a, Test.offsetX, l); // mismatched access; interferes with subsequent load
61+
return UNSAFE.getInt(a, Test.offsetY);
62+
}
63+
64+
public static void main(String[] args) {
65+
for (int i = 0; i < 20_000; i++) {
66+
int res = test(-1L);
67+
if (res != -1) {
68+
throw new AssertionError("Wrong result: " + res);
69+
}
70+
}
71+
System.out.println("TEST PASSED");
72+
}
73+
}

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on Oct 4, 2021

@openjdk-notifier[bot]
Please sign in to comment.