cardTableModRefBS.hpp revision 13249:a2753984d2c1
156893Sfenner/* 256893Sfenner * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. 356893Sfenner * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 456893Sfenner * 556893Sfenner * This code is free software; you can redistribute it and/or modify it 656893Sfenner * under the terms of the GNU General Public License version 2 only, as 756893Sfenner * published by the Free Software Foundation. 856893Sfenner * 956893Sfenner * This code is distributed in the hope that it will be useful, but WITHOUT 1056893Sfenner * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1156893Sfenner * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1256893Sfenner * version 2 for more details (a copy is included in the LICENSE file that 1356893Sfenner * accompanied this code). 1456893Sfenner * 1556893Sfenner * You should have received a copy of the GNU General Public License version 1656893Sfenner * 2 along with this work; if not, write to the Free Software Foundation, 1756893Sfenner * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1856893Sfenner * 1956893Sfenner * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2056893Sfenner * or visit www.oracle.com if you need additional information or have any 2156893Sfenner * questions. 2256893Sfenner * 2356893Sfenner */ 2456893Sfenner 2556893Sfenner#ifndef SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP 2656893Sfenner#define SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP 2756893Sfenner 2856893Sfenner#include "gc/shared/modRefBarrierSet.hpp" 2956893Sfenner#include "oops/oop.hpp" 3056893Sfenner#include "utilities/align.hpp" 3156893Sfenner 3256893Sfenner// This kind of "BarrierSet" allows a "CollectedHeap" to detect and 3356893Sfenner// enumerate ref fields that have been modified (since the last 3456893Sfenner// enumeration.) 3556893Sfenner 3656893Sfenner// As it currently stands, this barrier is *imprecise*: when a ref field in 3756893Sfenner// an object "o" is modified, the card table entry for the card containing 3856893Sfenner// the head of "o" is dirtied, not necessarily the card containing the 3956893Sfenner// modified field itself. For object arrays, however, the barrier *is* 4056893Sfenner// precise; only the card containing the modified element is dirtied. 4156893Sfenner// Closures used to scan dirty cards should take these 4256893Sfenner// considerations into account. 4356893Sfenner 4456893Sfennerclass CardTableModRefBS: public ModRefBarrierSet { 4556893Sfenner // Some classes get to look at some private stuff. 4656893Sfenner friend class VMStructs; 4756893Sfenner protected: 4856893Sfenner 4956893Sfenner enum CardValues { 5056893Sfenner clean_card = -1, 5156893Sfenner // The mask contains zeros in places for all other values. 5256893Sfenner clean_card_mask = clean_card - 31, 5356893Sfenner 5456893Sfenner dirty_card = 0, 5556893Sfenner precleaned_card = 1, 5656893Sfenner claimed_card = 2, 5756893Sfenner deferred_card = 4, 5856893Sfenner last_card = 8, 5956893Sfenner CT_MR_BS_last_reserved = 16 6056893Sfenner }; 6156893Sfenner 6256893Sfenner // a word's worth (row) of clean card values 6356893Sfenner static const intptr_t clean_card_row = (intptr_t)(-1); 6456893Sfenner 6556893Sfenner // The declaration order of these const fields is important; see the 6656893Sfenner // constructor before changing. 6756893Sfenner const MemRegion _whole_heap; // the region covered by the card table 6856893Sfenner size_t _guard_index; // index of very last element in the card 6956893Sfenner // table; it is set to a guard value 7056893Sfenner // (last_card) and should never be modified 7156893Sfenner size_t _last_valid_index; // index of the last valid element 7256893Sfenner const size_t _page_size; // page size used when mapping _byte_map 7356893Sfenner size_t _byte_map_size; // in bytes 7456893Sfenner jbyte* _byte_map; // the card marking array 7556893Sfenner 7656893Sfenner int _cur_covered_regions; 7756893Sfenner // The covered regions should be in address order. 7856893Sfenner MemRegion* _covered; 7956893Sfenner // The committed regions correspond one-to-one to the covered regions. 8056893Sfenner // They represent the card-table memory that has been committed to service 8156893Sfenner // the corresponding covered region. It may be that committed region for 8256893Sfenner // one covered region corresponds to a larger region because of page-size 8356893Sfenner // roundings. Thus, a committed region for one covered region may 8456893Sfenner // actually extend onto the card-table space for the next covered region. 8556893Sfenner MemRegion* _committed; 8656893Sfenner 8756893Sfenner // The last card is a guard card, and we commit the page for it so 8856893Sfenner // we can use the card for verification purposes. We make sure we never 8956893Sfenner // uncommit the MemRegion for that page. 9056893Sfenner MemRegion _guard_region; 9156893Sfenner 9256893Sfenner protected: 9356893Sfenner inline size_t compute_byte_map_size(); 9456893Sfenner 9556893Sfenner // Finds and return the index of the region, if any, to which the given 9656893Sfenner // region would be contiguous. If none exists, assign a new region and 9756893Sfenner // returns its index. Requires that no more than the maximum number of 9856893Sfenner // covered regions defined in the constructor are ever in use. 9956893Sfenner int find_covering_region_by_base(HeapWord* base); 10056893Sfenner 10156893Sfenner // Same as above, but finds the region containing the given address 10256893Sfenner // instead of starting at a given base address. 10356893Sfenner int find_covering_region_containing(HeapWord* addr); 10456893Sfenner 10556893Sfenner // Resize one of the regions covered by the remembered set. 10656893Sfenner virtual void resize_covered_region(MemRegion new_region); 10756893Sfenner 10856893Sfenner // Returns the leftmost end of a committed region corresponding to a 10956893Sfenner // covered region before covered region "ind", or else "NULL" if "ind" is 11056893Sfenner // the first covered region. 11156893Sfenner HeapWord* largest_prev_committed_end(int ind) const; 11256893Sfenner 11356893Sfenner // Returns the part of the region mr that doesn't intersect with 11456893Sfenner // any committed region other than self. Used to prevent uncommitting 11556893Sfenner // regions that are also committed by other regions. Also protects 11656893Sfenner // against uncommitting the guard region. 11756893Sfenner MemRegion committed_unique_to_self(int self, MemRegion mr) const; 11856893Sfenner 11956893Sfenner // Mapping from address to card marking array entry 12056893Sfenner jbyte* byte_for(const void* p) const { 12156893Sfenner assert(_whole_heap.contains(p), 12256893Sfenner "Attempt to access p = " PTR_FORMAT " out of bounds of " 12356893Sfenner " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")", 12456893Sfenner p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())); 12556893Sfenner jbyte* result = &byte_map_base[uintptr_t(p) >> card_shift]; 12656893Sfenner assert(result >= _byte_map && result < _byte_map + _byte_map_size, 12756893Sfenner "out of bounds accessor for card marking array"); 12856893Sfenner return result; 12956893Sfenner } 13056893Sfenner 13156893Sfenner // The card table byte one after the card marking array 13256893Sfenner // entry for argument address. Typically used for higher bounds 13356893Sfenner // for loops iterating through the card table. 13456893Sfenner jbyte* byte_after(const void* p) const { 13556893Sfenner return byte_for(p) + 1; 13656893Sfenner } 13756893Sfenner 13856893Sfenner protected: 13956893Sfenner // Dirty the bytes corresponding to "mr" (not all of which must be 14056893Sfenner // covered.) 14156893Sfenner void dirty_MemRegion(MemRegion mr); 14256893Sfenner 14356893Sfenner // Clear (to clean_card) the bytes entirely contained within "mr" (not 14456893Sfenner // all of which must be covered.) 14556893Sfenner void clear_MemRegion(MemRegion mr); 14656893Sfenner 14756893Sfennerpublic: 14856893Sfenner // Constants 14956893Sfenner enum SomePublicConstants { 15056893Sfenner card_shift = 9, 15156893Sfenner card_size = 1 << card_shift, 15256893Sfenner card_size_in_words = card_size / sizeof(HeapWord) 15356893Sfenner }; 15456893Sfenner 15556893Sfenner static int clean_card_val() { return clean_card; } 15656893Sfenner static int clean_card_mask_val() { return clean_card_mask; } 15756893Sfenner static int dirty_card_val() { return dirty_card; } 15856893Sfenner static int claimed_card_val() { return claimed_card; } 15956893Sfenner static int precleaned_card_val() { return precleaned_card; } 16056893Sfenner static int deferred_card_val() { return deferred_card; } 16156893Sfenner 16256893Sfenner virtual void initialize(); 16356893Sfenner 16456893Sfenner // *** Barrier set functions. 16556893Sfenner 16656893Sfenner bool has_write_ref_pre_barrier() { return false; } 16756893Sfenner 16856893Sfenner // Initialization utilities; covered_words is the size of the covered region 16956893Sfenner // in, um, words. 17056893Sfenner inline size_t cards_required(size_t covered_words) { 17156893Sfenner // Add one for a guard card, used to detect errors. 17256893Sfenner const size_t words = align_up(covered_words, card_size_in_words); 17356893Sfenner return words / card_size_in_words + 1; 17456893Sfenner } 17556893Sfenner 17656893Sfennerprotected: 17756893Sfenner 17856893Sfenner CardTableModRefBS(MemRegion whole_heap, const BarrierSet::FakeRtti& fake_rtti); 17956893Sfenner ~CardTableModRefBS(); 18056893Sfenner 18156893Sfenner // Record a reference update. Note that these versions are precise! 18256893Sfenner // The scanning code has to handle the fact that the write barrier may be 18356893Sfenner // either precise or imprecise. We make non-virtual inline variants of 18456893Sfenner // these functions here for performance. 18556893Sfenner 18656893Sfenner void write_ref_field_work(oop obj, size_t offset, oop newVal); 18756893Sfenner virtual void write_ref_field_work(void* field, oop newVal, bool release); 18856893Sfennerpublic: 18956893Sfenner 19056893Sfenner bool has_write_ref_array_opt() { return true; } 19156893Sfenner bool has_write_region_opt() { return true; } 19256893Sfenner 19356893Sfenner inline void inline_write_region(MemRegion mr) { 19456893Sfenner dirty_MemRegion(mr); 19556893Sfenner } 19656893Sfennerprotected: 19756893Sfenner void write_region_work(MemRegion mr) { 19856893Sfenner inline_write_region(mr); 19956893Sfenner } 20056893Sfennerpublic: 20156893Sfenner 20256893Sfenner inline void inline_write_ref_array(MemRegion mr) { 20356893Sfenner dirty_MemRegion(mr); 20456893Sfenner } 20556893Sfennerprotected: 20656893Sfenner void write_ref_array_work(MemRegion mr) { 20756893Sfenner inline_write_ref_array(mr); 20856893Sfenner } 20956893Sfennerpublic: 21056893Sfenner 21156893Sfenner bool is_aligned(HeapWord* addr) { 21256893Sfenner return is_card_aligned(addr); 21356893Sfenner } 21456893Sfenner 21556893Sfenner // *** Card-table-barrier-specific things. 21656893Sfenner 21756893Sfenner template <class T> inline void inline_write_ref_field_pre(T* field, oop newVal) {} 21856893Sfenner 21956893Sfenner template <class T> inline void inline_write_ref_field(T* field, oop newVal, bool release); 22056893Sfenner 22156893Sfenner // These are used by G1, when it uses the card table as a temporary data 22256893Sfenner // structure for card claiming. 22356893Sfenner bool is_card_dirty(size_t card_index) { 22456893Sfenner return _byte_map[card_index] == dirty_card_val(); 22556893Sfenner } 22656893Sfenner 22756893Sfenner void mark_card_dirty(size_t card_index) { 22856893Sfenner _byte_map[card_index] = dirty_card_val(); 22956893Sfenner } 23056893Sfenner 23156893Sfenner bool is_card_clean(size_t card_index) { 23256893Sfenner return _byte_map[card_index] == clean_card_val(); 23356893Sfenner } 23456893Sfenner 23556893Sfenner // Card marking array base (adjusted for heap low boundary) 23656893Sfenner // This would be the 0th element of _byte_map, if the heap started at 0x0. 23756893Sfenner // But since the heap starts at some higher address, this points to somewhere 23856893Sfenner // before the beginning of the actual _byte_map. 23956893Sfenner jbyte* byte_map_base; 24056893Sfenner 24156893Sfenner // Return true if "p" is at the start of a card. 24256893Sfenner bool is_card_aligned(HeapWord* p) { 24356893Sfenner jbyte* pcard = byte_for(p); 24456893Sfenner return (addr_for(pcard) == p); 24556893Sfenner } 24656893Sfenner 24756893Sfenner HeapWord* align_to_card_boundary(HeapWord* p) { 24856893Sfenner jbyte* pcard = byte_for(p + card_size_in_words - 1); 24956893Sfenner return addr_for(pcard); 25056893Sfenner } 25156893Sfenner 25256893Sfenner // The kinds of precision a CardTableModRefBS may offer. 25356893Sfenner enum PrecisionStyle { 25456893Sfenner Precise, 25556893Sfenner ObjHeadPreciseArray 25656893Sfenner }; 25756893Sfenner 25856893Sfenner // Tells what style of precision this card table offers. 25956893Sfenner PrecisionStyle precision() { 26056893Sfenner return ObjHeadPreciseArray; // Only one supported for now. 26156893Sfenner } 26256893Sfenner 26356893Sfenner // ModRefBS functions. 26456893Sfenner virtual void invalidate(MemRegion mr); 26556893Sfenner void clear(MemRegion mr); 26656893Sfenner void dirty(MemRegion mr); 26756893Sfenner 26856893Sfenner // *** Card-table-RemSet-specific things. 26956893Sfenner 27056893Sfenner static uintx ct_max_alignment_constraint(); 27156893Sfenner 27256893Sfenner // Apply closure "cl" to the dirty cards containing some part of 27356893Sfenner // MemRegion "mr". 27456893Sfenner void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl); 27556893Sfenner 27656893Sfenner // Return the MemRegion corresponding to the first maximal run 27756893Sfenner // of dirty cards lying completely within MemRegion mr. 27856893Sfenner // If reset is "true", then sets those card table entries to the given 27956893Sfenner // value. 28056893Sfenner MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset, 28156893Sfenner int reset_val); 28256893Sfenner 28356893Sfenner // Provide read-only access to the card table array. 28456893Sfenner const jbyte* byte_for_const(const void* p) const { 28556893Sfenner return byte_for(p); 28656893Sfenner } 28756893Sfenner const jbyte* byte_after_const(const void* p) const { 28856893Sfenner return byte_after(p); 28956893Sfenner } 29056893Sfenner 29156893Sfenner // Mapping from card marking array entry to address of first word 29256893Sfenner HeapWord* addr_for(const jbyte* p) const { 29356893Sfenner assert(p >= _byte_map && p < _byte_map + _byte_map_size, 29456893Sfenner "out of bounds access to card marking array. p: " PTR_FORMAT 29556893Sfenner " _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT, 29656893Sfenner p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size)); 29756893Sfenner size_t delta = pointer_delta(p, byte_map_base, sizeof(jbyte)); 29856893Sfenner HeapWord* result = (HeapWord*) (delta << card_shift); 29956893Sfenner assert(_whole_heap.contains(result), 30056893Sfenner "Returning result = " PTR_FORMAT " out of bounds of " 30156893Sfenner " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")", 30256893Sfenner p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end())); 30356893Sfenner return result; 30456893Sfenner } 30556893Sfenner 30656893Sfenner // Mapping from address to card marking array index. 30756893Sfenner size_t index_for(void* p) { 30856893Sfenner assert(_whole_heap.contains(p), 30956893Sfenner "Attempt to access p = " PTR_FORMAT " out of bounds of " 31056893Sfenner " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")", 31156893Sfenner p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())); 31256893Sfenner return byte_for(p) - _byte_map; 31356893Sfenner } 31456893Sfenner 31556893Sfenner const jbyte* byte_for_index(const size_t card_index) const { 31656893Sfenner return _byte_map + card_index; 31756893Sfenner } 31856893Sfenner 31956893Sfenner // Print a description of the memory for the barrier set 32056893Sfenner virtual void print_on(outputStream* st) const; 32156893Sfenner 32256893Sfenner void verify(); 32356893Sfenner void verify_guard(); 32456893Sfenner 32556893Sfenner // val_equals -> it will check that all cards covered by mr equal val 32656893Sfenner // !val_equals -> it will check that all cards covered by mr do not equal val 32756893Sfenner void verify_region(MemRegion mr, jbyte val, bool val_equals) PRODUCT_RETURN; 32856893Sfenner void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN; 32956893Sfenner void verify_dirty_region(MemRegion mr) PRODUCT_RETURN; 33056893Sfenner}; 33156893Sfenner 33256893Sfennertemplate<> 33356893Sfennerstruct BarrierSet::GetName<CardTableModRefBS> { 33456893Sfenner static const BarrierSet::Name value = BarrierSet::CardTableModRef; 33556893Sfenner}; 33656893Sfenner 33756893Sfenner 33856893Sfenner#endif // SHARE_VM_GC_SHARED_CARDTABLEMODREFBS_HPP 33956893Sfenner