8234616: assert(0 <= i && i < _len) failed: illegal index in PhaseMacroExpand::expand_macro_nodes()

Make sure the index into the macro node array is decremented on removal.

Reviewed-by: vlivanov, kvn
This commit is contained in:
Tobias Hartmann 2019-12-04 07:07:21 +01:00
parent 503a960e7d
commit b0812b2802

@ -2533,7 +2533,7 @@ bool PhaseMacroExpand::expand_macro_nodes() {
while (progress) { while (progress) {
progress = false; progress = false;
for (int i = C->macro_count(); i > 0; i--) { for (int i = C->macro_count(); i > 0; i--) {
Node * n = C->macro_node(i-1); Node* n = C->macro_node(i-1);
bool success = false; bool success = false;
debug_only(int old_macro_count = C->macro_count();); debug_only(int old_macro_count = C->macro_count(););
if (n->Opcode() == Op_LoopLimit) { if (n->Opcode() == Op_LoopLimit) {
@ -2578,7 +2578,7 @@ bool PhaseMacroExpand::expand_macro_nodes() {
C->remove_macro_node(n); C->remove_macro_node(n);
success = true; success = true;
} }
assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count"); assert(!success || (C->macro_count() == (old_macro_count - 1)), "elimination must have deleted one node from macro list");
progress = progress || success; progress = progress || success;
} }
} }
@ -2586,32 +2586,30 @@ bool PhaseMacroExpand::expand_macro_nodes() {
// expand arraycopy "macro" nodes first // expand arraycopy "macro" nodes first
// For ReduceBulkZeroing, we must first process all arraycopy nodes // For ReduceBulkZeroing, we must first process all arraycopy nodes
// before the allocate nodes are expanded. // before the allocate nodes are expanded.
int macro_idx = C->macro_count() - 1; for (int i = C->macro_count(); i > 0; i--) {
while (macro_idx >= 0) { Node* n = C->macro_node(i-1);
Node * n = C->macro_node(macro_idx);
assert(n->is_macro(), "only macro nodes expected here"); assert(n->is_macro(), "only macro nodes expected here");
if (_igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) { if (_igvn.type(n) == Type::TOP || (n->in(0) != NULL && n->in(0)->is_top())) {
// node is unreachable, so don't try to expand it // node is unreachable, so don't try to expand it
C->remove_macro_node(n); C->remove_macro_node(n);
continue; continue;
} }
int macro_count = C->macro_count(); debug_only(int old_macro_count = C->macro_count(););
switch (n->class_id()) { switch (n->class_id()) {
case Node::Class_Lock: case Node::Class_Lock:
expand_lock_node(n->as_Lock()); expand_lock_node(n->as_Lock());
assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); assert(C->macro_count() == (old_macro_count - 1), "expansion must have deleted one node from macro list");
break; break;
case Node::Class_Unlock: case Node::Class_Unlock:
expand_unlock_node(n->as_Unlock()); expand_unlock_node(n->as_Unlock());
assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); assert(C->macro_count() == (old_macro_count - 1), "expansion must have deleted one node from macro list");
break; break;
case Node::Class_ArrayCopy: case Node::Class_ArrayCopy:
expand_arraycopy_node(n->as_ArrayCopy()); expand_arraycopy_node(n->as_ArrayCopy());
assert(C->macro_count() < macro_count, "must have deleted a node from macro list"); assert(C->macro_count() == (old_macro_count - 1), "expansion must have deleted one node from macro list");
break; break;
} }
if (C->failing()) return true; if (C->failing()) return true;
macro_idx --;
} }
// All nodes except Allocate nodes are expanded now. There could be // All nodes except Allocate nodes are expanded now. There could be