24
25 #include "precompiled.hpp"
26 #include "gc/shared/c2/barrierSetC2.hpp"
27 #include "opto/arraycopynode.hpp"
28 #include "opto/graphKit.hpp"
29 #include "opto/idealKit.hpp"
30 #include "opto/narrowptrnode.hpp"
31 #include "utilities/macros.hpp"
32
33 // By default this is a no-op.
34 void BarrierSetC2::resolve_address(C2Access& access) const { }
35
36 void* C2Access::barrier_set_state() const {
37 return _kit->barrier_set_state();
38 }
39
40 bool C2Access::needs_cpu_membar() const {
41 bool mismatched = (_decorators & C2_MISMATCHED) != 0;
42 bool is_unordered = (_decorators & MO_UNORDERED) != 0;
43 bool anonymous = (_decorators & C2_UNSAFE_ACCESS) != 0;
44 bool on_heap = (_decorators & IN_HEAP) != 0;
45
46 bool is_write = (_decorators & C2_WRITE_ACCESS) != 0;
47 bool is_read = (_decorators & C2_READ_ACCESS) != 0;
48 bool is_atomic = is_read && is_write;
49
50 if (is_atomic) {
51 // Atomics always need to be wrapped in CPU membars
52 return true;
53 }
54
55 if (anonymous) {
56 // We will need memory barriers unless we can determine a unique
57 // alias category for this reference. (Note: If for some reason
58 // the barriers get omitted and the unsafe reference begins to "pollute"
59 // the alias analysis of the rest of the graph, either Compile::can_alias
60 // or Compile::must_alias will throw a diagnostic assert.)
61 if (!on_heap || !is_unordered || (mismatched && !_addr.type()->isa_aryptr())) {
62 return true;
63 }
64 }
65
66 return false;
67 }
68
69 Node* BarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const {
70 DecoratorSet decorators = access.decorators();
71 GraphKit* kit = access.kit();
72
73 bool mismatched = (decorators & C2_MISMATCHED) != 0;
74 bool unaligned = (decorators & C2_UNALIGNED) != 0;
75 bool requires_atomic_access = (decorators & MO_UNORDERED) == 0;
76
77 bool in_root = (decorators & IN_ROOT) != 0;
78 assert(!in_root, "not supported yet");
79
80 if (access.type() == T_DOUBLE) {
81 Node* new_val = kit->dstore_rounding(val.node());
82 val.set_node(new_val);
83 }
84
85 MemNode::MemOrd mo = access.mem_node_mo();
86
87 Node* store = kit->store_to_memory(kit->control(), access.addr().node(), val.node(), access.type(),
88 access.addr().type(), mo, requires_atomic_access, unaligned, mismatched);
89 access.set_raw_access(store);
90 return store;
91 }
92
93 Node* BarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
94 DecoratorSet decorators = access.decorators();
95 GraphKit* kit = access.kit();
96
97 Node* adr = access.addr().node();
98 const TypePtr* adr_type = access.addr().type();
99
100 bool mismatched = (decorators & C2_MISMATCHED) != 0;
101 bool requires_atomic_access = (decorators & MO_UNORDERED) == 0;
102 bool unaligned = (decorators & C2_UNALIGNED) != 0;
103 bool control_dependent = (decorators & C2_CONTROL_DEPENDENT_LOAD) != 0;
104 bool pinned = (decorators & C2_PINNED_LOAD) != 0;
105
106 bool in_root = (decorators & IN_ROOT) != 0;
107 assert(!in_root, "not supported yet");
108
109 MemNode::MemOrd mo = access.mem_node_mo();
110 LoadNode::ControlDependency dep = pinned ? LoadNode::Pinned : LoadNode::DependsOnlyOnTest;
111 Node* control = control_dependent ? kit->control() : NULL;
112
113 Node* load = kit->make_load(control, adr, val_type, access.type(), adr_type, mo,
114 dep, requires_atomic_access, unaligned, mismatched);
115 access.set_raw_access(load);
116
117 return load;
118 }
119
120 class C2AccessFence: public StackObj {
121 C2Access& _access;
122
123 public:
124 C2AccessFence(C2Access& access) :
125 _access(access) {
126 GraphKit* kit = access.kit();
127 DecoratorSet decorators = access.decorators();
|
24
25 #include "precompiled.hpp"
26 #include "gc/shared/c2/barrierSetC2.hpp"
27 #include "opto/arraycopynode.hpp"
28 #include "opto/graphKit.hpp"
29 #include "opto/idealKit.hpp"
30 #include "opto/narrowptrnode.hpp"
31 #include "utilities/macros.hpp"
32
33 // By default this is a no-op.
34 void BarrierSetC2::resolve_address(C2Access& access) const { }
35
36 void* C2Access::barrier_set_state() const {
37 return _kit->barrier_set_state();
38 }
39
40 bool C2Access::needs_cpu_membar() const {
41 bool mismatched = (_decorators & C2_MISMATCHED) != 0;
42 bool is_unordered = (_decorators & MO_UNORDERED) != 0;
43 bool anonymous = (_decorators & C2_UNSAFE_ACCESS) != 0;
44 bool in_heap = (_decorators & IN_HEAP) != 0;
45
46 bool is_write = (_decorators & C2_WRITE_ACCESS) != 0;
47 bool is_read = (_decorators & C2_READ_ACCESS) != 0;
48 bool is_atomic = is_read && is_write;
49
50 if (is_atomic) {
51 // Atomics always need to be wrapped in CPU membars
52 return true;
53 }
54
55 if (anonymous) {
56 // We will need memory barriers unless we can determine a unique
57 // alias category for this reference. (Note: If for some reason
58 // the barriers get omitted and the unsafe reference begins to "pollute"
59 // the alias analysis of the rest of the graph, either Compile::can_alias
60 // or Compile::must_alias will throw a diagnostic assert.)
61 if (!in_heap || !is_unordered || (mismatched && !_addr.type()->isa_aryptr())) {
62 return true;
63 }
64 }
65
66 return false;
67 }
68
69 Node* BarrierSetC2::store_at_resolved(C2Access& access, C2AccessValue& val) const {
70 DecoratorSet decorators = access.decorators();
71 GraphKit* kit = access.kit();
72
73 bool mismatched = (decorators & C2_MISMATCHED) != 0;
74 bool unaligned = (decorators & C2_UNALIGNED) != 0;
75 bool requires_atomic_access = (decorators & MO_UNORDERED) == 0;
76
77 bool in_native = (decorators & IN_NATIVE) != 0;
78 assert(!in_native, "not supported yet");
79
80 if (access.type() == T_DOUBLE) {
81 Node* new_val = kit->dstore_rounding(val.node());
82 val.set_node(new_val);
83 }
84
85 MemNode::MemOrd mo = access.mem_node_mo();
86
87 Node* store = kit->store_to_memory(kit->control(), access.addr().node(), val.node(), access.type(),
88 access.addr().type(), mo, requires_atomic_access, unaligned, mismatched);
89 access.set_raw_access(store);
90 return store;
91 }
92
93 Node* BarrierSetC2::load_at_resolved(C2Access& access, const Type* val_type) const {
94 DecoratorSet decorators = access.decorators();
95 GraphKit* kit = access.kit();
96
97 Node* adr = access.addr().node();
98 const TypePtr* adr_type = access.addr().type();
99
100 bool mismatched = (decorators & C2_MISMATCHED) != 0;
101 bool requires_atomic_access = (decorators & MO_UNORDERED) == 0;
102 bool unaligned = (decorators & C2_UNALIGNED) != 0;
103 bool control_dependent = (decorators & C2_CONTROL_DEPENDENT_LOAD) != 0;
104 bool pinned = (decorators & C2_PINNED_LOAD) != 0;
105
106 bool in_native = (decorators & IN_NATIVE) != 0;
107 assert(!in_native, "not supported yet");
108
109 MemNode::MemOrd mo = access.mem_node_mo();
110 LoadNode::ControlDependency dep = pinned ? LoadNode::Pinned : LoadNode::DependsOnlyOnTest;
111 Node* control = control_dependent ? kit->control() : NULL;
112
113 Node* load = kit->make_load(control, adr, val_type, access.type(), adr_type, mo,
114 dep, requires_atomic_access, unaligned, mismatched);
115 access.set_raw_access(load);
116
117 return load;
118 }
119
120 class C2AccessFence: public StackObj {
121 C2Access& _access;
122
123 public:
124 C2AccessFence(C2Access& access) :
125 _access(access) {
126 GraphKit* kit = access.kit();
127 DecoratorSet decorators = access.decorators();
|