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.