8218874: C2: Unsafe to access PhaseIdealLoop outside of constructors
authorvlivanov
Thu, 14 Feb 2019 15:27:12 -0800
changeset 53766 7e4a9e912759
parent 53765 e002408eb0c0
child 53767 f940579715a5
8218874: C2: Unsafe to access PhaseIdealLoop outside of constructors Reviewed-by: thartmann, kvn
src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
src/hotspot/share/opto/compile.cpp
src/hotspot/share/opto/loopnode.cpp
src/hotspot/share/opto/loopnode.hpp
--- 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);
   }
 }
--- 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);
     }
--- 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();
 
--- 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<uint>* _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;