Skip to content

Commit 3bddee5

Browse files
committed
8210392: assert(Compile::current()->live_nodes() < Compile::current()->max_node_limit()) failed: Live Node limit exceeded limit
Avoid excessive split-if. Backport-of: a17df8d
1 parent 54a9e3c commit 3bddee5

File tree

3 files changed

+89
-12
lines changed

3 files changed

+89
-12
lines changed

src/hotspot/share/opto/loopnode.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,14 @@ SHENANDOAHGC_ONLY(private:)
13071307
ProjNode* output_proj, IdealLoopTree* loop);
13081308
void check_created_predicate_for_unswitching(const Node* new_entry) const PRODUCT_RETURN;
13091309

1310+
// Determine if a method is too big for a/another round of split-if, based on
1311+
// a magic (approximate) ratio derived from the equally magic constant 35000,
1312+
// previously used for this purpose (but without relating to the node limit).
1313+
bool must_throttle_split_if() {
1314+
uint threshold = C->max_node_limit() * 2 / 5;
1315+
return C->live_nodes() > threshold;
1316+
}
1317+
13101318
bool _created_loop_node;
13111319
#ifdef ASSERT
13121320
void dump_real_LCA(Node* early, Node* wrong_lca);

src/hotspot/share/opto/loopopts.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1009,8 +1009,7 @@ Node *PhaseIdealLoop::split_if_with_blocks_pre( Node *n ) {
10091009
}
10101010
}
10111011

1012-
// Use same limit as split_if_with_blocks_post
1013-
if( C->live_nodes() > 35000 ) return n; // Method too big
1012+
if (must_throttle_split_if()) return n;
10141013

10151014
// Split 'n' through the merge point if it is profitable
10161015
Node *phi = split_thru_phi( n, n_blk, policy );
@@ -1118,9 +1117,10 @@ bool PhaseIdealLoop::identical_backtoback_ifs(Node *n) {
11181117
return true;
11191118
}
11201119

1121-
bool PhaseIdealLoop::can_split_if(Node *n_ctrl) {
1122-
if (C->live_nodes() > 35000) {
1123-
return false; // Method too big
1120+
1121+
bool PhaseIdealLoop::can_split_if(Node* n_ctrl) {
1122+
if (must_throttle_split_if()) {
1123+
return false;
11241124
}
11251125

11261126
// Do not do 'split-if' if irreducible loops are present.
@@ -1483,20 +1483,21 @@ void PhaseIdealLoop::split_if_with_blocks_post(Node *n, bool last_round) {
14831483
// Check for aggressive application of 'split-if' optimization,
14841484
// using basic block level info.
14851485
void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack, bool last_round) {
1486-
Node *n = C->root();
1487-
visited.set(n->_idx); // first, mark node as visited
1486+
Node* root = C->root();
1487+
visited.set(root->_idx); // first, mark root as visited
14881488
// Do pre-visit work for root
1489-
n = split_if_with_blocks_pre( n );
1490-
uint cnt = n->outcnt();
1491-
uint i = 0;
1489+
Node* n = split_if_with_blocks_pre(root);
1490+
uint cnt = n->outcnt();
1491+
uint i = 0;
1492+
14921493
while (true) {
14931494
// Visit all children
14941495
if (i < cnt) {
14951496
Node* use = n->raw_out(i);
14961497
++i;
14971498
if (use->outcnt() != 0 && !visited.test_set(use->_idx)) {
14981499
// Now do pre-visit work for this use
1499-
use = split_if_with_blocks_pre( use );
1500+
use = split_if_with_blocks_pre(use);
15001501
nstack.push(n, i); // Save parent and next use's index.
15011502
n = use; // Process all children of current use.
15021503
cnt = use->outcnt();
@@ -1507,7 +1508,10 @@ void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack
15071508
// All of n's children have been processed, complete post-processing.
15081509
if (cnt != 0 && !n->is_Con()) {
15091510
assert(has_node(n), "no dead nodes");
1510-
split_if_with_blocks_post( n, last_round );
1511+
split_if_with_blocks_post(n, last_round);
1512+
}
1513+
if (must_throttle_split_if()) {
1514+
nstack.clear();
15111515
}
15121516
if (nstack.is_empty()) {
15131517
// Finished all nodes on stack.
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (c) 2019, 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 8210392
27+
* @summary C2 Assert failure: Live node limit exceeded
28+
*
29+
* @run main/othervm compiler.loopopts.Test8210392
30+
*/
31+
32+
package compiler.loopopts;
33+
34+
public class Test8210392 {
35+
public static int ival = 17;
36+
37+
public static int intFn() {
38+
int v = 0, k = 0;
39+
for (int i = 17; i < 311; i += 3) {
40+
v = Test8210392.ival;
41+
int j = 1;
42+
do {
43+
v *= i;
44+
v += j * v;
45+
while (++k < 1)
46+
;
47+
} while (++j < 13);
48+
}
49+
return v;
50+
}
51+
52+
public void mainTest() {
53+
for (int i = 0; i < 30000; i++) {
54+
Test8210392.ival = intFn();
55+
}
56+
}
57+
58+
public static void main(String[] _args) {
59+
Test8210392 tc = new Test8210392();
60+
for (int i = 0; i < 10; i++) {
61+
tc.mainTest();
62+
}
63+
}
64+
}
65+

0 commit comments

Comments
 (0)