Skip to content

Commit 6d54f99

Browse files
author
duke
committed
Backport ff2f39f
1 parent d1bd5c0 commit 6d54f99

File tree

4 files changed

+123
-12
lines changed

4 files changed

+123
-12
lines changed

src/hotspot/share/opto/compile.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1483,12 +1483,18 @@ const TypePtr *Compile::flatten_alias_type( const TypePtr *tj ) const {
14831483
} else {
14841484
ciInstanceKlass *canonical_holder = ik->get_canonical_holder(offset);
14851485
assert(offset < canonical_holder->layout_helper_size_in_bytes(), "");
1486-
if (!ik->equals(canonical_holder) || tj->offset() != offset) {
1487-
if( is_known_inst ) {
1488-
tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, true, nullptr, offset, to->instance_id());
1489-
} else {
1490-
tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, false, nullptr, offset);
1491-
}
1486+
assert(tj->offset() == offset, "no change to offset expected");
1487+
bool xk = to->klass_is_exact();
1488+
int instance_id = to->instance_id();
1489+
1490+
// If the input type's class is the holder: if exact, the type only includes interfaces implemented by the holder
1491+
// but if not exact, it may include extra interfaces: build new type from the holder class to make sure only
1492+
// its interfaces are included.
1493+
if (xk && ik->equals(canonical_holder)) {
1494+
assert(tj == TypeInstPtr::make(to->ptr(), canonical_holder, is_known_inst, nullptr, offset, instance_id), "exact type should be canonical type");
1495+
} else {
1496+
assert(xk || !is_known_inst, "Known instance should be exact type");
1497+
tj = to = TypeInstPtr::make(to->ptr(), canonical_holder, is_known_inst, nullptr, offset, instance_id);
14921498
}
14931499
}
14941500
}

src/hotspot/share/opto/graphKit.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1556,6 +1556,7 @@ Node* GraphKit::make_load(Node* ctl, Node* adr, const Type* t, BasicType bt,
15561556
bool mismatched,
15571557
bool unsafe,
15581558
uint8_t barrier_data) {
1559+
assert(adr_idx == C->get_alias_index(_gvn.type(adr)->isa_ptr()), "slice of address and input slice don't match");
15591560
assert(adr_idx != Compile::AliasIdxTop, "use other make_load factory" );
15601561
const TypePtr* adr_type = nullptr; // debug-mode-only argument
15611562
debug_only(adr_type = C->get_adr_type(adr_idx));
@@ -1585,6 +1586,7 @@ Node* GraphKit::store_to_memory(Node* ctl, Node* adr, Node *val, BasicType bt,
15851586
bool unsafe,
15861587
int barrier_data) {
15871588
assert(adr_idx != Compile::AliasIdxTop, "use other store_to_memory factory" );
1589+
assert(adr_idx == C->get_alias_index(_gvn.type(adr)->isa_ptr()), "slice of address and input slice don't match");
15881590
const TypePtr* adr_type = nullptr;
15891591
debug_only(adr_type = C->get_adr_type(adr_idx));
15901592
Node *mem = memory(adr_idx);

src/hotspot/share/opto/library_call.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,11 +2921,10 @@ bool LibraryCallKit::inline_native_notify_jvmti_funcs(address funcAddr, const ch
29212921
Node* thread = ideal.thread();
29222922
Node* jt_addr = basic_plus_adr(thread, in_bytes(JavaThread::is_in_VTMS_transition_offset()));
29232923
Node* vt_addr = basic_plus_adr(vt_oop, java_lang_Thread::is_in_VTMS_transition_offset());
2924-
const TypePtr *addr_type = _gvn.type(addr)->isa_ptr();
29252924

29262925
sync_kit(ideal);
2927-
access_store_at(nullptr, jt_addr, addr_type, hide, _gvn.type(hide), T_BOOLEAN, IN_NATIVE | MO_UNORDERED);
2928-
access_store_at(nullptr, vt_addr, addr_type, hide, _gvn.type(hide), T_BOOLEAN, IN_NATIVE | MO_UNORDERED);
2926+
access_store_at(nullptr, jt_addr, _gvn.type(jt_addr)->is_ptr(), hide, _gvn.type(hide), T_BOOLEAN, IN_NATIVE | MO_UNORDERED);
2927+
access_store_at(nullptr, vt_addr, _gvn.type(vt_addr)->is_ptr(), hide, _gvn.type(hide), T_BOOLEAN, IN_NATIVE | MO_UNORDERED);
29292928

29302929
ideal.sync_kit(this);
29312930
} ideal.end_if();
@@ -3283,7 +3282,9 @@ bool LibraryCallKit::inline_native_getEventWriter() {
32833282

32843283
// Load the raw epoch value from the threadObj.
32853284
Node* threadObj_epoch_offset = basic_plus_adr(threadObj, java_lang_Thread::jfr_epoch_offset());
3286-
Node* threadObj_epoch_raw = access_load_at(threadObj, threadObj_epoch_offset, TypeRawPtr::BOTTOM, TypeInt::CHAR, T_CHAR,
3285+
Node* threadObj_epoch_raw = access_load_at(threadObj, threadObj_epoch_offset,
3286+
_gvn.type(threadObj_epoch_offset)->isa_ptr(),
3287+
TypeInt::CHAR, T_CHAR,
32873288
IN_HEAP | MO_UNORDERED | C2_MISMATCHED | C2_CONTROL_DEPENDENT_LOAD);
32883289

32893290
// Mask off the excluded information from the epoch.
@@ -3298,7 +3299,8 @@ bool LibraryCallKit::inline_native_getEventWriter() {
32983299

32993300
// Load the raw epoch value from the vthread.
33003301
Node* vthread_epoch_offset = basic_plus_adr(vthread, java_lang_Thread::jfr_epoch_offset());
3301-
Node* vthread_epoch_raw = access_load_at(vthread, vthread_epoch_offset, TypeRawPtr::BOTTOM, TypeInt::CHAR, T_CHAR,
3302+
Node* vthread_epoch_raw = access_load_at(vthread, vthread_epoch_offset, _gvn.type(vthread_epoch_offset)->is_ptr(),
3303+
TypeInt::CHAR, T_CHAR,
33023304
IN_HEAP | MO_UNORDERED | C2_MISMATCHED | C2_CONTROL_DEPENDENT_LOAD);
33033305

33043306
// Mask off the excluded information from the epoch.
@@ -3534,7 +3536,7 @@ void LibraryCallKit::extend_setCurrentThread(Node* jt, Node* thread) {
35343536

35353537
// Load the raw epoch value from the vthread.
35363538
Node* epoch_offset = basic_plus_adr(thread, java_lang_Thread::jfr_epoch_offset());
3537-
Node* epoch_raw = access_load_at(thread, epoch_offset, TypeRawPtr::BOTTOM, TypeInt::CHAR, T_CHAR,
3539+
Node* epoch_raw = access_load_at(thread, epoch_offset, _gvn.type(epoch_offset)->is_ptr(), TypeInt::CHAR, T_CHAR,
35383540
IN_HEAP | MO_UNORDERED | C2_MISMATCHED | C2_CONTROL_DEPENDENT_LOAD);
35393541

35403542
// Mask off the excluded information from the epoch.
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
/*
2+
* Copyright (c) 2024, Red Hat, Inc. 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 8340214
27+
* @summary C2 compilation asserts with "no node with a side effect" in PhaseIdealLoop::try_sink_out_of_loop
28+
*
29+
* @run main/othervm -XX:-BackgroundCompilation TestBadMemSliceWithInterfaces
30+
*
31+
*/
32+
33+
public class TestBadMemSliceWithInterfaces {
34+
public static void main(String[] args) {
35+
B b = new B();
36+
C c = new C();
37+
for (int i = 0; i < 20_000; i++) {
38+
test1(b, c, true);
39+
test1(b, c, false);
40+
b.field = 0;
41+
c.field = 0;
42+
int res = test2(b, c, true);
43+
if (res != 42) {
44+
throw new RuntimeException("incorrect result " + res);
45+
}
46+
res = test2(b, c, false);
47+
if (res != 42) {
48+
throw new RuntimeException("incorrect result " + res);
49+
}
50+
}
51+
}
52+
53+
private static void test1(B b, C c, boolean flag) {
54+
A a;
55+
if (flag) {
56+
a = b;
57+
} else {
58+
a = c;
59+
}
60+
for (int i = 0; i < 1000; i++) {
61+
a.field = 42;
62+
}
63+
}
64+
65+
private static int test2(B b, C c, boolean flag) {
66+
A a;
67+
if (flag) {
68+
a = b;
69+
} else {
70+
a = c;
71+
}
72+
int v = 0;
73+
for (int i = 0; i < 2; i++) {
74+
v += a.field;
75+
a.field = 42;
76+
}
77+
return v;
78+
}
79+
80+
interface I {
81+
void m();
82+
}
83+
84+
static class A {
85+
int field;
86+
}
87+
88+
static class B extends A implements I {
89+
@Override
90+
public void m() {
91+
92+
}
93+
}
94+
95+
static class C extends A implements I {
96+
@Override
97+
public void m() {
98+
99+
}
100+
}
101+
}

0 commit comments

Comments
 (0)