1 /* 2 * Copyright (c) 2014, 2017, 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_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 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_VM_MEMORY_ITERATOR_INLINE_HPP