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