< 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 >