--- old/src/share/vm/memory/sharedHeap.cpp 2015-02-18 13:24:52.916887220 +0100 +++ new/src/share/vm/memory/sharedHeap.cpp 2015-02-18 13:24:52.848885203 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2015, 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 @@ -38,23 +38,27 @@ PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC -SharedHeap* SharedHeap::_sh; - -// The set of potentially parallel tasks in root scanning. -enum SH_process_roots_tasks { - SH_PS_Universe_oops_do, - SH_PS_JNIHandles_oops_do, - SH_PS_ObjectSynchronizer_oops_do, - SH_PS_FlatProfiler_oops_do, - SH_PS_Management_oops_do, - SH_PS_SystemDictionary_oops_do, - SH_PS_ClassLoaderDataGraph_oops_do, - SH_PS_jvmti_oops_do, - SH_PS_CodeCache_oops_do, - // Leave this one last. - SH_PS_NumElements +static const char* ext_roots_task_strings[SharedHeap::SH_PS_NumElements] = { + "Thread Roots (ms)", + "StringTable Roots (ms)", + "Universe Roots (ms)", + "JNI Handles Roots (ms)", + "ObjectSynchronizer Roots (ms)", + "FlatProfiler Roots (ms)", + "Management Roots (ms)", + "SystemDictionary Roots (ms)", + "CLDG Roots (ms)", + "JVMTI Roots (ms)", + "CodeCache Roots (ms)" }; +const char* SharedHeap::ext_roots_task_str(uint task) { + vmassert(task < ARRAY_SIZE(ext_roots_task_strings), "must be"); + return ext_roots_task_strings[task]; +} + +SharedHeap* SharedHeap::_sh; + SharedHeap::SharedHeap(CollectorPolicy* policy_) : CollectedHeap(), _collector_policy(policy_), @@ -185,7 +189,8 @@ OopClosure* weak_roots, CLDClosure* strong_cld_closure, CLDClosure* weak_cld_closure, - CodeBlobClosure* code_roots) { + CodeBlobClosure* code_roots, + PhaseTimeData* phase_durations) { StrongRootsScope srs(this, activate_scope); // General roots. @@ -200,8 +205,11 @@ // first process the strong CLDs and nmethods and then, after a barrier, // let the thread process the weak CLDs and nmethods. - if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) { - ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure); + { + TrackPhaseTime x(phase_durations, SH_PS_ClassLoaderDataGraph_oops_do); + if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) { + ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure); + } } // Some CLDs contained in the thread frames should be considered strong. @@ -210,60 +218,89 @@ // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; - Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); + { + TrackPhaseTime x(phase_durations, SH_PS_Threads_oops_do); + Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); + } // This is the point where this worker thread will not find more strong CLDs/nmethods. // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing. active_strong_roots_scope()->mark_worker_done_with_threads(n_par_threads()); - if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) { - Universe::oops_do(strong_roots); + { + TrackPhaseTime x(phase_durations, SH_PS_Universe_oops_do); + if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) { + Universe::oops_do(strong_roots); + } } - // Global (strong) JNI handles - if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do)) - JNIHandles::oops_do(strong_roots); - - if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do)) - ObjectSynchronizer::oops_do(strong_roots); - if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do)) - FlatProfiler::oops_do(strong_roots); - if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do)) - Management::oops_do(strong_roots); - if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do)) - JvmtiExport::oops_do(strong_roots); - - if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) { - SystemDictionary::roots_oops_do(strong_roots, weak_roots); - } - - // All threads execute the following. A specific chunk of buckets - // from the StringTable are the individual tasks. - if (weak_roots != NULL) { - if (CollectedHeap::use_parallel_gc_threads()) { - StringTable::possibly_parallel_oops_do(weak_roots); - } else { - StringTable::oops_do(weak_roots); + { + TrackPhaseTime x(phase_durations, SH_PS_JNIHandles_oops_do); + // Global (strong) JNI handles + if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do)) + JNIHandles::oops_do(strong_roots); + } + + { + TrackPhaseTime x(phase_durations, SH_PS_ObjectSynchronizer_oops_do); + if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do)) + ObjectSynchronizer::oops_do(strong_roots); + } + { + TrackPhaseTime x(phase_durations, SH_PS_FlatProfiler_oops_do); + if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do)) + FlatProfiler::oops_do(strong_roots); + } + { + TrackPhaseTime x(phase_durations, SH_PS_Management_oops_do); + if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do)) + Management::oops_do(strong_roots); + } + { + TrackPhaseTime x(phase_durations, SH_PS_jvmti_oops_do); + if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do)) + JvmtiExport::oops_do(strong_roots); + } + { + TrackPhaseTime x(phase_durations, SH_PS_SystemDictionary_oops_do); + if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) { + SystemDictionary::roots_oops_do(strong_roots, weak_roots); } } - if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) { - if (so & SO_ScavengeCodeCache) { - assert(code_roots != NULL, "must supply closure for code cache"); - - // We only visit parts of the CodeCache when scavenging. - CodeCache::scavenge_root_nmethods_do(code_roots); + { + TrackPhaseTime x(phase_durations, SH_PS_StringTable_oops_do); + // All threads execute the following. A specific chunk of buckets + // from the StringTable are the individual tasks. + if (weak_roots != NULL) { + if (CollectedHeap::use_parallel_gc_threads()) { + StringTable::possibly_parallel_oops_do(weak_roots); + } else { + StringTable::oops_do(weak_roots); + } } - if (so & SO_AllCodeCache) { - assert(code_roots != NULL, "must supply closure for code cache"); + } - // CMSCollector uses this to do intermediate-strength collections. - // We scan the entire code cache, since CodeCache::do_unloading is not called. - CodeCache::blobs_do(code_roots); + { + TrackPhaseTime x(phase_durations, SH_PS_CodeCache_oops_do); + if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) { + if (so & SO_ScavengeCodeCache) { + assert(code_roots != NULL, "must supply closure for code cache"); + + // We only visit parts of the CodeCache when scavenging. + CodeCache::scavenge_root_nmethods_do(code_roots); + } + if (so & SO_AllCodeCache) { + assert(code_roots != NULL, "must supply closure for code cache"); + + // CMSCollector uses this to do intermediate-strength collections. + // We scan the entire code cache, since CodeCache::do_unloading is not called. + CodeCache::blobs_do(code_roots); + } + // Verify that the code cache contents are not subject to + // movement by a scavenging collection. + DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations)); + DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); } - // Verify that the code cache contents are not subject to - // movement by a scavenging collection. - DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations)); - DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); } _process_strong_tasks->all_tasks_completed(); @@ -273,22 +310,26 @@ ScanningOption so, OopClosure* roots, CLDClosure* cld_closure, - CodeBlobClosure* code_closure) { + CodeBlobClosure* code_closure, + PhaseTimeData* phase_durations) { process_roots(activate_scope, so, roots, roots, cld_closure, cld_closure, - code_closure); + code_closure, + phase_durations); } void SharedHeap::process_strong_roots(bool activate_scope, ScanningOption so, OopClosure* roots, CLDClosure* cld_closure, - CodeBlobClosure* code_closure) { + CodeBlobClosure* code_closure, + PhaseTimeData* phase_durations) { process_roots(activate_scope, so, roots, NULL, cld_closure, NULL, - code_closure); + code_closure, + phase_durations); }