# HG changeset patch # User vlivanov # Date 1550186832 28800 # Node ID 7e4a9e912759b352671f69715910eeae92bc7296 # Parent e002408eb0c09343820b272e95dce2b2511a5391 8218874: C2: Unsafe to access PhaseIdealLoop outside of constructors Reviewed-by: thartmann, kvn diff -r e002408eb0c0 -r 7e4a9e912759 src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Thu Feb 14 15:27:12 2019 -0800 +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp Thu Feb 14 15:27:12 2019 -0800 @@ -130,7 +130,7 @@ ZBarrierSetC2State* s = bs->state(); if (s->load_barrier_count() >= 2) { Compile::TracePhase tp("idealLoop", &C->timers[Phase::_t_idealLoop]); - PhaseIdealLoop ideal_loop(igvn, LoopOptsLastRound); + PhaseIdealLoop::optimize(igvn, LoopOptsLastRound); if (C->major_progress()) C->print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2); } } diff -r e002408eb0c0 -r 7e4a9e912759 src/hotspot/share/opto/compile.cpp --- a/src/hotspot/share/opto/compile.cpp Thu Feb 14 15:27:12 2019 -0800 +++ b/src/hotspot/share/opto/compile.cpp Thu Feb 14 15:27:12 2019 -0800 @@ -2112,7 +2112,7 @@ // PhaseIdealLoop is expensive so we only try it once we are // out of live nodes and we only try it again if the previous // helped got the number of nodes down significantly - PhaseIdealLoop ideal_loop(igvn, LoopOptsNone); + PhaseIdealLoop::optimize(igvn, LoopOptsNone); if (failing()) return; low_live_nodes = live_nodes(); _major_progress = true; @@ -2160,7 +2160,7 @@ while(major_progress() && (_loop_opts_cnt > 0)) { TracePhase tp("idealLoop", &timers[_t_idealLoop]); assert( cnt++ < 40, "infinite cycle in loop optimization" ); - PhaseIdealLoop ideal_loop(igvn, mode); + PhaseIdealLoop::optimize(igvn, mode); _loop_opts_cnt--; if (failing()) return false; if (major_progress()) print_method(PHASE_PHASEIDEALLOOP_ITERATIONS, 2); @@ -2282,7 +2282,7 @@ if (has_loops()) { // Cleanup graph (remove dead nodes). TracePhase tp("idealLoop", &timers[_t_idealLoop]); - PhaseIdealLoop ideal_loop(igvn, LoopOptsNone); + PhaseIdealLoop::optimize(igvn, LoopOptsNone); if (major_progress()) print_method(PHASE_PHASEIDEAL_BEFORE_EA, 2); if (failing()) return; } @@ -2316,7 +2316,7 @@ if((_loop_opts_cnt > 0) && (has_loops() || has_split_ifs())) { { TracePhase tp("idealLoop", &timers[_t_idealLoop]); - PhaseIdealLoop ideal_loop(igvn, LoopOptsDefault); + PhaseIdealLoop::optimize(igvn, LoopOptsDefault); _loop_opts_cnt--; if (major_progress()) print_method(PHASE_PHASEIDEALLOOP1, 2); if (failing()) return; @@ -2324,7 +2324,7 @@ // Loop opts pass if partial peeling occurred in previous pass if(PartialPeelLoop && major_progress() && (_loop_opts_cnt > 0)) { TracePhase tp("idealLoop", &timers[_t_idealLoop]); - PhaseIdealLoop ideal_loop(igvn, LoopOptsSkipSplitIf); + PhaseIdealLoop::optimize(igvn, LoopOptsSkipSplitIf); _loop_opts_cnt--; if (major_progress()) print_method(PHASE_PHASEIDEALLOOP2, 2); if (failing()) return; @@ -2332,7 +2332,7 @@ // Loop opts pass for loop-unrolling before CCP if(major_progress() && (_loop_opts_cnt > 0)) { TracePhase tp("idealLoop", &timers[_t_idealLoop]); - PhaseIdealLoop ideal_loop(igvn, LoopOptsSkipSplitIf); + PhaseIdealLoop::optimize(igvn, LoopOptsSkipSplitIf); _loop_opts_cnt--; if (major_progress()) print_method(PHASE_PHASEIDEALLOOP3, 2); } diff -r e002408eb0c0 -r 7e4a9e912759 src/hotspot/share/opto/loopnode.cpp --- a/src/hotspot/share/opto/loopnode.cpp Thu Feb 14 15:27:12 2019 -0800 +++ b/src/hotspot/share/opto/loopnode.cpp Thu Feb 14 15:27:12 2019 -0800 @@ -2712,8 +2712,6 @@ bool do_split_ifs = (mode == LoopOptsDefault || mode == LoopOptsLastRound); bool skip_loop_opts = (mode == LoopOptsNone); - ResourceMark rm; - int old_progress = C->major_progress(); uint orig_worklist_size = _igvn._worklist.size(); diff -r e002408eb0c0 -r 7e4a9e912759 src/hotspot/share/opto/loopnode.hpp --- a/src/hotspot/share/opto/loopnode.hpp Thu Feb 14 15:27:12 2019 -0800 +++ b/src/hotspot/share/opto/loopnode.hpp Thu Feb 14 15:27:12 2019 -0800 @@ -880,6 +880,42 @@ uint *_dom_depth; // Used for fast LCA test GrowableArray* _dom_stk; // For recomputation of dom depth + // Perform verification that the graph is valid. + PhaseIdealLoop( PhaseIterGVN &igvn) : + PhaseTransform(Ideal_Loop), + _igvn(igvn), + _verify_me(NULL), + _verify_only(true), + _dom_lca_tags(arena()) { // Thread::resource_area + build_and_optimize(LoopOptsVerify); + } + + // build the loop tree and perform any requested optimizations + void build_and_optimize(LoopOptsMode mode); + + // Dominators for the sea of nodes + void Dominators(); + + // Compute the Ideal Node to Loop mapping + PhaseIdealLoop(PhaseIterGVN &igvn, LoopOptsMode mode) : + PhaseTransform(Ideal_Loop), + _igvn(igvn), + _verify_me(NULL), + _verify_only(false), + _dom_lca_tags(arena()) { // Thread::resource_area + build_and_optimize(mode); + } + + // Verify that verify_me made the same decisions as a fresh run. + PhaseIdealLoop(PhaseIterGVN &igvn, const PhaseIdealLoop *verify_me) : + PhaseTransform(Ideal_Loop), + _igvn(igvn), + _verify_me(verify_me), + _verify_only(false), + _dom_lca_tags(arena()) { // Thread::resource_area + build_and_optimize(LoopOptsVerify); + } + public: Node* idom_no_update(Node* d) const { return idom_no_update(d->_idx); @@ -923,54 +959,27 @@ // Replace parallel induction variable (parallel to trip counter) void replace_parallel_iv(IdealLoopTree *loop); - // Perform verification that the graph is valid. - PhaseIdealLoop( PhaseIterGVN &igvn) : - PhaseTransform(Ideal_Loop), - _igvn(igvn), - _verify_me(NULL), - _verify_only(true), - _dom_lca_tags(arena()) { // Thread::resource_area - build_and_optimize(LoopOptsVerify); - } - - // build the loop tree and perform any requested optimizations - void build_and_optimize(LoopOptsMode mode); - - // Dominators for the sea of nodes - void Dominators(); Node *dom_lca( Node *n1, Node *n2 ) const { return find_non_split_ctrl(dom_lca_internal(n1, n2)); } Node *dom_lca_internal( Node *n1, Node *n2 ) const; - // Compute the Ideal Node to Loop mapping - PhaseIdealLoop(PhaseIterGVN &igvn, LoopOptsMode mode) : - PhaseTransform(Ideal_Loop), - _igvn(igvn), - _verify_me(NULL), - _verify_only(false), - _dom_lca_tags(arena()) { // Thread::resource_area - build_and_optimize(mode); - } - - // Verify that verify_me made the same decisions as a fresh run. - PhaseIdealLoop(PhaseIterGVN &igvn, const PhaseIdealLoop *verify_me) : - PhaseTransform(Ideal_Loop), - _igvn(igvn), - _verify_me(verify_me), - _verify_only(false), - _dom_lca_tags(arena()) { // Thread::resource_area - build_and_optimize(LoopOptsVerify); - } - // Build and verify the loop tree without modifying the graph. This // is useful to verify that all inputs properly dominate their uses. static void verify(PhaseIterGVN& igvn) { #ifdef ASSERT + ResourceMark rm; PhaseIdealLoop v(igvn); #endif } + // Recommended way to use PhaseIdealLoop. + // Run PhaseIdealLoop in some mode and allocates a local scope for memory allocations. + static void optimize(PhaseIterGVN &igvn, LoopOptsMode mode) { + ResourceMark rm; + PhaseIdealLoop v(igvn, mode); + } + // True if the method has at least 1 irreducible loop bool _has_irreducible_loops;