< prev index next >

src/hotspot/share/memory/iterator.inline.hpp

Print this page




  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
< prev index next >