8306456: Don't leak _worklist's memory in PhaseLive::compute

Reviewed-by: kvn, dlong
This commit is contained in:
Johan Sjölen 2023-04-21 13:36:36 +00:00
parent be6031b87d
commit 6e77e14fdb
2 changed files with 15 additions and 16 deletions
src/hotspot/share/opto

@ -54,7 +54,6 @@ PhaseLive::PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena, b
void PhaseLive::compute(uint maxlrg) {
_maxlrg = maxlrg;
_worklist = new (_arena) Block_List();
// Init the sparse live arrays. This data is live on exit from here!
// The _live info is the live-out info.
@ -88,6 +87,8 @@ void PhaseLive::compute(uint maxlrg) {
_free_IndexSet = nullptr;
Block_List worklist;
// Blocks having done pass-1
VectorSet first_pass;
@ -135,13 +136,13 @@ void PhaseLive::compute(uint maxlrg) {
// Push these live-in things to predecessors
for (uint l = 1; l < block->num_preds(); l++) {
Block* p = _cfg.get_block_for_node(block->pred(l));
add_liveout(p, use, first_pass);
add_liveout(worklist, p, use, first_pass);
// PhiNode uses go in the live-out set of prior blocks.
for (uint k = i; k > 0; k--) {
Node *phi = block->get_node(k - 1);
if (l < phi->req()) {
add_liveout(p, _names.at(phi->in(l)->_idx), first_pass);
add_liveout(worklist, p, _names.at(phi->in(l)->_idx), first_pass);
}
}
}
@ -149,15 +150,15 @@ void PhaseLive::compute(uint maxlrg) {
first_pass.set(block->_pre_order);
// Inner loop: blocks that picked up new live-out values to be propagated
while (_worklist->size()) {
Block* block = _worklist->pop();
while (worklist.size() != 0) {
Block* block = worklist.pop();
IndexSet *delta = getset(block);
assert(delta->count(), "missing delta set");
// Add new-live-in to predecessors live-out sets
for (uint l = 1; l < block->num_preds(); l++) {
Block* predecessor = _cfg.get_block_for_node(block->pred(l));
add_liveout(predecessor, delta, first_pass);
add_liveout(worklist, predecessor, delta, first_pass);
}
freeset(block);
@ -228,7 +229,7 @@ void PhaseLive::freeset(Block *p) {
// Add a live-out value to a given blocks live-out set. If it is new, then
// also add it to the delta set and stick the block on the worklist.
void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) {
void PhaseLive::add_liveout(Block_List& worklist, Block* p, uint r, VectorSet& first_pass) {
IndexSet *live = &_live[p->_pre_order-1];
if (live->insert(r)) { // If actually inserted...
// We extended the live-out set. See if the value is generated locally.
@ -236,7 +237,7 @@ void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) {
if (!_defs[p->_pre_order-1].member(r)) {
if (!_deltas[p->_pre_order-1] && // Not on worklist?
first_pass.test(p->_pre_order)) {
_worklist->push(p); // Actually go on worklist if already 1st pass
worklist.push(p); // Actually go on worklist if already 1st pass
}
getset(p)->insert(r);
}
@ -244,7 +245,7 @@ void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) {
}
// Add a vector of live-out values to a given blocks live-out set.
void PhaseLive::add_liveout(Block *p, IndexSet *lo, VectorSet &first_pass) {
void PhaseLive::add_liveout(Block_List& worklist, Block* p, IndexSet* lo, VectorSet& first_pass) {
IndexSet *live = &_live[p->_pre_order-1];
IndexSet *defs = &_defs[p->_pre_order-1];
IndexSet *on_worklist = _deltas[p->_pre_order-1];
@ -265,7 +266,7 @@ void PhaseLive::add_liveout(Block *p, IndexSet *lo, VectorSet &first_pass) {
_deltas[p->_pre_order-1] = delta; // Flag as on worklist now
if (!on_worklist && // Not on worklist?
first_pass.test(p->_pre_order)) {
_worklist->push(p); // Actually go on worklist if already 1st pass
worklist.push(p); // Actually go on worklist if already 1st pass
}
} else { // Nothing there; just free it
delta->set_next(_free_IndexSet);

@ -57,20 +57,18 @@ class PhaseLive : public Phase {
IndexSet **_deltas;
IndexSet *_free_IndexSet; // Free list of same
Block_List *_worklist; // Worklist for iterative solution
const PhaseCFG &_cfg; // Basic blocks
const LRG_List &_names; // Mapping from Nodes to live ranges
uint _maxlrg; // Largest live-range number
Arena *_arena;
bool _keep_deltas; // Retain live in information
IndexSet *getset( Block *p );
IndexSet *getset(Block* p);
IndexSet *getfreeset( );
void freeset( Block *p );
void add_liveout( Block *p, uint r, VectorSet &first_pass );
void add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass );
void add_livein( Block *p, IndexSet *lo );
void add_liveout(Block_List& worklist, Block* p, uint r, VectorSet& first_pass);
void add_liveout(Block_List& worklist, Block* p, IndexSet* lo, VectorSet& first_pass);
void add_livein(Block* p, IndexSet* lo);
public:
PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena, bool keep_deltas);