1 /*
2 * Copyright (c) 2001, 2015, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
26 #define SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
27
28 #include "gc/shared/barrierSet.hpp"
29 #include "gc/shared/cardTableModRefBS.inline.hpp"
30
31 // Inline functions of BarrierSet, which de-virtualize certain
32 // performance-critical calls when the barrier is the most common
33 // card-table kind.
34
35 inline bool BarrierSet::devirtualize_reference_writes() const {
36 switch (kind()) {
37 case CardTableForRS:
38 case CardTableExtension:
39 return true;
40 default:
41 return false;
42 }
43 }
44
45 template <class T> void BarrierSet::write_ref_field_pre(T* field, oop new_val) {
46 if (devirtualize_reference_writes()) {
47 barrier_set_cast<CardTableModRefBS>(this)->inline_write_ref_field_pre(field, new_val);
48 } else {
49 write_ref_field_pre_work(field, new_val);
50 }
51 }
52
53 void BarrierSet::write_ref_field(void* field, oop new_val, bool release) {
54 if (devirtualize_reference_writes()) {
55 barrier_set_cast<CardTableModRefBS>(this)->inline_write_ref_field(field, new_val, release);
56 } else {
57 write_ref_field_work(field, new_val, release);
58 }
59 }
60
61 // count is number of array elements being written
62 void BarrierSet::write_ref_array(HeapWord* start, size_t count) {
63 assert(count <= (size_t)max_intx, "count too large");
64 HeapWord* end = (HeapWord*)((char*)start + (count*heapOopSize));
65 // In the case of compressed oops, start and end may potentially be misaligned;
66 // so we need to conservatively align the first downward (this is not
67 // strictly necessary for current uses, but a case of good hygiene and,
68 // if you will, aesthetics) and the second upward (this is essential for
69 // current uses) to a HeapWord boundary, so we mark all cards overlapping
70 // this write. If this evolves in the future to calling a
71 // logging barrier of narrow oop granularity, like the pre-barrier for G1
72 // (mentioned here merely by way of example), we will need to change this
73 // interface, so it is "exactly precise" (if i may be allowed the adverbial
74 // redundancy for emphasis) and does not include narrow oop slots not
75 // included in the original write interval.
76 HeapWord* aligned_start = (HeapWord*)align_size_down((uintptr_t)start, HeapWordSize);
77 HeapWord* aligned_end = (HeapWord*)align_size_up ((uintptr_t)end, HeapWordSize);
78 // If compressed oops were not being used, these should already be aligned
79 assert(UseCompressedOops || (aligned_start == start && aligned_end == end),
80 "Expected heap word alignment of start and end");
81 write_ref_array_work(MemRegion(aligned_start, aligned_end));
82 }
83
84
85 inline void BarrierSet::write_region(MemRegion mr) {
86 if (devirtualize_reference_writes()) {
87 barrier_set_cast<CardTableModRefBS>(this)->inline_write_region(mr);
88 } else {
89 write_region_work(mr);
90 }
91 }
92
93 #endif // SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
|
1 /*
2 * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
26 #define SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
27
28 #include "gc/shared/barrierSet.hpp"
29 #include "gc/shared/barrierSetConfig.inline.hpp"
30 #include "runtime/access.hpp"
31
32 namespace AccessInternal {
33
34 template <typename T, T>
35 struct HasOverloadHelper {};
36
37 template <class GCBarrierType, typename FuncType>
38 struct HasOopStoreAtOverload {
39 typedef jint yes;
40 typedef jbyte no;
41
42 template <typename F, typename T>
43 static yes& test(HasOverloadHelper<F, T::oop_store_at>*);
44 template <typename F, typename T>
45 static no& test(...);
46
47 enum {
48 value = sizeof(test<FuncType, GCBarrierType>(0)) == sizeof(yes)
49 };
50 };
51
52 template <class GCBarrierType, BarrierType type, DecoratorSet idecorators, typename T>
53 class AccessBarrierResolverProxy: public AllStatic { };
54
55 template <class GCBarrierType, DecoratorSet idecorators, typename P>
56 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_STORE, idecorators, P>: public AllStatic {
57 template <DecoratorSet decorators, typename T>
58 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
59 return (void*)&GCBarrierType::template store<T>;
60 }
61
62 template <DecoratorSet decorators, typename T>
63 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
64 return (void*)&GCBarrierType::oop_store;
65 }
66
67 public:
68 static void* resolve_barrier_type() {
69 return resolve_barrier_type_internal<idecorators, P>();
70 }
71 };
72
73 template <class GCBarrierType, DecoratorSet idecorators, typename P>
74 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_STORE_AT, idecorators, P>: public AllStatic {
75 public:
76 template <DecoratorSet decorators, typename T>
77 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
78 return (void*)&GCBarrierType::template store_at<T>;
79 }
80
81 // resolve_barrier_type_base searches the AccessBarrier class hierarchy for a
82 // matching overload of oop_store_at. The different overloads represent
83 // different base pointer types such as nmethod* oop or Klass*
84 template <class BarrierType, DecoratorSet decorators, typename T>
85 static typename EnableIf<HasOopStoreAtOverload<BarrierType, typename AccessFunctionTypes<decorators, T>::store_at_func_t>::value, void*>::type resolve_barrier_type_base() {
86 typename AccessFunctionTypes<decorators, T>::store_at_func_t resolved = &BarrierType::oop_store_at;
87 return (void*)resolved;
88 }
89
90 template <class BarrierType, DecoratorSet decorators, typename T>
91 static typename EnableIf<!HasOopStoreAtOverload<BarrierType, typename AccessFunctionTypes<decorators, T>::store_at_func_t>::value, void*>::type resolve_barrier_type_base() {
92 return AccessBarrierResolverProxy<typename BarrierType::SuperAccessBarrier, BARRIER_STORE_AT, decorators, P>::template resolve_barrier_type_base<typename BarrierType::SuperAccessBarrier, decorators, T>();
93 }
94
95 template <DecoratorSet decorators, typename T>
96 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
97 return resolve_barrier_type_base<GCBarrierType, decorators, T>();
98 }
99
100 static void* resolve_barrier_type() {
101 return resolve_barrier_type_internal<idecorators, P>();
102 }
103 };
104
105 template <class GCBarrierType, DecoratorSet idecorators, typename P>
106 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_LOAD, idecorators, P>: public AllStatic {
107 template <DecoratorSet decorators, typename T>
108 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
109 return (void*)&GCBarrierType::template load<T>;
110 }
111
112 template <DecoratorSet decorators, typename T>
113 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
114 return (void*)&GCBarrierType::oop_load;
115 }
116 public:
117 static void* resolve_barrier_type() {
118 return resolve_barrier_type_internal<idecorators, P>();
119 }
120 };
121
122 template <class GCBarrierType, DecoratorSet idecorators, typename P>
123 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_LOAD_AT, idecorators, P>: public AllStatic {
124 template <DecoratorSet decorators, typename T>
125 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
126 return (void*)&GCBarrierType::template load_at<T>;
127 }
128
129 template <DecoratorSet decorators, typename T>
130 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
131 return (void*)&GCBarrierType::oop_load_at;
132 }
133
134 public:
135 static void* resolve_barrier_type() {
136 return resolve_barrier_type_internal<idecorators, P>();
137 }
138 };
139
140 template <class GCBarrierType, DecoratorSet idecorators, typename P>
141 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_CAS, idecorators, P>: public AllStatic {
142 template <DecoratorSet decorators, typename T>
143 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
144 return (void*)&GCBarrierType::template cas<T>;
145 }
146
147 template <DecoratorSet decorators, typename T>
148 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
149 return (void*)&GCBarrierType::oop_cas;
150 }
151
152 public:
153 static void* resolve_barrier_type() {
154 return resolve_barrier_type_internal<idecorators, P>();
155 }
156 };
157
158 template <class GCBarrierType, DecoratorSet idecorators, typename P>
159 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_CAS_AT, idecorators, P>: public AllStatic {
160 template <DecoratorSet decorators, typename T>
161 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
162 return (void*)&GCBarrierType::template cas_at<T>;
163 }
164
165 template <DecoratorSet decorators, typename T>
166 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
167 return (void*)&GCBarrierType::oop_cas_at;
168 }
169
170 public:
171 static void* resolve_barrier_type() {
172 return resolve_barrier_type_internal<idecorators, P>();
173 }
174 };
175
176 template <class GCBarrierType, DecoratorSet idecorators, typename P>
177 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_SWAP, idecorators, P>: public AllStatic {
178 template <DecoratorSet decorators, typename T>
179 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
180 return (void*)&GCBarrierType::template swap<T>;
181 }
182
183 template <DecoratorSet decorators, typename T>
184 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
185 return (void*)&GCBarrierType::oop_swap;
186 }
187
188 public:
189 static void* resolve_barrier_type() {
190 return resolve_barrier_type_internal<idecorators, P>();
191 }
192 };
193
194 template <class GCBarrierType, DecoratorSet idecorators, typename P>
195 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_SWAP_AT, idecorators, P>: public AllStatic {
196 template <DecoratorSet decorators, typename T>
197 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
198 return (void*)&GCBarrierType::template swap_at<T>;
199 }
200
201 template <DecoratorSet decorators, typename T>
202 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
203 return (void*)&GCBarrierType::oop_swap_at;
204 }
205
206 public:
207 static void* resolve_barrier_type() {
208 return resolve_barrier_type_internal<idecorators, P>();
209 }
210 };
211
212 template <class GCBarrierType, DecoratorSet idecorators, typename P>
213 class AccessBarrierResolverProxy<GCBarrierType, BARRIER_COPY, idecorators, P>: public AllStatic {
214 template <DecoratorSet decorators, typename T>
215 static typename EnableIf<!DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
216 return (void*)&GCBarrierType::template copy<T>;
217 }
218
219 template <DecoratorSet decorators, typename T>
220 static typename EnableIf<DecoratorTest<decorators>::HAS_VALUE_IS_OOP, void*>::type resolve_barrier_type_internal() {
221 return (void*)&GCBarrierType::template oop_copy<T>;
222 }
223
224 public:
225 static void* resolve_barrier_type() {
226 return resolve_barrier_type_internal<idecorators, P>();
227 }
228 };
229
230 }
231
232 template <DecoratorSet decorators, typename T, BarrierType barrier_type>
233 void* BarrierSet::resolve_barrier() {
234 switch (kind()) {
235 #define BARRIER_SET_RESOLVE_BARRIER_CLOSURE(bs_name) \
236 case bs_name : { \
237 return AccessInternal::AccessBarrierResolverProxy<typename BSNameToType< bs_name >::type::AccessBarrier<decorators>, barrier_type, decorators, T>::resolve_barrier_type(); \
238 } \
239 break;
240 FOR_EACH_CONCRETE_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE)
241 #undef BARRIER_SET_RESOLVE_BARRIER_CLOSURE
242
243 default:
244 fatal("BarrierSet AccessBarrier resolving not implemented");
245 return NULL;
246 };
247 }
248
249 template <DecoratorSet decorators>
250 void* BarrierSet::resolve_clone_barrier() {
251 switch (kind()) {
252 #define BARRIER_SET_RESOLVE_BARRIER_CLOSURE(bs_name) \
253 case bs_name : { \
254 return (void*)&BSNameToType< bs_name >::type::AccessBarrier<decorators>::clone; \
255 } \
256 break;
257 FOR_EACH_CONCRETE_BARRIER_SET_DO(BARRIER_SET_RESOLVE_BARRIER_CLOSURE)
258 #undef BARRIER_SET_RESOLVE_BARRIER_CLOSURE
259
260 default:
261 fatal("BarrierSet AccessBarrier resolving not implemented");
262 return NULL;
263 };
264 }
265
266 template <DecoratorSet decorators>
267 inline void BarrierSet::AccessBarrier<decorators>::oop_store(void* addr, oop value) {
268 Basic::template oop_store<oop>(addr, value);
269 }
270
271 template <DecoratorSet decorators>
272 inline void BarrierSet::AccessBarrier<decorators>::oop_store_at(oop base, ptrdiff_t offset, oop value) {
273 Basic::template oop_store_at<oop>((void*)base, offset, value);
274 }
275
276 template <DecoratorSet decorators>
277 inline void BarrierSet::AccessBarrier<decorators>::oop_store_at(nmethod* base, ptrdiff_t offset, oop value) {
278 Basic::template oop_store_at<oop>((void*)base, offset, value);
279 }
280
281 template <DecoratorSet decorators>
282 inline void BarrierSet::AccessBarrier<decorators>::oop_store_at(Klass* base, ptrdiff_t offset, oop value) {
283 Basic::template oop_store_at<oop>((void*)base, offset, value);
284 }
285
286 template <DecoratorSet decorators>
287 inline oop BarrierSet::AccessBarrier<decorators>::oop_load(void* addr) {
288 return Basic::template oop_load<oop>(addr);
289 }
290
291 template <DecoratorSet decorators>
292 inline oop BarrierSet::AccessBarrier<decorators>::oop_load_at(oop base, ptrdiff_t offset) {
293 return Basic::template oop_load_at<oop>((void*)base, offset);
294 }
295
296 template <DecoratorSet decorators>
297 inline oop BarrierSet::AccessBarrier<decorators>::oop_cas(oop new_value, void* addr, oop compare_value) {
298 return Basic::template oop_cas<oop>(new_value, addr, compare_value);
299 }
300
301 template <DecoratorSet decorators>
302 inline oop BarrierSet::AccessBarrier<decorators>::oop_cas_at(oop new_value, oop base, ptrdiff_t offset, oop compare_value) {
303 return Basic::template oop_cas_at<oop>(new_value, (void*)base, offset, compare_value);
304 }
305
306 template <DecoratorSet decorators>
307 inline oop BarrierSet::AccessBarrier<decorators>::oop_swap(oop new_value, void* addr) {
308 return Basic::template oop_swap<oop>(new_value, addr);
309 }
310
311 template <DecoratorSet decorators>
312 inline oop BarrierSet::AccessBarrier<decorators>::oop_swap_at(oop new_value, oop base, ptrdiff_t offset) {
313 return Basic::template oop_swap_at<oop>(new_value, (void*)base, offset);
314 }
315
316 #endif // SHARE_VM_GC_SHARED_BARRIERSET_INLINE_HPP
|