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