1 /* 2 * Copyright (c) 2001, 2006, 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 // The following OopClosure types get specialized versions of 26 // "oop_oop_iterate" that invoke the closures' do_oop methods 27 // non-virtually, using a mechanism defined in this file. Extend these 28 // macros in the obvious way to add specializations for new closures. 29 30 // Forward declarations. 31 class OopClosure; 32 class OopsInGenClosure; 33 // DefNew 34 class ScanClosure; 35 class FastScanClosure; 36 class FilteringClosure; 37 // ParNew 38 class ParScanWithBarrierClosure; 39 class ParScanWithoutBarrierClosure; 40 // CMS 41 class MarkRefsIntoAndScanClosure; 42 class Par_MarkRefsIntoAndScanClosure; 43 class PushAndMarkClosure; 44 class Par_PushAndMarkClosure; 45 class PushOrMarkClosure; 46 class Par_PushOrMarkClosure; 47 class CMSKeepAliveClosure; 48 class CMSInnerParMarkAndPushClosure; 49 50 // This macro applies an argument macro to all OopClosures for which we 51 // want specialized bodies of "oop_oop_iterate". The arguments to "f" are: 52 // "f(closureType, non_virtual)" 53 // where "closureType" is the name of the particular subclass of OopClosure, 54 // and "non_virtual" will be the string "_nv" if the closure type should 55 // have its "do_oop" method invoked non-virtually, or else the 56 // string "_v". ("OopClosure" itself will be the only class in the latter 57 // category.) 58 59 // This is split into several because of a Visual C++ 6.0 compiler bug 60 // where very long macros cause the compiler to crash 61 62 // Some other heap might define further specialized closures. 63 #ifndef FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES 64 #define FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES(f) \ 65 /* None */ 66 #endif 67 68 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_S(f) \ 69 f(ScanClosure,_nv) \ 70 f(FastScanClosure,_nv) \ 71 f(FilteringClosure,_nv) 72 73 #ifndef SERIALGC 74 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) \ 75 f(ParScanWithBarrierClosure,_nv) \ 76 f(ParScanWithoutBarrierClosure,_nv) 77 #else // SERIALGC 78 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) 79 #endif // SERIALGC 80 81 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(f) \ 82 SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_S(f) \ 83 SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_P(f) 84 85 #ifndef SERIALGC 86 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f) \ 87 f(MarkRefsIntoAndScanClosure,_nv) \ 88 f(Par_MarkRefsIntoAndScanClosure,_nv) \ 89 f(PushAndMarkClosure,_nv) \ 90 f(Par_PushAndMarkClosure,_nv) \ 91 f(PushOrMarkClosure,_nv) \ 92 f(Par_PushOrMarkClosure,_nv) \ 93 f(CMSKeepAliveClosure,_nv) \ 94 f(CMSInnerParMarkAndPushClosure,_nv) \ 95 FURTHER_SPECIALIZED_OOP_OOP_ITERATE_CLOSURES(f) 96 #else // SERIALGC 97 #define SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f) 98 #endif // SERIALGC 99 100 101 // We separate these out, because sometime the general one has 102 // a different definition from the specialized ones, and sometimes it 103 // doesn't. 104 105 #define ALL_OOP_OOP_ITERATE_CLOSURES_1(f) \ 106 f(OopClosure,_v) \ 107 SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_1(f) 108 109 #define ALL_OOP_OOP_ITERATE_CLOSURES_2(f) \ 110 SPECIALIZED_OOP_OOP_ITERATE_CLOSURES_2(f) 111 112 #ifndef SERIALGC 113 // This macro applies an argument macro to all OopClosures for which we 114 // want specialized bodies of a family of methods related to 115 // "par_oop_iterate". The arguments to f are the same as above. 116 // The "root_class" is the most general class to define; this may be 117 // "OopClosure" in some applications and "OopsInGenClosure" in others. 118 119 #define SPECIALIZED_PAR_OOP_ITERATE_CLOSURES(f) \ 120 f(MarkRefsIntoAndScanClosure,_nv) \ 121 f(PushAndMarkClosure,_nv) \ 122 f(Par_MarkRefsIntoAndScanClosure,_nv) \ 123 f(Par_PushAndMarkClosure,_nv) 124 125 #define ALL_PAR_OOP_ITERATE_CLOSURES(f) \ 126 f(OopClosure,_v) \ 127 SPECIALIZED_PAR_OOP_ITERATE_CLOSURES(f) 128 #endif // SERIALGC 129 130 // This macro applies an argument macro to all OopClosures for which we 131 // want specialized bodies of a family of methods related to 132 // "oops_since_save_marks_do". The arguments to f are the same as above. 133 // The "root_class" is the most general class to define; this may be 134 // "OopClosure" in some applications and "OopsInGenClosure" in others. 135 136 137 // Some other heap might define further specialized closures. 138 #ifndef FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES 139 #define FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) \ 140 /* None */ 141 #endif 142 143 #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f) \ 144 f(ScanClosure,_nv) \ 145 f(FastScanClosure,_nv) 146 147 #ifndef SERIALGC 148 #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) \ 149 f(ParScanWithBarrierClosure,_nv) \ 150 f(ParScanWithoutBarrierClosure,_nv) \ 151 FURTHER_SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) 152 #else // SERIALGC 153 #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) 154 #endif // SERIALGC 155 156 #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(f) \ 157 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_S(f) \ 158 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG_P(f) 159 160 #define SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) \ 161 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES_YOUNG(f) 162 163 // We separate these out, because sometime the general one has 164 // a different definition from the specialized ones, and sometimes it 165 // doesn't. 166 // NOTE: One of the valid criticisms of this 167 // specialize-oop_oop_iterate-for-specific-closures idiom is that it is 168 // easy to have a silent performance bug: if you fail to de-virtualize, 169 // things still work, just slower. The "SpecializationStats" mode is 170 // intended to at least make such a failure easy to detect. 171 // *Not* using the ALL_SINCE_SAVE_MARKS_CLOSURES(f) macro defined 172 // below means that *only* closures for which oop_oop_iterate specializations 173 // exist above may be applied to "oops_since_save_marks". That is, 174 // this form of the performance bug is caught statically. When you add 175 // a definition for the general type, this property goes away. 176 // Make sure you test with SpecializationStats to find such bugs 177 // when introducing a new closure where you don't want virtual dispatch. 178 179 #define ALL_SINCE_SAVE_MARKS_CLOSURES(f) \ 180 f(OopsInGenClosure,_v) \ 181 SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(f) 182 183 // For keeping stats on effectiveness. 184 #define ENABLE_SPECIALIZATION_STATS 0 185 186 187 class SpecializationStats { 188 public: 189 enum Kind { 190 ik, // instanceKlass 191 irk, // instanceRefKlass 192 oa, // objArrayKlass 193 NUM_Kinds 194 }; 195 196 #if ENABLE_SPECIALIZATION_STATS 197 private: 198 static bool _init; 199 static bool _wrapped; 200 static jint _numCallsAll; 201 202 static jint _numCallsTotal[NUM_Kinds]; 203 static jint _numCalls_nv[NUM_Kinds]; 204 205 static jint _numDoOopCallsTotal[NUM_Kinds]; 206 static jint _numDoOopCalls_nv[NUM_Kinds]; 207 public: 208 #endif 209 static void clear() PRODUCT_RETURN; 210 211 static inline void record_call() PRODUCT_RETURN; 212 static inline void record_iterate_call_v(Kind k) PRODUCT_RETURN; 213 static inline void record_iterate_call_nv(Kind k) PRODUCT_RETURN; 214 static inline void record_do_oop_call_v(Kind k) PRODUCT_RETURN; 215 static inline void record_do_oop_call_nv(Kind k) PRODUCT_RETURN; 216 217 static void print() PRODUCT_RETURN; 218 }; 219 220 #ifndef PRODUCT 221 #if ENABLE_SPECIALIZATION_STATS 222 223 inline void SpecializationStats::record_call() { 224 Atomic::inc(&_numCallsAll); 225 } 226 inline void SpecializationStats::record_iterate_call_v(Kind k) { 227 Atomic::inc(&_numCallsTotal[k]); 228 } 229 inline void SpecializationStats::record_iterate_call_nv(Kind k) { 230 Atomic::inc(&_numCallsTotal[k]); 231 Atomic::inc(&_numCalls_nv[k]); 232 } 233 234 inline void SpecializationStats::record_do_oop_call_v(Kind k) { 235 Atomic::inc(&_numDoOopCallsTotal[k]); 236 } 237 inline void SpecializationStats::record_do_oop_call_nv(Kind k) { 238 Atomic::inc(&_numDoOopCallsTotal[k]); 239 Atomic::inc(&_numDoOopCalls_nv[k]); 240 } 241 242 #else // !ENABLE_SPECIALIZATION_STATS 243 244 inline void SpecializationStats::record_call() {} 245 inline void SpecializationStats::record_iterate_call_v(Kind k) {} 246 inline void SpecializationStats::record_iterate_call_nv(Kind k) {} 247 inline void SpecializationStats::record_do_oop_call_v(Kind k) {} 248 inline void SpecializationStats::record_do_oop_call_nv(Kind k) {} 249 inline void SpecializationStats::clear() {} 250 inline void SpecializationStats::print() {} 251 252 #endif // ENABLE_SPECIALIZATION_STATS 253 #endif // !PRODUCT