8139434: Unify GenRemSet and CardTableRS

Reviewed-by: jwilhelm, mgerdin
This commit is contained in:
David Lindholm 2015-10-14 09:33:45 +02:00
parent ebe8b1d7f6
commit a7d89b56a8
25 changed files with 94 additions and 257 deletions

View File

@ -65,7 +65,6 @@ class SpaceClosure;
class CompactibleSpaceClosure;
class Space;
class G1CollectorPolicy;
class GenRemSet;
class G1RemSet;
class HeapRegionRemSetIterator;
class ConcurrentMark;

View File

@ -291,7 +291,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
void G1CollectorPolicy::initialize_alignments() {
_space_alignment = HeapRegion::GrainBytes;
size_t card_table_alignment = GenRemSet::max_alignment_constraint();
size_t card_table_alignment = CardTableRS::ct_max_alignment_constraint();
size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
_heap_alignment = MAX3(card_table_alignment, _space_alignment, page_size);
}

View File

@ -24,6 +24,7 @@
#include "precompiled.hpp"
#include "gc/serial/defNewGeneration.inline.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/collectorCounters.hpp"
#include "gc/shared/gcHeapSummary.hpp"
#include "gc/shared/gcLocker.inline.hpp"
@ -33,7 +34,6 @@
#include "gc/shared/gcTraceTime.hpp"
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/genRemSet.hpp"
#include "gc/shared/generationSpec.hpp"
#include "gc/shared/referencePolicy.hpp"
#include "gc/shared/space.inline.hpp"
@ -69,8 +69,7 @@ bool DefNewGeneration::IsAliveClosure::do_object_b(oop p) {
DefNewGeneration::KeepAliveClosure::
KeepAliveClosure(ScanWeakRefClosure* cl) : _cl(cl) {
GenRemSet* rs = GenCollectedHeap::heap()->rem_set();
_rs = (CardTableRS*)rs;
_rs = GenCollectedHeap::heap()->rem_set();
}
void DefNewGeneration::KeepAliveClosure::do_oop(oop* p) { DefNewGeneration::KeepAliveClosure::do_oop_work(p); }

View File

@ -115,7 +115,7 @@ void GenMarkSweep::invoke_at_safepoint(ReferenceProcessor* rp, bool clear_all_so
// can clear the card table. Otherwise, we must invalidate
// it (consider all cards dirty). In the future, we might consider doing
// compaction within generations only, and doing card-table sliding.
GenRemSet* rs = gch->rem_set();
CardTableRS* rs = gch->rem_set();
Generation* old_gen = gch->old_gen();
// Clear/invalidate below make use of the "prev_used_regions" saved earlier.

View File

@ -42,7 +42,7 @@
TenuredGeneration::TenuredGeneration(ReservedSpace rs,
size_t initial_byte_size,
GenRemSet* remset) :
CardTableRS* remset) :
CardGeneration(rs, initial_byte_size, remset)
{
HeapWord* bottom = (HeapWord*) _virtual_space.low();

View File

@ -58,7 +58,7 @@ class TenuredGeneration: public CardGeneration {
public:
TenuredGeneration(ReservedSpace rs,
size_t initial_byte_size,
GenRemSet* remset);
CardTableRS* remset);
Generation::Name kind() { return Generation::MarkSweepCompact; }

View File

@ -26,9 +26,9 @@
#include "gc/shared/blockOffsetTable.inline.hpp"
#include "gc/shared/cardGeneration.inline.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/gcLocker.hpp"
#include "gc/shared/genOopClosures.inline.hpp"
#include "gc/shared/genRemSet.hpp"
#include "gc/shared/generationSpec.hpp"
#include "gc/shared/space.inline.hpp"
#include "memory/iterator.hpp"
@ -37,7 +37,7 @@
CardGeneration::CardGeneration(ReservedSpace rs,
size_t initial_byte_size,
GenRemSet* remset) :
CardTableRS* remset) :
Generation(rs, initial_byte_size), _rs(remset),
_shrink_factor(0), _min_heap_delta_bytes(), _capacity_at_prologue(),
_used_at_prologue()

View File

@ -37,7 +37,7 @@ class CardGeneration: public Generation {
friend class VMStructs;
protected:
// This is shared with other generations.
GenRemSet* _rs;
CardTableRS* _rs;
// This is local to this generation.
BlockOffsetSharedArray* _bts;
@ -52,7 +52,7 @@ class CardGeneration: public Generation {
size_t _capacity_at_prologue;
size_t _used_at_prologue;
CardGeneration(ReservedSpace rs, size_t initial_byte_size, GenRemSet* remset);
CardGeneration(ReservedSpace rs, size_t initial_byte_size, CardTableRS* remset);
virtual void assert_correct_size_change_locking() = 0;

View File

@ -34,8 +34,48 @@
#include "runtime/os.hpp"
#include "utilities/macros.hpp"
class HasAccumulatedModifiedOopsClosure : public KlassClosure {
bool _found;
public:
HasAccumulatedModifiedOopsClosure() : _found(false) {}
void do_klass(Klass* klass) {
if (_found) {
return;
}
if (klass->has_accumulated_modified_oops()) {
_found = true;
}
}
bool found() {
return _found;
}
};
bool KlassRemSet::mod_union_is_clear() {
HasAccumulatedModifiedOopsClosure closure;
ClassLoaderDataGraph::classes_do(&closure);
return !closure.found();
}
class ClearKlassModUnionClosure : public KlassClosure {
public:
void do_klass(Klass* klass) {
if (klass->has_accumulated_modified_oops()) {
klass->clear_accumulated_modified_oops();
}
}
};
void KlassRemSet::clear_mod_union() {
ClearKlassModUnionClosure closure;
ClassLoaderDataGraph::classes_do(&closure);
}
CardTableRS::CardTableRS(MemRegion whole_heap) :
GenRemSet(),
_bs(NULL),
_cur_youngergen_card_val(youngergenP1_card)
{
_ct_bs = new CardTableModRefBSForCTRS(whole_heap);

View File

@ -26,16 +26,26 @@
#define SHARE_VM_GC_SHARED_CARDTABLERS_HPP
#include "gc/shared/cardTableModRefBSForCTRS.hpp"
#include "gc/shared/genRemSet.hpp"
#include "memory/memRegion.hpp"
class Space;
class OopsInGenClosure;
// This kind of "GenRemSet" uses a card table both as shared data structure
// Helper to remember modified oops in all klasses.
class KlassRemSet {
bool _accumulate_modified_oops;
public:
KlassRemSet() : _accumulate_modified_oops(false) {}
void set_accumulate_modified_oops(bool value) { _accumulate_modified_oops = value; }
bool accumulate_modified_oops() { return _accumulate_modified_oops; }
bool mod_union_is_clear();
void clear_mod_union();
};
// This RemSet uses a card table both as shared data structure
// for a mod ref barrier set and for the rem set information.
class CardTableRS: public GenRemSet {
class CardTableRS: public CHeapObj<mtGC> {
friend class VMStructs;
// Below are private classes used in impl.
friend class VerifyCTSpaceClosure;
@ -54,9 +64,10 @@ class CardTableRS: public GenRemSet {
return CardTableModRefBSForCTRS::card_is_dirty_wrt_gen_iter(cv);
}
CardTableModRefBSForCTRS* _ct_bs;
KlassRemSet _klass_rem_set;
BarrierSet* _bs;
virtual void younger_refs_in_space_iterate(Space* sp, OopsInGenClosure* cl, uint n_threads);
CardTableModRefBSForCTRS* _ct_bs;
void verify_space(Space* s, HeapWord* gen_start);
@ -104,11 +115,18 @@ public:
CardTableRS(MemRegion whole_heap);
~CardTableRS();
// *** GenRemSet functions.
CardTableRS* as_CardTableRS() { return this; }
// Return the barrier set associated with "this."
BarrierSet* bs() { return _bs; }
// Set the barrier set.
void set_bs(BarrierSet* bs) { _bs = bs; }
KlassRemSet* klass_rem_set() { return &_klass_rem_set; }
CardTableModRefBSForCTRS* ct_bs() { return _ct_bs; }
void younger_refs_in_space_iterate(Space* sp, OopsInGenClosure* cl, uint n_threads);
// Override.
void prepare_for_younger_refs_iterate(bool parallel);

View File

@ -152,7 +152,7 @@ bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
return result;
}
GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap) {
CardTableRS* CollectorPolicy::create_rem_set(MemRegion whole_heap) {
return new CardTableRS(whole_heap);
}
@ -173,7 +173,7 @@ size_t CollectorPolicy::compute_heap_alignment() {
// byte entry and the os page size is 4096, the maximum heap size should
// be 512*4096 = 2MB aligned.
size_t alignment = GenRemSet::max_alignment_constraint();
size_t alignment = CardTableRS::ct_max_alignment_constraint();
if (UseLargePages) {
// In presence of large pages we have to make sure that our

View File

@ -26,7 +26,7 @@
#define SHARE_VM_GC_SHARED_COLLECTORPOLICY_HPP
#include "gc/shared/barrierSet.hpp"
#include "gc/shared/genRemSet.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/generationSpec.hpp"
#include "memory/allocation.hpp"
#include "utilities/macros.hpp"
@ -143,7 +143,7 @@ class CollectorPolicy : public CHeapObj<mtGC> {
#endif // INCLUDE_ALL_GCS
virtual GenRemSet* create_rem_set(MemRegion reserved);
virtual CardTableRS* create_rem_set(MemRegion reserved);
// This method controls how a collector satisfies a request
// for a block of memory. "gc_time_limit_was_exceeded" will

View File

@ -823,7 +823,7 @@ bool GenCollectedHeap::create_cms_collector() {
assert(_gen_policy->is_concurrent_mark_sweep_policy(), "Unexpected policy type");
CMSCollector* collector =
new CMSCollector((ConcurrentMarkSweepGeneration*)_old_gen,
_rem_set->as_CardTableRS(),
_rem_set,
_gen_policy->as_concurrent_mark_sweep_policy());
if (collector == NULL || !collector->completed_initialization()) {

View File

@ -64,8 +64,8 @@ private:
Generation* _young_gen;
Generation* _old_gen;
// The singleton Gen Remembered Set.
GenRemSet* _rem_set;
// The singleton CardTable Remembered Set.
CardTableRS* _rem_set;
// The generational collector policy.
GenCollectorPolicy* _gen_policy;
@ -361,9 +361,9 @@ public:
// collection.
virtual bool is_maximal_no_gc() const;
// This function returns the "GenRemSet" object that allows us to scan
// This function returns the CardTableRS object that allows us to scan
// generations in a fully generational heap.
GenRemSet* rem_set() { return _rem_set; }
CardTableRS* rem_set() { return _rem_set; }
// Convenience function to be used in situations where the heap type can be
// asserted to be this type.

View File

@ -29,7 +29,6 @@
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genOopClosures.hpp"
#include "gc/shared/genRemSet.hpp"
#include "gc/shared/generation.hpp"
#include "gc/shared/space.hpp"
@ -43,8 +42,7 @@ inline void OopsInGenClosure::set_generation(Generation* gen) {
_gen_boundary = _gen->reserved().start();
// Barrier set for the heap, must be set after heap is initialized
if (_rs == NULL) {
GenRemSet* rs = GenCollectedHeap::heap()->rem_set();
_rs = (CardTableRS*)rs;
_rs = GenCollectedHeap::heap()->rem_set();
}
}

View File

@ -1,77 +0,0 @@
/*
* Copyright (c) 2001, 2015, 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 "classfile/classLoaderData.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/genRemSet.hpp"
#include "oops/klass.hpp"
// This kind of "BarrierSet" allows a "CollectedHeap" to detect and
// enumerate ref fields that have been modified (since the last
// enumeration.)
uintx GenRemSet::max_alignment_constraint() {
return CardTableRS::ct_max_alignment_constraint();
}
class HasAccumulatedModifiedOopsClosure : public KlassClosure {
bool _found;
public:
HasAccumulatedModifiedOopsClosure() : _found(false) {}
void do_klass(Klass* klass) {
if (_found) {
return;
}
if (klass->has_accumulated_modified_oops()) {
_found = true;
}
}
bool found() {
return _found;
}
};
bool KlassRemSet::mod_union_is_clear() {
HasAccumulatedModifiedOopsClosure closure;
ClassLoaderDataGraph::classes_do(&closure);
return !closure.found();
}
class ClearKlassModUnionClosure : public KlassClosure {
public:
void do_klass(Klass* klass) {
if (klass->has_accumulated_modified_oops()) {
klass->clear_accumulated_modified_oops();
}
}
};
void KlassRemSet::clear_mod_union() {
ClearKlassModUnionClosure closure;
ClassLoaderDataGraph::classes_do(&closure);
}

View File

@ -1,133 +0,0 @@
/*
* Copyright (c) 2001, 2015, 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_GENREMSET_HPP
#define SHARE_VM_GC_SHARED_GENREMSET_HPP
#include "oops/oop.hpp"
// A GenRemSet provides ways of iterating over pointers across generations.
// (This is especially useful for older-to-younger.)
class Generation;
class BarrierSet;
class OopsInGenClosure;
class CardTableRS;
// Helper to remember modified oops in all klasses.
class KlassRemSet {
bool _accumulate_modified_oops;
public:
KlassRemSet() : _accumulate_modified_oops(false) {}
void set_accumulate_modified_oops(bool value) { _accumulate_modified_oops = value; }
bool accumulate_modified_oops() { return _accumulate_modified_oops; }
bool mod_union_is_clear();
void clear_mod_union();
};
class GenRemSet: public CHeapObj<mtGC> {
friend class Generation;
BarrierSet* _bs;
KlassRemSet _klass_rem_set;
public:
GenRemSet(BarrierSet * bs) : _bs(bs) {}
GenRemSet() : _bs(NULL) {}
// These are for dynamic downcasts. Unfortunately that it names the
// possible subtypes (but not that they are subtypes!) Return NULL if
// the cast is invalid.
virtual CardTableRS* as_CardTableRS() { return NULL; }
// Return the barrier set associated with "this."
BarrierSet* bs() { return _bs; }
// Set the barrier set.
void set_bs(BarrierSet* bs) { _bs = bs; }
KlassRemSet* klass_rem_set() { return &_klass_rem_set; }
// Do any (sequential) processing necessary to prepare for (possibly
// "parallel", if that arg is true) calls to younger_refs_iterate.
virtual void prepare_for_younger_refs_iterate(bool parallel) = 0;
// Apply the "do_oop" method of "blk" to (exactly) all oop locations
// 1) that are in objects allocated in "g" at the time of the last call
// to "save_Marks", and
// 2) that point to objects in younger generations.
virtual void younger_refs_iterate(Generation* g, OopsInGenClosure* blk, uint n_threads) = 0;
virtual void younger_refs_in_space_iterate(Space* sp,
OopsInGenClosure* cl,
uint n_threads) = 0;
// This method is used to notify the remembered set that "new_val" has
// been written into "field" by the garbage collector.
void write_ref_field_gc(void* field, oop new_val);
protected:
virtual void write_ref_field_gc_work(void* field, oop new_val) = 0;
public:
// A version of the above suitable for use by parallel collectors.
virtual void write_ref_field_gc_par(void* field, oop new_val) = 0;
// Resize one of the regions covered by the remembered set.
virtual void resize_covered_region(MemRegion new_region) = 0;
// If the rem set imposes any alignment restrictions on boundaries
// within the heap, this function tells whether they are met.
virtual bool is_aligned(HeapWord* addr) = 0;
// Returns any alignment constraint that the remembered set imposes upon the
// heap.
static uintx max_alignment_constraint();
virtual void verify() = 0;
// If appropriate, print some information about the remset on "tty".
virtual void print() {}
// Informs the RS that the given memregion contains no references to
// the young generation.
virtual void clear(MemRegion mr) = 0;
// Informs the RS that there are no references to the young generation
// from old_gen.
virtual void clear_into_younger(Generation* old_gen) = 0;
// Informs the RS that refs in the given "mr" may have changed
// arbitrarily, and therefore may contain old-to-young pointers.
// If "whole heap" is true, then this invalidation is part of an
// invalidation of the whole heap, which an implementation might
// handle differently than that of a sub-part of the heap.
virtual void invalidate(MemRegion mr, bool whole_heap = false) = 0;
// Informs the RS that refs in this generation
// may have changed arbitrarily, and therefore may contain
// old-to-young pointers in arbitrary locations.
virtual void invalidate_or_clear(Generation* old_gen) = 0;
};
#endif // SHARE_VM_GC_SHARED_GENREMSET_HPP

View File

@ -293,7 +293,7 @@ void Generation::oop_iterate(ExtendedOopClosure* cl) {
void Generation::younger_refs_in_space_iterate(Space* sp,
OopsInGenClosure* cl,
uint n_threads) {
GenRemSet* rs = GenCollectedHeap::heap()->rem_set();
CardTableRS* rs = GenCollectedHeap::heap()->rem_set();
rs->younger_refs_in_space_iterate(sp, cl, n_threads);
}

View File

@ -66,7 +66,6 @@ class OopClosure;
class ScanClosure;
class FastScanClosure;
class GenCollectedHeap;
class GenRemSet;
class GCStats;
// A "ScratchBlock" represents a block of memory in one generation usable by

View File

@ -25,7 +25,7 @@
#include "precompiled.hpp"
#include "gc/serial/defNewGeneration.hpp"
#include "gc/serial/tenuredGeneration.hpp"
#include "gc/shared/genRemSet.hpp"
#include "gc/shared/cardTableRS.hpp"
#include "gc/shared/generationSpec.hpp"
#include "memory/binaryTreeDictionary.hpp"
#include "memory/filemap.hpp"
@ -36,7 +36,7 @@
#include "gc/cms/parNewGeneration.hpp"
#endif // INCLUDE_ALL_GCS
Generation* GenerationSpec::init(ReservedSpace rs, GenRemSet* remset) {
Generation* GenerationSpec::init(ReservedSpace rs, CardTableRS* remset) {
switch (name()) {
case Generation::DefNew:
return new DefNewGeneration(rs, init_size());
@ -50,8 +50,7 @@ Generation* GenerationSpec::init(ReservedSpace rs, GenRemSet* remset) {
case Generation::ConcurrentMarkSweep: {
assert(UseConcMarkSweepGC, "UseConcMarkSweepGC should be set");
CardTableRS* ctrs = remset->as_CardTableRS();
if (ctrs == NULL) {
if (remset == NULL) {
vm_exit_during_initialization("Rem set incompatibility.");
}
// Otherwise
@ -60,7 +59,7 @@ Generation* GenerationSpec::init(ReservedSpace rs, GenRemSet* remset) {
ConcurrentMarkSweepGeneration* g = NULL;
g = new ConcurrentMarkSweepGeneration(rs,
init_size(), ctrs, UseCMSAdaptiveFreeLists,
init_size(), remset, UseCMSAdaptiveFreeLists,
(FreeBlockDictionary<FreeChunk>::DictionaryChoice)CMSDictionaryChoice);
g->initialize_performance_counters();

View File

@ -45,7 +45,7 @@ public:
_max_size(align_size_up(max_size, alignment))
{ }
Generation* init(ReservedSpace rs, GenRemSet* remset);
Generation* init(ReservedSpace rs, CardTableRS* remset);
// Accessors
Generation::Name name() const { return _name; }

View File

@ -47,7 +47,6 @@ class BlockOffsetArrayContigSpace;
class Generation;
class CompactibleSpace;
class BlockOffsetTable;
class GenRemSet;
class CardTableRS;
class DirtyCardToOopClosure;

View File

@ -35,7 +35,6 @@
#include "gc/shared/collectedHeap.inline.hpp"
#include "gc/shared/gcLocker.inline.hpp"
#include "gc/shared/genCollectedHeap.hpp"
#include "gc/shared/genRemSet.hpp"
#include "gc/shared/generation.hpp"
#include "gc/shared/space.hpp"
#include "interpreter/interpreter.hpp"

View File

@ -101,7 +101,6 @@
# include "gc/shared/gcStats.hpp"
# include "gc/shared/gcUtil.hpp"
# include "gc/shared/genCollectedHeap.hpp"
# include "gc/shared/genRemSet.hpp"
# include "gc/shared/generation.hpp"
# include "gc/shared/generationCounters.hpp"
# include "gc/shared/modRefBarrierSet.hpp"

View File

@ -502,7 +502,7 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
\
nonstatic_field(BlockOffsetArrayNonContigSpace, _unallocated_block, HeapWord*) \
\
nonstatic_field(CardGeneration, _rs, GenRemSet*) \
nonstatic_field(CardGeneration, _rs, CardTableRS*) \
nonstatic_field(CardGeneration, _bts, BlockOffsetSharedArray*) \
nonstatic_field(CardGeneration, _shrink_factor, size_t) \
nonstatic_field(CardGeneration, _capacity_at_prologue, size_t) \
@ -1524,8 +1524,7 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
declare_type(CardTableModRefBS, ModRefBarrierSet) \
declare_type(CardTableModRefBSForCTRS, CardTableModRefBS) \
declare_toplevel_type(BarrierSet::Name) \
declare_toplevel_type(GenRemSet) \
declare_type(CardTableRS, GenRemSet) \
declare_toplevel_type(CardTableRS) \
declare_toplevel_type(BlockOffsetSharedArray) \
declare_toplevel_type(BlockOffsetTable) \
declare_type(BlockOffsetArray, BlockOffsetTable) \
@ -1548,7 +1547,6 @@ typedef CompactHashtable<Symbol*, char> SymbolCompactHashTable;
\
declare_toplevel_type(BarrierSet*) \
declare_toplevel_type(BlockOffsetSharedArray*) \
declare_toplevel_type(GenRemSet*) \
declare_toplevel_type(CardTableRS*) \
declare_toplevel_type(CardTableModRefBS*) \
declare_toplevel_type(CardTableModRefBS**) \