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