21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_MEMORY_ITERATOR_INLINE_HPP 26 #define SHARE_VM_MEMORY_ITERATOR_INLINE_HPP 27 28 #include "classfile/classLoaderData.hpp" 29 #include "memory/iterator.hpp" 30 #include "oops/access.inline.hpp" 31 #include "oops/compressedOops.inline.hpp" 32 #include "oops/klass.hpp" 33 #include "oops/instanceKlass.inline.hpp" 34 #include "oops/instanceMirrorKlass.inline.hpp" 35 #include "oops/instanceClassLoaderKlass.inline.hpp" 36 #include "oops/instanceRefKlass.inline.hpp" 37 #include "oops/objArrayKlass.inline.hpp" 38 #include "oops/typeArrayKlass.inline.hpp" 39 #include "utilities/debug.hpp" 40 41 inline void MetadataAwareOopClosure::do_cld_nv(ClassLoaderData* cld) { 42 bool claim = true; // Must claim the class loader data before processing. 43 cld->oops_do(this, claim); 44 } 45 46 inline void MetadataAwareOopClosure::do_klass_nv(Klass* k) { 47 ClassLoaderData* cld = k->class_loader_data(); 48 do_cld_nv(cld); 49 } 50 51 #ifdef ASSERT 52 // This verification is applied to all visited oops. 53 // The closures can turn is off by overriding should_verify_oops(). 54 template <typename T> 55 void ExtendedOopClosure::verify(T* p) { 56 if (should_verify_oops()) { 57 T heap_oop = RawAccess<>::oop_load(p); 58 if (!CompressedOops::is_null(heap_oop)) { 59 oop o = CompressedOops::decode_not_null(heap_oop); 60 assert(Universe::heap()->is_in_closed_subset(o), 61 "should be in closed *p " PTR_FORMAT " " PTR_FORMAT, p2i(p), p2i(o)); 62 } 63 } 64 } 65 #endif 66 67 // Implementation of the non-virtual do_oop dispatch. 68 69 template <class OopClosureType, typename T> 70 inline void Devirtualizer<true>::do_oop(OopClosureType* closure, T* p) { 71 debug_only(closure->verify(p)); 72 closure->do_oop_nv(p); 73 } 74 template <class OopClosureType> 75 inline void Devirtualizer<true>::do_klass(OopClosureType* closure, Klass* k) { 76 closure->do_klass_nv(k); 77 } 78 template <class OopClosureType> 79 void Devirtualizer<true>::do_cld(OopClosureType* closure, ClassLoaderData* cld) { 80 closure->do_cld_nv(cld); 81 } 82 template <class OopClosureType> 83 inline bool Devirtualizer<true>::do_metadata(OopClosureType* closure) { 84 // Make sure the non-virtual and the virtual versions match. 85 assert(closure->do_metadata_nv() == closure->do_metadata(), "Inconsistency in do_metadata"); 86 return closure->do_metadata_nv(); 87 } 88 89 // Implementation of the virtual do_oop dispatch. 90 91 template <class OopClosureType, typename T> 92 void Devirtualizer<false>::do_oop(OopClosureType* closure, T* p) { 93 debug_only(closure->verify(p)); 94 closure->do_oop(p); 95 } 96 template <class OopClosureType> 97 void Devirtualizer<false>::do_klass(OopClosureType* closure, Klass* k) { 98 closure->do_klass(k); 99 } 100 template <class OopClosureType> 101 void Devirtualizer<false>::do_cld(OopClosureType* closure, ClassLoaderData* cld) { 102 closure->do_cld(cld); 103 } 104 template <class OopClosureType> 105 bool Devirtualizer<false>::do_metadata(OopClosureType* closure) { 106 return closure->do_metadata(); 107 } 108 109 // The list of all "specializable" oop_oop_iterate function definitions. 110 #define ALL_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ 111 ALL_INSTANCE_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) \ 112 ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) \ 113 ALL_INSTANCE_MIRROR_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) \ 114 ALL_INSTANCE_CLASS_LOADER_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ 115 ALL_OBJ_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) \ 116 ALL_TYPE_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) 117 118 #endif // SHARE_VM_MEMORY_ITERATOR_INLINE_HPP | 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_VM_MEMORY_ITERATOR_INLINE_HPP 26 #define SHARE_VM_MEMORY_ITERATOR_INLINE_HPP 27 28 #include "classfile/classLoaderData.hpp" 29 #include "memory/iterator.hpp" 30 #include "oops/access.inline.hpp" 31 #include "oops/compressedOops.inline.hpp" 32 #include "oops/klass.hpp" 33 #include "oops/instanceKlass.inline.hpp" 34 #include "oops/instanceMirrorKlass.inline.hpp" 35 #include "oops/instanceClassLoaderKlass.inline.hpp" 36 #include "oops/instanceRefKlass.inline.hpp" 37 #include "oops/objArrayKlass.inline.hpp" 38 #include "oops/typeArrayKlass.inline.hpp" 39 #include "utilities/debug.hpp" 40 41 inline void MetadataVisitingOopIterateClosure::do_cld(ClassLoaderData* cld) { 42 bool claim = true; // Must claim the class loader data before processing. 43 cld->oops_do(this, claim); 44 } 45 46 inline void MetadataVisitingOopIterateClosure::do_klass(Klass* k) { 47 ClassLoaderData* cld = k->class_loader_data(); 48 MetadataVisitingOopIterateClosure::do_cld(cld); 49 } 50 51 #ifdef ASSERT 52 // This verification is applied to all visited oops. 53 // The closures can turn is off by overriding should_verify_oops(). 54 template <typename T> 55 void OopIterateClosure::verify(T* p) { 56 if (should_verify_oops()) { 57 T heap_oop = RawAccess<>::oop_load(p); 58 if (!CompressedOops::is_null(heap_oop)) { 59 oop o = CompressedOops::decode_not_null(heap_oop); 60 assert(Universe::heap()->is_in_closed_subset(o), 61 "should be in closed *p " PTR_FORMAT " " PTR_FORMAT, p2i(p), p2i(o)); 62 } 63 } 64 } 65 #endif 66 67 // Implementation of the non-virtual do_oop dispatch. 68 // 69 // The same implementation is used for do_metadata, do_klass, and do_cld. 70 // 71 // Preconditions: 72 // - Base has a pure virtual do_oop 73 // - Only one of the classes in the inheritance chain from OopClosureType to 74 // Base implements do_oop. 75 // 76 // Given the preconditions: 77 // - If &OopClosureType::do_oop is resolved to &Base::do_oop, then there are no 78 // implementation of do_oop between Base and OopClosureType. However, there 79 // must be one implementation in one of the subclasses of OopClosureType. 80 // In this case we take the virtual call. 81 // 82 // - Conversely, if &OopClosureType::do_oop is not resolved to &Base::do_oop, 83 // then we've found the one and only concrete implementation. In this case we 84 // take a non-virtual call. 85 // 86 // Because of this it's clear when we should call the virtual call and 87 // when the non-virtual call should be made. 88 // 89 // The way we find if &OopClosureType::do_oop is resolved to &Base::do_oop is to 90 // check if the resulting type of the class of a member-function pointer to 91 // &OopClosureType::do_oop is equal to the type of the class of a 92 // &Base::do_oop member-function pointer. Template parameter deduction is used 93 // to find these types, and then the IsSame trait is used to check if they are 94 // equal. Finally, SFINAE is used to select the appropriate implementation. 95 // 96 // Template parameters: 97 // T - narrowOop or oop 98 // Receiver - the resolved type of the class of the 99 // &OopClosureType::do_oop member-function pointer. That is, 100 // the klass with the do_oop member function. 101 // Base - klass with the pure virtual do_oop member function. 102 // OopClosureType - The dynamic closure type 103 // 104 // Parameters: 105 // closure - The closure to call 106 // p - The oop (or narrowOop) field to pass to the closure 107 108 template <typename T, typename Receiver, typename Base, typename OopClosureType> 109 static typename EnableIf<IsSame<Receiver, Base>::value, void>::type 110 call_do_oop(void (Receiver::*)(T*), void (Base::*)(T*), OopClosureType* closure, T* p) { 111 closure->do_oop(p); 112 } 113 114 template <typename T, typename Receiver, typename Base, typename OopClosureType> 115 static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type 116 call_do_oop(void (Receiver::*)(T*), void (Base::*)(T*), OopClosureType* closure, T* p) { 117 // Sanity check 118 STATIC_ASSERT((!IsSame<OopClosureType, OopIterateClosure>::value)); 119 closure->OopClosureType::do_oop(p); 120 } 121 122 template <typename OopClosureType, typename T> 123 inline void Devirtualizer::do_oop_no_verify(OopClosureType* closure, T* p) { 124 call_do_oop<T>(&OopClosureType::do_oop, &OopClosure::do_oop, closure, p); 125 } 126 127 template <typename OopClosureType, typename T> 128 inline void Devirtualizer::do_oop(OopClosureType* closure, T* p) { 129 debug_only(closure->verify(p)); 130 131 do_oop_no_verify(closure, p); 132 } 133 134 // Implementation of the non-virtual do_metadata dispatch. 135 136 template <typename Receiver, typename Base, typename OopClosureType> 137 static typename EnableIf<IsSame<Receiver, Base>::value, bool>::type 138 call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) { 139 return closure->do_metadata(); 140 } 141 142 template <typename Receiver, typename Base, typename OopClosureType> 143 static typename EnableIf<!IsSame<Receiver, Base>::value, bool>::type 144 call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) { 145 return closure->OopClosureType::do_metadata(); 146 } 147 148 template <typename OopClosureType> 149 inline bool Devirtualizer::do_metadata(OopClosureType* closure) { 150 return call_do_metadata(&OopClosureType::do_metadata, &OopIterateClosure::do_metadata, closure); 151 } 152 153 // Implementation of the non-virtual do_klass dispatch. 154 155 template <typename Receiver, typename Base, typename OopClosureType> 156 static typename EnableIf<IsSame<Receiver, Base>::value, void>::type 157 call_do_klass(void (Receiver::*)(Klass*), void (Base::*)(Klass*), OopClosureType* closure, Klass* k) { 158 closure->do_klass(k); 159 } 160 161 template <typename Receiver, typename Base, typename OopClosureType> 162 static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type 163 call_do_klass(void (Receiver::*)(Klass*), void (Base::*)(Klass*), OopClosureType* closure, Klass* k) { 164 closure->OopClosureType::do_klass(k); 165 } 166 167 template <typename OopClosureType> 168 inline void Devirtualizer::do_klass(OopClosureType* closure, Klass* k) { 169 call_do_klass(&OopClosureType::do_klass, &OopIterateClosure::do_klass, closure, k); 170 } 171 172 // Implementation of the non-virtual do_cld dispatch. 173 174 template <typename Receiver, typename Base, typename OopClosureType> 175 static typename EnableIf<IsSame<Receiver, Base>::value, void>::type 176 call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) { 177 closure->do_cld(cld); 178 } 179 180 template <typename Receiver, typename Base, typename OopClosureType> 181 static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type 182 call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) { 183 closure->OopClosureType::do_cld(cld); 184 } 185 186 template <typename OopClosureType> 187 void Devirtualizer::do_cld(OopClosureType* closure, ClassLoaderData* cld) { 188 call_do_cld(&OopClosureType::do_cld, &OopIterateClosure::do_cld, closure, cld); 189 } 190 191 // Dispatch table implementation for *Klass::oop_oop_iterate 192 // 193 // It allows for a single call to do a multi-dispatch to an optimized version 194 // of oop_oop_iterate that statically know all these types: 195 // - OopClosureType : static type give at call site 196 // - Klass* : dynamic to static type through Klass::id() -> table index 197 // - UseCompressedOops : dynamic to static value determined once 198 // 199 // when users call obj->oop_iterate(&cl). 200 // 201 // oopDesc::oop_iterate() calls OopOopIterateDispatch::function(klass)(cl, obj, klass), 202 // which dispatches to an optimized version of 203 // [Instance, ObjArry, etc]Klass::oop_oop_iterate(oop, OopClosureType) 204 // 205 // OopClosureType : 206 // If OopClosureType has an implementation of do_oop (and do_metadata et.al.), 207 // then the static type of OopClosureType will be used to allow inlining of 208 // do_oop (even though do_oop is virtual). Otherwise, a virtual call will be 209 // used when calling do_oop. 210 // 211 // Klass* : 212 // A table mapping from *Klass::ID to function is setup. This happens once 213 // when the program starts, when the static _table instance is initialized for 214 // the OopOopIterateDispatch specialized with the OopClosureType. 215 // 216 // UseCompressedOops : 217 // Initially the table is populated with an init function, and not the actual 218 // oop_oop_iterate function. This is done, so that the first time we dispatch 219 // through the init function we check what the value of UseCompressedOops 220 // became, and use that to determine if we should install an optimized 221 // narrowOop version or optimized oop version of oop_oop_iterate. The appropriate 222 // oop_oop_iterate function replaces the init function in the table, and 223 // succeeding calls will jump directly to oop_oop_iterate. 224 225 226 template <typename OopClosureType> 227 class OopOopIterateDispatch { 228 private: 229 class Table { 230 private: 231 static const int NUM_KLASSES = 6; 232 233 template <typename KlassType, typename T> 234 static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* k) { 235 ((KlassType*)k)->KlassType::template oop_oop_iterate<T>(obj, cl); 236 } 237 238 template <typename KlassType> 239 static void init(OopClosureType* cl, oop obj, Klass* k) { 240 OopOopIterateDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k); 241 } 242 243 template <typename KlassType> 244 void set_init_function() { 245 _function[KlassType::ID] = &init<KlassType>; 246 } 247 248 template <typename KlassType> 249 void set_resolve_function() { 250 // Size requirement to prevent word tearing 251 // when functions pointers are updated. 252 STATIC_ASSERT(sizeof(_function[0]) == sizeof(void*)); 253 if (UseCompressedOops) { 254 _function[KlassType::ID] = &oop_oop_iterate<KlassType, narrowOop>; 255 } else { 256 _function[KlassType::ID] = &oop_oop_iterate<KlassType, oop>; 257 } 258 } 259 260 template <typename KlassType> 261 void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k) { 262 set_resolve_function<KlassType>(); 263 _function[KlassType::ID](cl, obj, k); 264 } 265 266 public: 267 void (*_function[NUM_KLASSES])(OopClosureType*, oop, Klass*); 268 269 Table(){ 270 set_init_function<InstanceKlass>(); 271 set_init_function<InstanceRefKlass>(); 272 set_init_function<InstanceMirrorKlass>(); 273 set_init_function<InstanceClassLoaderKlass>(); 274 set_init_function<ObjArrayKlass>(); 275 set_init_function<TypeArrayKlass>(); 276 } 277 }; 278 279 static Table _table; 280 public: 281 282 static void (*function(Klass* klass))(OopClosureType*, oop, Klass*) { 283 return _table._function[klass->id()]; 284 } 285 }; 286 287 template <typename OopClosureType> 288 typename OopOopIterateDispatch<OopClosureType>::Table OopOopIterateDispatch<OopClosureType>::_table; 289 290 291 template <typename OopClosureType> 292 class OopOopIterateBoundedDispatch { 293 private: 294 class Table { 295 private: 296 static const int NUM_KLASSES = 6; 297 298 template <typename KlassType, typename T> 299 static void oop_oop_iterate_bounded(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) { 300 ((KlassType*)k)->KlassType::template oop_oop_iterate_bounded<T>(obj, cl, mr); 301 } 302 303 template <typename KlassType> 304 static void init(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) { 305 OopOopIterateBoundedDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k, mr); 306 } 307 308 template <typename KlassType> 309 void set_init_function() { 310 _function[KlassType::ID] = &init<KlassType>; 311 } 312 313 template <typename KlassType> 314 void set_resolve_function() { 315 if (UseCompressedOops) { 316 _function[KlassType::ID] = &oop_oop_iterate_bounded<KlassType, narrowOop>; 317 } else { 318 _function[KlassType::ID] = &oop_oop_iterate_bounded<KlassType, oop>; 319 } 320 } 321 322 template <typename KlassType> 323 void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) { 324 set_resolve_function<KlassType>(); 325 _function[KlassType::ID](cl, obj, k, mr); 326 } 327 328 public: 329 void (*_function[NUM_KLASSES])(OopClosureType*, oop, Klass*, MemRegion); 330 331 Table(){ 332 set_init_function<InstanceKlass>(); 333 set_init_function<InstanceRefKlass>(); 334 set_init_function<InstanceMirrorKlass>(); 335 set_init_function<InstanceClassLoaderKlass>(); 336 set_init_function<ObjArrayKlass>(); 337 set_init_function<TypeArrayKlass>(); 338 } 339 }; 340 341 static Table _table; 342 public: 343 344 static void (*function(Klass* klass))(OopClosureType*, oop, Klass*, MemRegion) { 345 return _table._function[klass->id()]; 346 } 347 }; 348 349 template <typename OopClosureType> 350 typename OopOopIterateBoundedDispatch<OopClosureType>::Table OopOopIterateBoundedDispatch<OopClosureType>::_table; 351 352 353 template <typename OopClosureType> 354 class OopOopIterateBackwardsDispatch { 355 private: 356 class Table { 357 private: 358 static const int NUM_KLASSES = 6; 359 360 template <typename KlassType, typename T> 361 static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* k) { 362 ((KlassType*)k)->KlassType::template oop_oop_iterate_reverse<T>(obj, cl); 363 } 364 365 template <typename KlassType> 366 static void init(OopClosureType* cl, oop obj, Klass* k) { 367 OopOopIterateBackwardsDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k); 368 } 369 370 template <typename KlassType> 371 void set_init_function() { 372 _function[KlassType::ID] = &init<KlassType>; 373 } 374 375 template <typename KlassType> 376 void set_resolve_function() { 377 if (UseCompressedOops) { 378 _function[KlassType::ID] = &oop_oop_iterate_backwards<KlassType, narrowOop>; 379 } else { 380 _function[KlassType::ID] = &oop_oop_iterate_backwards<KlassType, oop>; 381 } 382 } 383 384 template <typename KlassType> 385 void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k) { 386 set_resolve_function<KlassType>(); 387 _function[KlassType::ID](cl, obj, k); 388 } 389 390 public: 391 void (*_function[NUM_KLASSES])(OopClosureType*, oop, Klass*); 392 393 Table(){ 394 set_init_function<InstanceKlass>(); 395 set_init_function<InstanceRefKlass>(); 396 set_init_function<InstanceMirrorKlass>(); 397 set_init_function<InstanceClassLoaderKlass>(); 398 set_init_function<ObjArrayKlass>(); 399 set_init_function<TypeArrayKlass>(); 400 } 401 }; 402 403 static Table _table; 404 public: 405 406 static void (*function(Klass* klass))(OopClosureType*, oop, Klass*) { 407 return _table._function[klass->id()]; 408 } 409 }; 410 411 template <typename OopClosureType> 412 typename OopOopIterateBackwardsDispatch<OopClosureType>::Table OopOopIterateBackwardsDispatch<OopClosureType>::_table; 413 414 415 template <typename OopClosureType> 416 void OopClosureDispatch::oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass) { 417 OopOopIterateDispatch<OopClosureType>::function(klass)(cl, obj, klass); 418 } 419 420 template <typename OopClosureType> 421 void OopClosureDispatch::oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr) { 422 OopOopIterateBoundedDispatch<OopClosureType>::function(klass)(cl, obj, klass, mr); 423 } 424 425 template <typename OopClosureType> 426 void OopClosureDispatch::oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass) { 427 OopOopIterateBackwardsDispatch<OopClosureType>::function(klass)(cl, obj, klass); 428 } 429 430 #endif // SHARE_VM_MEMORY_ITERATOR_INLINE_HPP |