8202813: Move vm_weak processing from SystemDictionary to WeakProcessor

SystemDictionary has all strong roots.  The weak oop_storage is processed by the WeakProcessor so it can be scanned and cleared concurrently and/or by parallel threads.

Reviewed-by: kbarrett, sjohanss
This commit is contained in:
Coleen Phillimore 2018-05-29 15:50:27 -04:00
parent 92b31787a2
commit e3a3941c9a
16 changed files with 22 additions and 64 deletions

@ -1817,22 +1817,11 @@ void SystemDictionary::add_to_hierarchy(InstanceKlass* k, TRAPS) {
// ----------------------------------------------------------------------------
// GC support
void SystemDictionary::always_strong_oops_do(OopClosure* blk) {
roots_oops_do(blk, NULL);
}
// Assumes classes in the SystemDictionary are only unloaded at a safepoint
// Note: anonymous classes are not in the SD.
bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive,
GCTimer* gc_timer,
bool SystemDictionary::do_unloading(GCTimer* gc_timer,
bool do_cleaning) {
{
GCTraceTime(Debug, gc, phases) t("SystemDictionary WeakHandle cleaning", gc_timer);
vm_weak_oop_storage()->weak_oops_do(is_alive, &do_nothing_cl);
}
bool unloading_occurred;
{
GCTraceTime(Debug, gc, phases) t("ClassLoaderData", gc_timer);
@ -1863,27 +1852,6 @@ bool SystemDictionary::do_unloading(BoolObjectClosure* is_alive,
return unloading_occurred;
}
void SystemDictionary::roots_oops_do(OopClosure* strong, OopClosure* weak) {
strong->do_oop(&_java_system_loader);
strong->do_oop(&_java_platform_loader);
strong->do_oop(&_system_loader_lock_obj);
CDS_ONLY(SystemDictionaryShared::roots_oops_do(strong);)
// Do strong roots marking if the closures are the same.
if (strong == weak || !ClassUnloading) {
// Only the protection domain oops contain references into the heap. Iterate
// over all of them.
vm_weak_oop_storage()->oops_do(strong);
} else {
if (weak != NULL) {
vm_weak_oop_storage()->oops_do(weak);
}
}
// Visit extra methods
invoke_method_table()->oops_do(strong);
}
void SystemDictionary::oops_do(OopClosure* f) {
f->do_oop(&_java_system_loader);
f->do_oop(&_java_platform_loader);
@ -1892,8 +1860,6 @@ void SystemDictionary::oops_do(OopClosure* f) {
// Visit extra methods
invoke_method_table()->oops_do(f);
vm_weak_oop_storage()->oops_do(f);
}
// CDS: scan and relocate all classes in the system dictionary.

@ -357,14 +357,9 @@ public:
// Garbage collection support
// This method applies "blk->do_oop" to all the pointers to "system"
// classes and loaders.
static void always_strong_oops_do(OopClosure* blk);
// Unload (that is, break root links to) all unmarked classes and
// loaders. Returns "true" iff something was unloaded.
static bool do_unloading(BoolObjectClosure* is_alive,
GCTimer* gc_timer,
static bool do_unloading(GCTimer* gc_timer,
bool do_cleaning = true);
// Used by DumpSharedSpaces only to remove classes that failed verification
@ -374,7 +369,6 @@ public:
// Applies "f->do_oop" to all root oops in the system dictionary.
static void oops_do(OopClosure* f);
static void roots_oops_do(OopClosure* strong, OopClosure* weak);
// System loader lock
static oop system_loader_lock() { return _system_loader_lock_obj; }

@ -1,5 +1,5 @@
/*
* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2017, 2018, 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
@ -222,10 +222,9 @@ void CMSHeap::cms_process_roots(StrongRootsScope* scope,
OopsInGenClosure* root_closure,
CLDClosure* cld_closure) {
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);
process_roots(scope, so, root_closure, cld_closure, weak_cld_closure, &mark_code_closure);
if (!only_strong_roots) {
process_string_table_roots(scope, root_closure);
}

@ -5201,7 +5201,7 @@ void CMSCollector::refProcessingWork() {
GCTraceTime(Debug, gc, phases) t("Class Unloading", _gc_timer_cm);
// Unload classes and purge the SystemDictionary.
bool purged_class = SystemDictionary::do_unloading(&_is_alive_closure, _gc_timer_cm);
bool purged_class = SystemDictionary::do_unloading(_gc_timer_cm);
// Unload nmethods.
CodeCache::do_unloading(&_is_alive_closure, purged_class);

@ -1665,7 +1665,7 @@ void G1ConcurrentMark::weak_refs_work(bool clear_all_soft_refs) {
// Unload Klasses, String, Symbols, Code Cache, etc.
if (ClassUnloadingWithConcurrentMark) {
GCTraceTime(Debug, gc, phases) debug("Class Unloading", _gc_timer_cm);
bool purged_classes = SystemDictionary::do_unloading(&g1_is_alive, _gc_timer_cm, false /* Defer cleaning */);
bool purged_classes = SystemDictionary::do_unloading(_gc_timer_cm, false /* Defer cleaning */);
_g1h->complete_cleaning(&g1_is_alive, purged_classes);
} else {
GCTraceTime(Debug, gc, phases) debug("Cleanup", _gc_timer_cm);

@ -222,7 +222,7 @@ void G1FullCollector::phase1_mark_live_objects() {
if (ClassUnloading) {
GCTraceTime(Debug, gc, phases) debug("Phase 1: Class Unloading and Cleanup", scope()->timer());
// Unload classes and purge the SystemDictionary.
bool purged_class = SystemDictionary::do_unloading(&_is_alive, scope()->timer());
bool purged_class = SystemDictionary::do_unloading(scope()->timer());
_heap->complete_cleaning(&_is_alive, purged_class);
} else {
GCTraceTime(Debug, gc, phases) debug("Phase 1: String and Symbol Tables Cleanup", scope()->timer());

@ -241,7 +241,6 @@ void G1RootProcessor::process_vm_roots(G1RootClosures* closures,
G1GCPhaseTimes* phase_times,
uint worker_i) {
OopClosure* strong_roots = closures->strong_oops();
OopClosure* weak_roots = closures->weak_oops();
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::UniverseRoots, worker_i);
@ -290,7 +289,7 @@ void G1RootProcessor::process_vm_roots(G1RootClosures* closures,
{
G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SystemDictionaryRoots, worker_i);
if (!_process_strong_tasks.is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) {
SystemDictionary::roots_oops_do(strong_roots, weak_roots);
SystemDictionary::oops_do(strong_roots);
}
}
}

@ -104,7 +104,7 @@ void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
break;
case system_dictionary:
SystemDictionary::always_strong_oops_do(&mark_and_push_closure);
SystemDictionary::oops_do(&mark_and_push_closure);
break;
case class_loader_data:

@ -521,7 +521,7 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
ObjectSynchronizer::oops_do(mark_and_push_closure());
Management::oops_do(mark_and_push_closure());
JvmtiExport::oops_do(mark_and_push_closure());
SystemDictionary::always_strong_oops_do(mark_and_push_closure());
SystemDictionary::oops_do(mark_and_push_closure());
ClassLoaderDataGraph::always_strong_cld_do(follow_cld_closure());
// Do not treat nmethods as strong roots for mark/sweep, since we can unload them.
//CodeCache::scavenge_root_nmethods_do(CodeBlobToOopClosure(mark_and_push_closure()));
@ -556,7 +556,7 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
GCTraceTime(Debug, gc, phases) t("Class Unloading", _gc_timer);
// Unload classes and purge the SystemDictionary.
bool purged_class = SystemDictionary::do_unloading(is_alive_closure(), _gc_timer);
bool purged_class = SystemDictionary::do_unloading(_gc_timer);
// Unload nmethods.
CodeCache::do_unloading(is_alive_closure(), purged_class);

@ -2139,7 +2139,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", &_gc_timer);
// Follow system dictionary roots and unload classes.
bool purged_class = SystemDictionary::do_unloading(is_alive_closure(), &_gc_timer);
bool purged_class = SystemDictionary::do_unloading(&_gc_timer);
// Unload nmethods.
CodeCache::do_unloading(is_alive_closure(), purged_class);

@ -228,7 +228,7 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
GCTraceTime(Debug, gc, phases) tm_m("Class Unloading", gc_timer());
// Unload classes and purge the SystemDictionary.
bool purged_class = SystemDictionary::do_unloading(&is_alive, gc_timer());
bool purged_class = SystemDictionary::do_unloading(gc_timer());
// Unload nmethods.
CodeCache::do_unloading(&is_alive, purged_class);

@ -783,7 +783,6 @@ static AssertNonScavengableClosure assert_is_non_scavengable_closure;
void GenCollectedHeap::process_roots(StrongRootsScope* scope,
ScanningOption so,
OopClosure* strong_roots,
OopClosure* weak_roots,
CLDClosure* strong_cld_closure,
CLDClosure* weak_cld_closure,
CodeBlobToOopClosure* code_roots) {
@ -827,7 +826,7 @@ void GenCollectedHeap::process_roots(StrongRootsScope* scope,
}
if (!_process_strong_tasks->is_task_claimed(GCH_PS_SystemDictionary_oops_do)) {
SystemDictionary::roots_oops_do(strong_roots, weak_roots);
SystemDictionary::oops_do(strong_roots);
}
if (!_process_strong_tasks->is_task_claimed(GCH_PS_CodeCache_oops_do)) {
@ -869,7 +868,7 @@ void GenCollectedHeap::young_process_roots(StrongRootsScope* scope,
CLDClosure* cld_closure) {
MarkingCodeBlobClosure mark_code_closure(root_closure, CodeBlobToOopClosure::FixRelocations);
process_roots(scope, SO_ScavengeCodeCache, root_closure, root_closure,
process_roots(scope, SO_ScavengeCodeCache, root_closure,
cld_closure, cld_closure, &mark_code_closure);
process_string_table_roots(scope, root_closure);
@ -893,10 +892,9 @@ void GenCollectedHeap::full_process_roots(StrongRootsScope* scope,
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);
process_roots(scope, so, root_closure, 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

@ -396,7 +396,6 @@ public:
void process_roots(StrongRootsScope* scope,
ScanningOption so,
OopClosure* strong_roots,
OopClosure* weak_roots,
CLDClosure* strong_cld_closure,
CLDClosure* weak_cld_closure,
CodeBlobToOopClosure* code_roots);

@ -23,6 +23,8 @@
*/
#include "precompiled.hpp"
#include "classfile/systemDictionary.hpp"
#include "gc/shared/oopStorage.inline.hpp"
#include "gc/shared/weakProcessor.hpp"
#include "prims/jvmtiExport.hpp"
#include "runtime/jniHandles.hpp"
@ -34,6 +36,7 @@
void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive) {
JNIHandles::weak_oops_do(is_alive, keep_alive);
JvmtiExport::weak_oops_do(is_alive, keep_alive);
SystemDictionary::vm_weak_oop_storage()->weak_oops_do(is_alive, keep_alive);
JFR_ONLY(Jfr::weak_oops_do(is_alive, keep_alive);)
}

@ -100,7 +100,7 @@ void RootSetClosure::process_roots(OopClosure* closure) {
Universe::oops_do(closure);
JNIHandles::oops_do(closure);
JvmtiExport::oops_do(closure);
SystemDictionary::always_strong_oops_do(closure);
SystemDictionary::oops_do(closure);
Management::oops_do(closure);
StringTable::oops_do(closure);
AOTLoader::oops_do(closure);

@ -2577,7 +2577,7 @@ class SimpleRootsClosure : public OopClosure {
jvmtiHeapReferenceKind kind = root_kind();
if (kind == JVMTI_HEAP_REFERENCE_SYSTEM_CLASS) {
// SystemDictionary::always_strong_oops_do reports the application
// SystemDictionary::oops_do reports the application
// class loader as a root. We want this root to be reported as
// a root kind of "OTHER" rather than "SYSTEM_CLASS".
if (!o->is_instance() || !InstanceKlass::cast(o->klass())->is_mirror_instance_klass()) {
@ -3003,7 +3003,7 @@ inline bool VM_HeapWalkOperation::collect_simple_roots() {
// Preloaded classes and loader from the system dictionary
blk.set_kind(JVMTI_HEAP_REFERENCE_SYSTEM_CLASS);
SystemDictionary::always_strong_oops_do(&blk);
SystemDictionary::oops_do(&blk);
ClassLoaderDataGraph::always_strong_oops_do(&blk, false);
if (blk.stopped()) {
return false;