src/hotspot/share/memory/iterator.inline.hpp
changeset 50752 9d62da00bf15
parent 49592 77fb0be7d19f
child 52141 de6dc206a92b
equal deleted inserted replaced
50751:d9132bdf6c30 50752:9d62da00bf15
    36 #include "oops/instanceRefKlass.inline.hpp"
    36 #include "oops/instanceRefKlass.inline.hpp"
    37 #include "oops/objArrayKlass.inline.hpp"
    37 #include "oops/objArrayKlass.inline.hpp"
    38 #include "oops/typeArrayKlass.inline.hpp"
    38 #include "oops/typeArrayKlass.inline.hpp"
    39 #include "utilities/debug.hpp"
    39 #include "utilities/debug.hpp"
    40 
    40 
    41 inline void MetadataAwareOopClosure::do_cld_nv(ClassLoaderData* cld) {
    41 inline void MetadataVisitingOopIterateClosure::do_cld(ClassLoaderData* cld) {
    42   bool claim = true;  // Must claim the class loader data before processing.
    42   bool claim = true;  // Must claim the class loader data before processing.
    43   cld->oops_do(this, claim);
    43   cld->oops_do(this, claim);
    44 }
    44 }
    45 
    45 
    46 inline void MetadataAwareOopClosure::do_klass_nv(Klass* k) {
    46 inline void MetadataVisitingOopIterateClosure::do_klass(Klass* k) {
    47   ClassLoaderData* cld = k->class_loader_data();
    47   ClassLoaderData* cld = k->class_loader_data();
    48   do_cld_nv(cld);
    48   MetadataVisitingOopIterateClosure::do_cld(cld);
    49 }
    49 }
    50 
    50 
    51 #ifdef ASSERT
    51 #ifdef ASSERT
    52 // This verification is applied to all visited oops.
    52 // This verification is applied to all visited oops.
    53 // The closures can turn is off by overriding should_verify_oops().
    53 // The closures can turn is off by overriding should_verify_oops().
    54 template <typename T>
    54 template <typename T>
    55 void ExtendedOopClosure::verify(T* p) {
    55 void OopIterateClosure::verify(T* p) {
    56   if (should_verify_oops()) {
    56   if (should_verify_oops()) {
    57     T heap_oop = RawAccess<>::oop_load(p);
    57     T heap_oop = RawAccess<>::oop_load(p);
    58     if (!CompressedOops::is_null(heap_oop)) {
    58     if (!CompressedOops::is_null(heap_oop)) {
    59       oop o = CompressedOops::decode_not_null(heap_oop);
    59       oop o = CompressedOops::decode_not_null(heap_oop);
    60       assert(Universe::heap()->is_in_closed_subset(o),
    60       assert(Universe::heap()->is_in_closed_subset(o),
    63   }
    63   }
    64 }
    64 }
    65 #endif
    65 #endif
    66 
    66 
    67 // Implementation of the non-virtual do_oop dispatch.
    67 // Implementation of the non-virtual do_oop dispatch.
    68 
    68 //
    69 template <class OopClosureType, typename T>
    69 // The same implementation is used for do_metadata, do_klass, and do_cld.
    70 inline void Devirtualizer<true>::do_oop(OopClosureType* closure, T* p) {
    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 is 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) {
    71   debug_only(closure->verify(p));
   129   debug_only(closure->verify(p));
    72   closure->do_oop_nv(p);
   130 
    73 }
   131   do_oop_no_verify(closure, p);
    74 template <class OopClosureType>
   132 }
    75 inline void Devirtualizer<true>::do_klass(OopClosureType* closure, Klass* k) {
   133 
    76   closure->do_klass_nv(k);
   134 // Implementation of the non-virtual do_metadata dispatch.
    77 }
   135 
    78 template <class OopClosureType>
   136 template <typename Receiver, typename Base, typename OopClosureType>
    79 void Devirtualizer<true>::do_cld(OopClosureType* closure, ClassLoaderData* cld) {
   137 static typename EnableIf<IsSame<Receiver, Base>::value, bool>::type
    80   closure->do_cld_nv(cld);
   138 call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) {
    81 }
   139   return closure->do_metadata();
    82 template <class OopClosureType>
   140 }
    83 inline bool Devirtualizer<true>::do_metadata(OopClosureType* closure) {
   141 
    84   // Make sure the non-virtual and the virtual versions match.
   142 template <typename Receiver, typename Base, typename OopClosureType>
    85   assert(closure->do_metadata_nv() == closure->do_metadata(), "Inconsistency in do_metadata");
   143 static typename EnableIf<!IsSame<Receiver, Base>::value, bool>::type
    86   return closure->do_metadata_nv();
   144 call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) {
    87 }
   145   return closure->OopClosureType::do_metadata();
    88 
   146 }
    89 // Implementation of the virtual do_oop dispatch.
   147 
    90 
   148 template <typename OopClosureType>
    91 template <class OopClosureType, typename T>
   149 inline bool Devirtualizer::do_metadata(OopClosureType* closure) {
    92 void Devirtualizer<false>::do_oop(OopClosureType* closure, T* p) {
   150   return call_do_metadata(&OopClosureType::do_metadata, &OopIterateClosure::do_metadata, closure);
    93   debug_only(closure->verify(p));
   151 }
    94   closure->do_oop(p);
   152 
    95 }
   153 // Implementation of the non-virtual do_klass dispatch.
    96 template <class OopClosureType>
   154 
    97 void Devirtualizer<false>::do_klass(OopClosureType* closure, Klass* k) {
   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) {
    98   closure->do_klass(k);
   158   closure->do_klass(k);
    99 }
   159 }
   100 template <class OopClosureType>
   160 
   101 void Devirtualizer<false>::do_cld(OopClosureType* closure, ClassLoaderData* cld) {
   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) {
   102   closure->do_cld(cld);
   177   closure->do_cld(cld);
   103 }
   178 }
   104 template <class OopClosureType>
   179 
   105 bool Devirtualizer<false>::do_metadata(OopClosureType* closure) {
   180 template <typename Receiver, typename Base, typename OopClosureType>
   106   return closure->do_metadata();
   181 static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type
   107 }
   182 call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) {
   108 
   183   closure->OopClosureType::do_cld(cld);
   109 // The list of all "specializable" oop_oop_iterate function definitions.
   184 }
   110 #define ALL_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)                  \
   185 
   111   ALL_INSTANCE_KLASS_OOP_OOP_ITERATE_DEFN(             OopClosureType, nv_suffix)  \
   186 template <typename OopClosureType>
   112   ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN(         OopClosureType, nv_suffix)  \
   187 void Devirtualizer::do_cld(OopClosureType* closure, ClassLoaderData* cld) {
   113   ALL_INSTANCE_MIRROR_KLASS_OOP_OOP_ITERATE_DEFN(      OopClosureType, nv_suffix)  \
   188   call_do_cld(&OopClosureType::do_cld, &OopIterateClosure::do_cld, closure, cld);
   114   ALL_INSTANCE_CLASS_LOADER_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix)  \
   189 }
   115   ALL_OBJ_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN(            OopClosureType, nv_suffix)  \
   190 
   116   ALL_TYPE_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN(           OopClosureType, nv_suffix)
   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 : public AllStatic {
       
   228 private:
       
   229   class Table {
       
   230   private:
       
   231     template <typename KlassType, typename T>
       
   232     static void oop_oop_iterate(OopClosureType* cl, oop obj, Klass* k) {
       
   233       ((KlassType*)k)->KlassType::template oop_oop_iterate<T>(obj, cl);
       
   234     }
       
   235 
       
   236     template <typename KlassType>
       
   237     static void init(OopClosureType* cl, oop obj, Klass* k) {
       
   238       OopOopIterateDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k);
       
   239     }
       
   240 
       
   241     template <typename KlassType>
       
   242     void set_init_function() {
       
   243       _function[KlassType::ID] = &init<KlassType>;
       
   244     }
       
   245 
       
   246     template <typename KlassType>
       
   247     void set_resolve_function() {
       
   248       // Size requirement to prevent word tearing
       
   249       // when functions pointers are updated.
       
   250       STATIC_ASSERT(sizeof(_function[0]) == sizeof(void*));
       
   251       if (UseCompressedOops) {
       
   252         _function[KlassType::ID] = &oop_oop_iterate<KlassType, narrowOop>;
       
   253       } else {
       
   254         _function[KlassType::ID] = &oop_oop_iterate<KlassType, oop>;
       
   255       }
       
   256     }
       
   257 
       
   258     template <typename KlassType>
       
   259     void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k) {
       
   260       set_resolve_function<KlassType>();
       
   261       _function[KlassType::ID](cl, obj, k);
       
   262     }
       
   263 
       
   264   public:
       
   265     void (*_function[KLASS_ID_COUNT])(OopClosureType*, oop, Klass*);
       
   266 
       
   267     Table(){
       
   268       set_init_function<InstanceKlass>();
       
   269       set_init_function<InstanceRefKlass>();
       
   270       set_init_function<InstanceMirrorKlass>();
       
   271       set_init_function<InstanceClassLoaderKlass>();
       
   272       set_init_function<ObjArrayKlass>();
       
   273       set_init_function<TypeArrayKlass>();
       
   274     }
       
   275   };
       
   276 
       
   277   static Table _table;
       
   278 public:
       
   279 
       
   280   static void (*function(Klass* klass))(OopClosureType*, oop, Klass*) {
       
   281     return _table._function[klass->id()];
       
   282   }
       
   283 };
       
   284 
       
   285 template <typename OopClosureType>
       
   286 typename OopOopIterateDispatch<OopClosureType>::Table OopOopIterateDispatch<OopClosureType>::_table;
       
   287 
       
   288 
       
   289 template <typename OopClosureType>
       
   290 class OopOopIterateBoundedDispatch {
       
   291 private:
       
   292   class Table {
       
   293   private:
       
   294     template <typename KlassType, typename T>
       
   295     static void oop_oop_iterate_bounded(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
       
   296       ((KlassType*)k)->KlassType::template oop_oop_iterate_bounded<T>(obj, cl, mr);
       
   297     }
       
   298 
       
   299     template <typename KlassType>
       
   300     static void init(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
       
   301       OopOopIterateBoundedDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k, mr);
       
   302     }
       
   303 
       
   304     template <typename KlassType>
       
   305     void set_init_function() {
       
   306       _function[KlassType::ID] = &init<KlassType>;
       
   307     }
       
   308 
       
   309     template <typename KlassType>
       
   310     void set_resolve_function() {
       
   311       if (UseCompressedOops) {
       
   312         _function[KlassType::ID] = &oop_oop_iterate_bounded<KlassType, narrowOop>;
       
   313       } else {
       
   314         _function[KlassType::ID] = &oop_oop_iterate_bounded<KlassType, oop>;
       
   315       }
       
   316     }
       
   317 
       
   318     template <typename KlassType>
       
   319     void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
       
   320       set_resolve_function<KlassType>();
       
   321       _function[KlassType::ID](cl, obj, k, mr);
       
   322     }
       
   323 
       
   324   public:
       
   325     void (*_function[KLASS_ID_COUNT])(OopClosureType*, oop, Klass*, MemRegion);
       
   326 
       
   327     Table(){
       
   328       set_init_function<InstanceKlass>();
       
   329       set_init_function<InstanceRefKlass>();
       
   330       set_init_function<InstanceMirrorKlass>();
       
   331       set_init_function<InstanceClassLoaderKlass>();
       
   332       set_init_function<ObjArrayKlass>();
       
   333       set_init_function<TypeArrayKlass>();
       
   334     }
       
   335   };
       
   336 
       
   337   static Table _table;
       
   338 public:
       
   339 
       
   340   static void (*function(Klass* klass))(OopClosureType*, oop, Klass*, MemRegion) {
       
   341     return _table._function[klass->id()];
       
   342   }
       
   343 };
       
   344 
       
   345 template <typename OopClosureType>
       
   346 typename OopOopIterateBoundedDispatch<OopClosureType>::Table OopOopIterateBoundedDispatch<OopClosureType>::_table;
       
   347 
       
   348 
       
   349 template <typename OopClosureType>
       
   350 class OopOopIterateBackwardsDispatch {
       
   351 private:
       
   352   class Table {
       
   353   private:
       
   354     template <typename KlassType, typename T>
       
   355     static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* k) {
       
   356       ((KlassType*)k)->KlassType::template oop_oop_iterate_reverse<T>(obj, cl);
       
   357     }
       
   358 
       
   359     template <typename KlassType>
       
   360     static void init(OopClosureType* cl, oop obj, Klass* k) {
       
   361       OopOopIterateBackwardsDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k);
       
   362     }
       
   363 
       
   364     template <typename KlassType>
       
   365     void set_init_function() {
       
   366       _function[KlassType::ID] = &init<KlassType>;
       
   367     }
       
   368 
       
   369     template <typename KlassType>
       
   370     void set_resolve_function() {
       
   371       if (UseCompressedOops) {
       
   372         _function[KlassType::ID] = &oop_oop_iterate_backwards<KlassType, narrowOop>;
       
   373       } else {
       
   374         _function[KlassType::ID] = &oop_oop_iterate_backwards<KlassType, oop>;
       
   375       }
       
   376     }
       
   377 
       
   378     template <typename KlassType>
       
   379     void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k) {
       
   380       set_resolve_function<KlassType>();
       
   381       _function[KlassType::ID](cl, obj, k);
       
   382     }
       
   383 
       
   384   public:
       
   385     void (*_function[KLASS_ID_COUNT])(OopClosureType*, oop, Klass*);
       
   386 
       
   387     Table(){
       
   388       set_init_function<InstanceKlass>();
       
   389       set_init_function<InstanceRefKlass>();
       
   390       set_init_function<InstanceMirrorKlass>();
       
   391       set_init_function<InstanceClassLoaderKlass>();
       
   392       set_init_function<ObjArrayKlass>();
       
   393       set_init_function<TypeArrayKlass>();
       
   394     }
       
   395   };
       
   396 
       
   397   static Table _table;
       
   398 public:
       
   399 
       
   400   static void (*function(Klass* klass))(OopClosureType*, oop, Klass*) {
       
   401     return _table._function[klass->id()];
       
   402   }
       
   403 };
       
   404 
       
   405 template <typename OopClosureType>
       
   406 typename OopOopIterateBackwardsDispatch<OopClosureType>::Table OopOopIterateBackwardsDispatch<OopClosureType>::_table;
       
   407 
       
   408 
       
   409 template <typename OopClosureType>
       
   410 void OopIteratorClosureDispatch::oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass) {
       
   411   OopOopIterateDispatch<OopClosureType>::function(klass)(cl, obj, klass);
       
   412 }
       
   413 
       
   414 template <typename OopClosureType>
       
   415 void OopIteratorClosureDispatch::oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr) {
       
   416   OopOopIterateBoundedDispatch<OopClosureType>::function(klass)(cl, obj, klass, mr);
       
   417 }
       
   418 
       
   419 template <typename OopClosureType>
       
   420 void OopIteratorClosureDispatch::oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass) {
       
   421   OopOopIterateBackwardsDispatch<OopClosureType>::function(klass)(cl, obj, klass);
       
   422 }
   117 
   423 
   118 #endif // SHARE_VM_MEMORY_ITERATOR_INLINE_HPP
   424 #endif // SHARE_VM_MEMORY_ITERATOR_INLINE_HPP