74 // BarrierSet::AccessBarrier accessor that attaches GC-required barriers
75 // to the access.
76 // * Step 5.a: Barrier resolution. This step is invoked the first time a runtime-dispatch
77 // happens for an access. The appropriate BarrierSet::AccessBarrier accessor
78 // is resolved, then the function pointer is updated to that accessor for
79 // future invocations.
80 // * Step 5.b: Post-runtime dispatch. This step now casts previously unknown types such
81 // as the address type of an oop on the heap (is it oop* or narrowOop*) to
82 // the appropriate type. It also splits sufficiently orthogonal accesses into
83 // different functions, such as whether the access involves oops or primitives
84 // and whether the access is performed on the heap or outside. Then the
85 // appropriate BarrierSet::AccessBarrier is called to perform the access.
86 //
87 // The implementation of step 1-4 resides in in accessBackend.hpp, to allow selected
88 // accesses to be accessible from only access.hpp, as opposed to access.inline.hpp.
89 // Steps 5.a and 5.b require knowledge about the GC backends, and therefore needs to
90 // include the various GC backend .inline.hpp headers. Their implementation resides in
91 // access.inline.hpp. The accesses that are allowed through the access.hpp file
92 // must be instantiated in access.cpp using the INSTANTIATE_HPP_ACCESS macro.
93
94 namespace AccessInternal {
95 template <DecoratorSet decorators, typename T>
96 void store_at(oop base, ptrdiff_t offset, T value);
97
98 template <DecoratorSet decorators, typename T>
99 T load_at(oop base, ptrdiff_t offset);
100
101 template <DecoratorSet decorators, typename T>
102 T atomic_cmpxchg_at(T new_value, oop base, ptrdiff_t offset, T compare_value);
103
104 template <DecoratorSet decorators, typename T>
105 T atomic_xchg_at(T new_value, oop base, ptrdiff_t offset);
106
107 template <DecoratorSet decorators, typename P, typename T>
108 void store(P* addr, T value);
109
110 template <DecoratorSet decorators, typename P, typename T>
111 T load(P* addr);
112
113 template <DecoratorSet decorators, typename P, typename T>
114 T atomic_cmpxchg(T new_value, P* addr, T compare_value);
115
116 template <DecoratorSet decorators, typename P, typename T>
117 T atomic_xchg(T new_value, P* addr);
118
119 template <DecoratorSet decorators, typename T>
120 bool arraycopy(arrayOop src_obj, arrayOop dst_obj, T *src, T *dst, size_t length);
121
122 template <DecoratorSet decorators>
123 void clone(oop src, oop dst, size_t size);
124
125 template <DecoratorSet decorators>
126 oop resolve(oop src);
127
128 template <DecoratorSet decorators>
129 bool equals(oop o1, oop o2);
130
131 // Infer the type that should be returned from a load.
132 template <typename P, DecoratorSet decorators>
133 class OopLoadProxy: public StackObj {
134 private:
135 P *const _addr;
136 public:
137 OopLoadProxy(P* addr) : _addr(addr) {}
138
139 inline operator oop() {
140 return load<decorators | INTERNAL_VALUE_IS_OOP, P, oop>(_addr);
141 }
142
143 inline operator narrowOop() {
144 return load<decorators | INTERNAL_VALUE_IS_OOP, P, narrowOop>(_addr);
145 }
146
147 template <typename T>
148 inline bool operator ==(const T& other) const {
149 return load<decorators | INTERNAL_VALUE_IS_OOP, P, T>(_addr) == other;
150 }
151
152 template <typename T>
153 inline bool operator !=(const T& other) const {
154 return load<decorators | INTERNAL_VALUE_IS_OOP, P, T>(_addr) != other;
155 }
156 };
157
158 // Infer the type that should be returned from a load_at.
159 template <DecoratorSet decorators>
160 class LoadAtProxy: public StackObj {
161 private:
162 const oop _base;
163 const ptrdiff_t _offset;
164 public:
165 LoadAtProxy(oop base, ptrdiff_t offset) : _base(base), _offset(offset) {}
166
167 template <typename T>
168 inline operator T() const {
169 return load_at<decorators, T>(_base, _offset);
170 }
171
172 template <typename T>
173 inline bool operator ==(const T& other) const { return load_at<decorators, T>(_base, _offset) == other; }
174
175 template <typename T>
176 inline bool operator !=(const T& other) const { return load_at<decorators, T>(_base, _offset) != other; }
177 };
178
179 template <DecoratorSet decorators>
180 class OopLoadAtProxy: public StackObj {
181 private:
182 const oop _base;
183 const ptrdiff_t _offset;
184 public:
185 OopLoadAtProxy(oop base, ptrdiff_t offset) : _base(base), _offset(offset) {}
186
187 inline operator oop() const {
188 return load_at<decorators | INTERNAL_VALUE_IS_OOP, oop>(_base, _offset);
189 }
190
191 inline operator narrowOop() const {
192 return load_at<decorators | INTERNAL_VALUE_IS_OOP, narrowOop>(_base, _offset);
193 }
194
195 template <typename T>
196 inline bool operator ==(const T& other) const {
197 return load_at<decorators | INTERNAL_VALUE_IS_OOP, T>(_base, _offset) == other;
198 }
199
200 template <typename T>
201 inline bool operator !=(const T& other) const {
202 return load_at<decorators | INTERNAL_VALUE_IS_OOP, T>(_base, _offset) != other;
203 }
204 };
205 }
206
207 template <DecoratorSet decorators = INTERNAL_EMPTY>
208 class Access: public AllStatic {
209 // This function asserts that if an access gets passed in a decorator outside
210 // of the expected_decorators, then something is wrong. It additionally checks
211 // the consistency of the decorators so that supposedly disjoint decorators are indeed
212 // disjoint. For example, an access can not be both in heap and on root at the
213 // same time.
214 template <DecoratorSet expected_decorators>
215 static void verify_decorators();
216
217 template <DecoratorSet expected_mo_decorators>
218 static void verify_primitive_decorators() {
219 const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE ^ AS_DEST_NOT_INITIALIZED) |
220 IN_HEAP | IN_HEAP_ARRAY;
221 verify_decorators<expected_mo_decorators | primitive_decorators>();
222 }
223
224 template <DecoratorSet expected_mo_decorators>
225 static void verify_oop_decorators() {
|
74 // BarrierSet::AccessBarrier accessor that attaches GC-required barriers
75 // to the access.
76 // * Step 5.a: Barrier resolution. This step is invoked the first time a runtime-dispatch
77 // happens for an access. The appropriate BarrierSet::AccessBarrier accessor
78 // is resolved, then the function pointer is updated to that accessor for
79 // future invocations.
80 // * Step 5.b: Post-runtime dispatch. This step now casts previously unknown types such
81 // as the address type of an oop on the heap (is it oop* or narrowOop*) to
82 // the appropriate type. It also splits sufficiently orthogonal accesses into
83 // different functions, such as whether the access involves oops or primitives
84 // and whether the access is performed on the heap or outside. Then the
85 // appropriate BarrierSet::AccessBarrier is called to perform the access.
86 //
87 // The implementation of step 1-4 resides in in accessBackend.hpp, to allow selected
88 // accesses to be accessible from only access.hpp, as opposed to access.inline.hpp.
89 // Steps 5.a and 5.b require knowledge about the GC backends, and therefore needs to
90 // include the various GC backend .inline.hpp headers. Their implementation resides in
91 // access.inline.hpp. The accesses that are allowed through the access.hpp file
92 // must be instantiated in access.cpp using the INSTANTIATE_HPP_ACCESS macro.
93
94 template <DecoratorSet decorators = INTERNAL_EMPTY>
95 class Access: public AllStatic {
96 // This function asserts that if an access gets passed in a decorator outside
97 // of the expected_decorators, then something is wrong. It additionally checks
98 // the consistency of the decorators so that supposedly disjoint decorators are indeed
99 // disjoint. For example, an access can not be both in heap and on root at the
100 // same time.
101 template <DecoratorSet expected_decorators>
102 static void verify_decorators();
103
104 template <DecoratorSet expected_mo_decorators>
105 static void verify_primitive_decorators() {
106 const DecoratorSet primitive_decorators = (AS_DECORATOR_MASK ^ AS_NO_KEEPALIVE ^ AS_DEST_NOT_INITIALIZED) |
107 IN_HEAP | IN_HEAP_ARRAY;
108 verify_decorators<expected_mo_decorators | primitive_decorators>();
109 }
110
111 template <DecoratorSet expected_mo_decorators>
112 static void verify_oop_decorators() {
|