--- old/hotspot/src/share/vm/memory/cardTableModRefBS.hpp 2009-08-01 04:11:57.758686369 +0100 +++ new/hotspot/src/share/vm/memory/cardTableModRefBS.hpp 2009-08-01 04:11:57.679301619 +0100 @@ -2,7 +2,7 @@ #pragma ident "@(#)cardTableModRefBS.hpp 1.53 07/10/04 10:49:32 JVM" #endif /* - * Copyright 2000-2006 Sun Microsystems, Inc. All Rights Reserved. + * 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 @@ -55,10 +55,15 @@ 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, - last_card = 4, - CT_MR_BS_last_reserved = 10 + claimed_card = 2, + deferred_card = 4, + last_card = 8, + CT_MR_BS_last_reserved = 16 }; // dirty and precleaned are equivalent wrt younger_refs_iter. @@ -153,17 +158,6 @@ 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 @@ -266,17 +260,25 @@ 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. - BarrierSet::Name kind() { return BarrierSet::CardTableModRef; } bool is_a(BarrierSet::Name bsn) { - return bsn == BarrierSet::CardTableModRef || bsn == BarrierSet::ModRef; + return bsn == BarrierSet::CardTableModRef || ModRefBarrierSet::is_a(bsn); } CardTableModRefBS(MemRegion whole_heap, int max_covered_regions); // *** Barrier set functions. - inline bool write_ref_needs_barrier(oop* field, oop new_val) { + 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(); @@ -288,7 +290,7 @@ // 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); + void write_ref_field_work(void* field, oop newVal); public: bool has_write_ref_array_opt() { return true; } @@ -318,11 +320,41 @@ // *** Card-table-barrier-specific things. - inline void inline_write_ref_field(oop* field, oop newVal) { + 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 @@ -347,8 +379,9 @@ } // ModRefBS functions. - void invalidate(MemRegion mr); + 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); @@ -378,25 +411,50 @@ 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); + // 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, after - // marking those cards precleaned. - MemRegion dirty_card_range_after_preclean(MemRegion mr); + // 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. - int index_for(void* p) { + 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(); @@ -405,6 +463,7 @@ static size_t par_chunk_heapword_alignment() { return CardsPerStrideChunk * card_size_in_words; } + }; class CardTableRS;