# HG changeset patch # User rkennke # Date 1444136710 -7200 # Node ID 09c6aa9c4a338a7baef52f29c3917990639477c2 # Parent 29693376eaec7f8a9bfe1c082a23f46898300e91 Implemented additional optimizations for read barriers. diff -r 29693376eaec -r 09c6aa9c4a33 src/share/vm/opto/shenandoahSupport.cpp --- a/src/share/vm/opto/shenandoahSupport.cpp Tue Oct 06 15:04:50 2015 +0200 +++ b/src/share/vm/opto/shenandoahSupport.cpp Tue Oct 06 15:05:10 2015 +0200 @@ -93,6 +93,72 @@ return true; } +bool ShenandoahReadBarrierNode::dominates_memory_rb_impl(PhaseTransform* phase, + Node* b1, + Node* b2, + Node* current, + Unique_Node_List &visited) { + if (current == NULL) { + return false; // Incomplete phi. Try again later. + } else if (visited.member(current)) { + // We have already seen it. + return true; + } + visited.push(current); + + if (current == b1) { + return true; + } else if (current == phase->C->immutable_memory()) { + return false; + } else if (current->isa_Phi()) { + bool dominates = true; + for (uint i = 1; i < current->req() && dominates == true; i++) { + Node* in = current->in(i); + dominates = dominates && dominates_memory_rb_impl(phase, b1, b2, in, visited); + } + return dominates; + } else if (current->Opcode() == Op_ShenandoahWriteBarrier) { + const Type* in_type = current->bottom_type(); + const Type* this_type = b2->bottom_type(); + if (is_independent(in_type, this_type)) { + Node* in = current->in(Memory); + return dominates_memory_rb_impl(phase, b1, b2, in, visited); + } else { + return false; + } + } else if (current->Opcode() == Op_ShenandoahWBMemProj) { + Node* in = current->in(0); + return dominates_memory_rb_impl(phase, b1, b2, in, visited); + } else if (current->is_top()) { + return true; // Dead path + } else if (current->is_Proj()) { + return dominates_memory_rb_impl(phase, b1, b2, current->in(0), visited); + } else if (current->is_Call()) { + return false; // TODO: Maybe improve by looking at the call's memory effects? + } else if (current->is_MemBar()) { + return false; // TODO: Do we need to stop at *any* membar? + } else if (current->is_MergeMem()) { + // if (true) return false; + // tty->print_cr("current == mergemem: "); current->dump(); + const TypePtr* adr_type = phase->type(b2)->is_ptr()->add_offset(-8); + uint alias_idx = phase->C->get_alias_index(adr_type); + Node* mem_in = current->as_MergeMem()->memory_at(alias_idx); + return dominates_memory_rb_impl(phase, b1, b2, current->in(TypeFunc::Memory), visited); + } else { + // tty->print_cr("what else can we see here:"); +#ifdef ASSERT + current->dump(); +#endif + ShouldNotReachHere(); + return false; + } +} + +bool ShenandoahReadBarrierNode::dominates_memory_rb(PhaseTransform* phase, Node* b1, Node* b2) { + Unique_Node_List visited; + return dominates_memory_rb_impl(phase, b1->in(Memory), b2, b2->in(Memory), visited); +} + bool ShenandoahReadBarrierNode::is_independent(const Type* in_type, const Type* this_type) const { assert(in_type->isa_oopptr(), "expect oop ptr"); assert(this_type->isa_oopptr(), "expect oop ptr"); @@ -132,8 +198,6 @@ return NULL; } - // if (true) return NULL; - if (in(Memory) == phase->C->immutable_memory()) return NULL; // If memory input is a MergeMem, take the appropriate slice out of it. @@ -308,7 +372,7 @@ Node* in = current->in(0); return dominates_memory_impl(phase, b1, b2, in, visited); } else if (current->is_top()) { - return false; // Dead path + return true; // Dead path } else if (current->is_Proj()) { // tty->print_cr("current == proj: "); current->dump(); return dominates_memory_impl(phase, b1, b2, current->in(0), visited); @@ -424,30 +488,27 @@ // tty->print("optimizing rb: "); dump(); Node* id = ShenandoahBarrierNode::Identity(phase); - if (true) return id; - - if (id == this) { + if (id == this && phase->is_IterGVN()) { Node* n = in(ValueIn); // No success in super call. Try to combine identical read barriers. for (DUIterator i = n->outs(); n->has_out(i); i++) { Node* sibling = n->out(i); - if (sibling == this) { + if (sibling == this || sibling->Opcode() != Op_ShenandoahReadBarrier) { continue; } - if (sibling->outcnt() == 0) { - continue; - } - if (sibling->Opcode() == Op_ShenandoahReadBarrier && - sibling->in(Control) == in(Control) && - sibling->in(Memory) == in(Memory) && - sibling->in(ValueIn) == in(ValueIn)) { - // assert(sibling->hash() == hash(), "ident node needs same hash"); - // assert(cmp(sibling) == 1, "ident node needs equals"); - //if (sibling->_hash_lock == 0) { - // tty->print_cr("skipped sibling not in hash: "); sibling->dump(); - //} else { + assert(sibling->in(ValueIn) == in(ValueIn), "sanity"); + if (phase->is_IterGVN()->hash_find(sibling) && + sibling->bottom_type() == bottom_type() && + sibling->in(Control) == in(Control) && + dominates_memory_rb(phase, sibling, this)) { + /* + if (in(Memory) != sibling->in(Memory)) { + tty->print_cr("interesting rb-fold"); + dump(); + sibling->dump(); + } + */ return sibling; - //} } } } diff -r 29693376eaec -r 09c6aa9c4a33 src/share/vm/opto/shenandoahSupport.hpp --- a/src/share/vm/opto/shenandoahSupport.hpp Tue Oct 06 15:04:50 2015 +0200 +++ b/src/share/vm/opto/shenandoahSupport.hpp Tue Oct 06 15:05:10 2015 +0200 @@ -82,7 +82,8 @@ private: bool is_independent(const Type* in_type, const Type* this_type) const; - + bool dominates_memory_rb(PhaseTransform* phase, Node* b1, Node* b2); + bool dominates_memory_rb_impl(PhaseTransform* phase, Node* b1, Node* b2, Node* current, Unique_Node_List &visited); }; class ShenandoahWriteBarrierNode : public ShenandoahBarrierNode {