annotate src/share/vm/memory/cardTableModRefBS.cpp @ 1091:6aa7255741f3

6906727: UseCompressedOops: some card-marking fixes related to object arrays Summary: Introduced a new write_ref_array(HeapWords* start, size_t count) method that does the requisite MemRegion range calculation so (some of the) clients of the erstwhile write_ref_array(MemRegion mr) do not need to worry. This removed all external uses of array_size(), which was also simplified and made private. Asserts were added to catch other possible issues. Further, less essential, fixes stemming from this investigation are deferred to CR 6904516 (to follow shortly in hs17). Reviewed-by: kvn, coleenp, jmasa
author ysr
date Thu, 03 Dec 2009 15:01:57 -0800
parents 8624da129f0b
children c18cbe5936b8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
579
0fbdb4381b99 6814575: Update copyright year
xdono
parents: 489
diff changeset
2 * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 // This kind of "BarrierSet" allows a "CollectedHeap" to detect and
a61af66fc99e Initial load
duke
parents:
diff changeset
26 // enumerate ref fields that have been modified (since the last
a61af66fc99e Initial load
duke
parents:
diff changeset
27 // enumeration.)
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 # include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
30 # include "incls/_cardTableModRefBS.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
31
a61af66fc99e Initial load
duke
parents:
diff changeset
32 size_t CardTableModRefBS::cards_required(size_t covered_words)
a61af66fc99e Initial load
duke
parents:
diff changeset
33 {
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // Add one for a guard card, used to detect errors.
a61af66fc99e Initial load
duke
parents:
diff changeset
35 const size_t words = align_size_up(covered_words, card_size_in_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
36 return words / card_size_in_words + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
37 }
a61af66fc99e Initial load
duke
parents:
diff changeset
38
a61af66fc99e Initial load
duke
parents:
diff changeset
39 size_t CardTableModRefBS::compute_byte_map_size()
a61af66fc99e Initial load
duke
parents:
diff changeset
40 {
a61af66fc99e Initial load
duke
parents:
diff changeset
41 assert(_guard_index == cards_required(_whole_heap.word_size()) - 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
42 "unitialized, check declaration order");
a61af66fc99e Initial load
duke
parents:
diff changeset
43 assert(_page_size != 0, "unitialized, check declaration order");
a61af66fc99e Initial load
duke
parents:
diff changeset
44 const size_t granularity = os::vm_allocation_granularity();
a61af66fc99e Initial load
duke
parents:
diff changeset
45 return align_size_up(_guard_index + 1, MAX2(_page_size, granularity));
a61af66fc99e Initial load
duke
parents:
diff changeset
46 }
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 CardTableModRefBS::CardTableModRefBS(MemRegion whole_heap,
a61af66fc99e Initial load
duke
parents:
diff changeset
49 int max_covered_regions):
a61af66fc99e Initial load
duke
parents:
diff changeset
50 ModRefBarrierSet(max_covered_regions),
a61af66fc99e Initial load
duke
parents:
diff changeset
51 _whole_heap(whole_heap),
a61af66fc99e Initial load
duke
parents:
diff changeset
52 _guard_index(cards_required(whole_heap.word_size()) - 1),
a61af66fc99e Initial load
duke
parents:
diff changeset
53 _last_valid_index(_guard_index - 1),
21
b611e572fc5b 6635560: segv in reference processor on t1000
jcoomes
parents: 0
diff changeset
54 _page_size(os::vm_page_size()),
0
a61af66fc99e Initial load
duke
parents:
diff changeset
55 _byte_map_size(compute_byte_map_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
56 {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 _kind = BarrierSet::CardTableModRef;
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 HeapWord* low_bound = _whole_heap.start();
a61af66fc99e Initial load
duke
parents:
diff changeset
60 HeapWord* high_bound = _whole_heap.end();
a61af66fc99e Initial load
duke
parents:
diff changeset
61 assert((uintptr_t(low_bound) & (card_size - 1)) == 0, "heap must start at card boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
62 assert((uintptr_t(high_bound) & (card_size - 1)) == 0, "heap must end at card boundary");
a61af66fc99e Initial load
duke
parents:
diff changeset
63
a61af66fc99e Initial load
duke
parents:
diff changeset
64 assert(card_size <= 512, "card_size must be less than 512"); // why?
a61af66fc99e Initial load
duke
parents:
diff changeset
65
a61af66fc99e Initial load
duke
parents:
diff changeset
66 _covered = new MemRegion[max_covered_regions];
a61af66fc99e Initial load
duke
parents:
diff changeset
67 _committed = new MemRegion[max_covered_regions];
a61af66fc99e Initial load
duke
parents:
diff changeset
68 if (_covered == NULL || _committed == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
69 vm_exit_during_initialization("couldn't alloc card table covered region set.");
a61af66fc99e Initial load
duke
parents:
diff changeset
70 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 for (i = 0; i < max_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
72 _covered[i].set_word_size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
73 _committed[i].set_word_size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
74 }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 _cur_covered_regions = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 :
a61af66fc99e Initial load
duke
parents:
diff changeset
78 MAX2(_page_size, (size_t) os::vm_allocation_granularity());
a61af66fc99e Initial load
duke
parents:
diff changeset
79 ReservedSpace heap_rs(_byte_map_size, rs_align, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 os::trace_page_sizes("card table", _guard_index + 1, _guard_index + 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
81 _page_size, heap_rs.base(), heap_rs.size());
a61af66fc99e Initial load
duke
parents:
diff changeset
82 if (!heap_rs.is_reserved()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
83 vm_exit_during_initialization("Could not reserve enough space for the "
a61af66fc99e Initial load
duke
parents:
diff changeset
84 "card marking array");
a61af66fc99e Initial load
duke
parents:
diff changeset
85 }
a61af66fc99e Initial load
duke
parents:
diff changeset
86
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // The assember store_check code will do an unsigned shift of the oop,
a61af66fc99e Initial load
duke
parents:
diff changeset
88 // then add it to byte_map_base, i.e.
a61af66fc99e Initial load
duke
parents:
diff changeset
89 //
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // _byte_map = byte_map_base + (uintptr_t(low_bound) >> card_shift)
a61af66fc99e Initial load
duke
parents:
diff changeset
91 _byte_map = (jbyte*) heap_rs.base();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 byte_map_base = _byte_map - (uintptr_t(low_bound) >> card_shift);
a61af66fc99e Initial load
duke
parents:
diff changeset
93 assert(byte_for(low_bound) == &_byte_map[0], "Checking start of map");
a61af66fc99e Initial load
duke
parents:
diff changeset
94 assert(byte_for(high_bound-1) <= &_byte_map[_last_valid_index], "Checking end of map");
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 jbyte* guard_card = &_byte_map[_guard_index];
a61af66fc99e Initial load
duke
parents:
diff changeset
97 uintptr_t guard_page = align_size_down((uintptr_t)guard_card, _page_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
98 _guard_region = MemRegion((HeapWord*)guard_page, _page_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 if (!os::commit_memory((char*)guard_page, _page_size, _page_size)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
100 // Do better than this for Merlin
a61af66fc99e Initial load
duke
parents:
diff changeset
101 vm_exit_out_of_memory(_page_size, "card table last card");
a61af66fc99e Initial load
duke
parents:
diff changeset
102 }
a61af66fc99e Initial load
duke
parents:
diff changeset
103 *guard_card = last_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
104
a61af66fc99e Initial load
duke
parents:
diff changeset
105 _lowest_non_clean =
a61af66fc99e Initial load
duke
parents:
diff changeset
106 NEW_C_HEAP_ARRAY(CardArr, max_covered_regions);
a61af66fc99e Initial load
duke
parents:
diff changeset
107 _lowest_non_clean_chunk_size =
a61af66fc99e Initial load
duke
parents:
diff changeset
108 NEW_C_HEAP_ARRAY(size_t, max_covered_regions);
a61af66fc99e Initial load
duke
parents:
diff changeset
109 _lowest_non_clean_base_chunk_index =
a61af66fc99e Initial load
duke
parents:
diff changeset
110 NEW_C_HEAP_ARRAY(uintptr_t, max_covered_regions);
a61af66fc99e Initial load
duke
parents:
diff changeset
111 _last_LNC_resizing_collection =
a61af66fc99e Initial load
duke
parents:
diff changeset
112 NEW_C_HEAP_ARRAY(int, max_covered_regions);
a61af66fc99e Initial load
duke
parents:
diff changeset
113 if (_lowest_non_clean == NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
114 || _lowest_non_clean_chunk_size == NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
115 || _lowest_non_clean_base_chunk_index == NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
116 || _last_LNC_resizing_collection == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
117 vm_exit_during_initialization("couldn't allocate an LNC array.");
a61af66fc99e Initial load
duke
parents:
diff changeset
118 for (i = 0; i < max_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
119 _lowest_non_clean[i] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
120 _lowest_non_clean_chunk_size[i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
121 _last_LNC_resizing_collection[i] = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
123
a61af66fc99e Initial load
duke
parents:
diff changeset
124 if (TraceCardTableModRefBS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
125 gclog_or_tty->print_cr("CardTableModRefBS::CardTableModRefBS: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
126 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
127 " &_byte_map[0]: " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
128 " &_byte_map[_last_valid_index]: " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
129 &_byte_map[0],
a61af66fc99e Initial load
duke
parents:
diff changeset
130 &_byte_map[_last_valid_index]);
a61af66fc99e Initial load
duke
parents:
diff changeset
131 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
132 " byte_map_base: " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
133 byte_map_base);
a61af66fc99e Initial load
duke
parents:
diff changeset
134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
135 }
a61af66fc99e Initial load
duke
parents:
diff changeset
136
a61af66fc99e Initial load
duke
parents:
diff changeset
137 int CardTableModRefBS::find_covering_region_by_base(HeapWord* base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
138 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
139 for (i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
140 if (_covered[i].start() == base) return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
141 if (_covered[i].start() > base) break;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 }
a61af66fc99e Initial load
duke
parents:
diff changeset
143 // If we didn't find it, create a new one.
a61af66fc99e Initial load
duke
parents:
diff changeset
144 assert(_cur_covered_regions < _max_covered_regions,
a61af66fc99e Initial load
duke
parents:
diff changeset
145 "too many covered regions");
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // Move the ones above up, to maintain sorted order.
a61af66fc99e Initial load
duke
parents:
diff changeset
147 for (int j = _cur_covered_regions; j > i; j--) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 _covered[j] = _covered[j-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
149 _committed[j] = _committed[j-1];
a61af66fc99e Initial load
duke
parents:
diff changeset
150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
151 int res = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
152 _cur_covered_regions++;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 _covered[res].set_start(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
154 _covered[res].set_word_size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 jbyte* ct_start = byte_for(base);
a61af66fc99e Initial load
duke
parents:
diff changeset
156 uintptr_t ct_start_aligned = align_size_down((uintptr_t)ct_start, _page_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
157 _committed[res].set_start((HeapWord*)ct_start_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
158 _committed[res].set_word_size(0);
a61af66fc99e Initial load
duke
parents:
diff changeset
159 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 int CardTableModRefBS::find_covering_region_containing(HeapWord* addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
163 for (int i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 if (_covered[i].contains(addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
168 assert(0, "address outside of heap?");
a61af66fc99e Initial load
duke
parents:
diff changeset
169 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 HeapWord* CardTableModRefBS::largest_prev_committed_end(int ind) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
173 HeapWord* max_end = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 for (int j = 0; j < ind; j++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
175 HeapWord* this_end = _committed[j].end();
a61af66fc99e Initial load
duke
parents:
diff changeset
176 if (this_end > max_end) max_end = this_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
177 }
a61af66fc99e Initial load
duke
parents:
diff changeset
178 return max_end;
a61af66fc99e Initial load
duke
parents:
diff changeset
179 }
a61af66fc99e Initial load
duke
parents:
diff changeset
180
a61af66fc99e Initial load
duke
parents:
diff changeset
181 MemRegion CardTableModRefBS::committed_unique_to_self(int self,
a61af66fc99e Initial load
duke
parents:
diff changeset
182 MemRegion mr) const {
a61af66fc99e Initial load
duke
parents:
diff changeset
183 MemRegion result = mr;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 for (int r = 0; r < _cur_covered_regions; r += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
185 if (r != self) {
a61af66fc99e Initial load
duke
parents:
diff changeset
186 result = result.minus(_committed[r]);
a61af66fc99e Initial load
duke
parents:
diff changeset
187 }
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189 // Never include the guard page.
a61af66fc99e Initial load
duke
parents:
diff changeset
190 result = result.minus(_guard_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
191 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 void CardTableModRefBS::resize_covered_region(MemRegion new_region) {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 // We don't change the start of a region, only the end.
a61af66fc99e Initial load
duke
parents:
diff changeset
196 assert(_whole_heap.contains(new_region),
a61af66fc99e Initial load
duke
parents:
diff changeset
197 "attempt to cover area not in reserved area");
a61af66fc99e Initial load
duke
parents:
diff changeset
198 debug_only(verify_guard();)
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
199 // collided is true if the expansion would push into another committed region
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
200 debug_only(bool collided = false;)
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
201 int const ind = find_covering_region_by_base(new_region.start());
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
202 MemRegion const old_region = _covered[ind];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
203 assert(old_region.start() == new_region.start(), "just checking");
a61af66fc99e Initial load
duke
parents:
diff changeset
204 if (new_region.word_size() != old_region.word_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
205 // Commit new or uncommit old pages, if necessary.
a61af66fc99e Initial load
duke
parents:
diff changeset
206 MemRegion cur_committed = _committed[ind];
a61af66fc99e Initial load
duke
parents:
diff changeset
207 // Extend the end of this _commited region
a61af66fc99e Initial load
duke
parents:
diff changeset
208 // to cover the end of any lower _committed regions.
a61af66fc99e Initial load
duke
parents:
diff changeset
209 // This forms overlapping regions, but never interior regions.
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
210 HeapWord* const max_prev_end = largest_prev_committed_end(ind);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
211 if (max_prev_end > cur_committed.end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
212 cur_committed.set_end(max_prev_end);
a61af66fc99e Initial load
duke
parents:
diff changeset
213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
214 // Align the end up to a page size (starts are already aligned).
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
215 jbyte* const new_end = byte_after(new_region.last());
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
216 HeapWord* new_end_aligned =
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
217 (HeapWord*) align_size_up((uintptr_t)new_end, _page_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
218 assert(new_end_aligned >= (HeapWord*) new_end,
a61af66fc99e Initial load
duke
parents:
diff changeset
219 "align up, but less");
581
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
220 // Check the other regions (excludes "ind") to ensure that
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
221 // the new_end_aligned does not intrude onto the committed
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
222 // space of another region.
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
223 int ri = 0;
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
224 for (ri = 0; ri < _cur_covered_regions; ri++) {
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
225 if (ri != ind) {
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
226 if (_committed[ri].contains(new_end_aligned)) {
581
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
227 // The prior check included in the assert
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
228 // (new_end_aligned >= _committed[ri].start())
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
229 // is redundant with the "contains" test.
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
230 // Any region containing the new end
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
231 // should start at or beyond the region found (ind)
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
232 // for the new end (committed regions are not expected to
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
233 // be proper subsets of other committed regions).
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
234 assert(_committed[ri].start() >= _committed[ind].start(),
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
235 "New end of committed region is inconsistent");
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
236 new_end_aligned = _committed[ri].start();
581
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
237 // new_end_aligned can be equal to the start of its
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
238 // committed region (i.e., of "ind") if a second
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
239 // region following "ind" also start at the same location
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
240 // as "ind".
9e5a6ed08fc9 6786346: intermittent Internal Error (src/share/vm/memory/cardTableModRefBS.cpp:226)
jmasa
parents: 489
diff changeset
241 assert(new_end_aligned >= _committed[ind].start(),
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
242 "New end of committed region is before start");
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
243 debug_only(collided = true;)
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
244 // Should only collide with 1 region
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
245 break;
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
246 }
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
247 }
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
248 }
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
249 #ifdef ASSERT
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
250 for (++ri; ri < _cur_covered_regions; ri++) {
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
251 assert(!_committed[ri].contains(new_end_aligned),
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
252 "New end of committed region is in a second committed region");
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
253 }
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
254 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // The guard page is always committed and should not be committed over.
887
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
256 // "guarded" is used for assertion checking below and recalls the fact
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
257 // that the would-be end of the new committed region would have
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
258 // penetrated the guard page.
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
259 HeapWord* new_end_for_commit = new_end_aligned;
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
260
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
261 DEBUG_ONLY(bool guarded = false;)
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
262 if (new_end_for_commit > _guard_region.start()) {
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
263 new_end_for_commit = _guard_region.start();
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
264 DEBUG_ONLY(guarded = true;)
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
265 }
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
266
0
a61af66fc99e Initial load
duke
parents:
diff changeset
267 if (new_end_for_commit > cur_committed.end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
268 // Must commit new pages.
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
269 MemRegion const new_committed =
0
a61af66fc99e Initial load
duke
parents:
diff changeset
270 MemRegion(cur_committed.end(), new_end_for_commit);
a61af66fc99e Initial load
duke
parents:
diff changeset
271
a61af66fc99e Initial load
duke
parents:
diff changeset
272 assert(!new_committed.is_empty(), "Region should not be empty here");
a61af66fc99e Initial load
duke
parents:
diff changeset
273 if (!os::commit_memory((char*)new_committed.start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
274 new_committed.byte_size(), _page_size)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
275 // Do better than this for Merlin
a61af66fc99e Initial load
duke
parents:
diff changeset
276 vm_exit_out_of_memory(new_committed.byte_size(),
a61af66fc99e Initial load
duke
parents:
diff changeset
277 "card table expansion");
a61af66fc99e Initial load
duke
parents:
diff changeset
278 }
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // Use new_end_aligned (as opposed to new_end_for_commit) because
a61af66fc99e Initial load
duke
parents:
diff changeset
280 // the cur_committed region may include the guard region.
a61af66fc99e Initial load
duke
parents:
diff changeset
281 } else if (new_end_aligned < cur_committed.end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // Must uncommit pages.
6
73e96e5c30df 6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents: 0
diff changeset
283 MemRegion const uncommit_region =
0
a61af66fc99e Initial load
duke
parents:
diff changeset
284 committed_unique_to_self(ind, MemRegion(new_end_aligned,
a61af66fc99e Initial load
duke
parents:
diff changeset
285 cur_committed.end()));
a61af66fc99e Initial load
duke
parents:
diff changeset
286 if (!uncommit_region.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (!os::uncommit_memory((char*)uncommit_region.start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
288 uncommit_region.byte_size())) {
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
289 assert(false, "Card table contraction failed");
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
290 // The call failed so don't change the end of the
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
291 // committed region. This is better than taking the
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
292 // VM down.
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
293 new_end_aligned = _committed[ind].end();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
297 // In any case, we can reset the end of the current committed entry.
a61af66fc99e Initial load
duke
parents:
diff changeset
298 _committed[ind].set_end(new_end_aligned);
a61af66fc99e Initial load
duke
parents:
diff changeset
299
a61af66fc99e Initial load
duke
parents:
diff changeset
300 // The default of 0 is not necessarily clean cards.
a61af66fc99e Initial load
duke
parents:
diff changeset
301 jbyte* entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
302 if (old_region.last() < _whole_heap.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
303 entry = byte_for(_whole_heap.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
304 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 entry = byte_after(old_region.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
306 }
489
2494ab195856 6653214: MemoryPoolMXBean.setUsageThreshold() does not support large heap sizes.
swamyv
parents: 356
diff changeset
307 assert(index_for(new_region.last()) < _guard_index,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
308 "The guard card will be overwritten");
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
309 // This line commented out cleans the newly expanded region and
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
310 // not the aligned up expanded region.
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
311 // jbyte* const end = byte_after(new_region.last());
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
312 jbyte* const end = (jbyte*) new_end_for_commit;
887
ff004bcd2596 6843292: "Expect to be beyond new region unless impacting another region" assertion too strong
jmasa
parents: 628
diff changeset
313 assert((end >= byte_after(new_region.last())) || collided || guarded,
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
314 "Expect to be beyond new region unless impacting another region");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
315 // do nothing if we resized downward.
208
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
316 #ifdef ASSERT
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
317 for (int ri = 0; ri < _cur_covered_regions; ri++) {
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
318 if (ri != ind) {
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
319 // The end of the new committed region should not
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
320 // be in any existing region unless it matches
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
321 // the start of the next region.
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
322 assert(!_committed[ri].contains(end) ||
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
323 (_committed[ri].start() == (HeapWord*) end),
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
324 "Overlapping committed regions");
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
325 }
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
326 }
35ca13d63fe8 6688799: Second fix for Guarantee failure "Unexpected dirty card found"
jmasa
parents: 113
diff changeset
327 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
328 if (entry < end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
329 memset(entry, clean_card, pointer_delta(end, entry, sizeof(jbyte)));
a61af66fc99e Initial load
duke
parents:
diff changeset
330 }
a61af66fc99e Initial load
duke
parents:
diff changeset
331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
332 // In any case, the covered size changes.
a61af66fc99e Initial load
duke
parents:
diff changeset
333 _covered[ind].set_word_size(new_region.word_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
334 if (TraceCardTableModRefBS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
335 gclog_or_tty->print_cr("CardTableModRefBS::resize_covered_region: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
336 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
337 " _covered[%d].start(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
338 " _covered[%d].last(): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
339 ind, _covered[ind].start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
340 ind, _covered[ind].last());
a61af66fc99e Initial load
duke
parents:
diff changeset
341 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
342 " _committed[%d].start(): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
343 " _committed[%d].last(): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
344 ind, _committed[ind].start(),
a61af66fc99e Initial load
duke
parents:
diff changeset
345 ind, _committed[ind].last());
a61af66fc99e Initial load
duke
parents:
diff changeset
346 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
347 " byte_for(start): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
348 " byte_for(last): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
349 byte_for(_covered[ind].start()),
a61af66fc99e Initial load
duke
parents:
diff changeset
350 byte_for(_covered[ind].last()));
a61af66fc99e Initial load
duke
parents:
diff changeset
351 gclog_or_tty->print_cr(" "
a61af66fc99e Initial load
duke
parents:
diff changeset
352 " addr_for(start): " INTPTR_FORMAT
a61af66fc99e Initial load
duke
parents:
diff changeset
353 " addr_for(last): " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
354 addr_for((jbyte*) _committed[ind].start()),
a61af66fc99e Initial load
duke
parents:
diff changeset
355 addr_for((jbyte*) _committed[ind].last()));
a61af66fc99e Initial load
duke
parents:
diff changeset
356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
357 debug_only(verify_guard();)
a61af66fc99e Initial load
duke
parents:
diff changeset
358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
359
a61af66fc99e Initial load
duke
parents:
diff changeset
360 // Note that these versions are precise! The scanning code has to handle the
a61af66fc99e Initial load
duke
parents:
diff changeset
361 // fact that the write barrier may be either precise or imprecise.
a61af66fc99e Initial load
duke
parents:
diff changeset
362
113
ba764ed4b6f2 6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents: 46
diff changeset
363 void CardTableModRefBS::write_ref_field_work(void* field, oop newVal) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
364 inline_write_ref_field(field, newVal);
a61af66fc99e Initial load
duke
parents:
diff changeset
365 }
a61af66fc99e Initial load
duke
parents:
diff changeset
366
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
367 /*
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
368 Claimed and deferred bits are used together in G1 during the evacuation
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
369 pause. These bits can have the following state transitions:
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
370 1. The claimed bit can be put over any other card state. Except that
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
371 the "dirty -> dirty and claimed" transition is checked for in
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
372 G1 code and is not used.
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
373 2. Deferred bit can be set only if the previous state of the card
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
374 was either clean or claimed. mark_card_deferred() is wait-free.
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
375 We do not care if the operation is be successful because if
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
376 it does not it will only result in duplicate entry in the update
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
377 buffer because of the "cache-miss". So it's not worth spinning.
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
378 */
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
379
0
a61af66fc99e Initial load
duke
parents:
diff changeset
380
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
381 bool CardTableModRefBS::claim_card(size_t card_index) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
382 jbyte val = _byte_map[card_index];
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
383 assert(val != dirty_card_val(), "Shouldn't claim a dirty card");
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
384 while (val == clean_card_val() ||
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
385 (val & (clean_card_mask_val() | claimed_card_val())) != claimed_card_val()) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
386 jbyte new_val = val;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
387 if (val == clean_card_val()) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
388 new_val = (jbyte)claimed_card_val();
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
389 } else {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
390 new_val = val | (jbyte)claimed_card_val();
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
391 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
392 jbyte res = Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
393 if (res == val) {
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
394 return true;
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
395 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
396 val = res;
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
397 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
398 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
399 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
400
616
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
401 bool CardTableModRefBS::mark_card_deferred(size_t card_index) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
402 jbyte val = _byte_map[card_index];
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
403 // It's already processed
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
404 if ((val & (clean_card_mask_val() | deferred_card_val())) == deferred_card_val()) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
405 return false;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
406 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
407 // Cached bit can be installed either on a clean card or on a claimed card.
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
408 jbyte new_val = val;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
409 if (val == clean_card_val()) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
410 new_val = (jbyte)deferred_card_val();
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
411 } else {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
412 if (val & claimed_card_val()) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
413 new_val = val | (jbyte)deferred_card_val();
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
414 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
415 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
416 if (new_val != val) {
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
417 Atomic::cmpxchg(new_val, &_byte_map[card_index], val);
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
418 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
419 return true;
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
420 }
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
421
4f360ec815ba 6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents: 581
diff changeset
422
0
a61af66fc99e Initial load
duke
parents:
diff changeset
423 void CardTableModRefBS::non_clean_card_iterate(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
424 MemRegion mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
425 DirtyCardToOopClosure* dcto_cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
426 MemRegionClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
427 bool clear) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 if (!mr.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 int n_threads = SharedHeap::heap()->n_par_threads();
a61af66fc99e Initial load
duke
parents:
diff changeset
430 if (n_threads > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
431 #ifndef SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
432 par_non_clean_card_iterate_work(sp, mr, dcto_cl, cl, clear, n_threads);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 #else // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
434 fatal("Parallel gc not supported here.");
a61af66fc99e Initial load
duke
parents:
diff changeset
435 #endif // SERIALGC
a61af66fc99e Initial load
duke
parents:
diff changeset
436 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 non_clean_card_iterate_work(mr, cl, clear);
a61af66fc99e Initial load
duke
parents:
diff changeset
438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // NOTE: For this to work correctly, it is important that
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // we look for non-clean cards below (so as to catch those
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // marked precleaned), rather than look explicitly for dirty
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // cards (and miss those marked precleaned). In that sense,
a61af66fc99e Initial load
duke
parents:
diff changeset
446 // the name precleaned is currently somewhat of a misnomer.
a61af66fc99e Initial load
duke
parents:
diff changeset
447 void CardTableModRefBS::non_clean_card_iterate_work(MemRegion mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
448 MemRegionClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
449 bool clear) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // Figure out whether we have to worry about parallelism.
a61af66fc99e Initial load
duke
parents:
diff changeset
451 bool is_par = (SharedHeap::heap()->n_par_threads() > 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
452 for (int i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 MemRegion mri = mr.intersection(_covered[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
454 if (mri.word_size() > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 jbyte* cur_entry = byte_for(mri.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
456 jbyte* limit = byte_for(mri.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
457 while (cur_entry >= limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
458 jbyte* next_entry = cur_entry - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
459 if (*cur_entry != clean_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
460 size_t non_clean_cards = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Should the next card be included in this range of dirty cards.
a61af66fc99e Initial load
duke
parents:
diff changeset
462 while (next_entry >= limit && *next_entry != clean_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 non_clean_cards++;
a61af66fc99e Initial load
duke
parents:
diff changeset
464 cur_entry = next_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
465 next_entry--;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // The memory region may not be on a card boundary. So that
a61af66fc99e Initial load
duke
parents:
diff changeset
468 // objects beyond the end of the region are not processed, make
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // cur_cards precise with regard to the end of the memory region.
a61af66fc99e Initial load
duke
parents:
diff changeset
470 MemRegion cur_cards(addr_for(cur_entry),
a61af66fc99e Initial load
duke
parents:
diff changeset
471 non_clean_cards * card_size_in_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
472 MemRegion dirty_region = cur_cards.intersection(mri);
a61af66fc99e Initial load
duke
parents:
diff changeset
473 if (clear) {
a61af66fc99e Initial load
duke
parents:
diff changeset
474 for (size_t i = 0; i < non_clean_cards; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // Clean the dirty cards (but leave the other non-clean
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // alone.) If parallel, do the cleaning atomically.
a61af66fc99e Initial load
duke
parents:
diff changeset
477 jbyte cur_entry_val = cur_entry[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
478 if (card_is_dirty_wrt_gen_iter(cur_entry_val)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
479 if (is_par) {
a61af66fc99e Initial load
duke
parents:
diff changeset
480 jbyte res = Atomic::cmpxchg(clean_card, &cur_entry[i], cur_entry_val);
a61af66fc99e Initial load
duke
parents:
diff changeset
481 assert(res != clean_card,
a61af66fc99e Initial load
duke
parents:
diff changeset
482 "Dirty card mysteriously cleaned");
a61af66fc99e Initial load
duke
parents:
diff changeset
483 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 cur_entry[i] = clean_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
485 }
a61af66fc99e Initial load
duke
parents:
diff changeset
486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
488 }
a61af66fc99e Initial load
duke
parents:
diff changeset
489 cl->do_MemRegion(dirty_region);
a61af66fc99e Initial load
duke
parents:
diff changeset
490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
491 cur_entry = next_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
494 }
a61af66fc99e Initial load
duke
parents:
diff changeset
495 }
a61af66fc99e Initial load
duke
parents:
diff changeset
496
a61af66fc99e Initial load
duke
parents:
diff changeset
497 void CardTableModRefBS::mod_oop_in_space_iterate(Space* sp,
a61af66fc99e Initial load
duke
parents:
diff changeset
498 OopClosure* cl,
a61af66fc99e Initial load
duke
parents:
diff changeset
499 bool clear,
a61af66fc99e Initial load
duke
parents:
diff changeset
500 bool before_save_marks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
501 // Note that dcto_cl is resource-allocated, so there is no
a61af66fc99e Initial load
duke
parents:
diff changeset
502 // corresponding "delete".
a61af66fc99e Initial load
duke
parents:
diff changeset
503 DirtyCardToOopClosure* dcto_cl = sp->new_dcto_cl(cl, precision());
a61af66fc99e Initial load
duke
parents:
diff changeset
504 MemRegion used_mr;
a61af66fc99e Initial load
duke
parents:
diff changeset
505 if (before_save_marks) {
a61af66fc99e Initial load
duke
parents:
diff changeset
506 used_mr = sp->used_region_at_save_marks();
a61af66fc99e Initial load
duke
parents:
diff changeset
507 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
508 used_mr = sp->used_region();
a61af66fc99e Initial load
duke
parents:
diff changeset
509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
510 non_clean_card_iterate(sp, used_mr, dcto_cl, dcto_cl, clear);
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 void CardTableModRefBS::dirty_MemRegion(MemRegion mr) {
1091
6aa7255741f3 6906727: UseCompressedOops: some card-marking fixes related to object arrays
ysr
parents: 940
diff changeset
514 assert((HeapWord*)align_size_down((uintptr_t)mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
6aa7255741f3 6906727: UseCompressedOops: some card-marking fixes related to object arrays
ysr
parents: 940
diff changeset
515 assert((HeapWord*)align_size_up ((uintptr_t)mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
516 jbyte* cur = byte_for(mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
517 jbyte* last = byte_after(mr.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
518 while (cur < last) {
a61af66fc99e Initial load
duke
parents:
diff changeset
519 *cur = dirty_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
520 cur++;
a61af66fc99e Initial load
duke
parents:
diff changeset
521 }
a61af66fc99e Initial load
duke
parents:
diff changeset
522 }
a61af66fc99e Initial load
duke
parents:
diff changeset
523
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
524 void CardTableModRefBS::invalidate(MemRegion mr, bool whole_heap) {
1091
6aa7255741f3 6906727: UseCompressedOops: some card-marking fixes related to object arrays
ysr
parents: 940
diff changeset
525 assert((HeapWord*)align_size_down((uintptr_t)mr.start(), HeapWordSize) == mr.start(), "Unaligned start");
6aa7255741f3 6906727: UseCompressedOops: some card-marking fixes related to object arrays
ysr
parents: 940
diff changeset
526 assert((HeapWord*)align_size_up ((uintptr_t)mr.end(), HeapWordSize) == mr.end(), "Unaligned end" );
0
a61af66fc99e Initial load
duke
parents:
diff changeset
527 for (int i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
528 MemRegion mri = mr.intersection(_covered[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
529 if (!mri.is_empty()) dirty_MemRegion(mri);
a61af66fc99e Initial load
duke
parents:
diff changeset
530 }
a61af66fc99e Initial load
duke
parents:
diff changeset
531 }
a61af66fc99e Initial load
duke
parents:
diff changeset
532
a61af66fc99e Initial load
duke
parents:
diff changeset
533 void CardTableModRefBS::clear_MemRegion(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 // Be conservative: only clean cards entirely contained within the
a61af66fc99e Initial load
duke
parents:
diff changeset
535 // region.
a61af66fc99e Initial load
duke
parents:
diff changeset
536 jbyte* cur;
a61af66fc99e Initial load
duke
parents:
diff changeset
537 if (mr.start() == _whole_heap.start()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
538 cur = byte_for(mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
539 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 assert(mr.start() > _whole_heap.start(), "mr is not covered.");
a61af66fc99e Initial load
duke
parents:
diff changeset
541 cur = byte_after(mr.start() - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 jbyte* last = byte_after(mr.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
544 memset(cur, clean_card, pointer_delta(last, cur, sizeof(jbyte)));
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546
a61af66fc99e Initial load
duke
parents:
diff changeset
547 void CardTableModRefBS::clear(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
548 for (int i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
549 MemRegion mri = mr.intersection(_covered[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
550 if (!mri.is_empty()) clear_MemRegion(mri);
a61af66fc99e Initial load
duke
parents:
diff changeset
551 }
a61af66fc99e Initial load
duke
parents:
diff changeset
552 }
a61af66fc99e Initial load
duke
parents:
diff changeset
553
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
554 void CardTableModRefBS::dirty(MemRegion mr) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
555 jbyte* first = byte_for(mr.start());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
556 jbyte* last = byte_after(mr.last());
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
557 memset(first, dirty_card, last-first);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
558 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
559
0
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // NOTES:
a61af66fc99e Initial load
duke
parents:
diff changeset
561 // (1) Unlike mod_oop_in_space_iterate() above, dirty_card_iterate()
a61af66fc99e Initial load
duke
parents:
diff changeset
562 // iterates over dirty cards ranges in increasing address order.
a61af66fc99e Initial load
duke
parents:
diff changeset
563 void CardTableModRefBS::dirty_card_iterate(MemRegion mr,
a61af66fc99e Initial load
duke
parents:
diff changeset
564 MemRegionClosure* cl) {
a61af66fc99e Initial load
duke
parents:
diff changeset
565 for (int i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
566 MemRegion mri = mr.intersection(_covered[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
567 if (!mri.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
568 jbyte *cur_entry, *next_entry, *limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
569 for (cur_entry = byte_for(mri.start()), limit = byte_for(mri.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
570 cur_entry <= limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
571 cur_entry = next_entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
572 next_entry = cur_entry + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
573 if (*cur_entry == dirty_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 size_t dirty_cards;
a61af66fc99e Initial load
duke
parents:
diff changeset
575 // Accumulate maximal dirty card range, starting at cur_entry
a61af66fc99e Initial load
duke
parents:
diff changeset
576 for (dirty_cards = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
577 next_entry <= limit && *next_entry == dirty_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
578 dirty_cards++, next_entry++);
a61af66fc99e Initial load
duke
parents:
diff changeset
579 MemRegion cur_cards(addr_for(cur_entry),
a61af66fc99e Initial load
duke
parents:
diff changeset
580 dirty_cards*card_size_in_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
581 cl->do_MemRegion(cur_cards);
a61af66fc99e Initial load
duke
parents:
diff changeset
582 }
a61af66fc99e Initial load
duke
parents:
diff changeset
583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
584 }
a61af66fc99e Initial load
duke
parents:
diff changeset
585 }
a61af66fc99e Initial load
duke
parents:
diff changeset
586 }
a61af66fc99e Initial load
duke
parents:
diff changeset
587
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
588 MemRegion CardTableModRefBS::dirty_card_range_after_reset(MemRegion mr,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
589 bool reset,
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
590 int reset_val) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
591 for (int i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
592 MemRegion mri = mr.intersection(_covered[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
593 if (!mri.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
594 jbyte* cur_entry, *next_entry, *limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
595 for (cur_entry = byte_for(mri.start()), limit = byte_for(mri.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
596 cur_entry <= limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
597 cur_entry = next_entry) {
a61af66fc99e Initial load
duke
parents:
diff changeset
598 next_entry = cur_entry + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
599 if (*cur_entry == dirty_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
600 size_t dirty_cards;
a61af66fc99e Initial load
duke
parents:
diff changeset
601 // Accumulate maximal dirty card range, starting at cur_entry
a61af66fc99e Initial load
duke
parents:
diff changeset
602 for (dirty_cards = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
603 next_entry <= limit && *next_entry == dirty_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
604 dirty_cards++, next_entry++);
a61af66fc99e Initial load
duke
parents:
diff changeset
605 MemRegion cur_cards(addr_for(cur_entry),
a61af66fc99e Initial load
duke
parents:
diff changeset
606 dirty_cards*card_size_in_words);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
607 if (reset) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
608 for (size_t i = 0; i < dirty_cards; i++) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
609 cur_entry[i] = reset_val;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 113
diff changeset
610 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612 return cur_cards;
a61af66fc99e Initial load
duke
parents:
diff changeset
613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
614 }
a61af66fc99e Initial load
duke
parents:
diff changeset
615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
617 return MemRegion(mr.end(), mr.end());
a61af66fc99e Initial load
duke
parents:
diff changeset
618 }
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // Set all the dirty cards in the given region to "precleaned" state.
a61af66fc99e Initial load
duke
parents:
diff changeset
621 void CardTableModRefBS::preclean_dirty_cards(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
622 for (int i = 0; i < _cur_covered_regions; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 MemRegion mri = mr.intersection(_covered[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
624 if (!mri.is_empty()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 jbyte *cur_entry, *limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
626 for (cur_entry = byte_for(mri.start()), limit = byte_for(mri.last());
a61af66fc99e Initial load
duke
parents:
diff changeset
627 cur_entry <= limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 cur_entry++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 if (*cur_entry == dirty_card) {
a61af66fc99e Initial load
duke
parents:
diff changeset
630 *cur_entry = precleaned_card;
a61af66fc99e Initial load
duke
parents:
diff changeset
631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
633 }
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 uintx CardTableModRefBS::ct_max_alignment_constraint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
638 return card_size * os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641 void CardTableModRefBS::verify_guard() {
a61af66fc99e Initial load
duke
parents:
diff changeset
642 // For product build verification
a61af66fc99e Initial load
duke
parents:
diff changeset
643 guarantee(_byte_map[_guard_index] == last_card,
a61af66fc99e Initial load
duke
parents:
diff changeset
644 "card table guard has been modified");
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 void CardTableModRefBS::verify() {
a61af66fc99e Initial load
duke
parents:
diff changeset
648 verify_guard();
a61af66fc99e Initial load
duke
parents:
diff changeset
649 }
a61af66fc99e Initial load
duke
parents:
diff changeset
650
a61af66fc99e Initial load
duke
parents:
diff changeset
651 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
652 class GuaranteeNotModClosure: public MemRegionClosure {
a61af66fc99e Initial load
duke
parents:
diff changeset
653 CardTableModRefBS* _ct;
a61af66fc99e Initial load
duke
parents:
diff changeset
654 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
655 GuaranteeNotModClosure(CardTableModRefBS* ct) : _ct(ct) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
656 void do_MemRegion(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
657 jbyte* entry = _ct->byte_for(mr.start());
a61af66fc99e Initial load
duke
parents:
diff changeset
658 guarantee(*entry != CardTableModRefBS::clean_card,
a61af66fc99e Initial load
duke
parents:
diff changeset
659 "Dirty card in region that should be clean");
a61af66fc99e Initial load
duke
parents:
diff changeset
660 }
a61af66fc99e Initial load
duke
parents:
diff changeset
661 };
a61af66fc99e Initial load
duke
parents:
diff changeset
662
a61af66fc99e Initial load
duke
parents:
diff changeset
663 void CardTableModRefBS::verify_clean_region(MemRegion mr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
664 GuaranteeNotModClosure blk(this);
a61af66fc99e Initial load
duke
parents:
diff changeset
665 non_clean_card_iterate_work(mr, &blk, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
666 }
940
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
667
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
668 // To verify a MemRegion is entirely dirty this closure is passed to
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
669 // dirty_card_iterate. If the region is dirty do_MemRegion will be
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
670 // invoked only once with a MemRegion equal to the one being
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
671 // verified.
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
672 class GuaranteeDirtyClosure: public MemRegionClosure {
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
673 CardTableModRefBS* _ct;
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
674 MemRegion _mr;
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
675 bool _result;
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
676 public:
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
677 GuaranteeDirtyClosure(CardTableModRefBS* ct, MemRegion mr)
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
678 : _ct(ct), _mr(mr), _result(false) {}
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
679 void do_MemRegion(MemRegion mr) {
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
680 _result = _mr.equals(mr);
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
681 }
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
682 bool result() const { return _result; }
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
683 };
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
684
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
685 void CardTableModRefBS::verify_dirty_region(MemRegion mr) {
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
686 GuaranteeDirtyClosure blk(this, mr);
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
687 dirty_card_iterate(mr, &blk);
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
688 guarantee(blk.result(), "Non-dirty cards in region that should be dirty");
8624da129f0b 6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents: 887
diff changeset
689 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
690 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
691
a61af66fc99e Initial load
duke
parents:
diff changeset
692 bool CardTableModRefBSForCTRS::card_will_be_scanned(jbyte cv) {
a61af66fc99e Initial load
duke
parents:
diff changeset
693 return
a61af66fc99e Initial load
duke
parents:
diff changeset
694 CardTableModRefBS::card_will_be_scanned(cv) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
695 _rs->is_prev_nonclean_card_val(cv);
a61af66fc99e Initial load
duke
parents:
diff changeset
696 };
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 bool CardTableModRefBSForCTRS::card_may_have_been_dirty(jbyte cv) {
a61af66fc99e Initial load
duke
parents:
diff changeset
699 return
a61af66fc99e Initial load
duke
parents:
diff changeset
700 cv != clean_card &&
a61af66fc99e Initial load
duke
parents:
diff changeset
701 (CardTableModRefBS::card_may_have_been_dirty(cv) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
702 CardTableRS::youngergen_may_have_been_dirty(cv));
a61af66fc99e Initial load
duke
parents:
diff changeset
703 };