From 4cbddf71bde6e6e740dfb8a3b935e065c9114850 Mon Sep 17 00:00:00 2001 From: Xie Yiding Date: Sat, 22 Apr 2023 11:50:09 +0000 Subject: [PATCH 1/2] PhaseLive::compute allocates the Block_List on its live arena, but the backing Block_Array is allocated on the ResourceArea. This causes the memory of the worklist to build up without being freed. Signed-off-by: Xie Yiding --- hotspot/src/share/vm/opto/live.cpp | 24 ++++++++++++++---------- hotspot/src/share/vm/opto/live.hpp | 6 ++---- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp index 53599162e..03447fb53 100644 --- a/hotspot/src/share/vm/opto/live.cpp +++ b/hotspot/src/share/vm/opto/live.cpp @@ -46,7 +46,6 @@ PhaseLive::PhaseLive( const PhaseCFG &cfg, const LRG_List &names, Arena *arena ) 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. @@ -72,6 +71,7 @@ void PhaseLive::compute(uint maxlrg) { memset(_deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks()); _free_IndexSet = NULL; + Block_List worklist; // Blocks having done pass-1 VectorSet first_pass(Thread::current()->resource_area()); @@ -120,26 +120,30 @@ 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--) { - add_liveout(p, _names.at(block->get_node(k-1)->in(l)->_idx), first_pass); + 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); + } } } freeset(block); 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); @@ -207,7 +211,7 @@ void PhaseLive::freeset(const 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. @@ -215,7 +219,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); } @@ -223,7 +227,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]; @@ -244,7 +248,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); diff --git a/hotspot/src/share/vm/opto/live.hpp b/hotspot/src/share/vm/opto/live.hpp index 343c5c6f7..63e1e7f0e 100644 --- a/hotspot/src/share/vm/opto/live.hpp +++ b/hotspot/src/share/vm/opto/live.hpp @@ -57,8 +57,6 @@ 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 @@ -67,8 +65,8 @@ class PhaseLive : public Phase { IndexSet *getset( Block *p ); IndexSet *getfreeset( ); void freeset( const Block *p ); - void add_liveout( Block *p, uint r, VectorSet &first_pass ); - void add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ); + 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); public: PhaseLive(const PhaseCFG &cfg, const LRG_List &names, Arena *arena); -- Gitee From 49273623c3874ff9b7a7245c4d17367c9c6e5bb8 Mon Sep 17 00:00:00 2001 From: Xie Yiding Date: Thu, 27 Apr 2023 18:03:02 +0000 Subject: [PATCH 2/2] fix bug Signed-off-by: Xie Yiding --- hotspot/src/share/vm/opto/live.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp index 03447fb53..d5103169c 100644 --- a/hotspot/src/share/vm/opto/live.cpp +++ b/hotspot/src/share/vm/opto/live.cpp @@ -126,7 +126,6 @@ void PhaseLive::compute(uint maxlrg) { 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); } } -- Gitee