Skip to content

Commit 7d8bd21

Browse files
Cesar Soares Lucaschhagedorn
andcommitted
8335977: Deoptimization fails with assert "object should be reallocated already"
Co-authored-by: Christian Hagedorn <chagedorn@openjdk.org> Reviewed-by: thartmann, kvn, vlivanov
1 parent b269493 commit 7d8bd21

File tree

2 files changed

+106
-7
lines changed

2 files changed

+106
-7
lines changed

src/hotspot/share/opto/output.cpp

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,14 @@ void PhaseOutput::FillLocArray( int idx, MachSafePointNode* sfpt, Node *local,
792792

793793
for (uint i = 1; i < smerge->req(); i++) {
794794
Node* obj_node = smerge->in(i);
795-
(void)FillLocArray(mv->possible_objects()->length(), sfpt, obj_node, mv->possible_objects(), objs);
795+
int idx = mv->possible_objects()->length();
796+
(void)FillLocArray(idx, sfpt, obj_node, mv->possible_objects(), objs);
797+
798+
// By default ObjectValues that are in 'possible_objects' are not root objects.
799+
// They will be marked as root later if they are directly referenced in a JVMS.
800+
assert(mv->possible_objects()->length() > idx, "Didn't add entry to possible_objects?!");
801+
assert(mv->possible_objects()->at(idx)->is_object(), "Entries in possible_objects should be ObjectValue.");
802+
mv->possible_objects()->at(idx)->as_ObjectValue()->set_root(false);
796803
}
797804
}
798805
array->append(mv);
@@ -1127,7 +1134,14 @@ void PhaseOutput::Process_OopMap_Node(MachNode *mach, int current_offset) {
11271134

11281135
for (uint i = 1; i < smerge->req(); i++) {
11291136
Node* obj_node = smerge->in(i);
1130-
FillLocArray(mv->possible_objects()->length(), sfn, obj_node, mv->possible_objects(), objs);
1137+
int idx = mv->possible_objects()->length();
1138+
(void)FillLocArray(idx, sfn, obj_node, mv->possible_objects(), objs);
1139+
1140+
// By default ObjectValues that are in 'possible_objects' are not root objects.
1141+
// They will be marked as root later if they are directly referenced in a JVMS.
1142+
assert(mv->possible_objects()->length() > idx, "Didn't add entry to possible_objects?!");
1143+
assert(mv->possible_objects()->at(idx)->is_object(), "Entries in possible_objects should be ObjectValue.");
1144+
mv->possible_objects()->at(idx)->as_ObjectValue()->set_root(false);
11311145
}
11321146
}
11331147
scval = mv;
@@ -1158,11 +1172,17 @@ void PhaseOutput::Process_OopMap_Node(MachNode *mach, int current_offset) {
11581172

11591173
for (int j = 0; j< merge->possible_objects()->length(); j++) {
11601174
ObjectValue* ov = merge->possible_objects()->at(j)->as_ObjectValue();
1161-
bool is_root = locarray->contains(ov) ||
1162-
exparray->contains(ov) ||
1163-
contains_as_owner(monarray, ov) ||
1164-
contains_as_scalarized_obj(jvms, sfn, objs, ov);
1165-
ov->set_root(is_root);
1175+
if (ov->is_root()) {
1176+
// Already flagged as 'root' by something else. We shouldn't change it
1177+
// to non-root in a younger JVMS because it may need to be alive in
1178+
// a younger JVMS.
1179+
} else {
1180+
bool is_root = locarray->contains(ov) ||
1181+
exparray->contains(ov) ||
1182+
contains_as_owner(monarray, ov) ||
1183+
contains_as_scalarized_obj(jvms, sfn, objs, ov);
1184+
ov->set_root(is_root);
1185+
}
11661186
}
11671187
}
11681188
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2024, 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 8335977
27+
* @summary Check that Reduce Allocation Merges doesn't crash when there
28+
* is an uncommon_trap with a chain of JVMS and, the reduced phi
29+
* input(s) are local(s) in an old JVMS but not in a younger JVMS.
30+
* I.e., check that we don't lose track of "_is_root" when traversing
31+
* a JVMS chain.
32+
* @run main/othervm -Xbatch
33+
* -XX:CompileOnly=compiler.escapeAnalysis.TestReduceAllocationAndJVMStates::test*
34+
* compiler.escapeAnalysis.TestReduceAllocationAndJVMStates
35+
* @run main compiler.escapeAnalysis.TestReduceAllocationAndJVMStates
36+
*/
37+
package compiler.escapeAnalysis;
38+
39+
public class TestReduceAllocationAndJVMStates {
40+
static boolean bFld;
41+
static int iFld;
42+
43+
public static void main(String[] args) {
44+
bFld = false;
45+
46+
for (int i = 0; i < 10000; i++) {
47+
test(i % 2 == 0);
48+
}
49+
bFld = true;
50+
51+
// This will trigger a deoptimization which
52+
// will make the issue manifest to the user
53+
test(true);
54+
}
55+
56+
static int test(boolean flag) {
57+
Super a = new A();
58+
Super b = new B();
59+
Super s = (flag ? a : b);
60+
61+
// This needs to be inlined by C2
62+
check();
63+
64+
return a.i + b.i + s.i;
65+
}
66+
67+
// This shouldn't be manually inlined
68+
static void check() {
69+
if (bFld) {
70+
iFld = 34;
71+
}
72+
}
73+
}
74+
75+
class Super {
76+
int i;
77+
}
78+
class A extends Super {}
79+
class B extends Super {}

0 commit comments

Comments
 (0)