< prev index next >

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

Print this page
rev 52851 : Streamline CAS barriers, C2 ideal graph generation and matching

*** 623,667 **** } return load; } Node* ShenandoahBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node* expected_val, ! Node* val, const Type* value_type) const { GraphKit* kit = access.kit(); if (access.is_oop()) { ! val = shenandoah_storeval_barrier(kit, val); shenandoah_write_barrier_pre(kit, false /* do_load */, NULL, NULL, max_juint, NULL, NULL, expected_val /* pre_val */, T_OBJECT); } - return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, val, value_type); - } ! Node* ShenandoahBarrierSetC2::atomic_cmpxchg_val_at(C2AtomicAccess& access, Node* expected_val, ! Node* new_val, const Type* val_type) const { ! // TODO: Implement using proper barriers. ! return BarrierSetC2::atomic_cmpxchg_val_at(access, expected_val, new_val, val_type); } Node* ShenandoahBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node* expected_val, ! Node* val, const Type* value_type) const { GraphKit* kit = access.kit(); if (access.is_oop()) { ! val = shenandoah_storeval_barrier(kit, val); shenandoah_write_barrier_pre(kit, false /* do_load */, NULL, NULL, max_juint, NULL, NULL, expected_val /* pre_val */, T_OBJECT); } ! return BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, val, value_type); ! } ! ! Node* ShenandoahBarrierSetC2::atomic_cmpxchg_bool_at(C2AtomicAccess& access, Node* expected_val, ! Node* new_val, const Type* val_type) const { ! // TODO: Implement using proper barriers. ! return BarrierSetC2::atomic_cmpxchg_bool_at(access, expected_val, new_val, val_type); } Node* ShenandoahBarrierSetC2::atomic_xchg_at_resolved(C2AtomicAccess& access, Node* val, const Type* value_type) const { GraphKit* kit = access.kit(); if (access.is_oop()) { --- 623,746 ---- } return load; } + static void pin_atomic_op(C2AtomicAccess& access) { + if (!access.needs_pinning()) { + return; + } + // SCMemProjNodes represent the memory state of a LoadStore. Their + // main role is to prevent LoadStore nodes from being optimized away + // when their results aren't used. + GraphKit* kit = access.kit(); + Node* load_store = access.raw_access(); + assert(load_store != NULL, "must pin atomic op"); + Node* proj = kit->gvn().transform(new SCMemProjNode(load_store)); + kit->set_memory(proj, access.alias_idx()); + } + Node* ShenandoahBarrierSetC2::atomic_cmpxchg_val_at_resolved(C2AtomicAccess& access, Node* expected_val, ! Node* new_val, const Type* value_type) const { GraphKit* kit = access.kit(); if (access.is_oop()) { ! new_val = shenandoah_storeval_barrier(kit, new_val); shenandoah_write_barrier_pre(kit, false /* do_load */, NULL, NULL, max_juint, NULL, NULL, expected_val /* pre_val */, T_OBJECT); + MemNode::MemOrd mo = access.mem_node_mo(); + Node* mem = access.memory(); + Node* adr = access.addr().node(); + const TypePtr* adr_type = access.addr().type(); + Node* load_store = NULL; + + #ifdef _LP64 + if (adr->bottom_type()->is_ptr_to_narrowoop()) { + Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop())); + Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop())); + if (ShenandoahCASBarrier) { + load_store = kit->gvn().transform(new ShenandoahCompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo)); + } else { + load_store = kit->gvn().transform(new CompareAndExchangeNNode(kit->control(), mem, adr, newval_enc, oldval_enc, adr_type, value_type->make_narrowoop(), mo)); + } + } else + #endif + { + if (ShenandoahCASBarrier) { + load_store = kit->gvn().transform(new ShenandoahCompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo)); + } else { + load_store = kit->gvn().transform(new CompareAndExchangePNode(kit->control(), mem, adr, new_val, expected_val, adr_type, value_type->is_oopptr(), mo)); + } } ! access.set_raw_access(load_store); ! pin_atomic_op(access); ! ! #ifdef _LP64 ! if (adr->bottom_type()->is_ptr_to_narrowoop()) { ! load_store = kit->gvn().transform(new DecodeNNode(load_store, load_store->get_ptr_type())); ! } ! #endif ! return load_store; ! } ! return BarrierSetC2::atomic_cmpxchg_val_at_resolved(access, expected_val, new_val, value_type); } Node* ShenandoahBarrierSetC2::atomic_cmpxchg_bool_at_resolved(C2AtomicAccess& access, Node* expected_val, ! Node* new_val, const Type* value_type) const { GraphKit* kit = access.kit(); if (access.is_oop()) { ! new_val = shenandoah_storeval_barrier(kit, new_val); shenandoah_write_barrier_pre(kit, false /* do_load */, NULL, NULL, max_juint, NULL, NULL, expected_val /* pre_val */, T_OBJECT); + DecoratorSet decorators = access.decorators(); + MemNode::MemOrd mo = access.mem_node_mo(); + Node* mem = access.memory(); + bool is_weak_cas = (decorators & C2_WEAK_CMPXCHG) != 0; + Node* load_store = NULL; + Node* adr = access.addr().node(); + #ifdef _LP64 + if (adr->bottom_type()->is_ptr_to_narrowoop()) { + Node *newval_enc = kit->gvn().transform(new EncodePNode(new_val, new_val->bottom_type()->make_narrowoop())); + Node *oldval_enc = kit->gvn().transform(new EncodePNode(expected_val, expected_val->bottom_type()->make_narrowoop())); + if (ShenandoahCASBarrier) { + if (is_weak_cas) { + load_store = kit->gvn().transform(new ShenandoahWeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo)); + } else { + load_store = kit->gvn().transform(new ShenandoahCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo)); } ! } else { ! if (is_weak_cas) { ! load_store = kit->gvn().transform(new WeakCompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo)); ! } else { ! load_store = kit->gvn().transform(new CompareAndSwapNNode(kit->control(), mem, adr, newval_enc, oldval_enc, mo)); ! } ! } ! } else ! #endif ! { ! if (ShenandoahCASBarrier) { ! if (is_weak_cas) { ! load_store = kit->gvn().transform(new ShenandoahWeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo)); ! } else { ! load_store = kit->gvn().transform(new ShenandoahCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo)); ! } ! } else { ! if (is_weak_cas) { ! load_store = kit->gvn().transform(new WeakCompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo)); ! } else { ! load_store = kit->gvn().transform(new CompareAndSwapPNode(kit->control(), mem, adr, new_val, expected_val, mo)); ! } ! } ! } ! access.set_raw_access(load_store); ! pin_atomic_op(access); ! return load_store; ! } ! return BarrierSetC2::atomic_cmpxchg_bool_at_resolved(access, expected_val, new_val, value_type); } Node* ShenandoahBarrierSetC2::atomic_xchg_at_resolved(C2AtomicAccess& access, Node* val, const Type* value_type) const { GraphKit* kit = access.kit(); if (access.is_oop()) {
*** 674,688 **** result /* pre_val */, T_OBJECT); } return result; } - Node* ShenandoahBarrierSetC2::atomic_xchg_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const { - // TODO: Implement using proper barriers. - return BarrierSetC2::atomic_xchg_at(access, new_val, value_type); - } - Node* ShenandoahBarrierSetC2::atomic_add_at(C2AtomicAccess& access, Node* new_val, const Type* value_type) const { // TODO: Implement using proper barriers. return BarrierSetC2::atomic_add_at(access, new_val, value_type); } --- 753,762 ----
< prev index next >