--- old/src/share/vm/opto/escape.cpp 2015-10-08 22:15:49.550259047 +0200 +++ new/src/share/vm/opto/escape.cpp 2015-10-08 22:15:49.484260623 +0200 @@ -36,6 +36,7 @@ #include "opto/phaseX.hpp" #include "opto/movenode.hpp" #include "opto/rootnode.hpp" +#include "opto/shenandoahSupport.hpp" ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) : _nodes(C->comp_arena(), C->unique(), C->unique(), NULL), @@ -530,7 +531,7 @@ // Pointer stores in G1 barriers looks like unsafe access. // Ignore such stores to be able scalar replace non-escaping // allocations. - if (UseG1GC && adr->is_AddP()) { + if ((UseG1GC || UseShenandoahGC) && adr->is_AddP()) { Node* base = get_addp_base(adr); if (base->Opcode() == Op_LoadP && base->in(MemNode::Address)->is_AddP()) { @@ -572,6 +573,12 @@ add_java_object(n, PointsToNode::ArgEscape); break; } + case Op_ShenandoahReadBarrier: + case Op_ShenandoahWriteBarrier: + // Barriers 'pass through' its arguments. I.e. what goes in, comes out. + // It doesn't escape. + add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahBarrierNode::ValueIn), delayed_worklist); + break; default: ; // Do nothing for nodes not related to EA. } @@ -766,6 +773,12 @@ } break; } + case Op_ShenandoahReadBarrier: + case Op_ShenandoahWriteBarrier: + // Barriers 'pass through' its arguments. I.e. what goes in, comes out. + // It doesn't escape. + add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(ShenandoahBarrierNode::ValueIn), NULL); + break; default: { // This method should be called only for EA specific nodes which may // miss some edges when they were created. @@ -885,7 +898,7 @@ } else { // An other type of call, assume the worst case: // returned value is unknown and globally escapes. - assert(call->Opcode() == Op_CallDynamicJava, "add failed case check"); + assert(call->Opcode() == Op_CallDynamicJava || call->Opcode() == Op_CallLeaf, "add failed case check"); map_ideal_node(call, phantom_obj); } } @@ -961,6 +974,9 @@ (call->as_CallLeaf()->_name != NULL && (strcmp(call->as_CallLeaf()->_name, "g1_wb_pre") == 0 || strcmp(call->as_CallLeaf()->_name, "g1_wb_post") == 0 || + strcmp(call->as_CallLeaf()->_name, "shenandoah_clone_barrier") == 0 || + strcmp(call->as_CallLeaf()->_name, "shenandoah_read_barrier") == 0 || + strcmp(call->as_CallLeaf()->_name, "shenandoah_cas_obj") == 0 || strcmp(call->as_CallLeaf()->_name, "updateBytesCRC32") == 0 || strcmp(call->as_CallLeaf()->_name, "updateBytesCRC32C") == 0 || strcmp(call->as_CallLeaf()->_name, "updateBytesAdler32") == 0 || @@ -2054,6 +2070,9 @@ } else if (adr_type->isa_aryptr()) { if (offset == arrayOopDesc::length_offset_in_bytes()) { // Ignore array length load. + } else if (UseShenandoahGC && offset == -8) { + // Shenandoah read barrier. + bt = T_ARRAY; } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) { // Ignore first AddP. } else { @@ -2642,6 +2661,7 @@ prev = result; if (result == start_mem) break; // hit one of our sentinels + assert(result->Opcode() != Op_ShenandoahWBMemProj, "unexpected memory slice"); if (result->is_Mem()) { const Type *at = igvn->type(result->in(MemNode::Address)); if (at == Type::TOP) @@ -3005,6 +3025,7 @@ n->is_CheckCastPP() || n->is_EncodeP() || n->is_DecodeN() || + n->is_ShenandoahBarrier() || (n->is_ConstraintCast() && n->Opcode() == Op_CastPP)) { if (visited.test_set(n->_idx)) { assert(n->is_Phi(), "loops only through Phi's"); @@ -3075,6 +3096,7 @@ use->is_CheckCastPP() || use->is_EncodeNarrowPtr() || use->is_DecodeNarrowPtr() || + use->is_ShenandoahBarrier() || (use->is_ConstraintCast() && use->Opcode() == Op_CastPP)) { alloc_worklist.append_if_missing(use); #ifdef ASSERT @@ -3099,7 +3121,8 @@ if (!(op == Op_CmpP || op == Op_Conv2B || op == Op_CastP2X || op == Op_StoreCM || op == Op_FastLock || op == Op_AryEq || op == Op_StrComp || - op == Op_StrEquals || op == Op_StrIndexOf)) { + op == Op_StrEquals || op == Op_StrIndexOf || + op == Op_ShenandoahWBMemProj)) { n->dump(); use->dump(); assert(false, "EA: missing allocation reference path");