< 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 >