< prev index next >

src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp

Print this page

        

*** 36,45 **** --- 36,46 ---- #include "opto/idealKit.hpp" #include "opto/macro.hpp" #include "opto/movenode.hpp" #include "opto/narrowptrnode.hpp" #include "opto/rootnode.hpp" + #include "opto/runtime.hpp" ShenandoahBarrierSetC2* ShenandoahBarrierSetC2::bsc2() { return reinterpret_cast<ShenandoahBarrierSetC2*>(BarrierSet::barrier_set()->barrier_set_c2()); }
*** 459,473 **** return TypeFunc::make(domain, range); } const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() { ! const Type **fields = TypeTuple::fields(3); ! fields[TypeFunc::Parms+0] = TypeInstPtr::NOTNULL; // src ! fields[TypeFunc::Parms+1] = TypeInstPtr::NOTNULL; // dst ! fields[TypeFunc::Parms+2] = TypeInt::INT; // length ! const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+3, fields); // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields); --- 460,472 ---- return TypeFunc::make(domain, range); } const TypeFunc* ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type() { ! const Type **fields = TypeTuple::fields(1); ! fields[TypeFunc::Parms+0] = TypeOopPtr::NOTNULL; // src oop ! const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+1, fields); // create result type (range) fields = TypeTuple::fields(0); const TypeTuple *range = TypeTuple::make(TypeFunc::Parms+0, fields);
*** 794,822 **** return true; } return false; } - #define XTOP LP64_ONLY(COMMA phase->top()) - void ShenandoahBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const { Node* ctrl = ac->in(TypeFunc::Control); Node* mem = ac->in(TypeFunc::Memory); Node* src = ac->in(ArrayCopyNode::Src); Node* src_offset = ac->in(ArrayCopyNode::SrcPos); Node* dest = ac->in(ArrayCopyNode::Dest); Node* dest_offset = ac->in(ArrayCopyNode::DestPos); Node* length = ac->in(ArrayCopyNode::Length); assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null"); if (ShenandoahCloneBarrier && clone_needs_barrier(src, phase->igvn())) { ! Node* call = phase->make_leaf_call(ctrl, mem, ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier), "shenandoah_clone", TypeRawPtr::BOTTOM, ! src, dest, length); call = phase->transform_later(call); phase->igvn().replace_node(ac, call); } else { BarrierSetC2::clone_at_expansion(phase, ac); } } --- 793,871 ---- return true; } return false; } void ShenandoahBarrierSetC2::clone_at_expansion(PhaseMacroExpand* phase, ArrayCopyNode* ac) const { Node* ctrl = ac->in(TypeFunc::Control); Node* mem = ac->in(TypeFunc::Memory); Node* src = ac->in(ArrayCopyNode::Src); Node* src_offset = ac->in(ArrayCopyNode::SrcPos); Node* dest = ac->in(ArrayCopyNode::Dest); Node* dest_offset = ac->in(ArrayCopyNode::DestPos); Node* length = ac->in(ArrayCopyNode::Length); assert (src_offset == NULL && dest_offset == NULL, "for clone offsets should be null"); + assert (src->is_AddP(), "for clone the src should be the interior ptr"); + assert (dest->is_AddP(), "for clone the dst should be the interior ptr"); + if (ShenandoahCloneBarrier && clone_needs_barrier(src, phase->igvn())) { ! // Check if heap is has forwarded objects. If it does, we need to call into the special ! // routine that would fix up source references before we can continue. ! ! enum { _heap_stable = 1, _heap_unstable, PATH_LIMIT }; ! Node* region = new RegionNode(PATH_LIMIT); ! Node* mem_phi = new PhiNode(region, Type::MEMORY, TypeRawPtr::BOTTOM); ! ! Node* thread = phase->transform_later(new ThreadLocalNode()); ! Node* offset = phase->igvn().MakeConX(in_bytes(ShenandoahThreadLocalData::gc_state_offset())); ! Node* gc_state_addr = phase->transform_later(new AddPNode(phase->C->top(), thread, offset)); ! ! uint gc_state_idx = Compile::AliasIdxRaw; ! const TypePtr* gc_state_adr_type = NULL; // debug-mode-only argument ! debug_only(gc_state_adr_type = phase->C->get_adr_type(gc_state_idx)); ! ! Node* gc_state = phase->transform_later(new LoadBNode(ctrl, mem, gc_state_addr, gc_state_adr_type, TypeInt::BYTE, MemNode::unordered)); ! Node* stable_and = phase->transform_later(new AndINode(gc_state, phase->igvn().intcon(ShenandoahHeap::HAS_FORWARDED))); ! Node* stable_cmp = phase->transform_later(new CmpINode(stable_and, phase->igvn().zerocon(T_INT))); ! Node* stable_test = phase->transform_later(new BoolNode(stable_cmp, BoolTest::ne)); ! ! IfNode* stable_iff = phase->transform_later(new IfNode(ctrl, stable_test, PROB_UNLIKELY(0.999), COUNT_UNKNOWN))->as_If(); ! Node* stable_ctrl = phase->transform_later(new IfFalseNode(stable_iff)); ! Node* unstable_ctrl = phase->transform_later(new IfTrueNode(stable_iff)); ! ! // Heap is stable, no need to do anything additional ! region->init_req(_heap_stable, stable_ctrl); ! mem_phi->init_req(_heap_stable, mem); ! ! // Heap is unstable, call into clone barrier stub ! Node* call = phase->make_leaf_call(unstable_ctrl, mem, ShenandoahBarrierSetC2::shenandoah_clone_barrier_Type(), CAST_FROM_FN_PTR(address, ShenandoahRuntime::shenandoah_clone_barrier), "shenandoah_clone", TypeRawPtr::BOTTOM, ! src->in(AddPNode::Base)); call = phase->transform_later(call); + + ctrl = phase->transform_later(new ProjNode(call, TypeFunc::Control)); + mem = phase->transform_later(new ProjNode(call, TypeFunc::Memory)); + region->init_req(_heap_unstable, ctrl); + mem_phi->init_req(_heap_unstable, mem); + + // Wire up the actual arraycopy stub now + ctrl = phase->transform_later(region); + mem = phase->transform_later(mem_phi); + + const char* name = "arraycopy"; + call = phase->make_leaf_call(ctrl, mem, + OptoRuntime::fast_arraycopy_Type(), + phase->basictype2arraycopy(T_LONG, NULL, NULL, true, name, true), + name, TypeRawPtr::BOTTOM, + src, dest, length + LP64_ONLY(COMMA phase->top())); + call = phase->transform_later(call); + + // Hook up the whole thing into the graph phase->igvn().replace_node(ac, call); } else { BarrierSetC2::clone_at_expansion(phase, ac); } }
< prev index next >