changeset 9618:32062879e445

Eliminate barriers at parse time when possible.
author rkennke
date Wed, 16 Sep 2015 17:20:28 +0200
parents cff0ec3d1627
children 40d499730aad
files src/share/vm/opto/graphKit.cpp src/share/vm/opto/shenandoahSupport.cpp src/share/vm/opto/shenandoahSupport.hpp
diffstat 3 files changed, 32 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/graphKit.cpp	Wed Sep 16 17:19:55 2015 +0200
+++ b/src/share/vm/opto/graphKit.cpp	Wed Sep 16 17:20:28 2015 +0200
@@ -4428,16 +4428,20 @@
 
   if (UseShenandoahGC && ShenandoahReadBarrier) {
     const Type* obj_type = obj->bottom_type();
-
     if (obj_type->higher_equal(TypePtr::NULL_PTR)) {
+      // tty->print_cr("killed barrier for NULL object");
+      return obj;
+    }
+    const TypePtr* adr_type = obj_type->is_ptr()->add_offset(-8);
+    Node* mem = use_mem ? memory(adr_type) : immutable_memory();
+
+    if (! ShenandoahBarrierNode::needs_barrier(&_gvn, obj, mem)) {
       // We know it is null, no barrier needed.
       return obj;
     }
 
-    const TypePtr* adr_type = obj_type->is_ptr()->add_offset(-8);
 
     Node* ctrl = use_ctrl ? control() : NULL;
-    Node* mem = use_mem ? memory(adr_type) : immutable_memory();
     ShenandoahReadBarrierNode* rb = new ShenandoahReadBarrierNode(ctrl, mem, obj);
     Node* n = _gvn.transform(rb);
     record_for_igvn(n);
@@ -4452,10 +4456,10 @@
 
   if (UseShenandoahGC && ShenandoahWriteBarrier) {
     
-    const Type* obj_type = obj->bottom_type();
-    if (obj_type->higher_equal(TypePtr::NULL_PTR)) {
+    if (! ShenandoahBarrierNode::needs_barrier(&_gvn, obj, NULL)) {
       return obj;
     }
+    const Type* obj_type = obj->bottom_type();
     const TypePtr* adr_type = obj_type->is_ptr()->add_offset(-8);
     ShenandoahWriteBarrierNode* wb = new ShenandoahWriteBarrierNode(NULL, memory(adr_type), obj);
     Node* n = _gvn.transform(wb);
--- a/src/share/vm/opto/shenandoahSupport.cpp	Wed Sep 16 17:19:55 2015 +0200
+++ b/src/share/vm/opto/shenandoahSupport.cpp	Wed Sep 16 17:20:28 2015 +0200
@@ -44,7 +44,7 @@
   return n;
 }
 
-bool ShenandoahBarrierNode::phi_needs_barrier(PhaseTransform* phase, Node* phi, GrowableArray<Node*>* phistack, Node* rb_mem) {
+bool ShenandoahBarrierNode::phi_needs_barrier(PhaseTransform* phase, Node* phi, Node* rb_mem, GrowableArray<Node*>* phistack) {
   assert(phi->is_Phi(), "expect phi");
   if (phistack->contains(phi)) {
     // If we came back to the same phi, then it's a loop in which we don't need a barrier.
@@ -57,7 +57,7 @@
     Node* input = phi->in(i);
     if (input == NULL) {
       need_barrier = true; // Phi not complete yet?
-    } else if (needs_barrier(phase, input, phistack, rb_mem)) {
+    } else if (needs_barrier_impl(phase, input, rb_mem, phistack)) {
       need_barrier = true;
     }
   }
@@ -65,7 +65,13 @@
   return need_barrier;
 }
 
-bool ShenandoahBarrierNode::needs_barrier(PhaseTransform* phase, Node* n, GrowableArray<Node*>* phistack, Node* rb_mem) {
+bool ShenandoahBarrierNode::needs_barrier(PhaseTransform* phase, Node* n, Node* rb_mem) {
+  Arena* a = phase->arena();
+  GrowableArray<Node*>* phistack = new (a) GrowableArray<Node*>(a, 4, 0, NULL);
+  return needs_barrier_impl(phase, n, rb_mem, phistack);
+}
+
+bool ShenandoahBarrierNode::needs_barrier_impl(PhaseTransform* phase, Node* n, Node* rb_mem, GrowableArray<Node*>* phistack) {
   if (n->is_Allocate()) {
     // tty->print_cr("killed barrier for newly allocated object");
     return false;;
@@ -86,20 +92,20 @@
   }
 
   if (n->is_CheckCastPP() || n->is_ConstraintCast()) {
-    return needs_barrier(phase, n->in(1), phistack, rb_mem);
+    return needs_barrier_impl(phase, n->in(1), rb_mem, phistack);
   }
   if (n->is_Parm()) {
     return true;
   }
   if (n->is_Proj()) {
-    return needs_barrier(phase, n->in(0), phistack, rb_mem);
+    return needs_barrier_impl(phase, n->in(0), rb_mem, phistack);
   }
   if (n->is_Phi()) {
-    return phi_needs_barrier(phase, n, phistack, rb_mem);
+    return phi_needs_barrier(phase, n, rb_mem, phistack);
   }
   if (n->is_CMove()) {
-    return needs_barrier(phase, n->in(CMoveNode::IfFalse), phistack, rb_mem) ||
-      needs_barrier(phase, n->in(CMoveNode::IfTrue ), phistack, rb_mem);
+    return needs_barrier_impl(phase, n->in(CMoveNode::IfFalse), rb_mem, phistack) ||
+           needs_barrier_impl(phase, n->in(CMoveNode::IfTrue ), rb_mem, phistack);
   }
   if (n->Opcode() == Op_CreateEx) {
     return true;
@@ -169,8 +175,8 @@
   if (input->Opcode() == Op_ShenandoahWBMemProj) {
     input = input->in(0);
     assert(input->Opcode() == Op_ShenandoahWriteBarrier, "expect write barrier");
-    const Type* in_type = input->bottom_type(); // phase->type(input);
-    const Type* this_type = bottom_type(); //phase->type(this);
+    const Type* in_type = phase->type(input);
+    const Type* this_type = phase->type(this);
     if (is_independent(in_type, this_type)) {
       set_req(Memory, input->in(Memory));
       return this;
@@ -179,7 +185,7 @@
   return NULL;
 }
 
-uint ShenandoahWriteBarrierNode::count_rb_users(Node* n, GrowableArray<Node*>* phistack) const {
+uint ShenandoahWriteBarrierNode::count_rb_users(Node* n, GrowableArray<Node*>* phistack) {
   uint count = 0;
   for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
     Node* o = n->fast_out(j);
@@ -237,10 +243,8 @@
   // if (true) return this;
 
   Node* n = in(ValueIn);
-  Arena* a = phase->arena();
-  GrowableArray<Node*>* phistack = new (a) GrowableArray<Node*>(a, 4, 0, NULL);
   Node* rb_mem = Opcode() == Op_ShenandoahReadBarrier ? in(Memory) : NULL;
-  if (! needs_barrier(phase, n, phistack, rb_mem)) {
+  if (! needs_barrier(phase, n, rb_mem)) {
     return kill_mem_proj(phase, n);
   }
 
--- a/src/share/vm/opto/shenandoahSupport.hpp	Wed Sep 16 17:19:55 2015 +0200
+++ b/src/share/vm/opto/shenandoahSupport.hpp	Wed Sep 16 17:20:28 2015 +0200
@@ -57,9 +57,11 @@
   uint num_mem_projs();
 #endif
 
+  static bool needs_barrier(PhaseTransform* phase, Node* n, Node* rb_mem);
+
 private:
-  bool phi_needs_barrier(PhaseTransform* phase, Node* phi, GrowableArray<Node*>* phistack, Node* rb_mem);
-  bool needs_barrier(PhaseTransform* phase, Node* n, GrowableArray<Node*>* phistack, Node* rb_mem);
+  static bool phi_needs_barrier(PhaseTransform* phase, Node* phi, Node* rb_mem, GrowableArray<Node*>* phistack);
+  static bool needs_barrier_impl(PhaseTransform* phase, Node* n, Node* rb_mem, GrowableArray<Node*>* phistack);
 };
 
 class ShenandoahReadBarrierNode : public ShenandoahBarrierNode {
@@ -91,7 +93,7 @@
   //   Node::set_req(i, n);
   // }
 private:
-  uint count_rb_users(Node* n, GrowableArray<Node*>* phistack) const;
+  static uint count_rb_users(Node* n, GrowableArray<Node*>* phistack);
 };
 
 class ShenandoahWBMemProjNode : public ProjNode {
@@ -117,44 +119,6 @@
   virtual const Type *Value( PhaseTransform *phase ) const {
     return bottom_type();
   }
-  virtual void set_req( uint i, Node *n ) {
-#ifdef ASSERT
-    if (!(n == NULL || n->Opcode() == Op_ShenandoahWriteBarrier || n->is_Mach() || n->is_top())) {
-      tty->print_cr("unexpected input for SWBMemProj:");
-      n->dump(3);
-      tty->print_cr("this:");
-      dump(3);
-    }
-    /*
-    if (n == NULL) {
-      tty->print_cr("set NULL to: idx=%d", _idx);
-      if (_idx == 7143) {
-	tty->print_cr("break here");
-      }
-    }
-    if (n != NULL && n->is_top()) {
-      tty->print_cr("set top to: idx=%d", _idx);
-    }
-    */
-#endif
-    assert(n == NULL || n->Opcode() == Op_ShenandoahWriteBarrier || n->is_Mach() || n->is_top(), "epxect wb");
-    Node::set_req(i, n);
-#ifdef ASSERT
-    if (in(0) != NULL && in(0)->is_ShenandoahBarrier()) {
-      in(0)->as_ShenandoahBarrier()->check_invariants();
-    }
-#endif
-  }
-
-  virtual void init_req( uint i, Node *n ) {
-    Node::init_req(i, n);
-#ifdef ASSERT
-    if (in(0) != NULL && in(0)->is_ShenandoahBarrier()) {
-      in(0)->as_ShenandoahBarrier()->check_invariants();
-    }
-#endif
-  }
-
 #ifndef PRODUCT
   virtual void dump_spec(outputStream *st) const {};
 #endif