< prev index next >

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

Print this page
rev 56771 : 8233339: Shenandoah: Centralize load barrier decisions into ShenandoahBarrierSet

*** 533,590 **** return BarrierSetC2::store_at_resolved(access, val); } Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const { DecoratorSet decorators = access.decorators(); Node* adr = access.addr().node(); Node* obj = access.base(); bool mismatched = (decorators & C2_MISMATCHED) != 0; bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0; bool on_heap = (decorators & IN_HEAP) != 0; bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0; bool is_unordered = (decorators & MO_UNORDERED) != 0; bool need_cpu_mem_bar = !is_unordered || mismatched || !on_heap; - bool is_traversal_mode = ShenandoahHeap::heap()->is_traversal_mode(); - bool keep_alive = (decorators & AS_NO_KEEPALIVE) == 0 || is_traversal_mode; - bool in_native = (decorators & IN_NATIVE) != 0; Node* top = Compile::current()->top(); Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top; Node* load = BarrierSetC2::load_at_resolved(access, val_type); ! if (access.is_oop()) { ! if (ShenandoahLoadRefBarrier) { ! load = new ShenandoahLoadReferenceBarrierNode(NULL, load, in_native && !is_traversal_mode); if (access.is_parse_access()) { load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load); } else { load = static_cast<C2OptAccess &>(access).gvn().transform(load); } - } - } // If we are reading the value of the referent field of a Reference // object (either by using Unsafe directly or through reflection) // then, if SATB is enabled, we need to record the referent in an // SATB log buffer using the pre-barrier mechanism. // Also we need to add memory barrier to prevent commoning reads // from this field across safepoint since GC can change its value. ! bool need_read_barrier = ShenandoahKeepAliveBarrier && ! (on_weak_ref || (unknown && offset != top && obj != top)); ! ! if (!access.is_oop() || !need_read_barrier) { return load; } assert(access.is_parse_access(), "entry not supported at optimization time"); C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access); GraphKit* kit = parse_access.kit(); ! if (on_weak_ref && keep_alive) { // Use the pre-barrier to record the value in the referent field satb_write_barrier_pre(kit, false /* do_load */, NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */, load /* pre_val */, T_OBJECT); // Add memory barrier to prevent commoning reads from this field --- 533,590 ---- return BarrierSetC2::store_at_resolved(access, val); } Node* ShenandoahBarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const { DecoratorSet decorators = access.decorators(); + BasicType type = access.type(); + + assert((decorators & AS_RAW) == 0, "Unexpected decorator"); + assert((decorators & AS_NO_KEEPALIVE) == 0, "Unexpected decorator"); Node* adr = access.addr().node(); Node* obj = access.base(); bool mismatched = (decorators & C2_MISMATCHED) != 0; bool unknown = (decorators & ON_UNKNOWN_OOP_REF) != 0; bool on_heap = (decorators & IN_HEAP) != 0; bool on_weak_ref = (decorators & (ON_WEAK_OOP_REF | ON_PHANTOM_OOP_REF)) != 0; bool is_unordered = (decorators & MO_UNORDERED) != 0; bool need_cpu_mem_bar = !is_unordered || mismatched || !on_heap; Node* top = Compile::current()->top(); Node* offset = adr->is_AddP() ? adr->in(AddPNode::Offset) : top; Node* load = BarrierSetC2::load_at_resolved(access, val_type); + if (!ShenandoahBarrierSet::need_load_reference_barrier(decorators, type)) { + return load; + } ! load = new ShenandoahLoadReferenceBarrierNode(NULL, load, ShenandoahBarrierSet::use_native_load_reference_barrier(decorators, type)); if (access.is_parse_access()) { load = static_cast<C2ParseAccess &>(access).kit()->gvn().transform(load); } else { load = static_cast<C2OptAccess &>(access).gvn().transform(load); } + if (!ShenandoahBarrierSet::need_keep_alive_barrier(decorators, type)) { + return load; + } // If we are reading the value of the referent field of a Reference // object (either by using Unsafe directly or through reflection) // then, if SATB is enabled, we need to record the referent in an // SATB log buffer using the pre-barrier mechanism. // Also we need to add memory barrier to prevent commoning reads // from this field across safepoint since GC can change its value. ! if (unknown && (offset == top || obj == top)) { return load; } assert(access.is_parse_access(), "entry not supported at optimization time"); C2ParseAccess& parse_access = static_cast<C2ParseAccess&>(access); GraphKit* kit = parse_access.kit(); ! if (on_weak_ref) { // Use the pre-barrier to record the value in the referent field satb_write_barrier_pre(kit, false /* do_load */, NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */, load /* pre_val */, T_OBJECT); // Add memory barrier to prevent commoning reads from this field
< prev index next >