8064721: The card tables only ever need two covering regions

Reviewed-by: jmasa, tschatzl, kbarrett
This commit is contained in:
Erik Helin 2014-11-18 10:36:42 +01:00
parent 2616e09389
commit f3997d8eed
17 changed files with 35 additions and 75 deletions

View file

@ -1888,7 +1888,7 @@ jint G1CollectedHeap::initialize() {
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size())); initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
// Create the gen rem set (and barrier set) for the entire reserved region. // Create the gen rem set (and barrier set) for the entire reserved region.
_rem_set = collector_policy()->create_rem_set(reserved_region(), 2); _rem_set = collector_policy()->create_rem_set(reserved_region());
set_barrier_set(rem_set()->bs()); set_barrier_set(rem_set()->bs());
if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) { if (!barrier_set()->is_a(BarrierSet::G1SATBCTLogging)) {
vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS"); vm_exit_during_initialization("G1 requires a G1SATBLoggingCardTableModRefBS");

View file

@ -32,9 +32,8 @@
#include "runtime/orderAccess.inline.hpp" #include "runtime/orderAccess.inline.hpp"
#include "runtime/thread.inline.hpp" #include "runtime/thread.inline.hpp"
G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap, G1SATBCardTableModRefBS::G1SATBCardTableModRefBS(MemRegion whole_heap) :
int max_covered_regions) : CardTableModRefBSForCTRS(whole_heap)
CardTableModRefBSForCTRS(whole_heap, max_covered_regions)
{ {
_kind = G1SATBCT; _kind = G1SATBCT;
} }
@ -132,9 +131,8 @@ void G1SATBCardTableLoggingModRefBSChangedListener::on_commit(uint start_idx, si
} }
G1SATBCardTableLoggingModRefBS:: G1SATBCardTableLoggingModRefBS::
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap, G1SATBCardTableLoggingModRefBS(MemRegion whole_heap) :
int max_covered_regions) : G1SATBCardTableModRefBS(whole_heap),
G1SATBCardTableModRefBS(whole_heap, max_covered_regions),
_dcqs(JavaThread::dirty_card_queue_set()), _dcqs(JavaThread::dirty_card_queue_set()),
_listener() _listener()
{ {

View file

@ -50,8 +50,7 @@ public:
// pre-marking object graph. // pre-marking object graph.
static void enqueue(oop pre_val); static void enqueue(oop pre_val);
G1SATBCardTableModRefBS(MemRegion whole_heap, G1SATBCardTableModRefBS(MemRegion whole_heap);
int max_covered_regions);
bool is_a(BarrierSet::Name bsn) { bool is_a(BarrierSet::Name bsn) {
return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn); return bsn == BarrierSet::G1SATBCT || CardTableModRefBS::is_a(bsn);
@ -152,8 +151,7 @@ class G1SATBCardTableLoggingModRefBS: public G1SATBCardTableModRefBS {
return ReservedSpace::allocation_align_size_up(number_of_slots); return ReservedSpace::allocation_align_size_up(number_of_slots);
} }
G1SATBCardTableLoggingModRefBS(MemRegion whole_heap, G1SATBCardTableLoggingModRefBS(MemRegion whole_heap);
int max_covered_regions);
virtual void initialize() { } virtual void initialize() { }
virtual void initialize(G1RegionToSpaceMapper* mapper); virtual void initialize(G1RegionToSpaceMapper* mapper);

View file

@ -53,8 +53,8 @@ class CardTableExtension : public CardTableModRefBS {
verify_card = CardTableModRefBS::CT_MR_BS_last_reserved + 5 verify_card = CardTableModRefBS::CT_MR_BS_last_reserved + 5
}; };
CardTableExtension(MemRegion whole_heap, int max_covered_regions) : CardTableExtension(MemRegion whole_heap) :
CardTableModRefBS(whole_heap, max_covered_regions) { } CardTableModRefBS(whole_heap) { }
// Too risky for the 4/10/02 putback // Too risky for the 4/10/02 putback
// BarrierSet::Name kind() { return BarrierSet::CardTableExtension; } // BarrierSet::Name kind() { return BarrierSet::CardTableExtension; }

View file

@ -76,7 +76,7 @@ jint ParallelScavengeHeap::initialize() {
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size())); initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
CardTableExtension* const barrier_set = new CardTableExtension(reserved_region(), 3); CardTableExtension* const barrier_set = new CardTableExtension(reserved_region());
barrier_set->initialize(); barrier_set->initialize();
_barrier_set = barrier_set; _barrier_set = barrier_set;
oopDesc::set_bs(_barrier_set); oopDesc::set_bs(_barrier_set);

View file

@ -49,7 +49,12 @@ public:
TargetUninitialized = 1 TargetUninitialized = 1
}; };
protected: protected:
int _max_covered_regions; // Some barrier sets create tables whose elements correspond to parts of
// the heap; the CardTableModRefBS is an example. Such barrier sets will
// normally reserve space for such tables, and commit parts of the table
// "covering" parts of the heap that are committed. At most one covered
// region per generation is needed.
static const int _max_covered_regions = 2;
Name _kind; Name _kind;
public: public:
@ -159,18 +164,6 @@ public:
protected: protected:
virtual void write_region_work(MemRegion mr) = 0; virtual void write_region_work(MemRegion mr) = 0;
public: public:
// Some barrier sets create tables whose elements correspond to parts of
// the heap; the CardTableModRefBS is an example. Such barrier sets will
// normally reserve space for such tables, and commit parts of the table
// "covering" parts of the heap that are committed. The constructor is
// passed the maximum number of independently committable subregions to
// be covered, and the "resize_covered_region" function allows the
// sub-parts of the heap to inform the barrier set of changes of their
// sizes.
BarrierSet(int max_covered_regions) :
_max_covered_regions(max_covered_regions) {}
// Inform the BarrierSet that the the covered heap region that starts // Inform the BarrierSet that the the covered heap region that starts
// with "base" has been changed to have the given size (possibly from 0, // with "base" has been changed to have the given size (possibly from 0,
// for initialization.) // for initialization.)

View file

@ -53,9 +53,8 @@ size_t CardTableModRefBS::compute_byte_map_size()
return align_size_up(_guard_index + 1, MAX2(_page_size, granularity)); return align_size_up(_guard_index + 1, MAX2(_page_size, granularity));
} }
CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap, CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap) :
int max_covered_regions): ModRefBarrierSet(),
ModRefBarrierSet(max_covered_regions),
_whole_heap(whole_heap), _whole_heap(whole_heap),
_guard_index(0), _guard_index(0),
_guard_region(), _guard_region(),

View file

@ -284,7 +284,7 @@ public:
return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn); return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn);
} }
CardTableModRefBS(MemRegion whole_heap, int max_covered_regions); CardTableModRefBS(MemRegion whole_heap);
~CardTableModRefBS(); ~CardTableModRefBS();
virtual void initialize(); virtual void initialize();
@ -482,9 +482,8 @@ protected:
bool card_will_be_scanned(jbyte cv); bool card_will_be_scanned(jbyte cv);
bool card_may_have_been_dirty(jbyte cv); bool card_may_have_been_dirty(jbyte cv);
public: public:
CardTableModRefBSForCTRS(MemRegion whole_heap, CardTableModRefBSForCTRS(MemRegion whole_heap) :
int max_covered_regions) : CardTableModRefBS(whole_heap) {}
CardTableModRefBS(whole_heap, max_covered_regions) {}
void set_CTRS(CardTableRS* rs) { _rs = rs; } void set_CTRS(CardTableRS* rs) { _rs = rs; }
}; };

View file

@ -38,21 +38,18 @@
#include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp" #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
#endif // INCLUDE_ALL_GCS #endif // INCLUDE_ALL_GCS
CardTableRS::CardTableRS(MemRegion whole_heap, CardTableRS::CardTableRS(MemRegion whole_heap) :
int max_covered_regions) :
GenRemSet(), GenRemSet(),
_cur_youngergen_card_val(youngergenP1_card), _cur_youngergen_card_val(youngergenP1_card)
_regions_to_iterate(max_covered_regions - 1)
{ {
#if INCLUDE_ALL_GCS #if INCLUDE_ALL_GCS
if (UseG1GC) { if (UseG1GC) {
_ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap, _ct_bs = new G1SATBCardTableLoggingModRefBS(whole_heap);
max_covered_regions);
} else { } else {
_ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions); _ct_bs = new CardTableModRefBSForCTRS(whole_heap);
} }
#else #else
_ct_bs = new CardTableModRefBSForCTRS(whole_heap, max_covered_regions); _ct_bs = new CardTableModRefBSForCTRS(whole_heap);
#endif #endif
_ct_bs->initialize(); _ct_bs->initialize();
set_bs(_ct_bs); set_bs(_ct_bs);

View file

@ -83,7 +83,8 @@ class CardTableRS: public GenRemSet {
jbyte _cur_youngergen_card_val; jbyte _cur_youngergen_card_val;
int _regions_to_iterate; // Number of generations, plus one for lingering PermGen issues in CardTableRS.
static const int _regions_to_iterate = 3;
jbyte cur_youngergen_card_val() { jbyte cur_youngergen_card_val() {
return _cur_youngergen_card_val; return _cur_youngergen_card_val;
@ -101,7 +102,7 @@ class CardTableRS: public GenRemSet {
jbyte find_unused_youngergenP_card_value(); jbyte find_unused_youngergenP_card_value();
public: public:
CardTableRS(MemRegion whole_heap, int max_covered_regions); CardTableRS(MemRegion whole_heap);
~CardTableRS(); ~CardTableRS();
// *** GenRemSet functions. // *** GenRemSet functions.

View file

@ -152,9 +152,8 @@ bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
return result; return result;
} }
GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap, GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap) {
int max_covered_regions) { return new CardTableRS(whole_heap);
return new CardTableRS(whole_heap, max_covered_regions);
} }
void CollectorPolicy::cleared_all_soft_refs() { void CollectorPolicy::cleared_all_soft_refs() {

View file

@ -152,10 +152,7 @@ class CollectorPolicy : public CHeapObj<mtGC> {
virtual BarrierSet::Name barrier_set_name() = 0; virtual BarrierSet::Name barrier_set_name() = 0;
// Create the remembered set (to cover the given reserved region, virtual GenRemSet* create_rem_set(MemRegion reserved);
// allowing breaking up into at most "max_covered_regions").
virtual GenRemSet* create_rem_set(MemRegion reserved,
int max_covered_regions);
// This method controls how a collector satisfies a request // This method controls how a collector satisfies a request
// for a block of memory. "gc_time_limit_was_exceeded" will // for a block of memory. "gc_time_limit_was_exceeded" will

View file

@ -109,13 +109,11 @@ jint GenCollectedHeap::initialize() {
char* heap_address; char* heap_address;
size_t total_reserved = 0; size_t total_reserved = 0;
int n_covered_regions = 0;
ReservedSpace heap_rs; ReservedSpace heap_rs;
size_t heap_alignment = collector_policy()->heap_alignment(); size_t heap_alignment = collector_policy()->heap_alignment();
heap_address = allocate(heap_alignment, &total_reserved, heap_address = allocate(heap_alignment, &total_reserved, &heap_rs);
&n_covered_regions, &heap_rs);
if (!heap_rs.is_reserved()) { if (!heap_rs.is_reserved()) {
vm_shutdown_during_initialization( vm_shutdown_during_initialization(
@ -125,7 +123,7 @@ jint GenCollectedHeap::initialize() {
initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size())); initialize_reserved_region((HeapWord*)heap_rs.base(), (HeapWord*)(heap_rs.base() + heap_rs.size()));
_rem_set = collector_policy()->create_rem_set(reserved_region(), n_covered_regions); _rem_set = collector_policy()->create_rem_set(reserved_region());
set_barrier_set(rem_set()->bs()); set_barrier_set(rem_set()->bs());
_gch = this; _gch = this;
@ -152,14 +150,12 @@ jint GenCollectedHeap::initialize() {
char* GenCollectedHeap::allocate(size_t alignment, char* GenCollectedHeap::allocate(size_t alignment,
size_t* _total_reserved, size_t* _total_reserved,
int* _n_covered_regions,
ReservedSpace* heap_rs){ ReservedSpace* heap_rs){
const char overflow_msg[] = "The size of the object heap + VM data exceeds " const char overflow_msg[] = "The size of the object heap + VM data exceeds "
"the maximum representable size"; "the maximum representable size";
// Now figure out the total size. // Now figure out the total size.
size_t total_reserved = 0; size_t total_reserved = 0;
int n_covered_regions = 0;
const size_t pageSize = UseLargePages ? const size_t pageSize = UseLargePages ?
os::large_page_size() : os::vm_page_size(); os::large_page_size() : os::vm_page_size();
@ -170,18 +166,12 @@ char* GenCollectedHeap::allocate(size_t alignment,
if (total_reserved < _gen_specs[i]->max_size()) { if (total_reserved < _gen_specs[i]->max_size()) {
vm_exit_during_initialization(overflow_msg); vm_exit_during_initialization(overflow_msg);
} }
n_covered_regions += _gen_specs[i]->n_covered_regions();
} }
assert(total_reserved % alignment == 0, assert(total_reserved % alignment == 0,
err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment=" err_msg("Gen size; total_reserved=" SIZE_FORMAT ", alignment="
SIZE_FORMAT, total_reserved, alignment)); SIZE_FORMAT, total_reserved, alignment));
// Needed until the cardtable is fixed to have the right number
// of covered regions.
n_covered_regions += 2;
*_total_reserved = total_reserved; *_total_reserved = total_reserved;
*_n_covered_regions = n_covered_regions;
*heap_rs = Universe::reserve_heap(total_reserved, alignment); *heap_rs = Universe::reserve_heap(total_reserved, alignment);
return heap_rs->base(); return heap_rs->base();

View file

@ -121,9 +121,7 @@ public:
// Returns JNI_OK on success // Returns JNI_OK on success
virtual jint initialize(); virtual jint initialize();
char* allocate(size_t alignment, char* allocate(size_t alignment, size_t* _total_reserved, ReservedSpace* heap_rs);
size_t* _total_reserved, int* _n_covered_regions,
ReservedSpace* heap_rs);
// Does operations required after initialization has been done. // Does operations required after initialization has been done.
void post_initialize(); void post_initialize();

View file

@ -59,10 +59,6 @@ public:
set_init_size(align_size_up(init_size(), alignment)); set_init_size(align_size_up(init_size(), alignment));
set_max_size(align_size_up(max_size(), alignment)); set_max_size(align_size_up(max_size(), alignment));
} }
// Return the number of regions contained in the generation which
// might need to be independently covered by a remembered set.
virtual int n_covered_regions() const { return 1; }
}; };
typedef GenerationSpec* GenerationSpecPtr; typedef GenerationSpec* GenerationSpecPtr;

View file

@ -95,10 +95,6 @@ public:
// The caller guarantees that "mr" contains no references. (Perhaps it's // The caller guarantees that "mr" contains no references. (Perhaps it's
// objects have been moved elsewhere.) // objects have been moved elsewhere.)
virtual void clear(MemRegion mr) = 0; virtual void clear(MemRegion mr) = 0;
// Pass along the argument to the superclass.
ModRefBarrierSet(int max_covered_regions) :
BarrierSet(max_covered_regions) {}
}; };
#endif // SHARE_VM_MEMORY_MODREFBARRIERSET_HPP #endif // SHARE_VM_MEMORY_MODREFBARRIERSET_HPP

View file

@ -473,7 +473,6 @@ typedef TwoOopHashtable<Symbol*, mtClass> SymbolTwoOopHashtable;
\ \
unchecked_nonstatic_field(ageTable, sizes, sizeof(ageTable::sizes)) \ unchecked_nonstatic_field(ageTable, sizes, sizeof(ageTable::sizes)) \
\ \
nonstatic_field(BarrierSet, _max_covered_regions, int) \
nonstatic_field(BarrierSet, _kind, BarrierSet::Name) \ nonstatic_field(BarrierSet, _kind, BarrierSet::Name) \
nonstatic_field(BlockOffsetTable, _bottom, HeapWord*) \ nonstatic_field(BlockOffsetTable, _bottom, HeapWord*) \
nonstatic_field(BlockOffsetTable, _end, HeapWord*) \ nonstatic_field(BlockOffsetTable, _end, HeapWord*) \