mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-25 09:40:10 +00:00
8189359: Move native weak oops cleaning out of ReferenceProcessor
Reviewed-by: pliden, kbarrett
This commit is contained in:
parent
250160bf99
commit
3fbc4aec64
@ -55,6 +55,7 @@
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "gc/shared/taskqueue.inline.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
@ -5224,6 +5225,11 @@ void CMSCollector::refProcessingWork() {
|
||||
pt.print_all_references();
|
||||
}
|
||||
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) t("Weak Processing", _gc_timer_cm);
|
||||
WeakProcessor::weak_oops_do(&_is_alive_closure, &cmsKeepAliveClosure, &cmsDrainMarkingStackClosure);
|
||||
}
|
||||
|
||||
// This is the point where the entire marking should have completed.
|
||||
verify_work_stacks_empty();
|
||||
|
||||
|
||||
@ -46,6 +46,7 @@
|
||||
#include "gc/shared/spaceDecorator.hpp"
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "gc/shared/taskqueue.inline.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "gc/shared/workgroup.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "logging/logStream.hpp"
|
||||
@ -999,6 +1000,8 @@ void ParNewGeneration::collect(bool full,
|
||||
_gc_tracer.report_tenuring_threshold(tenuring_threshold());
|
||||
pt.print_all_references();
|
||||
|
||||
WeakProcessor::weak_oops_do(&is_alive, &keep_alive, &evacuate_followers);
|
||||
|
||||
if (!promotion_failed()) {
|
||||
// Swap the survivor spaces.
|
||||
eden()->clear(SpaceDecorator::Mangle);
|
||||
|
||||
@ -70,6 +70,7 @@
|
||||
#include "gc/shared/preservedMarks.inline.hpp"
|
||||
#include "gc/shared/referenceProcessor.inline.hpp"
|
||||
#include "gc/shared/taskqueue.inline.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
@ -4128,17 +4129,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
void G1CollectedHeap::process_weak_jni_handles() {
|
||||
double ref_proc_start = os::elapsedTime();
|
||||
|
||||
G1STWIsAliveClosure is_alive(this);
|
||||
G1KeepAliveClosure keep_alive(this);
|
||||
JNIHandles::weak_oops_do(&is_alive, &keep_alive);
|
||||
|
||||
double ref_proc_time = os::elapsedTime() - ref_proc_start;
|
||||
g1_policy()->phase_times()->record_ref_proc_time(ref_proc_time * 1000.0);
|
||||
}
|
||||
|
||||
void G1CollectedHeap::preserve_cm_referents(G1ParScanThreadStateSet* per_thread_states) {
|
||||
// Any reference objects, in the collection set, that were 'discovered'
|
||||
// by the CM ref processor should have already been copied (either by
|
||||
@ -4369,14 +4359,23 @@ void G1CollectedHeap::post_evacuate_collection_set(EvacuationInfo& evacuation_in
|
||||
process_discovered_references(per_thread_states);
|
||||
} else {
|
||||
ref_processor_stw()->verify_no_references_recorded();
|
||||
process_weak_jni_handles();
|
||||
}
|
||||
|
||||
G1STWIsAliveClosure is_alive(this);
|
||||
G1KeepAliveClosure keep_alive(this);
|
||||
|
||||
{
|
||||
double start = os::elapsedTime();
|
||||
|
||||
WeakProcessor::weak_oops_do(&is_alive, &keep_alive);
|
||||
|
||||
double time_ms = (os::elapsedTime() - start) * 1000.0;
|
||||
g1_policy()->phase_times()->record_ref_proc_time(time_ms);
|
||||
}
|
||||
|
||||
if (G1StringDedup::is_enabled()) {
|
||||
double fixup_start = os::elapsedTime();
|
||||
|
||||
G1STWIsAliveClosure is_alive(this);
|
||||
G1KeepAliveClosure keep_alive(this);
|
||||
G1StringDedup::unlink_or_oops_do(&is_alive, &keep_alive, true, g1_policy()->phase_times());
|
||||
|
||||
double fixup_time_ms = (os::elapsedTime() - fixup_start) * 1000.0;
|
||||
|
||||
@ -303,8 +303,6 @@ private:
|
||||
|
||||
void trace_heap(GCWhen::Type when, const GCTracer* tracer);
|
||||
|
||||
void process_weak_jni_handles();
|
||||
|
||||
// These are macros so that, if the assert fires, we get the correct
|
||||
// line number, file, etc.
|
||||
|
||||
|
||||
@ -48,6 +48,7 @@
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "gc/shared/taskqueue.inline.hpp"
|
||||
#include "gc/shared/vmGCOperations.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
@ -1603,6 +1604,23 @@ void G1ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
|
||||
// Is alive closure.
|
||||
G1CMIsAliveClosure g1_is_alive(g1h);
|
||||
|
||||
// Instances of the 'Keep Alive' and 'Complete GC' closures used
|
||||
// in serial reference processing. Note these closures are also
|
||||
// used for serially processing (by the the current thread) the
|
||||
// JNI references during parallel reference processing.
|
||||
//
|
||||
// These closures do not need to synchronize with the worker
|
||||
// threads involved in parallel reference processing as these
|
||||
// instances are executed serially by the current thread (e.g.
|
||||
// reference processing is not multi-threaded and is thus
|
||||
// performed by the current thread instead of a gang worker).
|
||||
//
|
||||
// The gang tasks involved in parallel reference processing create
|
||||
// their own instances of these closures, which do their own
|
||||
// synchronization among themselves.
|
||||
G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0), true /* is_serial */);
|
||||
G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), true /* is_serial */);
|
||||
|
||||
// Inner scope to exclude the cleaning of the string and symbol
|
||||
// tables from the displayed time.
|
||||
{
|
||||
@ -1617,23 +1635,6 @@ void G1ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
|
||||
rp->setup_policy(clear_all_soft_refs);
|
||||
assert(_global_mark_stack.is_empty(), "mark stack should be empty");
|
||||
|
||||
// Instances of the 'Keep Alive' and 'Complete GC' closures used
|
||||
// in serial reference processing. Note these closures are also
|
||||
// used for serially processing (by the the current thread) the
|
||||
// JNI references during parallel reference processing.
|
||||
//
|
||||
// These closures do not need to synchronize with the worker
|
||||
// threads involved in parallel reference processing as these
|
||||
// instances are executed serially by the current thread (e.g.
|
||||
// reference processing is not multi-threaded and is thus
|
||||
// performed by the current thread instead of a gang worker).
|
||||
//
|
||||
// The gang tasks involved in parallel reference processing create
|
||||
// their own instances of these closures, which do their own
|
||||
// synchronization among themselves.
|
||||
G1CMKeepAliveAndDrainClosure g1_keep_alive(this, task(0), true /* is_serial */);
|
||||
G1CMDrainMarkingStackClosure g1_drain_mark_stack(this, task(0), true /* is_serial */);
|
||||
|
||||
// We need at least one active thread. If reference processing
|
||||
// is not multi-threaded we use the current (VMThread) thread,
|
||||
// otherwise we use the work gang from the G1CollectedHeap and
|
||||
@ -1687,6 +1688,11 @@ void G1ConcurrentMark::weakRefsWork(bool clear_all_soft_refs) {
|
||||
assert(!rp->discovery_enabled(), "Post condition");
|
||||
}
|
||||
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) debug("Weak Processing", _gc_timer_cm);
|
||||
WeakProcessor::weak_oops_do(&g1_is_alive, &g1_keep_alive, &g1_drain_mark_stack);
|
||||
}
|
||||
|
||||
if (has_overflown()) {
|
||||
// We can not trust g1_is_alive if the marking stack overflowed
|
||||
return;
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
#include "gc/shared/modRefBarrierSet.hpp"
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/space.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "oops/instanceRefKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
@ -181,6 +182,13 @@ void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
|
||||
pt.print_all_references();
|
||||
}
|
||||
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) trace("Weak Processing", gc_timer());
|
||||
WeakProcessor::weak_oops_do(&GenMarkSweep::is_alive,
|
||||
&GenMarkSweep::keep_alive,
|
||||
&GenMarkSweep::follow_stack_closure);
|
||||
}
|
||||
|
||||
// This is the point where the entire marking should have completed.
|
||||
assert(GenMarkSweep::_marking_stack.is_empty(), "Marking should have completed");
|
||||
|
||||
@ -272,7 +280,7 @@ void G1MarkSweep::mark_sweep_phase3() {
|
||||
|
||||
// Now adjust pointers in remaining weak roots. (All of which should
|
||||
// have been cleared if they pointed to non-surviving objects.)
|
||||
JNIHandles::weak_oops_do(&GenMarkSweep::adjust_pointer_closure);
|
||||
WeakProcessor::oops_do(&GenMarkSweep::adjust_pointer_closure);
|
||||
|
||||
if (G1StringDedup::is_enabled()) {
|
||||
G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure);
|
||||
|
||||
@ -47,6 +47,7 @@
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/referenceProcessor.hpp"
|
||||
#include "gc/shared/spaceDecorator.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/biasedLocking.hpp"
|
||||
@ -542,6 +543,11 @@ void PSMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
||||
pt.print_all_references();
|
||||
}
|
||||
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) t("Weak Processing", _gc_timer);
|
||||
WeakProcessor::weak_oops_do(is_alive_closure(), mark_and_push_closure(), follow_stack_closure());
|
||||
}
|
||||
|
||||
// This is the point where the entire marking should have completed.
|
||||
assert(_marking_stack.is_empty(), "Marking should have completed");
|
||||
|
||||
@ -617,7 +623,7 @@ void PSMarkSweep::mark_sweep_phase3() {
|
||||
// Now adjust pointers in remaining weak roots. (All of which should
|
||||
// have been cleared if they pointed to non-surviving objects.)
|
||||
// Global (weak) JNI handles
|
||||
JNIHandles::weak_oops_do(adjust_pointer_closure());
|
||||
WeakProcessor::oops_do(adjust_pointer_closure());
|
||||
|
||||
CodeBlobToOopClosure adjust_from_blobs(adjust_pointer_closure(), CodeBlobToOopClosure::FixRelocations);
|
||||
CodeCache::blobs_do(&adjust_from_blobs);
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/referenceProcessor.hpp"
|
||||
#include "gc/shared/spaceDecorator.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/instanceKlass.inline.hpp"
|
||||
@ -2118,6 +2119,11 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
|
||||
pt.print_all_references();
|
||||
}
|
||||
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) tm("Weak Processing", &_gc_timer);
|
||||
WeakProcessor::weak_oops_do(is_alive_closure(), &mark_and_push_closure, &follow_stack_closure);
|
||||
}
|
||||
|
||||
// This is the point where the entire marking should have completed.
|
||||
assert(cm->marking_stacks_empty(), "Marking should have completed");
|
||||
|
||||
@ -2170,8 +2176,7 @@ void PSParallelCompact::adjust_roots(ParCompactionManager* cm) {
|
||||
|
||||
// Now adjust pointers in remaining weak roots. (All of which should
|
||||
// have been cleared if they pointed to non-surviving objects.)
|
||||
// Global (weak) JNI handles
|
||||
JNIHandles::weak_oops_do(&oop_closure);
|
||||
WeakProcessor::oops_do(&oop_closure);
|
||||
|
||||
CodeBlobToOopClosure adjust_from_blobs(&oop_closure, CodeBlobToOopClosure::FixRelocations);
|
||||
CodeCache::blobs_do(&adjust_from_blobs);
|
||||
|
||||
@ -45,6 +45,7 @@
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/referenceProcessor.hpp"
|
||||
#include "gc/shared/spaceDecorator.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
@ -406,14 +407,15 @@ bool PSScavenge::invoke_no_policy() {
|
||||
|
||||
scavenge_midpoint.update();
|
||||
|
||||
PSKeepAliveClosure keep_alive(promotion_manager);
|
||||
PSEvacuateFollowersClosure evac_followers(promotion_manager);
|
||||
|
||||
// Process reference objects discovered during scavenge
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) tm("Reference Processing", &_gc_timer);
|
||||
|
||||
reference_processor()->setup_policy(false); // not always_clear
|
||||
reference_processor()->set_active_mt_degree(active_workers);
|
||||
PSKeepAliveClosure keep_alive(promotion_manager);
|
||||
PSEvacuateFollowersClosure evac_followers(promotion_manager);
|
||||
ReferenceProcessorStats stats;
|
||||
ReferenceProcessorPhaseTimes pt(&_gc_timer, reference_processor()->num_q());
|
||||
if (reference_processor()->processing_is_mt()) {
|
||||
@ -440,6 +442,11 @@ bool PSScavenge::invoke_no_policy() {
|
||||
pt.print_enqueue_phase();
|
||||
}
|
||||
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) tm("Weak Processing", &_gc_timer);
|
||||
WeakProcessor::weak_oops_do(&_is_alive_closure, &keep_alive, &evac_followers);
|
||||
}
|
||||
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) tm("Scrub String Table", &_gc_timer);
|
||||
// Unlink any dead interned Strings and process the remaining live ones.
|
||||
|
||||
@ -41,6 +41,7 @@
|
||||
#include "gc/shared/space.inline.hpp"
|
||||
#include "gc/shared/spaceDecorator.hpp"
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
@ -658,6 +659,8 @@ void DefNewGeneration::collect(bool full,
|
||||
gc_tracer.report_tenuring_threshold(tenuring_threshold());
|
||||
pt.print_all_references();
|
||||
|
||||
WeakProcessor::weak_oops_do(&is_alive, &keep_alive, &evacuate_followers);
|
||||
|
||||
if (!_promotion_failed) {
|
||||
// Swap the survivor spaces.
|
||||
eden()->clear(SpaceDecorator::Mangle);
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
#include "gc/shared/referencePolicy.hpp"
|
||||
#include "gc/shared/space.hpp"
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "oops/instanceRefKlass.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "prims/jvmtiExport.hpp"
|
||||
@ -217,6 +218,11 @@ void GenMarkSweep::mark_sweep_phase1(bool clear_all_softrefs) {
|
||||
gc_tracer()->report_gc_reference_stats(stats);
|
||||
}
|
||||
|
||||
{
|
||||
GCTraceTime(Debug, gc, phases) tm_m("Weak Processing", gc_timer());
|
||||
WeakProcessor::weak_oops_do(&is_alive, &keep_alive, &follow_stack_closure);
|
||||
}
|
||||
|
||||
// This is the point where the entire marking should have completed.
|
||||
assert(_marking_stack.is_empty(), "Marking should have completed");
|
||||
|
||||
|
||||
@ -42,6 +42,7 @@
|
||||
#include "gc/shared/space.hpp"
|
||||
#include "gc/shared/strongRootsScope.hpp"
|
||||
#include "gc/shared/vmGCOperations.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "gc/shared/workgroup.hpp"
|
||||
#include "memory/filemap.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
@ -652,7 +653,7 @@ void GenCollectedHeap::full_process_roots(StrongRootsScope* scope,
|
||||
}
|
||||
|
||||
void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) {
|
||||
JNIHandles::weak_oops_do(root_closure);
|
||||
WeakProcessor::oops_do(root_closure);
|
||||
_young_gen->ref_processor()->weak_oops_do(root_closure);
|
||||
_old_gen->ref_processor()->weak_oops_do(root_closure);
|
||||
}
|
||||
|
||||
@ -36,7 +36,6 @@
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/java.hpp"
|
||||
#include "runtime/jniHandles.hpp"
|
||||
|
||||
ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
|
||||
ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL;
|
||||
@ -245,51 +244,16 @@ ReferenceProcessorStats ReferenceProcessor::process_discovered_references(
|
||||
is_alive, keep_alive, complete_gc, task_executor, phase_times);
|
||||
}
|
||||
|
||||
// Weak global JNI references. It would make more sense (semantically) to
|
||||
// traverse these simultaneously with the regular weak references above, but
|
||||
// that is not how the JDK1.2 specification is. See #4126360. Native code can
|
||||
// thus use JNI weak references to circumvent the phantom references and
|
||||
// resurrect a "post-mortem" object.
|
||||
{
|
||||
GCTraceTime(Debug, gc, ref) tt("JNI Weak Reference", phase_times->gc_timer());
|
||||
if (task_executor != NULL) {
|
||||
task_executor->set_single_threaded_mode();
|
||||
}
|
||||
process_phaseJNI(is_alive, keep_alive, complete_gc);
|
||||
if (task_executor != NULL) {
|
||||
// Record the work done by the parallel workers.
|
||||
task_executor->set_single_threaded_mode();
|
||||
}
|
||||
|
||||
phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000);
|
||||
|
||||
log_develop_trace(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs());
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
// Calculate the number of jni handles.
|
||||
size_t ReferenceProcessor::count_jni_refs() {
|
||||
class CountHandleClosure: public OopClosure {
|
||||
private:
|
||||
size_t _count;
|
||||
public:
|
||||
CountHandleClosure(): _count(0) {}
|
||||
void do_oop(oop* unused) { _count++; }
|
||||
void do_oop(narrowOop* unused) { ShouldNotReachHere(); }
|
||||
size_t count() { return _count; }
|
||||
};
|
||||
CountHandleClosure global_handle_count;
|
||||
JNIHandles::weak_oops_do(&global_handle_count);
|
||||
return global_handle_count.count();
|
||||
}
|
||||
#endif
|
||||
|
||||
void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive,
|
||||
OopClosure* keep_alive,
|
||||
VoidClosure* complete_gc) {
|
||||
JNIHandles::weak_oops_do(is_alive, keep_alive);
|
||||
complete_gc->do_void();
|
||||
}
|
||||
|
||||
void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor,
|
||||
ReferenceProcessorPhaseTimes* phase_times) {
|
||||
// Enqueue references that are not made active again, and
|
||||
|
||||
@ -246,10 +246,6 @@ class ReferenceProcessor : public CHeapObj<mtGC> {
|
||||
AbstractRefProcTaskExecutor* task_executor,
|
||||
ReferenceProcessorPhaseTimes* phase_times);
|
||||
|
||||
void process_phaseJNI(BoolObjectClosure* is_alive,
|
||||
OopClosure* keep_alive,
|
||||
VoidClosure* complete_gc);
|
||||
|
||||
// Work methods used by the method process_discovered_reflist
|
||||
// Phase1: keep alive all those referents that are otherwise
|
||||
// dead but which must be kept alive by policy (and their closure).
|
||||
@ -341,9 +337,6 @@ class ReferenceProcessor : public CHeapObj<mtGC> {
|
||||
|
||||
void clear_discovered_references(DiscoveredList& refs_list);
|
||||
|
||||
// Calculate the number of jni handles.
|
||||
size_t count_jni_refs();
|
||||
|
||||
void log_reflist_counts(DiscoveredList ref_lists[], uint active_length, size_t total_count) PRODUCT_RETURN;
|
||||
|
||||
// Balances reference queues.
|
||||
|
||||
39
src/hotspot/share/gc/shared/weakProcessor.cpp
Normal file
39
src/hotspot/share/gc/shared/weakProcessor.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "gc/shared/weakProcessor.hpp"
|
||||
#include "runtime/jniHandles.hpp"
|
||||
|
||||
void WeakProcessor::weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete) {
|
||||
JNIHandles::weak_oops_do(is_alive, keep_alive);
|
||||
if (complete != NULL) {
|
||||
complete->do_void();
|
||||
}
|
||||
}
|
||||
|
||||
void WeakProcessor::oops_do(OopClosure* closure) {
|
||||
AlwaysTrueClosure always_true;
|
||||
JNIHandles::weak_oops_do(&always_true, closure);
|
||||
}
|
||||
49
src/hotspot/share/gc/shared/weakProcessor.hpp
Normal file
49
src/hotspot/share/gc/shared/weakProcessor.hpp
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2017, 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
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_GC_SHARED_WEAKPROCESSOR_HPP
|
||||
#define SHARE_VM_GC_SHARED_WEAKPROCESSOR_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/iterator.hpp"
|
||||
|
||||
// Helper class to aid in root scanning and cleaning of weak oops in the VM.
|
||||
//
|
||||
// New containers of weak oops added to this class will automatically
|
||||
// be cleaned by all GCs, including the young generation GCs.
|
||||
class WeakProcessor : AllStatic {
|
||||
public:
|
||||
// Visit all oop*s and apply the keep_alive closure if the referenced
|
||||
// object is considered alive by the is_alive closure, otherwise do some
|
||||
// container specific cleanup of element holding the oop.
|
||||
//
|
||||
// The complete closure is used as a post-processing step,
|
||||
// called after all container have been processed.
|
||||
static void weak_oops_do(BoolObjectClosure* is_alive, OopClosure* keep_alive, VoidClosure* complete = NULL);
|
||||
|
||||
// Visit all oop*s and apply the given closure.
|
||||
static void oops_do(OopClosure* closure);
|
||||
};
|
||||
|
||||
#endif // SHARE_VM_GC_SHARED_WEAKPROCESSOR_HPP
|
||||
Loading…
x
Reference in New Issue
Block a user