changeset 9448:e45726f53c00

Instead of null-checking, make barrier versions with null-checks included.
author rkennke
date Tue, 18 Aug 2015 18:37:40 +0200
parents 3882524b04a9
children ea0fa7eace6e
files src/cpu/x86/vm/x86_64.ad src/share/vm/opto/graphKit.cpp
diffstat 2 files changed, 60 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/x86/vm/x86_64.ad	Tue Aug 18 18:36:41 2015 +0200
+++ b/src/cpu/x86/vm/x86_64.ad	Tue Aug 18 18:37:40 2015 +0200
@@ -6400,6 +6400,28 @@
 %}
 
 instruct shenandoahRB(rRegP dst, rRegP src, rFlagsReg cr) %{
+  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
+  match(Set dst (ShenandoahReadBarrier src));
+  effect(DEF dst, USE src, KILL cr);
+  ins_cost(300); // XXX
+  format %{ "shenandoah_rb $dst,$src" %}
+  ins_encode %{
+    Register s = $src$$Register;
+    Register d = $dst$$Register;
+    Label is_null;
+    if (s != d) {
+      __ movptr(d, 0);
+    }
+    __ testptr(s, s);
+    __ jcc(Assembler::zero, is_null);
+    __ movptr(d, Address(s, -8));
+    __ bind(is_null);
+  %}
+  ins_pipe(ialu_reg_mem);
+%}
+
+instruct shenandoahRBNotNull(rRegP dst, rRegP src, rFlagsReg cr) %{
+  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
   match(Set dst (ShenandoahReadBarrier src));
   effect(DEF dst, USE src);
   ins_cost(125); // XXX
@@ -6413,6 +6435,32 @@
 %}
 
 instruct shenandoahWB(rax_RegP dst, rdi_RegP src, rFlagsReg cr) %{
+  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
+  match(Set dst (ShenandoahWriteBarrier src));
+  effect(DEF dst, USE_KILL src, KILL cr);
+  ins_cost(125); // XXX
+  format %{ "shenandoah_wb $dst,$src" %}
+  ins_encode %{
+    Label done;
+    Register s = $src$$Register;
+    Register d = $dst$$Register;
+    assert(s == rdi, "need rdi");
+    assert(d == rax, "result in rax");
+    __ movptr(d, 0);
+    __ testptr(s, s);
+    __ jcc(Assembler::zero, done);
+    Address evacuation_in_progress = Address(r15_thread, in_bytes(JavaThread::evacuation_in_progress_offset()));
+    __ cmpb(evacuation_in_progress, 0);
+    __ movptr(d, Address(s, -8));
+    __ jcc(Assembler::equal, done);
+    __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::x86::shenandoah_wb())));
+    __ bind(done);
+  %}
+  ins_pipe(pipe_slow);
+%}
+
+instruct shenandoahWBNotNull(rax_RegP dst, rdi_RegP src, rFlagsReg cr) %{
+  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
   match(Set dst (ShenandoahWriteBarrier src));
   effect(DEF dst, USE_KILL src, KILL cr);
   ins_cost(300); // XXX
--- a/src/share/vm/opto/graphKit.cpp	Tue Aug 18 18:36:41 2015 +0200
+++ b/src/share/vm/opto/graphKit.cpp	Tue Aug 18 18:37:40 2015 +0200
@@ -4436,38 +4436,12 @@
 
     const TypePtr* adr_type = obj_type->is_ptr()->add_offset(-8);
 
-    if (obj_type->meet(TypePtr::NULL_PTR) == obj_type->remove_speculative()) {
-
-      // We don't know if it's null or not. Need null-check.
-      enum { _not_null_path = 1, _null_path, PATH_LIMIT };
-      RegionNode* region = new RegionNode(PATH_LIMIT);
-      Node*       phi    = new PhiNode(region, obj_type);
-      Node* null_ctrl = top();
-      Node* not_null_obj = null_check_oop(obj, &null_ctrl);
-
-      region->init_req(_null_path, null_ctrl);
-      phi   ->init_req(_null_path, obj);
-
-      Node* ctrl = use_ctrl ? control() : NULL;
-      ShenandoahReadBarrierNode* rb = new ShenandoahReadBarrierNode(ctrl, memory(adr_type), not_null_obj);
-      Node* n = _gvn.transform(rb);
-
-      region->init_req(_not_null_path, control());
-      phi   ->init_req(_not_null_path, n);
-
-      set_control(_gvn.transform(region));
-      record_for_igvn(region);
-      return _gvn.transform(phi);
-
-    } else {
-      // We know it is not null. Simple barrier is sufficient.
-      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);
-      return n;
-    }
+    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);
+    return n;
 
   } else {
     return obj;
@@ -4483,46 +4457,12 @@
       return obj;
     }
     const TypePtr* adr_type = obj_type->is_ptr()->add_offset(-8);
-    if (obj_type->meet(TypePtr::NULL_PTR) == obj_type->remove_speculative()) {
-      // We don't know if it's null or not. Need null-check.
-      enum { _not_null_path = 1, _null_path, PATH_LIMIT };
-      RegionNode* region = new RegionNode(PATH_LIMIT);
-      Node*       phi    = new PhiNode(region, obj_type);
-      Node*    memphi    = PhiNode::make(region, memory(adr_type), Type::MEMORY, C->alias_type(adr_type)->adr_type());
-
-      Node* prev_mem = memory(adr_type);
-      Node* null_ctrl = top();
-      Node* not_null_obj = null_check_oop(obj, &null_ctrl);
-
-      region->init_req(_null_path, null_ctrl);
-      phi   ->init_req(_null_path, obj);
-      memphi->init_req(_null_path, prev_mem);
-
-      ShenandoahWriteBarrierNode* wb = new ShenandoahWriteBarrierNode(NULL, memory(adr_type), not_null_obj);
-      Node* n = _gvn.transform(wb);
-      if (n == wb) { // New barrier needs memory projection.
-	Node* proj = _gvn.transform(new ShenandoahWBMemProjNode(n));
-	set_memory(proj, adr_type);
-      }
-
-      region->init_req(_not_null_path, control());
-      phi   ->init_req(_not_null_path, n);
-      memphi->init_req(_not_null_path, memory(adr_type));
-
-      set_control(_gvn.transform(region));
-      record_for_igvn(region);
-      set_memory(_gvn.transform(memphi), adr_type);
-
-      return _gvn.transform(phi);
-    } else {
-      // We know it is not null. Simple barrier is sufficient.
-      ShenandoahWriteBarrierNode* wb = new ShenandoahWriteBarrierNode(NULL, memory(adr_type), obj);
-      Node* proj = _gvn.transform(new ShenandoahWBMemProjNode(wb));
-      set_memory(proj, adr_type);
-      Node* n = _gvn.transform(wb);
-      record_for_igvn(n);
-      return n;
-    }
+    ShenandoahWriteBarrierNode* wb = new ShenandoahWriteBarrierNode(NULL, memory(adr_type), obj);
+    Node* proj = _gvn.transform(new ShenandoahWBMemProjNode(wb));
+    set_memory(proj, adr_type);
+    Node* n = _gvn.transform(wb);
+    record_for_igvn(n);
+    return n;
 
   } else {
     return obj;