1 /*
   2  * Copyright (c) 2011, 2014, 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_MEMORY_SPECIALIZED_OOP_CLOSURES_INLINE_HPP
  26 #define SHARE_VM_MEMORY_SPECIALIZED_OOP_CLOSURES_INLINE_HPP
  27 
  28 #include "utilities/templateIdioms.hpp"
  29 #include "memory/specialized_oop_closures.hpp"
  30 
  31 template <class OopClosureType, class OopType>
  32 inline typename enable_if<!has_member_function_do_oop<OopClosureType, void (OopClosureType::*)(OopType *obj)>::value, void>::type
  33 OopClosureDispatcher::do_oop_internal_try_v(OopClosureType *cl, OopType *obj) {
  34   cl->do_oop(obj);
  35 }
  36 
  37 template <class OopClosureType, class OopType>
  38 inline typename enable_if<has_member_function_do_oop<OopClosureType, void (OopClosureType::*)(OopType *obj)>::value, void>::type
  39 OopClosureDispatcher::do_oop_internal_try_v(OopClosureType *cl, OopType *obj) {
  40   cl->OopClosureType::do_oop(obj);
  41 }
  42 
  43 template <class OopClosureType, class OopType>
  44 inline typename enable_if<!has_member_function_do_oop_nv<OopClosureType, void (OopClosureType::*)(OopType *obj)>::value, void>::type
  45 OopClosureDispatcher::do_oop_internal_try_nv(OopClosureType *cl, OopType *obj) {
  46   do_oop_internal_try_v<OopClosureType, OopType>(cl, obj);
  47 }
  48 
  49 template <class OopClosureType, class OopType>
  50 inline typename enable_if<has_member_function_do_oop_nv<OopClosureType, void (OopClosureType::*)(OopType *obj)>::value, void>::type
  51 OopClosureDispatcher::do_oop_internal_try_nv(OopClosureType *cl, OopType *obj) {
  52   // Backward-compatibility - if do_oop_nv is declared, use it
  53   cl->do_oop_nv(obj);
  54 }
  55 
  56 template <class OopClosureType, class OopType>
  57 inline void OopClosureDispatcher::do_oop_internal(OopClosureType *cl, OopType *obj) {
  58   do_oop_internal_try_nv<OopClosureType, OopType>(cl, obj);
  59 }
  60 
  61 #define OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_OOP_DEF(OopClosureType, OopType)                \
  62 template <>                                                                                     \
  63 inline void                                                                                     \
  64 OopClosureDispatcher::do_oop_internal<OopClosureType, OopType>(OopClosureType *cl, OopType *obj) { \
  65   reinterpret_cast<OopClosure*>(cl)->do_oop(obj);                                               \
  66 } 
  67 
  68 #define OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_OOP_ALL(OopClosureType)                         \
  69 OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_OOP_DEF(OopClosureType, narrowOop)                      \
  70 OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_OOP_DEF(OopClosureType, oop)
  71 
  72 UNSPECIALIZED_OOP_OOP_ITERATE_CLOSURES(OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_OOP_ALL)
  73 
  74 template <class OopClosureType>
  75 inline typename enable_if<has_member_function_do_metadata<OopClosureType, bool (OopClosureType::*)()>::value, bool>::type
  76 OopClosureDispatcher::do_metadata_internal_try_v(OopClosureType *cl) {
  77   return cl->OopClosureType::do_metadata();
  78 }
  79 
  80 template <class OopClosureType>
  81 inline typename enable_if<!has_member_function_do_metadata<OopClosureType, bool (OopClosureType::*)()>::value, bool>::type
  82 OopClosureDispatcher::do_metadata_internal_try_v(OopClosureType *cl) {
  83   return cl->do_metadata();
  84 }
  85 
  86 // Use _nv call if declared for backward compatibility
  87 template <class OopClosureType>
  88 inline typename enable_if<has_member_function_do_metadata_nv<OopClosureType, bool (OopClosureType::*)()>::value, bool>::type
  89 OopClosureDispatcher::do_metadata_internal_try_nv(OopClosureType *cl) {
  90   return cl->OopClosureType::do_metadata_nv();
  91 }
  92 
  93 // Non-virtualize virtual call if _nv is not declared
  94 template <class OopClosureType>
  95 inline typename enable_if<!has_member_function_do_metadata_nv<OopClosureType, bool (OopClosureType::*)()>::value, bool>::type
  96 OopClosureDispatcher::do_metadata_internal_try_nv(OopClosureType *cl) {
  97   return do_metadata_internal_try_v<OopClosureType>(cl);
  98 }
  99 
 100 template <class OopClosureType>
 101 inline bool OopClosureDispatcher::do_metadata_internal(OopClosureType *cl) {
 102   return do_metadata_internal_try_nv<OopClosureType>(cl);
 103 }
 104 
 105 #define OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_METADATA_DEF(OopClosureType)                    \
 106 template <>                                                                                     \
 107 inline bool                                                                                     \
 108 OopClosureDispatcher::do_metadata_internal<OopClosureType>(OopClosureType *cl) {                \
 109   return reinterpret_cast<ExtendedOopClosure*>(cl)->do_metadata();                              \
 110 }
 111 
 112 UNSPECIALIZED_DO_METADATA_CLOSURES(OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_METADATA_DEF)
 113 
 114 // call _nv for backward compatibility - it is expected to be called if it exists
 115 template <class OopClosureType>
 116 inline typename enable_if<has_member_function_do_klass<OopClosureType, void (OopClosureType::*)(Klass*)>::value, void>::type
 117 OopClosureDispatcher::do_klass_internal_try_v(OopClosureType *cl, Klass *klass) {
 118   cl->OopClosureType::do_klass(klass);
 119 }
 120 
 121 // non-virtualize the virtual call if _nv is not expected
 122 template <class OopClosureType>
 123 inline typename enable_if<!has_member_function_do_klass<OopClosureType, void (OopClosureType::*)(Klass*)>::value, void>::type
 124 OopClosureDispatcher::do_klass_internal_try_v(OopClosureType *cl, Klass *klass) {
 125   cl->do_klass(klass);
 126 }
 127 
 128 // call _nv for backward compatibility - it is expected to be called if it exists
 129 template <class OopClosureType>
 130 inline typename enable_if<has_member_function_do_klass_nv<OopClosureType, void (OopClosureType::*)(Klass*)>::value, void>::type
 131 OopClosureDispatcher::do_klass_internal_try_nv(OopClosureType *cl, Klass *klass) {
 132   cl->do_klass_nv(klass);
 133 }
 134 
 135 // non-virtualize the virtual call if _nv is not expected
 136 template <class OopClosureType>
 137 inline typename enable_if<!has_member_function_do_klass_nv<OopClosureType, void (OopClosureType::*)(Klass*)>::value, void>::type
 138 OopClosureDispatcher::do_klass_internal_try_nv(OopClosureType *cl, Klass *klass) {
 139   do_klass_internal_try_v<OopClosureType>(cl, klass);
 140 }
 141 
 142 template <class OopClosureType>
 143 inline void OopClosureDispatcher::do_klass_internal(OopClosureType *cl, Klass *klass) {
 144   do_klass_internal_try_nv<OopClosureType>(cl, klass);
 145 }
 146 
 147 #define OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_KLASS_DEF(OopClosureType)                       \
 148 template <>                                                                                     \
 149 inline void                                                                                     \
 150 OopClosureDispatcher::do_klass_internal<OopClosureType>(OopClosureType *cl, Klass *klass) {     \
 151   reinterpret_cast<ExtendedOopClosure*>(cl)->do_klass(klass);                                   \
 152 }
 153 
 154 UNSPECIALIZED_DO_METADATA_CLOSURES(OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_KLASS_DEF)
 155 
 156 // non-virtualize the virtual call if the declared type also declared the member function
 157 // note that if a super class declared it, we can't safely remove virtual call
 158 template <class OopClosureType>
 159 inline typename enable_if<has_member_function_do_class_loader_data<OopClosureType, void (OopClosureType::*)(ClassLoaderData*)>::value, void>::type
 160 OopClosureDispatcher::do_class_loader_data_internal_try_v(OopClosureType *cl, ClassLoaderData *cld) {
 161   cl->OopClosureType::do_class_loader_data(cld);
 162 }
 163 
 164 template <class OopClosureType>
 165 inline typename enable_if<!has_member_function_do_class_loader_data<OopClosureType, void (OopClosureType::*)(ClassLoaderData*)>::value, void>::type
 166 OopClosureDispatcher::do_class_loader_data_internal_try_v(OopClosureType *cl, ClassLoaderData *cld) {
 167   cl->do_class_loader_data(cld);
 168 }
 169 
 170 // call _nv for backward compatibility - it is expected to be called if it exists
 171 template <class OopClosureType>
 172 inline typename enable_if<has_member_function_do_class_loader_data_nv<OopClosureType, void (OopClosureType::*)(ClassLoaderData*)>::value, void>::type
 173 OopClosureDispatcher::do_class_loader_data_internal_try_nv(OopClosureType *cl, ClassLoaderData *cld) {
 174   cl->do_class_loader_data_nv(cld);
 175 }
 176 
 177 // non-virtualize the virtual call if _nv is not expected
 178 template <class OopClosureType>
 179 inline typename enable_if<!has_member_function_do_class_loader_data_nv<OopClosureType, void (OopClosureType::*)(ClassLoaderData*)>::value, void>::type
 180 OopClosureDispatcher::do_class_loader_data_internal_try_nv(OopClosureType *cl, ClassLoaderData *cld) {
 181   do_class_loader_data_internal_try_v<OopClosureType>(cl, cld);
 182 }
 183 
 184 template <class OopClosureType>
 185 inline void OopClosureDispatcher::do_class_loader_data_internal(OopClosureType *cl, ClassLoaderData *cld) {
 186   do_class_loader_data_internal_try_nv<OopClosureType>(cl, cld);
 187 }
 188 
 189 #define OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_CLD_DEF(OopClosureType)                         \
 190 template <>                                                                                     \
 191 inline void                                                                                     \
 192 OopClosureDispatcher::do_class_loader_data_internal<OopClosureType>(OopClosureType *cl, ClassLoaderData *cld) {     \
 193   reinterpret_cast<ExtendedOopClosure*>(cl)->do_class_loader_data(cld);                                   \
 194 }
 195 
 196 UNSPECIALIZED_DO_METADATA_CLOSURES(OOP_CLOSURE_DISPATCHER_UNSPECIALIZED_DO_CLD_DEF)
 197 
 198 // Make sure we only dispatch to OopClosure subtypes, otherwise compiler error
 199 template <class OopClosureType, class OopType>
 200 inline typename enable_if<is_kind_of<OopClosure, OopClosureType>::value, void>::type 
 201 OopClosureDispatcher::do_oop(OopClosureType *cl, OopType *obj) {
 202   do_oop_internal<OopClosureType, OopType>(cl, obj);
 203 }
 204 
 205 // Only do metadata stuff on ExtendedOopClosure, otherwise compiler error
 206 template <class OopClosureType>
 207 inline typename enable_if<is_kind_of<ExtendedOopClosure, OopClosureType>::value, bool>::type
 208 OopClosureDispatcher::do_metadata(OopClosureType *cl) {
 209   return do_metadata_internal<OopClosureType>(cl);
 210 }
 211 
 212 template <class OopClosureType>
 213 inline typename enable_if<is_kind_of<ExtendedOopClosure, OopClosureType>::value, void>::type
 214 OopClosureDispatcher::do_klass(OopClosureType *cl, Klass *klass) {
 215   do_klass_internal<OopClosureType>(cl, klass);
 216 }
 217 
 218 template <class OopClosureType>
 219 inline typename enable_if<is_kind_of<ExtendedOopClosure, OopClosureType>::value, void>::type
 220 OopClosureDispatcher::do_class_loader_data(OopClosureType *cl, ClassLoaderData *cld) {
 221   do_class_loader_data_internal<OopClosureType>(cl, cld);
 222 }
 223 
 224 #endif // SHARE_VM_MEMORY_SPECIALIZED_OOP_CLOSURES_INLINE_HPP
 225