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