Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 3919:4f41766176cf
7084509: G1: fix inconsistencies and mistakes in the young list target length calculations
Summary: Fixed inconsistencies and mistakes in the young list target length calculations so that a) the calculated target length is optimal (before, it was not), b) other parameters like max survivor size and max gc locker eden expansion are always consistent with the calculated target length (before, they were not always), and c) the resulting target length was always bound by desired min and max values (before, it was not).
Reviewed-by: brutisso, johnc
author | tonyp |
---|---|
date | Thu, 08 Sep 2011 05:16:49 -0400 |
parents | 05550041d664 |
children | af2ab04e0038 |
rev | line source |
---|---|
342 | 1 /* |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
342 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1547
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1547
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1547
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "code/icBuffer.hpp" | |
27 #include "gc_implementation/g1/bufferingOopClosure.hpp" | |
28 #include "gc_implementation/g1/concurrentG1Refine.hpp" | |
29 #include "gc_implementation/g1/concurrentG1RefineThread.hpp" | |
30 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp" | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
31 #include "gc_implementation/g1/g1AllocRegion.inline.hpp" |
1972 | 32 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
33 #include "gc_implementation/g1/g1CollectorPolicy.hpp" | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
34 #include "gc_implementation/g1/g1ErgoVerbose.hpp" |
1972 | 35 #include "gc_implementation/g1/g1MarkSweep.hpp" |
36 #include "gc_implementation/g1/g1OopClosures.inline.hpp" | |
37 #include "gc_implementation/g1/g1RemSet.inline.hpp" | |
38 #include "gc_implementation/g1/heapRegionRemSet.hpp" | |
39 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
40 #include "gc_implementation/g1/vm_operations_g1.hpp" | |
41 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
42 #include "memory/gcLocker.inline.hpp" | |
43 #include "memory/genOopClosures.inline.hpp" | |
44 #include "memory/generationSpec.hpp" | |
45 #include "oops/oop.inline.hpp" | |
46 #include "oops/oop.pcgc.inline.hpp" | |
47 #include "runtime/aprofiler.hpp" | |
48 #include "runtime/vmThread.hpp" | |
342 | 49 |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
50 size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
51 |
342 | 52 // turn it on so that the contents of the young list (scan-only / |
53 // to-be-collected) are printed at "strategic" points before / during | |
54 // / after the collection --- this is useful for debugging | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
55 #define YOUNG_LIST_VERBOSE 0 |
342 | 56 // CURRENT STATUS |
57 // This file is under construction. Search for "FIXME". | |
58 | |
59 // INVARIANTS/NOTES | |
60 // | |
61 // All allocation activity covered by the G1CollectedHeap interface is | |
1973 | 62 // serialized by acquiring the HeapLock. This happens in mem_allocate |
63 // and allocate_new_tlab, which are the "entry" points to the | |
64 // allocation code from the rest of the JVM. (Note that this does not | |
65 // apply to TLAB allocation, which is not part of this interface: it | |
66 // is done by clients of this interface.) | |
342 | 67 |
68 // Local to this file. | |
69 | |
70 class RefineCardTableEntryClosure: public CardTableEntryClosure { | |
71 SuspendibleThreadSet* _sts; | |
72 G1RemSet* _g1rs; | |
73 ConcurrentG1Refine* _cg1r; | |
74 bool _concurrent; | |
75 public: | |
76 RefineCardTableEntryClosure(SuspendibleThreadSet* sts, | |
77 G1RemSet* g1rs, | |
78 ConcurrentG1Refine* cg1r) : | |
79 _sts(sts), _g1rs(g1rs), _cg1r(cg1r), _concurrent(true) | |
80 {} | |
81 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
1705 | 82 bool oops_into_cset = _g1rs->concurrentRefineOneCard(card_ptr, worker_i, false); |
83 // This path is executed by the concurrent refine or mutator threads, | |
84 // concurrently, and so we do not care if card_ptr contains references | |
85 // that point into the collection set. | |
86 assert(!oops_into_cset, "should be"); | |
87 | |
342 | 88 if (_concurrent && _sts->should_yield()) { |
89 // Caller will actually yield. | |
90 return false; | |
91 } | |
92 // Otherwise, we finished successfully; return true. | |
93 return true; | |
94 } | |
95 void set_concurrent(bool b) { _concurrent = b; } | |
96 }; | |
97 | |
98 | |
99 class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { | |
100 int _calls; | |
101 G1CollectedHeap* _g1h; | |
102 CardTableModRefBS* _ctbs; | |
103 int _histo[256]; | |
104 public: | |
105 ClearLoggedCardTableEntryClosure() : | |
106 _calls(0) | |
107 { | |
108 _g1h = G1CollectedHeap::heap(); | |
109 _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); | |
110 for (int i = 0; i < 256; i++) _histo[i] = 0; | |
111 } | |
112 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
113 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { | |
114 _calls++; | |
115 unsigned char* ujb = (unsigned char*)card_ptr; | |
116 int ind = (int)(*ujb); | |
117 _histo[ind]++; | |
118 *card_ptr = -1; | |
119 } | |
120 return true; | |
121 } | |
122 int calls() { return _calls; } | |
123 void print_histo() { | |
124 gclog_or_tty->print_cr("Card table value histogram:"); | |
125 for (int i = 0; i < 256; i++) { | |
126 if (_histo[i] != 0) { | |
127 gclog_or_tty->print_cr(" %d: %d", i, _histo[i]); | |
128 } | |
129 } | |
130 } | |
131 }; | |
132 | |
133 class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { | |
134 int _calls; | |
135 G1CollectedHeap* _g1h; | |
136 CardTableModRefBS* _ctbs; | |
137 public: | |
138 RedirtyLoggedCardTableEntryClosure() : | |
139 _calls(0) | |
140 { | |
141 _g1h = G1CollectedHeap::heap(); | |
142 _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); | |
143 } | |
144 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
145 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { | |
146 _calls++; | |
147 *card_ptr = 0; | |
148 } | |
149 return true; | |
150 } | |
151 int calls() { return _calls; } | |
152 }; | |
153 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
154 class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
155 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
156 bool do_card_ptr(jbyte* card_ptr, int worker_i) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
157 *card_ptr = CardTableModRefBS::dirty_card_val(); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
158 return true; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
159 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
160 }; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
161 |
342 | 162 YoungList::YoungList(G1CollectedHeap* g1h) |
163 : _g1h(g1h), _head(NULL), | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
164 _length(0), |
342 | 165 _last_sampled_rs_lengths(0), |
545 | 166 _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) |
342 | 167 { |
168 guarantee( check_list_empty(false), "just making sure..." ); | |
169 } | |
170 | |
171 void YoungList::push_region(HeapRegion *hr) { | |
172 assert(!hr->is_young(), "should not already be young"); | |
173 assert(hr->get_next_young_region() == NULL, "cause it should!"); | |
174 | |
175 hr->set_next_young_region(_head); | |
176 _head = hr; | |
177 | |
178 hr->set_young(); | |
179 double yg_surv_rate = _g1h->g1_policy()->predict_yg_surv_rate((int)_length); | |
180 ++_length; | |
181 } | |
182 | |
183 void YoungList::add_survivor_region(HeapRegion* hr) { | |
545 | 184 assert(hr->is_survivor(), "should be flagged as survivor region"); |
342 | 185 assert(hr->get_next_young_region() == NULL, "cause it should!"); |
186 | |
187 hr->set_next_young_region(_survivor_head); | |
188 if (_survivor_head == NULL) { | |
545 | 189 _survivor_tail = hr; |
342 | 190 } |
191 _survivor_head = hr; | |
192 | |
193 ++_survivor_length; | |
194 } | |
195 | |
196 void YoungList::empty_list(HeapRegion* list) { | |
197 while (list != NULL) { | |
198 HeapRegion* next = list->get_next_young_region(); | |
199 list->set_next_young_region(NULL); | |
200 list->uninstall_surv_rate_group(); | |
201 list->set_not_young(); | |
202 list = next; | |
203 } | |
204 } | |
205 | |
206 void YoungList::empty_list() { | |
207 assert(check_list_well_formed(), "young list should be well formed"); | |
208 | |
209 empty_list(_head); | |
210 _head = NULL; | |
211 _length = 0; | |
212 | |
213 empty_list(_survivor_head); | |
214 _survivor_head = NULL; | |
545 | 215 _survivor_tail = NULL; |
342 | 216 _survivor_length = 0; |
217 | |
218 _last_sampled_rs_lengths = 0; | |
219 | |
220 assert(check_list_empty(false), "just making sure..."); | |
221 } | |
222 | |
223 bool YoungList::check_list_well_formed() { | |
224 bool ret = true; | |
225 | |
226 size_t length = 0; | |
227 HeapRegion* curr = _head; | |
228 HeapRegion* last = NULL; | |
229 while (curr != NULL) { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
230 if (!curr->is_young()) { |
342 | 231 gclog_or_tty->print_cr("### YOUNG REGION "PTR_FORMAT"-"PTR_FORMAT" " |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
232 "incorrectly tagged (y: %d, surv: %d)", |
342 | 233 curr->bottom(), curr->end(), |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
234 curr->is_young(), curr->is_survivor()); |
342 | 235 ret = false; |
236 } | |
237 ++length; | |
238 last = curr; | |
239 curr = curr->get_next_young_region(); | |
240 } | |
241 ret = ret && (length == _length); | |
242 | |
243 if (!ret) { | |
244 gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!"); | |
245 gclog_or_tty->print_cr("### list has %d entries, _length is %d", | |
246 length, _length); | |
247 } | |
248 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
249 return ret; |
342 | 250 } |
251 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
252 bool YoungList::check_list_empty(bool check_sample) { |
342 | 253 bool ret = true; |
254 | |
255 if (_length != 0) { | |
256 gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %d", | |
257 _length); | |
258 ret = false; | |
259 } | |
260 if (check_sample && _last_sampled_rs_lengths != 0) { | |
261 gclog_or_tty->print_cr("### YOUNG LIST has non-zero last sampled RS lengths"); | |
262 ret = false; | |
263 } | |
264 if (_head != NULL) { | |
265 gclog_or_tty->print_cr("### YOUNG LIST does not have a NULL head"); | |
266 ret = false; | |
267 } | |
268 if (!ret) { | |
269 gclog_or_tty->print_cr("### YOUNG LIST does not seem empty"); | |
270 } | |
271 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
272 return ret; |
342 | 273 } |
274 | |
275 void | |
276 YoungList::rs_length_sampling_init() { | |
277 _sampled_rs_lengths = 0; | |
278 _curr = _head; | |
279 } | |
280 | |
281 bool | |
282 YoungList::rs_length_sampling_more() { | |
283 return _curr != NULL; | |
284 } | |
285 | |
286 void | |
287 YoungList::rs_length_sampling_next() { | |
288 assert( _curr != NULL, "invariant" ); | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
289 size_t rs_length = _curr->rem_set()->occupied(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
290 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
291 _sampled_rs_lengths += rs_length; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
292 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
293 // The current region may not yet have been added to the |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
294 // incremental collection set (it gets added when it is |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
295 // retired as the current allocation region). |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
296 if (_curr->in_collection_set()) { |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
297 // Update the collection set policy information for this region |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
298 _g1h->g1_policy()->update_incremental_cset_info(_curr, rs_length); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
299 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
300 |
342 | 301 _curr = _curr->get_next_young_region(); |
302 if (_curr == NULL) { | |
303 _last_sampled_rs_lengths = _sampled_rs_lengths; | |
304 // gclog_or_tty->print_cr("last sampled RS lengths = %d", _last_sampled_rs_lengths); | |
305 } | |
306 } | |
307 | |
308 void | |
309 YoungList::reset_auxilary_lists() { | |
310 guarantee( is_empty(), "young list should be empty" ); | |
311 assert(check_list_well_formed(), "young list should be well formed"); | |
312 | |
313 // Add survivor regions to SurvRateGroup. | |
314 _g1h->g1_policy()->note_start_adding_survivor_regions(); | |
545 | 315 _g1h->g1_policy()->finished_recalculating_age_indexes(true /* is_survivors */); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
316 |
342 | 317 for (HeapRegion* curr = _survivor_head; |
318 curr != NULL; | |
319 curr = curr->get_next_young_region()) { | |
320 _g1h->g1_policy()->set_region_survivors(curr); | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
321 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
322 // The region is a non-empty survivor so let's add it to |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
323 // the incremental collection set for the next evacuation |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
324 // pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
325 _g1h->g1_policy()->add_region_to_incremental_cset_rhs(curr); |
342 | 326 } |
327 _g1h->g1_policy()->note_stop_adding_survivor_regions(); | |
328 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
329 _head = _survivor_head; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
330 _length = _survivor_length; |
342 | 331 if (_survivor_head != NULL) { |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
332 assert(_survivor_tail != NULL, "cause it shouldn't be"); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
333 assert(_survivor_length > 0, "invariant"); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
334 _survivor_tail->set_next_young_region(NULL); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
335 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
336 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
337 // Don't clear the survivor list handles until the start of |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
338 // the next evacuation pause - we need it in order to re-tag |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
339 // the survivor regions from this evacuation pause as 'young' |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
340 // at the start of the next. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
341 |
545 | 342 _g1h->g1_policy()->finished_recalculating_age_indexes(false /* is_survivors */); |
342 | 343 |
344 assert(check_list_well_formed(), "young list should be well formed"); | |
345 } | |
346 | |
347 void YoungList::print() { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
348 HeapRegion* lists[] = {_head, _survivor_head}; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
349 const char* names[] = {"YOUNG", "SURVIVOR"}; |
342 | 350 |
351 for (unsigned int list = 0; list < ARRAY_SIZE(lists); ++list) { | |
352 gclog_or_tty->print_cr("%s LIST CONTENTS", names[list]); | |
353 HeapRegion *curr = lists[list]; | |
354 if (curr == NULL) | |
355 gclog_or_tty->print_cr(" empty"); | |
356 while (curr != NULL) { | |
357 gclog_or_tty->print_cr(" [%08x-%08x], t: %08x, P: %08x, N: %08x, C: %08x, " | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
358 "age: %4d, y: %d, surv: %d", |
342 | 359 curr->bottom(), curr->end(), |
360 curr->top(), | |
361 curr->prev_top_at_mark_start(), | |
362 curr->next_top_at_mark_start(), | |
363 curr->top_at_conc_mark_count(), | |
364 curr->age_in_surv_rate_group_cond(), | |
365 curr->is_young(), | |
366 curr->is_survivor()); | |
367 curr = curr->get_next_young_region(); | |
368 } | |
369 } | |
370 | |
371 gclog_or_tty->print_cr(""); | |
372 } | |
373 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
374 void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
375 { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
376 // Claim the right to put the region on the dirty cards region list |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
377 // by installing a self pointer. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
378 HeapRegion* next = hr->get_next_dirty_cards_region(); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
379 if (next == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
380 HeapRegion* res = (HeapRegion*) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
381 Atomic::cmpxchg_ptr(hr, hr->next_dirty_cards_region_addr(), |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
382 NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
383 if (res == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
384 HeapRegion* head; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
385 do { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
386 // Put the region to the dirty cards region list. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
387 head = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
388 next = (HeapRegion*) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
389 Atomic::cmpxchg_ptr(hr, &_dirty_cards_region_list, head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
390 if (next == head) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
391 assert(hr->get_next_dirty_cards_region() == hr, |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
392 "hr->get_next_dirty_cards_region() != hr"); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
393 if (next == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
394 // The last region in the list points to itself. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
395 hr->set_next_dirty_cards_region(hr); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
396 } else { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
397 hr->set_next_dirty_cards_region(next); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
398 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
399 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
400 } while (next != head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
401 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
402 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
403 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
404 |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
405 HeapRegion* G1CollectedHeap::pop_dirty_cards_region() |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
406 { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
407 HeapRegion* head; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
408 HeapRegion* hr; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
409 do { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
410 head = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
411 if (head == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
412 return NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
413 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
414 HeapRegion* new_head = head->get_next_dirty_cards_region(); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
415 if (head == new_head) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
416 // The last region. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
417 new_head = NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
418 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
419 hr = (HeapRegion*)Atomic::cmpxchg_ptr(new_head, &_dirty_cards_region_list, |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
420 head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
421 } while (hr != head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
422 assert(hr != NULL, "invariant"); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
423 hr->set_next_dirty_cards_region(NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
424 return hr; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
425 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
426 |
342 | 427 void G1CollectedHeap::stop_conc_gc_threads() { |
794 | 428 _cg1r->stop(); |
342 | 429 _cmThread->stop(); |
430 } | |
431 | |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
432 #ifdef ASSERT |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
433 // A region is added to the collection set as it is retired |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
434 // so an address p can point to a region which will be in the |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
435 // collection set but has not yet been retired. This method |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
436 // therefore is only accurate during a GC pause after all |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
437 // regions have been retired. It is used for debugging |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
438 // to check if an nmethod has references to objects that can |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
439 // be move during a partial collection. Though it can be |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
440 // inaccurate, it is sufficient for G1 because the conservative |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
441 // implementation of is_scavengable() for G1 will indicate that |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
442 // all nmethods must be scanned during a partial collection. |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
443 bool G1CollectedHeap::is_in_partial_collection(const void* p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
444 HeapRegion* hr = heap_region_containing(p); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
445 return hr != NULL && hr->in_collection_set(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
446 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
447 #endif |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
448 |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
449 // Returns true if the reference points to an object that |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
450 // can move in an incremental collecction. |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
451 bool G1CollectedHeap::is_scavengable(const void* p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
452 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
453 G1CollectorPolicy* g1p = g1h->g1_policy(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
454 HeapRegion* hr = heap_region_containing(p); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
455 if (hr == NULL) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
456 // perm gen (or null) |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
457 return false; |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
458 } else { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
459 return !hr->isHumongous(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
460 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
461 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
462 |
342 | 463 void G1CollectedHeap::check_ct_logs_at_safepoint() { |
464 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
465 CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); | |
466 | |
467 // Count the dirty cards at the start. | |
468 CountNonCleanMemRegionClosure count1(this); | |
469 ct_bs->mod_card_iterate(&count1); | |
470 int orig_count = count1.n(); | |
471 | |
472 // First clear the logged cards. | |
473 ClearLoggedCardTableEntryClosure clear; | |
474 dcqs.set_closure(&clear); | |
475 dcqs.apply_closure_to_all_completed_buffers(); | |
476 dcqs.iterate_closure_all_threads(false); | |
477 clear.print_histo(); | |
478 | |
479 // Now ensure that there's no dirty cards. | |
480 CountNonCleanMemRegionClosure count2(this); | |
481 ct_bs->mod_card_iterate(&count2); | |
482 if (count2.n() != 0) { | |
483 gclog_or_tty->print_cr("Card table has %d entries; %d originally", | |
484 count2.n(), orig_count); | |
485 } | |
486 guarantee(count2.n() == 0, "Card table should be clean."); | |
487 | |
488 RedirtyLoggedCardTableEntryClosure redirty; | |
489 JavaThread::dirty_card_queue_set().set_closure(&redirty); | |
490 dcqs.apply_closure_to_all_completed_buffers(); | |
491 dcqs.iterate_closure_all_threads(false); | |
492 gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", | |
493 clear.calls(), orig_count); | |
494 guarantee(redirty.calls() == clear.calls(), | |
495 "Or else mechanism is broken."); | |
496 | |
497 CountNonCleanMemRegionClosure count3(this); | |
498 ct_bs->mod_card_iterate(&count3); | |
499 if (count3.n() != orig_count) { | |
500 gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.", | |
501 orig_count, count3.n()); | |
502 guarantee(count3.n() >= orig_count, "Should have restored them all."); | |
503 } | |
504 | |
505 JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); | |
506 } | |
507 | |
508 // Private class members. | |
509 | |
510 G1CollectedHeap* G1CollectedHeap::_g1h; | |
511 | |
512 // Private methods. | |
513 | |
2152 | 514 HeapRegion* |
2361 | 515 G1CollectedHeap::new_region_try_secondary_free_list() { |
2152 | 516 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
517 while (!_secondary_free_list.is_empty() || free_regions_coming()) { | |
518 if (!_secondary_free_list.is_empty()) { | |
519 if (G1ConcRegionFreeingVerbose) { | |
520 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
521 "secondary_free_list has "SIZE_FORMAT" entries", | |
522 _secondary_free_list.length()); | |
523 } | |
524 // It looks as if there are free regions available on the | |
525 // secondary_free_list. Let's move them to the free_list and try | |
526 // again to allocate from it. | |
527 append_secondary_free_list(); | |
528 | |
529 assert(!_free_list.is_empty(), "if the secondary_free_list was not " | |
530 "empty we should have moved at least one entry to the free_list"); | |
531 HeapRegion* res = _free_list.remove_head(); | |
532 if (G1ConcRegionFreeingVerbose) { | |
533 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
534 "allocated "HR_FORMAT" from secondary_free_list", | |
535 HR_FORMAT_PARAMS(res)); | |
536 } | |
537 return res; | |
538 } | |
539 | |
540 // Wait here until we get notifed either when (a) there are no | |
541 // more free regions coming or (b) some regions have been moved on | |
542 // the secondary_free_list. | |
543 SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag); | |
544 } | |
545 | |
546 if (G1ConcRegionFreeingVerbose) { | |
547 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
548 "could not allocate from secondary_free_list"); | |
549 } | |
550 return NULL; | |
551 } | |
552 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
553 HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool do_expand) { |
2152 | 554 assert(!isHumongous(word_size) || |
555 word_size <= (size_t) HeapRegion::GrainWords, | |
556 "the only time we use this to allocate a humongous region is " | |
557 "when we are allocating a single humongous region"); | |
558 | |
559 HeapRegion* res; | |
560 if (G1StressConcRegionFreeing) { | |
561 if (!_secondary_free_list.is_empty()) { | |
562 if (G1ConcRegionFreeingVerbose) { | |
563 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
564 "forced to look at the secondary_free_list"); | |
565 } | |
2361 | 566 res = new_region_try_secondary_free_list(); |
2152 | 567 if (res != NULL) { |
568 return res; | |
569 } | |
570 } | |
571 } | |
572 res = _free_list.remove_head_or_null(); | |
573 if (res == NULL) { | |
574 if (G1ConcRegionFreeingVerbose) { | |
575 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
576 "res == NULL, trying the secondary_free_list"); | |
577 } | |
2361 | 578 res = new_region_try_secondary_free_list(); |
2152 | 579 } |
342 | 580 if (res == NULL && do_expand) { |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
581 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
582 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
583 ergo_format_reason("region allocation request failed") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
584 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
585 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
586 if (expand(word_size * HeapWordSize)) { |
3766 | 587 // Even though the heap was expanded, it might not have reached |
588 // the desired size. So, we cannot assume that the allocation | |
589 // will succeed. | |
590 res = _free_list.remove_head_or_null(); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
591 } |
342 | 592 } |
593 return res; | |
594 } | |
595 | |
3766 | 596 size_t G1CollectedHeap::humongous_obj_allocate_find_first(size_t num_regions, |
597 size_t word_size) { | |
2361 | 598 assert(isHumongous(word_size), "word_size should be humongous"); |
599 assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); | |
600 | |
3766 | 601 size_t first = G1_NULL_HRS_INDEX; |
2152 | 602 if (num_regions == 1) { |
603 // Only one region to allocate, no need to go through the slower | |
604 // path. The caller will attempt the expasion if this fails, so | |
605 // let's not try to expand here too. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
606 HeapRegion* hr = new_region(word_size, false /* do_expand */); |
2152 | 607 if (hr != NULL) { |
608 first = hr->hrs_index(); | |
609 } else { | |
3766 | 610 first = G1_NULL_HRS_INDEX; |
2152 | 611 } |
612 } else { | |
613 // We can't allocate humongous regions while cleanupComplete() is | |
614 // running, since some of the regions we find to be empty might not | |
615 // yet be added to the free list and it is not straightforward to | |
616 // know which list they are on so that we can remove them. Note | |
617 // that we only need to do this if we need to allocate more than | |
618 // one region to satisfy the current humongous allocation | |
619 // request. If we are only allocating one region we use the common | |
620 // region allocation code (see above). | |
621 wait_while_free_regions_coming(); | |
2361 | 622 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 623 |
624 if (free_regions() >= num_regions) { | |
3766 | 625 first = _hrs.find_contiguous(num_regions); |
626 if (first != G1_NULL_HRS_INDEX) { | |
627 for (size_t i = first; i < first + num_regions; ++i) { | |
628 HeapRegion* hr = region_at(i); | |
2152 | 629 assert(hr->is_empty(), "sanity"); |
2361 | 630 assert(is_on_master_free_list(hr), "sanity"); |
2152 | 631 hr->set_pending_removal(true); |
632 } | |
633 _free_list.remove_all_pending(num_regions); | |
634 } | |
635 } | |
636 } | |
637 return first; | |
638 } | |
639 | |
2361 | 640 HeapWord* |
3766 | 641 G1CollectedHeap::humongous_obj_allocate_initialize_regions(size_t first, |
2361 | 642 size_t num_regions, |
643 size_t word_size) { | |
3766 | 644 assert(first != G1_NULL_HRS_INDEX, "pre-condition"); |
2361 | 645 assert(isHumongous(word_size), "word_size should be humongous"); |
646 assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); | |
647 | |
648 // Index of last region in the series + 1. | |
3766 | 649 size_t last = first + num_regions; |
2361 | 650 |
651 // We need to initialize the region(s) we just discovered. This is | |
652 // a bit tricky given that it can happen concurrently with | |
653 // refinement threads refining cards on these regions and | |
654 // potentially wanting to refine the BOT as they are scanning | |
655 // those cards (this can happen shortly after a cleanup; see CR | |
656 // 6991377). So we have to set up the region(s) carefully and in | |
657 // a specific order. | |
658 | |
659 // The word size sum of all the regions we will allocate. | |
660 size_t word_size_sum = num_regions * HeapRegion::GrainWords; | |
661 assert(word_size <= word_size_sum, "sanity"); | |
662 | |
663 // This will be the "starts humongous" region. | |
3766 | 664 HeapRegion* first_hr = region_at(first); |
2361 | 665 // The header of the new object will be placed at the bottom of |
666 // the first region. | |
667 HeapWord* new_obj = first_hr->bottom(); | |
668 // This will be the new end of the first region in the series that | |
669 // should also match the end of the last region in the seriers. | |
670 HeapWord* new_end = new_obj + word_size_sum; | |
671 // This will be the new top of the first region that will reflect | |
672 // this allocation. | |
673 HeapWord* new_top = new_obj + word_size; | |
674 | |
675 // First, we need to zero the header of the space that we will be | |
676 // allocating. When we update top further down, some refinement | |
677 // threads might try to scan the region. By zeroing the header we | |
678 // ensure that any thread that will try to scan the region will | |
679 // come across the zero klass word and bail out. | |
680 // | |
681 // NOTE: It would not have been correct to have used | |
682 // CollectedHeap::fill_with_object() and make the space look like | |
683 // an int array. The thread that is doing the allocation will | |
684 // later update the object header to a potentially different array | |
685 // type and, for a very short period of time, the klass and length | |
686 // fields will be inconsistent. This could cause a refinement | |
687 // thread to calculate the object size incorrectly. | |
688 Copy::fill_to_words(new_obj, oopDesc::header_size(), 0); | |
689 | |
690 // We will set up the first region as "starts humongous". This | |
691 // will also update the BOT covering all the regions to reflect | |
692 // that there is a single object that starts at the bottom of the | |
693 // first region. | |
694 first_hr->set_startsHumongous(new_top, new_end); | |
695 | |
696 // Then, if there are any, we will set up the "continues | |
697 // humongous" regions. | |
698 HeapRegion* hr = NULL; | |
3766 | 699 for (size_t i = first + 1; i < last; ++i) { |
700 hr = region_at(i); | |
2361 | 701 hr->set_continuesHumongous(first_hr); |
702 } | |
703 // If we have "continues humongous" regions (hr != NULL), then the | |
704 // end of the last one should match new_end. | |
705 assert(hr == NULL || hr->end() == new_end, "sanity"); | |
706 | |
707 // Up to this point no concurrent thread would have been able to | |
708 // do any scanning on any region in this series. All the top | |
709 // fields still point to bottom, so the intersection between | |
710 // [bottom,top] and [card_start,card_end] will be empty. Before we | |
711 // update the top fields, we'll do a storestore to make sure that | |
712 // no thread sees the update to top before the zeroing of the | |
713 // object header and the BOT initialization. | |
714 OrderAccess::storestore(); | |
715 | |
716 // Now that the BOT and the object header have been initialized, | |
717 // we can update top of the "starts humongous" region. | |
718 assert(first_hr->bottom() < new_top && new_top <= first_hr->end(), | |
719 "new_top should be in this region"); | |
720 first_hr->set_top(new_top); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
721 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
722 HeapWord* bottom = first_hr->bottom(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
723 HeapWord* end = first_hr->orig_end(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
724 if ((first + 1) == last) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
725 // the series has a single humongous region |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
726 _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, new_top); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
727 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
728 // the series has more than one humongous regions |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
729 _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
730 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
731 } |
2361 | 732 |
733 // Now, we will update the top fields of the "continues humongous" | |
734 // regions. The reason we need to do this is that, otherwise, | |
735 // these regions would look empty and this will confuse parts of | |
736 // G1. For example, the code that looks for a consecutive number | |
737 // of empty regions will consider them empty and try to | |
738 // re-allocate them. We can extend is_empty() to also include | |
739 // !continuesHumongous(), but it is easier to just update the top | |
740 // fields here. The way we set top for all regions (i.e., top == | |
741 // end for all regions but the last one, top == new_top for the | |
742 // last one) is actually used when we will free up the humongous | |
743 // region in free_humongous_region(). | |
744 hr = NULL; | |
3766 | 745 for (size_t i = first + 1; i < last; ++i) { |
746 hr = region_at(i); | |
2361 | 747 if ((i + 1) == last) { |
748 // last continues humongous region | |
749 assert(hr->bottom() < new_top && new_top <= hr->end(), | |
750 "new_top should fall on this region"); | |
751 hr->set_top(new_top); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
752 _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top); |
2361 | 753 } else { |
754 // not last one | |
755 assert(new_top > hr->end(), "new_top should be above this region"); | |
756 hr->set_top(hr->end()); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
757 _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end()); |
2361 | 758 } |
759 } | |
760 // If we have continues humongous regions (hr != NULL), then the | |
761 // end of the last one should match new_end and its top should | |
762 // match new_top. | |
763 assert(hr == NULL || | |
764 (hr->end() == new_end && hr->top() == new_top), "sanity"); | |
765 | |
766 assert(first_hr->used() == word_size * HeapWordSize, "invariant"); | |
767 _summary_bytes_used += first_hr->used(); | |
768 _humongous_set.add(first_hr); | |
769 | |
770 return new_obj; | |
771 } | |
772 | |
342 | 773 // If could fit into free regions w/o expansion, try. |
774 // Otherwise, if can expand, do so. | |
775 // Otherwise, if using ex regions might help, try with ex given back. | |
1973 | 776 HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) { |
2152 | 777 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); |
778 | |
779 verify_region_sets_optional(); | |
342 | 780 |
781 size_t num_regions = | |
1973 | 782 round_to(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords; |
342 | 783 size_t x_size = expansion_regions(); |
3766 | 784 size_t fs = _hrs.free_suffix(); |
785 size_t first = humongous_obj_allocate_find_first(num_regions, word_size); | |
786 if (first == G1_NULL_HRS_INDEX) { | |
2152 | 787 // The only thing we can do now is attempt expansion. |
342 | 788 if (fs + x_size >= num_regions) { |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
789 // If the number of regions we're trying to allocate for this |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
790 // object is at most the number of regions in the free suffix, |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
791 // then the call to humongous_obj_allocate_find_first() above |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
792 // should have succeeded and we wouldn't be here. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
793 // |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
794 // We should only be trying to expand when the free suffix is |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
795 // not sufficient for the object _and_ we have some expansion |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
796 // room available. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
797 assert(num_regions > fs, "earlier allocation should have succeeded"); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
798 |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
799 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
800 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
801 ergo_format_reason("humongous allocation request failed") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
802 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
803 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
804 if (expand((num_regions - fs) * HeapRegion::GrainBytes)) { |
3766 | 805 // Even though the heap was expanded, it might not have |
806 // reached the desired size. So, we cannot assume that the | |
807 // allocation will succeed. | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
808 first = humongous_obj_allocate_find_first(num_regions, word_size); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
809 } |
2152 | 810 } |
811 } | |
812 | |
2361 | 813 HeapWord* result = NULL; |
3766 | 814 if (first != G1_NULL_HRS_INDEX) { |
2361 | 815 result = |
816 humongous_obj_allocate_initialize_regions(first, num_regions, word_size); | |
817 assert(result != NULL, "it should always return a valid result"); | |
2152 | 818 } |
819 | |
820 verify_region_sets_optional(); | |
2361 | 821 |
822 return result; | |
342 | 823 } |
824 | |
1973 | 825 HeapWord* G1CollectedHeap::allocate_new_tlab(size_t word_size) { |
826 assert_heap_not_locked_and_not_at_safepoint(); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
827 assert(!isHumongous(word_size), "we do not allow humongous TLABs"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
828 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
829 unsigned int dummy_gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
830 return attempt_allocation(word_size, &dummy_gc_count_before); |
342 | 831 } |
832 | |
833 HeapWord* | |
834 G1CollectedHeap::mem_allocate(size_t word_size, | |
1973 | 835 bool* gc_overhead_limit_was_exceeded) { |
836 assert_heap_not_locked_and_not_at_safepoint(); | |
342 | 837 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
838 // Loop until the allocation is satisified, or unsatisfied after GC. |
1973 | 839 for (int try_count = 1; /* we'll return */; try_count += 1) { |
840 unsigned int gc_count_before; | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
841 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
842 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
843 if (!isHumongous(word_size)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
844 result = attempt_allocation(word_size, &gc_count_before); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
845 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
846 result = attempt_allocation_humongous(word_size, &gc_count_before); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
847 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
848 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
849 return result; |
342 | 850 } |
851 | |
852 // Create the garbage collection operation... | |
1973 | 853 VM_G1CollectForAllocation op(gc_count_before, word_size); |
342 | 854 // ...and get the VM thread to execute it. |
855 VMThread::execute(&op); | |
1973 | 856 |
857 if (op.prologue_succeeded() && op.pause_succeeded()) { | |
858 // If the operation was successful we'll return the result even | |
859 // if it is NULL. If the allocation attempt failed immediately | |
860 // after a Full GC, it's unlikely we'll be able to allocate now. | |
861 HeapWord* result = op.result(); | |
862 if (result != NULL && !isHumongous(word_size)) { | |
863 // Allocations that take place on VM operations do not do any | |
864 // card dirtying and we have to do it here. We only have to do | |
865 // this for non-humongous allocations, though. | |
866 dirty_young_block(result, word_size); | |
867 } | |
342 | 868 return result; |
1973 | 869 } else { |
870 assert(op.result() == NULL, | |
871 "the result should be NULL if the VM op did not succeed"); | |
342 | 872 } |
873 | |
874 // Give a warning if we seem to be looping forever. | |
875 if ((QueuedAllocationWarningCount > 0) && | |
876 (try_count % QueuedAllocationWarningCount == 0)) { | |
1973 | 877 warning("G1CollectedHeap::mem_allocate retries %d times", try_count); |
342 | 878 } |
879 } | |
1973 | 880 |
881 ShouldNotReachHere(); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
882 return NULL; |
342 | 883 } |
884 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
885 HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
886 unsigned int *gc_count_before_ret) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
887 // Make sure you read the note in attempt_allocation_humongous(). |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
888 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
889 assert_heap_not_locked_and_not_at_safepoint(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
890 assert(!isHumongous(word_size), "attempt_allocation_slow() should not " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
891 "be called for humongous allocation requests"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
892 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
893 // We should only get here after the first-level allocation attempt |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
894 // (attempt_allocation()) failed to allocate. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
895 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
896 // We will loop until a) we manage to successfully perform the |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
897 // allocation or b) we successfully schedule a collection which |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
898 // fails to perform the allocation. b) is the only case when we'll |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
899 // return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
900 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
901 for (int try_count = 1; /* we'll return */; try_count += 1) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
902 bool should_try_gc; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
903 unsigned int gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
904 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
905 { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
906 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
907 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
908 result = _mutator_alloc_region.attempt_allocation_locked(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
909 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
910 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
911 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
912 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
913 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
914 // If we reach here, attempt_allocation_locked() above failed to |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
915 // allocate a new region. So the mutator alloc region should be NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
916 assert(_mutator_alloc_region.get() == NULL, "only way to get here"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
917 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
918 if (GC_locker::is_active_and_needs_gc()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
919 if (g1_policy()->can_expand_young_list()) { |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
920 // No need for an ergo verbose message here, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
921 // can_expand_young_list() does this when it returns true. |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
922 result = _mutator_alloc_region.attempt_allocation_force(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
923 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
924 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
925 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
926 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
927 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
928 should_try_gc = false; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
929 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
930 // Read the GC count while still holding the Heap_lock. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
931 gc_count_before = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
932 should_try_gc = true; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
933 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
934 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
935 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
936 if (should_try_gc) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
937 bool succeeded; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
938 result = do_collection_pause(word_size, gc_count_before, &succeeded); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
939 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
940 assert(succeeded, "only way to get back a non-NULL result"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
941 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
942 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
943 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
944 if (succeeded) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
945 // If we get here we successfully scheduled a collection which |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
946 // failed to allocate. No point in trying to allocate |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
947 // further. We'll just return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
948 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
949 *gc_count_before_ret = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
950 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
951 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
952 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
953 GC_locker::stall_until_clear(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
954 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
955 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
956 // We can reach here if we were unsuccessul in scheduling a |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
957 // collection (because another thread beat us to it) or if we were |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
958 // stalled due to the GC locker. In either can we should retry the |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
959 // allocation attempt in case another thread successfully |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
960 // performed a collection and reclaimed enough space. We do the |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
961 // first attempt (without holding the Heap_lock) here and the |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
962 // follow-on attempt will be at the start of the next loop |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
963 // iteration (after taking the Heap_lock). |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
964 result = _mutator_alloc_region.attempt_allocation(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
965 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
966 if (result != NULL ){ |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
967 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
968 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
969 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
970 // Give a warning if we seem to be looping forever. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
971 if ((QueuedAllocationWarningCount > 0) && |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
972 (try_count % QueuedAllocationWarningCount == 0)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
973 warning("G1CollectedHeap::attempt_allocation_slow() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
974 "retries %d times", try_count); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
975 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
976 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
977 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
978 ShouldNotReachHere(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
979 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
980 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
981 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
982 HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
983 unsigned int * gc_count_before_ret) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
984 // The structure of this method has a lot of similarities to |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
985 // attempt_allocation_slow(). The reason these two were not merged |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
986 // into a single one is that such a method would require several "if |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
987 // allocation is not humongous do this, otherwise do that" |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
988 // conditional paths which would obscure its flow. In fact, an early |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
989 // version of this code did use a unified method which was harder to |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
990 // follow and, as a result, it had subtle bugs that were hard to |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
991 // track down. So keeping these two methods separate allows each to |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
992 // be more readable. It will be good to keep these two in sync as |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
993 // much as possible. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
994 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
995 assert_heap_not_locked_and_not_at_safepoint(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
996 assert(isHumongous(word_size), "attempt_allocation_humongous() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
997 "should only be called for humongous allocations"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
998 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
999 // We will loop until a) we manage to successfully perform the |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1000 // allocation or b) we successfully schedule a collection which |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1001 // fails to perform the allocation. b) is the only case when we'll |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1002 // return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1003 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1004 for (int try_count = 1; /* we'll return */; try_count += 1) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1005 bool should_try_gc; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1006 unsigned int gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1007 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1008 { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1009 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1010 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1011 // Given that humongous objects are not allocated in young |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1012 // regions, we'll first try to do the allocation without doing a |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1013 // collection hoping that there's enough space in the heap. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1014 result = humongous_obj_allocate(word_size); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1015 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1016 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1017 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1018 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1019 if (GC_locker::is_active_and_needs_gc()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1020 should_try_gc = false; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1021 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1022 // Read the GC count while still holding the Heap_lock. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1023 gc_count_before = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1024 should_try_gc = true; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1025 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1026 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1027 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1028 if (should_try_gc) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1029 // If we failed to allocate the humongous object, we should try to |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1030 // do a collection pause (if we're allowed) in case it reclaims |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1031 // enough space for the allocation to succeed after the pause. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1032 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1033 bool succeeded; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1034 result = do_collection_pause(word_size, gc_count_before, &succeeded); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1035 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1036 assert(succeeded, "only way to get back a non-NULL result"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1037 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1038 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1039 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1040 if (succeeded) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1041 // If we get here we successfully scheduled a collection which |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1042 // failed to allocate. No point in trying to allocate |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1043 // further. We'll just return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1044 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1045 *gc_count_before_ret = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1046 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1047 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1048 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1049 GC_locker::stall_until_clear(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1050 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1051 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1052 // We can reach here if we were unsuccessul in scheduling a |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1053 // collection (because another thread beat us to it) or if we were |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1054 // stalled due to the GC locker. In either can we should retry the |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1055 // allocation attempt in case another thread successfully |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1056 // performed a collection and reclaimed enough space. Give a |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1057 // warning if we seem to be looping forever. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1058 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1059 if ((QueuedAllocationWarningCount > 0) && |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1060 (try_count % QueuedAllocationWarningCount == 0)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1061 warning("G1CollectedHeap::attempt_allocation_humongous() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1062 "retries %d times", try_count); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1063 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1064 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1065 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1066 ShouldNotReachHere(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1067 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1068 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1069 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1070 HeapWord* G1CollectedHeap::attempt_allocation_at_safepoint(size_t word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1071 bool expect_null_mutator_alloc_region) { |
2152 | 1072 assert_at_safepoint(true /* should_be_vm_thread */); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1073 assert(_mutator_alloc_region.get() == NULL || |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1074 !expect_null_mutator_alloc_region, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1075 "the current alloc region was unexpectedly found to be non-NULL"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1076 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1077 if (!isHumongous(word_size)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1078 return _mutator_alloc_region.attempt_allocation_locked(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1079 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1080 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1081 return humongous_obj_allocate(word_size); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1082 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1083 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1084 ShouldNotReachHere(); |
342 | 1085 } |
1086 | |
1087 class PostMCRemSetClearClosure: public HeapRegionClosure { | |
1088 ModRefBarrierSet* _mr_bs; | |
1089 public: | |
1090 PostMCRemSetClearClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {} | |
1091 bool doHeapRegion(HeapRegion* r) { | |
1092 r->reset_gc_time_stamp(); | |
1093 if (r->continuesHumongous()) | |
1094 return false; | |
1095 HeapRegionRemSet* hrrs = r->rem_set(); | |
1096 if (hrrs != NULL) hrrs->clear(); | |
1097 // You might think here that we could clear just the cards | |
1098 // corresponding to the used region. But no: if we leave a dirty card | |
1099 // in a region we might allocate into, then it would prevent that card | |
1100 // from being enqueued, and cause it to be missed. | |
1101 // Re: the performance cost: we shouldn't be doing full GC anyway! | |
1102 _mr_bs->clear(MemRegion(r->bottom(), r->end())); | |
1103 return false; | |
1104 } | |
1105 }; | |
1106 | |
1107 | |
1108 class PostMCRemSetInvalidateClosure: public HeapRegionClosure { | |
1109 ModRefBarrierSet* _mr_bs; | |
1110 public: | |
1111 PostMCRemSetInvalidateClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {} | |
1112 bool doHeapRegion(HeapRegion* r) { | |
1113 if (r->continuesHumongous()) return false; | |
1114 if (r->used_region().word_size() != 0) { | |
1115 _mr_bs->invalidate(r->used_region(), true /*whole heap*/); | |
1116 } | |
1117 return false; | |
1118 } | |
1119 }; | |
1120 | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1121 class RebuildRSOutOfRegionClosure: public HeapRegionClosure { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1122 G1CollectedHeap* _g1h; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1123 UpdateRSOopClosure _cl; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1124 int _worker_i; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1125 public: |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1126 RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) : |
1861 | 1127 _cl(g1->g1_rem_set(), worker_i), |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1128 _worker_i(worker_i), |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1129 _g1h(g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1130 { } |
1960
878b57474103
6978187: G1: assert(ParallelGCThreads> 1 || n_yielded() == _hrrs->occupied()) strikes again
johnc
parents:
1883
diff
changeset
|
1131 |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1132 bool doHeapRegion(HeapRegion* r) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1133 if (!r->continuesHumongous()) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1134 _cl.set_from(r); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1135 r->oop_iterate(&_cl); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1136 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1137 return false; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1138 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1139 }; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1140 |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1141 class ParRebuildRSTask: public AbstractGangTask { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1142 G1CollectedHeap* _g1; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1143 public: |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1144 ParRebuildRSTask(G1CollectedHeap* g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1145 : AbstractGangTask("ParRebuildRSTask"), |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1146 _g1(g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1147 { } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1148 |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1149 void work(int i) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1150 RebuildRSOutOfRegionClosure rebuild_rs(_g1, i); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1151 _g1->heap_region_par_iterate_chunked(&rebuild_rs, i, |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1152 HeapRegion::RebuildRSClaimValue); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1153 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1154 }; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1155 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1156 class PostCompactionPrinterClosure: public HeapRegionClosure { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1157 private: |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1158 G1HRPrinter* _hr_printer; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1159 public: |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1160 bool doHeapRegion(HeapRegion* hr) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1161 assert(!hr->is_young(), "not expecting to find young regions"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1162 // We only generate output for non-empty regions. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1163 if (!hr->is_empty()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1164 if (!hr->isHumongous()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1165 _hr_printer->post_compaction(hr, G1HRPrinter::Old); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1166 } else if (hr->startsHumongous()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1167 if (hr->capacity() == (size_t) HeapRegion::GrainBytes) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1168 // single humongous region |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1169 _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1170 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1171 _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1172 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1173 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1174 assert(hr->continuesHumongous(), "only way to get here"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1175 _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1176 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1177 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1178 return false; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1179 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1180 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1181 PostCompactionPrinterClosure(G1HRPrinter* hr_printer) |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1182 : _hr_printer(hr_printer) { } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1183 }; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1184 |
1973 | 1185 bool G1CollectedHeap::do_collection(bool explicit_gc, |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1186 bool clear_all_soft_refs, |
342 | 1187 size_t word_size) { |
2152 | 1188 assert_at_safepoint(true /* should_be_vm_thread */); |
1189 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1190 if (GC_locker::check_active_before_gc()) { |
1973 | 1191 return false; |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1192 } |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1193 |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
2039
diff
changeset
|
1194 SvcGCMarker sgcm(SvcGCMarker::FULL); |
342 | 1195 ResourceMark rm; |
1196 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1197 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1198 Universe::print_heap_before_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1199 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1200 |
2152 | 1201 verify_region_sets_optional(); |
342 | 1202 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1203 const bool do_clear_all_soft_refs = clear_all_soft_refs || |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1204 collector_policy()->should_clear_all_soft_refs(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1205 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1206 ClearedAllSoftRefs casr(do_clear_all_soft_refs, collector_policy()); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1207 |
342 | 1208 { |
1209 IsGCActiveMark x; | |
1210 | |
1211 // Timing | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1212 bool system_gc = (gc_cause() == GCCause::_java_lang_system_gc); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1213 assert(!system_gc || explicit_gc, "invariant"); |
342 | 1214 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
1215 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1216 TraceTime t(system_gc ? "Full GC (System.gc())" : "Full GC", |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1217 PrintGC, true, gclog_or_tty); |
342 | 1218 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
1219 TraceCollectorStats tcs(g1mm()->full_collection_counters()); |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
3323
diff
changeset
|
1220 TraceMemoryManagerStats tms(true /* fullGC */, gc_cause()); |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1221 |
342 | 1222 double start = os::elapsedTime(); |
1223 g1_policy()->record_full_collection_start(); | |
1224 | |
2152 | 1225 wait_while_free_regions_coming(); |
2361 | 1226 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 1227 |
342 | 1228 gc_prologue(true); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1229 increment_total_collections(true /* full gc */); |
342 | 1230 |
1231 size_t g1h_prev_used = used(); | |
1232 assert(used() == recalculate_used(), "Should be equal"); | |
1233 | |
1234 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { | |
1235 HandleMark hm; // Discard invalid handles created during verification | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1236 gclog_or_tty->print(" VerifyBeforeGC:"); |
342 | 1237 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1238 Universe::verify(/* allow dirty */ true, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1239 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1240 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1241 |
342 | 1242 } |
3869
7f776886a215
6810861: G1: support -XX:+{PrintClassHistogram,HeapDump}{Before,After}FullGC
ysr
parents:
3867
diff
changeset
|
1243 pre_full_gc_dump(); |
342 | 1244 |
1245 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
1246 | |
1247 // We want to discover references, but not process them yet. | |
1248 // This mode is disabled in | |
1249 // instanceRefKlass::process_discovered_references if the | |
1250 // generation does some collection work, or | |
1251 // instanceRefKlass::enqueue_discovered_references if the | |
1252 // generation returns without doing any work. | |
1253 ref_processor()->disable_discovery(); | |
1254 ref_processor()->abandon_partial_discovery(); | |
1255 ref_processor()->verify_no_references_recorded(); | |
1256 | |
1257 // Abandon current iterations of concurrent marking and concurrent | |
1258 // refinement, if any are in progress. | |
1259 concurrent_mark()->abort(); | |
1260 | |
1261 // Make sure we'll choose a new allocation region afterwards. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1262 release_mutator_alloc_region(); |
636 | 1263 abandon_gc_alloc_regions(); |
1861 | 1264 g1_rem_set()->cleanupHRRS(); |
342 | 1265 tear_down_region_lists(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1266 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1267 // We should call this after we retire any currently active alloc |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1268 // regions so that all the ALLOC / RETIRE events are generated |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1269 // before the start GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1270 _hr_printer.start_gc(true /* full */, (size_t) total_collections()); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1271 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1272 // We may have added regions to the current incremental collection |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1273 // set between the last GC or pause and now. We need to clear the |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1274 // incremental collection set and then start rebuilding it afresh |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1275 // after this full GC. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1276 abandon_collection_set(g1_policy()->inc_cset_head()); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1277 g1_policy()->clear_incremental_cset(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1278 g1_policy()->stop_incremental_cset_building(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1279 |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1280 empty_young_list(); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1281 g1_policy()->set_full_young_gcs(true); |
342 | 1282 |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
1283 // See the comment in G1CollectedHeap::ref_processing_init() about |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
1284 // how reference processing currently works in G1. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
1285 |
342 | 1286 // Temporarily make reference _discovery_ single threaded (non-MT). |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
1287 ReferenceProcessorMTDiscoveryMutator rp_disc_ser(ref_processor(), false); |
342 | 1288 |
1289 // Temporarily make refs discovery atomic | |
1290 ReferenceProcessorAtomicMutator rp_disc_atomic(ref_processor(), true); | |
1291 | |
1292 // Temporarily clear _is_alive_non_header | |
1293 ReferenceProcessorIsAliveMutator rp_is_alive_null(ref_processor(), NULL); | |
1294 | |
1295 ref_processor()->enable_discovery(); | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1296 ref_processor()->setup_policy(do_clear_all_soft_refs); |
342 | 1297 // Do collection work |
1298 { | |
1299 HandleMark hm; // Discard invalid handles created during gc | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1300 G1MarkSweep::invoke_at_safepoint(ref_processor(), do_clear_all_soft_refs); |
342 | 1301 } |
2152 | 1302 assert(free_regions() == 0, "we should not have added any free regions"); |
342 | 1303 rebuild_region_lists(); |
1304 | |
1305 _summary_bytes_used = recalculate_used(); | |
1306 | |
1307 ref_processor()->enqueue_discovered_references(); | |
1308 | |
1309 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | |
1310 | |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1311 MemoryService::track_memory_usage(); |
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1312 |
342 | 1313 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { |
1314 HandleMark hm; // Discard invalid handles created during verification | |
1315 gclog_or_tty->print(" VerifyAfterGC:"); | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
1316 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1317 Universe::verify(/* allow dirty */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1318 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1319 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1320 |
342 | 1321 } |
1322 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); | |
1323 | |
1324 reset_gc_time_stamp(); | |
1325 // Since everything potentially moved, we will clear all remembered | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1326 // sets, and clear all cards. Later we will rebuild remebered |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1327 // sets. We will also reset the GC time stamps of the regions. |
342 | 1328 PostMCRemSetClearClosure rs_clear(mr_bs()); |
1329 heap_region_iterate(&rs_clear); | |
1330 | |
1331 // Resize the heap if necessary. | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1332 resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); |
342 | 1333 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1334 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1335 // We should do this after we potentially resize the heap so |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1336 // that all the COMMIT / UNCOMMIT events are generated before |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1337 // the end GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1338 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1339 PostCompactionPrinterClosure cl(hr_printer()); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1340 heap_region_iterate(&cl); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1341 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1342 _hr_printer.end_gc(true /* full */, (size_t) total_collections()); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1343 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1344 |
342 | 1345 if (_cg1r->use_cache()) { |
1346 _cg1r->clear_and_record_card_counts(); | |
1347 _cg1r->clear_hot_cache(); | |
1348 } | |
1349 | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1350 // Rebuild remembered sets of all regions. |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
1351 |
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
1352 if (G1CollectedHeap::use_parallel_gc_threads()) { |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1353 ParRebuildRSTask rebuild_rs_task(this); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1354 assert(check_heap_region_claim_values( |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1355 HeapRegion::InitialClaimValue), "sanity check"); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1356 set_par_threads(workers()->total_workers()); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1357 workers()->run_task(&rebuild_rs_task); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1358 set_par_threads(0); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1359 assert(check_heap_region_claim_values( |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1360 HeapRegion::RebuildRSClaimValue), "sanity check"); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1361 reset_heap_region_claim_values(); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1362 } else { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1363 RebuildRSOutOfRegionClosure rebuild_rs(this); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1364 heap_region_iterate(&rebuild_rs); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1365 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1366 |
342 | 1367 if (PrintGC) { |
1368 print_size_transition(gclog_or_tty, g1h_prev_used, used(), capacity()); | |
1369 } | |
1370 | |
1371 if (true) { // FIXME | |
1372 // Ask the permanent generation to adjust size for full collections | |
1373 perm()->compute_new_size(); | |
1374 } | |
1375 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1376 // Start a new incremental collection set for the next pause |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1377 assert(g1_policy()->collection_set() == NULL, "must be"); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1378 g1_policy()->start_incremental_cset_building(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1379 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1380 // Clear the _cset_fast_test bitmap in anticipation of adding |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1381 // regions to the incremental collection set for the next |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1382 // evacuation pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1383 clear_cset_fast_test(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1384 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1385 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1386 |
342 | 1387 double end = os::elapsedTime(); |
1388 g1_policy()->record_full_collection_end(); | |
1389 | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1390 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1391 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1392 #endif |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1393 |
342 | 1394 gc_epilogue(true); |
1395 | |
794 | 1396 // Discard all rset updates |
1397 JavaThread::dirty_card_queue_set().abandon_logs(); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
1398 assert(!G1DeferredRSUpdate |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
1399 || (G1DeferredRSUpdate && (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any"); |
342 | 1400 } |
1401 | |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1402 _young_list->reset_sampled_info(); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1403 // At this point there should be no regions in the |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1404 // entire heap tagged as young. |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1405 assert( check_young_list_empty(true /* check_heap */), |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1406 "young list should be empty at this point"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1407 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1408 // Update the number of full collections that have been completed. |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
1409 increment_full_collections_completed(false /* concurrent */); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1410 |
3766 | 1411 _hrs.verify_optional(); |
2152 | 1412 verify_region_sets_optional(); |
1413 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1414 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1415 Universe::print_heap_after_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1416 } |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
1417 g1mm()->update_counters(); |
3869
7f776886a215
6810861: G1: support -XX:+{PrintClassHistogram,HeapDump}{Before,After}FullGC
ysr
parents:
3867
diff
changeset
|
1418 post_full_gc_dump(); |
1973 | 1419 |
1420 return true; | |
342 | 1421 } |
1422 | |
1423 void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { | |
1973 | 1424 // do_collection() will return whether it succeeded in performing |
1425 // the GC. Currently, there is no facility on the | |
1426 // do_full_collection() API to notify the caller than the collection | |
1427 // did not succeed (e.g., because it was locked out by the GC | |
1428 // locker). So, right now, we'll ignore the return value. | |
1429 bool dummy = do_collection(true, /* explicit_gc */ | |
1430 clear_all_soft_refs, | |
1431 0 /* word_size */); | |
342 | 1432 } |
1433 | |
1434 // This code is mostly copied from TenuredGeneration. | |
1435 void | |
1436 G1CollectedHeap:: | |
1437 resize_if_necessary_after_full_collection(size_t word_size) { | |
1438 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, "sanity check"); | |
1439 | |
1440 // Include the current allocation, if any, and bytes that will be | |
1441 // pre-allocated to support collections, as "used". | |
1442 const size_t used_after_gc = used(); | |
1443 const size_t capacity_after_gc = capacity(); | |
1444 const size_t free_after_gc = capacity_after_gc - used_after_gc; | |
1445 | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1446 // This is enforced in arguments.cpp. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1447 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1448 "otherwise the code below doesn't make sense"); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1449 |
342 | 1450 // We don't have floating point command-line arguments |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1451 const double minimum_free_percentage = (double) MinHeapFreeRatio / 100.0; |
342 | 1452 const double maximum_used_percentage = 1.0 - minimum_free_percentage; |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1453 const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100.0; |
342 | 1454 const double minimum_used_percentage = 1.0 - maximum_free_percentage; |
1455 | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1456 const size_t min_heap_size = collector_policy()->min_heap_byte_size(); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1457 const size_t max_heap_size = collector_policy()->max_heap_byte_size(); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1458 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1459 // We have to be careful here as these two calculations can overflow |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1460 // 32-bit size_t's. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1461 double used_after_gc_d = (double) used_after_gc; |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1462 double minimum_desired_capacity_d = used_after_gc_d / maximum_used_percentage; |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1463 double maximum_desired_capacity_d = used_after_gc_d / minimum_used_percentage; |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1464 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1465 // Let's make sure that they are both under the max heap size, which |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1466 // by default will make them fit into a size_t. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1467 double desired_capacity_upper_bound = (double) max_heap_size; |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1468 minimum_desired_capacity_d = MIN2(minimum_desired_capacity_d, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1469 desired_capacity_upper_bound); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1470 maximum_desired_capacity_d = MIN2(maximum_desired_capacity_d, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1471 desired_capacity_upper_bound); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1472 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1473 // We can now safely turn them into size_t's. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1474 size_t minimum_desired_capacity = (size_t) minimum_desired_capacity_d; |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1475 size_t maximum_desired_capacity = (size_t) maximum_desired_capacity_d; |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1476 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1477 // This assert only makes sense here, before we adjust them |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1478 // with respect to the min and max heap size. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1479 assert(minimum_desired_capacity <= maximum_desired_capacity, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1480 err_msg("minimum_desired_capacity = "SIZE_FORMAT", " |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1481 "maximum_desired_capacity = "SIZE_FORMAT, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1482 minimum_desired_capacity, maximum_desired_capacity)); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1483 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1484 // Should not be greater than the heap max size. No need to adjust |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1485 // it with respect to the heap min size as it's a lower bound (i.e., |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1486 // we'll try to make the capacity larger than it, not smaller). |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1487 minimum_desired_capacity = MIN2(minimum_desired_capacity, max_heap_size); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1488 // Should not be less than the heap min size. No need to adjust it |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1489 // with respect to the heap max size as it's an upper bound (i.e., |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1490 // we'll try to make the capacity smaller than it, not greater). |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1491 maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size); |
342 | 1492 |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1493 if (capacity_after_gc < minimum_desired_capacity) { |
342 | 1494 // Don't expand unless it's significant |
1495 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1496 ergo_verbose4(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1497 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1498 ergo_format_reason("capacity lower than " |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1499 "min desired capacity after Full GC") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1500 ergo_format_byte("capacity") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1501 ergo_format_byte("occupancy") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1502 ergo_format_byte_perc("min desired capacity"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1503 capacity_after_gc, used_after_gc, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1504 minimum_desired_capacity, (double) MinHeapFreeRatio); |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1505 expand(expand_bytes); |
342 | 1506 |
1507 // No expansion, now see if we want to shrink | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1508 } else if (capacity_after_gc > maximum_desired_capacity) { |
342 | 1509 // Capacity too large, compute shrinking size |
1510 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1511 ergo_verbose4(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1512 "attempt heap shrinking", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1513 ergo_format_reason("capacity higher than " |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1514 "max desired capacity after Full GC") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1515 ergo_format_byte("capacity") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1516 ergo_format_byte("occupancy") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1517 ergo_format_byte_perc("max desired capacity"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1518 capacity_after_gc, used_after_gc, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1519 maximum_desired_capacity, (double) MaxHeapFreeRatio); |
342 | 1520 shrink(shrink_bytes); |
1521 } | |
1522 } | |
1523 | |
1524 | |
1525 HeapWord* | |
1973 | 1526 G1CollectedHeap::satisfy_failed_allocation(size_t word_size, |
1527 bool* succeeded) { | |
2152 | 1528 assert_at_safepoint(true /* should_be_vm_thread */); |
1973 | 1529 |
1530 *succeeded = true; | |
1531 // Let's attempt the allocation first. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1532 HeapWord* result = |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1533 attempt_allocation_at_safepoint(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1534 false /* expect_null_mutator_alloc_region */); |
1973 | 1535 if (result != NULL) { |
1536 assert(*succeeded, "sanity"); | |
1537 return result; | |
1538 } | |
342 | 1539 |
1540 // In a G1 heap, we're supposed to keep allocation from failing by | |
1541 // incremental pauses. Therefore, at least for now, we'll favor | |
1542 // expansion over collection. (This might change in the future if we can | |
1543 // do something smarter than full collection to satisfy a failed alloc.) | |
1544 result = expand_and_allocate(word_size); | |
1545 if (result != NULL) { | |
1973 | 1546 assert(*succeeded, "sanity"); |
342 | 1547 return result; |
1548 } | |
1549 | |
1973 | 1550 // Expansion didn't work, we'll try to do a Full GC. |
1551 bool gc_succeeded = do_collection(false, /* explicit_gc */ | |
1552 false, /* clear_all_soft_refs */ | |
1553 word_size); | |
1554 if (!gc_succeeded) { | |
1555 *succeeded = false; | |
1556 return NULL; | |
1557 } | |
1558 | |
1559 // Retry the allocation | |
1560 result = attempt_allocation_at_safepoint(word_size, | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1561 true /* expect_null_mutator_alloc_region */); |
342 | 1562 if (result != NULL) { |
1973 | 1563 assert(*succeeded, "sanity"); |
342 | 1564 return result; |
1565 } | |
1566 | |
1973 | 1567 // Then, try a Full GC that will collect all soft references. |
1568 gc_succeeded = do_collection(false, /* explicit_gc */ | |
1569 true, /* clear_all_soft_refs */ | |
1570 word_size); | |
1571 if (!gc_succeeded) { | |
1572 *succeeded = false; | |
1573 return NULL; | |
1574 } | |
1575 | |
1576 // Retry the allocation once more | |
1577 result = attempt_allocation_at_safepoint(word_size, | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1578 true /* expect_null_mutator_alloc_region */); |
342 | 1579 if (result != NULL) { |
1973 | 1580 assert(*succeeded, "sanity"); |
342 | 1581 return result; |
1582 } | |
1583 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1584 assert(!collector_policy()->should_clear_all_soft_refs(), |
1973 | 1585 "Flag should have been handled and cleared prior to this point"); |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1586 |
342 | 1587 // What else? We might try synchronous finalization later. If the total |
1588 // space available is large enough for the allocation, then a more | |
1589 // complete compaction phase than we've tried so far might be | |
1590 // appropriate. | |
1973 | 1591 assert(*succeeded, "sanity"); |
342 | 1592 return NULL; |
1593 } | |
1594 | |
1595 // Attempting to expand the heap sufficiently | |
1596 // to support an allocation of the given "word_size". If | |
1597 // successful, perform the allocation and return the address of the | |
1598 // allocated block, or else "NULL". | |
1599 | |
1600 HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size) { | |
2152 | 1601 assert_at_safepoint(true /* should_be_vm_thread */); |
1602 | |
1603 verify_region_sets_optional(); | |
1973 | 1604 |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1605 size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes); |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1606 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1607 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1608 ergo_format_reason("allocation request failed") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1609 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1610 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1611 if (expand(expand_bytes)) { |
3766 | 1612 _hrs.verify_optional(); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1613 verify_region_sets_optional(); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1614 return attempt_allocation_at_safepoint(word_size, |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1615 false /* expect_null_mutator_alloc_region */); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1616 } |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1617 return NULL; |
342 | 1618 } |
1619 | |
3766 | 1620 void G1CollectedHeap::update_committed_space(HeapWord* old_end, |
1621 HeapWord* new_end) { | |
1622 assert(old_end != new_end, "don't call this otherwise"); | |
1623 assert((HeapWord*) _g1_storage.high() == new_end, "invariant"); | |
1624 | |
1625 // Update the committed mem region. | |
1626 _g1_committed.set_end(new_end); | |
1627 // Tell the card table about the update. | |
1628 Universe::heap()->barrier_set()->resize_covered_region(_g1_committed); | |
1629 // Tell the BOT about the update. | |
1630 _bot_shared->resize(_g1_committed.word_size()); | |
1631 } | |
1632 | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1633 bool G1CollectedHeap::expand(size_t expand_bytes) { |
342 | 1634 size_t old_mem_size = _g1_storage.committed_size(); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1635 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); |
342 | 1636 aligned_expand_bytes = align_size_up(aligned_expand_bytes, |
1637 HeapRegion::GrainBytes); | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1638 ergo_verbose2(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1639 "expand the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1640 ergo_format_byte("requested expansion amount") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1641 ergo_format_byte("attempted expansion amount"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1642 expand_bytes, aligned_expand_bytes); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1643 |
3766 | 1644 // First commit the memory. |
1645 HeapWord* old_end = (HeapWord*) _g1_storage.high(); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1646 bool successful = _g1_storage.expand_by(aligned_expand_bytes); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1647 if (successful) { |
3766 | 1648 // Then propagate this update to the necessary data structures. |
1649 HeapWord* new_end = (HeapWord*) _g1_storage.high(); | |
1650 update_committed_space(old_end, new_end); | |
1651 | |
1652 FreeRegionList expansion_list("Local Expansion List"); | |
1653 MemRegion mr = _hrs.expand_by(old_end, new_end, &expansion_list); | |
1654 assert(mr.start() == old_end, "post-condition"); | |
1655 // mr might be a smaller region than what was requested if | |
1656 // expand_by() was unable to allocate the HeapRegion instances | |
1657 assert(mr.end() <= new_end, "post-condition"); | |
1658 | |
1659 size_t actual_expand_bytes = mr.byte_size(); | |
1660 assert(actual_expand_bytes <= aligned_expand_bytes, "post-condition"); | |
1661 assert(actual_expand_bytes == expansion_list.total_capacity_bytes(), | |
1662 "post-condition"); | |
1663 if (actual_expand_bytes < aligned_expand_bytes) { | |
1664 // We could not expand _hrs to the desired size. In this case we | |
1665 // need to shrink the committed space accordingly. | |
1666 assert(mr.end() < new_end, "invariant"); | |
1667 | |
1668 size_t diff_bytes = aligned_expand_bytes - actual_expand_bytes; | |
1669 // First uncommit the memory. | |
1670 _g1_storage.shrink_by(diff_bytes); | |
1671 // Then propagate this update to the necessary data structures. | |
1672 update_committed_space(new_end, mr.end()); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1673 } |
3766 | 1674 _free_list.add_as_tail(&expansion_list); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1675 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1676 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1677 HeapWord* curr = mr.start(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1678 while (curr < mr.end()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1679 HeapWord* curr_end = curr + HeapRegion::GrainWords; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1680 _hr_printer.commit(curr, curr_end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1681 curr = curr_end; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1682 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1683 assert(curr == mr.end(), "post-condition"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1684 } |
3919
4f41766176cf
7084509: G1: fix inconsistencies and mistakes in the young list target length calculations
tonyp
parents:
3916
diff
changeset
|
1685 g1_policy()->calculate_reserve(n_regions()); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1686 } else { |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1687 ergo_verbose0(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1688 "did not expand the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1689 ergo_format_reason("heap expansion operation failed")); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1690 // The expansion of the virtual storage space was unsuccessful. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1691 // Let's see if it was because we ran out of swap. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1692 if (G1ExitOnExpansionFailure && |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1693 _g1_storage.uncommitted_size() >= aligned_expand_bytes) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1694 // We had head room... |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1695 vm_exit_out_of_memory(aligned_expand_bytes, "G1 heap expansion"); |
342 | 1696 } |
1697 } | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1698 return successful; |
342 | 1699 } |
1700 | |
3766 | 1701 void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { |
342 | 1702 size_t old_mem_size = _g1_storage.committed_size(); |
1703 size_t aligned_shrink_bytes = | |
1704 ReservedSpace::page_align_size_down(shrink_bytes); | |
1705 aligned_shrink_bytes = align_size_down(aligned_shrink_bytes, | |
1706 HeapRegion::GrainBytes); | |
1707 size_t num_regions_deleted = 0; | |
3766 | 1708 MemRegion mr = _hrs.shrink_by(aligned_shrink_bytes, &num_regions_deleted); |
1709 HeapWord* old_end = (HeapWord*) _g1_storage.high(); | |
1710 assert(mr.end() == old_end, "post-condition"); | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1711 |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1712 ergo_verbose3(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1713 "shrink the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1714 ergo_format_byte("requested shrinking amount") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1715 ergo_format_byte("aligned shrinking amount") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1716 ergo_format_byte("attempted shrinking amount"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1717 shrink_bytes, aligned_shrink_bytes, mr.byte_size()); |
3766 | 1718 if (mr.byte_size() > 0) { |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1719 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1720 HeapWord* curr = mr.end(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1721 while (curr > mr.start()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1722 HeapWord* curr_end = curr; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1723 curr -= HeapRegion::GrainWords; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1724 _hr_printer.uncommit(curr, curr_end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1725 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1726 assert(curr == mr.start(), "post-condition"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1727 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1728 |
342 | 1729 _g1_storage.shrink_by(mr.byte_size()); |
3766 | 1730 HeapWord* new_end = (HeapWord*) _g1_storage.high(); |
1731 assert(mr.start() == new_end, "post-condition"); | |
1732 | |
1733 _expansion_regions += num_regions_deleted; | |
1734 update_committed_space(old_end, new_end); | |
1735 HeapRegionRemSet::shrink_heap(n_regions()); | |
3919
4f41766176cf
7084509: G1: fix inconsistencies and mistakes in the young list target length calculations
tonyp
parents:
3916
diff
changeset
|
1736 g1_policy()->calculate_reserve(n_regions()); |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1737 } else { |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1738 ergo_verbose0(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1739 "did not shrink the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1740 ergo_format_reason("heap shrinking operation failed")); |
342 | 1741 } |
1742 } | |
1743 | |
1744 void G1CollectedHeap::shrink(size_t shrink_bytes) { | |
2152 | 1745 verify_region_sets_optional(); |
1746 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1747 // We should only reach here at the end of a Full GC which means we |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1748 // should not not be holding to any GC alloc regions. The method |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1749 // below will make sure of that and do any remaining clean up. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1750 abandon_gc_alloc_regions(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1751 |
2152 | 1752 // Instead of tearing down / rebuilding the free lists here, we |
1753 // could instead use the remove_all_pending() method on free_list to | |
1754 // remove only the ones that we need to remove. | |
342 | 1755 tear_down_region_lists(); // We will rebuild them in a moment. |
1756 shrink_helper(shrink_bytes); | |
1757 rebuild_region_lists(); | |
2152 | 1758 |
3766 | 1759 _hrs.verify_optional(); |
2152 | 1760 verify_region_sets_optional(); |
342 | 1761 } |
1762 | |
1763 // Public methods. | |
1764 | |
1765 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
1766 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
1767 #endif // _MSC_VER | |
1768 | |
1769 | |
1770 G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) : | |
1771 SharedHeap(policy_), | |
1772 _g1_policy(policy_), | |
1111 | 1773 _dirty_card_queue_set(false), |
1705 | 1774 _into_cset_dirty_card_queue_set(false), |
2037
b03260081e9b
7006113: G1: Initialize ReferenceProcessor::_is_alive_non_header field
johnc
parents:
2030
diff
changeset
|
1775 _is_alive_closure(this), |
342 | 1776 _ref_processor(NULL), |
1777 _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)), | |
1778 _bot_shared(NULL), | |
1779 _objs_with_preserved_marks(NULL), _preserved_marks_of_objs(NULL), | |
1780 _evac_failure_scan_stack(NULL) , | |
1781 _mark_in_progress(false), | |
2152 | 1782 _cg1r(NULL), _summary_bytes_used(0), |
342 | 1783 _refine_cte_cl(NULL), |
1784 _full_collection(false), | |
2152 | 1785 _free_list("Master Free List"), |
1786 _secondary_free_list("Secondary Free List"), | |
1787 _humongous_set("Master Humongous Set"), | |
1788 _free_regions_coming(false), | |
342 | 1789 _young_list(new YoungList(this)), |
1790 _gc_time_stamp(0), | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1791 _retained_old_gc_alloc_region(NULL), |
526 | 1792 _surviving_young_words(NULL), |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1793 _full_collections_completed(0), |
526 | 1794 _in_cset_fast_test(NULL), |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
1795 _in_cset_fast_test_base(NULL), |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
1796 _dirty_cards_region_list(NULL) { |
342 | 1797 _g1h = this; // To catch bugs. |
1798 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { | |
1799 vm_exit_during_initialization("Failed necessary allocation."); | |
1800 } | |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1801 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1802 _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1803 |
342 | 1804 int n_queues = MAX2((int)ParallelGCThreads, 1); |
1805 _task_queues = new RefToScanQueueSet(n_queues); | |
1806 | |
1807 int n_rem_sets = HeapRegionRemSet::num_par_rem_sets(); | |
1808 assert(n_rem_sets > 0, "Invariant."); | |
1809 | |
1810 HeapRegionRemSetIterator** iter_arr = | |
1811 NEW_C_HEAP_ARRAY(HeapRegionRemSetIterator*, n_queues); | |
1812 for (int i = 0; i < n_queues; i++) { | |
1813 iter_arr[i] = new HeapRegionRemSetIterator(); | |
1814 } | |
1815 _rem_set_iterator = iter_arr; | |
1816 | |
1817 for (int i = 0; i < n_queues; i++) { | |
1818 RefToScanQueue* q = new RefToScanQueue(); | |
1819 q->initialize(); | |
1820 _task_queues->register_queue(i, q); | |
1821 } | |
1822 | |
1823 guarantee(_task_queues != NULL, "task_queues allocation failure."); | |
1824 } | |
1825 | |
1826 jint G1CollectedHeap::initialize() { | |
1166 | 1827 CollectedHeap::pre_initialize(); |
342 | 1828 os::enable_vtime(); |
1829 | |
1830 // Necessary to satisfy locking discipline assertions. | |
1831 | |
1832 MutexLocker x(Heap_lock); | |
1833 | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1834 // We have to initialize the printer before committing the heap, as |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1835 // it will be used then. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1836 _hr_printer.set_active(G1PrintHeapRegions); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1837 |
342 | 1838 // While there are no constraints in the GC code that HeapWordSize |
1839 // be any particular value, there are multiple other areas in the | |
1840 // system which believe this to be true (e.g. oop->object_size in some | |
1841 // cases incorrectly returns the size in wordSize units rather than | |
1842 // HeapWordSize). | |
1843 guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize"); | |
1844 | |
1845 size_t init_byte_size = collector_policy()->initial_heap_byte_size(); | |
1846 size_t max_byte_size = collector_policy()->max_heap_byte_size(); | |
1847 | |
1848 // Ensure that the sizes are properly aligned. | |
1849 Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap"); | |
1850 Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap"); | |
1851 | |
1852 _cg1r = new ConcurrentG1Refine(); | |
1853 | |
1854 // Reserve the maximum. | |
1855 PermanentGenerationSpec* pgs = collector_policy()->permanent_generation(); | |
1856 // Includes the perm-gen. | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1857 |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1858 // When compressed oops are enabled, the preferred heap base |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1859 // is calculated by subtracting the requested size from the |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1860 // 32Gb boundary and using the result as the base address for |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1861 // heap reservation. If the requested size is not aligned to |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1862 // HeapRegion::GrainBytes (i.e. the alignment that is passed |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1863 // into the ReservedHeapSpace constructor) then the actual |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1864 // base of the reserved heap may end up differing from the |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1865 // address that was requested (i.e. the preferred heap base). |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1866 // If this happens then we could end up using a non-optimal |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1867 // compressed oops mode. |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1868 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1869 // Since max_byte_size is aligned to the size of a heap region (checked |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1870 // above), we also need to align the perm gen size as it might not be. |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1871 const size_t total_reserved = max_byte_size + |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1872 align_size_up(pgs->max_size(), HeapRegion::GrainBytes); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1873 Universe::check_alignment(total_reserved, HeapRegion::GrainBytes, "g1 heap and perm"); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1874 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1875 char* addr = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1876 |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1877 ReservedHeapSpace heap_rs(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1878 UseLargePages, addr); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1879 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1880 if (UseCompressedOops) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1881 if (addr != NULL && !heap_rs.is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1882 // Failed to reserve at specified address - the requested memory |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1883 // region is taken already, for example, by 'java' launcher. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1884 // Try again to reserver heap higher. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1885 addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop); |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1886 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1887 ReservedHeapSpace heap_rs0(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1888 UseLargePages, addr); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1889 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1890 if (addr != NULL && !heap_rs0.is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1891 // Failed to reserve at specified address again - give up. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1892 addr = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1893 assert(addr == NULL, ""); |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1894 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1895 ReservedHeapSpace heap_rs1(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1896 UseLargePages, addr); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1897 heap_rs = heap_rs1; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1898 } else { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1899 heap_rs = heap_rs0; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1900 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1901 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1902 } |
342 | 1903 |
1904 if (!heap_rs.is_reserved()) { | |
1905 vm_exit_during_initialization("Could not reserve enough space for object heap"); | |
1906 return JNI_ENOMEM; | |
1907 } | |
1908 | |
1909 // It is important to do this in a way such that concurrent readers can't | |
1910 // temporarily think somethings in the heap. (I've actually seen this | |
1911 // happen in asserts: DLD.) | |
1912 _reserved.set_word_size(0); | |
1913 _reserved.set_start((HeapWord*)heap_rs.base()); | |
1914 _reserved.set_end((HeapWord*)(heap_rs.base() + heap_rs.size())); | |
1915 | |
1916 _expansion_regions = max_byte_size/HeapRegion::GrainBytes; | |
1917 | |
1918 // Create the gen rem set (and barrier set) for the entire reserved region. | |
1919 _rem_set = collector_policy()->create_rem_set(_reserved, 2); | |
1920 set_barrier_set(rem_set()->bs()); | |
1921 if (barrier_set()->is_a(BarrierSet::ModRef)) { | |
1922 _mr_bs = (ModRefBarrierSet*)_barrier_set; | |
1923 } else { | |
1924 vm_exit_during_initialization("G1 requires a mod ref bs."); | |
1925 return JNI_ENOMEM; | |
1926 } | |
1927 | |
1928 // Also create a G1 rem set. | |
1861 | 1929 if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { |
1930 _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs()); | |
342 | 1931 } else { |
1861 | 1932 vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); |
1933 return JNI_ENOMEM; | |
342 | 1934 } |
1935 | |
1936 // Carve out the G1 part of the heap. | |
1937 | |
1938 ReservedSpace g1_rs = heap_rs.first_part(max_byte_size); | |
1939 _g1_reserved = MemRegion((HeapWord*)g1_rs.base(), | |
1940 g1_rs.size()/HeapWordSize); | |
1941 ReservedSpace perm_gen_rs = heap_rs.last_part(max_byte_size); | |
1942 | |
1943 _perm_gen = pgs->init(perm_gen_rs, pgs->init_size(), rem_set()); | |
1944 | |
1945 _g1_storage.initialize(g1_rs, 0); | |
1946 _g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0); | |
3766 | 1947 _hrs.initialize((HeapWord*) _g1_reserved.start(), |
1948 (HeapWord*) _g1_reserved.end(), | |
1949 _expansion_regions); | |
342 | 1950 |
807
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1951 // 6843694 - ensure that the maximum region index can fit |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1952 // in the remembered set structures. |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1953 const size_t max_region_idx = ((size_t)1 << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1; |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1954 guarantee((max_regions() - 1) <= max_region_idx, "too many regions"); |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1955 |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1956 size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1; |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1957 guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized"); |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1958 guarantee((size_t) HeapRegion::CardsPerRegion < max_cards_per_region, |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1959 "too many cards per region"); |
807
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1960 |
2152 | 1961 HeapRegionSet::set_unrealistically_long_length(max_regions() + 1); |
1962 | |
342 | 1963 _bot_shared = new G1BlockOffsetSharedArray(_reserved, |
1964 heap_word_size(init_byte_size)); | |
1965 | |
1966 _g1h = this; | |
1967 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1968 _in_cset_fast_test_length = max_regions(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1969 _in_cset_fast_test_base = NEW_C_HEAP_ARRAY(bool, _in_cset_fast_test_length); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1970 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1971 // We're biasing _in_cset_fast_test to avoid subtracting the |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1972 // beginning of the heap every time we want to index; basically |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1973 // it's the same with what we do with the card table. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1974 _in_cset_fast_test = _in_cset_fast_test_base - |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1975 ((size_t) _g1_reserved.start() >> HeapRegion::LogOfHRGrainBytes); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1976 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1977 // Clear the _cset_fast_test bitmap in anticipation of adding |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1978 // regions to the incremental collection set for the first |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1979 // evacuation pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1980 clear_cset_fast_test(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1981 |
342 | 1982 // Create the ConcurrentMark data structure and thread. |
1983 // (Must do this late, so that "max_regions" is defined.) | |
1984 _cm = new ConcurrentMark(heap_rs, (int) max_regions()); | |
1985 _cmThread = _cm->cmThread(); | |
1986 | |
1987 // Initialize the from_card cache structure of HeapRegionRemSet. | |
1988 HeapRegionRemSet::init_heap(max_regions()); | |
1989 | |
677 | 1990 // Now expand into the initial heap size. |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1991 if (!expand(init_byte_size)) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1992 vm_exit_during_initialization("Failed to allocate initial heap."); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1993 return JNI_ENOMEM; |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1994 } |
342 | 1995 |
1996 // Perform any initialization actions delegated to the policy. | |
1997 g1_policy()->init(); | |
1998 | |
1999 g1_policy()->note_start_of_mark_thread(); | |
2000 | |
2001 _refine_cte_cl = | |
2002 new RefineCardTableEntryClosure(ConcurrentG1RefineThread::sts(), | |
2003 g1_rem_set(), | |
2004 concurrent_g1_refine()); | |
2005 JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); | |
2006 | |
2007 JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon, | |
2008 SATB_Q_FL_lock, | |
1111 | 2009 G1SATBProcessCompletedThreshold, |
342 | 2010 Shared_SATB_Q_lock); |
794 | 2011 |
2012 JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, | |
2013 DirtyCardQ_FL_lock, | |
1111 | 2014 concurrent_g1_refine()->yellow_zone(), |
2015 concurrent_g1_refine()->red_zone(), | |
794 | 2016 Shared_DirtyCardQ_lock); |
2017 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2018 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2019 dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2020 DirtyCardQ_FL_lock, |
1111 | 2021 -1, // never trigger processing |
2022 -1, // no limit on length | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2023 Shared_DirtyCardQ_lock, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2024 &JavaThread::dirty_card_queue_set()); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2025 } |
1705 | 2026 |
2027 // Initialize the card queue set used to hold cards containing | |
2028 // references into the collection set. | |
2029 _into_cset_dirty_card_queue_set.initialize(DirtyCardQ_CBL_mon, | |
2030 DirtyCardQ_FL_lock, | |
2031 -1, // never trigger processing | |
2032 -1, // no limit on length | |
2033 Shared_DirtyCardQ_lock, | |
2034 &JavaThread::dirty_card_queue_set()); | |
2035 | |
342 | 2036 // In case we're keeping closure specialization stats, initialize those |
2037 // counts and that mechanism. | |
2038 SpecializationStats::clear(); | |
2039 | |
2040 // Do later initialization work for concurrent refinement. | |
2041 _cg1r->init(); | |
2042 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2043 // Here we allocate the dummy full region that is required by the |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2044 // G1AllocRegion class. If we don't pass an address in the reserved |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2045 // space here, lots of asserts fire. |
3766 | 2046 |
2047 HeapRegion* dummy_region = new_heap_region(0 /* index of bottom region */, | |
2048 _g1_reserved.start()); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2049 // We'll re-use the same region whether the alloc region will |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2050 // require BOT updates or not and, if it doesn't, then a non-young |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2051 // region will complain that it cannot support allocations without |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2052 // BOT updates. So we'll tag the dummy region as young to avoid that. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2053 dummy_region->set_young(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2054 // Make sure it's full. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2055 dummy_region->set_top(dummy_region->end()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2056 G1AllocRegion::setup(this, dummy_region); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2057 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2058 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2059 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2060 // Do create of the monitoring and management support so that |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2061 // values in the heap have been properly initialized. |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2062 _g1mm = new G1MonitoringSupport(this, &_g1_storage); |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2063 |
342 | 2064 return JNI_OK; |
2065 } | |
2066 | |
2067 void G1CollectedHeap::ref_processing_init() { | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2068 // Reference processing in G1 currently works as follows: |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2069 // |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2070 // * There is only one reference processor instance that |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2071 // 'spans' the entire heap. It is created by the code |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2072 // below. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2073 // * Reference discovery is not enabled during an incremental |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2074 // pause (see 6484982). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2075 // * Discoverered refs are not enqueued nor are they processed |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2076 // during an incremental pause (see 6484982). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2077 // * Reference discovery is enabled at initial marking. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2078 // * Reference discovery is disabled and the discovered |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2079 // references processed etc during remarking. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2080 // * Reference discovery is MT (see below). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2081 // * Reference discovery requires a barrier (see below). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2082 // * Reference processing is currently not MT (see 6608385). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2083 // * A full GC enables (non-MT) reference discovery and |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2084 // processes any discovered references. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2085 |
342 | 2086 SharedHeap::ref_processing_init(); |
2087 MemRegion mr = reserved_region(); | |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2088 _ref_processor = |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2089 new ReferenceProcessor(mr, // span |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2090 ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2091 (int) ParallelGCThreads, // degree of mt processing |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2092 ParallelGCThreads > 1 || ConcGCThreads > 1, // mt discovery |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2093 (int) MAX2(ParallelGCThreads, ConcGCThreads), // degree of mt discovery |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2094 false, // Reference discovery is not atomic |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2095 &_is_alive_closure, // is alive closure for efficiency |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2096 true); // Setting next fields of discovered |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2097 // lists requires a barrier. |
342 | 2098 } |
2099 | |
2100 size_t G1CollectedHeap::capacity() const { | |
2101 return _g1_committed.byte_size(); | |
2102 } | |
2103 | |
1705 | 2104 void G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure* cl, |
2105 DirtyCardQueue* into_cset_dcq, | |
2106 bool concurrent, | |
342 | 2107 int worker_i) { |
889 | 2108 // Clean cards in the hot card cache |
1705 | 2109 concurrent_g1_refine()->clean_up_cache(worker_i, g1_rem_set(), into_cset_dcq); |
889 | 2110 |
342 | 2111 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); |
2112 int n_completed_buffers = 0; | |
1705 | 2113 while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) { |
342 | 2114 n_completed_buffers++; |
2115 } | |
2116 g1_policy()->record_update_rs_processed_buffers(worker_i, | |
2117 (double) n_completed_buffers); | |
2118 dcqs.clear_n_completed_buffers(); | |
2119 assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!"); | |
2120 } | |
2121 | |
2122 | |
2123 // Computes the sum of the storage used by the various regions. | |
2124 | |
2125 size_t G1CollectedHeap::used() const { | |
862
36b5611220a7
6863216: Clean up debugging debris inadvertently pushed with 6700789
ysr
parents:
861
diff
changeset
|
2126 assert(Heap_lock->owner() != NULL, |
36b5611220a7
6863216: Clean up debugging debris inadvertently pushed with 6700789
ysr
parents:
861
diff
changeset
|
2127 "Should be owned on this thread's behalf."); |
342 | 2128 size_t result = _summary_bytes_used; |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2129 // Read only once in case it is set to NULL concurrently |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2130 HeapRegion* hr = _mutator_alloc_region.get(); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2131 if (hr != NULL) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2132 result += hr->used(); |
342 | 2133 return result; |
2134 } | |
2135 | |
846
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2136 size_t G1CollectedHeap::used_unlocked() const { |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2137 size_t result = _summary_bytes_used; |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2138 return result; |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2139 } |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2140 |
342 | 2141 class SumUsedClosure: public HeapRegionClosure { |
2142 size_t _used; | |
2143 public: | |
2144 SumUsedClosure() : _used(0) {} | |
2145 bool doHeapRegion(HeapRegion* r) { | |
2146 if (!r->continuesHumongous()) { | |
2147 _used += r->used(); | |
2148 } | |
2149 return false; | |
2150 } | |
2151 size_t result() { return _used; } | |
2152 }; | |
2153 | |
2154 size_t G1CollectedHeap::recalculate_used() const { | |
2155 SumUsedClosure blk; | |
3766 | 2156 heap_region_iterate(&blk); |
342 | 2157 return blk.result(); |
2158 } | |
2159 | |
2160 size_t G1CollectedHeap::unsafe_max_alloc() { | |
2152 | 2161 if (free_regions() > 0) return HeapRegion::GrainBytes; |
342 | 2162 // otherwise, is there space in the current allocation region? |
2163 | |
2164 // We need to store the current allocation region in a local variable | |
2165 // here. The problem is that this method doesn't take any locks and | |
2166 // there may be other threads which overwrite the current allocation | |
2167 // region field. attempt_allocation(), for example, sets it to NULL | |
2168 // and this can happen *after* the NULL check here but before the call | |
2169 // to free(), resulting in a SIGSEGV. Note that this doesn't appear | |
2170 // to be a problem in the optimized build, since the two loads of the | |
2171 // current allocation region field are optimized away. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2172 HeapRegion* hr = _mutator_alloc_region.get(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2173 if (hr == NULL) { |
342 | 2174 return 0; |
2175 } | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2176 return hr->free(); |
342 | 2177 } |
2178 | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2179 bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2180 return |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2181 ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2182 (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2183 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2184 |
3285
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2185 #ifndef PRODUCT |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2186 void G1CollectedHeap::allocate_dummy_regions() { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2187 // Let's fill up most of the region |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2188 size_t word_size = HeapRegion::GrainWords - 1024; |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2189 // And as a result the region we'll allocate will be humongous. |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2190 guarantee(isHumongous(word_size), "sanity"); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2191 |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2192 for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2193 // Let's use the existing mechanism for the allocation |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2194 HeapWord* dummy_obj = humongous_obj_allocate(word_size); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2195 if (dummy_obj != NULL) { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2196 MemRegion mr(dummy_obj, word_size); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2197 CollectedHeap::fill_with_object(mr); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2198 } else { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2199 // If we can't allocate once, we probably cannot allocate |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2200 // again. Let's get out of the loop. |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2201 break; |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2202 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2203 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2204 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2205 #endif // !PRODUCT |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2206 |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2207 void G1CollectedHeap::increment_full_collections_completed(bool concurrent) { |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2208 MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2209 |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2210 // We assume that if concurrent == true, then the caller is a |
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2211 // concurrent thread that was joined the Suspendible Thread |
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2212 // Set. If there's ever a cheap way to check this, we should add an |
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2213 // assert here. |
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2214 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2215 // We have already incremented _total_full_collections at the start |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2216 // of the GC, so total_full_collections() represents how many full |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2217 // collections have been started. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2218 unsigned int full_collections_started = total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2219 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2220 // Given that this method is called at the end of a Full GC or of a |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2221 // concurrent cycle, and those can be nested (i.e., a Full GC can |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2222 // interrupt a concurrent cycle), the number of full collections |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2223 // completed should be either one (in the case where there was no |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2224 // nesting) or two (when a Full GC interrupted a concurrent cycle) |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2225 // behind the number of full collections started. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2226 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2227 // This is the case for the inner caller, i.e. a Full GC. |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2228 assert(concurrent || |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2229 (full_collections_started == _full_collections_completed + 1) || |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2230 (full_collections_started == _full_collections_completed + 2), |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2231 err_msg("for inner caller (Full GC): full_collections_started = %u " |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2232 "is inconsistent with _full_collections_completed = %u", |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2233 full_collections_started, _full_collections_completed)); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2234 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2235 // This is the case for the outer caller, i.e. the concurrent cycle. |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2236 assert(!concurrent || |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2237 (full_collections_started == _full_collections_completed + 1), |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2238 err_msg("for outer caller (concurrent cycle): " |
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2239 "full_collections_started = %u " |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2240 "is inconsistent with _full_collections_completed = %u", |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2241 full_collections_started, _full_collections_completed)); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2242 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2243 _full_collections_completed += 1; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2244 |
1840
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2245 // We need to clear the "in_progress" flag in the CM thread before |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2246 // we wake up any waiters (especially when ExplicitInvokesConcurrent |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2247 // is set) so that if a waiter requests another System.gc() it doesn't |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2248 // incorrectly see that a marking cyle is still in progress. |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2249 if (concurrent) { |
1840
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2250 _cmThread->clear_in_progress(); |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2251 } |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2252 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2253 // This notify_all() will ensure that a thread that called |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2254 // System.gc() with (with ExplicitGCInvokesConcurrent set or not) |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2255 // and it's waiting for a full GC to finish will be woken up. It is |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2256 // waiting in VM_G1IncCollectionPause::doit_epilogue(). |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2257 FullGCCount_lock->notify_all(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2258 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2259 |
342 | 2260 void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) { |
2152 | 2261 assert_at_safepoint(true /* should_be_vm_thread */); |
342 | 2262 GCCauseSetter gcs(this, cause); |
2263 switch (cause) { | |
2264 case GCCause::_heap_inspection: | |
2265 case GCCause::_heap_dump: { | |
2266 HandleMark hm; | |
2267 do_full_collection(false); // don't clear all soft refs | |
2268 break; | |
2269 } | |
2270 default: // XXX FIX ME | |
2271 ShouldNotReachHere(); // Unexpected use of this function | |
2272 } | |
2273 } | |
2274 | |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2275 void G1CollectedHeap::collect(GCCause::Cause cause) { |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2276 // The caller doesn't have the Heap_lock |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2277 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2278 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2279 unsigned int gc_count_before; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2280 unsigned int full_gc_count_before; |
342 | 2281 { |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2282 MutexLocker ml(Heap_lock); |
1973 | 2283 |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2284 // Read the GC count while holding the Heap_lock |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2285 gc_count_before = SharedHeap::heap()->total_collections(); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2286 full_gc_count_before = SharedHeap::heap()->total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2287 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2288 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2289 if (should_do_concurrent_full_gc(cause)) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2290 // Schedule an initial-mark evacuation pause that will start a |
1973 | 2291 // concurrent cycle. We're setting word_size to 0 which means that |
2292 // we are not requesting a post-GC allocation. | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2293 VM_G1IncCollectionPause op(gc_count_before, |
1973 | 2294 0, /* word_size */ |
2295 true, /* should_initiate_conc_mark */ | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2296 g1_policy()->max_pause_time_ms(), |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2297 cause); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2298 VMThread::execute(&op); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2299 } else { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2300 if (cause == GCCause::_gc_locker |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2301 DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2302 |
1973 | 2303 // Schedule a standard evacuation pause. We're setting word_size |
2304 // to 0 which means that we are not requesting a post-GC allocation. | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2305 VM_G1IncCollectionPause op(gc_count_before, |
1973 | 2306 0, /* word_size */ |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2307 false, /* should_initiate_conc_mark */ |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2308 g1_policy()->max_pause_time_ms(), |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2309 cause); |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2310 VMThread::execute(&op); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2311 } else { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2312 // Schedule a Full GC. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2313 VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause); |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2314 VMThread::execute(&op); |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2315 } |
342 | 2316 } |
2317 } | |
2318 | |
2319 bool G1CollectedHeap::is_in(const void* p) const { | |
3766 | 2320 HeapRegion* hr = _hrs.addr_to_region((HeapWord*) p); |
2321 if (hr != NULL) { | |
342 | 2322 return hr->is_in(p); |
2323 } else { | |
2324 return _perm_gen->as_gen()->is_in(p); | |
2325 } | |
2326 } | |
2327 | |
2328 // Iteration functions. | |
2329 | |
2330 // Iterates an OopClosure over all ref-containing fields of objects | |
2331 // within a HeapRegion. | |
2332 | |
2333 class IterateOopClosureRegionClosure: public HeapRegionClosure { | |
2334 MemRegion _mr; | |
2335 OopClosure* _cl; | |
2336 public: | |
2337 IterateOopClosureRegionClosure(MemRegion mr, OopClosure* cl) | |
2338 : _mr(mr), _cl(cl) {} | |
2339 bool doHeapRegion(HeapRegion* r) { | |
2340 if (! r->continuesHumongous()) { | |
2341 r->oop_iterate(_cl); | |
2342 } | |
2343 return false; | |
2344 } | |
2345 }; | |
2346 | |
678 | 2347 void G1CollectedHeap::oop_iterate(OopClosure* cl, bool do_perm) { |
342 | 2348 IterateOopClosureRegionClosure blk(_g1_committed, cl); |
3766 | 2349 heap_region_iterate(&blk); |
678 | 2350 if (do_perm) { |
2351 perm_gen()->oop_iterate(cl); | |
2352 } | |
342 | 2353 } |
2354 | |
678 | 2355 void G1CollectedHeap::oop_iterate(MemRegion mr, OopClosure* cl, bool do_perm) { |
342 | 2356 IterateOopClosureRegionClosure blk(mr, cl); |
3766 | 2357 heap_region_iterate(&blk); |
678 | 2358 if (do_perm) { |
2359 perm_gen()->oop_iterate(cl); | |
2360 } | |
342 | 2361 } |
2362 | |
2363 // Iterates an ObjectClosure over all objects within a HeapRegion. | |
2364 | |
2365 class IterateObjectClosureRegionClosure: public HeapRegionClosure { | |
2366 ObjectClosure* _cl; | |
2367 public: | |
2368 IterateObjectClosureRegionClosure(ObjectClosure* cl) : _cl(cl) {} | |
2369 bool doHeapRegion(HeapRegion* r) { | |
2370 if (! r->continuesHumongous()) { | |
2371 r->object_iterate(_cl); | |
2372 } | |
2373 return false; | |
2374 } | |
2375 }; | |
2376 | |
678 | 2377 void G1CollectedHeap::object_iterate(ObjectClosure* cl, bool do_perm) { |
342 | 2378 IterateObjectClosureRegionClosure blk(cl); |
3766 | 2379 heap_region_iterate(&blk); |
678 | 2380 if (do_perm) { |
2381 perm_gen()->object_iterate(cl); | |
2382 } | |
342 | 2383 } |
2384 | |
2385 void G1CollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) { | |
2386 // FIXME: is this right? | |
2387 guarantee(false, "object_iterate_since_last_GC not supported by G1 heap"); | |
2388 } | |
2389 | |
2390 // Calls a SpaceClosure on a HeapRegion. | |
2391 | |
2392 class SpaceClosureRegionClosure: public HeapRegionClosure { | |
2393 SpaceClosure* _cl; | |
2394 public: | |
2395 SpaceClosureRegionClosure(SpaceClosure* cl) : _cl(cl) {} | |
2396 bool doHeapRegion(HeapRegion* r) { | |
2397 _cl->do_space(r); | |
2398 return false; | |
2399 } | |
2400 }; | |
2401 | |
2402 void G1CollectedHeap::space_iterate(SpaceClosure* cl) { | |
2403 SpaceClosureRegionClosure blk(cl); | |
3766 | 2404 heap_region_iterate(&blk); |
342 | 2405 } |
2406 | |
3766 | 2407 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { |
2408 _hrs.iterate(cl); | |
342 | 2409 } |
2410 | |
2411 void G1CollectedHeap::heap_region_iterate_from(HeapRegion* r, | |
3766 | 2412 HeapRegionClosure* cl) const { |
2413 _hrs.iterate_from(r, cl); | |
342 | 2414 } |
2415 | |
2416 void | |
2417 G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl, | |
2418 int worker, | |
2419 jint claim_value) { | |
355 | 2420 const size_t regions = n_regions(); |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
2421 const size_t worker_num = (G1CollectedHeap::use_parallel_gc_threads() ? ParallelGCThreads : 1); |
355 | 2422 // try to spread out the starting points of the workers |
2423 const size_t start_index = regions / worker_num * (size_t) worker; | |
2424 | |
2425 // each worker will actually look at all regions | |
2426 for (size_t count = 0; count < regions; ++count) { | |
2427 const size_t index = (start_index + count) % regions; | |
2428 assert(0 <= index && index < regions, "sanity"); | |
2429 HeapRegion* r = region_at(index); | |
2430 // we'll ignore "continues humongous" regions (we'll process them | |
2431 // when we come across their corresponding "start humongous" | |
2432 // region) and regions already claimed | |
2433 if (r->claim_value() == claim_value || r->continuesHumongous()) { | |
2434 continue; | |
2435 } | |
2436 // OK, try to claim it | |
342 | 2437 if (r->claimHeapRegion(claim_value)) { |
355 | 2438 // success! |
2439 assert(!r->continuesHumongous(), "sanity"); | |
2440 if (r->startsHumongous()) { | |
2441 // If the region is "starts humongous" we'll iterate over its | |
2442 // "continues humongous" first; in fact we'll do them | |
2443 // first. The order is important. In on case, calling the | |
2444 // closure on the "starts humongous" region might de-allocate | |
2445 // and clear all its "continues humongous" regions and, as a | |
2446 // result, we might end up processing them twice. So, we'll do | |
2447 // them first (notice: most closures will ignore them anyway) and | |
2448 // then we'll do the "starts humongous" region. | |
2449 for (size_t ch_index = index + 1; ch_index < regions; ++ch_index) { | |
2450 HeapRegion* chr = region_at(ch_index); | |
2451 | |
2452 // if the region has already been claimed or it's not | |
2453 // "continues humongous" we're done | |
2454 if (chr->claim_value() == claim_value || | |
2455 !chr->continuesHumongous()) { | |
2456 break; | |
2457 } | |
2458 | |
2459 // Noone should have claimed it directly. We can given | |
2460 // that we claimed its "starts humongous" region. | |
2461 assert(chr->claim_value() != claim_value, "sanity"); | |
2462 assert(chr->humongous_start_region() == r, "sanity"); | |
2463 | |
2464 if (chr->claimHeapRegion(claim_value)) { | |
2465 // we should always be able to claim it; noone else should | |
2466 // be trying to claim this region | |
2467 | |
2468 bool res2 = cl->doHeapRegion(chr); | |
2469 assert(!res2, "Should not abort"); | |
2470 | |
2471 // Right now, this holds (i.e., no closure that actually | |
2472 // does something with "continues humongous" regions | |
2473 // clears them). We might have to weaken it in the future, | |
2474 // but let's leave these two asserts here for extra safety. | |
2475 assert(chr->continuesHumongous(), "should still be the case"); | |
2476 assert(chr->humongous_start_region() == r, "sanity"); | |
2477 } else { | |
2478 guarantee(false, "we should not reach here"); | |
2479 } | |
2480 } | |
2481 } | |
2482 | |
2483 assert(!r->continuesHumongous(), "sanity"); | |
2484 bool res = cl->doHeapRegion(r); | |
2485 assert(!res, "Should not abort"); | |
2486 } | |
2487 } | |
2488 } | |
2489 | |
390 | 2490 class ResetClaimValuesClosure: public HeapRegionClosure { |
2491 public: | |
2492 bool doHeapRegion(HeapRegion* r) { | |
2493 r->set_claim_value(HeapRegion::InitialClaimValue); | |
2494 return false; | |
2495 } | |
2496 }; | |
2497 | |
2498 void | |
2499 G1CollectedHeap::reset_heap_region_claim_values() { | |
2500 ResetClaimValuesClosure blk; | |
2501 heap_region_iterate(&blk); | |
2502 } | |
2503 | |
355 | 2504 #ifdef ASSERT |
2505 // This checks whether all regions in the heap have the correct claim | |
2506 // value. I also piggy-backed on this a check to ensure that the | |
2507 // humongous_start_region() information on "continues humongous" | |
2508 // regions is correct. | |
2509 | |
2510 class CheckClaimValuesClosure : public HeapRegionClosure { | |
2511 private: | |
2512 jint _claim_value; | |
2513 size_t _failures; | |
2514 HeapRegion* _sh_region; | |
2515 public: | |
2516 CheckClaimValuesClosure(jint claim_value) : | |
2517 _claim_value(claim_value), _failures(0), _sh_region(NULL) { } | |
2518 bool doHeapRegion(HeapRegion* r) { | |
2519 if (r->claim_value() != _claim_value) { | |
2520 gclog_or_tty->print_cr("Region ["PTR_FORMAT","PTR_FORMAT"), " | |
2521 "claim value = %d, should be %d", | |
2522 r->bottom(), r->end(), r->claim_value(), | |
2523 _claim_value); | |
2524 ++_failures; | |
2525 } | |
2526 if (!r->isHumongous()) { | |
2527 _sh_region = NULL; | |
2528 } else if (r->startsHumongous()) { | |
2529 _sh_region = r; | |
2530 } else if (r->continuesHumongous()) { | |
2531 if (r->humongous_start_region() != _sh_region) { | |
2532 gclog_or_tty->print_cr("Region ["PTR_FORMAT","PTR_FORMAT"), " | |
2533 "HS = "PTR_FORMAT", should be "PTR_FORMAT, | |
2534 r->bottom(), r->end(), | |
2535 r->humongous_start_region(), | |
2536 _sh_region); | |
2537 ++_failures; | |
342 | 2538 } |
2539 } | |
355 | 2540 return false; |
2541 } | |
2542 size_t failures() { | |
2543 return _failures; | |
2544 } | |
2545 }; | |
2546 | |
2547 bool G1CollectedHeap::check_heap_region_claim_values(jint claim_value) { | |
2548 CheckClaimValuesClosure cl(claim_value); | |
2549 heap_region_iterate(&cl); | |
2550 return cl.failures() == 0; | |
2551 } | |
2552 #endif // ASSERT | |
342 | 2553 |
2554 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) { | |
2555 HeapRegion* r = g1_policy()->collection_set(); | |
2556 while (r != NULL) { | |
2557 HeapRegion* next = r->next_in_collection_set(); | |
2558 if (cl->doHeapRegion(r)) { | |
2559 cl->incomplete(); | |
2560 return; | |
2561 } | |
2562 r = next; | |
2563 } | |
2564 } | |
2565 | |
2566 void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r, | |
2567 HeapRegionClosure *cl) { | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2568 if (r == NULL) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2569 // The CSet is empty so there's nothing to do. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2570 return; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2571 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2572 |
342 | 2573 assert(r->in_collection_set(), |
2574 "Start region must be a member of the collection set."); | |
2575 HeapRegion* cur = r; | |
2576 while (cur != NULL) { | |
2577 HeapRegion* next = cur->next_in_collection_set(); | |
2578 if (cl->doHeapRegion(cur) && false) { | |
2579 cl->incomplete(); | |
2580 return; | |
2581 } | |
2582 cur = next; | |
2583 } | |
2584 cur = g1_policy()->collection_set(); | |
2585 while (cur != r) { | |
2586 HeapRegion* next = cur->next_in_collection_set(); | |
2587 if (cl->doHeapRegion(cur) && false) { | |
2588 cl->incomplete(); | |
2589 return; | |
2590 } | |
2591 cur = next; | |
2592 } | |
2593 } | |
2594 | |
2595 CompactibleSpace* G1CollectedHeap::first_compactible_space() { | |
3766 | 2596 return n_regions() > 0 ? region_at(0) : NULL; |
342 | 2597 } |
2598 | |
2599 | |
2600 Space* G1CollectedHeap::space_containing(const void* addr) const { | |
2601 Space* res = heap_region_containing(addr); | |
2602 if (res == NULL) | |
2603 res = perm_gen()->space_containing(addr); | |
2604 return res; | |
2605 } | |
2606 | |
2607 HeapWord* G1CollectedHeap::block_start(const void* addr) const { | |
2608 Space* sp = space_containing(addr); | |
2609 if (sp != NULL) { | |
2610 return sp->block_start(addr); | |
2611 } | |
2612 return NULL; | |
2613 } | |
2614 | |
2615 size_t G1CollectedHeap::block_size(const HeapWord* addr) const { | |
2616 Space* sp = space_containing(addr); | |
2617 assert(sp != NULL, "block_size of address outside of heap"); | |
2618 return sp->block_size(addr); | |
2619 } | |
2620 | |
2621 bool G1CollectedHeap::block_is_obj(const HeapWord* addr) const { | |
2622 Space* sp = space_containing(addr); | |
2623 return sp->block_is_obj(addr); | |
2624 } | |
2625 | |
2626 bool G1CollectedHeap::supports_tlab_allocation() const { | |
2627 return true; | |
2628 } | |
2629 | |
2630 size_t G1CollectedHeap::tlab_capacity(Thread* ignored) const { | |
2631 return HeapRegion::GrainBytes; | |
2632 } | |
2633 | |
2634 size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const { | |
2635 // Return the remaining space in the cur alloc region, but not less than | |
2636 // the min TLAB size. | |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2637 |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2638 // Also, this value can be at most the humongous object threshold, |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2639 // since we can't allow tlabs to grow big enough to accomodate |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2640 // humongous objects. |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2641 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2642 HeapRegion* hr = _mutator_alloc_region.get(); |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2643 size_t max_tlab_size = _humongous_object_threshold_in_words * wordSize; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2644 if (hr == NULL) { |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2645 return max_tlab_size; |
342 | 2646 } else { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2647 return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab_size); |
342 | 2648 } |
2649 } | |
2650 | |
2651 size_t G1CollectedHeap::max_capacity() const { | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2652 return _g1_reserved.byte_size(); |
342 | 2653 } |
2654 | |
2655 jlong G1CollectedHeap::millis_since_last_gc() { | |
2656 // assert(false, "NYI"); | |
2657 return 0; | |
2658 } | |
2659 | |
2660 void G1CollectedHeap::prepare_for_verify() { | |
2661 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { | |
2662 ensure_parsability(false); | |
2663 } | |
2664 g1_rem_set()->prepare_for_verify(); | |
2665 } | |
2666 | |
2667 class VerifyLivenessOopClosure: public OopClosure { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2668 G1CollectedHeap* _g1h; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2669 VerifyOption _vo; |
342 | 2670 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2671 VerifyLivenessOopClosure(G1CollectedHeap* g1h, VerifyOption vo): |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2672 _g1h(g1h), _vo(vo) |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2673 { } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2674 void do_oop(narrowOop *p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2675 void do_oop( oop *p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2676 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2677 template <class T> void do_oop_work(T *p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2678 oop obj = oopDesc::load_decode_heap_oop(p); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2679 guarantee(obj == NULL || !_g1h->is_obj_dead_cond(obj, _vo), |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2680 "Dead object referenced by a not dead object"); |
342 | 2681 } |
2682 }; | |
2683 | |
2684 class VerifyObjsInRegionClosure: public ObjectClosure { | |
811 | 2685 private: |
342 | 2686 G1CollectedHeap* _g1h; |
2687 size_t _live_bytes; | |
2688 HeapRegion *_hr; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2689 VerifyOption _vo; |
342 | 2690 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2691 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2692 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2693 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2694 VerifyObjsInRegionClosure(HeapRegion *hr, VerifyOption vo) |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2695 : _live_bytes(0), _hr(hr), _vo(vo) { |
342 | 2696 _g1h = G1CollectedHeap::heap(); |
2697 } | |
2698 void do_object(oop o) { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2699 VerifyLivenessOopClosure isLive(_g1h, _vo); |
342 | 2700 assert(o != NULL, "Huh?"); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2701 if (!_g1h->is_obj_dead_cond(o, _vo)) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2702 // If the object is alive according to the mark word, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2703 // then verify that the marking information agrees. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2704 // Note we can't verify the contra-positive of the |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2705 // above: if the object is dead (according to the mark |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2706 // word), it may not be marked, or may have been marked |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2707 // but has since became dead, or may have been allocated |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2708 // since the last marking. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2709 if (_vo == VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2710 guarantee(!_g1h->is_obj_dead(o), "mark word and concurrent mark mismatch"); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2711 } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2712 |
342 | 2713 o->oop_iterate(&isLive); |
1389
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2714 if (!_hr->obj_allocated_since_prev_marking(o)) { |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2715 size_t obj_size = o->size(); // Make sure we don't overflow |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2716 _live_bytes += (obj_size * HeapWordSize); |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2717 } |
342 | 2718 } |
2719 } | |
2720 size_t live_bytes() { return _live_bytes; } | |
2721 }; | |
2722 | |
2723 class PrintObjsInRegionClosure : public ObjectClosure { | |
2724 HeapRegion *_hr; | |
2725 G1CollectedHeap *_g1; | |
2726 public: | |
2727 PrintObjsInRegionClosure(HeapRegion *hr) : _hr(hr) { | |
2728 _g1 = G1CollectedHeap::heap(); | |
2729 }; | |
2730 | |
2731 void do_object(oop o) { | |
2732 if (o != NULL) { | |
2733 HeapWord *start = (HeapWord *) o; | |
2734 size_t word_sz = o->size(); | |
2735 gclog_or_tty->print("\nPrinting obj "PTR_FORMAT" of size " SIZE_FORMAT | |
2736 " isMarkedPrev %d isMarkedNext %d isAllocSince %d\n", | |
2737 (void*) o, word_sz, | |
2738 _g1->isMarkedPrev(o), | |
2739 _g1->isMarkedNext(o), | |
2740 _hr->obj_allocated_since_prev_marking(o)); | |
2741 HeapWord *end = start + word_sz; | |
2742 HeapWord *cur; | |
2743 int *val; | |
2744 for (cur = start; cur < end; cur++) { | |
2745 val = (int *) cur; | |
2746 gclog_or_tty->print("\t "PTR_FORMAT":"PTR_FORMAT"\n", val, *val); | |
2747 } | |
2748 } | |
2749 } | |
2750 }; | |
2751 | |
2752 class VerifyRegionClosure: public HeapRegionClosure { | |
811 | 2753 private: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2754 bool _allow_dirty; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2755 bool _par; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2756 VerifyOption _vo; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2757 bool _failures; |
811 | 2758 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2759 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2760 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2761 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2762 VerifyRegionClosure(bool allow_dirty, bool par, VerifyOption vo) |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2763 : _allow_dirty(allow_dirty), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2764 _par(par), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2765 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2766 _failures(false) {} |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2767 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2768 bool failures() { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2769 return _failures; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2770 } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2771 |
342 | 2772 bool doHeapRegion(HeapRegion* r) { |
390 | 2773 guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue, |
2774 "Should be unclaimed at verify points."); | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
2775 if (!r->continuesHumongous()) { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2776 bool failures = false; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2777 r->verify(_allow_dirty, _vo, &failures); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2778 if (failures) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2779 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2780 } else { |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2781 VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2782 r->object_iterate(¬_dead_yet_cl); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2783 if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2784 gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] " |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2785 "max_live_bytes "SIZE_FORMAT" " |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2786 "< calculated "SIZE_FORMAT, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2787 r->bottom(), r->end(), |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2788 r->max_live_bytes(), |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2789 not_dead_yet_cl.live_bytes()); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2790 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2791 } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2792 } |
342 | 2793 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2794 return false; // stop the region iteration if we hit a failure |
342 | 2795 } |
2796 }; | |
2797 | |
2798 class VerifyRootsClosure: public OopsInGenClosure { | |
2799 private: | |
2800 G1CollectedHeap* _g1h; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2801 VerifyOption _vo; |
342 | 2802 bool _failures; |
2803 public: | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2804 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2805 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2806 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2807 VerifyRootsClosure(VerifyOption vo) : |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2808 _g1h(G1CollectedHeap::heap()), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2809 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2810 _failures(false) { } |
342 | 2811 |
2812 bool failures() { return _failures; } | |
2813 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2814 template <class T> void do_oop_nv(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2815 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2816 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2817 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2818 if (_g1h->is_obj_dead_cond(obj, _vo)) { |
342 | 2819 gclog_or_tty->print_cr("Root location "PTR_FORMAT" " |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2820 "points to dead obj "PTR_FORMAT, p, (void*) obj); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2821 if (_vo == VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2822 gclog_or_tty->print_cr(" Mark word: "PTR_FORMAT, (void*)(obj->mark())); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2823 } |
342 | 2824 obj->print_on(gclog_or_tty); |
2825 _failures = true; | |
2826 } | |
2827 } | |
2828 } | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2829 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2830 void do_oop(oop* p) { do_oop_nv(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2831 void do_oop(narrowOop* p) { do_oop_nv(p); } |
342 | 2832 }; |
2833 | |
390 | 2834 // This is the task used for parallel heap verification. |
2835 | |
2836 class G1ParVerifyTask: public AbstractGangTask { | |
2837 private: | |
2838 G1CollectedHeap* _g1h; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2839 bool _allow_dirty; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2840 VerifyOption _vo; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2841 bool _failures; |
390 | 2842 |
2843 public: | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2844 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2845 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2846 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2847 G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty, VerifyOption vo) : |
390 | 2848 AbstractGangTask("Parallel verify task"), |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2849 _g1h(g1h), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2850 _allow_dirty(allow_dirty), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2851 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2852 _failures(false) { } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2853 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2854 bool failures() { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2855 return _failures; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2856 } |
390 | 2857 |
2858 void work(int worker_i) { | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
2859 HandleMark hm; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2860 VerifyRegionClosure blk(_allow_dirty, true, _vo); |
390 | 2861 _g1h->heap_region_par_iterate_chunked(&blk, worker_i, |
2862 HeapRegion::ParVerifyClaimValue); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2863 if (blk.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2864 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2865 } |
390 | 2866 } |
2867 }; | |
2868 | |
342 | 2869 void G1CollectedHeap::verify(bool allow_dirty, bool silent) { |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2870 verify(allow_dirty, silent, VerifyOption_G1UsePrevMarking); |
811 | 2871 } |
2872 | |
2873 void G1CollectedHeap::verify(bool allow_dirty, | |
2874 bool silent, | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2875 VerifyOption vo) { |
342 | 2876 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2877 if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); } |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2878 VerifyRootsClosure rootsCl(vo); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
2879 CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2880 |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2881 // We apply the relevant closures to all the oops in the |
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2882 // system dictionary, the string table and the code cache. |
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2883 const int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings | SharedHeap::SO_CodeCache; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2884 |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2885 process_strong_roots(true, // activate StrongRootsScope |
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2886 true, // we set "collecting perm gen" to true, |
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2887 // so we don't reset the dirty cards in the perm gen. |
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2888 SharedHeap::ScanningOption(so), // roots scanning options |
342 | 2889 &rootsCl, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
2890 &blobsCl, |
342 | 2891 &rootsCl); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2892 |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2893 // If we're verifying after the marking phase of a Full GC then we can't |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2894 // treat the perm gen as roots into the G1 heap. Some of the objects in |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2895 // the perm gen may be dead and hence not marked. If one of these dead |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2896 // objects is considered to be a root then we may end up with a false |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2897 // "Root location <x> points to dead ob <y>" failure. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2898 if (vo != VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2899 // Since we used "collecting_perm_gen" == true above, we will not have |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2900 // checked the refs from perm into the G1-collected heap. We check those |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2901 // references explicitly below. Whether the relevant cards are dirty |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2902 // is checked further below in the rem set verification. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2903 if (!silent) { gclog_or_tty->print("Permgen roots "); } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2904 perm_gen()->oop_iterate(&rootsCl); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2905 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2906 bool failures = rootsCl.failures(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2907 |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2908 if (vo != VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2909 // If we're verifying during a full GC then the region sets |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2910 // will have been torn down at the start of the GC. Therefore |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2911 // verifying the region sets will fail. So we only verify |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2912 // the region sets when not in a full GC. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2913 if (!silent) { gclog_or_tty->print("HeapRegionSets "); } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2914 verify_region_sets(); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2915 } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2916 |
2152 | 2917 if (!silent) { gclog_or_tty->print("HeapRegions "); } |
390 | 2918 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
2919 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
2920 "sanity check"); | |
2921 | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2922 G1ParVerifyTask task(this, allow_dirty, vo); |
390 | 2923 int n_workers = workers()->total_workers(); |
2924 set_par_threads(n_workers); | |
2925 workers()->run_task(&task); | |
2926 set_par_threads(0); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2927 if (task.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2928 failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2929 } |
390 | 2930 |
2931 assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue), | |
2932 "sanity check"); | |
2933 | |
2934 reset_heap_region_claim_values(); | |
2935 | |
2936 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
2937 "sanity check"); | |
2938 } else { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2939 VerifyRegionClosure blk(allow_dirty, false, vo); |
3766 | 2940 heap_region_iterate(&blk); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2941 if (blk.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2942 failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2943 } |
390 | 2944 } |
2152 | 2945 if (!silent) gclog_or_tty->print("RemSet "); |
342 | 2946 rem_set()->verify(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2947 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2948 if (failures) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2949 gclog_or_tty->print_cr("Heap:"); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2950 print_on(gclog_or_tty, true /* extended */); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2951 gclog_or_tty->print_cr(""); |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1545
diff
changeset
|
2952 #ifndef PRODUCT |
1044 | 2953 if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { |
1388 | 2954 concurrent_mark()->print_reachable("at-verification-failure", |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2955 vo, false /* all */); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2956 } |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1545
diff
changeset
|
2957 #endif |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2958 gclog_or_tty->flush(); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2959 } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2960 guarantee(!failures, "there should not have been any failures"); |
342 | 2961 } else { |
2962 if (!silent) gclog_or_tty->print("(SKIPPING roots, heapRegions, remset) "); | |
2963 } | |
2964 } | |
2965 | |
2966 class PrintRegionClosure: public HeapRegionClosure { | |
2967 outputStream* _st; | |
2968 public: | |
2969 PrintRegionClosure(outputStream* st) : _st(st) {} | |
2970 bool doHeapRegion(HeapRegion* r) { | |
2971 r->print_on(_st); | |
2972 return false; | |
2973 } | |
2974 }; | |
2975 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2976 void G1CollectedHeap::print() const { print_on(tty); } |
342 | 2977 |
2978 void G1CollectedHeap::print_on(outputStream* st) const { | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2979 print_on(st, PrintHeapAtGCExtended); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2980 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2981 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2982 void G1CollectedHeap::print_on(outputStream* st, bool extended) const { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2983 st->print(" %-20s", "garbage-first heap"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2984 st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", |
846
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2985 capacity()/K, used_unlocked()/K); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2986 st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2987 _g1_storage.low_boundary(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2988 _g1_storage.high(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2989 _g1_storage.high_boundary()); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2990 st->cr(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2991 st->print(" region size " SIZE_FORMAT "K, ", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2992 HeapRegion::GrainBytes/K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2993 size_t young_regions = _young_list->length(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2994 st->print(SIZE_FORMAT " young (" SIZE_FORMAT "K), ", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2995 young_regions, young_regions * HeapRegion::GrainBytes / K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2996 size_t survivor_regions = g1_policy()->recorded_survivor_regions(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2997 st->print(SIZE_FORMAT " survivors (" SIZE_FORMAT "K)", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2998 survivor_regions, survivor_regions * HeapRegion::GrainBytes / K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2999 st->cr(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3000 perm()->as_gen()->print_on(st); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3001 if (extended) { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3002 st->cr(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3003 print_on_extended(st); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3004 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3005 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3006 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3007 void G1CollectedHeap::print_on_extended(outputStream* st) const { |
342 | 3008 PrintRegionClosure blk(st); |
3766 | 3009 heap_region_iterate(&blk); |
342 | 3010 } |
3011 | |
3012 void G1CollectedHeap::print_gc_threads_on(outputStream* st) const { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
3013 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1019 | 3014 workers()->print_worker_threads_on(st); |
3015 } | |
3016 _cmThread->print_on(st); | |
342 | 3017 st->cr(); |
1019 | 3018 _cm->print_worker_threads_on(st); |
3019 _cg1r->print_worker_threads_on(st); | |
342 | 3020 st->cr(); |
3021 } | |
3022 | |
3023 void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
3024 if (G1CollectedHeap::use_parallel_gc_threads()) { |
342 | 3025 workers()->threads_do(tc); |
3026 } | |
3027 tc->do_thread(_cmThread); | |
794 | 3028 _cg1r->threads_do(tc); |
342 | 3029 } |
3030 | |
3031 void G1CollectedHeap::print_tracing_info() const { | |
3032 // We'll overload this to mean "trace GC pause statistics." | |
3033 if (TraceGen0Time || TraceGen1Time) { | |
3034 // The "G1CollectorPolicy" is keeping track of these stats, so delegate | |
3035 // to that. | |
3036 g1_policy()->print_tracing_info(); | |
3037 } | |
751 | 3038 if (G1SummarizeRSetStats) { |
342 | 3039 g1_rem_set()->print_summary_info(); |
3040 } | |
1282 | 3041 if (G1SummarizeConcMark) { |
342 | 3042 concurrent_mark()->print_summary_info(); |
3043 } | |
3044 g1_policy()->print_yg_surv_rate_info(); | |
3045 SpecializationStats::print(); | |
3046 } | |
3047 | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3048 #ifndef PRODUCT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3049 // Helpful for debugging RSet issues. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3050 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3051 class PrintRSetsClosure : public HeapRegionClosure { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3052 private: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3053 const char* _msg; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3054 size_t _occupied_sum; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3055 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3056 public: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3057 bool doHeapRegion(HeapRegion* r) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3058 HeapRegionRemSet* hrrs = r->rem_set(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3059 size_t occupied = hrrs->occupied(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3060 _occupied_sum += occupied; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3061 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3062 gclog_or_tty->print_cr("Printing RSet for region "HR_FORMAT, |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3063 HR_FORMAT_PARAMS(r)); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3064 if (occupied == 0) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3065 gclog_or_tty->print_cr(" RSet is empty"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3066 } else { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3067 hrrs->print(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3068 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3069 gclog_or_tty->print_cr("----------"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3070 return false; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3071 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3072 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3073 PrintRSetsClosure(const char* msg) : _msg(msg), _occupied_sum(0) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3074 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3075 gclog_or_tty->print_cr("========================================"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3076 gclog_or_tty->print_cr(msg); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3077 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3078 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3079 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3080 ~PrintRSetsClosure() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3081 gclog_or_tty->print_cr("Occupied Sum: "SIZE_FORMAT, _occupied_sum); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3082 gclog_or_tty->print_cr("========================================"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3083 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3084 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3085 }; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3086 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3087 void G1CollectedHeap::print_cset_rsets() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3088 PrintRSetsClosure cl("Printing CSet RSets"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3089 collection_set_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3090 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3091 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3092 void G1CollectedHeap::print_all_rsets() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3093 PrintRSetsClosure cl("Printing All RSets");; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3094 heap_region_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3095 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3096 #endif // PRODUCT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3097 |
342 | 3098 G1CollectedHeap* G1CollectedHeap::heap() { |
3099 assert(_sh->kind() == CollectedHeap::G1CollectedHeap, | |
3100 "not a garbage-first heap"); | |
3101 return _g1h; | |
3102 } | |
3103 | |
3104 void G1CollectedHeap::gc_prologue(bool full /* Ignored */) { | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1166
diff
changeset
|
3105 // always_do_update_barrier = false; |
342 | 3106 assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); |
3107 // Call allocation profiler | |
3108 AllocationProfiler::iterate_since_last_gc(); | |
3109 // Fill TLAB's and such | |
3110 ensure_parsability(true); | |
3111 } | |
3112 | |
3113 void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { | |
3114 // FIXME: what is this about? | |
3115 // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled" | |
3116 // is set. | |
3117 COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), | |
3118 "derived pointer present")); | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1166
diff
changeset
|
3119 // always_do_update_barrier = true; |
342 | 3120 } |
3121 | |
1973 | 3122 HeapWord* G1CollectedHeap::do_collection_pause(size_t word_size, |
3123 unsigned int gc_count_before, | |
3124 bool* succeeded) { | |
3125 assert_heap_not_locked_and_not_at_safepoint(); | |
342 | 3126 g1_policy()->record_stop_world_start(); |
1973 | 3127 VM_G1IncCollectionPause op(gc_count_before, |
3128 word_size, | |
3129 false, /* should_initiate_conc_mark */ | |
3130 g1_policy()->max_pause_time_ms(), | |
3131 GCCause::_g1_inc_collection_pause); | |
3132 VMThread::execute(&op); | |
3133 | |
3134 HeapWord* result = op.result(); | |
3135 bool ret_succeeded = op.prologue_succeeded() && op.pause_succeeded(); | |
3136 assert(result == NULL || ret_succeeded, | |
3137 "the result should be NULL if the VM did not succeed"); | |
3138 *succeeded = ret_succeeded; | |
3139 | |
3140 assert_heap_not_locked(); | |
3141 return result; | |
342 | 3142 } |
3143 | |
3144 void | |
3145 G1CollectedHeap::doConcurrentMark() { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3146 MutexLockerEx x(CGC_lock, Mutex::_no_safepoint_check_flag); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3147 if (!_cmThread->in_progress()) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3148 _cmThread->set_started(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3149 CGC_lock->notify(); |
342 | 3150 } |
3151 } | |
3152 | |
3153 // <NEW PREDICTION> | |
3154 | |
3155 double G1CollectedHeap::predict_region_elapsed_time_ms(HeapRegion *hr, | |
3156 bool young) { | |
3157 return _g1_policy->predict_region_elapsed_time_ms(hr, young); | |
3158 } | |
3159 | |
3160 void G1CollectedHeap::check_if_region_is_too_expensive(double | |
3161 predicted_time_ms) { | |
3162 _g1_policy->check_if_region_is_too_expensive(predicted_time_ms); | |
3163 } | |
3164 | |
3165 size_t G1CollectedHeap::pending_card_num() { | |
3166 size_t extra_cards = 0; | |
3167 JavaThread *curr = Threads::first(); | |
3168 while (curr != NULL) { | |
3169 DirtyCardQueue& dcq = curr->dirty_card_queue(); | |
3170 extra_cards += dcq.size(); | |
3171 curr = curr->next(); | |
3172 } | |
3173 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
3174 size_t buffer_size = dcqs.buffer_size(); | |
3175 size_t buffer_num = dcqs.completed_buffers_num(); | |
3176 return buffer_size * buffer_num + extra_cards; | |
3177 } | |
3178 | |
3179 size_t G1CollectedHeap::max_pending_card_num() { | |
3180 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
3181 size_t buffer_size = dcqs.buffer_size(); | |
3182 size_t buffer_num = dcqs.completed_buffers_num(); | |
3183 int thread_num = Threads::number_of_threads(); | |
3184 return (buffer_num + thread_num) * buffer_size; | |
3185 } | |
3186 | |
3187 size_t G1CollectedHeap::cards_scanned() { | |
1861 | 3188 return g1_rem_set()->cardsScanned(); |
342 | 3189 } |
3190 | |
3191 void | |
3192 G1CollectedHeap::setup_surviving_young_words() { | |
3193 guarantee( _surviving_young_words == NULL, "pre-condition" ); | |
3194 size_t array_length = g1_policy()->young_cset_length(); | |
3195 _surviving_young_words = NEW_C_HEAP_ARRAY(size_t, array_length); | |
3196 if (_surviving_young_words == NULL) { | |
3197 vm_exit_out_of_memory(sizeof(size_t) * array_length, | |
3198 "Not enough space for young surv words summary."); | |
3199 } | |
3200 memset(_surviving_young_words, 0, array_length * sizeof(size_t)); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3201 #ifdef ASSERT |
342 | 3202 for (size_t i = 0; i < array_length; ++i) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3203 assert( _surviving_young_words[i] == 0, "memset above" ); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3204 } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3205 #endif // !ASSERT |
342 | 3206 } |
3207 | |
3208 void | |
3209 G1CollectedHeap::update_surviving_young_words(size_t* surv_young_words) { | |
3210 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); | |
3211 size_t array_length = g1_policy()->young_cset_length(); | |
3212 for (size_t i = 0; i < array_length; ++i) | |
3213 _surviving_young_words[i] += surv_young_words[i]; | |
3214 } | |
3215 | |
3216 void | |
3217 G1CollectedHeap::cleanup_surviving_young_words() { | |
3218 guarantee( _surviving_young_words != NULL, "pre-condition" ); | |
3219 FREE_C_HEAP_ARRAY(size_t, _surviving_young_words); | |
3220 _surviving_young_words = NULL; | |
3221 } | |
3222 | |
3223 // </NEW PREDICTION> | |
3224 | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3225 #ifdef ASSERT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3226 class VerifyCSetClosure: public HeapRegionClosure { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3227 public: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3228 bool doHeapRegion(HeapRegion* hr) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3229 // Here we check that the CSet region's RSet is ready for parallel |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3230 // iteration. The fields that we'll verify are only manipulated |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3231 // when the region is part of a CSet and is collected. Afterwards, |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3232 // we reset these fields when we clear the region's RSet (when the |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3233 // region is freed) so they are ready when the region is |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3234 // re-allocated. The only exception to this is if there's an |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3235 // evacuation failure and instead of freeing the region we leave |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3236 // it in the heap. In that case, we reset these fields during |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3237 // evacuation failure handling. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3238 guarantee(hr->rem_set()->verify_ready_for_par_iteration(), "verification"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3239 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3240 // Here's a good place to add any other checks we'd like to |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3241 // perform on CSet regions. |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3242 return false; |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3243 } |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3244 }; |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3245 #endif // ASSERT |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3246 |
1709 | 3247 #if TASKQUEUE_STATS |
3248 void G1CollectedHeap::print_taskqueue_stats_hdr(outputStream* const st) { | |
3249 st->print_raw_cr("GC Task Stats"); | |
3250 st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr(); | |
3251 st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr(); | |
3252 } | |
3253 | |
3254 void G1CollectedHeap::print_taskqueue_stats(outputStream* const st) const { | |
3255 print_taskqueue_stats_hdr(st); | |
3256 | |
3257 TaskQueueStats totals; | |
1755
8e5955ddf8e4
6978300: G1: debug builds crash if ParallelGCThreads==0
jcoomes
parents:
1719
diff
changeset
|
3258 const int n = workers() != NULL ? workers()->total_workers() : 1; |
1709 | 3259 for (int i = 0; i < n; ++i) { |
3260 st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr(); | |
3261 totals += task_queue(i)->stats; | |
3262 } | |
3263 st->print_raw("tot "); totals.print(st); st->cr(); | |
3264 | |
3265 DEBUG_ONLY(totals.verify()); | |
3266 } | |
3267 | |
3268 void G1CollectedHeap::reset_taskqueue_stats() { | |
1755
8e5955ddf8e4
6978300: G1: debug builds crash if ParallelGCThreads==0
jcoomes
parents:
1719
diff
changeset
|
3269 const int n = workers() != NULL ? workers()->total_workers() : 1; |
1709 | 3270 for (int i = 0; i < n; ++i) { |
3271 task_queue(i)->stats.reset(); | |
3272 } | |
3273 } | |
3274 #endif // TASKQUEUE_STATS | |
3275 | |
1973 | 3276 bool |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3277 G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { |
2152 | 3278 assert_at_safepoint(true /* should_be_vm_thread */); |
3279 guarantee(!is_gc_active(), "collection is not reentrant"); | |
3280 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3281 if (GC_locker::check_active_before_gc()) { |
1973 | 3282 return false; |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3283 } |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3284 |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
2039
diff
changeset
|
3285 SvcGCMarker sgcm(SvcGCMarker::MINOR); |
2039
7c5250dbd584
6896624: G1: hotspot:::gc and hotspot:::mem-pool-gc probes are not fired
tonyp
parents:
2038
diff
changeset
|
3286 ResourceMark rm; |
7c5250dbd584
6896624: G1: hotspot:::gc and hotspot:::mem-pool-gc probes are not fired
tonyp
parents:
2038
diff
changeset
|
3287 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3288 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3289 Universe::print_heap_before_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3290 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3291 |
2152 | 3292 verify_region_sets_optional(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3293 verify_dirty_young_regions(); |
2152 | 3294 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3295 { |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3296 // This call will decide whether this pause is an initial-mark |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3297 // pause. If it is, during_initial_mark_pause() will return true |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3298 // for the duration of this pause. |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3299 g1_policy()->decide_on_conc_mark_initiation(); |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3300 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3301 char verbose_str[128]; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3302 sprintf(verbose_str, "GC pause "); |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3303 if (g1_policy()->full_young_gcs()) { |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3304 strcat(verbose_str, "(young)"); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3305 } else { |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3306 strcat(verbose_str, "(partial)"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3307 } |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3308 if (g1_policy()->during_initial_mark_pause()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3309 strcat(verbose_str, " (initial-mark)"); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3310 // We are about to start a marking cycle, so we increment the |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3311 // full collection counter. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3312 increment_total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3313 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3314 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3315 // if PrintGCDetails is on, we'll print long statistics information |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3316 // in the collector policy code, so let's not print this as the output |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3317 // is messy if we do. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3318 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3319 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3320 TraceTime t(verbose_str, PrintGC && !PrintGCDetails, true, gclog_or_tty); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3321 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3322 TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
3323
diff
changeset
|
3323 TraceMemoryManagerStats tms(false /* fullGC */, gc_cause()); |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
3324 |
2361 | 3325 // If the secondary_free_list is not empty, append it to the |
3326 // free_list. No need to wait for the cleanup operation to finish; | |
3327 // the region allocation code will check the secondary_free_list | |
3328 // and wait if necessary. If the G1StressConcRegionFreeing flag is | |
3329 // set, skip this step so that the region allocation code has to | |
3330 // get entries from the secondary_free_list. | |
2152 | 3331 if (!G1StressConcRegionFreeing) { |
2361 | 3332 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 3333 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3334 |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3335 assert(check_young_list_well_formed(), |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3336 "young list should be well formed"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3337 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3338 { // Call to jvmpi::post_class_unload_events must occur outside of active GC |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3339 IsGCActiveMark x; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3340 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3341 gc_prologue(false); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3342 increment_total_collections(false /* full gc */); |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3343 increment_gc_time_stamp(); |
342 | 3344 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3345 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3346 HandleMark hm; // Discard invalid handles created during verification |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3347 gclog_or_tty->print(" VerifyBeforeGC:"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3348 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3349 Universe::verify(/* allow dirty */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3350 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3351 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3352 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3353 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3354 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3355 COMPILER2_PRESENT(DerivedPointerTable::clear()); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3356 |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
3357 // Please see comment in G1CollectedHeap::ref_processing_init() |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
3358 // to see how reference processing currently works in G1. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
3359 // |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3360 // We want to turn off ref discovery, if necessary, and turn it back on |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3361 // on again later if we do. XXX Dubious: why is discovery disabled? |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3362 bool was_enabled = ref_processor()->discovery_enabled(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3363 if (was_enabled) ref_processor()->disable_discovery(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3364 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3365 // Forget the current alloc region (we might even choose it to be part |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3366 // of the collection set!). |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3367 release_mutator_alloc_region(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3368 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3369 // We should call this after we retire the mutator alloc |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3370 // region(s) so that all the ALLOC / RETIRE events are generated |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3371 // before the start GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3372 _hr_printer.start_gc(false /* full */, (size_t) total_collections()); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3373 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3374 // The elapsed time induced by the start time below deliberately elides |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3375 // the possible verification above. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3376 double start_time_sec = os::elapsedTime(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3377 size_t start_used_bytes = used(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3378 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3379 #if YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3380 gclog_or_tty->print_cr("\nBefore recording pause start.\nYoung_list:"); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3381 _young_list->print(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3382 g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3383 #endif // YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3384 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3385 g1_policy()->record_collection_pause_start(start_time_sec, |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3386 start_used_bytes); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3387 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3388 #if YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3389 gclog_or_tty->print_cr("\nAfter recording pause start.\nYoung_list:"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3390 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3391 #endif // YOUNG_LIST_VERBOSE |
342 | 3392 |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3393 if (g1_policy()->during_initial_mark_pause()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3394 concurrent_mark()->checkpointRootsInitialPre(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3395 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3396 perm_gen()->save_marks(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3397 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3398 // We must do this before any possible evacuation that should propagate |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3399 // marks. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3400 if (mark_in_progress()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3401 double start_time_sec = os::elapsedTime(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3402 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3403 _cm->drainAllSATBBuffers(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3404 double finish_mark_ms = (os::elapsedTime() - start_time_sec) * 1000.0; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3405 g1_policy()->record_satb_drain_time(finish_mark_ms); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3406 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3407 // Record the number of elements currently on the mark stack, so we |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3408 // only iterate over these. (Since evacuation may add to the mark |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3409 // stack, doing more exposes race conditions.) If no mark is in |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3410 // progress, this will be zero. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3411 _cm->set_oops_do_bound(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3412 |
3378
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3413 if (mark_in_progress()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3414 concurrent_mark()->newCSet(); |
3378
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3415 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3416 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3417 #if YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3418 gclog_or_tty->print_cr("\nBefore choosing collection set.\nYoung_list:"); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3419 _young_list->print(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3420 g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3421 #endif // YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3422 |
1707 | 3423 g1_policy()->choose_collection_set(target_pause_time_ms); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3424 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3425 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3426 HeapRegion* hr = g1_policy()->collection_set(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3427 while (hr != NULL) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3428 G1HRPrinter::RegionType type; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3429 if (!hr->is_young()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3430 type = G1HRPrinter::Old; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3431 } else if (hr->is_survivor()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3432 type = G1HRPrinter::Survivor; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3433 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3434 type = G1HRPrinter::Eden; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3435 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3436 _hr_printer.cset(hr); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3437 hr = hr->next_in_collection_set(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3438 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3439 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3440 |
3378
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3441 // We have chosen the complete collection set. If marking is |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3442 // active then, we clear the region fields of any of the |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3443 // concurrent marking tasks whose region fields point into |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3444 // the collection set as these values will become stale. This |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3445 // will cause the owning marking threads to claim a new region |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3446 // when marking restarts. |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3447 if (mark_in_progress()) { |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3448 concurrent_mark()->reset_active_task_region_fields_in_cset(); |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3449 } |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3450 |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3451 #ifdef ASSERT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3452 VerifyCSetClosure cl; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3453 collection_set_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3454 #endif // ASSERT |
1707 | 3455 |
3456 setup_surviving_young_words(); | |
3457 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3458 // Initialize the GC alloc regions. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3459 init_gc_alloc_regions(); |
1707 | 3460 |
3461 // Actually do the work... | |
3462 evacuate_collection_set(); | |
3463 | |
3464 free_collection_set(g1_policy()->collection_set()); | |
3465 g1_policy()->clear_collection_set(); | |
3466 | |
3467 cleanup_surviving_young_words(); | |
3468 | |
3469 // Start a new incremental collection set for the next pause. | |
3470 g1_policy()->start_incremental_cset_building(); | |
3471 | |
3472 // Clear the _cset_fast_test bitmap in anticipation of adding | |
3473 // regions to the incremental collection set for the next | |
3474 // evacuation pause. | |
3475 clear_cset_fast_test(); | |
3476 | |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3477 _young_list->reset_sampled_info(); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3478 |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3479 // Don't check the whole heap at this point as the |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3480 // GC alloc regions from this pause have been tagged |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3481 // as survivors and moved on to the survivor list. |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3482 // Survivor regions will fail the !is_young() check. |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3483 assert(check_young_list_empty(false /* check_heap */), |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3484 "young list should be empty"); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3485 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3486 #if YOUNG_LIST_VERBOSE |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3487 gclog_or_tty->print_cr("Before recording survivors.\nYoung List:"); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3488 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3489 #endif // YOUNG_LIST_VERBOSE |
342 | 3490 |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3491 g1_policy()->record_survivor_regions(_young_list->survivor_length(), |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3492 _young_list->first_survivor_region(), |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3493 _young_list->last_survivor_region()); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3494 |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3495 _young_list->reset_auxilary_lists(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3496 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3497 if (evacuation_failed()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3498 _summary_bytes_used = recalculate_used(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3499 } else { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3500 // The "used" of the the collection set have already been subtracted |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3501 // when they were freed. Add in the bytes evacuated. |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3502 _summary_bytes_used += g1_policy()->bytes_copied_during_gc(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3503 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3504 |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3505 if (g1_policy()->during_initial_mark_pause()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3506 concurrent_mark()->checkpointRootsInitialPost(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3507 set_marking_started(); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3508 // CAUTION: after the doConcurrentMark() call below, |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3509 // the concurrent marking thread(s) could be running |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3510 // concurrently with us. Make sure that anything after |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3511 // this point does not assume that we are the only GC thread |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3512 // running. Note: of course, the actual marking work will |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3513 // not start until the safepoint itself is released in |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3514 // ConcurrentGCThread::safepoint_desynchronize(). |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3515 doConcurrentMark(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3516 } |
342 | 3517 |
3285
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
3518 allocate_dummy_regions(); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
3519 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3520 #if YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3521 gclog_or_tty->print_cr("\nEnd of the pause.\nYoung_list:"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3522 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3523 g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3524 #endif // YOUNG_LIST_VERBOSE |
342 | 3525 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3526 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3527 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3528 double end_time_sec = os::elapsedTime(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3529 double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3530 g1_policy()->record_pause_time_ms(pause_time_ms); |
1707 | 3531 g1_policy()->record_collection_pause_end(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3532 |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
3533 MemoryService::track_memory_usage(); |
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
3534 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3535 // In prepare_for_verify() below we'll need to scan the deferred |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3536 // update buffers to bring the RSets up-to-date if |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3537 // G1HRRSFlushLogBuffersOnVerify has been set. While scanning |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3538 // the update buffers we'll probably need to scan cards on the |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3539 // regions we just allocated to (i.e., the GC alloc |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3540 // regions). However, during the last GC we called |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3541 // set_saved_mark() on all the GC alloc regions, so card |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3542 // scanning might skip the [saved_mark_word()...top()] area of |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3543 // those regions (i.e., the area we allocated objects into |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3544 // during the last GC). But it shouldn't. Given that |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3545 // saved_mark_word() is conditional on whether the GC time stamp |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3546 // on the region is current or not, by incrementing the GC time |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3547 // stamp here we invalidate all the GC time stamps on all the |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3548 // regions and saved_mark_word() will simply return top() for |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3549 // all the regions. This is a nicer way of ensuring this rather |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3550 // than iterating over the regions and fixing them. In fact, the |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3551 // GC time stamp increment here also ensures that |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3552 // saved_mark_word() will return top() between pauses, i.e., |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3553 // during concurrent refinement. So we don't need the |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3554 // is_gc_active() check to decided which top to use when |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3555 // scanning cards (see CR 7039627). |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3556 increment_gc_time_stamp(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3557 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3558 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3559 HandleMark hm; // Discard invalid handles created during verification |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3560 gclog_or_tty->print(" VerifyAfterGC:"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3561 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3562 Universe::verify(/* allow dirty */ true, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3563 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3564 /* option */ VerifyOption_G1UsePrevMarking); |
342 | 3565 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3566 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3567 if (was_enabled) ref_processor()->enable_discovery(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3568 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3569 { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3570 size_t expand_bytes = g1_policy()->expansion_amount(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3571 if (expand_bytes > 0) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3572 size_t bytes_before = capacity(); |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
3573 // No need for an ergo verbose message here, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
3574 // expansion_amount() does this when it returns a value > 0. |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3575 if (!expand(expand_bytes)) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3576 // We failed to expand the heap so let's verify that |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3577 // committed/uncommitted amount match the backing store |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3578 assert(capacity() == _g1_storage.committed_size(), "committed size mismatch"); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3579 assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch"); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3580 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3581 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3582 } |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3583 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3584 // We should do this after we potentially expand the heap so |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3585 // that all the COMMIT events are generated before the end GC |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3586 // event, and after we retire the GC alloc regions so that all |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3587 // RETIRE events are generated before the end GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3588 _hr_printer.end_gc(false /* full */, (size_t) total_collections()); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3589 |
3764
053d84a76d3d
7032531: G1: enhance GC logging to include more accurate eden / survivor size transitions
tonyp
parents:
3378
diff
changeset
|
3590 // We have to do this after we decide whether to expand the heap or not. |
053d84a76d3d
7032531: G1: enhance GC logging to include more accurate eden / survivor size transitions
tonyp
parents:
3378
diff
changeset
|
3591 g1_policy()->print_heap_transition(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3592 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3593 if (mark_in_progress()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3594 concurrent_mark()->update_g1_committed(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3595 } |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3596 |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3597 #ifdef TRACESPINNING |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3598 ParallelTaskTerminator::print_termination_counts(); |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3599 #endif |
342 | 3600 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3601 gc_epilogue(false); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3602 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3603 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3604 if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3605 gclog_or_tty->print_cr("Stopping after GC #%d", ExitAfterGCNum); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3606 print_tracing_info(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3607 vm_exit(-1); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3608 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3609 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3610 |
3766 | 3611 _hrs.verify_optional(); |
2152 | 3612 verify_region_sets_optional(); |
3613 | |
1709 | 3614 TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats()); |
3615 TASKQUEUE_STATS_ONLY(reset_taskqueue_stats()); | |
3616 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3617 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3618 Universe::print_heap_after_gc(); |
342 | 3619 } |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3620 g1mm()->update_counters(); |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3621 |
884
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3622 if (G1SummarizeRSetStats && |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3623 (G1SummarizeRSetStatsPeriod > 0) && |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3624 (total_collections() % G1SummarizeRSetStatsPeriod == 0)) { |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3625 g1_rem_set()->print_summary_info(); |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3626 } |
1973 | 3627 |
3628 return true; | |
342 | 3629 } |
3630 | |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3631 size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose) |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3632 { |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3633 size_t gclab_word_size; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3634 switch (purpose) { |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3635 case GCAllocForSurvived: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3636 gclab_word_size = YoungPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3637 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3638 case GCAllocForTenured: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3639 gclab_word_size = OldPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3640 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3641 default: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3642 assert(false, "unknown GCAllocPurpose"); |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3643 gclab_word_size = OldPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3644 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3645 } |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3646 return gclab_word_size; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3647 } |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3648 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3649 void G1CollectedHeap::init_mutator_alloc_region() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3650 assert(_mutator_alloc_region.get() == NULL, "pre-condition"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3651 _mutator_alloc_region.init(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3652 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3653 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3654 void G1CollectedHeap::release_mutator_alloc_region() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3655 _mutator_alloc_region.release(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3656 assert(_mutator_alloc_region.get() == NULL, "post-condition"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3657 } |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3658 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3659 void G1CollectedHeap::init_gc_alloc_regions() { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3660 assert_at_safepoint(true /* should_be_vm_thread */); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3661 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3662 _survivor_gc_alloc_region.init(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3663 _old_gc_alloc_region.init(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3664 HeapRegion* retained_region = _retained_old_gc_alloc_region; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3665 _retained_old_gc_alloc_region = NULL; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3666 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3667 // We will discard the current GC alloc region if: |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3668 // a) it's in the collection set (it can happen!), |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3669 // b) it's already full (no point in using it), |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3670 // c) it's empty (this means that it was emptied during |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3671 // a cleanup and it should be on the free list now), or |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3672 // d) it's humongous (this means that it was emptied |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3673 // during a cleanup and was added to the free list, but |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3674 // has been subseqently used to allocate a humongous |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3675 // object that may be less than the region size). |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3676 if (retained_region != NULL && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3677 !retained_region->in_collection_set() && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3678 !(retained_region->top() == retained_region->end()) && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3679 !retained_region->is_empty() && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3680 !retained_region->isHumongous()) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3681 retained_region->set_saved_mark(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3682 _old_gc_alloc_region.set(retained_region); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3683 _hr_printer.reuse(retained_region); |
342 | 3684 } |
3685 } | |
3686 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3687 void G1CollectedHeap::release_gc_alloc_regions() { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3688 _survivor_gc_alloc_region.release(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3689 // If we have an old GC alloc region to release, we'll save it in |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3690 // _retained_old_gc_alloc_region. If we don't |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3691 // _retained_old_gc_alloc_region will become NULL. This is what we |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3692 // want either way so no reason to check explicitly for either |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3693 // condition. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3694 _retained_old_gc_alloc_region = _old_gc_alloc_region.release(); |
342 | 3695 } |
3696 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3697 void G1CollectedHeap::abandon_gc_alloc_regions() { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3698 assert(_survivor_gc_alloc_region.get() == NULL, "pre-condition"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3699 assert(_old_gc_alloc_region.get() == NULL, "pre-condition"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3700 _retained_old_gc_alloc_region = NULL; |
342 | 3701 } |
3702 | |
3703 void G1CollectedHeap::init_for_evac_failure(OopsInHeapRegionClosure* cl) { | |
3704 _drain_in_progress = false; | |
3705 set_evac_failure_closure(cl); | |
3706 _evac_failure_scan_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true); | |
3707 } | |
3708 | |
3709 void G1CollectedHeap::finalize_for_evac_failure() { | |
3710 assert(_evac_failure_scan_stack != NULL && | |
3711 _evac_failure_scan_stack->length() == 0, | |
3712 "Postcondition"); | |
3713 assert(!_drain_in_progress, "Postcondition"); | |
1045 | 3714 delete _evac_failure_scan_stack; |
342 | 3715 _evac_failure_scan_stack = NULL; |
3716 } | |
3717 | |
3718 // *** Sequential G1 Evacuation | |
3719 | |
3720 class G1IsAliveClosure: public BoolObjectClosure { | |
3721 G1CollectedHeap* _g1; | |
3722 public: | |
3723 G1IsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} | |
3724 void do_object(oop p) { assert(false, "Do not call."); } | |
3725 bool do_object_b(oop p) { | |
3726 // It is reachable if it is outside the collection set, or is inside | |
3727 // and forwarded. | |
3728 return !_g1->obj_in_cs(p) || p->is_forwarded(); | |
3729 } | |
3730 }; | |
3731 | |
3732 class G1KeepAliveClosure: public OopClosure { | |
3733 G1CollectedHeap* _g1; | |
3734 public: | |
3735 G1KeepAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3736 void do_oop(narrowOop* p) { guarantee(false, "Not needed"); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3737 void do_oop( oop* p) { |
342 | 3738 oop obj = *p; |
3739 if (_g1->obj_in_cs(obj)) { | |
3740 assert( obj->is_forwarded(), "invariant" ); | |
3741 *p = obj->forwardee(); | |
3742 } | |
3743 } | |
3744 }; | |
3745 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3746 class UpdateRSetDeferred : public OopsInHeapRegionClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3747 private: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3748 G1CollectedHeap* _g1; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3749 DirtyCardQueue *_dcq; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3750 CardTableModRefBS* _ct_bs; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3751 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3752 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3753 UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) : |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3754 _g1(g1), _ct_bs((CardTableModRefBS*)_g1->barrier_set()), _dcq(dcq) {} |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3755 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3756 virtual void do_oop(narrowOop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3757 virtual void do_oop( oop* p) { do_oop_work(p); } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3758 template <class T> void do_oop_work(T* p) { |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3759 assert(_from->is_in_reserved(p), "paranoia"); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3760 if (!_from->is_in_reserved(oopDesc::load_decode_heap_oop(p)) && |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3761 !_from->is_survivor()) { |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3762 size_t card_index = _ct_bs->index_for(p); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3763 if (_ct_bs->mark_card_deferred(card_index)) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3764 _dcq->enqueue((jbyte*)_ct_bs->byte_for_index(card_index)); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3765 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3766 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3767 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3768 }; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3769 |
342 | 3770 class RemoveSelfPointerClosure: public ObjectClosure { |
3771 private: | |
3772 G1CollectedHeap* _g1; | |
3773 ConcurrentMark* _cm; | |
3774 HeapRegion* _hr; | |
3775 size_t _prev_marked_bytes; | |
3776 size_t _next_marked_bytes; | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3777 OopsInHeapRegionClosure *_cl; |
342 | 3778 public: |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3779 RemoveSelfPointerClosure(G1CollectedHeap* g1, HeapRegion* hr, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3780 OopsInHeapRegionClosure* cl) : |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3781 _g1(g1), _hr(hr), _cm(_g1->concurrent_mark()), _prev_marked_bytes(0), |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3782 _next_marked_bytes(0), _cl(cl) {} |
342 | 3783 |
3784 size_t prev_marked_bytes() { return _prev_marked_bytes; } | |
3785 size_t next_marked_bytes() { return _next_marked_bytes; } | |
3786 | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3787 // <original comment> |
352
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3788 // The original idea here was to coalesce evacuated and dead objects. |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3789 // However that caused complications with the block offset table (BOT). |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3790 // In particular if there were two TLABs, one of them partially refined. |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3791 // |----- TLAB_1--------|----TLAB_2-~~~(partially refined part)~~~| |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3792 // The BOT entries of the unrefined part of TLAB_2 point to the start |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3793 // of TLAB_2. If the last object of the TLAB_1 and the first object |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3794 // of TLAB_2 are coalesced, then the cards of the unrefined part |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3795 // would point into middle of the filler object. |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3796 // The current approach is to not coalesce and leave the BOT contents intact. |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3797 // </original comment> |
352
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3798 // |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3799 // We now reset the BOT when we start the object iteration over the |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3800 // region and refine its entries for every object we come across. So |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3801 // the above comment is not really relevant and we should be able |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3802 // to coalesce dead objects if we want to. |
352
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3803 void do_object(oop obj) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3804 HeapWord* obj_addr = (HeapWord*) obj; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3805 assert(_hr->is_in(obj_addr), "sanity"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3806 size_t obj_size = obj->size(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3807 _hr->update_bot_for_object(obj_addr, obj_size); |
352
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3808 if (obj->is_forwarded() && obj->forwardee() == obj) { |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3809 // The object failed to move. |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3810 assert(!_g1->is_obj_dead(obj), "We should not be preserving dead objs."); |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3811 _cm->markPrev(obj); |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3812 assert(_cm->isPrevMarked(obj), "Should be marked!"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3813 _prev_marked_bytes += (obj_size * HeapWordSize); |
352
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3814 if (_g1->mark_in_progress() && !_g1->is_obj_ill(obj)) { |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3815 _cm->markAndGrayObjectIfNecessary(obj); |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3816 } |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3817 obj->set_mark(markOopDesc::prototype()); |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3818 // While we were processing RSet buffers during the |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3819 // collection, we actually didn't scan any cards on the |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3820 // collection set, since we didn't want to update remebered |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3821 // sets with entries that point into the collection set, given |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3822 // that live objects fromthe collection set are about to move |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3823 // and such entries will be stale very soon. This change also |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3824 // dealt with a reliability issue which involved scanning a |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3825 // card in the collection set and coming across an array that |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3826 // was being chunked and looking malformed. The problem is |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3827 // that, if evacuation fails, we might have remembered set |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3828 // entries missing given that we skipped cards on the |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3829 // collection set. So, we'll recreate such entries now. |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3830 obj->oop_iterate(_cl); |
352
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3831 assert(_cm->isPrevMarked(obj), "Should be marked!"); |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3832 } else { |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3833 // The object has been either evacuated or is dead. Fill it with a |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3834 // dummy object. |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3835 MemRegion mr((HeapWord*)obj, obj_size); |
481
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
3836 CollectedHeap::fill_with_object(mr); |
342 | 3837 _cm->clearRangeBothMaps(mr); |
3838 } | |
3839 } | |
3840 }; | |
3841 | |
3842 void G1CollectedHeap::remove_self_forwarding_pointers() { | |
1705 | 3843 UpdateRSetImmediate immediate_update(_g1h->g1_rem_set()); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3844 DirtyCardQueue dcq(&_g1h->dirty_card_queue_set()); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3845 UpdateRSetDeferred deferred_update(_g1h, &dcq); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3846 OopsInHeapRegionClosure *cl; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3847 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3848 cl = &deferred_update; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3849 } else { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3850 cl = &immediate_update; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3851 } |
342 | 3852 HeapRegion* cur = g1_policy()->collection_set(); |
3853 while (cur != NULL) { | |
3854 assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!"); | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3855 assert(!cur->isHumongous(), "sanity"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3856 |
342 | 3857 if (cur->evacuation_failed()) { |
3858 assert(cur->in_collection_set(), "bad CS"); | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3859 RemoveSelfPointerClosure rspc(_g1h, cur, cl); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3860 |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3861 // In the common case we make sure that this is done when the |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3862 // region is freed so that it is "ready-to-go" when it's |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3863 // re-allocated. However, when evacuation failure happens, a |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3864 // region will remain in the heap and might ultimately be added |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3865 // to a CSet in the future. So we have to be careful here and |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3866 // make sure the region's RSet is ready for parallel iteration |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3867 // whenever this might be required in the future. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3868 cur->rem_set()->reset_for_par_iteration(); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3869 cur->reset_bot(); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3870 cl->set_region(cur); |
342 | 3871 cur->object_iterate(&rspc); |
3872 | |
3873 // A number of manipulations to make the TAMS be the current top, | |
3874 // and the marked bytes be the ones observed in the iteration. | |
3875 if (_g1h->concurrent_mark()->at_least_one_mark_complete()) { | |
3876 // The comments below are the postconditions achieved by the | |
3877 // calls. Note especially the last such condition, which says that | |
3878 // the count of marked bytes has been properly restored. | |
3879 cur->note_start_of_marking(false); | |
3880 // _next_top_at_mark_start == top, _next_marked_bytes == 0 | |
3881 cur->add_to_marked_bytes(rspc.prev_marked_bytes()); | |
3882 // _next_marked_bytes == prev_marked_bytes. | |
3883 cur->note_end_of_marking(); | |
3884 // _prev_top_at_mark_start == top(), | |
3885 // _prev_marked_bytes == prev_marked_bytes | |
3886 } | |
3887 // If there is no mark in progress, we modified the _next variables | |
3888 // above needlessly, but harmlessly. | |
3889 if (_g1h->mark_in_progress()) { | |
3890 cur->note_start_of_marking(false); | |
3891 // _next_top_at_mark_start == top, _next_marked_bytes == 0 | |
3892 // _next_marked_bytes == next_marked_bytes. | |
3893 } | |
3894 | |
3895 // Now make sure the region has the right index in the sorted array. | |
3896 g1_policy()->note_change_in_marked_bytes(cur); | |
3897 } | |
3898 cur = cur->next_in_collection_set(); | |
3899 } | |
3900 assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!"); | |
3901 | |
3902 // Now restore saved marks, if any. | |
3903 if (_objs_with_preserved_marks != NULL) { | |
3904 assert(_preserved_marks_of_objs != NULL, "Both or none."); | |
3905 guarantee(_objs_with_preserved_marks->length() == | |
3906 _preserved_marks_of_objs->length(), "Both or none."); | |
3907 for (int i = 0; i < _objs_with_preserved_marks->length(); i++) { | |
3908 oop obj = _objs_with_preserved_marks->at(i); | |
3909 markOop m = _preserved_marks_of_objs->at(i); | |
3910 obj->set_mark(m); | |
3911 } | |
3912 // Delete the preserved marks growable arrays (allocated on the C heap). | |
3913 delete _objs_with_preserved_marks; | |
3914 delete _preserved_marks_of_objs; | |
3915 _objs_with_preserved_marks = NULL; | |
3916 _preserved_marks_of_objs = NULL; | |
3917 } | |
3918 } | |
3919 | |
3920 void G1CollectedHeap::push_on_evac_failure_scan_stack(oop obj) { | |
3921 _evac_failure_scan_stack->push(obj); | |
3922 } | |
3923 | |
3924 void G1CollectedHeap::drain_evac_failure_scan_stack() { | |
3925 assert(_evac_failure_scan_stack != NULL, "precondition"); | |
3926 | |
3927 while (_evac_failure_scan_stack->length() > 0) { | |
3928 oop obj = _evac_failure_scan_stack->pop(); | |
3929 _evac_failure_closure->set_region(heap_region_containing(obj)); | |
3930 obj->oop_iterate_backwards(_evac_failure_closure); | |
3931 } | |
3932 } | |
3933 | |
3934 oop | |
3935 G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, | |
3936 oop old) { | |
3323
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3937 assert(obj_in_cs(old), |
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3938 err_msg("obj: "PTR_FORMAT" should still be in the CSet", |
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3939 (HeapWord*) old)); |
342 | 3940 markOop m = old->mark(); |
3941 oop forward_ptr = old->forward_to_atomic(old); | |
3942 if (forward_ptr == NULL) { | |
3943 // Forward-to-self succeeded. | |
3944 if (_evac_failure_closure != cl) { | |
3945 MutexLockerEx x(EvacFailureStack_lock, Mutex::_no_safepoint_check_flag); | |
3946 assert(!_drain_in_progress, | |
3947 "Should only be true while someone holds the lock."); | |
3948 // Set the global evac-failure closure to the current thread's. | |
3949 assert(_evac_failure_closure == NULL, "Or locking has failed."); | |
3950 set_evac_failure_closure(cl); | |
3951 // Now do the common part. | |
3952 handle_evacuation_failure_common(old, m); | |
3953 // Reset to NULL. | |
3954 set_evac_failure_closure(NULL); | |
3955 } else { | |
3956 // The lock is already held, and this is recursive. | |
3957 assert(_drain_in_progress, "This should only be the recursive case."); | |
3958 handle_evacuation_failure_common(old, m); | |
3959 } | |
3960 return old; | |
3961 } else { | |
3323
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3962 // Forward-to-self failed. Either someone else managed to allocate |
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3963 // space for this object (old != forward_ptr) or they beat us in |
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3964 // self-forwarding it (old == forward_ptr). |
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3965 assert(old == forward_ptr || !obj_in_cs(forward_ptr), |
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3966 err_msg("obj: "PTR_FORMAT" forwarded to: "PTR_FORMAT" " |
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3967 "should not be in the CSet", |
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3968 (HeapWord*) old, (HeapWord*) forward_ptr)); |
342 | 3969 return forward_ptr; |
3970 } | |
3971 } | |
3972 | |
3973 void G1CollectedHeap::handle_evacuation_failure_common(oop old, markOop m) { | |
3974 set_evacuation_failed(true); | |
3975 | |
3976 preserve_mark_if_necessary(old, m); | |
3977 | |
3978 HeapRegion* r = heap_region_containing(old); | |
3979 if (!r->evacuation_failed()) { | |
3980 r->set_evacuation_failed(true); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3981 _hr_printer.evac_failure(r); |
342 | 3982 } |
3983 | |
3984 push_on_evac_failure_scan_stack(old); | |
3985 | |
3986 if (!_drain_in_progress) { | |
3987 // prevent recursion in copy_to_survivor_space() | |
3988 _drain_in_progress = true; | |
3989 drain_evac_failure_scan_stack(); | |
3990 _drain_in_progress = false; | |
3991 } | |
3992 } | |
3993 | |
3994 void G1CollectedHeap::preserve_mark_if_necessary(oop obj, markOop m) { | |
2038
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
3995 assert(evacuation_failed(), "Oversaving!"); |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
3996 // We want to call the "for_promotion_failure" version only in the |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
3997 // case of a promotion failure. |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
3998 if (m->must_be_preserved_for_promotion_failure(obj)) { |
342 | 3999 if (_objs_with_preserved_marks == NULL) { |
4000 assert(_preserved_marks_of_objs == NULL, "Both or none."); | |
4001 _objs_with_preserved_marks = | |
4002 new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true); | |
4003 _preserved_marks_of_objs = | |
4004 new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true); | |
4005 } | |
4006 _objs_with_preserved_marks->push(obj); | |
4007 _preserved_marks_of_objs->push(m); | |
4008 } | |
4009 } | |
4010 | |
4011 HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose, | |
4012 size_t word_size) { | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4013 if (purpose == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4014 HeapWord* result = survivor_attempt_allocation(word_size); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4015 if (result != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4016 return result; |
342 | 4017 } else { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4018 // Let's try to allocate in the old gen in case we can fit the |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4019 // object there. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4020 return old_attempt_allocation(word_size); |
342 | 4021 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4022 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4023 assert(purpose == GCAllocForTenured, "sanity"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4024 HeapWord* result = old_attempt_allocation(word_size); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4025 if (result != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4026 return result; |
342 | 4027 } else { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4028 // Let's try to allocate in the survivors in case we can fit the |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4029 // object there. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4030 return survivor_attempt_allocation(word_size); |
342 | 4031 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4032 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4033 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4034 ShouldNotReachHere(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4035 // Trying to keep some compilers happy. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4036 return NULL; |
342 | 4037 } |
4038 | |
4039 #ifndef PRODUCT | |
4040 bool GCLabBitMapClosure::do_bit(size_t offset) { | |
4041 HeapWord* addr = _bitmap->offsetToHeapWord(offset); | |
4042 guarantee(_cm->isMarked(oop(addr)), "it should be!"); | |
4043 return true; | |
4044 } | |
4045 #endif // PRODUCT | |
4046 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4047 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4048 ParGCAllocBuffer(gclab_word_size), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4049 _should_mark_objects(false), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4050 _bitmap(G1CollectedHeap::heap()->reserved_region().start(), gclab_word_size), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4051 _retired(false) |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4052 { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4053 //_should_mark_objects is set to true when G1ParCopyHelper needs to |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4054 // mark the forwarded location of an evacuated object. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4055 // We set _should_mark_objects to true if marking is active, i.e. when we |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4056 // need to propagate a mark, or during an initial mark pause, i.e. when we |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4057 // need to mark objects immediately reachable by the roots. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4058 if (G1CollectedHeap::heap()->mark_in_progress() || |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4059 G1CollectedHeap::heap()->g1_policy()->during_initial_mark_pause()) { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4060 _should_mark_objects = true; |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4061 } |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4062 } |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4063 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4064 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4065 : _g1h(g1h), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4066 _refs(g1h->task_queue(queue_num)), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4067 _dcq(&g1h->dirty_card_queue_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4068 _ct_bs((CardTableModRefBS*)_g1h->barrier_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4069 _g1_rem(g1h->g1_rem_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4070 _hash_seed(17), _queue_num(queue_num), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4071 _term_attempts(0), |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4072 _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4073 _tenured_alloc_buffer(g1h->desired_plab_sz(GCAllocForTenured)), |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4074 _age_table(false), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4075 _strong_roots_time(0), _term_time(0), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4076 _alloc_buffer_waste(0), _undo_waste(0) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4077 { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4078 // we allocate G1YoungSurvRateNumRegions plus one entries, since |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4079 // we "sacrifice" entry 0 to keep track of surviving bytes for |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4080 // non-young regions (where the age is -1) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4081 // We also add a few elements at the beginning and at the end in |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4082 // an attempt to eliminate cache contention |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4083 size_t real_length = 1 + _g1h->g1_policy()->young_cset_length(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4084 size_t array_length = PADDING_ELEM_NUM + |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4085 real_length + |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4086 PADDING_ELEM_NUM; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4087 _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4088 if (_surviving_young_words_base == NULL) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4089 vm_exit_out_of_memory(array_length * sizeof(size_t), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4090 "Not enough space for young surv histo."); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4091 _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4092 memset(_surviving_young_words, 0, real_length * sizeof(size_t)); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4093 |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4094 _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4095 _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4096 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4097 _start = os::elapsedTime(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4098 } |
342 | 4099 |
1709 | 4100 void |
4101 G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st) | |
4102 { | |
4103 st->print_raw_cr("GC Termination Stats"); | |
4104 st->print_raw_cr(" elapsed --strong roots-- -------termination-------" | |
4105 " ------waste (KiB)------"); | |
4106 st->print_raw_cr("thr ms ms % ms % attempts" | |
4107 " total alloc undo"); | |
4108 st->print_raw_cr("--- --------- --------- ------ --------- ------ --------" | |
4109 " ------- ------- -------"); | |
4110 } | |
4111 | |
4112 void | |
4113 G1ParScanThreadState::print_termination_stats(int i, | |
4114 outputStream* const st) const | |
4115 { | |
4116 const double elapsed_ms = elapsed_time() * 1000.0; | |
4117 const double s_roots_ms = strong_roots_time() * 1000.0; | |
4118 const double term_ms = term_time() * 1000.0; | |
4119 st->print_cr("%3d %9.2f %9.2f %6.2f " | |
4120 "%9.2f %6.2f " SIZE_FORMAT_W(8) " " | |
4121 SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7), | |
4122 i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms, | |
4123 term_ms, term_ms * 100 / elapsed_ms, term_attempts(), | |
4124 (alloc_buffer_waste() + undo_waste()) * HeapWordSize / K, | |
4125 alloc_buffer_waste() * HeapWordSize / K, | |
4126 undo_waste() * HeapWordSize / K); | |
4127 } | |
4128 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4129 #ifdef ASSERT |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4130 bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4131 assert(ref != NULL, "invariant"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4132 assert(UseCompressedOops, "sanity"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4133 assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref)); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4134 oop p = oopDesc::load_decode_heap_oop(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4135 assert(_g1h->is_in_g1_reserved(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4136 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4137 return true; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4138 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4139 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4140 bool G1ParScanThreadState::verify_ref(oop* ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4141 assert(ref != NULL, "invariant"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4142 if (has_partial_array_mask(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4143 // Must be in the collection set--it's already been copied. |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4144 oop p = clear_partial_array_mask(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4145 assert(_g1h->obj_in_cs(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4146 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4147 } else { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4148 oop p = oopDesc::load_decode_heap_oop(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4149 assert(_g1h->is_in_g1_reserved(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4150 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4151 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4152 return true; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4153 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4154 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4155 bool G1ParScanThreadState::verify_task(StarTask ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4156 if (ref.is_narrow()) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4157 return verify_ref((narrowOop*) ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4158 } else { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4159 return verify_ref((oop*) ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4160 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4161 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4162 #endif // ASSERT |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4163 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4164 void G1ParScanThreadState::trim_queue() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4165 StarTask ref; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4166 do { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4167 // Drain the overflow stack first, so other threads can steal. |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4168 while (refs()->pop_overflow(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4169 deal_with_reference(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4170 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4171 while (refs()->pop_local(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4172 deal_with_reference(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4173 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4174 } while (!refs()->is_empty()); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4175 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4176 |
342 | 4177 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) : |
4178 _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()), | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4179 _par_scan_state(par_scan_state), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4180 _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4181 _mark_in_progress(_g1->mark_in_progress()) { } |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4182 |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4183 template <class T> void G1ParCopyHelper::mark_object(T* p) { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4184 // This is called from do_oop_work for objects that are not |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4185 // in the collection set. Objects in the collection set |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4186 // are marked after they have been evacuated. |
342 | 4187 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4188 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4189 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4190 oop obj = oopDesc::decode_heap_oop(heap_oop); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4191 HeapWord* addr = (HeapWord*)obj; |
3323
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
4192 if (_g1->is_in_g1_reserved(addr)) { |
342 | 4193 _cm->grayRoot(oop(addr)); |
3323
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
4194 } |
342 | 4195 } |
4196 } | |
4197 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4198 oop G1ParCopyHelper::copy_to_survivor_space(oop old, bool should_mark_copy) { |
342 | 4199 size_t word_sz = old->size(); |
4200 HeapRegion* from_region = _g1->heap_region_containing_raw(old); | |
4201 // +1 to make the -1 indexes valid... | |
4202 int young_index = from_region->young_index_in_cset()+1; | |
4203 assert( (from_region->is_young() && young_index > 0) || | |
4204 (!from_region->is_young() && young_index == 0), "invariant" ); | |
4205 G1CollectorPolicy* g1p = _g1->g1_policy(); | |
4206 markOop m = old->mark(); | |
545 | 4207 int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() |
4208 : m->age(); | |
4209 GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, | |
342 | 4210 word_sz); |
4211 HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz); | |
4212 oop obj = oop(obj_ptr); | |
4213 | |
4214 if (obj_ptr == NULL) { | |
4215 // This will either forward-to-self, or detect that someone else has | |
4216 // installed a forwarding pointer. | |
4217 OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure(); | |
4218 return _g1->handle_evacuation_failure_par(cl, old); | |
4219 } | |
4220 | |
526 | 4221 // We're going to allocate linearly, so might as well prefetch ahead. |
4222 Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes); | |
4223 | |
342 | 4224 oop forward_ptr = old->forward_to_atomic(obj); |
4225 if (forward_ptr == NULL) { | |
4226 Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); | |
526 | 4227 if (g1p->track_object_age(alloc_purpose)) { |
4228 // We could simply do obj->incr_age(). However, this causes a | |
4229 // performance issue. obj->incr_age() will first check whether | |
4230 // the object has a displaced mark by checking its mark word; | |
4231 // getting the mark word from the new location of the object | |
4232 // stalls. So, given that we already have the mark word and we | |
4233 // are about to install it anyway, it's better to increase the | |
4234 // age on the mark word, when the object does not have a | |
4235 // displaced mark word. We're not expecting many objects to have | |
4236 // a displaced marked word, so that case is not optimized | |
4237 // further (it could be...) and we simply call obj->incr_age(). | |
4238 | |
4239 if (m->has_displaced_mark_helper()) { | |
4240 // in this case, we have to install the mark word first, | |
4241 // otherwise obj looks to be forwarded (the old mark word, | |
4242 // which contains the forward pointer, was copied) | |
4243 obj->set_mark(m); | |
4244 obj->incr_age(); | |
4245 } else { | |
4246 m = m->incr_age(); | |
545 | 4247 obj->set_mark(m); |
526 | 4248 } |
545 | 4249 _par_scan_state->age_table()->add(obj, word_sz); |
4250 } else { | |
4251 obj->set_mark(m); | |
526 | 4252 } |
4253 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4254 // Mark the evacuated object or propagate "next" mark bit |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4255 if (should_mark_copy) { |
342 | 4256 if (!use_local_bitmaps || |
4257 !_par_scan_state->alloc_buffer(alloc_purpose)->mark(obj_ptr)) { | |
4258 // if we couldn't mark it on the local bitmap (this happens when | |
4259 // the object was not allocated in the GCLab), we have to bite | |
4260 // the bullet and do the standard parallel mark | |
4261 _cm->markAndGrayObjectIfNecessary(obj); | |
4262 } | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4263 |
342 | 4264 if (_g1->isMarkedNext(old)) { |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4265 // Unmark the object's old location so that marking |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4266 // doesn't think the old object is alive. |
342 | 4267 _cm->nextMarkBitMap()->parClear((HeapWord*)old); |
4268 } | |
4269 } | |
4270 | |
4271 size_t* surv_young_words = _par_scan_state->surviving_young_words(); | |
4272 surv_young_words[young_index] += word_sz; | |
4273 | |
4274 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { | |
4275 arrayOop(old)->set_length(0); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4276 oop* old_p = set_partial_array_mask(old); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4277 _par_scan_state->push_on_queue(old_p); |
342 | 4278 } else { |
526 | 4279 // No point in using the slower heap_region_containing() method, |
4280 // given that we know obj is in the heap. | |
4281 _scanner->set_region(_g1->heap_region_containing_raw(obj)); | |
342 | 4282 obj->oop_iterate_backwards(_scanner); |
4283 } | |
4284 } else { | |
4285 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); | |
4286 obj = forward_ptr; | |
4287 } | |
4288 return obj; | |
4289 } | |
4290 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4291 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4292 template <class T> |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4293 void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object> |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4294 ::do_oop_work(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4295 oop obj = oopDesc::load_decode_heap_oop(p); |
342 | 4296 assert(barrier != G1BarrierRS || obj != NULL, |
4297 "Precondition: G1BarrierRS implies obj is nonNull"); | |
4298 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4299 // Marking: |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4300 // If the object is in the collection set, then the thread |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4301 // that copies the object should mark, or propagate the |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4302 // mark to, the evacuated object. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4303 // If the object is not in the collection set then we |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4304 // should call the mark_object() method depending on the |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4305 // value of the template parameter do_mark_object (which will |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4306 // be true for root scanning closures during an initial mark |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4307 // pause). |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4308 // The mark_object() method first checks whether the object |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4309 // is marked and, if not, attempts to mark the object. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4310 |
526 | 4311 // here the null check is implicit in the cset_fast_test() test |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4312 if (_g1->in_cset_fast_test(obj)) { |
526 | 4313 if (obj->is_forwarded()) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4314 oopDesc::encode_store_heap_oop(p, obj->forwardee()); |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4315 // If we are a root scanning closure during an initial |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4316 // mark pause (i.e. do_mark_object will be true) then |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4317 // we also need to handle marking of roots in the |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4318 // event of an evacuation failure. In the event of an |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4319 // evacuation failure, the object is forwarded to itself |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4320 // and not copied so let's mark it here. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4321 if (do_mark_object && obj->forwardee() == obj) { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4322 mark_object(p); |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4323 } |
526 | 4324 } else { |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4325 // We need to mark the copied object if we're a root scanning |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4326 // closure during an initial mark pause (i.e. do_mark_object |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4327 // will be true), or the object is already marked and we need |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4328 // to propagate the mark to the evacuated copy. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4329 bool should_mark_copy = do_mark_object || |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4330 _during_initial_mark || |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4331 (_mark_in_progress && !_g1->is_obj_ill(obj)); |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4332 |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4333 oop copy_oop = copy_to_survivor_space(obj, should_mark_copy); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4334 oopDesc::encode_store_heap_oop(p, copy_oop); |
342 | 4335 } |
526 | 4336 // When scanning the RS, we only care about objs in CS. |
4337 if (barrier == G1BarrierRS) { | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4338 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); |
342 | 4339 } |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4340 } else { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4341 // The object is not in collection set. If we're a root scanning |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4342 // closure during an initial mark pause (i.e. do_mark_object will |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4343 // be true) then attempt to mark the object. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4344 if (do_mark_object) { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4345 mark_object(p); |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4346 } |
526 | 4347 } |
4348 | |
4349 if (barrier == G1BarrierEvac && obj != NULL) { | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4350 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); |
526 | 4351 } |
4352 | |
4353 if (do_gen_barrier && obj != NULL) { | |
4354 par_do_barrier(p); | |
4355 } | |
4356 } | |
4357 | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4358 template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(oop* p); |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4359 template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(narrowOop* p); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4360 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4361 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) { |
526 | 4362 assert(has_partial_array_mask(p), "invariant"); |
4363 oop old = clear_partial_array_mask(p); | |
342 | 4364 assert(old->is_objArray(), "must be obj array"); |
4365 assert(old->is_forwarded(), "must be forwarded"); | |
4366 assert(Universe::heap()->is_in_reserved(old), "must be in heap."); | |
4367 | |
4368 objArrayOop obj = objArrayOop(old->forwardee()); | |
4369 assert((void*)old != (void*)old->forwardee(), "self forwarding here?"); | |
4370 // Process ParGCArrayScanChunk elements now | |
4371 // and push the remainder back onto queue | |
4372 int start = arrayOop(old)->length(); | |
4373 int end = obj->length(); | |
4374 int remainder = end - start; | |
4375 assert(start <= end, "just checking"); | |
4376 if (remainder > 2 * ParGCArrayScanChunk) { | |
4377 // Test above combines last partial chunk with a full chunk | |
4378 end = start + ParGCArrayScanChunk; | |
4379 arrayOop(old)->set_length(end); | |
4380 // Push remainder. | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4381 oop* old_p = set_partial_array_mask(old); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4382 assert(arrayOop(old)->length() < obj->length(), "Empty push?"); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4383 _par_scan_state->push_on_queue(old_p); |
342 | 4384 } else { |
4385 // Restore length so that the heap remains parsable in | |
4386 // case of evacuation failure. | |
4387 arrayOop(old)->set_length(end); | |
4388 } | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4389 _scanner.set_region(_g1->heap_region_containing_raw(obj)); |
342 | 4390 // process our set of indices (include header in first chunk) |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4391 obj->oop_iterate_range(&_scanner, start, end); |
342 | 4392 } |
4393 | |
4394 class G1ParEvacuateFollowersClosure : public VoidClosure { | |
4395 protected: | |
4396 G1CollectedHeap* _g1h; | |
4397 G1ParScanThreadState* _par_scan_state; | |
4398 RefToScanQueueSet* _queues; | |
4399 ParallelTaskTerminator* _terminator; | |
4400 | |
4401 G1ParScanThreadState* par_scan_state() { return _par_scan_state; } | |
4402 RefToScanQueueSet* queues() { return _queues; } | |
4403 ParallelTaskTerminator* terminator() { return _terminator; } | |
4404 | |
4405 public: | |
4406 G1ParEvacuateFollowersClosure(G1CollectedHeap* g1h, | |
4407 G1ParScanThreadState* par_scan_state, | |
4408 RefToScanQueueSet* queues, | |
4409 ParallelTaskTerminator* terminator) | |
4410 : _g1h(g1h), _par_scan_state(par_scan_state), | |
4411 _queues(queues), _terminator(terminator) {} | |
4412 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4413 void do_void(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4414 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4415 private: |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4416 inline bool offer_termination(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4417 }; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4418 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4419 bool G1ParEvacuateFollowersClosure::offer_termination() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4420 G1ParScanThreadState* const pss = par_scan_state(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4421 pss->start_term_time(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4422 const bool res = terminator()->offer_termination(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4423 pss->end_term_time(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4424 return res; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4425 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4426 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4427 void G1ParEvacuateFollowersClosure::do_void() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4428 StarTask stolen_task; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4429 G1ParScanThreadState* const pss = par_scan_state(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4430 pss->trim_queue(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4431 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4432 do { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4433 while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4434 assert(pss->verify_task(stolen_task), "sanity"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4435 if (stolen_task.is_narrow()) { |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4436 pss->deal_with_reference((narrowOop*) stolen_task); |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4437 } else { |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4438 pss->deal_with_reference((oop*) stolen_task); |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4439 } |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4440 |
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4441 // We've just processed a reference and we might have made |
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4442 // available new entries on the queues. So we have to make sure |
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4443 // we drain the queues as necessary. |
342 | 4444 pss->trim_queue(); |
4445 } | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4446 } while (!offer_termination()); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4447 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4448 pss->retire_alloc_buffers(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4449 } |
342 | 4450 |
4451 class G1ParTask : public AbstractGangTask { | |
4452 protected: | |
4453 G1CollectedHeap* _g1h; | |
4454 RefToScanQueueSet *_queues; | |
4455 ParallelTaskTerminator _terminator; | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4456 int _n_workers; |
342 | 4457 |
4458 Mutex _stats_lock; | |
4459 Mutex* stats_lock() { return &_stats_lock; } | |
4460 | |
4461 size_t getNCards() { | |
4462 return (_g1h->capacity() + G1BlockOffsetSharedArray::N_bytes - 1) | |
4463 / G1BlockOffsetSharedArray::N_bytes; | |
4464 } | |
4465 | |
4466 public: | |
4467 G1ParTask(G1CollectedHeap* g1h, int workers, RefToScanQueueSet *task_queues) | |
4468 : AbstractGangTask("G1 collection"), | |
4469 _g1h(g1h), | |
4470 _queues(task_queues), | |
4471 _terminator(workers, _queues), | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4472 _stats_lock(Mutex::leaf, "parallel G1 stats lock", true), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4473 _n_workers(workers) |
342 | 4474 {} |
4475 | |
4476 RefToScanQueueSet* queues() { return _queues; } | |
4477 | |
4478 RefToScanQueue *work_queue(int i) { | |
4479 return queues()->queue(i); | |
4480 } | |
4481 | |
4482 void work(int i) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4483 if (i >= _n_workers) return; // no work needed this round |
1611 | 4484 |
4485 double start_time_ms = os::elapsedTime() * 1000.0; | |
4486 _g1h->g1_policy()->record_gc_worker_start_time(i, start_time_ms); | |
4487 | |
342 | 4488 ResourceMark rm; |
4489 HandleMark hm; | |
4490 | |
526 | 4491 G1ParScanThreadState pss(_g1h, i); |
4492 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss); | |
4493 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss); | |
4494 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss); | |
342 | 4495 |
4496 pss.set_evac_closure(&scan_evac_cl); | |
4497 pss.set_evac_failure_closure(&evac_failure_cl); | |
4498 pss.set_partial_scan_closure(&partial_scan_cl); | |
4499 | |
4500 G1ParScanExtRootClosure only_scan_root_cl(_g1h, &pss); | |
4501 G1ParScanPermClosure only_scan_perm_cl(_g1h, &pss); | |
4502 G1ParScanHeapRSClosure only_scan_heap_rs_cl(_g1h, &pss); | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4503 G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4504 |
342 | 4505 G1ParScanAndMarkExtRootClosure scan_mark_root_cl(_g1h, &pss); |
4506 G1ParScanAndMarkPermClosure scan_mark_perm_cl(_g1h, &pss); | |
4507 G1ParScanAndMarkHeapRSClosure scan_mark_heap_rs_cl(_g1h, &pss); | |
4508 | |
4509 OopsInHeapRegionClosure *scan_root_cl; | |
4510 OopsInHeapRegionClosure *scan_perm_cl; | |
4511 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
4512 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
342 | 4513 scan_root_cl = &scan_mark_root_cl; |
4514 scan_perm_cl = &scan_mark_perm_cl; | |
4515 } else { | |
4516 scan_root_cl = &only_scan_root_cl; | |
4517 scan_perm_cl = &only_scan_perm_cl; | |
4518 } | |
4519 | |
4520 pss.start_strong_roots(); | |
4521 _g1h->g1_process_strong_roots(/* not collecting perm */ false, | |
4522 SharedHeap::SO_AllClasses, | |
4523 scan_root_cl, | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4524 &push_heap_rs_cl, |
342 | 4525 scan_perm_cl, |
4526 i); | |
4527 pss.end_strong_roots(); | |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4528 |
342 | 4529 { |
4530 double start = os::elapsedTime(); | |
4531 G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator); | |
4532 evac.do_void(); | |
4533 double elapsed_ms = (os::elapsedTime()-start)*1000.0; | |
4534 double term_ms = pss.term_time()*1000.0; | |
4535 _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms); | |
1611 | 4536 _g1h->g1_policy()->record_termination(i, term_ms, pss.term_attempts()); |
342 | 4537 } |
1282 | 4538 _g1h->g1_policy()->record_thread_age_table(pss.age_table()); |
342 | 4539 _g1h->update_surviving_young_words(pss.surviving_young_words()+1); |
4540 | |
4541 // Clean up any par-expanded rem sets. | |
4542 HeapRegionRemSet::par_cleanup(); | |
4543 | |
4544 if (ParallelGCVerbose) { | |
1709 | 4545 MutexLocker x(stats_lock()); |
4546 pss.print_termination_stats(i); | |
342 | 4547 } |
4548 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4549 assert(pss.refs()->is_empty(), "should be empty"); |
1611 | 4550 double end_time_ms = os::elapsedTime() * 1000.0; |
4551 _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms); | |
342 | 4552 } |
4553 }; | |
4554 | |
4555 // *** Common G1 Evacuation Stuff | |
4556 | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
4557 // This method is run in a GC worker. |
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
4558 |
342 | 4559 void |
4560 G1CollectedHeap:: | |
4561 g1_process_strong_roots(bool collecting_perm_gen, | |
4562 SharedHeap::ScanningOption so, | |
4563 OopClosure* scan_non_heap_roots, | |
4564 OopsInHeapRegionClosure* scan_rs, | |
4565 OopsInGenClosure* scan_perm, | |
4566 int worker_i) { | |
4567 // First scan the strong roots, including the perm gen. | |
4568 double ext_roots_start = os::elapsedTime(); | |
4569 double closure_app_time_sec = 0.0; | |
4570 | |
4571 BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); | |
4572 BufferingOopsInGenClosure buf_scan_perm(scan_perm); | |
4573 buf_scan_perm.set_generation(perm_gen()); | |
4574 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4575 // Walk the code cache w/o buffering, because StarTask cannot handle |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4576 // unaligned oop locations. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4577 CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, /*do_marking=*/ true); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4578 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4579 process_strong_roots(false, // no scoping; this is parallel code |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4580 collecting_perm_gen, so, |
342 | 4581 &buf_scan_non_heap_roots, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4582 &eager_scan_code_roots, |
342 | 4583 &buf_scan_perm); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4584 |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4585 // Now the ref_processor roots. |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4586 if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) { |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4587 // We need to treat the discovered reference lists as roots and |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4588 // keep entries (which are added by the marking threads) on them |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4589 // live until they can be processed at the end of marking. |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4590 ref_processor()->weak_oops_do(&buf_scan_non_heap_roots); |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4591 } |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4592 |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4593 // Finish up any enqueued closure apps (attributed as object copy time). |
342 | 4594 buf_scan_non_heap_roots.done(); |
4595 buf_scan_perm.done(); | |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4596 |
342 | 4597 double ext_roots_end = os::elapsedTime(); |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4598 |
342 | 4599 g1_policy()->reset_obj_copy_time(worker_i); |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4600 double obj_copy_time_sec = buf_scan_perm.closure_app_seconds() + |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4601 buf_scan_non_heap_roots.closure_app_seconds(); |
342 | 4602 g1_policy()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0); |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4603 |
342 | 4604 double ext_root_time_ms = |
4605 ((ext_roots_end - ext_roots_start) - obj_copy_time_sec) * 1000.0; | |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4606 |
342 | 4607 g1_policy()->record_ext_root_scan_time(worker_i, ext_root_time_ms); |
4608 | |
4609 // Scan strong roots in mark stack. | |
4610 if (!_process_strong_tasks->is_task_claimed(G1H_PS_mark_stack_oops_do)) { | |
4611 concurrent_mark()->oops_do(scan_non_heap_roots); | |
4612 } | |
4613 double mark_stack_scan_ms = (os::elapsedTime() - ext_roots_end) * 1000.0; | |
4614 g1_policy()->record_mark_stack_scan_time(worker_i, mark_stack_scan_ms); | |
4615 | |
4616 // Now scan the complement of the collection set. | |
4617 if (scan_rs != NULL) { | |
4618 g1_rem_set()->oops_into_collection_set_do(scan_rs, worker_i); | |
4619 } | |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4620 |
342 | 4621 _process_strong_tasks->all_tasks_completed(); |
4622 } | |
4623 | |
4624 void | |
4625 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure, | |
4626 OopClosure* non_root_closure) { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4627 CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4628 SharedHeap::process_weak_roots(root_closure, &roots_in_blobs, non_root_closure); |
342 | 4629 } |
4630 | |
4631 void G1CollectedHeap::evacuate_collection_set() { | |
4632 set_evacuation_failed(false); | |
4633 | |
4634 g1_rem_set()->prepare_for_oops_into_collection_set_do(); | |
4635 concurrent_g1_refine()->set_use_cache(false); | |
889 | 4636 concurrent_g1_refine()->clear_hot_cache_claimed_index(); |
4637 | |
342 | 4638 int n_workers = (ParallelGCThreads > 0 ? workers()->total_workers() : 1); |
4639 set_par_threads(n_workers); | |
4640 G1ParTask g1_par_task(this, n_workers, _task_queues); | |
4641 | |
4642 init_for_evac_failure(NULL); | |
4643 | |
4644 rem_set()->prepare_for_younger_refs_iterate(true); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4645 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4646 assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty"); |
342 | 4647 double start_par = os::elapsedTime(); |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
4648 if (G1CollectedHeap::use_parallel_gc_threads()) { |
342 | 4649 // The individual threads will set their evac-failure closures. |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4650 StrongRootsScope srs(this); |
1709 | 4651 if (ParallelGCVerbose) G1ParScanThreadState::print_termination_stats_hdr(); |
342 | 4652 workers()->run_task(&g1_par_task); |
4653 } else { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4654 StrongRootsScope srs(this); |
342 | 4655 g1_par_task.work(0); |
4656 } | |
4657 | |
4658 double par_time = (os::elapsedTime() - start_par) * 1000.0; | |
4659 g1_policy()->record_par_time(par_time); | |
4660 set_par_threads(0); | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
4661 |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
4662 // Weak root processing. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
4663 // Note: when JSR 292 is enabled and code blobs can contain |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
4664 // non-perm oops then we will need to process the code blobs |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
4665 // here too. |
342 | 4666 { |
4667 G1IsAliveClosure is_alive(this); | |
4668 G1KeepAliveClosure keep_alive(this); | |
4669 JNIHandles::weak_oops_do(&is_alive, &keep_alive); | |
4670 } | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4671 release_gc_alloc_regions(); |
342 | 4672 g1_rem_set()->cleanup_after_oops_into_collection_set_do(); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4673 |
889 | 4674 concurrent_g1_refine()->clear_hot_cache(); |
342 | 4675 concurrent_g1_refine()->set_use_cache(true); |
4676 | |
4677 finalize_for_evac_failure(); | |
4678 | |
4679 // Must do this before removing self-forwarding pointers, which clears | |
4680 // the per-region evac-failure flags. | |
4681 concurrent_mark()->complete_marking_in_collection_set(); | |
4682 | |
4683 if (evacuation_failed()) { | |
4684 remove_self_forwarding_pointers(); | |
4685 if (PrintGCDetails) { | |
1719
b63010841f78
6975964: G1: print out a more descriptive message for evacuation failure when +PrintGCDetails is set
tonyp
parents:
1718
diff
changeset
|
4686 gclog_or_tty->print(" (to-space overflow)"); |
342 | 4687 } else if (PrintGC) { |
4688 gclog_or_tty->print("--"); | |
4689 } | |
4690 } | |
4691 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4692 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4693 RedirtyLoggedCardTableEntryFastClosure redirty; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4694 dirty_card_queue_set().set_closure(&redirty); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4695 dirty_card_queue_set().apply_closure_to_all_completed_buffers(); |
1111 | 4696 |
4697 DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set(); | |
4698 dcq.merge_bufferlists(&dirty_card_queue_set()); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4699 assert(dirty_card_queue_set().completed_buffers_num() == 0, "All should be consumed"); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4700 } |
342 | 4701 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); |
4702 } | |
4703 | |
2173 | 4704 void G1CollectedHeap::free_region_if_empty(HeapRegion* hr, |
2152 | 4705 size_t* pre_used, |
4706 FreeRegionList* free_list, | |
4707 HumongousRegionSet* humongous_proxy_set, | |
2173 | 4708 HRRSCleanupTask* hrrs_cleanup_task, |
2152 | 4709 bool par) { |
4710 if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young()) { | |
4711 if (hr->isHumongous()) { | |
4712 assert(hr->startsHumongous(), "we should only see starts humongous"); | |
4713 free_humongous_region(hr, pre_used, free_list, humongous_proxy_set, par); | |
4714 } else { | |
4715 free_region(hr, pre_used, free_list, par); | |
342 | 4716 } |
2173 | 4717 } else { |
4718 hr->rem_set()->do_cleanup_work(hrrs_cleanup_task); | |
342 | 4719 } |
4720 } | |
4721 | |
2152 | 4722 void G1CollectedHeap::free_region(HeapRegion* hr, |
4723 size_t* pre_used, | |
4724 FreeRegionList* free_list, | |
4725 bool par) { | |
4726 assert(!hr->isHumongous(), "this is only for non-humongous regions"); | |
4727 assert(!hr->is_empty(), "the region should not be empty"); | |
4728 assert(free_list != NULL, "pre-condition"); | |
4729 | |
4730 *pre_used += hr->used(); | |
4731 hr->hr_clear(par, true /* clear_space */); | |
2432
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2369
diff
changeset
|
4732 free_list->add_as_head(hr); |
2152 | 4733 } |
4734 | |
4735 void G1CollectedHeap::free_humongous_region(HeapRegion* hr, | |
4736 size_t* pre_used, | |
4737 FreeRegionList* free_list, | |
4738 HumongousRegionSet* humongous_proxy_set, | |
4739 bool par) { | |
4740 assert(hr->startsHumongous(), "this is only for starts humongous regions"); | |
4741 assert(free_list != NULL, "pre-condition"); | |
4742 assert(humongous_proxy_set != NULL, "pre-condition"); | |
4743 | |
4744 size_t hr_used = hr->used(); | |
4745 size_t hr_capacity = hr->capacity(); | |
4746 size_t hr_pre_used = 0; | |
4747 _humongous_set.remove_with_proxy(hr, humongous_proxy_set); | |
4748 hr->set_notHumongous(); | |
4749 free_region(hr, &hr_pre_used, free_list, par); | |
4750 | |
3766 | 4751 size_t i = hr->hrs_index() + 1; |
2152 | 4752 size_t num = 1; |
3766 | 4753 while (i < n_regions()) { |
4754 HeapRegion* curr_hr = region_at(i); | |
2152 | 4755 if (!curr_hr->continuesHumongous()) { |
4756 break; | |
4757 } | |
4758 curr_hr->set_notHumongous(); | |
4759 free_region(curr_hr, &hr_pre_used, free_list, par); | |
4760 num += 1; | |
4761 i += 1; | |
4762 } | |
4763 assert(hr_pre_used == hr_used, | |
4764 err_msg("hr_pre_used: "SIZE_FORMAT" and hr_used: "SIZE_FORMAT" " | |
4765 "should be the same", hr_pre_used, hr_used)); | |
4766 *pre_used += hr_pre_used; | |
4767 } | |
4768 | |
4769 void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used, | |
4770 FreeRegionList* free_list, | |
4771 HumongousRegionSet* humongous_proxy_set, | |
4772 bool par) { | |
4773 if (pre_used > 0) { | |
4774 Mutex* lock = (par) ? ParGCRareEvent_lock : NULL; | |
342 | 4775 MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag); |
2152 | 4776 assert(_summary_bytes_used >= pre_used, |
4777 err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" " | |
4778 "should be >= pre_used: "SIZE_FORMAT, | |
4779 _summary_bytes_used, pre_used)); | |
342 | 4780 _summary_bytes_used -= pre_used; |
2152 | 4781 } |
4782 if (free_list != NULL && !free_list->is_empty()) { | |
4783 MutexLockerEx x(FreeList_lock, Mutex::_no_safepoint_check_flag); | |
2432
455328d90876
7029458: G1: Add newly-reclaimed regions to the beginning of the region free list, not the end
tonyp
parents:
2369
diff
changeset
|
4784 _free_list.add_as_head(free_list); |
2152 | 4785 } |
4786 if (humongous_proxy_set != NULL && !humongous_proxy_set->is_empty()) { | |
4787 MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); | |
4788 _humongous_set.update_from_proxy(humongous_proxy_set); | |
342 | 4789 } |
4790 } | |
4791 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4792 class G1ParCleanupCTTask : public AbstractGangTask { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4793 CardTableModRefBS* _ct_bs; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4794 G1CollectedHeap* _g1h; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4795 HeapRegion* volatile _su_head; |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4796 public: |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4797 G1ParCleanupCTTask(CardTableModRefBS* ct_bs, |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4798 G1CollectedHeap* g1h) : |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4799 AbstractGangTask("G1 Par Cleanup CT Task"), |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4800 _ct_bs(ct_bs), _g1h(g1h) { } |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4801 |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4802 void work(int i) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4803 HeapRegion* r; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4804 while (r = _g1h->pop_dirty_cards_region()) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4805 clear_cards(r); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4806 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4807 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4808 |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4809 void clear_cards(HeapRegion* r) { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4810 // Cards of the survivors should have already been dirtied. |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4811 if (!r->is_survivor()) { |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4812 _ct_bs->clear(MemRegion(r->bottom(), r->end())); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4813 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4814 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4815 }; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4816 |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4817 #ifndef PRODUCT |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4818 class G1VerifyCardTableCleanup: public HeapRegionClosure { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4819 G1CollectedHeap* _g1h; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4820 CardTableModRefBS* _ct_bs; |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4821 public: |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4822 G1VerifyCardTableCleanup(G1CollectedHeap* g1h, CardTableModRefBS* ct_bs) |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4823 : _g1h(g1h), _ct_bs(ct_bs) { } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4824 virtual bool doHeapRegion(HeapRegion* r) { |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4825 if (r->is_survivor()) { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4826 _g1h->verify_dirty_region(r); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4827 } else { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4828 _g1h->verify_not_dirty_region(r); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4829 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4830 return false; |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4831 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4832 }; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4833 |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4834 void G1CollectedHeap::verify_not_dirty_region(HeapRegion* hr) { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4835 // All of the region should be clean. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4836 CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4837 MemRegion mr(hr->bottom(), hr->end()); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4838 ct_bs->verify_not_dirty_region(mr); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4839 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4840 |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4841 void G1CollectedHeap::verify_dirty_region(HeapRegion* hr) { |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4842 // We cannot guarantee that [bottom(),end()] is dirty. Threads |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4843 // dirty allocated blocks as they allocate them. The thread that |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4844 // retires each region and replaces it with a new one will do a |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4845 // maximal allocation to fill in [pre_dummy_top(),end()] but will |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4846 // not dirty that area (one less thing to have to do while holding |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4847 // a lock). So we can only verify that [bottom(),pre_dummy_top()] |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4848 // is dirty. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4849 CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4850 MemRegion mr(hr->bottom(), hr->pre_dummy_top()); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4851 ct_bs->verify_dirty_region(mr); |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4852 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4853 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4854 void G1CollectedHeap::verify_dirty_young_list(HeapRegion* head) { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4855 CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4856 for (HeapRegion* hr = head; hr != NULL; hr = hr->get_next_young_region()) { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4857 verify_dirty_region(hr); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4858 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4859 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4860 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4861 void G1CollectedHeap::verify_dirty_young_regions() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4862 verify_dirty_young_list(_young_list->first_region()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4863 verify_dirty_young_list(_young_list->first_survivor_region()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4864 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4865 #endif |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4866 |
342 | 4867 void G1CollectedHeap::cleanUpCardTable() { |
4868 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); | |
4869 double start = os::elapsedTime(); | |
4870 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4871 // Iterate over the dirty cards region list. |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4872 G1ParCleanupCTTask cleanup_task(ct_bs, this); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4873 |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4874 if (ParallelGCThreads > 0) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4875 set_par_threads(workers()->total_workers()); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4876 workers()->run_task(&cleanup_task); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4877 set_par_threads(0); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4878 } else { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4879 while (_dirty_cards_region_list) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4880 HeapRegion* r = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4881 cleanup_task.clear_cards(r); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4882 _dirty_cards_region_list = r->get_next_dirty_cards_region(); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4883 if (_dirty_cards_region_list == r) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4884 // The last region. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4885 _dirty_cards_region_list = NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4886 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4887 r->set_next_dirty_cards_region(NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4888 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4889 } |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4890 |
342 | 4891 double elapsed = os::elapsedTime() - start; |
4892 g1_policy()->record_clear_ct_time( elapsed * 1000.0); | |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4893 #ifndef PRODUCT |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4894 if (G1VerifyCTCleanup || VerifyAfterGC) { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4895 G1VerifyCardTableCleanup cleanup_verifier(this, ct_bs); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4896 heap_region_iterate(&cleanup_verifier); |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4897 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4898 #endif |
342 | 4899 } |
4900 | |
4901 void G1CollectedHeap::free_collection_set(HeapRegion* cs_head) { | |
2152 | 4902 size_t pre_used = 0; |
4903 FreeRegionList local_free_list("Local List for CSet Freeing"); | |
4904 | |
342 | 4905 double young_time_ms = 0.0; |
4906 double non_young_time_ms = 0.0; | |
4907 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4908 // Since the collection set is a superset of the the young list, |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4909 // all we need to do to clear the young list is clear its |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4910 // head and length, and unlink any young regions in the code below |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4911 _young_list->clear(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4912 |
342 | 4913 G1CollectorPolicy* policy = g1_policy(); |
4914 | |
4915 double start_sec = os::elapsedTime(); | |
4916 bool non_young = true; | |
4917 | |
4918 HeapRegion* cur = cs_head; | |
4919 int age_bound = -1; | |
4920 size_t rs_lengths = 0; | |
4921 | |
4922 while (cur != NULL) { | |
2361 | 4923 assert(!is_on_master_free_list(cur), "sanity"); |
2152 | 4924 |
342 | 4925 if (non_young) { |
4926 if (cur->is_young()) { | |
4927 double end_sec = os::elapsedTime(); | |
4928 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
4929 non_young_time_ms += elapsed_ms; | |
4930 | |
4931 start_sec = os::elapsedTime(); | |
4932 non_young = false; | |
4933 } | |
4934 } else { | |
2152 | 4935 double end_sec = os::elapsedTime(); |
4936 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
4937 young_time_ms += elapsed_ms; | |
4938 | |
4939 start_sec = os::elapsedTime(); | |
4940 non_young = true; | |
342 | 4941 } |
4942 | |
4943 rs_lengths += cur->rem_set()->occupied(); | |
4944 | |
4945 HeapRegion* next = cur->next_in_collection_set(); | |
4946 assert(cur->in_collection_set(), "bad CS"); | |
4947 cur->set_next_in_collection_set(NULL); | |
4948 cur->set_in_collection_set(false); | |
4949 | |
4950 if (cur->is_young()) { | |
4951 int index = cur->young_index_in_cset(); | |
4952 guarantee( index != -1, "invariant" ); | |
4953 guarantee( (size_t)index < policy->young_cset_length(), "invariant" ); | |
4954 size_t words_survived = _surviving_young_words[index]; | |
4955 cur->record_surv_words_in_group(words_survived); | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4956 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4957 // At this point the we have 'popped' cur from the collection set |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4958 // (linked via next_in_collection_set()) but it is still in the |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4959 // young list (linked via next_young_region()). Clear the |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4960 // _next_young_region field. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4961 cur->set_next_young_region(NULL); |
342 | 4962 } else { |
4963 int index = cur->young_index_in_cset(); | |
4964 guarantee( index == -1, "invariant" ); | |
4965 } | |
4966 | |
4967 assert( (cur->is_young() && cur->young_index_in_cset() > -1) || | |
4968 (!cur->is_young() && cur->young_index_in_cset() == -1), | |
4969 "invariant" ); | |
4970 | |
4971 if (!cur->evacuation_failed()) { | |
4972 // And the region is empty. | |
2152 | 4973 assert(!cur->is_empty(), "Should not have empty regions in a CS."); |
4974 free_region(cur, &pre_used, &local_free_list, false /* par */); | |
342 | 4975 } else { |
4976 cur->uninstall_surv_rate_group(); | |
4977 if (cur->is_young()) | |
4978 cur->set_young_index_in_cset(-1); | |
4979 cur->set_not_young(); | |
4980 cur->set_evacuation_failed(false); | |
4981 } | |
4982 cur = next; | |
4983 } | |
4984 | |
4985 policy->record_max_rs_lengths(rs_lengths); | |
4986 policy->cset_regions_freed(); | |
4987 | |
4988 double end_sec = os::elapsedTime(); | |
4989 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
4990 if (non_young) | |
4991 non_young_time_ms += elapsed_ms; | |
4992 else | |
4993 young_time_ms += elapsed_ms; | |
4994 | |
2152 | 4995 update_sets_after_freeing_regions(pre_used, &local_free_list, |
4996 NULL /* humongous_proxy_set */, | |
4997 false /* par */); | |
342 | 4998 policy->record_young_free_cset_time_ms(young_time_ms); |
4999 policy->record_non_young_free_cset_time_ms(non_young_time_ms); | |
5000 } | |
5001 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5002 // This routine is similar to the above but does not record |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5003 // any policy statistics or update free lists; we are abandoning |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5004 // the current incremental collection set in preparation of a |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5005 // full collection. After the full GC we will start to build up |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5006 // the incremental collection set again. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5007 // This is only called when we're doing a full collection |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5008 // and is immediately followed by the tearing down of the young list. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5009 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5010 void G1CollectedHeap::abandon_collection_set(HeapRegion* cs_head) { |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5011 HeapRegion* cur = cs_head; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5012 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5013 while (cur != NULL) { |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5014 HeapRegion* next = cur->next_in_collection_set(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5015 assert(cur->in_collection_set(), "bad CS"); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5016 cur->set_next_in_collection_set(NULL); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5017 cur->set_in_collection_set(false); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5018 cur->set_young_index_in_cset(-1); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5019 cur = next; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5020 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5021 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5022 |
2152 | 5023 void G1CollectedHeap::set_free_regions_coming() { |
5024 if (G1ConcRegionFreeingVerbose) { | |
5025 gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : " | |
5026 "setting free regions coming"); | |
5027 } | |
5028 | |
5029 assert(!free_regions_coming(), "pre-condition"); | |
5030 _free_regions_coming = true; | |
342 | 5031 } |
5032 | |
2152 | 5033 void G1CollectedHeap::reset_free_regions_coming() { |
5034 { | |
5035 assert(free_regions_coming(), "pre-condition"); | |
5036 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); | |
5037 _free_regions_coming = false; | |
5038 SecondaryFreeList_lock->notify_all(); | |
5039 } | |
5040 | |
5041 if (G1ConcRegionFreeingVerbose) { | |
5042 gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : " | |
5043 "reset free regions coming"); | |
342 | 5044 } |
5045 } | |
5046 | |
2152 | 5047 void G1CollectedHeap::wait_while_free_regions_coming() { |
5048 // Most of the time we won't have to wait, so let's do a quick test | |
5049 // first before we take the lock. | |
5050 if (!free_regions_coming()) { | |
5051 return; | |
5052 } | |
5053 | |
5054 if (G1ConcRegionFreeingVerbose) { | |
5055 gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : " | |
5056 "waiting for free regions"); | |
342 | 5057 } |
5058 | |
5059 { | |
2152 | 5060 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
5061 while (free_regions_coming()) { | |
5062 SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag); | |
342 | 5063 } |
2152 | 5064 } |
5065 | |
5066 if (G1ConcRegionFreeingVerbose) { | |
5067 gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : " | |
5068 "done waiting for free regions"); | |
5069 } | |
342 | 5070 } |
5071 | |
5072 void G1CollectedHeap::set_region_short_lived_locked(HeapRegion* hr) { | |
5073 assert(heap_lock_held_for_gc(), | |
5074 "the heap lock should already be held by or for this thread"); | |
5075 _young_list->push_region(hr); | |
5076 g1_policy()->set_region_short_lived(hr); | |
5077 } | |
5078 | |
5079 class NoYoungRegionsClosure: public HeapRegionClosure { | |
5080 private: | |
5081 bool _success; | |
5082 public: | |
5083 NoYoungRegionsClosure() : _success(true) { } | |
5084 bool doHeapRegion(HeapRegion* r) { | |
5085 if (r->is_young()) { | |
5086 gclog_or_tty->print_cr("Region ["PTR_FORMAT", "PTR_FORMAT") tagged as young", | |
5087 r->bottom(), r->end()); | |
5088 _success = false; | |
5089 } | |
5090 return false; | |
5091 } | |
5092 bool success() { return _success; } | |
5093 }; | |
5094 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5095 bool G1CollectedHeap::check_young_list_empty(bool check_heap, bool check_sample) { |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5096 bool ret = _young_list->check_list_empty(check_sample); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5097 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5098 if (check_heap) { |
342 | 5099 NoYoungRegionsClosure closure; |
5100 heap_region_iterate(&closure); | |
5101 ret = ret && closure.success(); | |
5102 } | |
5103 | |
5104 return ret; | |
5105 } | |
5106 | |
5107 void G1CollectedHeap::empty_young_list() { | |
5108 assert(heap_lock_held_for_gc(), | |
5109 "the heap lock should already be held by or for this thread"); | |
5110 | |
5111 _young_list->empty_list(); | |
5112 } | |
5113 | |
5114 // Done at the start of full GC. | |
5115 void G1CollectedHeap::tear_down_region_lists() { | |
2152 | 5116 _free_list.remove_all(); |
342 | 5117 } |
5118 | |
5119 class RegionResetter: public HeapRegionClosure { | |
2152 | 5120 G1CollectedHeap* _g1h; |
5121 FreeRegionList _local_free_list; | |
5122 | |
342 | 5123 public: |
2152 | 5124 RegionResetter() : _g1h(G1CollectedHeap::heap()), |
5125 _local_free_list("Local Free List for RegionResetter") { } | |
5126 | |
342 | 5127 bool doHeapRegion(HeapRegion* r) { |
5128 if (r->continuesHumongous()) return false; | |
5129 if (r->top() > r->bottom()) { | |
5130 if (r->top() < r->end()) { | |
5131 Copy::fill_to_words(r->top(), | |
5132 pointer_delta(r->end(), r->top())); | |
5133 } | |
5134 } else { | |
5135 assert(r->is_empty(), "tautology"); | |
2152 | 5136 _local_free_list.add_as_tail(r); |
342 | 5137 } |
5138 return false; | |
5139 } | |
5140 | |
2152 | 5141 void update_free_lists() { |
5142 _g1h->update_sets_after_freeing_regions(0, &_local_free_list, NULL, | |
5143 false /* par */); | |
5144 } | |
342 | 5145 }; |
5146 | |
5147 // Done at the end of full GC. | |
5148 void G1CollectedHeap::rebuild_region_lists() { | |
5149 // This needs to go at the end of the full GC. | |
5150 RegionResetter rs; | |
5151 heap_region_iterate(&rs); | |
2152 | 5152 rs.update_free_lists(); |
342 | 5153 } |
5154 | |
5155 void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) { | |
5156 _refine_cte_cl->set_concurrent(concurrent); | |
5157 } | |
5158 | |
5159 bool G1CollectedHeap::is_in_closed_subset(const void* p) const { | |
5160 HeapRegion* hr = heap_region_containing(p); | |
5161 if (hr == NULL) { | |
5162 return is_in_permanent(p); | |
5163 } else { | |
5164 return hr->is_in(p); | |
5165 } | |
5166 } | |
2152 | 5167 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5168 // Methods for the mutator alloc region |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5169 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5170 HeapRegion* G1CollectedHeap::new_mutator_alloc_region(size_t word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5171 bool force) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5172 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5173 assert(!force || g1_policy()->can_expand_young_list(), |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5174 "if force is true we should be able to expand the young list"); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
5175 bool young_list_full = g1_policy()->is_young_list_full(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
5176 if (force || !young_list_full) { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5177 HeapRegion* new_alloc_region = new_region(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5178 false /* do_expand */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5179 if (new_alloc_region != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5180 g1_policy()->update_region_num(true /* next_is_young */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5181 set_region_short_lived_locked(new_alloc_region); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
5182 _hr_printer.alloc(new_alloc_region, G1HRPrinter::Eden, young_list_full); |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
5183 g1mm()->update_eden_counters(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5184 return new_alloc_region; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5185 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5186 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5187 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5188 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5189 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5190 void G1CollectedHeap::retire_mutator_alloc_region(HeapRegion* alloc_region, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5191 size_t allocated_bytes) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5192 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5193 assert(alloc_region->is_young(), "all mutator alloc regions should be young"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5194 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5195 g1_policy()->add_region_to_incremental_cset_lhs(alloc_region); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5196 _summary_bytes_used += allocated_bytes; |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
5197 _hr_printer.retire(alloc_region); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5198 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5199 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5200 HeapRegion* MutatorAllocRegion::allocate_new_region(size_t word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5201 bool force) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5202 return _g1h->new_mutator_alloc_region(word_size, force); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5203 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5204 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5205 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5206 size_t allocated_bytes) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5207 _g1h->retire_mutator_alloc_region(alloc_region, allocated_bytes); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5208 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5209 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5210 // Methods for the GC alloc regions |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5211 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5212 HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5213 size_t count, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5214 GCAllocPurpose ap) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5215 assert(FreeList_lock->owned_by_self(), "pre-condition"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5216 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5217 if (count < g1_policy()->max_regions(ap)) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5218 HeapRegion* new_alloc_region = new_region(word_size, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5219 true /* do_expand */); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5220 if (new_alloc_region != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5221 // We really only need to do this for old regions given that we |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5222 // should never scan survivors. But it doesn't hurt to do it |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5223 // for survivors too. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5224 new_alloc_region->set_saved_mark(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5225 if (ap == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5226 new_alloc_region->set_survivor(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5227 _hr_printer.alloc(new_alloc_region, G1HRPrinter::Survivor); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5228 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5229 _hr_printer.alloc(new_alloc_region, G1HRPrinter::Old); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5230 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5231 return new_alloc_region; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5232 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5233 g1_policy()->note_alloc_region_limit_reached(ap); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5234 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5235 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5236 return NULL; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5237 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5238 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5239 void G1CollectedHeap::retire_gc_alloc_region(HeapRegion* alloc_region, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5240 size_t allocated_bytes, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5241 GCAllocPurpose ap) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5242 alloc_region->note_end_of_copying(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5243 g1_policy()->record_bytes_copied_during_gc(allocated_bytes); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5244 if (ap == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5245 young_list()->add_survivor_region(alloc_region); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5246 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5247 _hr_printer.retire(alloc_region); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5248 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5249 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5250 HeapRegion* SurvivorGCAllocRegion::allocate_new_region(size_t word_size, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5251 bool force) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5252 assert(!force, "not supported for GC alloc regions"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5253 return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForSurvived); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5254 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5255 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5256 void SurvivorGCAllocRegion::retire_region(HeapRegion* alloc_region, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5257 size_t allocated_bytes) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5258 _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5259 GCAllocForSurvived); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5260 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5261 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5262 HeapRegion* OldGCAllocRegion::allocate_new_region(size_t word_size, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5263 bool force) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5264 assert(!force, "not supported for GC alloc regions"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5265 return _g1h->new_gc_alloc_region(word_size, count(), GCAllocForTenured); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5266 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5267 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5268 void OldGCAllocRegion::retire_region(HeapRegion* alloc_region, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5269 size_t allocated_bytes) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5270 _g1h->retire_gc_alloc_region(alloc_region, allocated_bytes, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5271 GCAllocForTenured); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5272 } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5273 // Heap region set verification |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5274 |
2152 | 5275 class VerifyRegionListsClosure : public HeapRegionClosure { |
5276 private: | |
5277 HumongousRegionSet* _humongous_set; | |
5278 FreeRegionList* _free_list; | |
5279 size_t _region_count; | |
5280 | |
5281 public: | |
5282 VerifyRegionListsClosure(HumongousRegionSet* humongous_set, | |
5283 FreeRegionList* free_list) : | |
5284 _humongous_set(humongous_set), _free_list(free_list), | |
5285 _region_count(0) { } | |
5286 | |
5287 size_t region_count() { return _region_count; } | |
5288 | |
5289 bool doHeapRegion(HeapRegion* hr) { | |
5290 _region_count += 1; | |
5291 | |
5292 if (hr->continuesHumongous()) { | |
5293 return false; | |
5294 } | |
5295 | |
5296 if (hr->is_young()) { | |
5297 // TODO | |
5298 } else if (hr->startsHumongous()) { | |
5299 _humongous_set->verify_next_region(hr); | |
5300 } else if (hr->is_empty()) { | |
5301 _free_list->verify_next_region(hr); | |
5302 } | |
5303 return false; | |
5304 } | |
5305 }; | |
5306 | |
3766 | 5307 HeapRegion* G1CollectedHeap::new_heap_region(size_t hrs_index, |
5308 HeapWord* bottom) { | |
5309 HeapWord* end = bottom + HeapRegion::GrainWords; | |
5310 MemRegion mr(bottom, end); | |
5311 assert(_g1_reserved.contains(mr), "invariant"); | |
5312 // This might return NULL if the allocation fails | |
5313 return new HeapRegion(hrs_index, _bot_shared, mr, true /* is_zeroed */); | |
5314 } | |
5315 | |
2152 | 5316 void G1CollectedHeap::verify_region_sets() { |
5317 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); | |
5318 | |
5319 // First, check the explicit lists. | |
5320 _free_list.verify(); | |
5321 { | |
5322 // Given that a concurrent operation might be adding regions to | |
5323 // the secondary free list we have to take the lock before | |
5324 // verifying it. | |
5325 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); | |
5326 _secondary_free_list.verify(); | |
5327 } | |
5328 _humongous_set.verify(); | |
5329 | |
5330 // If a concurrent region freeing operation is in progress it will | |
5331 // be difficult to correctly attributed any free regions we come | |
5332 // across to the correct free list given that they might belong to | |
5333 // one of several (free_list, secondary_free_list, any local lists, | |
5334 // etc.). So, if that's the case we will skip the rest of the | |
5335 // verification operation. Alternatively, waiting for the concurrent | |
5336 // operation to complete will have a non-trivial effect on the GC's | |
5337 // operation (no concurrent operation will last longer than the | |
5338 // interval between two calls to verification) and it might hide | |
5339 // any issues that we would like to catch during testing. | |
5340 if (free_regions_coming()) { | |
5341 return; | |
5342 } | |
5343 | |
2361 | 5344 // Make sure we append the secondary_free_list on the free_list so |
5345 // that all free regions we will come across can be safely | |
5346 // attributed to the free_list. | |
5347 append_secondary_free_list_if_not_empty_with_lock(); | |
2152 | 5348 |
5349 // Finally, make sure that the region accounting in the lists is | |
5350 // consistent with what we see in the heap. | |
5351 _humongous_set.verify_start(); | |
5352 _free_list.verify_start(); | |
5353 | |
5354 VerifyRegionListsClosure cl(&_humongous_set, &_free_list); | |
5355 heap_region_iterate(&cl); | |
5356 | |
5357 _humongous_set.verify_end(); | |
5358 _free_list.verify_end(); | |
342 | 5359 } |