Mercurial > hg > graal-compiler
comparison src/share/vm/memory/referenceProcessor.cpp @ 10405:f2110083203d
8005849: JEP 167: Event-Based JVM Tracing
Reviewed-by: acorn, coleenp, sla
Contributed-by: Karen Kinnear <karen.kinnear@oracle.com>, Bengt Rutisson <bengt.rutisson@oracle.com>, Calvin Cheung <calvin.cheung@oracle.com>, Erik Gahlin <erik.gahlin@oracle.com>, Erik Helin <erik.helin@oracle.com>, Jesper Wilhelmsson <jesper.wilhelmsson@oracle.com>, Keith McGuigan <keith.mcguigan@oracle.com>, Mattias Tobiasson <mattias.tobiasson@oracle.com>, Markus Gronlund <markus.gronlund@oracle.com>, Mikael Auno <mikael.auno@oracle.com>, Nils Eliasson <nils.eliasson@oracle.com>, Nils Loodin <nils.loodin@oracle.com>, Rickard Backman <rickard.backman@oracle.com>, Staffan Larsen <staffan.larsen@oracle.com>, Stefan Karlsson <stefan.karlsson@oracle.com>, Yekaterina Kantserova <yekaterina.kantserova@oracle.com>
author | sla |
---|---|
date | Mon, 10 Jun 2013 11:30:51 +0200 |
parents | 001ec9515f84 |
children | 836a62f43af9 190899198332 |
comparison
equal
deleted
inserted
replaced
10404:d0add7016434 | 10405:f2110083203d |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | 4 * |
5 * This code is free software; you can redistribute it and/or modify it | 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 | 6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
23 */ | 23 */ |
24 | 24 |
25 #include "precompiled.hpp" | 25 #include "precompiled.hpp" |
26 #include "classfile/javaClasses.hpp" | 26 #include "classfile/javaClasses.hpp" |
27 #include "classfile/systemDictionary.hpp" | 27 #include "classfile/systemDictionary.hpp" |
28 #include "gc_implementation/shared/gcTimer.hpp" | |
29 #include "gc_implementation/shared/gcTraceTime.hpp" | |
28 #include "gc_interface/collectedHeap.hpp" | 30 #include "gc_interface/collectedHeap.hpp" |
29 #include "gc_interface/collectedHeap.inline.hpp" | 31 #include "gc_interface/collectedHeap.inline.hpp" |
30 #include "memory/referencePolicy.hpp" | 32 #include "memory/referencePolicy.hpp" |
31 #include "memory/referenceProcessor.hpp" | 33 #include "memory/referenceProcessor.hpp" |
32 #include "oops/oop.inline.hpp" | 34 #include "oops/oop.inline.hpp" |
178 } | 180 } |
179 // Else leave clock stalled at its old value until time progresses | 181 // Else leave clock stalled at its old value until time progresses |
180 // past clock value. | 182 // past clock value. |
181 } | 183 } |
182 | 184 |
183 void ReferenceProcessor::process_discovered_references( | 185 size_t ReferenceProcessor::total_count(DiscoveredList lists[]) { |
186 size_t total = 0; | |
187 for (uint i = 0; i < _max_num_q; ++i) { | |
188 total += lists[i].length(); | |
189 } | |
190 return total; | |
191 } | |
192 | |
193 ReferenceProcessorStats ReferenceProcessor::process_discovered_references( | |
184 BoolObjectClosure* is_alive, | 194 BoolObjectClosure* is_alive, |
185 OopClosure* keep_alive, | 195 OopClosure* keep_alive, |
186 VoidClosure* complete_gc, | 196 VoidClosure* complete_gc, |
187 AbstractRefProcTaskExecutor* task_executor) { | 197 AbstractRefProcTaskExecutor* task_executor, |
198 GCTimer* gc_timer) { | |
188 NOT_PRODUCT(verify_ok_to_handle_reflists()); | 199 NOT_PRODUCT(verify_ok_to_handle_reflists()); |
189 | 200 |
190 assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); | 201 assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); |
191 // Stop treating discovered references specially. | 202 // Stop treating discovered references specially. |
192 disable_discovery(); | 203 disable_discovery(); |
200 // discovered soft refs. | 211 // discovered soft refs. |
201 | 212 |
202 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); | 213 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); |
203 | 214 |
204 bool trace_time = PrintGCDetails && PrintReferenceGC; | 215 bool trace_time = PrintGCDetails && PrintReferenceGC; |
216 | |
205 // Soft references | 217 // Soft references |
218 size_t soft_count = 0; | |
206 { | 219 { |
207 TraceTime tt("SoftReference", trace_time, false, gclog_or_tty); | 220 GCTraceTime tt("SoftReference", trace_time, false, gc_timer); |
208 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, | 221 soft_count = |
209 is_alive, keep_alive, complete_gc, task_executor); | 222 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, |
223 is_alive, keep_alive, complete_gc, task_executor); | |
210 } | 224 } |
211 | 225 |
212 update_soft_ref_master_clock(); | 226 update_soft_ref_master_clock(); |
213 | 227 |
214 // Weak references | 228 // Weak references |
229 size_t weak_count = 0; | |
215 { | 230 { |
216 TraceTime tt("WeakReference", trace_time, false, gclog_or_tty); | 231 GCTraceTime tt("WeakReference", trace_time, false, gc_timer); |
217 process_discovered_reflist(_discoveredWeakRefs, NULL, true, | 232 weak_count = |
218 is_alive, keep_alive, complete_gc, task_executor); | 233 process_discovered_reflist(_discoveredWeakRefs, NULL, true, |
234 is_alive, keep_alive, complete_gc, task_executor); | |
219 } | 235 } |
220 | 236 |
221 // Final references | 237 // Final references |
238 size_t final_count = 0; | |
222 { | 239 { |
223 TraceTime tt("FinalReference", trace_time, false, gclog_or_tty); | 240 GCTraceTime tt("FinalReference", trace_time, false, gc_timer); |
224 process_discovered_reflist(_discoveredFinalRefs, NULL, false, | 241 final_count = |
225 is_alive, keep_alive, complete_gc, task_executor); | 242 process_discovered_reflist(_discoveredFinalRefs, NULL, false, |
243 is_alive, keep_alive, complete_gc, task_executor); | |
226 } | 244 } |
227 | 245 |
228 // Phantom references | 246 // Phantom references |
247 size_t phantom_count = 0; | |
229 { | 248 { |
230 TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty); | 249 GCTraceTime tt("PhantomReference", trace_time, false, gc_timer); |
231 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, | 250 phantom_count = |
232 is_alive, keep_alive, complete_gc, task_executor); | 251 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, |
252 is_alive, keep_alive, complete_gc, task_executor); | |
233 } | 253 } |
234 | 254 |
235 // Weak global JNI references. It would make more sense (semantically) to | 255 // Weak global JNI references. It would make more sense (semantically) to |
236 // traverse these simultaneously with the regular weak references above, but | 256 // traverse these simultaneously with the regular weak references above, but |
237 // that is not how the JDK1.2 specification is. See #4126360. Native code can | 257 // that is not how the JDK1.2 specification is. See #4126360. Native code can |
238 // thus use JNI weak references to circumvent the phantom references and | 258 // thus use JNI weak references to circumvent the phantom references and |
239 // resurrect a "post-mortem" object. | 259 // resurrect a "post-mortem" object. |
240 { | 260 { |
241 TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty); | 261 GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer); |
242 if (task_executor != NULL) { | 262 if (task_executor != NULL) { |
243 task_executor->set_single_threaded_mode(); | 263 task_executor->set_single_threaded_mode(); |
244 } | 264 } |
245 process_phaseJNI(is_alive, keep_alive, complete_gc); | 265 process_phaseJNI(is_alive, keep_alive, complete_gc); |
246 } | 266 } |
267 | |
268 return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count); | |
247 } | 269 } |
248 | 270 |
249 #ifndef PRODUCT | 271 #ifndef PRODUCT |
250 // Calculate the number of jni handles. | 272 // Calculate the number of jni handles. |
251 uint ReferenceProcessor::count_jni_refs() { | 273 uint ReferenceProcessor::count_jni_refs() { |
876 balance_queues(_discoveredWeakRefs); | 898 balance_queues(_discoveredWeakRefs); |
877 balance_queues(_discoveredFinalRefs); | 899 balance_queues(_discoveredFinalRefs); |
878 balance_queues(_discoveredPhantomRefs); | 900 balance_queues(_discoveredPhantomRefs); |
879 } | 901 } |
880 | 902 |
881 void | 903 size_t |
882 ReferenceProcessor::process_discovered_reflist( | 904 ReferenceProcessor::process_discovered_reflist( |
883 DiscoveredList refs_lists[], | 905 DiscoveredList refs_lists[], |
884 ReferencePolicy* policy, | 906 ReferencePolicy* policy, |
885 bool clear_referent, | 907 bool clear_referent, |
886 BoolObjectClosure* is_alive, | 908 BoolObjectClosure* is_alive, |
899 | 921 |
900 if ((mt_processing && ParallelRefProcBalancingEnabled) || | 922 if ((mt_processing && ParallelRefProcBalancingEnabled) || |
901 must_balance) { | 923 must_balance) { |
902 balance_queues(refs_lists); | 924 balance_queues(refs_lists); |
903 } | 925 } |
926 | |
927 size_t total_list_count = total_count(refs_lists); | |
928 | |
904 if (PrintReferenceGC && PrintGCDetails) { | 929 if (PrintReferenceGC && PrintGCDetails) { |
905 size_t total = 0; | 930 gclog_or_tty->print(", %u refs", total_list_count); |
906 for (uint i = 0; i < _max_num_q; ++i) { | |
907 total += refs_lists[i].length(); | |
908 } | |
909 gclog_or_tty->print(", %u refs", total); | |
910 } | 931 } |
911 | 932 |
912 // Phase 1 (soft refs only): | 933 // Phase 1 (soft refs only): |
913 // . Traverse the list and remove any SoftReferences whose | 934 // . Traverse the list and remove any SoftReferences whose |
914 // referents are not alive, but that should be kept alive for | 935 // referents are not alive, but that should be kept alive for |
949 for (uint i = 0; i < _max_num_q; i++) { | 970 for (uint i = 0; i < _max_num_q; i++) { |
950 process_phase3(refs_lists[i], clear_referent, | 971 process_phase3(refs_lists[i], clear_referent, |
951 is_alive, keep_alive, complete_gc); | 972 is_alive, keep_alive, complete_gc); |
952 } | 973 } |
953 } | 974 } |
975 | |
976 return total_list_count; | |
954 } | 977 } |
955 | 978 |
956 void ReferenceProcessor::clean_up_discovered_references() { | 979 void ReferenceProcessor::clean_up_discovered_references() { |
957 // loop over the lists | 980 // loop over the lists |
958 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) { | 981 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) { |
1264 // in any order and, indeed, concurrently. | 1287 // in any order and, indeed, concurrently. |
1265 void ReferenceProcessor::preclean_discovered_references( | 1288 void ReferenceProcessor::preclean_discovered_references( |
1266 BoolObjectClosure* is_alive, | 1289 BoolObjectClosure* is_alive, |
1267 OopClosure* keep_alive, | 1290 OopClosure* keep_alive, |
1268 VoidClosure* complete_gc, | 1291 VoidClosure* complete_gc, |
1269 YieldClosure* yield) { | 1292 YieldClosure* yield, |
1293 GCTimer* gc_timer) { | |
1270 | 1294 |
1271 NOT_PRODUCT(verify_ok_to_handle_reflists()); | 1295 NOT_PRODUCT(verify_ok_to_handle_reflists()); |
1272 | 1296 |
1273 // Soft references | 1297 // Soft references |
1274 { | 1298 { |
1275 TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, | 1299 GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, |
1276 false, gclog_or_tty); | 1300 false, gc_timer); |
1277 for (uint i = 0; i < _max_num_q; i++) { | 1301 for (uint i = 0; i < _max_num_q; i++) { |
1278 if (yield->should_return()) { | 1302 if (yield->should_return()) { |
1279 return; | 1303 return; |
1280 } | 1304 } |
1281 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, | 1305 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, |
1283 } | 1307 } |
1284 } | 1308 } |
1285 | 1309 |
1286 // Weak references | 1310 // Weak references |
1287 { | 1311 { |
1288 TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, | 1312 GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, |
1289 false, gclog_or_tty); | 1313 false, gc_timer); |
1290 for (uint i = 0; i < _max_num_q; i++) { | 1314 for (uint i = 0; i < _max_num_q; i++) { |
1291 if (yield->should_return()) { | 1315 if (yield->should_return()) { |
1292 return; | 1316 return; |
1293 } | 1317 } |
1294 preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, | 1318 preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, |
1296 } | 1320 } |
1297 } | 1321 } |
1298 | 1322 |
1299 // Final references | 1323 // Final references |
1300 { | 1324 { |
1301 TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, | 1325 GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, |
1302 false, gclog_or_tty); | 1326 false, gc_timer); |
1303 for (uint i = 0; i < _max_num_q; i++) { | 1327 for (uint i = 0; i < _max_num_q; i++) { |
1304 if (yield->should_return()) { | 1328 if (yield->should_return()) { |
1305 return; | 1329 return; |
1306 } | 1330 } |
1307 preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, | 1331 preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, |
1309 } | 1333 } |
1310 } | 1334 } |
1311 | 1335 |
1312 // Phantom references | 1336 // Phantom references |
1313 { | 1337 { |
1314 TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, | 1338 GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, |
1315 false, gclog_or_tty); | 1339 false, gc_timer); |
1316 for (uint i = 0; i < _max_num_q; i++) { | 1340 for (uint i = 0; i < _max_num_q; i++) { |
1317 if (yield->should_return()) { | 1341 if (yield->should_return()) { |
1318 return; | 1342 return; |
1319 } | 1343 } |
1320 preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, | 1344 preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, |