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 "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 "oops/valueArrayKlass.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_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 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       set_init_function<ValueArrayKlass>();
 275     }
 276   };
 277 
 278   static Table _table;
 279 public:
 280 
 281   static void (*function(Klass* klass))(OopClosureType*, oop, Klass*) {
 282     return _table._function[klass->id()];
 283   }
 284 };
 285 
 286 template <typename OopClosureType>
 287 typename OopOopIterateDispatch<OopClosureType>::Table OopOopIterateDispatch<OopClosureType>::_table;
 288 
 289 
 290 template <typename OopClosureType>
 291 class OopOopIterateBoundedDispatch {
 292 private:
 293   class Table {
 294   private:
 295     template <typename KlassType, typename T>
 296     static void oop_oop_iterate_bounded(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
 297       ((KlassType*)k)->KlassType::template oop_oop_iterate_bounded<T>(obj, cl, mr);
 298     }
 299 
 300     template <typename KlassType>
 301     static void init(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
 302       OopOopIterateBoundedDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k, mr);
 303     }
 304 
 305     template <typename KlassType>
 306     void set_init_function() {
 307       _function[KlassType::ID] = &init<KlassType>;
 308     }
 309 
 310     template <typename KlassType>
 311     void set_resolve_function() {
 312       if (UseCompressedOops) {
 313         _function[KlassType::ID] = &oop_oop_iterate_bounded<KlassType, narrowOop>;
 314       } else {
 315         _function[KlassType::ID] = &oop_oop_iterate_bounded<KlassType, oop>;
 316       }
 317     }
 318 
 319     template <typename KlassType>
 320     void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k, MemRegion mr) {
 321       set_resolve_function<KlassType>();
 322       _function[KlassType::ID](cl, obj, k, mr);
 323     }
 324 
 325   public:
 326     void (*_function[KLASS_ID_COUNT])(OopClosureType*, oop, Klass*, MemRegion);
 327 
 328     Table(){
 329       set_init_function<InstanceKlass>();
 330       set_init_function<InstanceRefKlass>();
 331       set_init_function<InstanceMirrorKlass>();
 332       set_init_function<InstanceClassLoaderKlass>();
 333       set_init_function<ObjArrayKlass>();
 334       set_init_function<TypeArrayKlass>();
 335       set_init_function<ValueArrayKlass>();
 336     }
 337   };
 338 
 339   static Table _table;
 340 public:
 341 
 342   static void (*function(Klass* klass))(OopClosureType*, oop, Klass*, MemRegion) {
 343     return _table._function[klass->id()];
 344   }
 345 };
 346 
 347 template <typename OopClosureType>
 348 typename OopOopIterateBoundedDispatch<OopClosureType>::Table OopOopIterateBoundedDispatch<OopClosureType>::_table;
 349 
 350 
 351 template <typename OopClosureType>
 352 class OopOopIterateBackwardsDispatch {
 353 private:
 354   class Table {
 355   private:
 356     template <typename KlassType, typename T>
 357     static void oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* k) {
 358       ((KlassType*)k)->KlassType::template oop_oop_iterate_reverse<T>(obj, cl);
 359     }
 360 
 361     template <typename KlassType>
 362     static void init(OopClosureType* cl, oop obj, Klass* k) {
 363       OopOopIterateBackwardsDispatch<OopClosureType>::_table.set_resolve_function_and_execute<KlassType>(cl, obj, k);
 364     }
 365 
 366     template <typename KlassType>
 367     void set_init_function() {
 368       _function[KlassType::ID] = &init<KlassType>;
 369     }
 370 
 371     template <typename KlassType>
 372     void set_resolve_function() {
 373       if (UseCompressedOops) {
 374         _function[KlassType::ID] = &oop_oop_iterate_backwards<KlassType, narrowOop>;
 375       } else {
 376         _function[KlassType::ID] = &oop_oop_iterate_backwards<KlassType, oop>;
 377       }
 378     }
 379 
 380     template <typename KlassType>
 381     void set_resolve_function_and_execute(OopClosureType* cl, oop obj, Klass* k) {
 382       set_resolve_function<KlassType>();
 383       _function[KlassType::ID](cl, obj, k);
 384     }
 385 
 386   public:
 387     void (*_function[KLASS_ID_COUNT])(OopClosureType*, oop, Klass*);
 388 
 389     Table(){
 390       set_init_function<InstanceKlass>();
 391       set_init_function<InstanceRefKlass>();
 392       set_init_function<InstanceMirrorKlass>();
 393       set_init_function<InstanceClassLoaderKlass>();
 394       set_init_function<ObjArrayKlass>();
 395       set_init_function<TypeArrayKlass>();
 396       set_init_function<ValueArrayKlass>();
 397     }
 398   };
 399 
 400   static Table _table;
 401 public:
 402 
 403   static void (*function(Klass* klass))(OopClosureType*, oop, Klass*) {
 404     return _table._function[klass->id()];
 405   }
 406 };
 407 
 408 template <typename OopClosureType>
 409 typename OopOopIterateBackwardsDispatch<OopClosureType>::Table OopOopIterateBackwardsDispatch<OopClosureType>::_table;
 410 
 411 
 412 template <typename OopClosureType>
 413 void OopIteratorClosureDispatch::oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass) {
 414   OopOopIterateDispatch<OopClosureType>::function(klass)(cl, obj, klass);
 415 }
 416 
 417 template <typename OopClosureType>
 418 void OopIteratorClosureDispatch::oop_oop_iterate(OopClosureType* cl, oop obj, Klass* klass, MemRegion mr) {
 419   OopOopIterateBoundedDispatch<OopClosureType>::function(klass)(cl, obj, klass, mr);
 420 }
 421 
 422 template <typename OopClosureType>
 423 void OopIteratorClosureDispatch::oop_oop_iterate_backwards(OopClosureType* cl, oop obj, Klass* klass) {
 424   OopOopIterateBackwardsDispatch<OopClosureType>::function(klass)(cl, obj, klass);
 425 }
 426 
 427 #endif // SHARE_MEMORY_ITERATOR_INLINE_HPP