Mercurial > hg > jdk9-shenandoah > hotspot
changeset 9443:f4cde0bdf81b
More efficient barrier elimination.
author | rkennke |
---|---|
date | Tue, 11 Aug 2015 13:00:15 +0200 |
parents | 02d3bc62ae6b |
children | 4a1d26f20b62 |
files | src/share/vm/opto/shenandoahSupport.cpp src/share/vm/opto/shenandoahSupport.hpp |
diffstat | 2 files changed, 91 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- a/src/share/vm/opto/shenandoahSupport.cpp Tue Aug 11 12:57:55 2015 +0200 +++ b/src/share/vm/opto/shenandoahSupport.cpp Tue Aug 11 13:00:15 2015 +0200 @@ -1,5 +1,6 @@ #include "opto/callnode.hpp" +#include "opto/movenode.hpp" #include "opto/phaseX.hpp" #include "opto/shenandoahSupport.hpp" @@ -43,6 +44,88 @@ return n; } +bool ShenandoahBarrierNode::phi_needs_barrier(PhaseTransform* phase, Node* phi, GrowableArray<Node*>* phistack, Node* rb_mem) { + 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. + // Unless we need on another path. + return false; + } + bool need_barrier = false; + phistack->push(phi); + for (uint i = 1; i < phi->req() && ! need_barrier; i++) { + Node* input = phi->in(i); + if (input == NULL) { + need_barrier = true; // Phi not complete yet? + } else if (needs_barrier(phase, input, phistack, rb_mem)) { + need_barrier = true; + } + } + phistack->pop(); + return need_barrier; +} + +bool ShenandoahBarrierNode::needs_barrier(PhaseTransform* phase, Node* n, GrowableArray<Node*>* phistack, Node* rb_mem) { + if (n->is_Allocate()) { + // tty->print_cr("killed barrier for newly allocated object"); + return false;; + } + + if (n->is_CallJava()) { + return true; + } + + const Type* type = phase->type(n); + if (type->higher_equal(TypePtr::NULL_PTR)) { + // tty->print_cr("killed barrier for NULL object"); + return false; + } + if (type->isa_oopptr() && type->is_oopptr()->const_oop() != NULL) { + // tty->print_cr("killed barrier for constant object"); + return false; + } + + if (n->is_CheckCastPP() || n->is_ConstraintCast()) { + return needs_barrier(phase, n->in(1), phistack, rb_mem); + } + if (n->is_Parm()) { + return true; + } + if (n->is_Proj()) { + return needs_barrier(phase, n->in(0), phistack, rb_mem); + } + if (n->is_Phi()) { + return phi_needs_barrier(phase, n, phistack, rb_mem); + } + 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); + } + if (n->Opcode() == Op_CreateEx) { + return true; + } + if (n->Opcode() == Op_ShenandoahWriteBarrier) { + // tty->print_cr("skipped barrier for chained write barrier object"); + return false; + } + if (n->Opcode() == Op_ShenandoahReadBarrier) { + if (rb_mem == n->in(Memory)) { + // tty->print_cr("Eliminated chained read barrier"); + return false; + } else { + return true; + } + } + + if (n->Opcode() == Op_LoadP) { + return true; + } +#ifdef ASSERT + tty->print("need barrier on?: "); n->dump(); +#endif + return true; +} + Node* ShenandoahBarrierNode::Identity(PhaseTransform* phase) { #ifdef ASSERT @@ -52,21 +135,10 @@ // if (true) return this; Node* n = in(ValueIn); - if (phase->type(n)->higher_equal(TypePtr::NULL_PTR)) { - // tty->print_cr("killed barrier for NULL object"); - return kill_mem_proj(phase, n); - } - if (AllocateNode::Ideal_allocation(n, phase) != NULL) { - // tty->print_cr("killed barrier for newly allocated object"); - return kill_mem_proj(phase, n); - } - if (phase->type(n)->is_oopptr()->const_oop() != NULL) { - // tty->print_cr("killed barrier for constant object"); - return kill_mem_proj(phase, n); - } - - if (n->Opcode() == Op_ShenandoahWriteBarrier) { - // tty->print_cr("skipped barrier for chained write barrier object"); + 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)) { return kill_mem_proj(phase, n); }
--- a/src/share/vm/opto/shenandoahSupport.hpp Tue Aug 11 12:57:55 2015 +0200 +++ b/src/share/vm/opto/shenandoahSupport.hpp Tue Aug 11 13:00:15 2015 +0200 @@ -56,6 +56,10 @@ void check_invariants(); uint num_mem_projs(); #endif + +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); }; class ShenandoahReadBarrierNode : public ShenandoahBarrierNode {