197 // NOTE: One of the valid criticisms of this
198 // specialize-oop_oop_iterate-for-specific-closures idiom is that it is
199 // easy to have a silent performance bug: if you fail to de-virtualize,
200 // things still work, just slower. The "SpecializationStats" mode is
201 // intended to at least make such a failure easy to detect.
202 // *Not* using the ALL_SINCE_SAVE_MARKS_CLOSURES(f) macro defined
203 // below means that *only* closures for which oop_oop_iterate specializations
204 // exist above may be applied to "oops_since_save_marks". That is,
205 // this form of the performance bug is caught statically. When you add
206 // a definition for the general type, this property goes away.
207 // Make sure you test with SpecializationStats to find such bugs
208 // when introducing a new closure where you don't want virtual dispatch.
209
210 #define ALL_SINCE_SAVE_MARKS_CLOSURES(f) \
211 f(OopsInGenClosure,_v) \
212 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f)
213
214 // For keeping stats on effectiveness.
215 #define ENABLE_SPECIALIZATION_STATS 0
216
217 enum DispatchTag {
218 _unknown_klass = 1,
219 _instance_mirror_klass,
220 _instance_class_loader_klass,
221 _instance_ref_klass,
222 };
223
224 /**
225 * The OopClosureDispatcher is a proxy class that automatically figures out
226 * which OopClosure member function to call. It first checks for overridden
227 * specializations using macros (only needed for OopClosure and
228 * ExtendedOopClosure. These will result in virtual calls.
229 * Otherwise if it's a subclass of these two, it will first try to call
230 * the corresponding _nv member function for backward compatibility.
231 * Otherwise, it will check for a a normal non nv declaration, in the derived
232 * class (not the super class). If it exists, it will be called, otherwise
233 * it resorts to a normal virtual call.
234 */
235 class OopClosureDispatcher : AllStatic {
236 template<class OopClosureType, class OopType>
237 static typename enable_if<!has_member_function_do_oop_nv<OopClosureType, void (OopClosureType::*)(OopType *obj)>::value, void>::type
238 do_oop_internal_try_nv(OopClosureType *cl, OopType *obj);
239
240 template<class OopClosureType, class OopType>
241 static typename enable_if<has_member_function_do_oop_nv<OopClosureType, void (OopClosureType::*)(OopType *obj)>::value, void>::type
242 do_oop_internal_try_nv(OopClosureType *cl, OopType *obj);
|
197 // NOTE: One of the valid criticisms of this
198 // specialize-oop_oop_iterate-for-specific-closures idiom is that it is
199 // easy to have a silent performance bug: if you fail to de-virtualize,
200 // things still work, just slower. The "SpecializationStats" mode is
201 // intended to at least make such a failure easy to detect.
202 // *Not* using the ALL_SINCE_SAVE_MARKS_CLOSURES(f) macro defined
203 // below means that *only* closures for which oop_oop_iterate specializations
204 // exist above may be applied to "oops_since_save_marks". That is,
205 // this form of the performance bug is caught statically. When you add
206 // a definition for the general type, this property goes away.
207 // Make sure you test with SpecializationStats to find such bugs
208 // when introducing a new closure where you don't want virtual dispatch.
209
210 #define ALL_SINCE_SAVE_MARKS_CLOSURES(f) \
211 f(OopsInGenClosure,_v) \
212 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f)
213
214 // For keeping stats on effectiveness.
215 #define ENABLE_SPECIALIZATION_STATS 0
216
217 typedef enum DispatchTag {
218 _unknown_klass = 1,
219 _instance_mirror_klass,
220 _instance_class_loader_klass,
221 _instance_ref_klass
222 } DispatchTag;
223
224 /**
225 * The OopClosureDispatcher is a proxy class that automatically figures out
226 * which OopClosure member function to call. It first checks for overridden
227 * specializations using macros (only needed for OopClosure and
228 * ExtendedOopClosure. These will result in virtual calls.
229 * Otherwise if it's a subclass of these two, it will first try to call
230 * the corresponding _nv member function for backward compatibility.
231 * Otherwise, it will check for a a normal non nv declaration, in the derived
232 * class (not the super class). If it exists, it will be called, otherwise
233 * it resorts to a normal virtual call.
234 */
235 class OopClosureDispatcher : AllStatic {
236 template<class OopClosureType, class OopType>
237 static typename enable_if<!has_member_function_do_oop_nv<OopClosureType, void (OopClosureType::*)(OopType *obj)>::value, void>::type
238 do_oop_internal_try_nv(OopClosureType *cl, OopType *obj);
239
240 template<class OopClosureType, class OopType>
241 static typename enable_if<has_member_function_do_oop_nv<OopClosureType, void (OopClosureType::*)(OopType *obj)>::value, void>::type
242 do_oop_internal_try_nv(OopClosureType *cl, OopType *obj);
|