1 | /* |
2 | * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. |
3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | * |
5 | * This code is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License version 2 only, as |
7 | * published by the Free Software Foundation. |
8 | * |
9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
12 | * version 2 for more details (a copy is included in the LICENSE file that |
13 | * accompanied this code). |
14 | * |
15 | * You should have received a copy of the GNU General Public License version |
16 | * 2 along with this work; if not, write to the Free Software Foundation, |
17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
18 | * |
19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 | * or visit www.oracle.com if you need additional information or have any |
21 | * questions. |
22 | * |
23 | */ |
24 | |
25 | #ifndef SHARE_GC_SHARED_CARDTABLE_HPP |
26 | #define SHARE_GC_SHARED_CARDTABLE_HPP |
27 | |
28 | #include "memory/allocation.hpp" |
29 | #include "memory/memRegion.hpp" |
30 | #include "oops/oopsHierarchy.hpp" |
31 | #include "utilities/align.hpp" |
32 | |
33 | class CardTable: public CHeapObj<mtGC> { |
34 | friend class VMStructs; |
35 | public: |
36 | typedef uint8_t CardValue; |
37 | |
38 | // All code generators assume that the size of a card table entry is one byte. |
39 | // They need to be updated to reflect any change to this. |
40 | // This code can typically be found by searching for the byte_map_base() method. |
41 | STATIC_ASSERT(sizeof(CardValue) == 1); |
42 | |
43 | protected: |
44 | // The declaration order of these const fields is important; see the |
45 | // constructor before changing. |
46 | const bool _scanned_concurrently; |
47 | const MemRegion _whole_heap; // the region covered by the card table |
48 | size_t _guard_index; // index of very last element in the card |
49 | // table; it is set to a guard value |
50 | // (last_card) and should never be modified |
51 | size_t _last_valid_index; // index of the last valid element |
52 | const size_t _page_size; // page size used when mapping _byte_map |
53 | size_t _byte_map_size; // in bytes |
54 | CardValue* _byte_map; // the card marking array |
55 | CardValue* _byte_map_base; |
56 | |
57 | int _cur_covered_regions; |
58 | |
59 | // The covered regions should be in address order. |
60 | MemRegion* _covered; |
61 | // The committed regions correspond one-to-one to the covered regions. |
62 | // They represent the card-table memory that has been committed to service |
63 | // the corresponding covered region. It may be that committed region for |
64 | // one covered region corresponds to a larger region because of page-size |
65 | // roundings. Thus, a committed region for one covered region may |
66 | // actually extend onto the card-table space for the next covered region. |
67 | MemRegion* _committed; |
68 | |
69 | // The last card is a guard card, and we commit the page for it so |
70 | // we can use the card for verification purposes. We make sure we never |
71 | // uncommit the MemRegion for that page. |
72 | MemRegion _guard_region; |
73 | |
74 | inline size_t compute_byte_map_size(); |
75 | |
76 | // Finds and return the index of the region, if any, to which the given |
77 | // region would be contiguous. If none exists, assign a new region and |
78 | // returns its index. Requires that no more than the maximum number of |
79 | // covered regions defined in the constructor are ever in use. |
80 | int find_covering_region_by_base(HeapWord* base); |
81 | |
82 | // Same as above, but finds the region containing the given address |
83 | // instead of starting at a given base address. |
84 | int find_covering_region_containing(HeapWord* addr); |
85 | |
86 | // Returns the leftmost end of a committed region corresponding to a |
87 | // covered region before covered region "ind", or else "NULL" if "ind" is |
88 | // the first covered region. |
89 | HeapWord* largest_prev_committed_end(int ind) const; |
90 | |
91 | // Returns the part of the region mr that doesn't intersect with |
92 | // any committed region other than self. Used to prevent uncommitting |
93 | // regions that are also committed by other regions. Also protects |
94 | // against uncommitting the guard region. |
95 | MemRegion committed_unique_to_self(int self, MemRegion mr) const; |
96 | |
97 | // Some barrier sets create tables whose elements correspond to parts of |
98 | // the heap; the CardTableBarrierSet is an example. Such barrier sets will |
99 | // normally reserve space for such tables, and commit parts of the table |
100 | // "covering" parts of the heap that are committed. At most one covered |
101 | // region per generation is needed. |
102 | static const int _max_covered_regions = 2; |
103 | |
104 | enum CardValues { |
105 | clean_card = (CardValue)-1, |
106 | // The mask contains zeros in places for all other values. |
107 | clean_card_mask = clean_card - 31, |
108 | |
109 | dirty_card = 0, |
110 | precleaned_card = 1, |
111 | claimed_card = 2, |
112 | deferred_card = 4, |
113 | last_card = 8, |
114 | CT_MR_BS_last_reserved = 16 |
115 | }; |
116 | |
117 | // a word's worth (row) of clean card values |
118 | static const intptr_t clean_card_row = (intptr_t)(-1); |
119 | |
120 | public: |
121 | CardTable(MemRegion whole_heap, bool conc_scan); |
122 | virtual ~CardTable(); |
123 | virtual void initialize(); |
124 | |
125 | // The kinds of precision a CardTable may offer. |
126 | enum PrecisionStyle { |
127 | Precise, |
128 | ObjHeadPreciseArray |
129 | }; |
130 | |
131 | // Tells what style of precision this card table offers. |
132 | PrecisionStyle precision() { |
133 | return ObjHeadPreciseArray; // Only one supported for now. |
134 | } |
135 | |
136 | // *** Barrier set functions. |
137 | |
138 | // Initialization utilities; covered_words is the size of the covered region |
139 | // in, um, words. |
140 | inline size_t cards_required(size_t covered_words) { |
141 | // Add one for a guard card, used to detect errors. |
142 | const size_t words = align_up(covered_words, card_size_in_words); |
143 | return words / card_size_in_words + 1; |
144 | } |
145 | |
146 | // Dirty the bytes corresponding to "mr" (not all of which must be |
147 | // covered.) |
148 | void dirty_MemRegion(MemRegion mr); |
149 | |
150 | // Clear (to clean_card) the bytes entirely contained within "mr" (not |
151 | // all of which must be covered.) |
152 | void clear_MemRegion(MemRegion mr); |
153 | |
154 | // Return true if "p" is at the start of a card. |
155 | bool is_card_aligned(HeapWord* p) { |
156 | CardValue* pcard = byte_for(p); |
157 | return (addr_for(pcard) == p); |
158 | } |
159 | |
160 | // Mapping from address to card marking array entry |
161 | CardValue* byte_for(const void* p) const { |
162 | assert(_whole_heap.contains(p), |
163 | "Attempt to access p = " PTR_FORMAT " out of bounds of " |
164 | " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")" , |
165 | p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())); |
166 | CardValue* result = &_byte_map_base[uintptr_t(p) >> card_shift]; |
167 | assert(result >= _byte_map && result < _byte_map + _byte_map_size, |
168 | "out of bounds accessor for card marking array" ); |
169 | return result; |
170 | } |
171 | |
172 | // The card table byte one after the card marking array |
173 | // entry for argument address. Typically used for higher bounds |
174 | // for loops iterating through the card table. |
175 | CardValue* byte_after(const void* p) const { |
176 | return byte_for(p) + 1; |
177 | } |
178 | |
179 | virtual void invalidate(MemRegion mr); |
180 | void clear(MemRegion mr); |
181 | void dirty(MemRegion mr); |
182 | |
183 | // Provide read-only access to the card table array. |
184 | const CardValue* byte_for_const(const void* p) const { |
185 | return byte_for(p); |
186 | } |
187 | const CardValue* byte_after_const(const void* p) const { |
188 | return byte_after(p); |
189 | } |
190 | |
191 | // Mapping from card marking array entry to address of first word |
192 | HeapWord* addr_for(const CardValue* p) const { |
193 | assert(p >= _byte_map && p < _byte_map + _byte_map_size, |
194 | "out of bounds access to card marking array. p: " PTR_FORMAT |
195 | " _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT, |
196 | p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size)); |
197 | size_t delta = pointer_delta(p, _byte_map_base, sizeof(CardValue)); |
198 | HeapWord* result = (HeapWord*) (delta << card_shift); |
199 | assert(_whole_heap.contains(result), |
200 | "Returning result = " PTR_FORMAT " out of bounds of " |
201 | " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")" , |
202 | p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end())); |
203 | return result; |
204 | } |
205 | |
206 | // Mapping from address to card marking array index. |
207 | size_t index_for(void* p) { |
208 | assert(_whole_heap.contains(p), |
209 | "Attempt to access p = " PTR_FORMAT " out of bounds of " |
210 | " card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")" , |
211 | p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end())); |
212 | return byte_for(p) - _byte_map; |
213 | } |
214 | |
215 | CardValue* byte_for_index(const size_t card_index) const { |
216 | return _byte_map + card_index; |
217 | } |
218 | |
219 | // Resize one of the regions covered by the remembered set. |
220 | virtual void resize_covered_region(MemRegion new_region); |
221 | |
222 | // *** Card-table-RemSet-specific things. |
223 | |
224 | static uintx ct_max_alignment_constraint(); |
225 | |
226 | // Apply closure "cl" to the dirty cards containing some part of |
227 | // MemRegion "mr". |
228 | void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl); |
229 | |
230 | // Return the MemRegion corresponding to the first maximal run |
231 | // of dirty cards lying completely within MemRegion mr. |
232 | // If reset is "true", then sets those card table entries to the given |
233 | // value. |
234 | MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset, |
235 | int reset_val); |
236 | |
237 | // Constants |
238 | enum SomePublicConstants { |
239 | card_shift = 9, |
240 | card_size = 1 << card_shift, |
241 | card_size_in_words = card_size / sizeof(HeapWord) |
242 | }; |
243 | |
244 | static CardValue clean_card_val() { return clean_card; } |
245 | static CardValue clean_card_mask_val() { return clean_card_mask; } |
246 | static CardValue dirty_card_val() { return dirty_card; } |
247 | static CardValue claimed_card_val() { return claimed_card; } |
248 | static CardValue precleaned_card_val() { return precleaned_card; } |
249 | static CardValue deferred_card_val() { return deferred_card; } |
250 | static intptr_t clean_card_row_val() { return clean_card_row; } |
251 | |
252 | // Card marking array base (adjusted for heap low boundary) |
253 | // This would be the 0th element of _byte_map, if the heap started at 0x0. |
254 | // But since the heap starts at some higher address, this points to somewhere |
255 | // before the beginning of the actual _byte_map. |
256 | CardValue* byte_map_base() const { return _byte_map_base; } |
257 | bool scanned_concurrently() const { return _scanned_concurrently; } |
258 | |
259 | virtual bool is_in_young(oop obj) const = 0; |
260 | |
261 | // Print a description of the memory for the card table |
262 | virtual void print_on(outputStream* st) const; |
263 | |
264 | void verify(); |
265 | void verify_guard(); |
266 | |
267 | // val_equals -> it will check that all cards covered by mr equal val |
268 | // !val_equals -> it will check that all cards covered by mr do not equal val |
269 | void verify_region(MemRegion mr, CardValue val, bool val_equals) PRODUCT_RETURN; |
270 | void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN; |
271 | void verify_dirty_region(MemRegion mr) PRODUCT_RETURN; |
272 | }; |
273 | |
274 | #endif // SHARE_GC_SHARED_CARDTABLE_HPP |
275 | |