Mercurial > hg > jdk9-shenandoah > hotspot
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