Skip to content

Commit ea56776

Browse files
committedMar 31, 2020
8239072: subtype check macro node causes node budget to be exhausted
Reviewed-by: vlivanov, kvn
1 parent 73ddea7 commit ea56776

File tree

3 files changed

+71
-15
lines changed

3 files changed

+71
-15
lines changed
 

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

+17
Original file line numberDiff line numberDiff line change
@@ -4224,3 +4224,20 @@ void CloneMap::dump(node_idx_t key) const {
42244224
ni.dump();
42254225
}
42264226
}
4227+
4228+
// Move Allocate nodes to the start of the list
4229+
void Compile::sort_macro_nodes() {
4230+
int count = macro_count();
4231+
int allocates = 0;
4232+
for (int i = 0; i < count; i++) {
4233+
Node* n = macro_node(i);
4234+
if (n->is_Allocate()) {
4235+
if (i != allocates) {
4236+
Node* tmp = macro_node(allocates);
4237+
_macro_nodes->at_put(allocates, n);
4238+
_macro_nodes->at_put(i, tmp);
4239+
}
4240+
allocates++;
4241+
}
4242+
}
4243+
}

‎src/hotspot/share/opto/compile.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,8 @@ class Compile : public Phase {
718718
int opaque4_count() const { return _opaque4_nodes->length(); }
719719
void remove_opaque4_nodes(PhaseIterGVN &igvn);
720720

721+
void sort_macro_nodes();
722+
721723
// remove the opaque nodes that protect the predicates so that the unused checks and
722724
// uncommon traps will be eliminated from the graph.
723725
void cleanup_loop_predicates(PhaseIterGVN &igvn);

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

+52-15
Original file line numberDiff line numberDiff line change
@@ -2658,12 +2658,6 @@ bool PhaseMacroExpand::expand_macro_nodes() {
26582658
// Last attempt to eliminate macro nodes.
26592659
eliminate_macro_nodes();
26602660

2661-
// Make sure expansion will not cause node limit to be exceeded.
2662-
// Worst case is a macro node gets expanded into about 200 nodes.
2663-
// Allow 50% more for optimization.
2664-
if (C->check_node_count(C->macro_count() * 300, "out of nodes before macro expansion" ) )
2665-
return true;
2666-
26672661
// Eliminate Opaque and LoopLimit nodes. Do it after all loop optimizations.
26682662
bool progress = true;
26692663
while (progress) {
@@ -2719,17 +2713,44 @@ bool PhaseMacroExpand::expand_macro_nodes() {
27192713
}
27202714
}
27212715

2716+
// Clean up the graph so we're less likely to hit the maximum node
2717+
// limit
2718+
_igvn.set_delay_transform(false);
2719+
_igvn.optimize();
2720+
if (C->failing()) return true;
2721+
_igvn.set_delay_transform(true);
2722+
2723+
2724+
// Because we run IGVN after each expansion, some macro nodes may go
2725+
// dead and be removed from the list as we iterate over it. Move
2726+
// Allocate nodes (processed in a second pass) at the beginning of
2727+
// the list and then iterate from the last element of the list until
2728+
// an Allocate node is seen. This is robust to random deletion in
2729+
// the list due to nodes going dead.
2730+
C->sort_macro_nodes();
2731+
27222732
// expand arraycopy "macro" nodes first
27232733
// For ReduceBulkZeroing, we must first process all arraycopy nodes
27242734
// before the allocate nodes are expanded.
2725-
for (int i = C->macro_count(); i > 0; i--) {
2726-
Node* n = C->macro_node(i-1);
2735+
while (C->macro_count() > 0) {
2736+
int macro_count = C->macro_count();
2737+
Node * n = C->macro_node(macro_count-1);
27272738
assert(n->is_macro(), "only macro nodes expected here");
27282739
if (_igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) {
27292740
// node is unreachable, so don't try to expand it
27302741
C->remove_macro_node(n);
27312742
continue;
27322743
}
2744+
if (n->is_Allocate()) {
2745+
break;
2746+
}
2747+
// Make sure expansion will not cause node limit to be exceeded.
2748+
// Worst case is a macro node gets expanded into about 200 nodes.
2749+
// Allow 50% more for optimization.
2750+
if (C->check_node_count(300, "out of nodes before macro expansion")) {
2751+
return true;
2752+
}
2753+
27332754
debug_only(int old_macro_count = C->macro_count(););
27342755
switch (n->class_id()) {
27352756
case Node::Class_Lock:
@@ -2748,18 +2769,23 @@ bool PhaseMacroExpand::expand_macro_nodes() {
27482769
expand_subtypecheck_node(n->as_SubTypeCheck());
27492770
assert(C->macro_count() == (old_macro_count - 1), "expansion must have deleted one node from macro list");
27502771
break;
2772+
default:
2773+
assert(false, "unknown node type in macro list");
27512774
}
2775+
assert(C->macro_count() < macro_count, "must have deleted a node from macro list");
2776+
if (C->failing()) return true;
2777+
2778+
// Clean up the graph so we're less likely to hit the maximum node
2779+
// limit
2780+
_igvn.set_delay_transform(false);
2781+
_igvn.optimize();
27522782
if (C->failing()) return true;
2783+
_igvn.set_delay_transform(true);
27532784
}
27542785

27552786
// All nodes except Allocate nodes are expanded now. There could be
27562787
// new optimization opportunities (such as folding newly created
27572788
// load from a just allocated object). Run IGVN.
2758-
_igvn.set_delay_transform(false);
2759-
_igvn.optimize();
2760-
if (C->failing()) return true;
2761-
2762-
_igvn.set_delay_transform(true);
27632789

27642790
// expand "macro" nodes
27652791
// nodes are removed from the macro list as they are processed
@@ -2772,6 +2798,12 @@ bool PhaseMacroExpand::expand_macro_nodes() {
27722798
C->remove_macro_node(n);
27732799
continue;
27742800
}
2801+
// Make sure expansion will not cause node limit to be exceeded.
2802+
// Worst case is a macro node gets expanded into about 200 nodes.
2803+
// Allow 50% more for optimization.
2804+
if (C->check_node_count(300, "out of nodes before macro expansion")) {
2805+
return true;
2806+
}
27752807
switch (n->class_id()) {
27762808
case Node::Class_Allocate:
27772809
expand_allocate(n->as_Allocate());
@@ -2784,10 +2816,15 @@ bool PhaseMacroExpand::expand_macro_nodes() {
27842816
}
27852817
assert(C->macro_count() < macro_count, "must have deleted a node from macro list");
27862818
if (C->failing()) return true;
2819+
2820+
// Clean up the graph so we're less likely to hit the maximum node
2821+
// limit
2822+
_igvn.set_delay_transform(false);
2823+
_igvn.optimize();
2824+
if (C->failing()) return true;
2825+
_igvn.set_delay_transform(true);
27872826
}
27882827

27892828
_igvn.set_delay_transform(false);
2790-
_igvn.optimize();
2791-
if (C->failing()) return true;
27922829
return false;
27932830
}

0 commit comments

Comments
 (0)
Please sign in to comment.