< prev index next >

src/share/vm/memory/genCollectedHeap.cpp

Print this page

        

*** 24,33 **** --- 24,34 ---- #include "precompiled.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmSymbols.hpp" + #include "code/codeCache.hpp" #include "code/icBuffer.hpp" #include "gc_implementation/shared/collectorCounters.hpp" #include "gc_implementation/shared/gcTrace.hpp" #include "gc_implementation/shared/gcTraceTime.hpp" #include "gc_implementation/shared/vmGCOperations.hpp"
*** 47,56 **** --- 48,58 ---- #include "runtime/fprofiler.hpp" #include "runtime/handles.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/vmThread.hpp" + #include "services/management.hpp" #include "services/memoryService.hpp" #include "utilities/vmError.hpp" #include "utilities/workgroup.hpp" #include "utilities/macros.hpp" #if INCLUDE_ALL_GCS
*** 61,86 **** GenCollectedHeap* GenCollectedHeap::_gch; NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;) // The set of potentially parallel tasks in root scanning. enum GCH_strong_roots_tasks { ! // We probably want to parallelize both of these internally, but for now... GCH_PS_younger_gens, // Leave this one last. GCH_PS_NumElements }; GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) : SharedHeap(policy), _gen_policy(policy), ! _gen_process_roots_tasks(new SubTasksDone(GCH_PS_NumElements)), _full_collections_completed(0) { - if (_gen_process_roots_tasks == NULL || - !_gen_process_roots_tasks->valid()) { - vm_exit_during_initialization("Failed necessary allocation."); - } assert(policy != NULL, "Sanity check"); } jint GenCollectedHeap::initialize() { CollectedHeap::pre_initialize(); --- 63,92 ---- GenCollectedHeap* GenCollectedHeap::_gch; NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;) // The set of potentially parallel tasks in root scanning. enum GCH_strong_roots_tasks { ! GCH_PS_Universe_oops_do, ! GCH_PS_JNIHandles_oops_do, ! GCH_PS_ObjectSynchronizer_oops_do, ! GCH_PS_FlatProfiler_oops_do, ! GCH_PS_Management_oops_do, ! GCH_PS_SystemDictionary_oops_do, ! GCH_PS_ClassLoaderDataGraph_oops_do, ! GCH_PS_jvmti_oops_do, ! GCH_PS_CodeCache_oops_do, GCH_PS_younger_gens, // Leave this one last. GCH_PS_NumElements }; GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) : SharedHeap(policy), _gen_policy(policy), ! _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)), _full_collections_completed(0) { assert(policy != NULL, "Sanity check"); } jint GenCollectedHeap::initialize() { CollectedHeap::pre_initialize();
*** 587,671 **** return collector_policy()->satisfy_failed_allocation(size, is_tlab); } void GenCollectedHeap::set_par_threads(uint t) { SharedHeap::set_par_threads(t); ! _gen_process_roots_tasks->set_n_threads(t); } ! void GenCollectedHeap:: ! gen_process_roots(int level, ! bool younger_gens_as_roots, ! bool activate_scope, ! SharedHeap::ScanningOption so, ! OopsInGenClosure* not_older_gens, ! OopsInGenClosure* weak_roots, ! OopsInGenClosure* older_gens, ! CLDClosure* cld_closure, CLDClosure* weak_cld_closure, ! CodeBlobClosure* code_closure) { // General roots. ! SharedHeap::process_roots(activate_scope, so, ! not_older_gens, weak_roots, ! cld_closure, weak_cld_closure, ! code_closure); ! if (younger_gens_as_roots) { ! if (!_gen_process_roots_tasks->is_task_claimed(GCH_PS_younger_gens)) { ! for (int i = 0; i < level; i++) { ! not_older_gens->set_generation(_gens[i]); ! _gens[i]->oop_iterate(not_older_gens); } ! not_older_gens->reset_generation(); } } ! // When collection is parallel, all threads get to cooperate to do ! // older-gen scanning. ! for (int i = level+1; i < _n_gens; i++) { ! older_gens->set_generation(_gens[i]); ! rem_set()->younger_refs_iterate(_gens[i], older_gens); ! older_gens->reset_generation(); } - _gen_process_roots_tasks->all_tasks_completed(); } ! void GenCollectedHeap:: ! gen_process_roots(int level, bool younger_gens_as_roots, bool activate_scope, ! SharedHeap::ScanningOption so, bool only_strong_roots, OopsInGenClosure* not_older_gens, OopsInGenClosure* older_gens, CLDClosure* cld_closure) { - const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; bool is_moving_collection = false; if (level == 0 || is_adjust_phase) { // young collections are always moving is_moving_collection = true; } MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); ! CodeBlobClosure* code_closure = &mark_code_closure; ! gen_process_roots(level, ! younger_gens_as_roots, ! activate_scope, so, ! not_older_gens, only_strong_roots ? NULL : not_older_gens, ! older_gens, ! cld_closure, only_strong_roots ? NULL : cld_closure, ! code_closure); } void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) { ! SharedHeap::process_weak_roots(root_closure); ! // "Local" "weak" refs for (int i = 0; i < _n_gens; i++) { _gens[i]->ref_processor()->weak_oops_do(root_closure); } } --- 593,760 ---- return collector_policy()->satisfy_failed_allocation(size, is_tlab); } void GenCollectedHeap::set_par_threads(uint t) { SharedHeap::set_par_threads(t); ! set_n_termination(t); } ! void GenCollectedHeap::set_n_termination(uint t) { ! _process_strong_tasks->set_n_threads(t); ! } ! ! #ifdef ASSERT ! class AssertNonScavengableClosure: public OopClosure { ! public: ! virtual void do_oop(oop* p) { ! assert(!Universe::heap()->is_in_partial_collection(*p), ! "Referent should not be scavengable."); } ! virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } ! }; ! static AssertNonScavengableClosure assert_is_non_scavengable_closure; ! #endif ! ! void GenCollectedHeap::process_roots(bool activate_scope, ! ScanningOption so, ! OopClosure* strong_roots, ! OopClosure* weak_roots, ! CLDClosure* strong_cld_closure, CLDClosure* weak_cld_closure, ! CodeBlobClosure* code_roots) { ! StrongRootsScope srs(this, activate_scope); // General roots. ! assert(_strong_roots_parity != 0, "must have called prologue code"); ! assert(code_roots != NULL, "code root closure should always be set"); ! // _n_termination for _process_strong_tasks should be set up stream ! // in a method not running in a GC worker. Otherwise the GC worker ! // could be trying to change the termination condition while the task ! // is executing in another GC worker. ! if (!_process_strong_tasks->is_task_claimed(GCH_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. ! // Don't process them if they will be processed during the ClassLoaderDataGraph phase. ! CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL; ! // 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); ! ! if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) { ! Universe::oops_do(strong_roots); } + // Global (strong) JNI handles + if (!_process_strong_tasks->is_task_claimed(GCH_PS_JNIHandles_oops_do)) { + JNIHandles::oops_do(strong_roots); } ! ! if (!_process_strong_tasks->is_task_claimed(GCH_PS_ObjectSynchronizer_oops_do)) { ! ObjectSynchronizer::oops_do(strong_roots); ! } ! if (!_process_strong_tasks->is_task_claimed(GCH_PS_FlatProfiler_oops_do)) { ! FlatProfiler::oops_do(strong_roots); ! } ! if (!_process_strong_tasks->is_task_claimed(GCH_PS_Management_oops_do)) { ! Management::oops_do(strong_roots); ! } ! if (!_process_strong_tasks->is_task_claimed(GCH_PS_jvmti_oops_do)) { ! JvmtiExport::oops_do(strong_roots); ! } ! ! if (!_process_strong_tasks->is_task_claimed(GCH_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); ! } ! } ! ! if (!_process_strong_tasks->is_task_claimed(GCH_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)); } } ! void GenCollectedHeap::gen_process_roots(int level, bool younger_gens_as_roots, bool activate_scope, ! ScanningOption so, bool only_strong_roots, OopsInGenClosure* not_older_gens, OopsInGenClosure* older_gens, CLDClosure* cld_closure) { const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; bool is_moving_collection = false; if (level == 0 || is_adjust_phase) { // young collections are always moving is_moving_collection = true; } MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); ! OopsInGenClosure* weak_roots = only_strong_roots ? NULL : not_older_gens; ! CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure; ! ! process_roots(activate_scope, so, ! not_older_gens, weak_roots, ! cld_closure, weak_cld_closure, ! &mark_code_closure); ! if (younger_gens_as_roots) { ! if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) { ! for (int i = 0; i < level; i++) { ! not_older_gens->set_generation(_gens[i]); ! _gens[i]->oop_iterate(not_older_gens); ! } ! not_older_gens->reset_generation(); ! } ! } ! // When collection is parallel, all threads get to cooperate to do ! // older-gen scanning. ! for (int i = level+1; i < _n_gens; i++) { ! older_gens->set_generation(_gens[i]); ! rem_set()->younger_refs_iterate(_gens[i], older_gens); ! older_gens->reset_generation(); ! } + _process_strong_tasks->all_tasks_completed(); } + + class AlwaysTrueClosure: public BoolObjectClosure { + public: + bool do_object_b(oop p) { return true; } + }; + static AlwaysTrueClosure always_true; + void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) { ! JNIHandles::weak_oops_do(&always_true, root_closure); for (int i = 0; i < _n_gens; i++) { _gens[i]->ref_processor()->weak_oops_do(root_closure); } }
< prev index next >