author | mgerdin |
Tue, 24 Sep 2013 14:46:29 +0200 | |
changeset 20309 | 7445302daff6 |
parent 19994 | ca520adcee02 |
child 22551 | 9bf46d16dcc6 |
permissions | -rw-r--r-- |
17327 | 1 |
/* |
2 |
* Copyright (c) 2013, 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 |
#include "precompiled.hpp" |
|
26 |
#include "gc_implementation/g1/g1CardCounts.hpp" |
|
27 |
#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
|
28 |
#include "gc_implementation/g1/g1CollectorPolicy.hpp" |
|
29 |
#include "gc_implementation/g1/g1GCPhaseTimes.hpp" |
|
30 |
#include "memory/cardTableModRefBS.hpp" |
|
31 |
#include "services/memTracker.hpp" |
|
32 |
#include "utilities/copy.hpp" |
|
33 |
||
34 |
void G1CardCounts::clear_range(size_t from_card_num, size_t to_card_num) { |
|
35 |
if (has_count_table()) { |
|
19994
ca520adcee02
8024671: G1 generates assert error messages in product builds
shade
parents:
18496
diff
changeset
|
36 |
assert(from_card_num >= 0 && from_card_num < _committed_max_card_num, |
ca520adcee02
8024671: G1 generates assert error messages in product builds
shade
parents:
18496
diff
changeset
|
37 |
err_msg("from card num out of range: "SIZE_FORMAT, from_card_num)); |
17327 | 38 |
assert(from_card_num < to_card_num, |
39 |
err_msg("Wrong order? from: " SIZE_FORMAT ", to: "SIZE_FORMAT, |
|
40 |
from_card_num, to_card_num)); |
|
41 |
assert(to_card_num <= _committed_max_card_num, |
|
42 |
err_msg("to card num out of range: " |
|
43 |
"to: "SIZE_FORMAT ", " |
|
44 |
"max: "SIZE_FORMAT, |
|
45 |
to_card_num, _committed_max_card_num)); |
|
46 |
||
47 |
to_card_num = MIN2(_committed_max_card_num, to_card_num); |
|
48 |
||
49 |
Copy::fill_to_bytes(&_card_counts[from_card_num], (to_card_num - from_card_num)); |
|
50 |
} |
|
51 |
} |
|
52 |
||
53 |
G1CardCounts::G1CardCounts(G1CollectedHeap *g1h): |
|
54 |
_g1h(g1h), _card_counts(NULL), |
|
55 |
_reserved_max_card_num(0), _committed_max_card_num(0), |
|
56 |
_committed_size(0) {} |
|
57 |
||
58 |
void G1CardCounts::initialize() { |
|
59 |
assert(_g1h->max_capacity() > 0, "initialization order"); |
|
60 |
assert(_g1h->capacity() == 0, "initialization order"); |
|
61 |
||
62 |
if (G1ConcRSHotCardLimit > 0) { |
|
63 |
// The max value we can store in the counts table is |
|
64 |
// max_jubyte. Guarantee the value of the hot |
|
65 |
// threshold limit is no more than this. |
|
66 |
guarantee(G1ConcRSHotCardLimit <= max_jubyte, "sanity"); |
|
67 |
||
20309 | 68 |
_ct_bs = _g1h->g1_barrier_set(); |
17327 | 69 |
_ct_bot = _ct_bs->byte_for_const(_g1h->reserved_region().start()); |
70 |
||
71 |
// Allocate/Reserve the counts table |
|
72 |
size_t reserved_bytes = _g1h->max_capacity(); |
|
73 |
_reserved_max_card_num = reserved_bytes >> CardTableModRefBS::card_shift; |
|
74 |
||
75 |
size_t reserved_size = _reserved_max_card_num * sizeof(jbyte); |
|
76 |
ReservedSpace rs(ReservedSpace::allocation_align_size_up(reserved_size)); |
|
77 |
if (!rs.is_reserved()) { |
|
78 |
warning("Could not reserve enough space for the card counts table"); |
|
79 |
guarantee(!has_reserved_count_table(), "should be NULL"); |
|
80 |
return; |
|
81 |
} |
|
82 |
||
83 |
MemTracker::record_virtual_memory_type((address)rs.base(), mtGC); |
|
84 |
||
85 |
_card_counts_storage.initialize(rs, 0); |
|
86 |
_card_counts = (jubyte*) _card_counts_storage.low(); |
|
87 |
} |
|
88 |
} |
|
89 |
||
90 |
void G1CardCounts::resize(size_t heap_capacity) { |
|
91 |
// Expand the card counts table to handle a heap with the given capacity. |
|
92 |
||
93 |
if (!has_reserved_count_table()) { |
|
94 |
// Don't expand if we failed to reserve the card counts table. |
|
95 |
return; |
|
96 |
} |
|
97 |
||
98 |
assert(_committed_size == |
|
99 |
ReservedSpace::allocation_align_size_up(_committed_size), |
|
100 |
err_msg("Unaligned? committed_size: " SIZE_FORMAT, _committed_size)); |
|
101 |
||
17394
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
102 |
// Verify that the committed space for the card counts matches our |
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
103 |
// committed max card num. Note for some allocation alignments, the |
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
104 |
// amount of space actually committed for the counts table will be able |
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
105 |
// to span more cards than the number spanned by the maximum heap. |
17327 | 106 |
size_t prev_committed_size = _committed_size; |
17394
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
107 |
size_t prev_committed_card_num = committed_to_card_num(prev_committed_size); |
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
108 |
|
17327 | 109 |
assert(prev_committed_card_num == _committed_max_card_num, |
110 |
err_msg("Card mismatch: " |
|
111 |
"prev: " SIZE_FORMAT ", " |
|
17394
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
112 |
"committed: "SIZE_FORMAT", " |
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
113 |
"reserved: "SIZE_FORMAT, |
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
114 |
prev_committed_card_num, _committed_max_card_num, _reserved_max_card_num)); |
17327 | 115 |
|
116 |
size_t new_size = (heap_capacity >> CardTableModRefBS::card_shift) * sizeof(jbyte); |
|
117 |
size_t new_committed_size = ReservedSpace::allocation_align_size_up(new_size); |
|
17394
156f30e1d09a
8014408: G1: crashes with assert assert(prev_committed_card_num == _committed_max_card_num) failed
johnc
parents:
17327
diff
changeset
|
118 |
size_t new_committed_card_num = committed_to_card_num(new_committed_size); |
17327 | 119 |
|
120 |
if (_committed_max_card_num < new_committed_card_num) { |
|
121 |
// we need to expand the backing store for the card counts |
|
122 |
size_t expand_size = new_committed_size - prev_committed_size; |
|
123 |
||
124 |
if (!_card_counts_storage.expand_by(expand_size)) { |
|
125 |
warning("Card counts table backing store commit failure"); |
|
126 |
return; |
|
127 |
} |
|
128 |
assert(_card_counts_storage.committed_size() == new_committed_size, |
|
129 |
"expansion commit failure"); |
|
130 |
||
131 |
_committed_size = new_committed_size; |
|
132 |
_committed_max_card_num = new_committed_card_num; |
|
133 |
||
134 |
clear_range(prev_committed_card_num, _committed_max_card_num); |
|
135 |
} |
|
136 |
} |
|
137 |
||
138 |
uint G1CardCounts::add_card_count(jbyte* card_ptr) { |
|
139 |
// Returns the number of times the card has been refined. |
|
140 |
// If we failed to reserve/commit the counts table, return 0. |
|
141 |
// If card_ptr is beyond the committed end of the counts table, |
|
142 |
// return 0. |
|
143 |
// Otherwise return the actual count. |
|
144 |
// Unless G1ConcRSHotCardLimit has been set appropriately, |
|
145 |
// returning 0 will result in the card being considered |
|
146 |
// cold and will be refined immediately. |
|
147 |
uint count = 0; |
|
148 |
if (has_count_table()) { |
|
149 |
size_t card_num = ptr_2_card_num(card_ptr); |
|
150 |
if (card_num < _committed_max_card_num) { |
|
151 |
count = (uint) _card_counts[card_num]; |
|
152 |
if (count < G1ConcRSHotCardLimit) { |
|
18496
78b3897aa229
8017070: G1: assert(_card_counts[card_num] <= G1ConcRSHotCardLimit) failed
johnc
parents:
17394
diff
changeset
|
153 |
_card_counts[card_num] = |
78b3897aa229
8017070: G1: assert(_card_counts[card_num] <= G1ConcRSHotCardLimit) failed
johnc
parents:
17394
diff
changeset
|
154 |
(jubyte)(MIN2((uintx)(_card_counts[card_num] + 1), G1ConcRSHotCardLimit)); |
17327 | 155 |
} |
156 |
} |
|
157 |
} |
|
158 |
return count; |
|
159 |
} |
|
160 |
||
161 |
bool G1CardCounts::is_hot(uint count) { |
|
162 |
return (count >= G1ConcRSHotCardLimit); |
|
163 |
} |
|
164 |
||
165 |
void G1CardCounts::clear_region(HeapRegion* hr) { |
|
166 |
assert(!hr->isHumongous(), "Should have been cleared"); |
|
167 |
if (has_count_table()) { |
|
168 |
HeapWord* bottom = hr->bottom(); |
|
169 |
||
170 |
// We use the last address in hr as hr could be the |
|
171 |
// last region in the heap. In which case trying to find |
|
172 |
// the card for hr->end() will be an OOB accesss to the |
|
173 |
// card table. |
|
174 |
HeapWord* last = hr->end() - 1; |
|
175 |
assert(_g1h->g1_committed().contains(last), |
|
176 |
err_msg("last not in committed: " |
|
177 |
"last: " PTR_FORMAT ", " |
|
178 |
"committed: [" PTR_FORMAT ", " PTR_FORMAT ")", |
|
179 |
last, |
|
180 |
_g1h->g1_committed().start(), |
|
181 |
_g1h->g1_committed().end())); |
|
182 |
||
183 |
const jbyte* from_card_ptr = _ct_bs->byte_for_const(bottom); |
|
184 |
const jbyte* last_card_ptr = _ct_bs->byte_for_const(last); |
|
185 |
||
186 |
#ifdef ASSERT |
|
187 |
HeapWord* start_addr = _ct_bs->addr_for(from_card_ptr); |
|
188 |
assert(start_addr == hr->bottom(), "alignment"); |
|
189 |
HeapWord* last_addr = _ct_bs->addr_for(last_card_ptr); |
|
190 |
assert((last_addr + CardTableModRefBS::card_size_in_words) == hr->end(), "alignment"); |
|
191 |
#endif // ASSERT |
|
192 |
||
193 |
// Clear the counts for the (exclusive) card range. |
|
194 |
size_t from_card_num = ptr_2_card_num(from_card_ptr); |
|
195 |
size_t to_card_num = ptr_2_card_num(last_card_ptr) + 1; |
|
196 |
clear_range(from_card_num, to_card_num); |
|
197 |
} |
|
198 |
} |
|
199 |
||
200 |
void G1CardCounts::clear_all() { |
|
201 |
assert(SafepointSynchronize::is_at_safepoint(), "don't call this otherwise"); |
|
202 |
clear_range((size_t)0, _committed_max_card_num); |
|
203 |
} |
|
204 |
||
205 |
G1CardCounts::~G1CardCounts() { |
|
206 |
if (has_reserved_count_table()) { |
|
207 |
_card_counts_storage.release(); |
|
208 |
} |
|
209 |
} |
|
210 |