< prev index next >

src/share/vm/opto/callnode.cpp

Print this page

        

@@ -35,10 +35,13 @@
 #include "opto/parse.hpp"
 #include "opto/regalloc.hpp"
 #include "opto/regmask.hpp"
 #include "opto/rootnode.hpp"
 #include "opto/runtime.hpp"
+#if INCLUDE_ALL_GCS
+#include "gc_implementation/shenandoah/c2/shenandoahBarrierSetC2.hpp"
+#endif
 
 // Portions of code courtesy of Clifford Click
 
 // Optimization - Graph Style
 

@@ -805,11 +808,11 @@
   }
   return cast;
 }
 
 
-void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj) {
+void CallNode::extract_projections(CallProjections* projs, bool separate_io_proj, bool do_asserts) {
   projs->fallthrough_proj      = NULL;
   projs->fallthrough_catchproj = NULL;
   projs->fallthrough_ioproj    = NULL;
   projs->catchall_ioproj       = NULL;
   projs->catchall_catchproj    = NULL;

@@ -868,21 +871,22 @@
     default:
       assert(false, "unexpected projection from allocation node.");
     }
   }
 
-  // The resproj may not exist because the result couuld be ignored
+  // The resproj may not exist because the result could be ignored
   // and the exception object may not exist if an exception handler
   // swallows the exception but all the other must exist and be found.
   assert(projs->fallthrough_proj      != NULL, "must be found");
-  assert(Compile::current()->inlining_incrementally() || projs->fallthrough_catchproj != NULL, "must be found");
-  assert(Compile::current()->inlining_incrementally() || projs->fallthrough_memproj   != NULL, "must be found");
-  assert(Compile::current()->inlining_incrementally() || projs->fallthrough_ioproj    != NULL, "must be found");
-  assert(Compile::current()->inlining_incrementally() || projs->catchall_catchproj    != NULL, "must be found");
+  do_asserts = do_asserts && !Compile::current()->inlining_incrementally();
+  assert(!do_asserts || projs->fallthrough_catchproj != NULL, "must be found");
+  assert(!do_asserts || projs->fallthrough_memproj   != NULL, "must be found");
+  assert(!do_asserts || projs->fallthrough_ioproj    != NULL, "must be found");
+  assert(!do_asserts || projs->catchall_catchproj    != NULL, "must be found");
   if (separate_io_proj) {
-    assert(Compile::current()->inlining_incrementally() || projs->catchall_memproj    != NULL, "must be found");
-    assert(Compile::current()->inlining_incrementally() || projs->catchall_ioproj     != NULL, "must be found");
+    assert(!do_asserts || projs->catchall_memproj    != NULL, "must be found");
+    assert(!do_asserts || projs->catchall_ioproj     != NULL, "must be found");
   }
 }
 
 Node *CallNode::Ideal(PhaseGVN *phase, bool can_reshape) {
   CallGenerator* cg = generator();

@@ -904,11 +908,10 @@
     }
   }
   return SafePointNode::Ideal(phase, can_reshape);
 }
 
-
 //=============================================================================
 uint CallJavaNode::size_of() const { return sizeof(*this); }
 uint CallJavaNode::cmp( const Node &n ) const {
   CallJavaNode &call = (CallJavaNode&)n;
   return CallNode::cmp(call) && _method == call._method;

@@ -996,10 +999,17 @@
 //------------------------------calling_convention-----------------------------
 void CallRuntimeNode::calling_convention( BasicType* sig_bt, VMRegPair *parm_regs, uint argcnt ) const {
   Matcher::c_calling_convention( sig_bt, parm_regs, argcnt );
 }
 
+bool CallRuntimeNode::is_call_to_arraycopystub() const {
+  if (_name != NULL && strstr(_name, "arraycopy") != 0) {
+    return true;
+  }
+  return false;
+}
+
 //=============================================================================
 //------------------------------calling_convention-----------------------------
 
 
 //=============================================================================

@@ -1009,10 +1019,41 @@
   st->print("%s", _name);
   CallNode::dump_spec(st);
 }
 #endif
 
+Node *CallLeafNode::Ideal(PhaseGVN *phase, bool can_reshape) {
+  if (UseShenandoahGC && is_g1_wb_pre_call()) {
+    uint cnt = OptoRuntime::g1_wb_pre_Type()->domain()->cnt();
+    if (req() > cnt) {
+      Node* addp = in(cnt);
+      if (has_only_g1_wb_pre_uses(addp)) {
+        del_req(cnt);
+        if (can_reshape) {
+          phase->is_IterGVN()->_worklist.push(addp);
+        }
+        return this;
+      }
+    }
+  }
+
+  return CallNode::Ideal(phase, can_reshape);
+}
+
+bool CallLeafNode::has_only_g1_wb_pre_uses(Node* n) {
+  if (UseShenandoahGC) {
+    return false;
+  }
+  for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+    Node* u = n->fast_out(i);
+    if (!u->is_g1_wb_pre_call()) {
+      return false;
+    }
+  }
+  return n->outcnt() > 0;
+}
+
 //=============================================================================
 
 void SafePointNode::set_local(JVMState* jvms, uint idx, Node *c) {
   assert(verify_jvms(jvms), "jvms must match");
   int loc = jvms->locoff() + idx;

@@ -1520,11 +1561,19 @@
   ProjNode *ctrl_proj = (ctrl->is_Proj()) ? ctrl->as_Proj() : NULL;
   if (ctrl_proj != NULL && ctrl_proj->_con == TypeFunc::Control) {
     Node *n = ctrl_proj->in(0);
     if (n != NULL && n->is_Unlock()) {
       UnlockNode *unlock = n->as_Unlock();
-      if (lock->obj_node()->eqv_uncast(unlock->obj_node()) &&
+      Node* lock_obj = lock->obj_node();
+      Node* unlock_obj = unlock->obj_node();
+#if INCLUDE_ALL_GCS
+      if (UseShenandoahGC) {
+        lock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(lock_obj);
+        unlock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(unlock_obj);
+      }
+#endif
+      if (lock_obj->eqv_uncast(unlock_obj) &&
           BoxLockNode::same_slot(lock->box_node(), unlock->box_node()) &&
           !unlock->is_eliminated()) {
         lock_ops.append(unlock);
         return true;
       }

@@ -1565,11 +1614,19 @@
       ctrl = next_control(ctrl->in(0));  // keep searching
     }
   }
   if (ctrl->is_Lock()) {
     LockNode *lock = ctrl->as_Lock();
-    if (lock->obj_node()->eqv_uncast(unlock->obj_node()) &&
+    Node* lock_obj = lock->obj_node();
+    Node* unlock_obj = unlock->obj_node();
+#if INCLUDE_ALL_GCS
+    if (UseShenandoahGC) {
+      lock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(lock_obj);
+      unlock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(unlock_obj);
+    }
+#endif
+    if (lock_obj->eqv_uncast(unlock_obj) &&
         BoxLockNode::same_slot(lock->box_node(), unlock->box_node())) {
       lock_result = lock;
     }
   }
   return lock_result;

@@ -1596,11 +1653,19 @@
           lock1_node = proj->unique_out();
         }
       }
       if (lock1_node != NULL && lock1_node->is_Lock()) {
         LockNode *lock1 = lock1_node->as_Lock();
-        if (lock->obj_node()->eqv_uncast(lock1->obj_node()) &&
+        Node* lock_obj = lock->obj_node();
+        Node* lock1_obj = lock1->obj_node();
+#if INCLUDE_ALL_GCS
+        if (UseShenandoahGC) {
+          lock_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(lock_obj);
+          lock1_obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(lock1_obj);
+        }
+#endif
+        if (lock_obj->eqv_uncast(lock1_obj) &&
             BoxLockNode::same_slot(lock->box_node(), lock1->box_node()) &&
             !lock1->is_eliminated()) {
           lock_ops.append(lock1);
           return true;
         }

@@ -1792,20 +1857,30 @@
     this->log_lock_optimization(c, "eliminate_lock_INLR_2b");
 #endif
     return false;
   }
 
+#if INCLUDE_ALL_GCS
+  if (UseShenandoahGC) {
+    obj = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(obj);
+  }
+#endif
   // Look for external lock for the same object.
   SafePointNode* sfn = this->as_SafePoint();
   JVMState* youngest_jvms = sfn->jvms();
   int max_depth = youngest_jvms->depth();
   for (int depth = 1; depth <= max_depth; depth++) {
     JVMState* jvms = youngest_jvms->of_depth(depth);
     int num_mon  = jvms->nof_monitors();
     // Loop over monitors
     for (int idx = 0; idx < num_mon; idx++) {
       Node* obj_node = sfn->monitor_obj(jvms, idx);
+#if INCLUDE_ALL_GCS
+      if (UseShenandoahGC) {
+        obj_node = ShenandoahBarrierSetC2::bsc2()->step_over_gc_barrier(obj_node);
+      }
+#endif
       BoxLockNode* box_node = sfn->monitor_box(jvms, idx)->as_BoxLock();
       if ((box_node->stack_slot() < stk_slot) && obj_node->eqv_uncast(obj)) {
         return true;
       }
     }
< prev index next >