8165949: Serial and ConcMarkSweep do not unload strings when class unloading is disabled
Reviewed-by: mgerdin, tschatzl, stefank
--- a/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Wed Oct 21 15:18:30 2015 +0200
+++ b/hotspot/src/share/vm/gc/cms/concurrentMarkSweepGeneration.cpp Wed Oct 05 13:35:57 2016 +0200
@@ -2340,7 +2340,7 @@
{
StrongRootsScope srs(1);
- gch->old_process_roots(&srs,
+ gch->cms_process_roots(&srs,
true, // young gen as roots
GenCollectedHeap::ScanningOption(roots_scanning_options()),
should_unload_classes(),
@@ -2412,7 +2412,7 @@
{
StrongRootsScope srs(1);
- gch->old_process_roots(&srs,
+ gch->cms_process_roots(&srs,
true, // young gen as roots
GenCollectedHeap::ScanningOption(roots_scanning_options()),
should_unload_classes(),
@@ -2899,7 +2899,7 @@
StrongRootsScope srs(1);
- gch->old_process_roots(&srs,
+ gch->cms_process_roots(&srs,
true, // young gen as roots
GenCollectedHeap::ScanningOption(roots_scanning_options()),
should_unload_classes(),
@@ -4284,7 +4284,7 @@
CLDToOopClosure cld_closure(&par_mri_cl, true);
- gch->old_process_roots(_strong_roots_scope,
+ gch->cms_process_roots(_strong_roots_scope,
false, // yg was scanned above
GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
_collector->should_unload_classes(),
@@ -4413,7 +4413,7 @@
// ---------- remaining roots --------------
_timer.reset();
_timer.start();
- gch->old_process_roots(_strong_roots_scope,
+ gch->cms_process_roots(_strong_roots_scope,
false, // yg was scanned above
GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()),
_collector->should_unload_classes(),
@@ -4960,7 +4960,7 @@
gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel.
StrongRootsScope srs(1);
- gch->old_process_roots(&srs,
+ gch->cms_process_roots(&srs,
true, // young gen as roots
GenCollectedHeap::ScanningOption(roots_scanning_options()),
should_unload_classes(),
--- a/hotspot/src/share/vm/gc/serial/genMarkSweep.cpp Wed Oct 21 15:18:30 2015 +0200
+++ b/hotspot/src/share/vm/gc/serial/genMarkSweep.cpp Wed Oct 05 13:35:57 2016 +0200
@@ -196,12 +196,13 @@
{
StrongRootsScope srs(1);
- gch->old_process_roots(&srs,
- false, // Younger gens are not roots.
- GenCollectedHeap::SO_None,
- ClassUnloading,
- &follow_root_closure,
- &follow_cld_closure);
+ gch->full_process_roots(&srs,
+ false, // not the adjust phase
+ GenCollectedHeap::SO_None,
+ ClassUnloading, // only strong roots if ClassUnloading
+ // is enabled
+ &follow_root_closure,
+ &follow_cld_closure);
}
// Process reference objects found during marking
@@ -293,12 +294,12 @@
{
StrongRootsScope srs(1);
- gch->old_process_roots(&srs,
- false, // Younger gens are not roots.
- GenCollectedHeap::SO_AllCodeCache,
- false,
- &adjust_pointer_closure,
- &adjust_cld_closure);
+ gch->full_process_roots(&srs,
+ true, // this is the adjust phase
+ GenCollectedHeap::SO_AllCodeCache,
+ false, // all roots
+ &adjust_pointer_closure,
+ &adjust_cld_closure);
}
gch->gen_process_weak_roots(&adjust_pointer_closure);
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Wed Oct 21 15:18:30 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.cpp Wed Oct 05 13:35:57 2016 +0200
@@ -613,16 +613,6 @@
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 (is_par) {
- 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");
@@ -644,6 +634,18 @@
}
}
+void GenCollectedHeap::process_string_table_roots(StrongRootsScope* scope,
+ OopClosure* root_closure) {
+ assert(root_closure != NULL, "Must be set");
+ // All threads execute the following. A specific chunk of buckets
+ // from the StringTable are the individual tasks.
+ if (scope->n_threads() > 1) {
+ StringTable::possibly_parallel_oops_do(root_closure);
+ } else {
+ StringTable::oops_do(root_closure);
+ }
+}
+
void GenCollectedHeap::young_process_roots(StrongRootsScope* scope,
OopsInGenClosure* root_closure,
OopsInGenClosure* old_gen_closure,
@@ -652,6 +654,7 @@
process_roots(scope, SO_ScavengeCodeCache, root_closure, root_closure,
cld_closure, cld_closure, &mark_code_closure);
+ process_string_table_roots(scope, root_closure);
if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
root_closure->reset_generation();
@@ -666,19 +669,20 @@
_process_strong_tasks->all_tasks_completed(scope->n_threads());
}
-void GenCollectedHeap::old_process_roots(StrongRootsScope* scope,
+void GenCollectedHeap::cms_process_roots(StrongRootsScope* scope,
bool young_gen_as_roots,
ScanningOption so,
bool only_strong_roots,
OopsInGenClosure* root_closure,
CLDClosure* cld_closure) {
- const bool is_moving_collection = !only_strong_roots && !young_gen_as_roots;
-
- MarkingCodeBlobClosure mark_code_closure(root_closure, is_moving_collection);
+ MarkingCodeBlobClosure mark_code_closure(root_closure, !CodeBlobToOopClosure::FixRelocations);
OopsInGenClosure* weak_roots = only_strong_roots ? NULL : root_closure;
CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
process_roots(scope, so, root_closure, weak_roots, cld_closure, weak_cld_closure, &mark_code_closure);
+ if (!only_strong_roots) {
+ process_string_table_roots(scope, root_closure);
+ }
if (young_gen_as_roots &&
!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) {
@@ -690,6 +694,27 @@
_process_strong_tasks->all_tasks_completed(scope->n_threads());
}
+void GenCollectedHeap::full_process_roots(StrongRootsScope* scope,
+ bool is_adjust_phase,
+ ScanningOption so,
+ bool only_strong_roots,
+ OopsInGenClosure* root_closure,
+ CLDClosure* cld_closure) {
+ MarkingCodeBlobClosure mark_code_closure(root_closure, is_adjust_phase);
+ OopsInGenClosure* weak_roots = only_strong_roots ? NULL : root_closure;
+ CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure;
+
+ process_roots(scope, so, root_closure, weak_roots, cld_closure, weak_cld_closure, &mark_code_closure);
+ if (is_adjust_phase) {
+ // We never treat the string table as roots during marking
+ // for the full gc, so we only need to process it during
+ // the adjust phase.
+ process_string_table_roots(scope, root_closure);
+ }
+
+ _process_strong_tasks->all_tasks_completed(scope->n_threads());
+}
+
void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) {
JNIHandles::weak_oops_do(root_closure);
_young_gen->ref_processor()->weak_oops_do(root_closure);
--- a/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Wed Oct 21 15:18:30 2015 +0200
+++ b/hotspot/src/share/vm/gc/shared/genCollectedHeap.hpp Wed Oct 05 13:35:57 2016 +0200
@@ -392,6 +392,9 @@
CLDClosure* weak_cld_closure,
CodeBlobToOopClosure* code_roots);
+ void process_string_table_roots(StrongRootsScope* scope,
+ OopClosure* root_closure);
+
public:
void young_process_roots(StrongRootsScope* scope,
OopsInGenClosure* root_closure,
@@ -403,13 +406,20 @@
// scan the younger generations itself. (For example, a generation might
// explicitly mark reachable objects in younger generations, to avoid
// excess storage retention.)
- void old_process_roots(StrongRootsScope* scope,
+ void cms_process_roots(StrongRootsScope* scope,
bool young_gen_as_roots,
ScanningOption so,
bool only_strong_roots,
OopsInGenClosure* root_closure,
CLDClosure* cld_closure);
+ void full_process_roots(StrongRootsScope* scope,
+ bool is_adjust_phase,
+ ScanningOption so,
+ bool only_strong_roots,
+ OopsInGenClosure* root_closure,
+ CLDClosure* cld_closure);
+
// Apply "root_closure" to all the weak roots of the system.
// These include JNI weak roots, string table,
// and referents of reachable weak refs.