Skip to content
This repository was archived by the owner on Sep 19, 2023. It is now read-only.

Commit 3f3bbdf

Browse files
committed
8285835: SIGSEGV in PhaseIdealLoop::build_loop_late_post_work
Backport-of: 8aa1526b443025b8606a3668262f46a9cb6ea6f6
1 parent 4708c7b commit 3f3bbdf

File tree

3 files changed

+145
-10
lines changed

3 files changed

+145
-10
lines changed

src/hotspot/share/opto/escape.cpp

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,9 @@ bool ConnectionGraph::compute_escape() {
281281
// 3. Adjust scalar_replaceable state of nonescaping objects and push
282282
// scalar replaceable allocations on alloc_worklist for processing
283283
// in split_unique_types().
284+
GrowableArray<JavaObjectNode*> jobj_worklist;
284285
int non_escaped_length = non_escaped_allocs_worklist.length();
286+
bool found_nsr_alloc = false;
285287
for (int next = 0; next < non_escaped_length; next++) {
286288
JavaObjectNode* ptn = non_escaped_allocs_worklist.at(next);
287289
bool noescape = (ptn->escape_state() == PointsToNode::NoEscape);
@@ -292,11 +294,25 @@ bool ConnectionGraph::compute_escape() {
292294
if (noescape && ptn->scalar_replaceable()) {
293295
adjust_scalar_replaceable_state(ptn);
294296
if (ptn->scalar_replaceable()) {
295-
alloc_worklist.append(ptn->ideal_node());
297+
jobj_worklist.push(ptn);
298+
} else {
299+
found_nsr_alloc = true;
296300
}
297301
}
298302
}
299303

304+
// Propagate NSR (Not Scalar Replaceable) state.
305+
if (found_nsr_alloc) {
306+
find_scalar_replaceable_allocs(jobj_worklist);
307+
}
308+
309+
for (int next = 0; next < jobj_worklist.length(); ++next) {
310+
JavaObjectNode* jobj = jobj_worklist.at(next);
311+
if (jobj->scalar_replaceable()) {
312+
alloc_worklist.append(jobj->ideal_node());
313+
}
314+
}
315+
300316
#ifdef ASSERT
301317
if (VerifyConnectionGraph) {
302318
// Verify that graph is complete - no new edges could be added or needed.
@@ -1865,15 +1881,19 @@ void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
18651881
set_not_scalar_replaceable(jobj NOT_PRODUCT(COMMA "is stored at unknown offset"));
18661882
return;
18671883
}
1868-
// 2. An object is not scalar replaceable if the field into which it is
1869-
// stored has multiple bases one of which is null.
1870-
if (field->base_count() > 1) {
1871-
for (BaseIterator i(field); i.has_next(); i.next()) {
1872-
PointsToNode* base = i.get();
1873-
if (base == null_obj) {
1874-
set_not_scalar_replaceable(jobj NOT_PRODUCT(COMMA "is stored into field with potentially null base"));
1875-
return;
1876-
}
1884+
for (BaseIterator i(field); i.has_next(); i.next()) {
1885+
PointsToNode* base = i.get();
1886+
// 2. An object is not scalar replaceable if the field into which it is
1887+
// stored has multiple bases one of which is null.
1888+
if ((base == null_obj) && (field->base_count() > 1)) {
1889+
set_not_scalar_replaceable(jobj NOT_PRODUCT(COMMA "is stored into field with potentially null base"));
1890+
return;
1891+
}
1892+
// 2.5. An object is not scalar replaceable if the field into which it is
1893+
// stored has NSR base.
1894+
if (!base->scalar_replaceable()) {
1895+
set_not_scalar_replaceable(jobj NOT_PRODUCT(COMMA "is stored into field with NSR base"));
1896+
return;
18771897
}
18781898
}
18791899
}
@@ -1963,6 +1983,36 @@ void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
19631983
}
19641984
}
19651985

1986+
// Propagate NSR (Not scalar replaceable) state.
1987+
void ConnectionGraph::find_scalar_replaceable_allocs(GrowableArray<JavaObjectNode*>& jobj_worklist) {
1988+
int jobj_length = jobj_worklist.length();
1989+
bool found_nsr_alloc = true;
1990+
while (found_nsr_alloc) {
1991+
found_nsr_alloc = false;
1992+
for (int next = 0; next < jobj_length; ++next) {
1993+
JavaObjectNode* jobj = jobj_worklist.at(next);
1994+
for (UseIterator i(jobj); (jobj->scalar_replaceable() && i.has_next()); i.next()) {
1995+
PointsToNode* use = i.get();
1996+
if (use->is_Field()) {
1997+
FieldNode* field = use->as_Field();
1998+
assert(field->is_oop() && field->scalar_replaceable(), "sanity");
1999+
assert(field->offset() != Type::OffsetBot, "sanity");
2000+
for (BaseIterator i(field); i.has_next(); i.next()) {
2001+
PointsToNode* base = i.get();
2002+
// An object is not scalar replaceable if the field into which
2003+
// it is stored has NSR base.
2004+
if ((base != null_obj) && !base->scalar_replaceable()) {
2005+
set_not_scalar_replaceable(jobj NOT_PRODUCT(COMMA "is stored into field with NSR base"));
2006+
found_nsr_alloc = true;
2007+
break;
2008+
}
2009+
}
2010+
}
2011+
}
2012+
}
2013+
}
2014+
}
2015+
19662016
#ifdef ASSERT
19672017
void ConnectionGraph::verify_connection_graph(
19682018
GrowableArray<PointsToNode*>& ptnodes_worklist,

src/hotspot/share/opto/escape.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,9 @@ class ConnectionGraph: public ResourceObj {
463463
// Adjust scalar_replaceable state after Connection Graph is built.
464464
void adjust_scalar_replaceable_state(JavaObjectNode* jobj);
465465

466+
// Propagate NSR (Not scalar replaceable) state.
467+
void find_scalar_replaceable_allocs(GrowableArray<JavaObjectNode*>& jobj_worklist);
468+
466469
// Optimize ideal graph.
467470
void optimize_ideal_graph(GrowableArray<Node*>& ptr_cmp_worklist,
468471
GrowableArray<MemBarStoreStoreNode*>& storestore_worklist);
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3+
*
4+
* This code is free software; you can redistribute it and/or modify it
5+
* under the terms of the GNU General Public License version 2 only, as
6+
* published by the Free Software Foundation.
7+
*
8+
* This code is distributed in the hope that it will be useful, but WITHOUT
9+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11+
* version 2 for more details (a copy is included in the LICENSE file that
12+
* accompanied this code).
13+
*
14+
* You should have received a copy of the GNU General Public License version
15+
* 2 along with this work; if not, write to the Free Software Foundation,
16+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17+
*
18+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
19+
* or visit www.oracle.com if you need additional information or have any
20+
* questions.
21+
*/
22+
23+
/*
24+
* @test
25+
* @bug 8285835
26+
* @summary EA does not propagate NSR (not scalar replaceable) state.
27+
* @run main/othervm -XX:-TieredCompilation -XX:-BackgroundCompilation -XX:-UseOnStackReplacement TestBrokenEA
28+
*/
29+
30+
public class TestBrokenEA {
31+
32+
public static void main(String[] args) {
33+
for (int i = 0; i < 20_000; i++) {
34+
test1(true);
35+
test1(false);
36+
test2(true);
37+
test2(false);
38+
}
39+
}
40+
41+
private static void test1(boolean flag) {
42+
A[] array = new A[1];
43+
if (flag) {
44+
C c = new C();
45+
B b = new B();
46+
b.c = c;
47+
A a = new A();
48+
a.b = b;
49+
array[0] = a;
50+
}
51+
A a = array[0];
52+
if (a != null) {
53+
a.b.c.f = 0x42;
54+
}
55+
}
56+
57+
private static void test2(boolean flag) {
58+
A a = null;
59+
if (flag) {
60+
C c = new C();
61+
B b = new B();
62+
b.c = c;
63+
a = new A();
64+
a.b = b;
65+
}
66+
if (a != null) {
67+
a.b.c.f = 0x42;
68+
}
69+
}
70+
71+
private static class A {
72+
public B b;
73+
}
74+
75+
private static class B {
76+
public C c;
77+
}
78+
79+
private static class C {
80+
public int f;
81+
}
82+
}

0 commit comments

Comments
 (0)