63 } |
63 } |
64 } |
64 } |
65 #endif |
65 #endif |
66 |
66 |
67 // Implementation of the non-virtual do_oop dispatch. |
67 // Implementation of the non-virtual do_oop dispatch. |
68 |
68 // |
69 template <class OopClosureType, typename T> |
69 // The same implementation is used for do_metadata, do_klass, and do_cld. |
70 inline void Devirtualizer<true>::do_oop(OopClosureType* closure, T* p) { |
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) { |
71 debug_only(closure->verify(p)); |
129 debug_only(closure->verify(p)); |
72 closure->do_oop_nv(p); |
130 |
73 } |
131 do_oop_no_verify(closure, p); |
74 template <class OopClosureType> |
132 } |
75 inline void Devirtualizer<true>::do_klass(OopClosureType* closure, Klass* k) { |
133 |
76 closure->do_klass_nv(k); |
134 // Implementation of the non-virtual do_metadata dispatch. |
77 } |
135 |
78 template <class OopClosureType> |
136 template <typename Receiver, typename Base, typename OopClosureType> |
79 void Devirtualizer<true>::do_cld(OopClosureType* closure, ClassLoaderData* cld) { |
137 static typename EnableIf<IsSame<Receiver, Base>::value, bool>::type |
80 closure->do_cld_nv(cld); |
138 call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) { |
81 } |
139 return closure->do_metadata(); |
82 template <class OopClosureType> |
140 } |
83 inline bool Devirtualizer<true>::do_metadata(OopClosureType* closure) { |
141 |
84 // Make sure the non-virtual and the virtual versions match. |
142 template <typename Receiver, typename Base, typename OopClosureType> |
85 assert(closure->do_metadata_nv() == closure->do_metadata(), "Inconsistency in do_metadata"); |
143 static typename EnableIf<!IsSame<Receiver, Base>::value, bool>::type |
86 return closure->do_metadata_nv(); |
144 call_do_metadata(bool (Receiver::*)(), bool (Base::*)(), OopClosureType* closure) { |
87 } |
145 return closure->OopClosureType::do_metadata(); |
88 |
146 } |
89 // Implementation of the virtual do_oop dispatch. |
147 |
90 |
148 template <typename OopClosureType> |
91 template <class OopClosureType, typename T> |
149 inline bool Devirtualizer::do_metadata(OopClosureType* closure) { |
92 void Devirtualizer<false>::do_oop(OopClosureType* closure, T* p) { |
150 return call_do_metadata(&OopClosureType::do_metadata, &OopIterateClosure::do_metadata, closure); |
93 debug_only(closure->verify(p)); |
151 } |
94 closure->do_oop(p); |
152 |
95 } |
153 // Implementation of the non-virtual do_klass dispatch. |
96 template <class OopClosureType> |
154 |
97 void Devirtualizer<false>::do_klass(OopClosureType* closure, Klass* k) { |
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) { |
98 closure->do_klass(k); |
158 closure->do_klass(k); |
99 } |
159 } |
100 template <class OopClosureType> |
160 |
101 void Devirtualizer<false>::do_cld(OopClosureType* closure, ClassLoaderData* cld) { |
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) { |
102 closure->do_cld(cld); |
177 closure->do_cld(cld); |
103 } |
178 } |
104 template <class OopClosureType> |
179 |
105 bool Devirtualizer<false>::do_metadata(OopClosureType* closure) { |
180 template <typename Receiver, typename Base, typename OopClosureType> |
106 return closure->do_metadata(); |
181 static typename EnableIf<!IsSame<Receiver, Base>::value, void>::type |
107 } |
182 call_do_cld(void (Receiver::*)(ClassLoaderData*), void (Base::*)(ClassLoaderData*), OopClosureType* closure, ClassLoaderData* cld) { |
108 |
183 closure->OopClosureType::do_cld(cld); |
109 // The list of all "specializable" oop_oop_iterate function definitions. |
184 } |
110 #define ALL_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ |
185 |
111 ALL_INSTANCE_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) \ |
186 template <typename OopClosureType> |
112 ALL_INSTANCE_REF_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) \ |
187 void Devirtualizer::do_cld(OopClosureType* closure, ClassLoaderData* cld) { |
113 ALL_INSTANCE_MIRROR_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) \ |
188 call_do_cld(&OopClosureType::do_cld, &OopIterateClosure::do_cld, closure, cld); |
114 ALL_INSTANCE_CLASS_LOADER_KLASS_OOP_OOP_ITERATE_DEFN(OopClosureType, nv_suffix) \ |
189 } |
115 ALL_OBJ_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) \ |
190 |
116 ALL_TYPE_ARRAY_KLASS_OOP_OOP_ITERATE_DEFN( OopClosureType, nv_suffix) |
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 } |
117 |
423 |
118 #endif // SHARE_VM_MEMORY_ITERATOR_INLINE_HPP |
424 #endif // SHARE_VM_MEMORY_ITERATOR_INLINE_HPP |