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,