8213384: Move G1/C2 barrier verification into G1BarrierSetC2
authorrkennke
Tue, 06 Nov 2018 17:28:14 +0100
changeset 52426 38bf0c9c4e64
parent 52425 cc7284e19666
child 52427 3c6aa484536c
8213384: Move G1/C2 barrier verification into G1BarrierSetC2 Reviewed-by: kvn, roland, eosterlund
src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp
src/hotspot/share/gc/g1/c2/g1BarrierSetC2.hpp
src/hotspot/share/gc/shared/c2/barrierSetC2.hpp
src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp
src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp
src/hotspot/share/opto/compile.cpp
src/hotspot/share/opto/compile.hpp
--- a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp	Tue Nov 06 15:14:10 2018 +0300
+++ b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.cpp	Tue Nov 06 17:28:14 2018 +0100
@@ -30,9 +30,11 @@
 #include "gc/g1/g1ThreadLocalData.hpp"
 #include "gc/g1/heapRegion.hpp"
 #include "opto/arraycopynode.hpp"
+#include "opto/compile.hpp"
 #include "opto/graphKit.hpp"
 #include "opto/idealKit.hpp"
 #include "opto/macro.hpp"
+#include "opto/rootnode.hpp"
 #include "opto/type.hpp"
 #include "utilities/macros.hpp"
 
@@ -773,3 +775,65 @@
   }
   return c;
 }
+
+#ifdef ASSERT
+void G1BarrierSetC2::verify_gc_barriers(Compile* compile, CompilePhase phase) const {
+  // Verify G1 pre-barriers
+  const int marking_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset());
+
+  ResourceArea *area = Thread::current()->resource_area();
+  Unique_Node_List visited(area);
+  Node_List worklist(area);
+  // We're going to walk control flow backwards starting from the Root
+  worklist.push(compile->root());
+  while (worklist.size() > 0) {
+    Node* x = worklist.pop();
+    if (x == NULL || x == compile->top()) continue;
+    if (visited.member(x)) {
+      continue;
+    } else {
+      visited.push(x);
+    }
+
+    if (x->is_Region()) {
+      for (uint i = 1; i < x->req(); i++) {
+        worklist.push(x->in(i));
+      }
+    } else {
+      worklist.push(x->in(0));
+      // We are looking for the pattern:
+      //                            /->ThreadLocal
+      // If->Bool->CmpI->LoadB->AddP->ConL(marking_offset)
+      //              \->ConI(0)
+      // We want to verify that the If and the LoadB have the same control
+      // See GraphKit::g1_write_barrier_pre()
+      if (x->is_If()) {
+        IfNode *iff = x->as_If();
+        if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) {
+          CmpNode *cmp = iff->in(1)->in(1)->as_Cmp();
+          if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0
+              && cmp->in(1)->is_Load()) {
+            LoadNode* load = cmp->in(1)->as_Load();
+            if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal
+                && load->in(2)->in(3)->is_Con()
+                && load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) {
+
+              Node* if_ctrl = iff->in(0);
+              Node* load_ctrl = load->in(0);
+
+              if (if_ctrl != load_ctrl) {
+                // Skip possible CProj->NeverBranch in infinite loops
+                if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
+                    && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
+                  if_ctrl = if_ctrl->in(0)->in(0);
+                }
+              }
+              assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
+            }
+          }
+        }
+      }
+    }
+  }
+}
+#endif
--- a/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.hpp	Tue Nov 06 15:14:10 2018 +0300
+++ b/src/hotspot/share/gc/g1/c2/g1BarrierSetC2.hpp	Tue Nov 06 17:28:14 2018 +0100
@@ -88,6 +88,10 @@
   virtual bool is_gc_barrier_node(Node* node) const;
   virtual void eliminate_gc_barrier(PhaseMacroExpand* macro, Node* node) const;
   virtual Node* step_over_gc_barrier(Node* c) const;
+
+#ifdef ASSERT
+  virtual void verify_gc_barriers(Compile* compile, CompilePhase phase) const;
+#endif
 };
 
 #endif // SHARE_GC_SHARED_C2_G1BARRIERSETC2_HPP
--- a/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp	Tue Nov 06 15:14:10 2018 +0300
+++ b/src/hotspot/share/gc/shared/c2/barrierSetC2.hpp	Tue Nov 06 17:28:14 2018 +0100
@@ -54,6 +54,7 @@
 // Loads and stores from an arraycopy being optimized
 const DecoratorSet C2_ARRAY_COPY             = DECORATOR_LAST << 10;
 
+class Compile;
 class GraphKit;
 class IdealKit;
 class Node;
@@ -272,7 +273,13 @@
   // If the BarrierSetC2 state has kept macro nodes in its compilation unit state to be
   // expanded later, then now is the time to do so.
   virtual bool expand_macro_nodes(PhaseMacroExpand* macro) const { return false; }
-  virtual void verify_gc_barriers(bool post_parse) const {}
+
+  enum CompilePhase {
+    BeforeOptimize, /* post_parse = true */
+    BeforeExpand, /* post_parse = false */
+    BeforeCodeGen
+  };
+  virtual void verify_gc_barriers(Compile* compile, CompilePhase phase) const {}
 };
 
 #endif // SHARE_GC_SHARED_C2_BARRIERSETC2_HPP
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp	Tue Nov 06 15:14:10 2018 +0300
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp	Tue Nov 06 17:28:14 2018 +0100
@@ -1464,6 +1464,12 @@
   return true;
 }
 
+void ZBarrierSetC2::verify_gc_barriers(Compile* compile, CompilePhase phase) const {
+  if (phase == BarrierSetC2::BeforeCodeGen) return;
+  bool post_parse = phase == BarrierSetC2::BeforeOptimize;
+  verify_gc_barriers(post_parse);
+}
+
 void ZBarrierSetC2::verify_gc_barriers(bool post_parse) const {
   ZBarrierSetC2State* s = state();
   Compile* C = Compile::current();
--- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp	Tue Nov 06 15:14:10 2018 +0300
+++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.hpp	Tue Nov 06 17:28:14 2018 +0100
@@ -163,6 +163,10 @@
   void expand_loadbarrier_optimized(PhaseMacroExpand* phase, LoadBarrierNode *barrier) const;
   const TypeFunc* load_barrier_Type() const;
 
+#ifdef ASSERT
+  void verify_gc_barriers(bool post_parse) const;
+#endif
+
 protected:
   virtual Node* load_at_resolved(C2Access& access, const Type* val_type) const;
   virtual Node* atomic_cmpxchg_val_at_resolved(C2AtomicParseAccess& access,
@@ -204,7 +208,7 @@
   static void loop_optimize_gc_barrier(PhaseIdealLoop* phase, Node* node, bool last_round);
 
 #ifdef ASSERT
-  virtual void verify_gc_barriers(bool post_parse) const;
+  virtual void verify_gc_barriers(Compile* compile, CompilePhase phase) const;
 #endif
 };
 
--- a/src/hotspot/share/opto/compile.cpp	Tue Nov 06 15:14:10 2018 +0300
+++ b/src/hotspot/share/opto/compile.cpp	Tue Nov 06 17:28:14 2018 +0100
@@ -892,7 +892,10 @@
   }
 #endif
 
-  NOT_PRODUCT( verify_barriers(); )
+#ifdef ASSERT
+  BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
+  bs->verify_gc_barriers(this, BarrierSetC2::BeforeCodeGen);
+#endif
 
   // Dump compilation data to replay it.
   if (directive->DumpReplayOption) {
@@ -2193,7 +2196,7 @@
 
 #ifdef ASSERT
   BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
-  bs->verify_gc_barriers(true);
+  bs->verify_gc_barriers(this, BarrierSetC2::BeforeOptimize);
 #endif
 
   ResourceMark rm;
@@ -2386,7 +2389,7 @@
 
 #ifdef ASSERT
   BarrierSetC2* bs = BarrierSet::barrier_set()->barrier_set_c2();
-  bs->verify_gc_barriers(false);
+  bs->verify_gc_barriers(this, BarrierSetC2::BeforeExpand);
 #endif
 
   {
@@ -3831,74 +3834,6 @@
     }
   }
 }
-
-// Verify GC barriers consistency
-// Currently supported:
-// - G1 pre-barriers (see GraphKit::g1_write_barrier_pre())
-void Compile::verify_barriers() {
-#if INCLUDE_G1GC
-  if (UseG1GC) {
-    // Verify G1 pre-barriers
-    const int marking_offset = in_bytes(G1ThreadLocalData::satb_mark_queue_active_offset());
-
-    ResourceArea *area = Thread::current()->resource_area();
-    Unique_Node_List visited(area);
-    Node_List worklist(area);
-    // We're going to walk control flow backwards starting from the Root
-    worklist.push(_root);
-    while (worklist.size() > 0) {
-      Node* x = worklist.pop();
-      if (x == NULL || x == top()) continue;
-      if (visited.member(x)) {
-        continue;
-      } else {
-        visited.push(x);
-      }
-
-      if (x->is_Region()) {
-        for (uint i = 1; i < x->req(); i++) {
-          worklist.push(x->in(i));
-        }
-      } else {
-        worklist.push(x->in(0));
-        // We are looking for the pattern:
-        //                            /->ThreadLocal
-        // If->Bool->CmpI->LoadB->AddP->ConL(marking_offset)
-        //              \->ConI(0)
-        // We want to verify that the If and the LoadB have the same control
-        // See GraphKit::g1_write_barrier_pre()
-        if (x->is_If()) {
-          IfNode *iff = x->as_If();
-          if (iff->in(1)->is_Bool() && iff->in(1)->in(1)->is_Cmp()) {
-            CmpNode *cmp = iff->in(1)->in(1)->as_Cmp();
-            if (cmp->Opcode() == Op_CmpI && cmp->in(2)->is_Con() && cmp->in(2)->bottom_type()->is_int()->get_con() == 0
-                && cmp->in(1)->is_Load()) {
-              LoadNode* load = cmp->in(1)->as_Load();
-              if (load->Opcode() == Op_LoadB && load->in(2)->is_AddP() && load->in(2)->in(2)->Opcode() == Op_ThreadLocal
-                  && load->in(2)->in(3)->is_Con()
-                  && load->in(2)->in(3)->bottom_type()->is_intptr_t()->get_con() == marking_offset) {
-
-                Node* if_ctrl = iff->in(0);
-                Node* load_ctrl = load->in(0);
-
-                if (if_ctrl != load_ctrl) {
-                  // Skip possible CProj->NeverBranch in infinite loops
-                  if ((if_ctrl->is_Proj() && if_ctrl->Opcode() == Op_CProj)
-                      && (if_ctrl->in(0)->is_MultiBranch() && if_ctrl->in(0)->Opcode() == Op_NeverBranch)) {
-                    if_ctrl = if_ctrl->in(0)->in(0);
-                  }
-                }
-                assert(load_ctrl != NULL && if_ctrl == load_ctrl, "controls must match");
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-#endif
-}
-
 #endif
 
 // The Compile object keeps track of failure reasons separately from the ciEnv.
--- a/src/hotspot/share/opto/compile.hpp	Tue Nov 06 15:14:10 2018 +0300
+++ b/src/hotspot/share/opto/compile.hpp	Tue Nov 06 17:28:14 2018 +0100
@@ -1329,9 +1329,6 @@
   // graph is strongly connected from root in both directions.
   void verify_graph_edges(bool no_dead_code = false) PRODUCT_RETURN;
 
-  // Verify GC barrier patterns
-  void verify_barriers() PRODUCT_RETURN;
-
   // End-of-run dumps.
   static void print_statistics() PRODUCT_RETURN;