hotspot/src/share/vm/memory/cardTableModRefBS.hpp
Print this page
rev 611 : Merge
*** 1,10 ****
#ifdef USE_PRAGMA_IDENT_HDR
#pragma ident "@(#)cardTableModRefBS.hpp 1.53 07/10/04 10:49:32 JVM"
#endif
/*
! * Copyright 2000-2006 Sun Microsystems, Inc. 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.
--- 1,10 ----
#ifdef USE_PRAGMA_IDENT_HDR
#pragma ident "@(#)cardTableModRefBS.hpp 1.53 07/10/04 10:49:32 JVM"
#endif
/*
! * Copyright 2000-2008 Sun Microsystems, Inc. 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.
*** 53,66 ****
#endif
protected:
enum CardValues {
clean_card = -1,
dirty_card = 0,
precleaned_card = 1,
! last_card = 4,
! CT_MR_BS_last_reserved = 10
};
// dirty and precleaned are equivalent wrt younger_refs_iter.
static bool card_is_dirty_wrt_gen_iter(jbyte cv) {
return cv == dirty_card || cv == precleaned_card;
--- 53,71 ----
#endif
protected:
enum CardValues {
clean_card = -1,
+ // The mask contains zeros in places for all other values.
+ clean_card_mask = clean_card - 31,
+
dirty_card = 0,
precleaned_card = 1,
! claimed_card = 2,
! deferred_card = 4,
! last_card = 8,
! CT_MR_BS_last_reserved = 16
};
// dirty and precleaned are equivalent wrt younger_refs_iter.
static bool card_is_dirty_wrt_gen_iter(jbyte cv) {
return cv == dirty_card || cv == precleaned_card;
*** 151,171 ****
// for loops iterating through the card table.
jbyte* byte_after(const void* p) const {
return byte_for(p) + 1;
}
- // Mapping from card marking array entry to address of first word
- HeapWord* addr_for(const jbyte* p) const {
- assert(p >= _byte_map && p < _byte_map + _byte_map_size,
- "out of bounds access to card marking array");
- size_t delta = pointer_delta(p, byte_map_base, sizeof(jbyte));
- HeapWord* result = (HeapWord*) (delta << card_shift);
- assert(_whole_heap.contains(result),
- "out of bounds accessor from card marking array");
- return result;
- }
-
// Iterate over the portion of the card-table which covers the given
// region mr in the given space and apply cl to any dirty sub-regions
// of mr. cl and dcto_cl must either be the same closure or cl must
// wrap dcto_cl. Both are required - neither may be NULL. Also, dcto_cl
// may be modified. Note that this function will operate in a parallel
--- 156,165 ----
*** 264,284 ****
card_shift = 9,
card_size = 1 << card_shift,
card_size_in_words = card_size / sizeof(HeapWord)
};
// For RTTI simulation.
- BarrierSet::Name kind() { return BarrierSet::CardTableModRef; }
bool is_a(BarrierSet::Name bsn) {
! return bsn == BarrierSet::CardTableModRef || bsn == BarrierSet::ModRef;
}
CardTableModRefBS(MemRegion whole_heap, int max_covered_regions);
// *** Barrier set functions.
! inline bool write_ref_needs_barrier(oop* field, oop new_val) {
// Note that this assumes the perm gen is the highest generation
// in the address space
return new_val != NULL && !new_val->is_perm();
}
--- 258,286 ----
card_shift = 9,
card_size = 1 << card_shift,
card_size_in_words = card_size / sizeof(HeapWord)
};
+ static int clean_card_val() { return clean_card; }
+ static int clean_card_mask_val() { return clean_card_mask; }
+ static int dirty_card_val() { return dirty_card; }
+ static int claimed_card_val() { return claimed_card; }
+ static int precleaned_card_val() { return precleaned_card; }
+ static int deferred_card_val() { return deferred_card; }
+
// For RTTI simulation.
bool is_a(BarrierSet::Name bsn) {
! return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn);
}
CardTableModRefBS(MemRegion whole_heap, int max_covered_regions);
// *** Barrier set functions.
! bool has_write_ref_pre_barrier() { return false; }
!
! inline bool write_ref_needs_barrier(void* field, oop new_val) {
// Note that this assumes the perm gen is the highest generation
// in the address space
return new_val != NULL && !new_val->is_perm();
}
*** 286,296 ****
// The scanning code has to handle the fact that the write barrier may be
// either precise or imprecise. We make non-virtual inline variants of
// these functions here for performance.
protected:
void write_ref_field_work(oop obj, size_t offset, oop newVal);
! void write_ref_field_work(oop* field, oop newVal);
public:
bool has_write_ref_array_opt() { return true; }
bool has_write_region_opt() { return true; }
--- 288,298 ----
// The scanning code has to handle the fact that the write barrier may be
// either precise or imprecise. We make non-virtual inline variants of
// these functions here for performance.
protected:
void write_ref_field_work(oop obj, size_t offset, oop newVal);
! void write_ref_field_work(void* field, oop newVal);
public:
bool has_write_ref_array_opt() { return true; }
bool has_write_region_opt() { return true; }
*** 316,330 ****
return is_card_aligned(addr);
}
// *** Card-table-barrier-specific things.
! inline void inline_write_ref_field(oop* field, oop newVal) {
jbyte* byte = byte_for(field);
*byte = dirty_card;
}
// Card marking array base (adjusted for heap low boundary)
// This would be the 0th element of _byte_map, if the heap started at 0x0.
// But since the heap starts at some higher address, this points to somewhere
// before the beginning of the actual _byte_map.
jbyte* byte_map_base;
--- 318,362 ----
return is_card_aligned(addr);
}
// *** Card-table-barrier-specific things.
! inline void inline_write_ref_field_pre(void* field, oop newVal) {}
!
! inline void inline_write_ref_field(void* field, oop newVal) {
jbyte* byte = byte_for(field);
*byte = dirty_card;
}
+ // These are used by G1, when it uses the card table as a temporary data
+ // structure for card claiming.
+ bool is_card_dirty(size_t card_index) {
+ return _byte_map[card_index] == dirty_card_val();
+ }
+
+ void mark_card_dirty(size_t card_index) {
+ _byte_map[card_index] = dirty_card_val();
+ }
+
+ bool is_card_claimed(size_t card_index) {
+ jbyte val = _byte_map[card_index];
+ return (val & (clean_card_mask_val() | claimed_card_val())) == claimed_card_val();
+ }
+
+ bool claim_card(size_t card_index);
+
+ bool is_card_clean(size_t card_index) {
+ return _byte_map[card_index] == clean_card_val();
+ }
+
+ bool is_card_deferred(size_t card_index) {
+ jbyte val = _byte_map[card_index];
+ return (val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val();
+ }
+
+ bool mark_card_deferred(size_t card_index);
+
// Card marking array base (adjusted for heap low boundary)
// This would be the 0th element of _byte_map, if the heap started at 0x0.
// But since the heap starts at some higher address, this points to somewhere
// before the beginning of the actual _byte_map.
jbyte* byte_map_base;
*** 345,356 ****
PrecisionStyle precision() {
return ObjHeadPreciseArray; // Only one supported for now.
}
// ModRefBS functions.
! void invalidate(MemRegion mr);
void clear(MemRegion mr);
void mod_oop_in_space_iterate(Space* sp, OopClosure* cl,
bool clear = false,
bool before_save_marks = false);
// *** Card-table-RemSet-specific things.
--- 377,389 ----
PrecisionStyle precision() {
return ObjHeadPreciseArray; // Only one supported for now.
}
// ModRefBS functions.
! virtual void invalidate(MemRegion mr, bool whole_heap = false);
void clear(MemRegion mr);
+ void dirty(MemRegion mr);
void mod_oop_in_space_iterate(Space* sp, OopClosure* cl,
bool clear = false,
bool before_save_marks = false);
// *** Card-table-RemSet-specific things.
*** 376,412 ****
non_clean_card_iterate_work(mr, cl, clear);
}
static uintx ct_max_alignment_constraint();
! // Apply closure cl to the dirty cards lying completely
! // within MemRegion mr, setting the cards to precleaned.
void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl);
// Return the MemRegion corresponding to the first maximal run
! // of dirty cards lying completely within MemRegion mr, after
! // marking those cards precleaned.
! MemRegion dirty_card_range_after_preclean(MemRegion mr);
// Set all the dirty cards in the given region to precleaned state.
void preclean_dirty_cards(MemRegion mr);
// Mapping from address to card marking array index.
! int index_for(void* p) {
assert(_whole_heap.contains(p),
"out of bounds access to card marking array");
return byte_for(p) - _byte_map;
}
void verify();
void verify_guard();
void verify_clean_region(MemRegion mr) PRODUCT_RETURN;
static size_t par_chunk_heapword_alignment() {
return CardsPerStrideChunk * card_size_in_words;
}
};
class CardTableRS;
// A specialization for the CardTableRS gen rem set.
--- 409,471 ----
non_clean_card_iterate_work(mr, cl, clear);
}
static uintx ct_max_alignment_constraint();
! // Apply closure "cl" to the dirty cards containing some part of
! // MemRegion "mr".
void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl);
// Return the MemRegion corresponding to the first maximal run
! // of dirty cards lying completely within MemRegion mr.
! // If reset is "true", then sets those card table entries to the given
! // value.
! MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset,
! int reset_val);
// Set all the dirty cards in the given region to precleaned state.
void preclean_dirty_cards(MemRegion mr);
+ // Provide read-only access to the card table array.
+ const jbyte* byte_for_const(const void* p) const {
+ return byte_for(p);
+ }
+ const jbyte* byte_after_const(const void* p) const {
+ return byte_after(p);
+ }
+
+ // Mapping from card marking array entry to address of first word
+ HeapWord* addr_for(const jbyte* p) const {
+ assert(p >= _byte_map && p < _byte_map + _byte_map_size,
+ "out of bounds access to card marking array");
+ size_t delta = pointer_delta(p, byte_map_base, sizeof(jbyte));
+ HeapWord* result = (HeapWord*) (delta << card_shift);
+ assert(_whole_heap.contains(result),
+ "out of bounds accessor from card marking array");
+ return result;
+ }
+
// Mapping from address to card marking array index.
! size_t index_for(void* p) {
assert(_whole_heap.contains(p),
"out of bounds access to card marking array");
return byte_for(p) - _byte_map;
}
+ const jbyte* byte_for_index(const size_t card_index) const {
+ return _byte_map + card_index;
+ }
+
void verify();
void verify_guard();
void verify_clean_region(MemRegion mr) PRODUCT_RETURN;
static size_t par_chunk_heapword_alignment() {
return CardsPerStrideChunk * card_size_in_words;
}
+
};
class CardTableRS;
// A specialization for the CardTableRS gen rem set.