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