8279219: [REDO] C2 crash when allocating array of size too large

Reviewed-by: thartmann, neliasso
This commit is contained in:
Roland Westrelin 2022-02-02 07:34:22 +00:00
parent 85d839fb4f
commit d32f99ee65
11 changed files with 254 additions and 76 deletions

View file

@ -3812,7 +3812,7 @@ bool Compile::final_graph_reshaping() {
// 'fall-thru' path, so expected kids is 1 less.
if (n->is_PCTable() && n->in(0) && n->in(0)->in(0)) {
if (n->in(0)->in(0)->is_Call()) {
CallNode *call = n->in(0)->in(0)->as_Call();
CallNode* call = n->in(0)->in(0)->as_Call();
if (call->entry_point() == OptoRuntime::rethrow_stub()) {
required_outcnt--; // Rethrow always has 1 less kid
} else if (call->req() > TypeFunc::Parms &&
@ -3821,22 +3821,25 @@ bool Compile::final_graph_reshaping() {
// detected that the virtual call will always result in a null
// pointer exception. The fall-through projection of this CatchNode
// will not be populated.
Node *arg0 = call->in(TypeFunc::Parms);
Node* arg0 = call->in(TypeFunc::Parms);
if (arg0->is_Type() &&
arg0->as_Type()->type()->higher_equal(TypePtr::NULL_PTR)) {
required_outcnt--;
}
} else if (call->entry_point() == OptoRuntime::new_array_Java() &&
call->req() > TypeFunc::Parms+1 &&
call->is_CallStaticJava()) {
// Check for negative array length. In such case, the optimizer has
} else if (call->entry_point() == OptoRuntime::new_array_Java() ||
call->entry_point() == OptoRuntime::new_array_nozero_Java()) {
// Check for illegal array length. In such case, the optimizer has
// detected that the allocation attempt will always result in an
// exception. There is no fall-through projection of this CatchNode .
Node *arg1 = call->in(TypeFunc::Parms+1);
if (arg1->is_Type() &&
arg1->as_Type()->type()->join(TypeInt::POS)->empty()) {
assert(call->is_CallStaticJava(), "static call expected");
assert(call->req() == call->jvms()->endoff() + 1, "missing extra input");
Node* valid_length_test = call->in(call->req()-1);
call->del_req(call->req()-1);
if (valid_length_test->find_int_con(1) == 0) {
required_outcnt--;
}
assert(n->outcnt() == required_outcnt, "malformed control flow");
continue;
}
}
}
@ -3845,6 +3848,14 @@ bool Compile::final_graph_reshaping() {
record_method_not_compilable("malformed control flow");
return true; // Not all targets reachable!
}
} else if (n->is_PCTable() && n->in(0) && n->in(0)->in(0) && n->in(0)->in(0)->is_Call()) {
CallNode* call = n->in(0)->in(0)->as_Call();
if (call->entry_point() == OptoRuntime::new_array_Java() ||
call->entry_point() == OptoRuntime::new_array_nozero_Java()) {
assert(call->is_CallStaticJava(), "static call expected");
assert(call->req() == call->jvms()->endoff() + 1, "missing extra input");
call->del_req(call->req()-1); // valid length test useless now
}
}
// Check that I actually visited all kids. Unreached kids
// must be infinite loops.