8312200: Fix Parse::catch_call_exceptions memory leak

Reviewed-by: kvn, thartmann
This commit is contained in:
Johan Sjölen 2023-07-19 09:03:53 +00:00
parent f677793d02
commit d33e8e6f93

@ -790,9 +790,10 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
Node* i_o = this->i_o(); Node* i_o = this->i_o();
// Add a CatchNode. // Add a CatchNode.
GrowableArray<int>* bcis = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, -1); Arena tmp_mem{mtCompiler};
GrowableArray<const Type*>* extypes = new (C->node_arena()) GrowableArray<const Type*>(C->node_arena(), 8, 0, nullptr); GrowableArray<int> bcis(&tmp_mem, 8, 0, -1);
GrowableArray<int>* saw_unloaded = new (C->node_arena()) GrowableArray<int>(C->node_arena(), 8, 0, 0); GrowableArray<const Type*> extypes(&tmp_mem, 8, 0, nullptr);
GrowableArray<int> saw_unloaded(&tmp_mem, 8, 0, -1);
bool default_handler = false; bool default_handler = false;
for (; !handlers.is_done(); handlers.next()) { for (; !handlers.is_done(); handlers.next()) {
@ -801,13 +802,13 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
ciInstanceKlass* h_klass = h->is_catch_all() ? env()->Throwable_klass() : h->catch_klass(); ciInstanceKlass* h_klass = h->is_catch_all() ? env()->Throwable_klass() : h->catch_klass();
// Do not introduce unloaded exception types into the graph: // Do not introduce unloaded exception types into the graph:
if (!h_klass->is_loaded()) { if (!h_klass->is_loaded()) {
if (saw_unloaded->contains(h_bci)) { if (saw_unloaded.contains(h_bci)) {
/* We've already seen an unloaded exception with h_bci, /* We've already seen an unloaded exception with h_bci,
so don't duplicate. Duplication will cause the CatchNode to be so don't duplicate. Duplication will cause the CatchNode to be
unnecessarily large. See 4713716. */ unnecessarily large. See 4713716. */
continue; continue;
} else { } else {
saw_unloaded->append(h_bci); saw_unloaded.append(h_bci);
} }
} }
const Type* h_extype = TypeOopPtr::make_from_klass(h_klass); const Type* h_extype = TypeOopPtr::make_from_klass(h_klass);
@ -815,21 +816,21 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
h_extype = h_extype->join(TypeInstPtr::NOTNULL); h_extype = h_extype->join(TypeInstPtr::NOTNULL);
assert(!h_extype->empty(), "sanity"); assert(!h_extype->empty(), "sanity");
// Note: It's OK if the BCIs repeat themselves. // Note: It's OK if the BCIs repeat themselves.
bcis->append(h_bci); bcis.append(h_bci);
extypes->append(h_extype); extypes.append(h_extype);
if (h_bci == -1) { if (h_bci == -1) {
default_handler = true; default_handler = true;
} }
} }
if (!default_handler) { if (!default_handler) {
bcis->append(-1); bcis.append(-1);
const Type* extype = TypeOopPtr::make_from_klass(env()->Throwable_klass())->is_instptr(); const Type* extype = TypeOopPtr::make_from_klass(env()->Throwable_klass())->is_instptr();
extype = extype->join(TypeInstPtr::NOTNULL); extype = extype->join(TypeInstPtr::NOTNULL);
extypes->append(extype); extypes.append(extype);
} }
int len = bcis->length(); int len = bcis.length();
CatchNode *cn = new CatchNode(control(), i_o, len+1); CatchNode *cn = new CatchNode(control(), i_o, len+1);
Node *catch_ = _gvn.transform(cn); Node *catch_ = _gvn.transform(cn);
@ -840,18 +841,18 @@ void Parse::catch_call_exceptions(ciExceptionHandlerStream& handlers) {
PreserveJVMState pjvms(this); PreserveJVMState pjvms(this);
// Locals are just copied from before the call. // Locals are just copied from before the call.
// Get control from the CatchNode. // Get control from the CatchNode.
int handler_bci = bcis->at(i); int handler_bci = bcis.at(i);
Node* ctrl = _gvn.transform( new CatchProjNode(catch_, i+1,handler_bci)); Node* ctrl = _gvn.transform( new CatchProjNode(catch_, i+1,handler_bci));
// This handler cannot happen? // This handler cannot happen?
if (ctrl == top()) continue; if (ctrl == top()) continue;
set_control(ctrl); set_control(ctrl);
// Create exception oop // Create exception oop
const TypeInstPtr* extype = extypes->at(i)->is_instptr(); const TypeInstPtr* extype = extypes.at(i)->is_instptr();
Node *ex_oop = _gvn.transform(new CreateExNode(extypes->at(i), ctrl, i_o)); Node* ex_oop = _gvn.transform(new CreateExNode(extypes.at(i), ctrl, i_o));
// Handle unloaded exception classes. // Handle unloaded exception classes.
if (saw_unloaded->contains(handler_bci)) { if (saw_unloaded.contains(handler_bci)) {
// An unloaded exception type is coming here. Do an uncommon trap. // An unloaded exception type is coming here. Do an uncommon trap.
#ifndef PRODUCT #ifndef PRODUCT
// We do not expect the same handler bci to take both cold unloaded // We do not expect the same handler bci to take both cold unloaded