1 /*
   2  * Copyright (c) 2014, 2019, 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_MEMORY_ITERATOR_INLINE_HPP
  26 #define SHARE_MEMORY_ITERATOR_INLINE_HPP
  27 
  28 #include "classfile/classLoaderData.hpp"
  29 #include "memory/iterator.hpp"
  30 #include "memory/universe.hpp"
  31 #include "oops/access.inline.hpp"
  32 #include "oops/compressedOops.inline.hpp"
  33 #include "oops/klass.hpp"
  34 #include "oops/instanceKlass.inline.hpp"
  35 #include "oops/instanceMirrorKlass.inline.hpp"
  36 #include "oops/instanceClassLoaderKlass.inline.hpp"
  37 #include "oops/instanceRefKlass.inline.hpp"
  38 #include "oops/objArrayKlass.inline.hpp"
  39 #include "oops/typeArrayKlass.inline.hpp"
  40 #include "utilities/debug.hpp"
  41 
  42 inline void MetadataVisitingOopIterateClosure::do_cld(ClassLoaderData* cld) {
  43   cld->oops_do(this, ClassLoaderData::_claim_strong);
  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(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 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) {
 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 : 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 }
 423 
 424 #endif // SHARE_MEMORY_ITERATOR_INLINE_HPP