1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/memory/specialized_oop_closures.hpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,235 @@ 1.4 +/* 1.5 + * Copyright 2001-2006 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// The following OopClosure types get specialized versions of 1.29 +// "oop_oop_iterate" that invoke the closures' do_oop methods 1.30 +// non-virtually, using a mechanism defined in this file. Extend these 1.31 +// macros in the obvious way to add specializations for new closures. 1.32 + 1.33 +// Forward declarations. 1.34 +class OopClosure; 1.35 +class OopsInGenClosure; 1.36 +// DefNew 1.37 +class ScanClosure; 1.38 +class FastScanClosure; 1.39 +class FilteringClosure; 1.40 +// ParNew 1.41 +class ParScanWithBarrierClosure; 1.42 +class ParScanWithoutBarrierClosure; 1.43 +// CMS 1.44 +class MarkRefsIntoAndScanClosure; 1.45 +class Par_MarkRefsIntoAndScanClosure; 1.46 +class PushAndMarkClosure; 1.47 +class Par_PushAndMarkClosure; 1.48 +class PushOrMarkClosure; 1.49 +class Par_PushOrMarkClosure; 1.50 +class CMSKeepAliveClosure; 1.51 +class CMSInnerParMarkAndPushClosure; 1.52 + 1.53 +// This macro applies an argument macro to all OopClosures for which we 1.54 +// want specialized bodies of "oop_oop_iterate". The arguments to "f" are: 1.55 +// "f(closureType, non_virtual)" 1.56 +// where "closureType" is the name of the particular subclass of OopClosure, 1.57 +// and "non_virtual" will be the string "_nv" if the closure type should 1.58 +// have its "do_oop" method invoked non-virtually, or else the 1.59 +// string "_v". ("OopClosure" itself will be the only class in the latter 1.60 +// category.) 1.61 + 1.62 +// This is split into several because of a Visual C++ 6.0 compiler bug 1.63 +// where very long macros cause the compiler to crash 1.64 + 1.65 +#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_S(f) \ 1.66 + f(ScanClosure,_nv) \ 1.67 + f(FastScanClosure,_nv) \ 1.68 + f(FilteringClosure,_nv) 1.69 + 1.70 +#ifndef SERIALGC 1.71 +#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) \ 1.72 + f(ParScanWithBarrierClosure,_nv) \ 1.73 + f(ParScanWithoutBarrierClosure,_nv) 1.74 +#else // SERIALGC 1.75 +#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) 1.76 +#endif // SERIALGC 1.77 + 1.78 +#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(f) \ 1.79 + SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_S(f) \ 1.80 + SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) 1.81 + 1.82 +#ifndef SERIALGC 1.83 +#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_3(f) \ 1.84 + f(MarkRefsIntoAndScanClosure,_nv) \ 1.85 + f(Par_MarkRefsIntoAndScanClosure,_nv) \ 1.86 + f(PushAndMarkClosure,_nv) \ 1.87 + f(Par_PushAndMarkClosure,_nv) \ 1.88 + f(PushOrMarkClosure,_nv) \ 1.89 + f(Par_PushOrMarkClosure,_nv) \ 1.90 + f(CMSKeepAliveClosure,_nv) \ 1.91 + f(CMSInnerParMarkAndPushClosure,_nv) 1.92 +#else // SERIALGC 1.93 +#define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_3(f) 1.94 +#endif // SERIALGC 1.95 + 1.96 +// We separate these out, because sometime the general one has 1.97 +// a different definition from the specialized ones, and sometimes it 1.98 +// doesn't. 1.99 + 1.100 +#define ALL_OOP_OOP_ITERATE_CLOSURES_1(f) \ 1.101 + f(OopClosure,_v) \ 1.102 + SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(f) 1.103 + 1.104 +#define ALL_OOP_OOP_ITERATE_CLOSURES_3(f) \ 1.105 + SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_3(f) 1.106 + 1.107 +#ifndef SERIALGC 1.108 +// This macro applies an argument macro to all OopClosures for which we 1.109 +// want specialized bodies of a family of methods related to 1.110 +// "par_oop_iterate". The arguments to f are the same as above. 1.111 +// The "root_class" is the most general class to define; this may be 1.112 +// "OopClosure" in some applications and "OopsInGenClosure" in others. 1.113 + 1.114 +#define SPECIALIZED_PAR_OOP_ITERATE_CLOSURES(f) \ 1.115 + f(MarkRefsIntoAndScanClosure,_nv) \ 1.116 + f(PushAndMarkClosure,_nv) \ 1.117 + f(Par_MarkRefsIntoAndScanClosure,_nv) \ 1.118 + f(Par_PushAndMarkClosure,_nv) 1.119 + 1.120 +#define ALL_PAR_OOP_ITERATE_CLOSURES(f) \ 1.121 + f(OopClosure,_v) \ 1.122 + SPECIALIZED_PAR_OOP_ITERATE_CLOSURES(f) 1.123 +#endif // SERIALGC 1.124 + 1.125 +// This macro applies an argument macro to all OopClosures for which we 1.126 +// want specialized bodies of a family of methods related to 1.127 +// "oops_since_save_marks_do". The arguments to f are the same as above. 1.128 +// The "root_class" is the most general class to define; this may be 1.129 +// "OopClosure" in some applications and "OopsInGenClosure" in others. 1.130 + 1.131 +#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f) \ 1.132 + f(ScanClosure,_nv) \ 1.133 + f(FastScanClosure,_nv) 1.134 + 1.135 +#ifndef SERIALGC 1.136 +#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) \ 1.137 + f(ParScanWithBarrierClosure,_nv) \ 1.138 + f(ParScanWithoutBarrierClosure,_nv) 1.139 +#else // SERIALGC 1.140 +#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) 1.141 +#endif // SERIALGC 1.142 + 1.143 +#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(f) \ 1.144 + SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f) \ 1.145 + SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) 1.146 + 1.147 +#define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) \ 1.148 + SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(f) 1.149 + 1.150 +// We separate these out, because sometime the general one has 1.151 +// a different definition from the specialized ones, and sometimes it 1.152 +// doesn't. 1.153 +// NOTE: One of the valid criticisms of this 1.154 +// specialize-oop_oop_iterate-for-specific-closures idiom is that it is 1.155 +// easy to have a silent performance bug: if you fail to de-virtualize, 1.156 +// things still work, just slower. The "SpecializationStats" mode is 1.157 +// intended to at least make such a failure easy to detect. 1.158 +// *Not* using the ALL_SINCE_SAVE_MARKS_CLOSURES(f) macro defined 1.159 +// below means that *only* closures for which oop_oop_iterate specializations 1.160 +// exist above may be applied to "oops_since_save_marks". That is, 1.161 +// this form of the performance bug is caught statically. When you add 1.162 +// a definition for the general type, this property goes away. 1.163 +// Make sure you test with SpecializationStats to find such bugs 1.164 +// when introducing a new closure where you don't want virtual dispatch. 1.165 + 1.166 +#define ALL_SINCE_SAVE_MARKS_CLOSURES(f) \ 1.167 + f(OopsInGenClosure,_v) \ 1.168 + SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) 1.169 + 1.170 +// For keeping stats on effectiveness. 1.171 +#define ENABLE_SPECIALIZATION_STATS 0 1.172 + 1.173 + 1.174 +class SpecializationStats { 1.175 +public: 1.176 + enum Kind { 1.177 + ik, // instanceKlass 1.178 + irk, // instanceRefKlass 1.179 + oa, // objArrayKlass 1.180 + NUM_Kinds 1.181 + }; 1.182 + 1.183 +#if ENABLE_SPECIALIZATION_STATS 1.184 +private: 1.185 + static int _numCallsAll; 1.186 + 1.187 + static int _numCallsTotal[NUM_Kinds]; 1.188 + static int _numCalls_nv[NUM_Kinds]; 1.189 + 1.190 + static int _numDoOopCallsTotal[NUM_Kinds]; 1.191 + static int _numDoOopCalls_nv[NUM_Kinds]; 1.192 +public: 1.193 +#endif 1.194 + static void clear() PRODUCT_RETURN; 1.195 + 1.196 + static inline void record_call() PRODUCT_RETURN; 1.197 + static inline void record_iterate_call_v(Kind k) PRODUCT_RETURN; 1.198 + static inline void record_iterate_call_nv(Kind k) PRODUCT_RETURN; 1.199 + static inline void record_do_oop_call_v(Kind k) PRODUCT_RETURN; 1.200 + static inline void record_do_oop_call_nv(Kind k) PRODUCT_RETURN; 1.201 + 1.202 + static void print() PRODUCT_RETURN; 1.203 +}; 1.204 + 1.205 +#ifndef PRODUCT 1.206 +#if ENABLE_SPECIALIZATION_STATS 1.207 + 1.208 +inline void SpecializationStats::record_call() { 1.209 + _numCallsAll++;; 1.210 +} 1.211 +inline void SpecializationStats::record_iterate_call_v(Kind k) { 1.212 + _numCallsTotal[k]++; 1.213 +} 1.214 +inline void SpecializationStats::record_iterate_call_nv(Kind k) { 1.215 + _numCallsTotal[k]++; 1.216 + _numCalls_nv[k]++; 1.217 +} 1.218 + 1.219 +inline void SpecializationStats::record_do_oop_call_v(Kind k) { 1.220 + _numDoOopCallsTotal[k]++; 1.221 +} 1.222 +inline void SpecializationStats::record_do_oop_call_nv(Kind k) { 1.223 + _numDoOopCallsTotal[k]++; 1.224 + _numDoOopCalls_nv[k]++; 1.225 +} 1.226 + 1.227 +#else // !ENABLE_SPECIALIZATION_STATS 1.228 + 1.229 +inline void SpecializationStats::record_call() {} 1.230 +inline void SpecializationStats::record_iterate_call_v(Kind k) {} 1.231 +inline void SpecializationStats::record_iterate_call_nv(Kind k) {} 1.232 +inline void SpecializationStats::record_do_oop_call_v(Kind k) {} 1.233 +inline void SpecializationStats::record_do_oop_call_nv(Kind k) {} 1.234 +inline void SpecializationStats::clear() {} 1.235 +inline void SpecializationStats::print() {} 1.236 + 1.237 +#endif // ENABLE_SPECIALIZATION_STATS 1.238 +#endif // !PRODUCT