src/share/vm/memory/referenceProcessor.cpp

Print this page
rev 4773 : 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>

*** 1,7 **** /* ! * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. --- 1,7 ---- /* ! * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.
*** 23,32 **** --- 23,34 ---- */ #include "precompiled.hpp" #include "classfile/javaClasses.hpp" #include "classfile/systemDictionary.hpp" + #include "gc_implementation/shared/gcTimer.hpp" + #include "gc_implementation/shared/gcTraceTime.hpp" #include "gc_interface/collectedHeap.hpp" #include "gc_interface/collectedHeap.inline.hpp" #include "memory/referencePolicy.hpp" #include "memory/referenceProcessor.hpp" #include "oops/oop.inline.hpp"
*** 178,192 **** } // Else leave clock stalled at its old value until time progresses // past clock value. } ! void ReferenceProcessor::process_discovered_references( BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, ! AbstractRefProcTaskExecutor* task_executor) { NOT_PRODUCT(verify_ok_to_handle_reflists()); assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); // Stop treating discovered references specially. disable_discovery(); --- 180,203 ---- } // Else leave clock stalled at its old value until time progresses // past clock value. } ! size_t ReferenceProcessor::total_count(DiscoveredList lists[]) { ! size_t total = 0; ! for (uint i = 0; i < _max_num_q; ++i) { ! total += lists[i].length(); ! } ! return total; ! } ! ! ReferenceProcessorStats ReferenceProcessor::process_discovered_references( BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, ! AbstractRefProcTaskExecutor* task_executor, ! GCTimer* gc_timer) { NOT_PRODUCT(verify_ok_to_handle_reflists()); assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); // Stop treating discovered references specially. disable_discovery();
*** 200,251 **** // discovered soft refs. _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); bool trace_time = PrintGCDetails && PrintReferenceGC; // Soft references { ! TraceTime tt("SoftReference", trace_time, false, gclog_or_tty); process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, is_alive, keep_alive, complete_gc, task_executor); } update_soft_ref_master_clock(); // Weak references { ! TraceTime tt("WeakReference", trace_time, false, gclog_or_tty); process_discovered_reflist(_discoveredWeakRefs, NULL, true, is_alive, keep_alive, complete_gc, task_executor); } // Final references { ! TraceTime tt("FinalReference", trace_time, false, gclog_or_tty); process_discovered_reflist(_discoveredFinalRefs, NULL, false, is_alive, keep_alive, complete_gc, task_executor); } // Phantom references { ! TraceTime tt("PhantomReference", trace_time, false, gclog_or_tty); process_discovered_reflist(_discoveredPhantomRefs, NULL, false, is_alive, keep_alive, complete_gc, task_executor); } // Weak global JNI references. It would make more sense (semantically) to // traverse these simultaneously with the regular weak references above, but // that is not how the JDK1.2 specification is. See #4126360. Native code can // thus use JNI weak references to circumvent the phantom references and // resurrect a "post-mortem" object. { ! TraceTime tt("JNI Weak Reference", trace_time, false, gclog_or_tty); if (task_executor != NULL) { task_executor->set_single_threaded_mode(); } process_phaseJNI(is_alive, keep_alive, complete_gc); } } #ifndef PRODUCT // Calculate the number of jni handles. uint ReferenceProcessor::count_jni_refs() { --- 211,273 ---- // discovered soft refs. _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); bool trace_time = PrintGCDetails && PrintReferenceGC; + // Soft references + size_t soft_count = 0; { ! GCTraceTime tt("SoftReference", trace_time, false, gc_timer); ! soft_count = process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, is_alive, keep_alive, complete_gc, task_executor); } update_soft_ref_master_clock(); // Weak references + size_t weak_count = 0; { ! GCTraceTime tt("WeakReference", trace_time, false, gc_timer); ! weak_count = process_discovered_reflist(_discoveredWeakRefs, NULL, true, is_alive, keep_alive, complete_gc, task_executor); } // Final references + size_t final_count = 0; { ! GCTraceTime tt("FinalReference", trace_time, false, gc_timer); ! final_count = process_discovered_reflist(_discoveredFinalRefs, NULL, false, is_alive, keep_alive, complete_gc, task_executor); } // Phantom references + size_t phantom_count = 0; { ! GCTraceTime tt("PhantomReference", trace_time, false, gc_timer); ! phantom_count = process_discovered_reflist(_discoveredPhantomRefs, NULL, false, is_alive, keep_alive, complete_gc, task_executor); } // Weak global JNI references. It would make more sense (semantically) to // traverse these simultaneously with the regular weak references above, but // that is not how the JDK1.2 specification is. See #4126360. Native code can // thus use JNI weak references to circumvent the phantom references and // resurrect a "post-mortem" object. { ! GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer); if (task_executor != NULL) { task_executor->set_single_threaded_mode(); } process_phaseJNI(is_alive, keep_alive, complete_gc); } + + return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count); } #ifndef PRODUCT // Calculate the number of jni handles. uint ReferenceProcessor::count_jni_refs() {
*** 876,886 **** balance_queues(_discoveredWeakRefs); balance_queues(_discoveredFinalRefs); balance_queues(_discoveredPhantomRefs); } ! void ReferenceProcessor::process_discovered_reflist( DiscoveredList refs_lists[], ReferencePolicy* policy, bool clear_referent, BoolObjectClosure* is_alive, --- 898,908 ---- balance_queues(_discoveredWeakRefs); balance_queues(_discoveredFinalRefs); balance_queues(_discoveredPhantomRefs); } ! size_t ReferenceProcessor::process_discovered_reflist( DiscoveredList refs_lists[], ReferencePolicy* policy, bool clear_referent, BoolObjectClosure* is_alive,
*** 899,914 **** if ((mt_processing && ParallelRefProcBalancingEnabled) || must_balance) { balance_queues(refs_lists); } if (PrintReferenceGC && PrintGCDetails) { ! size_t total = 0; ! for (uint i = 0; i < _max_num_q; ++i) { ! total += refs_lists[i].length(); ! } ! gclog_or_tty->print(", %u refs", total); } // Phase 1 (soft refs only): // . Traverse the list and remove any SoftReferences whose // referents are not alive, but that should be kept alive for --- 921,935 ---- if ((mt_processing && ParallelRefProcBalancingEnabled) || must_balance) { balance_queues(refs_lists); } + + size_t total_list_count = total_count(refs_lists); + if (PrintReferenceGC && PrintGCDetails) { ! gclog_or_tty->print(", %u refs", total_list_count); } // Phase 1 (soft refs only): // . Traverse the list and remove any SoftReferences whose // referents are not alive, but that should be kept alive for
*** 949,958 **** --- 970,981 ---- for (uint i = 0; i < _max_num_q; i++) { process_phase3(refs_lists[i], clear_referent, is_alive, keep_alive, complete_gc); } } + + return total_list_count; } void ReferenceProcessor::clean_up_discovered_references() { // loop over the lists for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
*** 1264,1281 **** // in any order and, indeed, concurrently. void ReferenceProcessor::preclean_discovered_references( BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, ! YieldClosure* yield) { NOT_PRODUCT(verify_ok_to_handle_reflists()); // Soft references { ! TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, ! false, gclog_or_tty); for (uint i = 0; i < _max_num_q; i++) { if (yield->should_return()) { return; } preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, --- 1287,1305 ---- // in any order and, indeed, concurrently. void ReferenceProcessor::preclean_discovered_references( BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete_gc, ! YieldClosure* yield, ! GCTimer* gc_timer) { NOT_PRODUCT(verify_ok_to_handle_reflists()); // Soft references { ! GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, ! false, gc_timer); for (uint i = 0; i < _max_num_q; i++) { if (yield->should_return()) { return; } preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive,
*** 1283,1294 **** } } // Weak references { ! TraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, ! false, gclog_or_tty); for (uint i = 0; i < _max_num_q; i++) { if (yield->should_return()) { return; } preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, --- 1307,1318 ---- } } // Weak references { ! GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, ! false, gc_timer); for (uint i = 0; i < _max_num_q; i++) { if (yield->should_return()) { return; } preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive,
*** 1296,1307 **** } } // Final references { ! TraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, ! false, gclog_or_tty); for (uint i = 0; i < _max_num_q; i++) { if (yield->should_return()) { return; } preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, --- 1320,1331 ---- } } // Final references { ! GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, ! false, gc_timer); for (uint i = 0; i < _max_num_q; i++) { if (yield->should_return()) { return; } preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive,
*** 1309,1320 **** } } // Phantom references { ! TraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, ! false, gclog_or_tty); for (uint i = 0; i < _max_num_q; i++) { if (yield->should_return()) { return; } preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, --- 1333,1344 ---- } } // Phantom references { ! GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, ! false, gc_timer); for (uint i = 0; i < _max_num_q; i++) { if (yield->should_return()) { return; } preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive,