Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/gc/shared/cardTable.hpp
40957 views
1
/*
2
* Copyright (c) 2000, 2020, 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 MemRegion _whole_heap; // the region covered by the card table
47
size_t _guard_index; // index of very last element in the card
48
// table; it is set to a guard value
49
// (last_card) and should never be modified
50
size_t _last_valid_index; // index of the last valid element
51
const size_t _page_size; // page size used when mapping _byte_map
52
size_t _byte_map_size; // in bytes
53
CardValue* _byte_map; // the card marking array
54
CardValue* _byte_map_base;
55
56
int _cur_covered_regions;
57
58
// The covered regions should be in address order.
59
MemRegion* _covered;
60
// The committed regions correspond one-to-one to the covered regions.
61
// They represent the card-table memory that has been committed to service
62
// the corresponding covered region. It may be that committed region for
63
// one covered region corresponds to a larger region because of page-size
64
// roundings. Thus, a committed region for one covered region may
65
// actually extend onto the card-table space for the next covered region.
66
MemRegion* _committed;
67
68
// The last card is a guard card, and we commit the page for it so
69
// we can use the card for verification purposes. We make sure we never
70
// uncommit the MemRegion for that page.
71
MemRegion _guard_region;
72
73
inline size_t compute_byte_map_size();
74
75
// Finds and return the index of the region, if any, to which the given
76
// region would be contiguous. If none exists, assign a new region and
77
// returns its index. Requires that no more than the maximum number of
78
// covered regions defined in the constructor are ever in use.
79
int find_covering_region_by_base(HeapWord* base);
80
81
// Same as above, but finds the region containing the given address
82
// instead of starting at a given base address.
83
int find_covering_region_containing(HeapWord* addr);
84
85
// Returns the leftmost end of a committed region corresponding to a
86
// covered region before covered region "ind", or else "NULL" if "ind" is
87
// the first covered region.
88
HeapWord* largest_prev_committed_end(int ind) const;
89
90
// Returns the part of the region mr that doesn't intersect with
91
// any committed region other than self. Used to prevent uncommitting
92
// regions that are also committed by other regions. Also protects
93
// against uncommitting the guard region.
94
MemRegion committed_unique_to_self(int self, MemRegion mr) const;
95
96
// Some barrier sets create tables whose elements correspond to parts of
97
// the heap; the CardTableBarrierSet is an example. Such barrier sets will
98
// normally reserve space for such tables, and commit parts of the table
99
// "covering" parts of the heap that are committed. At most one covered
100
// region per generation is needed.
101
static const int _max_covered_regions = 2;
102
103
enum CardValues {
104
clean_card = (CardValue)-1,
105
106
dirty_card = 0,
107
last_card = 1,
108
CT_MR_BS_last_reserved = 2
109
};
110
111
// a word's worth (row) of clean card values
112
static const intptr_t clean_card_row = (intptr_t)(-1);
113
114
public:
115
CardTable(MemRegion whole_heap);
116
virtual ~CardTable();
117
virtual void initialize();
118
119
// The kinds of precision a CardTable may offer.
120
enum PrecisionStyle {
121
Precise,
122
ObjHeadPreciseArray
123
};
124
125
// Tells what style of precision this card table offers.
126
PrecisionStyle precision() {
127
return ObjHeadPreciseArray; // Only one supported for now.
128
}
129
130
// *** Barrier set functions.
131
132
// Initialization utilities; covered_words is the size of the covered region
133
// in, um, words.
134
inline size_t cards_required(size_t covered_words) {
135
// Add one for a guard card, used to detect errors.
136
const size_t words = align_up(covered_words, card_size_in_words);
137
return words / card_size_in_words + 1;
138
}
139
140
// Dirty the bytes corresponding to "mr" (not all of which must be
141
// covered.)
142
void dirty_MemRegion(MemRegion mr);
143
144
// Clear (to clean_card) the bytes entirely contained within "mr" (not
145
// all of which must be covered.)
146
void clear_MemRegion(MemRegion mr);
147
148
// Return true if "p" is at the start of a card.
149
bool is_card_aligned(HeapWord* p) {
150
CardValue* pcard = byte_for(p);
151
return (addr_for(pcard) == p);
152
}
153
154
// Mapping from address to card marking array entry
155
CardValue* byte_for(const void* p) const {
156
assert(_whole_heap.contains(p),
157
"Attempt to access p = " PTR_FORMAT " out of bounds of "
158
" card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
159
p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
160
CardValue* result = &_byte_map_base[uintptr_t(p) >> card_shift];
161
assert(result >= _byte_map && result < _byte_map + _byte_map_size,
162
"out of bounds accessor for card marking array");
163
return result;
164
}
165
166
// The card table byte one after the card marking array
167
// entry for argument address. Typically used for higher bounds
168
// for loops iterating through the card table.
169
CardValue* byte_after(const void* p) const {
170
return byte_for(p) + 1;
171
}
172
173
virtual void invalidate(MemRegion mr);
174
void clear(MemRegion mr);
175
void dirty(MemRegion mr);
176
177
// Provide read-only access to the card table array.
178
const CardValue* byte_for_const(const void* p) const {
179
return byte_for(p);
180
}
181
const CardValue* byte_after_const(const void* p) const {
182
return byte_after(p);
183
}
184
185
// Mapping from card marking array entry to address of first word
186
HeapWord* addr_for(const CardValue* p) const {
187
assert(p >= _byte_map && p < _byte_map + _byte_map_size,
188
"out of bounds access to card marking array. p: " PTR_FORMAT
189
" _byte_map: " PTR_FORMAT " _byte_map + _byte_map_size: " PTR_FORMAT,
190
p2i(p), p2i(_byte_map), p2i(_byte_map + _byte_map_size));
191
size_t delta = pointer_delta(p, _byte_map_base, sizeof(CardValue));
192
HeapWord* result = (HeapWord*) (delta << card_shift);
193
assert(_whole_heap.contains(result),
194
"Returning result = " PTR_FORMAT " out of bounds of "
195
" card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
196
p2i(result), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
197
return result;
198
}
199
200
// Mapping from address to card marking array index.
201
size_t index_for(void* p) {
202
assert(_whole_heap.contains(p),
203
"Attempt to access p = " PTR_FORMAT " out of bounds of "
204
" card marking array's _whole_heap = [" PTR_FORMAT "," PTR_FORMAT ")",
205
p2i(p), p2i(_whole_heap.start()), p2i(_whole_heap.end()));
206
return byte_for(p) - _byte_map;
207
}
208
209
CardValue* byte_for_index(const size_t card_index) const {
210
return _byte_map + card_index;
211
}
212
213
// Resize one of the regions covered by the remembered set.
214
virtual void resize_covered_region(MemRegion new_region);
215
216
// *** Card-table-RemSet-specific things.
217
218
static uintx ct_max_alignment_constraint();
219
220
// Apply closure "cl" to the dirty cards containing some part of
221
// MemRegion "mr".
222
void dirty_card_iterate(MemRegion mr, MemRegionClosure* cl);
223
224
// Return the MemRegion corresponding to the first maximal run
225
// of dirty cards lying completely within MemRegion mr.
226
// If reset is "true", then sets those card table entries to the given
227
// value.
228
MemRegion dirty_card_range_after_reset(MemRegion mr, bool reset,
229
int reset_val);
230
231
// Constants
232
enum SomePublicConstants {
233
card_shift = 9,
234
card_size = 1 << card_shift,
235
card_size_in_words = card_size / sizeof(HeapWord)
236
};
237
238
static CardValue clean_card_val() { return clean_card; }
239
static CardValue dirty_card_val() { return dirty_card; }
240
static intptr_t clean_card_row_val() { return clean_card_row; }
241
242
// Card marking array base (adjusted for heap low boundary)
243
// This would be the 0th element of _byte_map, if the heap started at 0x0.
244
// But since the heap starts at some higher address, this points to somewhere
245
// before the beginning of the actual _byte_map.
246
CardValue* byte_map_base() const { return _byte_map_base; }
247
248
virtual bool is_in_young(oop obj) const = 0;
249
250
// Print a description of the memory for the card table
251
virtual void print_on(outputStream* st) const;
252
253
void verify();
254
void verify_guard();
255
256
// val_equals -> it will check that all cards covered by mr equal val
257
// !val_equals -> it will check that all cards covered by mr do not equal val
258
void verify_region(MemRegion mr, CardValue val, bool val_equals) PRODUCT_RETURN;
259
void verify_not_dirty_region(MemRegion mr) PRODUCT_RETURN;
260
void verify_dirty_region(MemRegion mr) PRODUCT_RETURN;
261
};
262
263
#endif // SHARE_GC_SHARED_CARDTABLE_HPP
264
265