Mercurial > hg > graal-compiler
annotate src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 3830:f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
Summary: Refactor the allocation code during GC to use the G1AllocRegion abstraction. Use separate subclasses of G1AllocRegion for survivor and old regions. Avoid BOT updates and dirty survivor cards incrementally for the former.
Reviewed-by: brutisso, johnc, ysr
author | tonyp |
---|---|
date | Fri, 12 Aug 2011 11:31:06 -0400 |
parents | 6aa4feb8a366 |
children | ff53346271fe |
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" | |
34 #include "gc_implementation/g1/g1MarkSweep.hpp" | |
35 #include "gc_implementation/g1/g1OopClosures.inline.hpp" | |
36 #include "gc_implementation/g1/g1RemSet.inline.hpp" | |
37 #include "gc_implementation/g1/heapRegionRemSet.hpp" | |
38 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
39 #include "gc_implementation/g1/vm_operations_g1.hpp" | |
40 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
41 #include "memory/gcLocker.inline.hpp" | |
42 #include "memory/genOopClosures.inline.hpp" | |
43 #include "memory/generationSpec.hpp" | |
44 #include "oops/oop.inline.hpp" | |
45 #include "oops/oop.pcgc.inline.hpp" | |
46 #include "runtime/aprofiler.hpp" | |
47 #include "runtime/vmThread.hpp" | |
342 | 48 |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
49 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
|
50 |
342 | 51 // turn it on so that the contents of the young list (scan-only / |
52 // to-be-collected) are printed at "strategic" points before / during | |
53 // / 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
|
54 #define YOUNG_LIST_VERBOSE 0 |
342 | 55 // CURRENT STATUS |
56 // This file is under construction. Search for "FIXME". | |
57 | |
58 // INVARIANTS/NOTES | |
59 // | |
60 // All allocation activity covered by the G1CollectedHeap interface is | |
1973 | 61 // serialized by acquiring the HeapLock. This happens in mem_allocate |
62 // and allocate_new_tlab, which are the "entry" points to the | |
63 // allocation code from the rest of the JVM. (Note that this does not | |
64 // apply to TLAB allocation, which is not part of this interface: it | |
65 // is done by clients of this interface.) | |
342 | 66 |
67 // Local to this file. | |
68 | |
69 class RefineCardTableEntryClosure: public CardTableEntryClosure { | |
70 SuspendibleThreadSet* _sts; | |
71 G1RemSet* _g1rs; | |
72 ConcurrentG1Refine* _cg1r; | |
73 bool _concurrent; | |
74 public: | |
75 RefineCardTableEntryClosure(SuspendibleThreadSet* sts, | |
76 G1RemSet* g1rs, | |
77 ConcurrentG1Refine* cg1r) : | |
78 _sts(sts), _g1rs(g1rs), _cg1r(cg1r), _concurrent(true) | |
79 {} | |
80 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
1705 | 81 bool oops_into_cset = _g1rs->concurrentRefineOneCard(card_ptr, worker_i, false); |
82 // This path is executed by the concurrent refine or mutator threads, | |
83 // concurrently, and so we do not care if card_ptr contains references | |
84 // that point into the collection set. | |
85 assert(!oops_into_cset, "should be"); | |
86 | |
342 | 87 if (_concurrent && _sts->should_yield()) { |
88 // Caller will actually yield. | |
89 return false; | |
90 } | |
91 // Otherwise, we finished successfully; return true. | |
92 return true; | |
93 } | |
94 void set_concurrent(bool b) { _concurrent = b; } | |
95 }; | |
96 | |
97 | |
98 class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { | |
99 int _calls; | |
100 G1CollectedHeap* _g1h; | |
101 CardTableModRefBS* _ctbs; | |
102 int _histo[256]; | |
103 public: | |
104 ClearLoggedCardTableEntryClosure() : | |
105 _calls(0) | |
106 { | |
107 _g1h = G1CollectedHeap::heap(); | |
108 _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); | |
109 for (int i = 0; i < 256; i++) _histo[i] = 0; | |
110 } | |
111 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
112 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { | |
113 _calls++; | |
114 unsigned char* ujb = (unsigned char*)card_ptr; | |
115 int ind = (int)(*ujb); | |
116 _histo[ind]++; | |
117 *card_ptr = -1; | |
118 } | |
119 return true; | |
120 } | |
121 int calls() { return _calls; } | |
122 void print_histo() { | |
123 gclog_or_tty->print_cr("Card table value histogram:"); | |
124 for (int i = 0; i < 256; i++) { | |
125 if (_histo[i] != 0) { | |
126 gclog_or_tty->print_cr(" %d: %d", i, _histo[i]); | |
127 } | |
128 } | |
129 } | |
130 }; | |
131 | |
132 class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { | |
133 int _calls; | |
134 G1CollectedHeap* _g1h; | |
135 CardTableModRefBS* _ctbs; | |
136 public: | |
137 RedirtyLoggedCardTableEntryClosure() : | |
138 _calls(0) | |
139 { | |
140 _g1h = G1CollectedHeap::heap(); | |
141 _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); | |
142 } | |
143 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
144 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { | |
145 _calls++; | |
146 *card_ptr = 0; | |
147 } | |
148 return true; | |
149 } | |
150 int calls() { return _calls; } | |
151 }; | |
152 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
153 class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
154 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
155 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
|
156 *card_ptr = CardTableModRefBS::dirty_card_val(); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
157 return true; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
158 } |
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 |
342 | 161 YoungList::YoungList(G1CollectedHeap* g1h) |
162 : _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
|
163 _length(0), |
342 | 164 _last_sampled_rs_lengths(0), |
545 | 165 _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) |
342 | 166 { |
167 guarantee( check_list_empty(false), "just making sure..." ); | |
168 } | |
169 | |
170 void YoungList::push_region(HeapRegion *hr) { | |
171 assert(!hr->is_young(), "should not already be young"); | |
172 assert(hr->get_next_young_region() == NULL, "cause it should!"); | |
173 | |
174 hr->set_next_young_region(_head); | |
175 _head = hr; | |
176 | |
177 hr->set_young(); | |
178 double yg_surv_rate = _g1h->g1_policy()->predict_yg_surv_rate((int)_length); | |
179 ++_length; | |
180 } | |
181 | |
182 void YoungList::add_survivor_region(HeapRegion* hr) { | |
545 | 183 assert(hr->is_survivor(), "should be flagged as survivor region"); |
342 | 184 assert(hr->get_next_young_region() == NULL, "cause it should!"); |
185 | |
186 hr->set_next_young_region(_survivor_head); | |
187 if (_survivor_head == NULL) { | |
545 | 188 _survivor_tail = hr; |
342 | 189 } |
190 _survivor_head = hr; | |
191 | |
192 ++_survivor_length; | |
193 } | |
194 | |
195 void YoungList::empty_list(HeapRegion* list) { | |
196 while (list != NULL) { | |
197 HeapRegion* next = list->get_next_young_region(); | |
198 list->set_next_young_region(NULL); | |
199 list->uninstall_surv_rate_group(); | |
200 list->set_not_young(); | |
201 list = next; | |
202 } | |
203 } | |
204 | |
205 void YoungList::empty_list() { | |
206 assert(check_list_well_formed(), "young list should be well formed"); | |
207 | |
208 empty_list(_head); | |
209 _head = NULL; | |
210 _length = 0; | |
211 | |
212 empty_list(_survivor_head); | |
213 _survivor_head = NULL; | |
545 | 214 _survivor_tail = NULL; |
342 | 215 _survivor_length = 0; |
216 | |
217 _last_sampled_rs_lengths = 0; | |
218 | |
219 assert(check_list_empty(false), "just making sure..."); | |
220 } | |
221 | |
222 bool YoungList::check_list_well_formed() { | |
223 bool ret = true; | |
224 | |
225 size_t length = 0; | |
226 HeapRegion* curr = _head; | |
227 HeapRegion* last = NULL; | |
228 while (curr != NULL) { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
229 if (!curr->is_young()) { |
342 | 230 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
|
231 "incorrectly tagged (y: %d, surv: %d)", |
342 | 232 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
|
233 curr->is_young(), curr->is_survivor()); |
342 | 234 ret = false; |
235 } | |
236 ++length; | |
237 last = curr; | |
238 curr = curr->get_next_young_region(); | |
239 } | |
240 ret = ret && (length == _length); | |
241 | |
242 if (!ret) { | |
243 gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!"); | |
244 gclog_or_tty->print_cr("### list has %d entries, _length is %d", | |
245 length, _length); | |
246 } | |
247 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
248 return ret; |
342 | 249 } |
250 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
251 bool YoungList::check_list_empty(bool check_sample) { |
342 | 252 bool ret = true; |
253 | |
254 if (_length != 0) { | |
255 gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %d", | |
256 _length); | |
257 ret = false; | |
258 } | |
259 if (check_sample && _last_sampled_rs_lengths != 0) { | |
260 gclog_or_tty->print_cr("### YOUNG LIST has non-zero last sampled RS lengths"); | |
261 ret = false; | |
262 } | |
263 if (_head != NULL) { | |
264 gclog_or_tty->print_cr("### YOUNG LIST does not have a NULL head"); | |
265 ret = false; | |
266 } | |
267 if (!ret) { | |
268 gclog_or_tty->print_cr("### YOUNG LIST does not seem empty"); | |
269 } | |
270 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
271 return ret; |
342 | 272 } |
273 | |
274 void | |
275 YoungList::rs_length_sampling_init() { | |
276 _sampled_rs_lengths = 0; | |
277 _curr = _head; | |
278 } | |
279 | |
280 bool | |
281 YoungList::rs_length_sampling_more() { | |
282 return _curr != NULL; | |
283 } | |
284 | |
285 void | |
286 YoungList::rs_length_sampling_next() { | |
287 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
|
288 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
|
289 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
290 _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
|
291 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
292 // 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
|
293 // 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
|
294 // 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
|
295 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
|
296 // 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
|
297 _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
|
298 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
299 |
342 | 300 _curr = _curr->get_next_young_region(); |
301 if (_curr == NULL) { | |
302 _last_sampled_rs_lengths = _sampled_rs_lengths; | |
303 // gclog_or_tty->print_cr("last sampled RS lengths = %d", _last_sampled_rs_lengths); | |
304 } | |
305 } | |
306 | |
307 void | |
308 YoungList::reset_auxilary_lists() { | |
309 guarantee( is_empty(), "young list should be empty" ); | |
310 assert(check_list_well_formed(), "young list should be well formed"); | |
311 | |
312 // Add survivor regions to SurvRateGroup. | |
313 _g1h->g1_policy()->note_start_adding_survivor_regions(); | |
545 | 314 _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
|
315 |
342 | 316 for (HeapRegion* curr = _survivor_head; |
317 curr != NULL; | |
318 curr = curr->get_next_young_region()) { | |
319 _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
|
320 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
321 // 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
|
322 // 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
|
323 // pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
324 _g1h->g1_policy()->add_region_to_incremental_cset_rhs(curr); |
342 | 325 } |
326 _g1h->g1_policy()->note_stop_adding_survivor_regions(); | |
327 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
328 _head = _survivor_head; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
329 _length = _survivor_length; |
342 | 330 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
|
331 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
|
332 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
|
333 _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
|
334 } |
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 // 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
|
337 // 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
|
338 // 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
|
339 // 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
|
340 |
545 | 341 _g1h->g1_policy()->finished_recalculating_age_indexes(false /* is_survivors */); |
342 | 342 |
343 assert(check_list_well_formed(), "young list should be well formed"); | |
344 } | |
345 | |
346 void YoungList::print() { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
347 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
|
348 const char* names[] = {"YOUNG", "SURVIVOR"}; |
342 | 349 |
350 for (unsigned int list = 0; list < ARRAY_SIZE(lists); ++list) { | |
351 gclog_or_tty->print_cr("%s LIST CONTENTS", names[list]); | |
352 HeapRegion *curr = lists[list]; | |
353 if (curr == NULL) | |
354 gclog_or_tty->print_cr(" empty"); | |
355 while (curr != NULL) { | |
356 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
|
357 "age: %4d, y: %d, surv: %d", |
342 | 358 curr->bottom(), curr->end(), |
359 curr->top(), | |
360 curr->prev_top_at_mark_start(), | |
361 curr->next_top_at_mark_start(), | |
362 curr->top_at_conc_mark_count(), | |
363 curr->age_in_surv_rate_group_cond(), | |
364 curr->is_young(), | |
365 curr->is_survivor()); | |
366 curr = curr->get_next_young_region(); | |
367 } | |
368 } | |
369 | |
370 gclog_or_tty->print_cr(""); | |
371 } | |
372 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
373 void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
374 { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
375 // 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
|
376 // by installing a self pointer. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
377 HeapRegion* next = hr->get_next_dirty_cards_region(); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
378 if (next == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
379 HeapRegion* res = (HeapRegion*) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
380 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
|
381 NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
382 if (res == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
383 HeapRegion* head; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
384 do { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
385 // Put the region to the dirty cards region list. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
386 head = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
387 next = (HeapRegion*) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
388 Atomic::cmpxchg_ptr(hr, &_dirty_cards_region_list, head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
389 if (next == head) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
390 assert(hr->get_next_dirty_cards_region() == hr, |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
391 "hr->get_next_dirty_cards_region() != hr"); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
392 if (next == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
393 // The last region in the list points to itself. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
394 hr->set_next_dirty_cards_region(hr); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
395 } else { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
396 hr->set_next_dirty_cards_region(next); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
397 } |
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 } while (next != head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
400 } |
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 HeapRegion* G1CollectedHeap::pop_dirty_cards_region() |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
405 { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
406 HeapRegion* head; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
407 HeapRegion* hr; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
408 do { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
409 head = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
410 if (head == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
411 return NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
412 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
413 HeapRegion* new_head = head->get_next_dirty_cards_region(); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
414 if (head == new_head) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
415 // The last region. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
416 new_head = NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
417 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
418 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
|
419 head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
420 } while (hr != head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
421 assert(hr != NULL, "invariant"); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
422 hr->set_next_dirty_cards_region(NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
423 return hr; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
424 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
425 |
342 | 426 void G1CollectedHeap::stop_conc_gc_threads() { |
794 | 427 _cg1r->stop(); |
342 | 428 _cmThread->stop(); |
429 } | |
430 | |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
431 #ifdef ASSERT |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
432 // 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
|
433 // 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
|
434 // 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
|
435 // 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
|
436 // regions have been retired. It is used for debugging |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
437 // 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
|
438 // 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
|
439 // inaccurate, it is sufficient for G1 because the conservative |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
440 // implementation of is_scavengable() for G1 will indicate that |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
441 // all nmethods must be scanned during a partial collection. |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
442 bool G1CollectedHeap::is_in_partial_collection(const void* p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
443 HeapRegion* hr = heap_region_containing(p); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
444 return hr != NULL && hr->in_collection_set(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
445 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
446 #endif |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
447 |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
448 // 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
|
449 // can move in an incremental collecction. |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
450 bool G1CollectedHeap::is_scavengable(const void* p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
451 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
452 G1CollectorPolicy* g1p = g1h->g1_policy(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
453 HeapRegion* hr = heap_region_containing(p); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
454 if (hr == NULL) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
455 // perm gen (or null) |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
456 return false; |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
457 } else { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
458 return !hr->isHumongous(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
459 } |
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 |
342 | 462 void G1CollectedHeap::check_ct_logs_at_safepoint() { |
463 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
464 CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); | |
465 | |
466 // Count the dirty cards at the start. | |
467 CountNonCleanMemRegionClosure count1(this); | |
468 ct_bs->mod_card_iterate(&count1); | |
469 int orig_count = count1.n(); | |
470 | |
471 // First clear the logged cards. | |
472 ClearLoggedCardTableEntryClosure clear; | |
473 dcqs.set_closure(&clear); | |
474 dcqs.apply_closure_to_all_completed_buffers(); | |
475 dcqs.iterate_closure_all_threads(false); | |
476 clear.print_histo(); | |
477 | |
478 // Now ensure that there's no dirty cards. | |
479 CountNonCleanMemRegionClosure count2(this); | |
480 ct_bs->mod_card_iterate(&count2); | |
481 if (count2.n() != 0) { | |
482 gclog_or_tty->print_cr("Card table has %d entries; %d originally", | |
483 count2.n(), orig_count); | |
484 } | |
485 guarantee(count2.n() == 0, "Card table should be clean."); | |
486 | |
487 RedirtyLoggedCardTableEntryClosure redirty; | |
488 JavaThread::dirty_card_queue_set().set_closure(&redirty); | |
489 dcqs.apply_closure_to_all_completed_buffers(); | |
490 dcqs.iterate_closure_all_threads(false); | |
491 gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", | |
492 clear.calls(), orig_count); | |
493 guarantee(redirty.calls() == clear.calls(), | |
494 "Or else mechanism is broken."); | |
495 | |
496 CountNonCleanMemRegionClosure count3(this); | |
497 ct_bs->mod_card_iterate(&count3); | |
498 if (count3.n() != orig_count) { | |
499 gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.", | |
500 orig_count, count3.n()); | |
501 guarantee(count3.n() >= orig_count, "Should have restored them all."); | |
502 } | |
503 | |
504 JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); | |
505 } | |
506 | |
507 // Private class members. | |
508 | |
509 G1CollectedHeap* G1CollectedHeap::_g1h; | |
510 | |
511 // Private methods. | |
512 | |
2152 | 513 HeapRegion* |
2361 | 514 G1CollectedHeap::new_region_try_secondary_free_list() { |
2152 | 515 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
516 while (!_secondary_free_list.is_empty() || free_regions_coming()) { | |
517 if (!_secondary_free_list.is_empty()) { | |
518 if (G1ConcRegionFreeingVerbose) { | |
519 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
520 "secondary_free_list has "SIZE_FORMAT" entries", | |
521 _secondary_free_list.length()); | |
522 } | |
523 // It looks as if there are free regions available on the | |
524 // secondary_free_list. Let's move them to the free_list and try | |
525 // again to allocate from it. | |
526 append_secondary_free_list(); | |
527 | |
528 assert(!_free_list.is_empty(), "if the secondary_free_list was not " | |
529 "empty we should have moved at least one entry to the free_list"); | |
530 HeapRegion* res = _free_list.remove_head(); | |
531 if (G1ConcRegionFreeingVerbose) { | |
532 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
533 "allocated "HR_FORMAT" from secondary_free_list", | |
534 HR_FORMAT_PARAMS(res)); | |
535 } | |
536 return res; | |
537 } | |
538 | |
539 // Wait here until we get notifed either when (a) there are no | |
540 // more free regions coming or (b) some regions have been moved on | |
541 // the secondary_free_list. | |
542 SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag); | |
543 } | |
544 | |
545 if (G1ConcRegionFreeingVerbose) { | |
546 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
547 "could not allocate from secondary_free_list"); | |
548 } | |
549 return NULL; | |
550 } | |
551 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
552 HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool do_expand) { |
2152 | 553 assert(!isHumongous(word_size) || |
554 word_size <= (size_t) HeapRegion::GrainWords, | |
555 "the only time we use this to allocate a humongous region is " | |
556 "when we are allocating a single humongous region"); | |
557 | |
558 HeapRegion* res; | |
559 if (G1StressConcRegionFreeing) { | |
560 if (!_secondary_free_list.is_empty()) { | |
561 if (G1ConcRegionFreeingVerbose) { | |
562 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
563 "forced to look at the secondary_free_list"); | |
564 } | |
2361 | 565 res = new_region_try_secondary_free_list(); |
2152 | 566 if (res != NULL) { |
567 return res; | |
568 } | |
569 } | |
570 } | |
571 res = _free_list.remove_head_or_null(); | |
572 if (res == NULL) { | |
573 if (G1ConcRegionFreeingVerbose) { | |
574 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
575 "res == NULL, trying the secondary_free_list"); | |
576 } | |
2361 | 577 res = new_region_try_secondary_free_list(); |
2152 | 578 } |
342 | 579 if (res == NULL && do_expand) { |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
580 if (expand(word_size * HeapWordSize)) { |
3766 | 581 // Even though the heap was expanded, it might not have reached |
582 // the desired size. So, we cannot assume that the allocation | |
583 // will succeed. | |
584 res = _free_list.remove_head_or_null(); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
585 } |
342 | 586 } |
587 return res; | |
588 } | |
589 | |
3766 | 590 size_t G1CollectedHeap::humongous_obj_allocate_find_first(size_t num_regions, |
591 size_t word_size) { | |
2361 | 592 assert(isHumongous(word_size), "word_size should be humongous"); |
593 assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); | |
594 | |
3766 | 595 size_t first = G1_NULL_HRS_INDEX; |
2152 | 596 if (num_regions == 1) { |
597 // Only one region to allocate, no need to go through the slower | |
598 // path. The caller will attempt the expasion if this fails, so | |
599 // 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
|
600 HeapRegion* hr = new_region(word_size, false /* do_expand */); |
2152 | 601 if (hr != NULL) { |
602 first = hr->hrs_index(); | |
603 } else { | |
3766 | 604 first = G1_NULL_HRS_INDEX; |
2152 | 605 } |
606 } else { | |
607 // We can't allocate humongous regions while cleanupComplete() is | |
608 // running, since some of the regions we find to be empty might not | |
609 // yet be added to the free list and it is not straightforward to | |
610 // know which list they are on so that we can remove them. Note | |
611 // that we only need to do this if we need to allocate more than | |
612 // one region to satisfy the current humongous allocation | |
613 // request. If we are only allocating one region we use the common | |
614 // region allocation code (see above). | |
615 wait_while_free_regions_coming(); | |
2361 | 616 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 617 |
618 if (free_regions() >= num_regions) { | |
3766 | 619 first = _hrs.find_contiguous(num_regions); |
620 if (first != G1_NULL_HRS_INDEX) { | |
621 for (size_t i = first; i < first + num_regions; ++i) { | |
622 HeapRegion* hr = region_at(i); | |
2152 | 623 assert(hr->is_empty(), "sanity"); |
2361 | 624 assert(is_on_master_free_list(hr), "sanity"); |
2152 | 625 hr->set_pending_removal(true); |
626 } | |
627 _free_list.remove_all_pending(num_regions); | |
628 } | |
629 } | |
630 } | |
631 return first; | |
632 } | |
633 | |
2361 | 634 HeapWord* |
3766 | 635 G1CollectedHeap::humongous_obj_allocate_initialize_regions(size_t first, |
2361 | 636 size_t num_regions, |
637 size_t word_size) { | |
3766 | 638 assert(first != G1_NULL_HRS_INDEX, "pre-condition"); |
2361 | 639 assert(isHumongous(word_size), "word_size should be humongous"); |
640 assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); | |
641 | |
642 // Index of last region in the series + 1. | |
3766 | 643 size_t last = first + num_regions; |
2361 | 644 |
645 // We need to initialize the region(s) we just discovered. This is | |
646 // a bit tricky given that it can happen concurrently with | |
647 // refinement threads refining cards on these regions and | |
648 // potentially wanting to refine the BOT as they are scanning | |
649 // those cards (this can happen shortly after a cleanup; see CR | |
650 // 6991377). So we have to set up the region(s) carefully and in | |
651 // a specific order. | |
652 | |
653 // The word size sum of all the regions we will allocate. | |
654 size_t word_size_sum = num_regions * HeapRegion::GrainWords; | |
655 assert(word_size <= word_size_sum, "sanity"); | |
656 | |
657 // This will be the "starts humongous" region. | |
3766 | 658 HeapRegion* first_hr = region_at(first); |
2361 | 659 // The header of the new object will be placed at the bottom of |
660 // the first region. | |
661 HeapWord* new_obj = first_hr->bottom(); | |
662 // This will be the new end of the first region in the series that | |
663 // should also match the end of the last region in the seriers. | |
664 HeapWord* new_end = new_obj + word_size_sum; | |
665 // This will be the new top of the first region that will reflect | |
666 // this allocation. | |
667 HeapWord* new_top = new_obj + word_size; | |
668 | |
669 // First, we need to zero the header of the space that we will be | |
670 // allocating. When we update top further down, some refinement | |
671 // threads might try to scan the region. By zeroing the header we | |
672 // ensure that any thread that will try to scan the region will | |
673 // come across the zero klass word and bail out. | |
674 // | |
675 // NOTE: It would not have been correct to have used | |
676 // CollectedHeap::fill_with_object() and make the space look like | |
677 // an int array. The thread that is doing the allocation will | |
678 // later update the object header to a potentially different array | |
679 // type and, for a very short period of time, the klass and length | |
680 // fields will be inconsistent. This could cause a refinement | |
681 // thread to calculate the object size incorrectly. | |
682 Copy::fill_to_words(new_obj, oopDesc::header_size(), 0); | |
683 | |
684 // We will set up the first region as "starts humongous". This | |
685 // will also update the BOT covering all the regions to reflect | |
686 // that there is a single object that starts at the bottom of the | |
687 // first region. | |
688 first_hr->set_startsHumongous(new_top, new_end); | |
689 | |
690 // Then, if there are any, we will set up the "continues | |
691 // humongous" regions. | |
692 HeapRegion* hr = NULL; | |
3766 | 693 for (size_t i = first + 1; i < last; ++i) { |
694 hr = region_at(i); | |
2361 | 695 hr->set_continuesHumongous(first_hr); |
696 } | |
697 // If we have "continues humongous" regions (hr != NULL), then the | |
698 // end of the last one should match new_end. | |
699 assert(hr == NULL || hr->end() == new_end, "sanity"); | |
700 | |
701 // Up to this point no concurrent thread would have been able to | |
702 // do any scanning on any region in this series. All the top | |
703 // fields still point to bottom, so the intersection between | |
704 // [bottom,top] and [card_start,card_end] will be empty. Before we | |
705 // update the top fields, we'll do a storestore to make sure that | |
706 // no thread sees the update to top before the zeroing of the | |
707 // object header and the BOT initialization. | |
708 OrderAccess::storestore(); | |
709 | |
710 // Now that the BOT and the object header have been initialized, | |
711 // we can update top of the "starts humongous" region. | |
712 assert(first_hr->bottom() < new_top && new_top <= first_hr->end(), | |
713 "new_top should be in this region"); | |
714 first_hr->set_top(new_top); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
715 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
716 HeapWord* bottom = first_hr->bottom(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
717 HeapWord* end = first_hr->orig_end(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
718 if ((first + 1) == last) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
719 // the series has a single humongous region |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
720 _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, new_top); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
721 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
722 // the series has more than one humongous regions |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
723 _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
724 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
725 } |
2361 | 726 |
727 // Now, we will update the top fields of the "continues humongous" | |
728 // regions. The reason we need to do this is that, otherwise, | |
729 // these regions would look empty and this will confuse parts of | |
730 // G1. For example, the code that looks for a consecutive number | |
731 // of empty regions will consider them empty and try to | |
732 // re-allocate them. We can extend is_empty() to also include | |
733 // !continuesHumongous(), but it is easier to just update the top | |
734 // fields here. The way we set top for all regions (i.e., top == | |
735 // end for all regions but the last one, top == new_top for the | |
736 // last one) is actually used when we will free up the humongous | |
737 // region in free_humongous_region(). | |
738 hr = NULL; | |
3766 | 739 for (size_t i = first + 1; i < last; ++i) { |
740 hr = region_at(i); | |
2361 | 741 if ((i + 1) == last) { |
742 // last continues humongous region | |
743 assert(hr->bottom() < new_top && new_top <= hr->end(), | |
744 "new_top should fall on this region"); | |
745 hr->set_top(new_top); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
746 _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top); |
2361 | 747 } else { |
748 // not last one | |
749 assert(new_top > hr->end(), "new_top should be above this region"); | |
750 hr->set_top(hr->end()); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
751 _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end()); |
2361 | 752 } |
753 } | |
754 // If we have continues humongous regions (hr != NULL), then the | |
755 // end of the last one should match new_end and its top should | |
756 // match new_top. | |
757 assert(hr == NULL || | |
758 (hr->end() == new_end && hr->top() == new_top), "sanity"); | |
759 | |
760 assert(first_hr->used() == word_size * HeapWordSize, "invariant"); | |
761 _summary_bytes_used += first_hr->used(); | |
762 _humongous_set.add(first_hr); | |
763 | |
764 return new_obj; | |
765 } | |
766 | |
342 | 767 // If could fit into free regions w/o expansion, try. |
768 // Otherwise, if can expand, do so. | |
769 // Otherwise, if using ex regions might help, try with ex given back. | |
1973 | 770 HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) { |
2152 | 771 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); |
772 | |
773 verify_region_sets_optional(); | |
342 | 774 |
775 size_t num_regions = | |
1973 | 776 round_to(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords; |
342 | 777 size_t x_size = expansion_regions(); |
3766 | 778 size_t fs = _hrs.free_suffix(); |
779 size_t first = humongous_obj_allocate_find_first(num_regions, word_size); | |
780 if (first == G1_NULL_HRS_INDEX) { | |
2152 | 781 // The only thing we can do now is attempt expansion. |
342 | 782 if (fs + x_size >= num_regions) { |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
783 // 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
|
784 // 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
|
785 // 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
|
786 // should have succeeded and we wouldn't be here. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
787 // |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
788 // 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
|
789 // 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
|
790 // room available. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
791 assert(num_regions > fs, "earlier allocation should have succeeded"); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
792 |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
793 if (expand((num_regions - fs) * HeapRegion::GrainBytes)) { |
3766 | 794 // Even though the heap was expanded, it might not have |
795 // reached the desired size. So, we cannot assume that the | |
796 // allocation will succeed. | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
797 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
|
798 } |
2152 | 799 } |
800 } | |
801 | |
2361 | 802 HeapWord* result = NULL; |
3766 | 803 if (first != G1_NULL_HRS_INDEX) { |
2361 | 804 result = |
805 humongous_obj_allocate_initialize_regions(first, num_regions, word_size); | |
806 assert(result != NULL, "it should always return a valid result"); | |
2152 | 807 } |
808 | |
809 verify_region_sets_optional(); | |
2361 | 810 |
811 return result; | |
342 | 812 } |
813 | |
1973 | 814 HeapWord* G1CollectedHeap::allocate_new_tlab(size_t word_size) { |
815 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
|
816 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
|
817 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
818 unsigned int dummy_gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
819 return attempt_allocation(word_size, &dummy_gc_count_before); |
342 | 820 } |
821 | |
822 HeapWord* | |
823 G1CollectedHeap::mem_allocate(size_t word_size, | |
1973 | 824 bool* gc_overhead_limit_was_exceeded) { |
825 assert_heap_not_locked_and_not_at_safepoint(); | |
342 | 826 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
827 // Loop until the allocation is satisified, or unsatisfied after GC. |
1973 | 828 for (int try_count = 1; /* we'll return */; try_count += 1) { |
829 unsigned int gc_count_before; | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
830 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
831 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
832 if (!isHumongous(word_size)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
833 result = attempt_allocation(word_size, &gc_count_before); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
834 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
835 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
|
836 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
837 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
838 return result; |
342 | 839 } |
840 | |
841 // Create the garbage collection operation... | |
1973 | 842 VM_G1CollectForAllocation op(gc_count_before, word_size); |
342 | 843 // ...and get the VM thread to execute it. |
844 VMThread::execute(&op); | |
1973 | 845 |
846 if (op.prologue_succeeded() && op.pause_succeeded()) { | |
847 // If the operation was successful we'll return the result even | |
848 // if it is NULL. If the allocation attempt failed immediately | |
849 // after a Full GC, it's unlikely we'll be able to allocate now. | |
850 HeapWord* result = op.result(); | |
851 if (result != NULL && !isHumongous(word_size)) { | |
852 // Allocations that take place on VM operations do not do any | |
853 // card dirtying and we have to do it here. We only have to do | |
854 // this for non-humongous allocations, though. | |
855 dirty_young_block(result, word_size); | |
856 } | |
342 | 857 return result; |
1973 | 858 } else { |
859 assert(op.result() == NULL, | |
860 "the result should be NULL if the VM op did not succeed"); | |
342 | 861 } |
862 | |
863 // Give a warning if we seem to be looping forever. | |
864 if ((QueuedAllocationWarningCount > 0) && | |
865 (try_count % QueuedAllocationWarningCount == 0)) { | |
1973 | 866 warning("G1CollectedHeap::mem_allocate retries %d times", try_count); |
342 | 867 } |
868 } | |
1973 | 869 |
870 ShouldNotReachHere(); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
871 return NULL; |
342 | 872 } |
873 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
874 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
|
875 unsigned int *gc_count_before_ret) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
876 // 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
|
877 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
878 assert_heap_not_locked_and_not_at_safepoint(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
879 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
|
880 "be called for humongous allocation requests"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
881 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
882 // 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
|
883 // (attempt_allocation()) failed to allocate. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
884 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
885 // 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
|
886 // 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
|
887 // 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
|
888 // return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
889 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
890 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
|
891 bool should_try_gc; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
892 unsigned int gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
893 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
894 { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
895 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
896 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
897 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
|
898 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
899 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
900 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
901 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
902 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
903 // 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
|
904 // 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
|
905 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
|
906 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
907 if (GC_locker::is_active_and_needs_gc()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
908 if (g1_policy()->can_expand_young_list()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
909 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
|
910 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
911 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
912 return result; |
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 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
915 should_try_gc = false; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
916 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
917 // 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
|
918 gc_count_before = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
919 should_try_gc = true; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
920 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
921 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
922 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
923 if (should_try_gc) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
924 bool succeeded; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
925 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
|
926 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
927 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
|
928 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
929 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
930 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
931 if (succeeded) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
932 // 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
|
933 // 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
|
934 // further. We'll just return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
935 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
936 *gc_count_before_ret = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
937 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
938 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
939 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
940 GC_locker::stall_until_clear(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
941 } |
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 // 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
|
944 // 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
|
945 // 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
|
946 // allocation attempt in case another thread successfully |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
947 // 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
|
948 // 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
|
949 // 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
|
950 // iteration (after taking the Heap_lock). |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
951 result = _mutator_alloc_region.attempt_allocation(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
952 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
953 if (result != NULL ){ |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
954 return result; |
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 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
957 // 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
|
958 if ((QueuedAllocationWarningCount > 0) && |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
959 (try_count % QueuedAllocationWarningCount == 0)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
960 warning("G1CollectedHeap::attempt_allocation_slow() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
961 "retries %d times", try_count); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
962 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
963 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
964 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
965 ShouldNotReachHere(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
966 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
967 } |
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 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
|
970 unsigned int * gc_count_before_ret) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
971 // 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
|
972 // 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
|
973 // 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
|
974 // 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
|
975 // 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
|
976 // 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
|
977 // 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
|
978 // 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
|
979 // 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
|
980 // much as possible. |
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 assert_heap_not_locked_and_not_at_safepoint(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
983 assert(isHumongous(word_size), "attempt_allocation_humongous() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
984 "should only be called for humongous allocations"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
985 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
986 // 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
|
987 // 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
|
988 // 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
|
989 // return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
990 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
991 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
|
992 bool should_try_gc; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
993 unsigned int gc_count_before; |
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 { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
996 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
997 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
998 // 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
|
999 // 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
|
1000 // 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
|
1001 result = humongous_obj_allocate(word_size); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1002 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1003 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1004 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1005 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1006 if (GC_locker::is_active_and_needs_gc()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1007 should_try_gc = false; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1008 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1009 // 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
|
1010 gc_count_before = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1011 should_try_gc = true; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1012 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1013 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1014 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1015 if (should_try_gc) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1016 // 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
|
1017 // 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
|
1018 // 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
|
1019 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1020 bool succeeded; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1021 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
|
1022 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1023 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
|
1024 return result; |
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 if (succeeded) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1028 // 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
|
1029 // 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
|
1030 // further. We'll just return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1031 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1032 *gc_count_before_ret = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1033 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1034 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1035 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1036 GC_locker::stall_until_clear(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1037 } |
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 // 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
|
1040 // 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
|
1041 // 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
|
1042 // allocation attempt in case another thread successfully |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1043 // 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
|
1044 // warning if we seem to be looping forever. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1045 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1046 if ((QueuedAllocationWarningCount > 0) && |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1047 (try_count % QueuedAllocationWarningCount == 0)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1048 warning("G1CollectedHeap::attempt_allocation_humongous() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1049 "retries %d times", try_count); |
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 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1053 ShouldNotReachHere(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1054 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1055 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1056 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1057 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
|
1058 bool expect_null_mutator_alloc_region) { |
2152 | 1059 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
|
1060 assert(_mutator_alloc_region.get() == NULL || |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1061 !expect_null_mutator_alloc_region, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1062 "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
|
1063 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1064 if (!isHumongous(word_size)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1065 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
|
1066 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1067 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1068 return humongous_obj_allocate(word_size); |
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 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1071 ShouldNotReachHere(); |
342 | 1072 } |
1073 | |
1074 class PostMCRemSetClearClosure: public HeapRegionClosure { | |
1075 ModRefBarrierSet* _mr_bs; | |
1076 public: | |
1077 PostMCRemSetClearClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {} | |
1078 bool doHeapRegion(HeapRegion* r) { | |
1079 r->reset_gc_time_stamp(); | |
1080 if (r->continuesHumongous()) | |
1081 return false; | |
1082 HeapRegionRemSet* hrrs = r->rem_set(); | |
1083 if (hrrs != NULL) hrrs->clear(); | |
1084 // You might think here that we could clear just the cards | |
1085 // corresponding to the used region. But no: if we leave a dirty card | |
1086 // in a region we might allocate into, then it would prevent that card | |
1087 // from being enqueued, and cause it to be missed. | |
1088 // Re: the performance cost: we shouldn't be doing full GC anyway! | |
1089 _mr_bs->clear(MemRegion(r->bottom(), r->end())); | |
1090 return false; | |
1091 } | |
1092 }; | |
1093 | |
1094 | |
1095 class PostMCRemSetInvalidateClosure: public HeapRegionClosure { | |
1096 ModRefBarrierSet* _mr_bs; | |
1097 public: | |
1098 PostMCRemSetInvalidateClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {} | |
1099 bool doHeapRegion(HeapRegion* r) { | |
1100 if (r->continuesHumongous()) return false; | |
1101 if (r->used_region().word_size() != 0) { | |
1102 _mr_bs->invalidate(r->used_region(), true /*whole heap*/); | |
1103 } | |
1104 return false; | |
1105 } | |
1106 }; | |
1107 | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1108 class RebuildRSOutOfRegionClosure: public HeapRegionClosure { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1109 G1CollectedHeap* _g1h; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1110 UpdateRSOopClosure _cl; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1111 int _worker_i; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1112 public: |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1113 RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) : |
1861 | 1114 _cl(g1->g1_rem_set(), worker_i), |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1115 _worker_i(worker_i), |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1116 _g1h(g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1117 { } |
1960
878b57474103
6978187: G1: assert(ParallelGCThreads> 1 || n_yielded() == _hrrs->occupied()) strikes again
johnc
parents:
1883
diff
changeset
|
1118 |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1119 bool doHeapRegion(HeapRegion* r) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1120 if (!r->continuesHumongous()) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1121 _cl.set_from(r); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1122 r->oop_iterate(&_cl); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1123 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1124 return false; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1125 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1126 }; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1127 |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1128 class ParRebuildRSTask: public AbstractGangTask { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1129 G1CollectedHeap* _g1; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1130 public: |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1131 ParRebuildRSTask(G1CollectedHeap* g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1132 : AbstractGangTask("ParRebuildRSTask"), |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1133 _g1(g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1134 { } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1135 |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1136 void work(int i) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1137 RebuildRSOutOfRegionClosure rebuild_rs(_g1, i); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1138 _g1->heap_region_par_iterate_chunked(&rebuild_rs, i, |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1139 HeapRegion::RebuildRSClaimValue); |
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 }; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1142 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1143 class PostCompactionPrinterClosure: public HeapRegionClosure { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1144 private: |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1145 G1HRPrinter* _hr_printer; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1146 public: |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1147 bool doHeapRegion(HeapRegion* hr) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1148 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
|
1149 // We only generate output for non-empty regions. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1150 if (!hr->is_empty()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1151 if (!hr->isHumongous()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1152 _hr_printer->post_compaction(hr, G1HRPrinter::Old); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1153 } else if (hr->startsHumongous()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1154 if (hr->capacity() == (size_t) HeapRegion::GrainBytes) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1155 // single humongous region |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1156 _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1157 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1158 _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1159 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1160 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1161 assert(hr->continuesHumongous(), "only way to get here"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1162 _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1163 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1164 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1165 return false; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1166 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1167 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1168 PostCompactionPrinterClosure(G1HRPrinter* hr_printer) |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1169 : _hr_printer(hr_printer) { } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1170 }; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1171 |
1973 | 1172 bool G1CollectedHeap::do_collection(bool explicit_gc, |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1173 bool clear_all_soft_refs, |
342 | 1174 size_t word_size) { |
2152 | 1175 assert_at_safepoint(true /* should_be_vm_thread */); |
1176 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1177 if (GC_locker::check_active_before_gc()) { |
1973 | 1178 return false; |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1179 } |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1180 |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
2039
diff
changeset
|
1181 SvcGCMarker sgcm(SvcGCMarker::FULL); |
342 | 1182 ResourceMark rm; |
1183 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1184 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1185 Universe::print_heap_before_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1186 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1187 |
2152 | 1188 verify_region_sets_optional(); |
342 | 1189 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1190 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
|
1191 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
|
1192 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1193 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
|
1194 |
342 | 1195 { |
1196 IsGCActiveMark x; | |
1197 | |
1198 // Timing | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1199 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
|
1200 assert(!system_gc || explicit_gc, "invariant"); |
342 | 1201 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
1202 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1203 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
|
1204 PrintGC, true, gclog_or_tty); |
342 | 1205 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
1206 TraceCollectorStats tcs(g1mm()->full_collection_counters()); |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
3323
diff
changeset
|
1207 TraceMemoryManagerStats tms(true /* fullGC */, gc_cause()); |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1208 |
342 | 1209 double start = os::elapsedTime(); |
1210 g1_policy()->record_full_collection_start(); | |
1211 | |
2152 | 1212 wait_while_free_regions_coming(); |
2361 | 1213 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 1214 |
342 | 1215 gc_prologue(true); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1216 increment_total_collections(true /* full gc */); |
342 | 1217 |
1218 size_t g1h_prev_used = used(); | |
1219 assert(used() == recalculate_used(), "Should be equal"); | |
1220 | |
1221 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { | |
1222 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
|
1223 gclog_or_tty->print(" VerifyBeforeGC:"); |
342 | 1224 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1225 Universe::verify(/* allow dirty */ true, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1226 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1227 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1228 |
342 | 1229 } |
1230 | |
1231 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
1232 | |
1233 // We want to discover references, but not process them yet. | |
1234 // This mode is disabled in | |
1235 // instanceRefKlass::process_discovered_references if the | |
1236 // generation does some collection work, or | |
1237 // instanceRefKlass::enqueue_discovered_references if the | |
1238 // generation returns without doing any work. | |
1239 ref_processor()->disable_discovery(); | |
1240 ref_processor()->abandon_partial_discovery(); | |
1241 ref_processor()->verify_no_references_recorded(); | |
1242 | |
1243 // Abandon current iterations of concurrent marking and concurrent | |
1244 // refinement, if any are in progress. | |
1245 concurrent_mark()->abort(); | |
1246 | |
1247 // 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
|
1248 release_mutator_alloc_region(); |
636 | 1249 abandon_gc_alloc_regions(); |
1861 | 1250 g1_rem_set()->cleanupHRRS(); |
342 | 1251 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
|
1252 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1253 // 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
|
1254 // 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
|
1255 // before the start GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1256 _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
|
1257 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1258 // 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
|
1259 // 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
|
1260 // 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
|
1261 // after this full GC. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1262 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
|
1263 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
|
1264 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
|
1265 |
342 | 1266 if (g1_policy()->in_young_gc_mode()) { |
1267 empty_young_list(); | |
1268 g1_policy()->set_full_young_gcs(true); | |
1269 } | |
1270 | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
1271 // 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
|
1272 // how reference processing currently works in G1. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
1273 |
342 | 1274 // Temporarily make reference _discovery_ single threaded (non-MT). |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
1275 ReferenceProcessorMTDiscoveryMutator rp_disc_ser(ref_processor(), false); |
342 | 1276 |
1277 // Temporarily make refs discovery atomic | |
1278 ReferenceProcessorAtomicMutator rp_disc_atomic(ref_processor(), true); | |
1279 | |
1280 // Temporarily clear _is_alive_non_header | |
1281 ReferenceProcessorIsAliveMutator rp_is_alive_null(ref_processor(), NULL); | |
1282 | |
1283 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
|
1284 ref_processor()->setup_policy(do_clear_all_soft_refs); |
342 | 1285 // Do collection work |
1286 { | |
1287 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
|
1288 G1MarkSweep::invoke_at_safepoint(ref_processor(), do_clear_all_soft_refs); |
342 | 1289 } |
2152 | 1290 assert(free_regions() == 0, "we should not have added any free regions"); |
342 | 1291 rebuild_region_lists(); |
1292 | |
1293 _summary_bytes_used = recalculate_used(); | |
1294 | |
1295 ref_processor()->enqueue_discovered_references(); | |
1296 | |
1297 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | |
1298 | |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1299 MemoryService::track_memory_usage(); |
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1300 |
342 | 1301 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { |
1302 HandleMark hm; // Discard invalid handles created during verification | |
1303 gclog_or_tty->print(" VerifyAfterGC:"); | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
1304 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1305 Universe::verify(/* allow dirty */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1306 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1307 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1308 |
342 | 1309 } |
1310 NOT_PRODUCT(ref_processor()->verify_no_references_recorded()); | |
1311 | |
1312 reset_gc_time_stamp(); | |
1313 // Since everything potentially moved, we will clear all remembered | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1314 // sets, and clear all cards. Later we will rebuild remebered |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1315 // sets. We will also reset the GC time stamps of the regions. |
342 | 1316 PostMCRemSetClearClosure rs_clear(mr_bs()); |
1317 heap_region_iterate(&rs_clear); | |
1318 | |
1319 // Resize the heap if necessary. | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1320 resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); |
342 | 1321 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1322 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1323 // 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
|
1324 // that all the COMMIT / UNCOMMIT events are generated before |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1325 // the end GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1326 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1327 PostCompactionPrinterClosure cl(hr_printer()); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1328 heap_region_iterate(&cl); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1329 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1330 _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
|
1331 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1332 |
342 | 1333 if (_cg1r->use_cache()) { |
1334 _cg1r->clear_and_record_card_counts(); | |
1335 _cg1r->clear_hot_cache(); | |
1336 } | |
1337 | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1338 // Rebuild remembered sets of all regions. |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
1339 |
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
1340 if (G1CollectedHeap::use_parallel_gc_threads()) { |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1341 ParRebuildRSTask rebuild_rs_task(this); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1342 assert(check_heap_region_claim_values( |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1343 HeapRegion::InitialClaimValue), "sanity check"); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1344 set_par_threads(workers()->total_workers()); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1345 workers()->run_task(&rebuild_rs_task); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1346 set_par_threads(0); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1347 assert(check_heap_region_claim_values( |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1348 HeapRegion::RebuildRSClaimValue), "sanity check"); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1349 reset_heap_region_claim_values(); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1350 } else { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1351 RebuildRSOutOfRegionClosure rebuild_rs(this); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1352 heap_region_iterate(&rebuild_rs); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1353 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1354 |
342 | 1355 if (PrintGC) { |
1356 print_size_transition(gclog_or_tty, g1h_prev_used, used(), capacity()); | |
1357 } | |
1358 | |
1359 if (true) { // FIXME | |
1360 // Ask the permanent generation to adjust size for full collections | |
1361 perm()->compute_new_size(); | |
1362 } | |
1363 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1364 // 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
|
1365 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
|
1366 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
|
1367 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1368 // 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
|
1369 // 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
|
1370 // evacuation pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1371 clear_cset_fast_test(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1372 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1373 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1374 |
342 | 1375 double end = os::elapsedTime(); |
1376 g1_policy()->record_full_collection_end(); | |
1377 | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1378 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1379 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1380 #endif |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1381 |
342 | 1382 gc_epilogue(true); |
1383 | |
794 | 1384 // Discard all rset updates |
1385 JavaThread::dirty_card_queue_set().abandon_logs(); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
1386 assert(!G1DeferredRSUpdate |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
1387 || (G1DeferredRSUpdate && (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any"); |
342 | 1388 } |
1389 | |
1390 if (g1_policy()->in_young_gc_mode()) { | |
1391 _young_list->reset_sampled_info(); | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1392 // At this point there should be no regions in the |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1393 // entire heap tagged as young. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1394 assert( check_young_list_empty(true /* check_heap */), |
342 | 1395 "young list should be empty at this point"); |
1396 } | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1397 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1398 // 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
|
1399 increment_full_collections_completed(false /* concurrent */); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1400 |
3766 | 1401 _hrs.verify_optional(); |
2152 | 1402 verify_region_sets_optional(); |
1403 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1404 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1405 Universe::print_heap_after_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1406 } |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
1407 g1mm()->update_counters(); |
1973 | 1408 |
1409 return true; | |
342 | 1410 } |
1411 | |
1412 void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { | |
1973 | 1413 // do_collection() will return whether it succeeded in performing |
1414 // the GC. Currently, there is no facility on the | |
1415 // do_full_collection() API to notify the caller than the collection | |
1416 // did not succeed (e.g., because it was locked out by the GC | |
1417 // locker). So, right now, we'll ignore the return value. | |
1418 bool dummy = do_collection(true, /* explicit_gc */ | |
1419 clear_all_soft_refs, | |
1420 0 /* word_size */); | |
342 | 1421 } |
1422 | |
1423 // This code is mostly copied from TenuredGeneration. | |
1424 void | |
1425 G1CollectedHeap:: | |
1426 resize_if_necessary_after_full_collection(size_t word_size) { | |
1427 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, "sanity check"); | |
1428 | |
1429 // Include the current allocation, if any, and bytes that will be | |
1430 // pre-allocated to support collections, as "used". | |
1431 const size_t used_after_gc = used(); | |
1432 const size_t capacity_after_gc = capacity(); | |
1433 const size_t free_after_gc = capacity_after_gc - used_after_gc; | |
1434 | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1435 // This is enforced in arguments.cpp. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1436 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1437 "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
|
1438 |
342 | 1439 // 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
|
1440 const double minimum_free_percentage = (double) MinHeapFreeRatio / 100.0; |
342 | 1441 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
|
1442 const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100.0; |
342 | 1443 const double minimum_used_percentage = 1.0 - maximum_free_percentage; |
1444 | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1445 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
|
1446 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
|
1447 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1448 // 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
|
1449 // 32-bit size_t's. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1450 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
|
1451 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
|
1452 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
|
1453 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1454 // 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
|
1455 // 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
|
1456 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
|
1457 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
|
1458 desired_capacity_upper_bound); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1459 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
|
1460 desired_capacity_upper_bound); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1461 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1462 // 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
|
1463 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
|
1464 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
|
1465 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1466 // 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
|
1467 // 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
|
1468 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
|
1469 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
|
1470 "maximum_desired_capacity = "SIZE_FORMAT, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1471 minimum_desired_capacity, maximum_desired_capacity)); |
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 // 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
|
1474 // 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
|
1475 // 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
|
1476 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
|
1477 // 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
|
1478 // 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
|
1479 // 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
|
1480 maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size); |
342 | 1481 |
1482 if (PrintGC && Verbose) { | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1483 const double free_percentage = |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1484 (double) free_after_gc / (double) capacity_after_gc; |
342 | 1485 gclog_or_tty->print_cr("Computing new size after full GC "); |
1486 gclog_or_tty->print_cr(" " | |
1487 " minimum_free_percentage: %6.2f", | |
1488 minimum_free_percentage); | |
1489 gclog_or_tty->print_cr(" " | |
1490 " maximum_free_percentage: %6.2f", | |
1491 maximum_free_percentage); | |
1492 gclog_or_tty->print_cr(" " | |
1493 " capacity: %6.1fK" | |
1494 " minimum_desired_capacity: %6.1fK" | |
1495 " maximum_desired_capacity: %6.1fK", | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1496 (double) capacity_after_gc / (double) K, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1497 (double) minimum_desired_capacity / (double) K, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1498 (double) maximum_desired_capacity / (double) K); |
342 | 1499 gclog_or_tty->print_cr(" " |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1500 " free_after_gc: %6.1fK" |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1501 " used_after_gc: %6.1fK", |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1502 (double) free_after_gc / (double) K, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1503 (double) used_after_gc / (double) K); |
342 | 1504 gclog_or_tty->print_cr(" " |
1505 " free_percentage: %6.2f", | |
1506 free_percentage); | |
1507 } | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1508 if (capacity_after_gc < minimum_desired_capacity) { |
342 | 1509 // Don't expand unless it's significant |
1510 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1511 if (expand(expand_bytes)) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1512 if (PrintGC && Verbose) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1513 gclog_or_tty->print_cr(" " |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1514 " expanding:" |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1515 " max_heap_size: %6.1fK" |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1516 " minimum_desired_capacity: %6.1fK" |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1517 " expand_bytes: %6.1fK", |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1518 (double) max_heap_size / (double) K, |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1519 (double) minimum_desired_capacity / (double) K, |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1520 (double) expand_bytes / (double) K); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1521 } |
342 | 1522 } |
1523 | |
1524 // 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
|
1525 } else if (capacity_after_gc > maximum_desired_capacity) { |
342 | 1526 // Capacity too large, compute shrinking size |
1527 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; | |
1528 shrink(shrink_bytes); | |
1529 if (PrintGC && Verbose) { | |
1530 gclog_or_tty->print_cr(" " | |
1531 " shrinking:" | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1532 " min_heap_size: %6.1fK" |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1533 " maximum_desired_capacity: %6.1fK" |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1534 " shrink_bytes: %6.1fK", |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1535 (double) min_heap_size / (double) K, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1536 (double) maximum_desired_capacity / (double) K, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1537 (double) shrink_bytes / (double) K); |
342 | 1538 } |
1539 } | |
1540 } | |
1541 | |
1542 | |
1543 HeapWord* | |
1973 | 1544 G1CollectedHeap::satisfy_failed_allocation(size_t word_size, |
1545 bool* succeeded) { | |
2152 | 1546 assert_at_safepoint(true /* should_be_vm_thread */); |
1973 | 1547 |
1548 *succeeded = true; | |
1549 // Let's attempt the allocation first. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1550 HeapWord* result = |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1551 attempt_allocation_at_safepoint(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1552 false /* expect_null_mutator_alloc_region */); |
1973 | 1553 if (result != NULL) { |
1554 assert(*succeeded, "sanity"); | |
1555 return result; | |
1556 } | |
342 | 1557 |
1558 // In a G1 heap, we're supposed to keep allocation from failing by | |
1559 // incremental pauses. Therefore, at least for now, we'll favor | |
1560 // expansion over collection. (This might change in the future if we can | |
1561 // do something smarter than full collection to satisfy a failed alloc.) | |
1562 result = expand_and_allocate(word_size); | |
1563 if (result != NULL) { | |
1973 | 1564 assert(*succeeded, "sanity"); |
342 | 1565 return result; |
1566 } | |
1567 | |
1973 | 1568 // Expansion didn't work, we'll try to do a Full GC. |
1569 bool gc_succeeded = do_collection(false, /* explicit_gc */ | |
1570 false, /* clear_all_soft_refs */ | |
1571 word_size); | |
1572 if (!gc_succeeded) { | |
1573 *succeeded = false; | |
1574 return NULL; | |
1575 } | |
1576 | |
1577 // Retry the allocation | |
1578 result = attempt_allocation_at_safepoint(word_size, | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1579 true /* expect_null_mutator_alloc_region */); |
342 | 1580 if (result != NULL) { |
1973 | 1581 assert(*succeeded, "sanity"); |
342 | 1582 return result; |
1583 } | |
1584 | |
1973 | 1585 // Then, try a Full GC that will collect all soft references. |
1586 gc_succeeded = do_collection(false, /* explicit_gc */ | |
1587 true, /* clear_all_soft_refs */ | |
1588 word_size); | |
1589 if (!gc_succeeded) { | |
1590 *succeeded = false; | |
1591 return NULL; | |
1592 } | |
1593 | |
1594 // Retry the allocation once more | |
1595 result = attempt_allocation_at_safepoint(word_size, | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1596 true /* expect_null_mutator_alloc_region */); |
342 | 1597 if (result != NULL) { |
1973 | 1598 assert(*succeeded, "sanity"); |
342 | 1599 return result; |
1600 } | |
1601 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1602 assert(!collector_policy()->should_clear_all_soft_refs(), |
1973 | 1603 "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
|
1604 |
342 | 1605 // What else? We might try synchronous finalization later. If the total |
1606 // space available is large enough for the allocation, then a more | |
1607 // complete compaction phase than we've tried so far might be | |
1608 // appropriate. | |
1973 | 1609 assert(*succeeded, "sanity"); |
342 | 1610 return NULL; |
1611 } | |
1612 | |
1613 // Attempting to expand the heap sufficiently | |
1614 // to support an allocation of the given "word_size". If | |
1615 // successful, perform the allocation and return the address of the | |
1616 // allocated block, or else "NULL". | |
1617 | |
1618 HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size) { | |
2152 | 1619 assert_at_safepoint(true /* should_be_vm_thread */); |
1620 | |
1621 verify_region_sets_optional(); | |
1973 | 1622 |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1623 size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1624 if (expand(expand_bytes)) { |
3766 | 1625 _hrs.verify_optional(); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1626 verify_region_sets_optional(); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1627 return attempt_allocation_at_safepoint(word_size, |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1628 false /* expect_null_mutator_alloc_region */); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1629 } |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1630 return NULL; |
342 | 1631 } |
1632 | |
3766 | 1633 void G1CollectedHeap::update_committed_space(HeapWord* old_end, |
1634 HeapWord* new_end) { | |
1635 assert(old_end != new_end, "don't call this otherwise"); | |
1636 assert((HeapWord*) _g1_storage.high() == new_end, "invariant"); | |
1637 | |
1638 // Update the committed mem region. | |
1639 _g1_committed.set_end(new_end); | |
1640 // Tell the card table about the update. | |
1641 Universe::heap()->barrier_set()->resize_covered_region(_g1_committed); | |
1642 // Tell the BOT about the update. | |
1643 _bot_shared->resize(_g1_committed.word_size()); | |
1644 } | |
1645 | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1646 bool G1CollectedHeap::expand(size_t expand_bytes) { |
342 | 1647 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
|
1648 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); |
342 | 1649 aligned_expand_bytes = align_size_up(aligned_expand_bytes, |
1650 HeapRegion::GrainBytes); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1651 |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1652 if (Verbose && PrintGC) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1653 gclog_or_tty->print("Expanding garbage-first heap from %ldK by %ldK", |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1654 old_mem_size/K, aligned_expand_bytes/K); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1655 } |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1656 |
3766 | 1657 // First commit the memory. |
1658 HeapWord* old_end = (HeapWord*) _g1_storage.high(); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1659 bool successful = _g1_storage.expand_by(aligned_expand_bytes); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1660 if (successful) { |
3766 | 1661 // Then propagate this update to the necessary data structures. |
1662 HeapWord* new_end = (HeapWord*) _g1_storage.high(); | |
1663 update_committed_space(old_end, new_end); | |
1664 | |
1665 FreeRegionList expansion_list("Local Expansion List"); | |
1666 MemRegion mr = _hrs.expand_by(old_end, new_end, &expansion_list); | |
1667 assert(mr.start() == old_end, "post-condition"); | |
1668 // mr might be a smaller region than what was requested if | |
1669 // expand_by() was unable to allocate the HeapRegion instances | |
1670 assert(mr.end() <= new_end, "post-condition"); | |
1671 | |
1672 size_t actual_expand_bytes = mr.byte_size(); | |
1673 assert(actual_expand_bytes <= aligned_expand_bytes, "post-condition"); | |
1674 assert(actual_expand_bytes == expansion_list.total_capacity_bytes(), | |
1675 "post-condition"); | |
1676 if (actual_expand_bytes < aligned_expand_bytes) { | |
1677 // We could not expand _hrs to the desired size. In this case we | |
1678 // need to shrink the committed space accordingly. | |
1679 assert(mr.end() < new_end, "invariant"); | |
1680 | |
1681 size_t diff_bytes = aligned_expand_bytes - actual_expand_bytes; | |
1682 // First uncommit the memory. | |
1683 _g1_storage.shrink_by(diff_bytes); | |
1684 // Then propagate this update to the necessary data structures. | |
1685 update_committed_space(new_end, mr.end()); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1686 } |
3766 | 1687 _free_list.add_as_tail(&expansion_list); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1688 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1689 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1690 HeapWord* curr = mr.start(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1691 while (curr < mr.end()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1692 HeapWord* curr_end = curr + HeapRegion::GrainWords; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1693 _hr_printer.commit(curr, curr_end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1694 curr = curr_end; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1695 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1696 assert(curr == mr.end(), "post-condition"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1697 } |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1698 } else { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1699 // The expansion of the virtual storage space was unsuccessful. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1700 // 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
|
1701 if (G1ExitOnExpansionFailure && |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1702 _g1_storage.uncommitted_size() >= aligned_expand_bytes) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1703 // We had head room... |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1704 vm_exit_out_of_memory(aligned_expand_bytes, "G1 heap expansion"); |
342 | 1705 } |
1706 } | |
2152 | 1707 |
342 | 1708 if (Verbose && PrintGC) { |
1709 size_t new_mem_size = _g1_storage.committed_size(); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1710 gclog_or_tty->print_cr("...%s, expanded to %ldK", |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1711 (successful ? "Successful" : "Failed"), |
342 | 1712 new_mem_size/K); |
1713 } | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1714 return successful; |
342 | 1715 } |
1716 | |
3766 | 1717 void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { |
342 | 1718 size_t old_mem_size = _g1_storage.committed_size(); |
1719 size_t aligned_shrink_bytes = | |
1720 ReservedSpace::page_align_size_down(shrink_bytes); | |
1721 aligned_shrink_bytes = align_size_down(aligned_shrink_bytes, | |
1722 HeapRegion::GrainBytes); | |
1723 size_t num_regions_deleted = 0; | |
3766 | 1724 MemRegion mr = _hrs.shrink_by(aligned_shrink_bytes, &num_regions_deleted); |
1725 HeapWord* old_end = (HeapWord*) _g1_storage.high(); | |
1726 assert(mr.end() == old_end, "post-condition"); | |
1727 if (mr.byte_size() > 0) { | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1728 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1729 HeapWord* curr = mr.end(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1730 while (curr > mr.start()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1731 HeapWord* curr_end = curr; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1732 curr -= HeapRegion::GrainWords; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1733 _hr_printer.uncommit(curr, curr_end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1734 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1735 assert(curr == mr.start(), "post-condition"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1736 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1737 |
342 | 1738 _g1_storage.shrink_by(mr.byte_size()); |
3766 | 1739 HeapWord* new_end = (HeapWord*) _g1_storage.high(); |
1740 assert(mr.start() == new_end, "post-condition"); | |
1741 | |
1742 _expansion_regions += num_regions_deleted; | |
1743 update_committed_space(old_end, new_end); | |
1744 HeapRegionRemSet::shrink_heap(n_regions()); | |
1745 | |
1746 if (Verbose && PrintGC) { | |
1747 size_t new_mem_size = _g1_storage.committed_size(); | |
1748 gclog_or_tty->print_cr("Shrinking garbage-first heap from %ldK by %ldK to %ldK", | |
1749 old_mem_size/K, aligned_shrink_bytes/K, | |
1750 new_mem_size/K); | |
1751 } | |
342 | 1752 } |
1753 } | |
1754 | |
1755 void G1CollectedHeap::shrink(size_t shrink_bytes) { | |
2152 | 1756 verify_region_sets_optional(); |
1757 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1758 // 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
|
1759 // 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
|
1760 // 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
|
1761 abandon_gc_alloc_regions(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1762 |
2152 | 1763 // Instead of tearing down / rebuilding the free lists here, we |
1764 // could instead use the remove_all_pending() method on free_list to | |
1765 // remove only the ones that we need to remove. | |
342 | 1766 tear_down_region_lists(); // We will rebuild them in a moment. |
1767 shrink_helper(shrink_bytes); | |
1768 rebuild_region_lists(); | |
2152 | 1769 |
3766 | 1770 _hrs.verify_optional(); |
2152 | 1771 verify_region_sets_optional(); |
342 | 1772 } |
1773 | |
1774 // Public methods. | |
1775 | |
1776 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
1777 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
1778 #endif // _MSC_VER | |
1779 | |
1780 | |
1781 G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) : | |
1782 SharedHeap(policy_), | |
1783 _g1_policy(policy_), | |
1111 | 1784 _dirty_card_queue_set(false), |
1705 | 1785 _into_cset_dirty_card_queue_set(false), |
2037
b03260081e9b
7006113: G1: Initialize ReferenceProcessor::_is_alive_non_header field
johnc
parents:
2030
diff
changeset
|
1786 _is_alive_closure(this), |
342 | 1787 _ref_processor(NULL), |
1788 _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)), | |
1789 _bot_shared(NULL), | |
1790 _objs_with_preserved_marks(NULL), _preserved_marks_of_objs(NULL), | |
1791 _evac_failure_scan_stack(NULL) , | |
1792 _mark_in_progress(false), | |
2152 | 1793 _cg1r(NULL), _summary_bytes_used(0), |
342 | 1794 _refine_cte_cl(NULL), |
1795 _full_collection(false), | |
2152 | 1796 _free_list("Master Free List"), |
1797 _secondary_free_list("Secondary Free List"), | |
1798 _humongous_set("Master Humongous Set"), | |
1799 _free_regions_coming(false), | |
342 | 1800 _young_list(new YoungList(this)), |
1801 _gc_time_stamp(0), | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1802 _retained_old_gc_alloc_region(NULL), |
526 | 1803 _surviving_young_words(NULL), |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1804 _full_collections_completed(0), |
526 | 1805 _in_cset_fast_test(NULL), |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
1806 _in_cset_fast_test_base(NULL), |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
1807 _dirty_cards_region_list(NULL) { |
342 | 1808 _g1h = this; // To catch bugs. |
1809 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { | |
1810 vm_exit_during_initialization("Failed necessary allocation."); | |
1811 } | |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1812 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1813 _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1814 |
342 | 1815 int n_queues = MAX2((int)ParallelGCThreads, 1); |
1816 _task_queues = new RefToScanQueueSet(n_queues); | |
1817 | |
1818 int n_rem_sets = HeapRegionRemSet::num_par_rem_sets(); | |
1819 assert(n_rem_sets > 0, "Invariant."); | |
1820 | |
1821 HeapRegionRemSetIterator** iter_arr = | |
1822 NEW_C_HEAP_ARRAY(HeapRegionRemSetIterator*, n_queues); | |
1823 for (int i = 0; i < n_queues; i++) { | |
1824 iter_arr[i] = new HeapRegionRemSetIterator(); | |
1825 } | |
1826 _rem_set_iterator = iter_arr; | |
1827 | |
1828 for (int i = 0; i < n_queues; i++) { | |
1829 RefToScanQueue* q = new RefToScanQueue(); | |
1830 q->initialize(); | |
1831 _task_queues->register_queue(i, q); | |
1832 } | |
1833 | |
1834 guarantee(_task_queues != NULL, "task_queues allocation failure."); | |
1835 } | |
1836 | |
1837 jint G1CollectedHeap::initialize() { | |
1166 | 1838 CollectedHeap::pre_initialize(); |
342 | 1839 os::enable_vtime(); |
1840 | |
1841 // Necessary to satisfy locking discipline assertions. | |
1842 | |
1843 MutexLocker x(Heap_lock); | |
1844 | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1845 // 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
|
1846 // it will be used then. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1847 _hr_printer.set_active(G1PrintHeapRegions); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1848 |
342 | 1849 // While there are no constraints in the GC code that HeapWordSize |
1850 // be any particular value, there are multiple other areas in the | |
1851 // system which believe this to be true (e.g. oop->object_size in some | |
1852 // cases incorrectly returns the size in wordSize units rather than | |
1853 // HeapWordSize). | |
1854 guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize"); | |
1855 | |
1856 size_t init_byte_size = collector_policy()->initial_heap_byte_size(); | |
1857 size_t max_byte_size = collector_policy()->max_heap_byte_size(); | |
1858 | |
1859 // Ensure that the sizes are properly aligned. | |
1860 Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap"); | |
1861 Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap"); | |
1862 | |
1863 _cg1r = new ConcurrentG1Refine(); | |
1864 | |
1865 // Reserve the maximum. | |
1866 PermanentGenerationSpec* pgs = collector_policy()->permanent_generation(); | |
1867 // Includes the perm-gen. | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1868 |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1869 // When compressed oops are enabled, the preferred heap base |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1870 // is calculated by subtracting the requested size from the |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1871 // 32Gb boundary and using the result as the base address for |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1872 // heap reservation. If the requested size is not aligned to |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1873 // HeapRegion::GrainBytes (i.e. the alignment that is passed |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1874 // into the ReservedHeapSpace constructor) then the actual |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1875 // base of the reserved heap may end up differing from the |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1876 // address that was requested (i.e. the preferred heap base). |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1877 // 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
|
1878 // compressed oops mode. |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1879 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1880 // 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
|
1881 // 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
|
1882 const size_t total_reserved = max_byte_size + |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1883 align_size_up(pgs->max_size(), HeapRegion::GrainBytes); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1884 Universe::check_alignment(total_reserved, HeapRegion::GrainBytes, "g1 heap and perm"); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1885 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1886 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
|
1887 |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1888 ReservedHeapSpace heap_rs(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1889 UseLargePages, addr); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1890 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1891 if (UseCompressedOops) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1892 if (addr != NULL && !heap_rs.is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1893 // 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
|
1894 // 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
|
1895 // Try again to reserver heap higher. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1896 addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop); |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1897 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1898 ReservedHeapSpace heap_rs0(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1899 UseLargePages, addr); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1900 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1901 if (addr != NULL && !heap_rs0.is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1902 // 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
|
1903 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
|
1904 assert(addr == NULL, ""); |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1905 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1906 ReservedHeapSpace heap_rs1(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1907 UseLargePages, addr); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1908 heap_rs = heap_rs1; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1909 } else { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1910 heap_rs = heap_rs0; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1911 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1912 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1913 } |
342 | 1914 |
1915 if (!heap_rs.is_reserved()) { | |
1916 vm_exit_during_initialization("Could not reserve enough space for object heap"); | |
1917 return JNI_ENOMEM; | |
1918 } | |
1919 | |
1920 // It is important to do this in a way such that concurrent readers can't | |
1921 // temporarily think somethings in the heap. (I've actually seen this | |
1922 // happen in asserts: DLD.) | |
1923 _reserved.set_word_size(0); | |
1924 _reserved.set_start((HeapWord*)heap_rs.base()); | |
1925 _reserved.set_end((HeapWord*)(heap_rs.base() + heap_rs.size())); | |
1926 | |
1927 _expansion_regions = max_byte_size/HeapRegion::GrainBytes; | |
1928 | |
1929 // Create the gen rem set (and barrier set) for the entire reserved region. | |
1930 _rem_set = collector_policy()->create_rem_set(_reserved, 2); | |
1931 set_barrier_set(rem_set()->bs()); | |
1932 if (barrier_set()->is_a(BarrierSet::ModRef)) { | |
1933 _mr_bs = (ModRefBarrierSet*)_barrier_set; | |
1934 } else { | |
1935 vm_exit_during_initialization("G1 requires a mod ref bs."); | |
1936 return JNI_ENOMEM; | |
1937 } | |
1938 | |
1939 // Also create a G1 rem set. | |
1861 | 1940 if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { |
1941 _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs()); | |
342 | 1942 } else { |
1861 | 1943 vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); |
1944 return JNI_ENOMEM; | |
342 | 1945 } |
1946 | |
1947 // Carve out the G1 part of the heap. | |
1948 | |
1949 ReservedSpace g1_rs = heap_rs.first_part(max_byte_size); | |
1950 _g1_reserved = MemRegion((HeapWord*)g1_rs.base(), | |
1951 g1_rs.size()/HeapWordSize); | |
1952 ReservedSpace perm_gen_rs = heap_rs.last_part(max_byte_size); | |
1953 | |
1954 _perm_gen = pgs->init(perm_gen_rs, pgs->init_size(), rem_set()); | |
1955 | |
1956 _g1_storage.initialize(g1_rs, 0); | |
1957 _g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0); | |
3766 | 1958 _hrs.initialize((HeapWord*) _g1_reserved.start(), |
1959 (HeapWord*) _g1_reserved.end(), | |
1960 _expansion_regions); | |
342 | 1961 |
807
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1962 // 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
|
1963 // in the remembered set structures. |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1964 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
|
1965 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
|
1966 |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1967 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
|
1968 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
|
1969 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
|
1970 "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
|
1971 |
2152 | 1972 HeapRegionSet::set_unrealistically_long_length(max_regions() + 1); |
1973 | |
342 | 1974 _bot_shared = new G1BlockOffsetSharedArray(_reserved, |
1975 heap_word_size(init_byte_size)); | |
1976 | |
1977 _g1h = this; | |
1978 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1979 _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
|
1980 _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
|
1981 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1982 // 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
|
1983 // 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
|
1984 // 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
|
1985 _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
|
1986 ((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
|
1987 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1988 // 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
|
1989 // 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
|
1990 // evacuation pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1991 clear_cset_fast_test(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1992 |
342 | 1993 // Create the ConcurrentMark data structure and thread. |
1994 // (Must do this late, so that "max_regions" is defined.) | |
1995 _cm = new ConcurrentMark(heap_rs, (int) max_regions()); | |
1996 _cmThread = _cm->cmThread(); | |
1997 | |
1998 // Initialize the from_card cache structure of HeapRegionRemSet. | |
1999 HeapRegionRemSet::init_heap(max_regions()); | |
2000 | |
677 | 2001 // Now expand into the initial heap size. |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2002 if (!expand(init_byte_size)) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2003 vm_exit_during_initialization("Failed to allocate initial heap."); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2004 return JNI_ENOMEM; |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2005 } |
342 | 2006 |
2007 // Perform any initialization actions delegated to the policy. | |
2008 g1_policy()->init(); | |
2009 | |
2010 g1_policy()->note_start_of_mark_thread(); | |
2011 | |
2012 _refine_cte_cl = | |
2013 new RefineCardTableEntryClosure(ConcurrentG1RefineThread::sts(), | |
2014 g1_rem_set(), | |
2015 concurrent_g1_refine()); | |
2016 JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); | |
2017 | |
2018 JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon, | |
2019 SATB_Q_FL_lock, | |
1111 | 2020 G1SATBProcessCompletedThreshold, |
342 | 2021 Shared_SATB_Q_lock); |
794 | 2022 |
2023 JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, | |
2024 DirtyCardQ_FL_lock, | |
1111 | 2025 concurrent_g1_refine()->yellow_zone(), |
2026 concurrent_g1_refine()->red_zone(), | |
794 | 2027 Shared_DirtyCardQ_lock); |
2028 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2029 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2030 dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2031 DirtyCardQ_FL_lock, |
1111 | 2032 -1, // never trigger processing |
2033 -1, // no limit on length | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2034 Shared_DirtyCardQ_lock, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2035 &JavaThread::dirty_card_queue_set()); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2036 } |
1705 | 2037 |
2038 // Initialize the card queue set used to hold cards containing | |
2039 // references into the collection set. | |
2040 _into_cset_dirty_card_queue_set.initialize(DirtyCardQ_CBL_mon, | |
2041 DirtyCardQ_FL_lock, | |
2042 -1, // never trigger processing | |
2043 -1, // no limit on length | |
2044 Shared_DirtyCardQ_lock, | |
2045 &JavaThread::dirty_card_queue_set()); | |
2046 | |
342 | 2047 // In case we're keeping closure specialization stats, initialize those |
2048 // counts and that mechanism. | |
2049 SpecializationStats::clear(); | |
2050 | |
2051 // Do later initialization work for concurrent refinement. | |
2052 _cg1r->init(); | |
2053 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2054 // 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
|
2055 // 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
|
2056 // space here, lots of asserts fire. |
3766 | 2057 |
2058 HeapRegion* dummy_region = new_heap_region(0 /* index of bottom region */, | |
2059 _g1_reserved.start()); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2060 // 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
|
2061 // 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
|
2062 // 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
|
2063 // 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
|
2064 dummy_region->set_young(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2065 // Make sure it's full. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2066 dummy_region->set_top(dummy_region->end()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2067 G1AllocRegion::setup(this, dummy_region); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2068 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2069 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2070 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2071 // 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
|
2072 // values in the heap have been properly initialized. |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2073 _g1mm = new G1MonitoringSupport(this, &_g1_storage); |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2074 |
342 | 2075 return JNI_OK; |
2076 } | |
2077 | |
2078 void G1CollectedHeap::ref_processing_init() { | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2079 // Reference processing in G1 currently works as follows: |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2080 // |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2081 // * There is only one reference processor instance that |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2082 // '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
|
2083 // below. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2084 // * Reference discovery is not enabled during an incremental |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2085 // pause (see 6484982). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2086 // * 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
|
2087 // during an incremental pause (see 6484982). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2088 // * Reference discovery is enabled at initial marking. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2089 // * Reference discovery is disabled and the discovered |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2090 // references processed etc during remarking. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2091 // * Reference discovery is MT (see below). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2092 // * Reference discovery requires a barrier (see below). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2093 // * Reference processing is currently not MT (see 6608385). |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2094 // * 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
|
2095 // processes any discovered references. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2096 |
342 | 2097 SharedHeap::ref_processing_init(); |
2098 MemRegion mr = reserved_region(); | |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2099 _ref_processor = |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2100 new ReferenceProcessor(mr, // span |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2101 ParallelRefProcEnabled && (ParallelGCThreads > 1), // mt processing |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2102 (int) ParallelGCThreads, // degree of mt processing |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2103 ParallelGCThreads > 1 || ConcGCThreads > 1, // mt discovery |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2104 (int) MAX2(ParallelGCThreads, ConcGCThreads), // degree of mt discovery |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2105 false, // Reference discovery is not atomic |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2106 &_is_alive_closure, // is alive closure for efficiency |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2107 true); // Setting next fields of discovered |
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2108 // lists requires a barrier. |
342 | 2109 } |
2110 | |
2111 size_t G1CollectedHeap::capacity() const { | |
2112 return _g1_committed.byte_size(); | |
2113 } | |
2114 | |
1705 | 2115 void G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure* cl, |
2116 DirtyCardQueue* into_cset_dcq, | |
2117 bool concurrent, | |
342 | 2118 int worker_i) { |
889 | 2119 // Clean cards in the hot card cache |
1705 | 2120 concurrent_g1_refine()->clean_up_cache(worker_i, g1_rem_set(), into_cset_dcq); |
889 | 2121 |
342 | 2122 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); |
2123 int n_completed_buffers = 0; | |
1705 | 2124 while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) { |
342 | 2125 n_completed_buffers++; |
2126 } | |
2127 g1_policy()->record_update_rs_processed_buffers(worker_i, | |
2128 (double) n_completed_buffers); | |
2129 dcqs.clear_n_completed_buffers(); | |
2130 assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!"); | |
2131 } | |
2132 | |
2133 | |
2134 // Computes the sum of the storage used by the various regions. | |
2135 | |
2136 size_t G1CollectedHeap::used() const { | |
862
36b5611220a7
6863216: Clean up debugging debris inadvertently pushed with 6700789
ysr
parents:
861
diff
changeset
|
2137 assert(Heap_lock->owner() != NULL, |
36b5611220a7
6863216: Clean up debugging debris inadvertently pushed with 6700789
ysr
parents:
861
diff
changeset
|
2138 "Should be owned on this thread's behalf."); |
342 | 2139 size_t result = _summary_bytes_used; |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2140 // 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
|
2141 HeapRegion* hr = _mutator_alloc_region.get(); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2142 if (hr != NULL) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2143 result += hr->used(); |
342 | 2144 return result; |
2145 } | |
2146 | |
846
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2147 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
|
2148 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
|
2149 return result; |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2150 } |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2151 |
342 | 2152 class SumUsedClosure: public HeapRegionClosure { |
2153 size_t _used; | |
2154 public: | |
2155 SumUsedClosure() : _used(0) {} | |
2156 bool doHeapRegion(HeapRegion* r) { | |
2157 if (!r->continuesHumongous()) { | |
2158 _used += r->used(); | |
2159 } | |
2160 return false; | |
2161 } | |
2162 size_t result() { return _used; } | |
2163 }; | |
2164 | |
2165 size_t G1CollectedHeap::recalculate_used() const { | |
2166 SumUsedClosure blk; | |
3766 | 2167 heap_region_iterate(&blk); |
342 | 2168 return blk.result(); |
2169 } | |
2170 | |
2171 size_t G1CollectedHeap::unsafe_max_alloc() { | |
2152 | 2172 if (free_regions() > 0) return HeapRegion::GrainBytes; |
342 | 2173 // otherwise, is there space in the current allocation region? |
2174 | |
2175 // We need to store the current allocation region in a local variable | |
2176 // here. The problem is that this method doesn't take any locks and | |
2177 // there may be other threads which overwrite the current allocation | |
2178 // region field. attempt_allocation(), for example, sets it to NULL | |
2179 // and this can happen *after* the NULL check here but before the call | |
2180 // to free(), resulting in a SIGSEGV. Note that this doesn't appear | |
2181 // to be a problem in the optimized build, since the two loads of the | |
2182 // current allocation region field are optimized away. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2183 HeapRegion* hr = _mutator_alloc_region.get(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2184 if (hr == NULL) { |
342 | 2185 return 0; |
2186 } | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2187 return hr->free(); |
342 | 2188 } |
2189 | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2190 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
|
2191 return |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2192 ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2193 (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2194 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2195 |
3285
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2196 #ifndef PRODUCT |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2197 void G1CollectedHeap::allocate_dummy_regions() { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2198 // Let's fill up most of the region |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2199 size_t word_size = HeapRegion::GrainWords - 1024; |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2200 // 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
|
2201 guarantee(isHumongous(word_size), "sanity"); |
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 for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2204 // 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
|
2205 HeapWord* dummy_obj = humongous_obj_allocate(word_size); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2206 if (dummy_obj != NULL) { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2207 MemRegion mr(dummy_obj, word_size); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2208 CollectedHeap::fill_with_object(mr); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2209 } else { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2210 // 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
|
2211 // again. Let's get out of the loop. |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2212 break; |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2213 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2214 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2215 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2216 #endif // !PRODUCT |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2217 |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2218 void G1CollectedHeap::increment_full_collections_completed(bool concurrent) { |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2219 MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2220 |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2221 // 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
|
2222 // 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
|
2223 // 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
|
2224 // assert here. |
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2225 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2226 // 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
|
2227 // 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
|
2228 // collections have been started. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2229 unsigned int full_collections_started = total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2230 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2231 // 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
|
2232 // 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
|
2233 // interrupt a concurrent cycle), the number of full collections |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2234 // 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
|
2235 // 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
|
2236 // behind the number of full collections started. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2237 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2238 // 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
|
2239 assert(concurrent || |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2240 (full_collections_started == _full_collections_completed + 1) || |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2241 (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
|
2242 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
|
2243 "is inconsistent with _full_collections_completed = %u", |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2244 full_collections_started, _full_collections_completed)); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2245 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2246 // 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
|
2247 assert(!concurrent || |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2248 (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
|
2249 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
|
2250 "full_collections_started = %u " |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2251 "is inconsistent with _full_collections_completed = %u", |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2252 full_collections_started, _full_collections_completed)); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2253 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2254 _full_collections_completed += 1; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2255 |
1840
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2256 // 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
|
2257 // we wake up any waiters (especially when ExplicitInvokesConcurrent |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2258 // 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
|
2259 // 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
|
2260 if (concurrent) { |
1840
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2261 _cmThread->clear_in_progress(); |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2262 } |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2263 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2264 // 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
|
2265 // System.gc() with (with ExplicitGCInvokesConcurrent set or not) |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2266 // 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
|
2267 // waiting in VM_G1IncCollectionPause::doit_epilogue(). |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2268 FullGCCount_lock->notify_all(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2269 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2270 |
342 | 2271 void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) { |
2152 | 2272 assert_at_safepoint(true /* should_be_vm_thread */); |
342 | 2273 GCCauseSetter gcs(this, cause); |
2274 switch (cause) { | |
2275 case GCCause::_heap_inspection: | |
2276 case GCCause::_heap_dump: { | |
2277 HandleMark hm; | |
2278 do_full_collection(false); // don't clear all soft refs | |
2279 break; | |
2280 } | |
2281 default: // XXX FIX ME | |
2282 ShouldNotReachHere(); // Unexpected use of this function | |
2283 } | |
2284 } | |
2285 | |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2286 void G1CollectedHeap::collect(GCCause::Cause cause) { |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2287 // 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
|
2288 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
|
2289 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2290 unsigned int gc_count_before; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2291 unsigned int full_gc_count_before; |
342 | 2292 { |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2293 MutexLocker ml(Heap_lock); |
1973 | 2294 |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2295 // 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
|
2296 gc_count_before = SharedHeap::heap()->total_collections(); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2297 full_gc_count_before = SharedHeap::heap()->total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2298 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2299 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2300 if (should_do_concurrent_full_gc(cause)) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2301 // Schedule an initial-mark evacuation pause that will start a |
1973 | 2302 // concurrent cycle. We're setting word_size to 0 which means that |
2303 // we are not requesting a post-GC allocation. | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2304 VM_G1IncCollectionPause op(gc_count_before, |
1973 | 2305 0, /* word_size */ |
2306 true, /* should_initiate_conc_mark */ | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2307 g1_policy()->max_pause_time_ms(), |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2308 cause); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2309 VMThread::execute(&op); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2310 } else { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2311 if (cause == GCCause::_gc_locker |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2312 DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2313 |
1973 | 2314 // Schedule a standard evacuation pause. We're setting word_size |
2315 // 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
|
2316 VM_G1IncCollectionPause op(gc_count_before, |
1973 | 2317 0, /* word_size */ |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2318 false, /* should_initiate_conc_mark */ |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2319 g1_policy()->max_pause_time_ms(), |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2320 cause); |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2321 VMThread::execute(&op); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2322 } else { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2323 // Schedule a Full GC. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2324 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
|
2325 VMThread::execute(&op); |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2326 } |
342 | 2327 } |
2328 } | |
2329 | |
2330 bool G1CollectedHeap::is_in(const void* p) const { | |
3766 | 2331 HeapRegion* hr = _hrs.addr_to_region((HeapWord*) p); |
2332 if (hr != NULL) { | |
342 | 2333 return hr->is_in(p); |
2334 } else { | |
2335 return _perm_gen->as_gen()->is_in(p); | |
2336 } | |
2337 } | |
2338 | |
2339 // Iteration functions. | |
2340 | |
2341 // Iterates an OopClosure over all ref-containing fields of objects | |
2342 // within a HeapRegion. | |
2343 | |
2344 class IterateOopClosureRegionClosure: public HeapRegionClosure { | |
2345 MemRegion _mr; | |
2346 OopClosure* _cl; | |
2347 public: | |
2348 IterateOopClosureRegionClosure(MemRegion mr, OopClosure* cl) | |
2349 : _mr(mr), _cl(cl) {} | |
2350 bool doHeapRegion(HeapRegion* r) { | |
2351 if (! r->continuesHumongous()) { | |
2352 r->oop_iterate(_cl); | |
2353 } | |
2354 return false; | |
2355 } | |
2356 }; | |
2357 | |
678 | 2358 void G1CollectedHeap::oop_iterate(OopClosure* cl, bool do_perm) { |
342 | 2359 IterateOopClosureRegionClosure blk(_g1_committed, cl); |
3766 | 2360 heap_region_iterate(&blk); |
678 | 2361 if (do_perm) { |
2362 perm_gen()->oop_iterate(cl); | |
2363 } | |
342 | 2364 } |
2365 | |
678 | 2366 void G1CollectedHeap::oop_iterate(MemRegion mr, OopClosure* cl, bool do_perm) { |
342 | 2367 IterateOopClosureRegionClosure blk(mr, cl); |
3766 | 2368 heap_region_iterate(&blk); |
678 | 2369 if (do_perm) { |
2370 perm_gen()->oop_iterate(cl); | |
2371 } | |
342 | 2372 } |
2373 | |
2374 // Iterates an ObjectClosure over all objects within a HeapRegion. | |
2375 | |
2376 class IterateObjectClosureRegionClosure: public HeapRegionClosure { | |
2377 ObjectClosure* _cl; | |
2378 public: | |
2379 IterateObjectClosureRegionClosure(ObjectClosure* cl) : _cl(cl) {} | |
2380 bool doHeapRegion(HeapRegion* r) { | |
2381 if (! r->continuesHumongous()) { | |
2382 r->object_iterate(_cl); | |
2383 } | |
2384 return false; | |
2385 } | |
2386 }; | |
2387 | |
678 | 2388 void G1CollectedHeap::object_iterate(ObjectClosure* cl, bool do_perm) { |
342 | 2389 IterateObjectClosureRegionClosure blk(cl); |
3766 | 2390 heap_region_iterate(&blk); |
678 | 2391 if (do_perm) { |
2392 perm_gen()->object_iterate(cl); | |
2393 } | |
342 | 2394 } |
2395 | |
2396 void G1CollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) { | |
2397 // FIXME: is this right? | |
2398 guarantee(false, "object_iterate_since_last_GC not supported by G1 heap"); | |
2399 } | |
2400 | |
2401 // Calls a SpaceClosure on a HeapRegion. | |
2402 | |
2403 class SpaceClosureRegionClosure: public HeapRegionClosure { | |
2404 SpaceClosure* _cl; | |
2405 public: | |
2406 SpaceClosureRegionClosure(SpaceClosure* cl) : _cl(cl) {} | |
2407 bool doHeapRegion(HeapRegion* r) { | |
2408 _cl->do_space(r); | |
2409 return false; | |
2410 } | |
2411 }; | |
2412 | |
2413 void G1CollectedHeap::space_iterate(SpaceClosure* cl) { | |
2414 SpaceClosureRegionClosure blk(cl); | |
3766 | 2415 heap_region_iterate(&blk); |
342 | 2416 } |
2417 | |
3766 | 2418 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { |
2419 _hrs.iterate(cl); | |
342 | 2420 } |
2421 | |
2422 void G1CollectedHeap::heap_region_iterate_from(HeapRegion* r, | |
3766 | 2423 HeapRegionClosure* cl) const { |
2424 _hrs.iterate_from(r, cl); | |
342 | 2425 } |
2426 | |
2427 void | |
2428 G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl, | |
2429 int worker, | |
2430 jint claim_value) { | |
355 | 2431 const size_t regions = n_regions(); |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
2432 const size_t worker_num = (G1CollectedHeap::use_parallel_gc_threads() ? ParallelGCThreads : 1); |
355 | 2433 // try to spread out the starting points of the workers |
2434 const size_t start_index = regions / worker_num * (size_t) worker; | |
2435 | |
2436 // each worker will actually look at all regions | |
2437 for (size_t count = 0; count < regions; ++count) { | |
2438 const size_t index = (start_index + count) % regions; | |
2439 assert(0 <= index && index < regions, "sanity"); | |
2440 HeapRegion* r = region_at(index); | |
2441 // we'll ignore "continues humongous" regions (we'll process them | |
2442 // when we come across their corresponding "start humongous" | |
2443 // region) and regions already claimed | |
2444 if (r->claim_value() == claim_value || r->continuesHumongous()) { | |
2445 continue; | |
2446 } | |
2447 // OK, try to claim it | |
342 | 2448 if (r->claimHeapRegion(claim_value)) { |
355 | 2449 // success! |
2450 assert(!r->continuesHumongous(), "sanity"); | |
2451 if (r->startsHumongous()) { | |
2452 // If the region is "starts humongous" we'll iterate over its | |
2453 // "continues humongous" first; in fact we'll do them | |
2454 // first. The order is important. In on case, calling the | |
2455 // closure on the "starts humongous" region might de-allocate | |
2456 // and clear all its "continues humongous" regions and, as a | |
2457 // result, we might end up processing them twice. So, we'll do | |
2458 // them first (notice: most closures will ignore them anyway) and | |
2459 // then we'll do the "starts humongous" region. | |
2460 for (size_t ch_index = index + 1; ch_index < regions; ++ch_index) { | |
2461 HeapRegion* chr = region_at(ch_index); | |
2462 | |
2463 // if the region has already been claimed or it's not | |
2464 // "continues humongous" we're done | |
2465 if (chr->claim_value() == claim_value || | |
2466 !chr->continuesHumongous()) { | |
2467 break; | |
2468 } | |
2469 | |
2470 // Noone should have claimed it directly. We can given | |
2471 // that we claimed its "starts humongous" region. | |
2472 assert(chr->claim_value() != claim_value, "sanity"); | |
2473 assert(chr->humongous_start_region() == r, "sanity"); | |
2474 | |
2475 if (chr->claimHeapRegion(claim_value)) { | |
2476 // we should always be able to claim it; noone else should | |
2477 // be trying to claim this region | |
2478 | |
2479 bool res2 = cl->doHeapRegion(chr); | |
2480 assert(!res2, "Should not abort"); | |
2481 | |
2482 // Right now, this holds (i.e., no closure that actually | |
2483 // does something with "continues humongous" regions | |
2484 // clears them). We might have to weaken it in the future, | |
2485 // but let's leave these two asserts here for extra safety. | |
2486 assert(chr->continuesHumongous(), "should still be the case"); | |
2487 assert(chr->humongous_start_region() == r, "sanity"); | |
2488 } else { | |
2489 guarantee(false, "we should not reach here"); | |
2490 } | |
2491 } | |
2492 } | |
2493 | |
2494 assert(!r->continuesHumongous(), "sanity"); | |
2495 bool res = cl->doHeapRegion(r); | |
2496 assert(!res, "Should not abort"); | |
2497 } | |
2498 } | |
2499 } | |
2500 | |
390 | 2501 class ResetClaimValuesClosure: public HeapRegionClosure { |
2502 public: | |
2503 bool doHeapRegion(HeapRegion* r) { | |
2504 r->set_claim_value(HeapRegion::InitialClaimValue); | |
2505 return false; | |
2506 } | |
2507 }; | |
2508 | |
2509 void | |
2510 G1CollectedHeap::reset_heap_region_claim_values() { | |
2511 ResetClaimValuesClosure blk; | |
2512 heap_region_iterate(&blk); | |
2513 } | |
2514 | |
355 | 2515 #ifdef ASSERT |
2516 // This checks whether all regions in the heap have the correct claim | |
2517 // value. I also piggy-backed on this a check to ensure that the | |
2518 // humongous_start_region() information on "continues humongous" | |
2519 // regions is correct. | |
2520 | |
2521 class CheckClaimValuesClosure : public HeapRegionClosure { | |
2522 private: | |
2523 jint _claim_value; | |
2524 size_t _failures; | |
2525 HeapRegion* _sh_region; | |
2526 public: | |
2527 CheckClaimValuesClosure(jint claim_value) : | |
2528 _claim_value(claim_value), _failures(0), _sh_region(NULL) { } | |
2529 bool doHeapRegion(HeapRegion* r) { | |
2530 if (r->claim_value() != _claim_value) { | |
2531 gclog_or_tty->print_cr("Region ["PTR_FORMAT","PTR_FORMAT"), " | |
2532 "claim value = %d, should be %d", | |
2533 r->bottom(), r->end(), r->claim_value(), | |
2534 _claim_value); | |
2535 ++_failures; | |
2536 } | |
2537 if (!r->isHumongous()) { | |
2538 _sh_region = NULL; | |
2539 } else if (r->startsHumongous()) { | |
2540 _sh_region = r; | |
2541 } else if (r->continuesHumongous()) { | |
2542 if (r->humongous_start_region() != _sh_region) { | |
2543 gclog_or_tty->print_cr("Region ["PTR_FORMAT","PTR_FORMAT"), " | |
2544 "HS = "PTR_FORMAT", should be "PTR_FORMAT, | |
2545 r->bottom(), r->end(), | |
2546 r->humongous_start_region(), | |
2547 _sh_region); | |
2548 ++_failures; | |
342 | 2549 } |
2550 } | |
355 | 2551 return false; |
2552 } | |
2553 size_t failures() { | |
2554 return _failures; | |
2555 } | |
2556 }; | |
2557 | |
2558 bool G1CollectedHeap::check_heap_region_claim_values(jint claim_value) { | |
2559 CheckClaimValuesClosure cl(claim_value); | |
2560 heap_region_iterate(&cl); | |
2561 return cl.failures() == 0; | |
2562 } | |
2563 #endif // ASSERT | |
342 | 2564 |
2565 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) { | |
2566 HeapRegion* r = g1_policy()->collection_set(); | |
2567 while (r != NULL) { | |
2568 HeapRegion* next = r->next_in_collection_set(); | |
2569 if (cl->doHeapRegion(r)) { | |
2570 cl->incomplete(); | |
2571 return; | |
2572 } | |
2573 r = next; | |
2574 } | |
2575 } | |
2576 | |
2577 void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r, | |
2578 HeapRegionClosure *cl) { | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2579 if (r == NULL) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2580 // 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
|
2581 return; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2582 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2583 |
342 | 2584 assert(r->in_collection_set(), |
2585 "Start region must be a member of the collection set."); | |
2586 HeapRegion* cur = r; | |
2587 while (cur != NULL) { | |
2588 HeapRegion* next = cur->next_in_collection_set(); | |
2589 if (cl->doHeapRegion(cur) && false) { | |
2590 cl->incomplete(); | |
2591 return; | |
2592 } | |
2593 cur = next; | |
2594 } | |
2595 cur = g1_policy()->collection_set(); | |
2596 while (cur != r) { | |
2597 HeapRegion* next = cur->next_in_collection_set(); | |
2598 if (cl->doHeapRegion(cur) && false) { | |
2599 cl->incomplete(); | |
2600 return; | |
2601 } | |
2602 cur = next; | |
2603 } | |
2604 } | |
2605 | |
2606 CompactibleSpace* G1CollectedHeap::first_compactible_space() { | |
3766 | 2607 return n_regions() > 0 ? region_at(0) : NULL; |
342 | 2608 } |
2609 | |
2610 | |
2611 Space* G1CollectedHeap::space_containing(const void* addr) const { | |
2612 Space* res = heap_region_containing(addr); | |
2613 if (res == NULL) | |
2614 res = perm_gen()->space_containing(addr); | |
2615 return res; | |
2616 } | |
2617 | |
2618 HeapWord* G1CollectedHeap::block_start(const void* addr) const { | |
2619 Space* sp = space_containing(addr); | |
2620 if (sp != NULL) { | |
2621 return sp->block_start(addr); | |
2622 } | |
2623 return NULL; | |
2624 } | |
2625 | |
2626 size_t G1CollectedHeap::block_size(const HeapWord* addr) const { | |
2627 Space* sp = space_containing(addr); | |
2628 assert(sp != NULL, "block_size of address outside of heap"); | |
2629 return sp->block_size(addr); | |
2630 } | |
2631 | |
2632 bool G1CollectedHeap::block_is_obj(const HeapWord* addr) const { | |
2633 Space* sp = space_containing(addr); | |
2634 return sp->block_is_obj(addr); | |
2635 } | |
2636 | |
2637 bool G1CollectedHeap::supports_tlab_allocation() const { | |
2638 return true; | |
2639 } | |
2640 | |
2641 size_t G1CollectedHeap::tlab_capacity(Thread* ignored) const { | |
2642 return HeapRegion::GrainBytes; | |
2643 } | |
2644 | |
2645 size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const { | |
2646 // Return the remaining space in the cur alloc region, but not less than | |
2647 // the min TLAB size. | |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2648 |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2649 // 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
|
2650 // 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
|
2651 // humongous objects. |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2652 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2653 HeapRegion* hr = _mutator_alloc_region.get(); |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2654 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
|
2655 if (hr == NULL) { |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2656 return max_tlab_size; |
342 | 2657 } else { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2658 return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab_size); |
342 | 2659 } |
2660 } | |
2661 | |
2662 size_t G1CollectedHeap::max_capacity() const { | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2663 return _g1_reserved.byte_size(); |
342 | 2664 } |
2665 | |
2666 jlong G1CollectedHeap::millis_since_last_gc() { | |
2667 // assert(false, "NYI"); | |
2668 return 0; | |
2669 } | |
2670 | |
2671 void G1CollectedHeap::prepare_for_verify() { | |
2672 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { | |
2673 ensure_parsability(false); | |
2674 } | |
2675 g1_rem_set()->prepare_for_verify(); | |
2676 } | |
2677 | |
2678 class VerifyLivenessOopClosure: public OopClosure { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2679 G1CollectedHeap* _g1h; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2680 VerifyOption _vo; |
342 | 2681 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2682 VerifyLivenessOopClosure(G1CollectedHeap* g1h, VerifyOption vo): |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2683 _g1h(g1h), _vo(vo) |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2684 { } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2685 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
|
2686 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
|
2687 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2688 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
|
2689 oop obj = oopDesc::load_decode_heap_oop(p); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2690 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
|
2691 "Dead object referenced by a not dead object"); |
342 | 2692 } |
2693 }; | |
2694 | |
2695 class VerifyObjsInRegionClosure: public ObjectClosure { | |
811 | 2696 private: |
342 | 2697 G1CollectedHeap* _g1h; |
2698 size_t _live_bytes; | |
2699 HeapRegion *_hr; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2700 VerifyOption _vo; |
342 | 2701 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2702 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2703 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2704 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2705 VerifyObjsInRegionClosure(HeapRegion *hr, VerifyOption vo) |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2706 : _live_bytes(0), _hr(hr), _vo(vo) { |
342 | 2707 _g1h = G1CollectedHeap::heap(); |
2708 } | |
2709 void do_object(oop o) { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2710 VerifyLivenessOopClosure isLive(_g1h, _vo); |
342 | 2711 assert(o != NULL, "Huh?"); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2712 if (!_g1h->is_obj_dead_cond(o, _vo)) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2713 // If the object is alive according to the mark word, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2714 // then verify that the marking information agrees. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2715 // Note we can't verify the contra-positive of the |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2716 // above: if the object is dead (according to the mark |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2717 // 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
|
2718 // but has since became dead, or may have been allocated |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2719 // since the last marking. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2720 if (_vo == VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2721 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
|
2722 } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2723 |
342 | 2724 o->oop_iterate(&isLive); |
1389
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2725 if (!_hr->obj_allocated_since_prev_marking(o)) { |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2726 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
|
2727 _live_bytes += (obj_size * HeapWordSize); |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2728 } |
342 | 2729 } |
2730 } | |
2731 size_t live_bytes() { return _live_bytes; } | |
2732 }; | |
2733 | |
2734 class PrintObjsInRegionClosure : public ObjectClosure { | |
2735 HeapRegion *_hr; | |
2736 G1CollectedHeap *_g1; | |
2737 public: | |
2738 PrintObjsInRegionClosure(HeapRegion *hr) : _hr(hr) { | |
2739 _g1 = G1CollectedHeap::heap(); | |
2740 }; | |
2741 | |
2742 void do_object(oop o) { | |
2743 if (o != NULL) { | |
2744 HeapWord *start = (HeapWord *) o; | |
2745 size_t word_sz = o->size(); | |
2746 gclog_or_tty->print("\nPrinting obj "PTR_FORMAT" of size " SIZE_FORMAT | |
2747 " isMarkedPrev %d isMarkedNext %d isAllocSince %d\n", | |
2748 (void*) o, word_sz, | |
2749 _g1->isMarkedPrev(o), | |
2750 _g1->isMarkedNext(o), | |
2751 _hr->obj_allocated_since_prev_marking(o)); | |
2752 HeapWord *end = start + word_sz; | |
2753 HeapWord *cur; | |
2754 int *val; | |
2755 for (cur = start; cur < end; cur++) { | |
2756 val = (int *) cur; | |
2757 gclog_or_tty->print("\t "PTR_FORMAT":"PTR_FORMAT"\n", val, *val); | |
2758 } | |
2759 } | |
2760 } | |
2761 }; | |
2762 | |
2763 class VerifyRegionClosure: public HeapRegionClosure { | |
811 | 2764 private: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2765 bool _allow_dirty; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2766 bool _par; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2767 VerifyOption _vo; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2768 bool _failures; |
811 | 2769 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2770 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2771 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2772 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2773 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
|
2774 : _allow_dirty(allow_dirty), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2775 _par(par), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2776 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2777 _failures(false) {} |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2778 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2779 bool failures() { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2780 return _failures; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2781 } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2782 |
342 | 2783 bool doHeapRegion(HeapRegion* r) { |
390 | 2784 guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue, |
2785 "Should be unclaimed at verify points."); | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
2786 if (!r->continuesHumongous()) { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2787 bool failures = false; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2788 r->verify(_allow_dirty, _vo, &failures); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2789 if (failures) { |
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 } else { |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2792 VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2793 r->object_iterate(¬_dead_yet_cl); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2794 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
|
2795 gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] " |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2796 "max_live_bytes "SIZE_FORMAT" " |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2797 "< calculated "SIZE_FORMAT, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2798 r->bottom(), r->end(), |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2799 r->max_live_bytes(), |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2800 not_dead_yet_cl.live_bytes()); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2801 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2802 } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2803 } |
342 | 2804 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2805 return false; // stop the region iteration if we hit a failure |
342 | 2806 } |
2807 }; | |
2808 | |
2809 class VerifyRootsClosure: public OopsInGenClosure { | |
2810 private: | |
2811 G1CollectedHeap* _g1h; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2812 VerifyOption _vo; |
342 | 2813 bool _failures; |
2814 public: | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2815 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2816 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2817 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2818 VerifyRootsClosure(VerifyOption vo) : |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2819 _g1h(G1CollectedHeap::heap()), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2820 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2821 _failures(false) { } |
342 | 2822 |
2823 bool failures() { return _failures; } | |
2824 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2825 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
|
2826 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2827 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2828 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
|
2829 if (_g1h->is_obj_dead_cond(obj, _vo)) { |
342 | 2830 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
|
2831 "points to dead obj "PTR_FORMAT, p, (void*) obj); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2832 if (_vo == VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2833 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
|
2834 } |
342 | 2835 obj->print_on(gclog_or_tty); |
2836 _failures = true; | |
2837 } | |
2838 } | |
2839 } | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2840 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2841 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
|
2842 void do_oop(narrowOop* p) { do_oop_nv(p); } |
342 | 2843 }; |
2844 | |
390 | 2845 // This is the task used for parallel heap verification. |
2846 | |
2847 class G1ParVerifyTask: public AbstractGangTask { | |
2848 private: | |
2849 G1CollectedHeap* _g1h; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2850 bool _allow_dirty; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2851 VerifyOption _vo; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2852 bool _failures; |
390 | 2853 |
2854 public: | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2855 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2856 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2857 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2858 G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty, VerifyOption vo) : |
390 | 2859 AbstractGangTask("Parallel verify task"), |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2860 _g1h(g1h), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2861 _allow_dirty(allow_dirty), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2862 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2863 _failures(false) { } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2864 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2865 bool failures() { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2866 return _failures; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2867 } |
390 | 2868 |
2869 void work(int worker_i) { | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
2870 HandleMark hm; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2871 VerifyRegionClosure blk(_allow_dirty, true, _vo); |
390 | 2872 _g1h->heap_region_par_iterate_chunked(&blk, worker_i, |
2873 HeapRegion::ParVerifyClaimValue); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2874 if (blk.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2875 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2876 } |
390 | 2877 } |
2878 }; | |
2879 | |
342 | 2880 void G1CollectedHeap::verify(bool allow_dirty, bool silent) { |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2881 verify(allow_dirty, silent, VerifyOption_G1UsePrevMarking); |
811 | 2882 } |
2883 | |
2884 void G1CollectedHeap::verify(bool allow_dirty, | |
2885 bool silent, | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2886 VerifyOption vo) { |
342 | 2887 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2888 if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); } |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2889 VerifyRootsClosure rootsCl(vo); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
2890 CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2891 |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2892 // 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
|
2893 // 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
|
2894 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
|
2895 |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2896 process_strong_roots(true, // activate StrongRootsScope |
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2897 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
|
2898 // 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
|
2899 SharedHeap::ScanningOption(so), // roots scanning options |
342 | 2900 &rootsCl, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
2901 &blobsCl, |
342 | 2902 &rootsCl); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2903 |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2904 // 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
|
2905 // 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
|
2906 // 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
|
2907 // 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
|
2908 // "Root location <x> points to dead ob <y>" failure. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2909 if (vo != VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2910 // 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
|
2911 // 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
|
2912 // references explicitly below. Whether the relevant cards are dirty |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2913 // is checked further below in the rem set verification. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2914 if (!silent) { gclog_or_tty->print("Permgen roots "); } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2915 perm_gen()->oop_iterate(&rootsCl); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2916 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2917 bool failures = rootsCl.failures(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2918 |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2919 if (vo != VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2920 // 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
|
2921 // 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
|
2922 // verifying the region sets will fail. So we only verify |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2923 // the region sets when not in a full GC. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2924 if (!silent) { gclog_or_tty->print("HeapRegionSets "); } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2925 verify_region_sets(); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2926 } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2927 |
2152 | 2928 if (!silent) { gclog_or_tty->print("HeapRegions "); } |
390 | 2929 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
2930 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
2931 "sanity check"); | |
2932 | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2933 G1ParVerifyTask task(this, allow_dirty, vo); |
390 | 2934 int n_workers = workers()->total_workers(); |
2935 set_par_threads(n_workers); | |
2936 workers()->run_task(&task); | |
2937 set_par_threads(0); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2938 if (task.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2939 failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2940 } |
390 | 2941 |
2942 assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue), | |
2943 "sanity check"); | |
2944 | |
2945 reset_heap_region_claim_values(); | |
2946 | |
2947 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
2948 "sanity check"); | |
2949 } else { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2950 VerifyRegionClosure blk(allow_dirty, false, vo); |
3766 | 2951 heap_region_iterate(&blk); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2952 if (blk.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2953 failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2954 } |
390 | 2955 } |
2152 | 2956 if (!silent) gclog_or_tty->print("RemSet "); |
342 | 2957 rem_set()->verify(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2958 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2959 if (failures) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2960 gclog_or_tty->print_cr("Heap:"); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2961 print_on(gclog_or_tty, true /* extended */); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2962 gclog_or_tty->print_cr(""); |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1545
diff
changeset
|
2963 #ifndef PRODUCT |
1044 | 2964 if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { |
1388 | 2965 concurrent_mark()->print_reachable("at-verification-failure", |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2966 vo, false /* all */); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2967 } |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1545
diff
changeset
|
2968 #endif |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2969 gclog_or_tty->flush(); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2970 } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2971 guarantee(!failures, "there should not have been any failures"); |
342 | 2972 } else { |
2973 if (!silent) gclog_or_tty->print("(SKIPPING roots, heapRegions, remset) "); | |
2974 } | |
2975 } | |
2976 | |
2977 class PrintRegionClosure: public HeapRegionClosure { | |
2978 outputStream* _st; | |
2979 public: | |
2980 PrintRegionClosure(outputStream* st) : _st(st) {} | |
2981 bool doHeapRegion(HeapRegion* r) { | |
2982 r->print_on(_st); | |
2983 return false; | |
2984 } | |
2985 }; | |
2986 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2987 void G1CollectedHeap::print() const { print_on(tty); } |
342 | 2988 |
2989 void G1CollectedHeap::print_on(outputStream* st) const { | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2990 print_on(st, PrintHeapAtGCExtended); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2991 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2992 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2993 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
|
2994 st->print(" %-20s", "garbage-first heap"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2995 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
|
2996 capacity()/K, used_unlocked()/K); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2997 st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2998 _g1_storage.low_boundary(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
2999 _g1_storage.high(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3000 _g1_storage.high_boundary()); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3001 st->cr(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3002 st->print(" region size " SIZE_FORMAT "K, ", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3003 HeapRegion::GrainBytes/K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3004 size_t young_regions = _young_list->length(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3005 st->print(SIZE_FORMAT " young (" SIZE_FORMAT "K), ", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3006 young_regions, young_regions * HeapRegion::GrainBytes / K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3007 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
|
3008 st->print(SIZE_FORMAT " survivors (" SIZE_FORMAT "K)", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3009 survivor_regions, survivor_regions * HeapRegion::GrainBytes / K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3010 st->cr(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3011 perm()->as_gen()->print_on(st); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3012 if (extended) { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3013 st->cr(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3014 print_on_extended(st); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3015 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3016 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3017 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3018 void G1CollectedHeap::print_on_extended(outputStream* st) const { |
342 | 3019 PrintRegionClosure blk(st); |
3766 | 3020 heap_region_iterate(&blk); |
342 | 3021 } |
3022 | |
3023 void G1CollectedHeap::print_gc_threads_on(outputStream* st) const { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
3024 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1019 | 3025 workers()->print_worker_threads_on(st); |
3026 } | |
3027 _cmThread->print_on(st); | |
342 | 3028 st->cr(); |
1019 | 3029 _cm->print_worker_threads_on(st); |
3030 _cg1r->print_worker_threads_on(st); | |
342 | 3031 st->cr(); |
3032 } | |
3033 | |
3034 void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
3035 if (G1CollectedHeap::use_parallel_gc_threads()) { |
342 | 3036 workers()->threads_do(tc); |
3037 } | |
3038 tc->do_thread(_cmThread); | |
794 | 3039 _cg1r->threads_do(tc); |
342 | 3040 } |
3041 | |
3042 void G1CollectedHeap::print_tracing_info() const { | |
3043 // We'll overload this to mean "trace GC pause statistics." | |
3044 if (TraceGen0Time || TraceGen1Time) { | |
3045 // The "G1CollectorPolicy" is keeping track of these stats, so delegate | |
3046 // to that. | |
3047 g1_policy()->print_tracing_info(); | |
3048 } | |
751 | 3049 if (G1SummarizeRSetStats) { |
342 | 3050 g1_rem_set()->print_summary_info(); |
3051 } | |
1282 | 3052 if (G1SummarizeConcMark) { |
342 | 3053 concurrent_mark()->print_summary_info(); |
3054 } | |
3055 g1_policy()->print_yg_surv_rate_info(); | |
3056 SpecializationStats::print(); | |
3057 } | |
3058 | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3059 #ifndef PRODUCT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3060 // Helpful for debugging RSet issues. |
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 class PrintRSetsClosure : public HeapRegionClosure { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3063 private: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3064 const char* _msg; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3065 size_t _occupied_sum; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3066 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3067 public: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3068 bool doHeapRegion(HeapRegion* r) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3069 HeapRegionRemSet* hrrs = r->rem_set(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3070 size_t occupied = hrrs->occupied(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3071 _occupied_sum += occupied; |
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 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
|
3074 HR_FORMAT_PARAMS(r)); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3075 if (occupied == 0) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3076 gclog_or_tty->print_cr(" RSet is empty"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3077 } else { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3078 hrrs->print(); |
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 gclog_or_tty->print_cr("----------"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3081 return false; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3082 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3083 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3084 PrintRSetsClosure(const char* msg) : _msg(msg), _occupied_sum(0) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3085 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3086 gclog_or_tty->print_cr("========================================"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3087 gclog_or_tty->print_cr(msg); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3088 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3089 } |
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 ~PrintRSetsClosure() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3092 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
|
3093 gclog_or_tty->print_cr("========================================"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3094 gclog_or_tty->cr(); |
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 }; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3097 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3098 void G1CollectedHeap::print_cset_rsets() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3099 PrintRSetsClosure cl("Printing CSet RSets"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3100 collection_set_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3101 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3102 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3103 void G1CollectedHeap::print_all_rsets() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3104 PrintRSetsClosure cl("Printing All RSets");; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3105 heap_region_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3106 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3107 #endif // PRODUCT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3108 |
342 | 3109 G1CollectedHeap* G1CollectedHeap::heap() { |
3110 assert(_sh->kind() == CollectedHeap::G1CollectedHeap, | |
3111 "not a garbage-first heap"); | |
3112 return _g1h; | |
3113 } | |
3114 | |
3115 void G1CollectedHeap::gc_prologue(bool full /* Ignored */) { | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1166
diff
changeset
|
3116 // always_do_update_barrier = false; |
342 | 3117 assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); |
3118 // Call allocation profiler | |
3119 AllocationProfiler::iterate_since_last_gc(); | |
3120 // Fill TLAB's and such | |
3121 ensure_parsability(true); | |
3122 } | |
3123 | |
3124 void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { | |
3125 // FIXME: what is this about? | |
3126 // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled" | |
3127 // is set. | |
3128 COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), | |
3129 "derived pointer present")); | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1166
diff
changeset
|
3130 // always_do_update_barrier = true; |
342 | 3131 } |
3132 | |
1973 | 3133 HeapWord* G1CollectedHeap::do_collection_pause(size_t word_size, |
3134 unsigned int gc_count_before, | |
3135 bool* succeeded) { | |
3136 assert_heap_not_locked_and_not_at_safepoint(); | |
342 | 3137 g1_policy()->record_stop_world_start(); |
1973 | 3138 VM_G1IncCollectionPause op(gc_count_before, |
3139 word_size, | |
3140 false, /* should_initiate_conc_mark */ | |
3141 g1_policy()->max_pause_time_ms(), | |
3142 GCCause::_g1_inc_collection_pause); | |
3143 VMThread::execute(&op); | |
3144 | |
3145 HeapWord* result = op.result(); | |
3146 bool ret_succeeded = op.prologue_succeeded() && op.pause_succeeded(); | |
3147 assert(result == NULL || ret_succeeded, | |
3148 "the result should be NULL if the VM did not succeed"); | |
3149 *succeeded = ret_succeeded; | |
3150 | |
3151 assert_heap_not_locked(); | |
3152 return result; | |
342 | 3153 } |
3154 | |
3155 void | |
3156 G1CollectedHeap::doConcurrentMark() { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3157 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
|
3158 if (!_cmThread->in_progress()) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3159 _cmThread->set_started(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3160 CGC_lock->notify(); |
342 | 3161 } |
3162 } | |
3163 | |
3164 void G1CollectedHeap::do_sync_mark() { | |
3165 _cm->checkpointRootsInitial(); | |
3166 _cm->markFromRoots(); | |
3167 _cm->checkpointRootsFinal(false); | |
3168 } | |
3169 | |
3170 // <NEW PREDICTION> | |
3171 | |
3172 double G1CollectedHeap::predict_region_elapsed_time_ms(HeapRegion *hr, | |
3173 bool young) { | |
3174 return _g1_policy->predict_region_elapsed_time_ms(hr, young); | |
3175 } | |
3176 | |
3177 void G1CollectedHeap::check_if_region_is_too_expensive(double | |
3178 predicted_time_ms) { | |
3179 _g1_policy->check_if_region_is_too_expensive(predicted_time_ms); | |
3180 } | |
3181 | |
3182 size_t G1CollectedHeap::pending_card_num() { | |
3183 size_t extra_cards = 0; | |
3184 JavaThread *curr = Threads::first(); | |
3185 while (curr != NULL) { | |
3186 DirtyCardQueue& dcq = curr->dirty_card_queue(); | |
3187 extra_cards += dcq.size(); | |
3188 curr = curr->next(); | |
3189 } | |
3190 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
3191 size_t buffer_size = dcqs.buffer_size(); | |
3192 size_t buffer_num = dcqs.completed_buffers_num(); | |
3193 return buffer_size * buffer_num + extra_cards; | |
3194 } | |
3195 | |
3196 size_t G1CollectedHeap::max_pending_card_num() { | |
3197 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
3198 size_t buffer_size = dcqs.buffer_size(); | |
3199 size_t buffer_num = dcqs.completed_buffers_num(); | |
3200 int thread_num = Threads::number_of_threads(); | |
3201 return (buffer_num + thread_num) * buffer_size; | |
3202 } | |
3203 | |
3204 size_t G1CollectedHeap::cards_scanned() { | |
1861 | 3205 return g1_rem_set()->cardsScanned(); |
342 | 3206 } |
3207 | |
3208 void | |
3209 G1CollectedHeap::setup_surviving_young_words() { | |
3210 guarantee( _surviving_young_words == NULL, "pre-condition" ); | |
3211 size_t array_length = g1_policy()->young_cset_length(); | |
3212 _surviving_young_words = NEW_C_HEAP_ARRAY(size_t, array_length); | |
3213 if (_surviving_young_words == NULL) { | |
3214 vm_exit_out_of_memory(sizeof(size_t) * array_length, | |
3215 "Not enough space for young surv words summary."); | |
3216 } | |
3217 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
|
3218 #ifdef ASSERT |
342 | 3219 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
|
3220 assert( _surviving_young_words[i] == 0, "memset above" ); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3221 } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3222 #endif // !ASSERT |
342 | 3223 } |
3224 | |
3225 void | |
3226 G1CollectedHeap::update_surviving_young_words(size_t* surv_young_words) { | |
3227 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); | |
3228 size_t array_length = g1_policy()->young_cset_length(); | |
3229 for (size_t i = 0; i < array_length; ++i) | |
3230 _surviving_young_words[i] += surv_young_words[i]; | |
3231 } | |
3232 | |
3233 void | |
3234 G1CollectedHeap::cleanup_surviving_young_words() { | |
3235 guarantee( _surviving_young_words != NULL, "pre-condition" ); | |
3236 FREE_C_HEAP_ARRAY(size_t, _surviving_young_words); | |
3237 _surviving_young_words = NULL; | |
3238 } | |
3239 | |
3240 // </NEW PREDICTION> | |
3241 | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3242 #ifdef ASSERT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3243 class VerifyCSetClosure: public HeapRegionClosure { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3244 public: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3245 bool doHeapRegion(HeapRegion* hr) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3246 // 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
|
3247 // 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
|
3248 // 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
|
3249 // 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
|
3250 // 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
|
3251 // 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
|
3252 // 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
|
3253 // 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
|
3254 // evacuation failure handling. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3255 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
|
3256 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3257 // 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
|
3258 // perform on CSet regions. |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3259 return false; |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3260 } |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3261 }; |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3262 #endif // ASSERT |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3263 |
1709 | 3264 #if TASKQUEUE_STATS |
3265 void G1CollectedHeap::print_taskqueue_stats_hdr(outputStream* const st) { | |
3266 st->print_raw_cr("GC Task Stats"); | |
3267 st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr(); | |
3268 st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr(); | |
3269 } | |
3270 | |
3271 void G1CollectedHeap::print_taskqueue_stats(outputStream* const st) const { | |
3272 print_taskqueue_stats_hdr(st); | |
3273 | |
3274 TaskQueueStats totals; | |
1755
8e5955ddf8e4
6978300: G1: debug builds crash if ParallelGCThreads==0
jcoomes
parents:
1719
diff
changeset
|
3275 const int n = workers() != NULL ? workers()->total_workers() : 1; |
1709 | 3276 for (int i = 0; i < n; ++i) { |
3277 st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr(); | |
3278 totals += task_queue(i)->stats; | |
3279 } | |
3280 st->print_raw("tot "); totals.print(st); st->cr(); | |
3281 | |
3282 DEBUG_ONLY(totals.verify()); | |
3283 } | |
3284 | |
3285 void G1CollectedHeap::reset_taskqueue_stats() { | |
1755
8e5955ddf8e4
6978300: G1: debug builds crash if ParallelGCThreads==0
jcoomes
parents:
1719
diff
changeset
|
3286 const int n = workers() != NULL ? workers()->total_workers() : 1; |
1709 | 3287 for (int i = 0; i < n; ++i) { |
3288 task_queue(i)->stats.reset(); | |
3289 } | |
3290 } | |
3291 #endif // TASKQUEUE_STATS | |
3292 | |
1973 | 3293 bool |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3294 G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { |
2152 | 3295 assert_at_safepoint(true /* should_be_vm_thread */); |
3296 guarantee(!is_gc_active(), "collection is not reentrant"); | |
3297 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3298 if (GC_locker::check_active_before_gc()) { |
1973 | 3299 return false; |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3300 } |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3301 |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
2039
diff
changeset
|
3302 SvcGCMarker sgcm(SvcGCMarker::MINOR); |
2039
7c5250dbd584
6896624: G1: hotspot:::gc and hotspot:::mem-pool-gc probes are not fired
tonyp
parents:
2038
diff
changeset
|
3303 ResourceMark rm; |
7c5250dbd584
6896624: G1: hotspot:::gc and hotspot:::mem-pool-gc probes are not fired
tonyp
parents:
2038
diff
changeset
|
3304 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3305 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3306 Universe::print_heap_before_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3307 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3308 |
2152 | 3309 verify_region_sets_optional(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3310 verify_dirty_young_regions(); |
2152 | 3311 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3312 { |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3313 // 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
|
3314 // 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
|
3315 // for the duration of this pause. |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3316 g1_policy()->decide_on_conc_mark_initiation(); |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3317 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3318 char verbose_str[128]; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3319 sprintf(verbose_str, "GC pause "); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3320 if (g1_policy()->in_young_gc_mode()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3321 if (g1_policy()->full_young_gcs()) |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3322 strcat(verbose_str, "(young)"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3323 else |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3324 strcat(verbose_str, "(partial)"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3325 } |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3326 if (g1_policy()->during_initial_mark_pause()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3327 strcat(verbose_str, " (initial-mark)"); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3328 // 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
|
3329 // full collection counter. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3330 increment_total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3331 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3332 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3333 // 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
|
3334 // 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
|
3335 // is messy if we do. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3336 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3337 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3338 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
|
3339 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3340 TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
3323
diff
changeset
|
3341 TraceMemoryManagerStats tms(false /* fullGC */, gc_cause()); |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
3342 |
2361 | 3343 // If the secondary_free_list is not empty, append it to the |
3344 // free_list. No need to wait for the cleanup operation to finish; | |
3345 // the region allocation code will check the secondary_free_list | |
3346 // and wait if necessary. If the G1StressConcRegionFreeing flag is | |
3347 // set, skip this step so that the region allocation code has to | |
3348 // get entries from the secondary_free_list. | |
2152 | 3349 if (!G1StressConcRegionFreeing) { |
2361 | 3350 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 3351 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3352 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3353 if (g1_policy()->in_young_gc_mode()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3354 assert(check_young_list_well_formed(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3355 "young list should be well formed"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3356 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3357 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3358 { // 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
|
3359 IsGCActiveMark x; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3360 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3361 gc_prologue(false); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3362 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
|
3363 increment_gc_time_stamp(); |
342 | 3364 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3365 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3366 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
|
3367 gclog_or_tty->print(" VerifyBeforeGC:"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3368 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3369 Universe::verify(/* allow dirty */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3370 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3371 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3372 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3373 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3374 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3375 COMPILER2_PRESENT(DerivedPointerTable::clear()); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3376 |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
3377 // Please see comment in G1CollectedHeap::ref_processing_init() |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
3378 // 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
|
3379 // |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3380 // 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
|
3381 // 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
|
3382 bool was_enabled = ref_processor()->discovery_enabled(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3383 if (was_enabled) ref_processor()->disable_discovery(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3384 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3385 // 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
|
3386 // of the collection set!). |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3387 release_mutator_alloc_region(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3388 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3389 // 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
|
3390 // 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
|
3391 // before the start GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3392 _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
|
3393 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3394 // 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
|
3395 // the possible verification above. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3396 double start_time_sec = os::elapsedTime(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3397 size_t start_used_bytes = used(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3398 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3399 #if YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3400 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
|
3401 _young_list->print(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3402 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
|
3403 #endif // YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3404 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3405 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
|
3406 start_used_bytes); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3407 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3408 #if YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3409 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
|
3410 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3411 #endif // YOUNG_LIST_VERBOSE |
342 | 3412 |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3413 if (g1_policy()->during_initial_mark_pause()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3414 concurrent_mark()->checkpointRootsInitialPre(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3415 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3416 perm_gen()->save_marks(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3417 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3418 // 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
|
3419 // marks. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3420 if (mark_in_progress()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3421 double start_time_sec = os::elapsedTime(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3422 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3423 _cm->drainAllSATBBuffers(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3424 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
|
3425 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
|
3426 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3427 // 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
|
3428 // 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
|
3429 // 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
|
3430 // progress, this will be zero. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3431 _cm->set_oops_do_bound(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3432 |
3378
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3433 if (mark_in_progress()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3434 concurrent_mark()->newCSet(); |
3378
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3435 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3436 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3437 #if YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3438 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
|
3439 _young_list->print(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3440 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
|
3441 #endif // YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3442 |
1707 | 3443 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
|
3444 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3445 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3446 HeapRegion* hr = g1_policy()->collection_set(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3447 while (hr != NULL) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3448 G1HRPrinter::RegionType type; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3449 if (!hr->is_young()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3450 type = G1HRPrinter::Old; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3451 } else if (hr->is_survivor()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3452 type = G1HRPrinter::Survivor; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3453 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3454 type = G1HRPrinter::Eden; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3455 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3456 _hr_printer.cset(hr); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3457 hr = hr->next_in_collection_set(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3458 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3459 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3460 |
3378
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3461 // 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
|
3462 // 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
|
3463 // 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
|
3464 // 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
|
3465 // 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
|
3466 // when marking restarts. |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3467 if (mark_in_progress()) { |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3468 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
|
3469 } |
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3470 |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3471 #ifdef ASSERT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3472 VerifyCSetClosure cl; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3473 collection_set_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3474 #endif // ASSERT |
1707 | 3475 |
3476 setup_surviving_young_words(); | |
3477 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3478 // Initialize the GC alloc regions. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3479 init_gc_alloc_regions(); |
1707 | 3480 |
3481 // Actually do the work... | |
3482 evacuate_collection_set(); | |
3483 | |
3484 free_collection_set(g1_policy()->collection_set()); | |
3485 g1_policy()->clear_collection_set(); | |
3486 | |
3487 cleanup_surviving_young_words(); | |
3488 | |
3489 // Start a new incremental collection set for the next pause. | |
3490 g1_policy()->start_incremental_cset_building(); | |
3491 | |
3492 // Clear the _cset_fast_test bitmap in anticipation of adding | |
3493 // regions to the incremental collection set for the next | |
3494 // evacuation pause. | |
3495 clear_cset_fast_test(); | |
3496 | |
3497 if (g1_policy()->in_young_gc_mode()) { | |
3498 _young_list->reset_sampled_info(); | |
3499 | |
3500 // Don't check the whole heap at this point as the | |
3501 // GC alloc regions from this pause have been tagged | |
3502 // as survivors and moved on to the survivor list. | |
3503 // Survivor regions will fail the !is_young() check. | |
3504 assert(check_young_list_empty(false /* check_heap */), | |
3505 "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
|
3506 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3507 #if YOUNG_LIST_VERBOSE |
1707 | 3508 gclog_or_tty->print_cr("Before recording survivors.\nYoung List:"); |
3509 _young_list->print(); | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3510 #endif // YOUNG_LIST_VERBOSE |
342 | 3511 |
1707 | 3512 g1_policy()->record_survivor_regions(_young_list->survivor_length(), |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3513 _young_list->first_survivor_region(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3514 _young_list->last_survivor_region()); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3515 |
1707 | 3516 _young_list->reset_auxilary_lists(); |
342 | 3517 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3518 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3519 if (evacuation_failed()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3520 _summary_bytes_used = recalculate_used(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3521 } else { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3522 // 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
|
3523 // 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
|
3524 _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
|
3525 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3526 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3527 if (g1_policy()->in_young_gc_mode() && |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3528 g1_policy()->during_initial_mark_pause()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3529 concurrent_mark()->checkpointRootsInitialPost(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3530 set_marking_started(); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3531 // CAUTION: after the doConcurrentMark() call below, |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3532 // the concurrent marking thread(s) could be running |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3533 // concurrently with us. Make sure that anything after |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3534 // 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
|
3535 // 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
|
3536 // 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
|
3537 // ConcurrentGCThread::safepoint_desynchronize(). |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3538 doConcurrentMark(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3539 } |
342 | 3540 |
3285
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
3541 allocate_dummy_regions(); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
3542 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3543 #if YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3544 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
|
3545 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3546 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
|
3547 #endif // YOUNG_LIST_VERBOSE |
342 | 3548 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3549 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3550 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3551 double end_time_sec = os::elapsedTime(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3552 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
|
3553 g1_policy()->record_pause_time_ms(pause_time_ms); |
1707 | 3554 g1_policy()->record_collection_pause_end(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3555 |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
3556 MemoryService::track_memory_usage(); |
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
3557 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3558 // 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
|
3559 // 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
|
3560 // 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
|
3561 // 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
|
3562 // 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
|
3563 // 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
|
3564 // 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
|
3565 // 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
|
3566 // 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
|
3567 // 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
|
3568 // 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
|
3569 // 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
|
3570 // 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
|
3571 // 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
|
3572 // 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
|
3573 // 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
|
3574 // 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
|
3575 // 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
|
3576 // 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
|
3577 // 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
|
3578 // scanning cards (see CR 7039627). |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3579 increment_gc_time_stamp(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3580 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3581 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3582 HandleMark hm; // Discard invalid handles created during verification |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3583 gclog_or_tty->print(" VerifyAfterGC:"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3584 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3585 Universe::verify(/* allow dirty */ true, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3586 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3587 /* option */ VerifyOption_G1UsePrevMarking); |
342 | 3588 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3589 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3590 if (was_enabled) ref_processor()->enable_discovery(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3591 |
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 size_t expand_bytes = g1_policy()->expansion_amount(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3594 if (expand_bytes > 0) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3595 size_t bytes_before = capacity(); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3596 if (!expand(expand_bytes)) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3597 // 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
|
3598 // committed/uncommitted amount match the backing store |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3599 assert(capacity() == _g1_storage.committed_size(), "committed size mismatch"); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3600 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
|
3601 } |
838
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 } |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3604 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3605 // 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
|
3606 // 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
|
3607 // 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
|
3608 // RETIRE events are generated before the end GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3609 _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
|
3610 |
3764
053d84a76d3d
7032531: G1: enhance GC logging to include more accurate eden / survivor size transitions
tonyp
parents:
3378
diff
changeset
|
3611 // 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
|
3612 g1_policy()->print_heap_transition(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3613 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3614 if (mark_in_progress()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3615 concurrent_mark()->update_g1_committed(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3616 } |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3617 |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3618 #ifdef TRACESPINNING |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3619 ParallelTaskTerminator::print_termination_counts(); |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3620 #endif |
342 | 3621 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3622 gc_epilogue(false); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3623 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3624 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3625 if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3626 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
|
3627 print_tracing_info(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3628 vm_exit(-1); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3629 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3630 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3631 |
3766 | 3632 _hrs.verify_optional(); |
2152 | 3633 verify_region_sets_optional(); |
3634 | |
1709 | 3635 TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats()); |
3636 TASKQUEUE_STATS_ONLY(reset_taskqueue_stats()); | |
3637 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3638 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3639 Universe::print_heap_after_gc(); |
342 | 3640 } |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3641 g1mm()->update_counters(); |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3642 |
884
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3643 if (G1SummarizeRSetStats && |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3644 (G1SummarizeRSetStatsPeriod > 0) && |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3645 (total_collections() % G1SummarizeRSetStatsPeriod == 0)) { |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3646 g1_rem_set()->print_summary_info(); |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3647 } |
1973 | 3648 |
3649 return true; | |
342 | 3650 } |
3651 | |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3652 size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose) |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3653 { |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3654 size_t gclab_word_size; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3655 switch (purpose) { |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3656 case GCAllocForSurvived: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3657 gclab_word_size = YoungPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3658 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3659 case GCAllocForTenured: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3660 gclab_word_size = OldPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3661 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3662 default: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3663 assert(false, "unknown GCAllocPurpose"); |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3664 gclab_word_size = OldPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3665 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3666 } |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3667 return gclab_word_size; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3668 } |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3669 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3670 void G1CollectedHeap::init_mutator_alloc_region() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3671 assert(_mutator_alloc_region.get() == NULL, "pre-condition"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3672 _mutator_alloc_region.init(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3673 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3674 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3675 void G1CollectedHeap::release_mutator_alloc_region() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3676 _mutator_alloc_region.release(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3677 assert(_mutator_alloc_region.get() == NULL, "post-condition"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3678 } |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3679 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3680 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
|
3681 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
|
3682 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3683 _survivor_gc_alloc_region.init(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3684 _old_gc_alloc_region.init(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3685 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
|
3686 _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
|
3687 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3688 // 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
|
3689 // 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
|
3690 // 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
|
3691 // 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
|
3692 // 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
|
3693 // 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
|
3694 // 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
|
3695 // 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
|
3696 // 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
|
3697 if (retained_region != NULL && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3698 !retained_region->in_collection_set() && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3699 !(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
|
3700 !retained_region->is_empty() && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3701 !retained_region->isHumongous()) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3702 retained_region->set_saved_mark(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3703 _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
|
3704 _hr_printer.reuse(retained_region); |
342 | 3705 } |
3706 } | |
3707 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3708 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
|
3709 _survivor_gc_alloc_region.release(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3710 // 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
|
3711 // _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
|
3712 // _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
|
3713 // 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
|
3714 // condition. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3715 _retained_old_gc_alloc_region = _old_gc_alloc_region.release(); |
342 | 3716 } |
3717 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3718 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
|
3719 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
|
3720 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
|
3721 _retained_old_gc_alloc_region = NULL; |
342 | 3722 } |
3723 | |
3724 void G1CollectedHeap::init_for_evac_failure(OopsInHeapRegionClosure* cl) { | |
3725 _drain_in_progress = false; | |
3726 set_evac_failure_closure(cl); | |
3727 _evac_failure_scan_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true); | |
3728 } | |
3729 | |
3730 void G1CollectedHeap::finalize_for_evac_failure() { | |
3731 assert(_evac_failure_scan_stack != NULL && | |
3732 _evac_failure_scan_stack->length() == 0, | |
3733 "Postcondition"); | |
3734 assert(!_drain_in_progress, "Postcondition"); | |
1045 | 3735 delete _evac_failure_scan_stack; |
342 | 3736 _evac_failure_scan_stack = NULL; |
3737 } | |
3738 | |
3739 // *** Sequential G1 Evacuation | |
3740 | |
3741 class G1IsAliveClosure: public BoolObjectClosure { | |
3742 G1CollectedHeap* _g1; | |
3743 public: | |
3744 G1IsAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} | |
3745 void do_object(oop p) { assert(false, "Do not call."); } | |
3746 bool do_object_b(oop p) { | |
3747 // It is reachable if it is outside the collection set, or is inside | |
3748 // and forwarded. | |
3749 | |
3750 #ifdef G1_DEBUG | |
3751 gclog_or_tty->print_cr("is alive "PTR_FORMAT" in CS %d forwarded %d overall %d", | |
3752 (void*) p, _g1->obj_in_cs(p), p->is_forwarded(), | |
3753 !_g1->obj_in_cs(p) || p->is_forwarded()); | |
3754 #endif // G1_DEBUG | |
3755 | |
3756 return !_g1->obj_in_cs(p) || p->is_forwarded(); | |
3757 } | |
3758 }; | |
3759 | |
3760 class G1KeepAliveClosure: public OopClosure { | |
3761 G1CollectedHeap* _g1; | |
3762 public: | |
3763 G1KeepAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3764 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
|
3765 void do_oop( oop* p) { |
342 | 3766 oop obj = *p; |
3767 #ifdef G1_DEBUG | |
3768 if (PrintGC && Verbose) { | |
3769 gclog_or_tty->print_cr("keep alive *"PTR_FORMAT" = "PTR_FORMAT" "PTR_FORMAT, | |
3770 p, (void*) obj, (void*) *p); | |
3771 } | |
3772 #endif // G1_DEBUG | |
3773 | |
3774 if (_g1->obj_in_cs(obj)) { | |
3775 assert( obj->is_forwarded(), "invariant" ); | |
3776 *p = obj->forwardee(); | |
3777 #ifdef G1_DEBUG | |
3778 gclog_or_tty->print_cr(" in CSet: moved "PTR_FORMAT" -> "PTR_FORMAT, | |
3779 (void*) obj, (void*) *p); | |
3780 #endif // G1_DEBUG | |
3781 } | |
3782 } | |
3783 }; | |
3784 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3785 class UpdateRSetDeferred : public OopsInHeapRegionClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3786 private: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3787 G1CollectedHeap* _g1; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3788 DirtyCardQueue *_dcq; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3789 CardTableModRefBS* _ct_bs; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3790 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3791 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3792 UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) : |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3793 _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
|
3794 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3795 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
|
3796 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
|
3797 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
|
3798 assert(_from->is_in_reserved(p), "paranoia"); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3799 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
|
3800 !_from->is_survivor()) { |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3801 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
|
3802 if (_ct_bs->mark_card_deferred(card_index)) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3803 _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
|
3804 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3805 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3806 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3807 }; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3808 |
342 | 3809 class RemoveSelfPointerClosure: public ObjectClosure { |
3810 private: | |
3811 G1CollectedHeap* _g1; | |
3812 ConcurrentMark* _cm; | |
3813 HeapRegion* _hr; | |
3814 size_t _prev_marked_bytes; | |
3815 size_t _next_marked_bytes; | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3816 OopsInHeapRegionClosure *_cl; |
342 | 3817 public: |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3818 RemoveSelfPointerClosure(G1CollectedHeap* g1, HeapRegion* hr, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3819 OopsInHeapRegionClosure* cl) : |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3820 _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
|
3821 _next_marked_bytes(0), _cl(cl) {} |
342 | 3822 |
3823 size_t prev_marked_bytes() { return _prev_marked_bytes; } | |
3824 size_t next_marked_bytes() { return _next_marked_bytes; } | |
3825 | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3826 // <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
|
3827 // 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
|
3828 // 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
|
3829 // 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
|
3830 // |----- 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
|
3831 // 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
|
3832 // 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
|
3833 // 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
|
3834 // would point into middle of the filler object. |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3835 // 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
|
3836 // </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
|
3837 // |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3838 // 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
|
3839 // 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
|
3840 // 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
|
3841 // 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
|
3842 void do_object(oop obj) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3843 HeapWord* obj_addr = (HeapWord*) obj; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3844 assert(_hr->is_in(obj_addr), "sanity"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3845 size_t obj_size = obj->size(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3846 _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
|
3847 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
|
3848 // 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
|
3849 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
|
3850 _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
|
3851 assert(_cm->isPrevMarked(obj), "Should be marked!"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3852 _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
|
3853 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
|
3854 _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
|
3855 } |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3856 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
|
3857 // 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
|
3858 // 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
|
3859 // 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
|
3860 // 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
|
3861 // 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
|
3862 // 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
|
3863 // 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
|
3864 // 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
|
3865 // 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
|
3866 // 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
|
3867 // 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
|
3868 // 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
|
3869 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
|
3870 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
|
3871 } 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
|
3872 // 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
|
3873 // dummy object. |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3874 MemRegion mr((HeapWord*)obj, obj_size); |
481
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
3875 CollectedHeap::fill_with_object(mr); |
342 | 3876 _cm->clearRangeBothMaps(mr); |
3877 } | |
3878 } | |
3879 }; | |
3880 | |
3881 void G1CollectedHeap::remove_self_forwarding_pointers() { | |
1705 | 3882 UpdateRSetImmediate immediate_update(_g1h->g1_rem_set()); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3883 DirtyCardQueue dcq(&_g1h->dirty_card_queue_set()); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3884 UpdateRSetDeferred deferred_update(_g1h, &dcq); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3885 OopsInHeapRegionClosure *cl; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3886 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3887 cl = &deferred_update; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3888 } else { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3889 cl = &immediate_update; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3890 } |
342 | 3891 HeapRegion* cur = g1_policy()->collection_set(); |
3892 while (cur != NULL) { | |
3893 assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!"); | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3894 assert(!cur->isHumongous(), "sanity"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3895 |
342 | 3896 if (cur->evacuation_failed()) { |
3897 assert(cur->in_collection_set(), "bad CS"); | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3898 RemoveSelfPointerClosure rspc(_g1h, cur, cl); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3899 |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3900 // 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
|
3901 // 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
|
3902 // re-allocated. However, when evacuation failure happens, a |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3903 // 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
|
3904 // 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
|
3905 // 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
|
3906 // whenever this might be required in the future. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3907 cur->rem_set()->reset_for_par_iteration(); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3908 cur->reset_bot(); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3909 cl->set_region(cur); |
342 | 3910 cur->object_iterate(&rspc); |
3911 | |
3912 // A number of manipulations to make the TAMS be the current top, | |
3913 // and the marked bytes be the ones observed in the iteration. | |
3914 if (_g1h->concurrent_mark()->at_least_one_mark_complete()) { | |
3915 // The comments below are the postconditions achieved by the | |
3916 // calls. Note especially the last such condition, which says that | |
3917 // the count of marked bytes has been properly restored. | |
3918 cur->note_start_of_marking(false); | |
3919 // _next_top_at_mark_start == top, _next_marked_bytes == 0 | |
3920 cur->add_to_marked_bytes(rspc.prev_marked_bytes()); | |
3921 // _next_marked_bytes == prev_marked_bytes. | |
3922 cur->note_end_of_marking(); | |
3923 // _prev_top_at_mark_start == top(), | |
3924 // _prev_marked_bytes == prev_marked_bytes | |
3925 } | |
3926 // If there is no mark in progress, we modified the _next variables | |
3927 // above needlessly, but harmlessly. | |
3928 if (_g1h->mark_in_progress()) { | |
3929 cur->note_start_of_marking(false); | |
3930 // _next_top_at_mark_start == top, _next_marked_bytes == 0 | |
3931 // _next_marked_bytes == next_marked_bytes. | |
3932 } | |
3933 | |
3934 // Now make sure the region has the right index in the sorted array. | |
3935 g1_policy()->note_change_in_marked_bytes(cur); | |
3936 } | |
3937 cur = cur->next_in_collection_set(); | |
3938 } | |
3939 assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!"); | |
3940 | |
3941 // Now restore saved marks, if any. | |
3942 if (_objs_with_preserved_marks != NULL) { | |
3943 assert(_preserved_marks_of_objs != NULL, "Both or none."); | |
3944 guarantee(_objs_with_preserved_marks->length() == | |
3945 _preserved_marks_of_objs->length(), "Both or none."); | |
3946 for (int i = 0; i < _objs_with_preserved_marks->length(); i++) { | |
3947 oop obj = _objs_with_preserved_marks->at(i); | |
3948 markOop m = _preserved_marks_of_objs->at(i); | |
3949 obj->set_mark(m); | |
3950 } | |
3951 // Delete the preserved marks growable arrays (allocated on the C heap). | |
3952 delete _objs_with_preserved_marks; | |
3953 delete _preserved_marks_of_objs; | |
3954 _objs_with_preserved_marks = NULL; | |
3955 _preserved_marks_of_objs = NULL; | |
3956 } | |
3957 } | |
3958 | |
3959 void G1CollectedHeap::push_on_evac_failure_scan_stack(oop obj) { | |
3960 _evac_failure_scan_stack->push(obj); | |
3961 } | |
3962 | |
3963 void G1CollectedHeap::drain_evac_failure_scan_stack() { | |
3964 assert(_evac_failure_scan_stack != NULL, "precondition"); | |
3965 | |
3966 while (_evac_failure_scan_stack->length() > 0) { | |
3967 oop obj = _evac_failure_scan_stack->pop(); | |
3968 _evac_failure_closure->set_region(heap_region_containing(obj)); | |
3969 obj->oop_iterate_backwards(_evac_failure_closure); | |
3970 } | |
3971 } | |
3972 | |
3973 oop | |
3974 G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, | |
3975 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
|
3976 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
|
3977 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
|
3978 (HeapWord*) old)); |
342 | 3979 markOop m = old->mark(); |
3980 oop forward_ptr = old->forward_to_atomic(old); | |
3981 if (forward_ptr == NULL) { | |
3982 // Forward-to-self succeeded. | |
3983 if (_evac_failure_closure != cl) { | |
3984 MutexLockerEx x(EvacFailureStack_lock, Mutex::_no_safepoint_check_flag); | |
3985 assert(!_drain_in_progress, | |
3986 "Should only be true while someone holds the lock."); | |
3987 // Set the global evac-failure closure to the current thread's. | |
3988 assert(_evac_failure_closure == NULL, "Or locking has failed."); | |
3989 set_evac_failure_closure(cl); | |
3990 // Now do the common part. | |
3991 handle_evacuation_failure_common(old, m); | |
3992 // Reset to NULL. | |
3993 set_evac_failure_closure(NULL); | |
3994 } else { | |
3995 // The lock is already held, and this is recursive. | |
3996 assert(_drain_in_progress, "This should only be the recursive case."); | |
3997 handle_evacuation_failure_common(old, m); | |
3998 } | |
3999 return old; | |
4000 } 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
|
4001 // 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
|
4002 // 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
|
4003 // 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
|
4004 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
|
4005 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
|
4006 "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
|
4007 (HeapWord*) old, (HeapWord*) forward_ptr)); |
342 | 4008 return forward_ptr; |
4009 } | |
4010 } | |
4011 | |
4012 void G1CollectedHeap::handle_evacuation_failure_common(oop old, markOop m) { | |
4013 set_evacuation_failed(true); | |
4014 | |
4015 preserve_mark_if_necessary(old, m); | |
4016 | |
4017 HeapRegion* r = heap_region_containing(old); | |
4018 if (!r->evacuation_failed()) { | |
4019 r->set_evacuation_failed(true); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
4020 _hr_printer.evac_failure(r); |
342 | 4021 } |
4022 | |
4023 push_on_evac_failure_scan_stack(old); | |
4024 | |
4025 if (!_drain_in_progress) { | |
4026 // prevent recursion in copy_to_survivor_space() | |
4027 _drain_in_progress = true; | |
4028 drain_evac_failure_scan_stack(); | |
4029 _drain_in_progress = false; | |
4030 } | |
4031 } | |
4032 | |
4033 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
|
4034 assert(evacuation_failed(), "Oversaving!"); |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
4035 // 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
|
4036 // case of a promotion failure. |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
4037 if (m->must_be_preserved_for_promotion_failure(obj)) { |
342 | 4038 if (_objs_with_preserved_marks == NULL) { |
4039 assert(_preserved_marks_of_objs == NULL, "Both or none."); | |
4040 _objs_with_preserved_marks = | |
4041 new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true); | |
4042 _preserved_marks_of_objs = | |
4043 new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true); | |
4044 } | |
4045 _objs_with_preserved_marks->push(obj); | |
4046 _preserved_marks_of_objs->push(m); | |
4047 } | |
4048 } | |
4049 | |
4050 HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose, | |
4051 size_t word_size) { | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4052 if (purpose == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4053 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
|
4054 if (result != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4055 return result; |
342 | 4056 } else { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4057 // 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
|
4058 // object there. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4059 return old_attempt_allocation(word_size); |
342 | 4060 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4061 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4062 assert(purpose == GCAllocForTenured, "sanity"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4063 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
|
4064 if (result != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4065 return result; |
342 | 4066 } else { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4067 // 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
|
4068 // object there. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4069 return survivor_attempt_allocation(word_size); |
342 | 4070 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4071 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4072 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4073 ShouldNotReachHere(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4074 // 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
|
4075 return NULL; |
342 | 4076 } |
4077 | |
4078 #ifndef PRODUCT | |
4079 bool GCLabBitMapClosure::do_bit(size_t offset) { | |
4080 HeapWord* addr = _bitmap->offsetToHeapWord(offset); | |
4081 guarantee(_cm->isMarked(oop(addr)), "it should be!"); | |
4082 return true; | |
4083 } | |
4084 #endif // PRODUCT | |
4085 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4086 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4087 : _g1h(g1h), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4088 _refs(g1h->task_queue(queue_num)), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4089 _dcq(&g1h->dirty_card_queue_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4090 _ct_bs((CardTableModRefBS*)_g1h->barrier_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4091 _g1_rem(g1h->g1_rem_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4092 _hash_seed(17), _queue_num(queue_num), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4093 _term_attempts(0), |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4094 _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4095 _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
|
4096 _age_table(false), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4097 _strong_roots_time(0), _term_time(0), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4098 _alloc_buffer_waste(0), _undo_waste(0) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4099 { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4100 // we allocate G1YoungSurvRateNumRegions plus one entries, since |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4101 // 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
|
4102 // non-young regions (where the age is -1) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4103 // 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
|
4104 // an attempt to eliminate cache contention |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4105 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
|
4106 size_t array_length = PADDING_ELEM_NUM + |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4107 real_length + |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4108 PADDING_ELEM_NUM; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4109 _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
|
4110 if (_surviving_young_words_base == NULL) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4111 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
|
4112 "Not enough space for young surv histo."); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4113 _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
|
4114 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
|
4115 |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4116 _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4117 _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4118 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4119 _start = os::elapsedTime(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4120 } |
342 | 4121 |
1709 | 4122 void |
4123 G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st) | |
4124 { | |
4125 st->print_raw_cr("GC Termination Stats"); | |
4126 st->print_raw_cr(" elapsed --strong roots-- -------termination-------" | |
4127 " ------waste (KiB)------"); | |
4128 st->print_raw_cr("thr ms ms % ms % attempts" | |
4129 " total alloc undo"); | |
4130 st->print_raw_cr("--- --------- --------- ------ --------- ------ --------" | |
4131 " ------- ------- -------"); | |
4132 } | |
4133 | |
4134 void | |
4135 G1ParScanThreadState::print_termination_stats(int i, | |
4136 outputStream* const st) const | |
4137 { | |
4138 const double elapsed_ms = elapsed_time() * 1000.0; | |
4139 const double s_roots_ms = strong_roots_time() * 1000.0; | |
4140 const double term_ms = term_time() * 1000.0; | |
4141 st->print_cr("%3d %9.2f %9.2f %6.2f " | |
4142 "%9.2f %6.2f " SIZE_FORMAT_W(8) " " | |
4143 SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7), | |
4144 i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms, | |
4145 term_ms, term_ms * 100 / elapsed_ms, term_attempts(), | |
4146 (alloc_buffer_waste() + undo_waste()) * HeapWordSize / K, | |
4147 alloc_buffer_waste() * HeapWordSize / K, | |
4148 undo_waste() * HeapWordSize / K); | |
4149 } | |
4150 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4151 #ifdef ASSERT |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4152 bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4153 assert(ref != NULL, "invariant"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4154 assert(UseCompressedOops, "sanity"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4155 assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref)); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4156 oop p = oopDesc::load_decode_heap_oop(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4157 assert(_g1h->is_in_g1_reserved(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4158 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4159 return true; |
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 bool G1ParScanThreadState::verify_ref(oop* ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4163 assert(ref != NULL, "invariant"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4164 if (has_partial_array_mask(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4165 // Must be in the collection set--it's already been copied. |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4166 oop p = clear_partial_array_mask(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4167 assert(_g1h->obj_in_cs(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4168 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4169 } else { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4170 oop p = oopDesc::load_decode_heap_oop(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4171 assert(_g1h->is_in_g1_reserved(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4172 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
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 return true; |
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 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4177 bool G1ParScanThreadState::verify_task(StarTask ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4178 if (ref.is_narrow()) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4179 return verify_ref((narrowOop*) ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4180 } else { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4181 return verify_ref((oop*) ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4182 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4183 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4184 #endif // ASSERT |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4185 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4186 void G1ParScanThreadState::trim_queue() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4187 StarTask ref; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4188 do { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4189 // Drain the overflow stack first, so other threads can steal. |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4190 while (refs()->pop_overflow(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4191 deal_with_reference(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4192 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4193 while (refs()->pop_local(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4194 deal_with_reference(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4195 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4196 } while (!refs()->is_empty()); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4197 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4198 |
342 | 4199 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) : |
4200 _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()), | |
4201 _par_scan_state(par_scan_state) { } | |
4202 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4203 template <class T> void G1ParCopyHelper::mark_forwardee(T* p) { |
342 | 4204 // This is called _after_ do_oop_work has been called, hence after |
4205 // the object has been relocated to its new location and *p points | |
4206 // to its new location. | |
4207 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4208 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4209 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4210 oop obj = oopDesc::decode_heap_oop(heap_oop); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4211 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
|
4212 if (_g1->is_in_g1_reserved(addr)) { |
342 | 4213 _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
|
4214 } |
342 | 4215 } |
4216 } | |
4217 | |
4218 oop G1ParCopyHelper::copy_to_survivor_space(oop old) { | |
4219 size_t word_sz = old->size(); | |
4220 HeapRegion* from_region = _g1->heap_region_containing_raw(old); | |
4221 // +1 to make the -1 indexes valid... | |
4222 int young_index = from_region->young_index_in_cset()+1; | |
4223 assert( (from_region->is_young() && young_index > 0) || | |
4224 (!from_region->is_young() && young_index == 0), "invariant" ); | |
4225 G1CollectorPolicy* g1p = _g1->g1_policy(); | |
4226 markOop m = old->mark(); | |
545 | 4227 int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() |
4228 : m->age(); | |
4229 GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, | |
342 | 4230 word_sz); |
4231 HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz); | |
4232 oop obj = oop(obj_ptr); | |
4233 | |
4234 if (obj_ptr == NULL) { | |
4235 // This will either forward-to-self, or detect that someone else has | |
4236 // installed a forwarding pointer. | |
4237 OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure(); | |
4238 return _g1->handle_evacuation_failure_par(cl, old); | |
4239 } | |
4240 | |
526 | 4241 // We're going to allocate linearly, so might as well prefetch ahead. |
4242 Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes); | |
4243 | |
342 | 4244 oop forward_ptr = old->forward_to_atomic(obj); |
4245 if (forward_ptr == NULL) { | |
4246 Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); | |
526 | 4247 if (g1p->track_object_age(alloc_purpose)) { |
4248 // We could simply do obj->incr_age(). However, this causes a | |
4249 // performance issue. obj->incr_age() will first check whether | |
4250 // the object has a displaced mark by checking its mark word; | |
4251 // getting the mark word from the new location of the object | |
4252 // stalls. So, given that we already have the mark word and we | |
4253 // are about to install it anyway, it's better to increase the | |
4254 // age on the mark word, when the object does not have a | |
4255 // displaced mark word. We're not expecting many objects to have | |
4256 // a displaced marked word, so that case is not optimized | |
4257 // further (it could be...) and we simply call obj->incr_age(). | |
4258 | |
4259 if (m->has_displaced_mark_helper()) { | |
4260 // in this case, we have to install the mark word first, | |
4261 // otherwise obj looks to be forwarded (the old mark word, | |
4262 // which contains the forward pointer, was copied) | |
4263 obj->set_mark(m); | |
4264 obj->incr_age(); | |
4265 } else { | |
4266 m = m->incr_age(); | |
545 | 4267 obj->set_mark(m); |
526 | 4268 } |
545 | 4269 _par_scan_state->age_table()->add(obj, word_sz); |
4270 } else { | |
4271 obj->set_mark(m); | |
526 | 4272 } |
4273 | |
342 | 4274 // preserve "next" mark bit |
4275 if (_g1->mark_in_progress() && !_g1->is_obj_ill(old)) { | |
4276 if (!use_local_bitmaps || | |
4277 !_par_scan_state->alloc_buffer(alloc_purpose)->mark(obj_ptr)) { | |
4278 // if we couldn't mark it on the local bitmap (this happens when | |
4279 // the object was not allocated in the GCLab), we have to bite | |
4280 // the bullet and do the standard parallel mark | |
4281 _cm->markAndGrayObjectIfNecessary(obj); | |
4282 } | |
4283 #if 1 | |
4284 if (_g1->isMarkedNext(old)) { | |
4285 _cm->nextMarkBitMap()->parClear((HeapWord*)old); | |
4286 } | |
4287 #endif | |
4288 } | |
4289 | |
4290 size_t* surv_young_words = _par_scan_state->surviving_young_words(); | |
4291 surv_young_words[young_index] += word_sz; | |
4292 | |
4293 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { | |
4294 arrayOop(old)->set_length(0); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4295 oop* old_p = set_partial_array_mask(old); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4296 _par_scan_state->push_on_queue(old_p); |
342 | 4297 } else { |
526 | 4298 // No point in using the slower heap_region_containing() method, |
4299 // given that we know obj is in the heap. | |
4300 _scanner->set_region(_g1->heap_region_containing_raw(obj)); | |
342 | 4301 obj->oop_iterate_backwards(_scanner); |
4302 } | |
4303 } else { | |
4304 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); | |
4305 obj = forward_ptr; | |
4306 } | |
4307 return obj; | |
4308 } | |
4309 | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4310 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_forwardee> |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4311 template <class T> |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4312 void G1ParCopyClosure <do_gen_barrier, barrier, do_mark_forwardee> |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4313 ::do_oop_work(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4314 oop obj = oopDesc::load_decode_heap_oop(p); |
342 | 4315 assert(barrier != G1BarrierRS || obj != NULL, |
4316 "Precondition: G1BarrierRS implies obj is nonNull"); | |
4317 | |
526 | 4318 // 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
|
4319 if (_g1->in_cset_fast_test(obj)) { |
526 | 4320 if (obj->is_forwarded()) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4321 oopDesc::encode_store_heap_oop(p, obj->forwardee()); |
526 | 4322 } else { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4323 oop copy_oop = copy_to_survivor_space(obj); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4324 oopDesc::encode_store_heap_oop(p, copy_oop); |
342 | 4325 } |
526 | 4326 // When scanning the RS, we only care about objs in CS. |
4327 if (barrier == G1BarrierRS) { | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4328 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); |
342 | 4329 } |
526 | 4330 } |
4331 | |
4332 if (barrier == G1BarrierEvac && obj != NULL) { | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4333 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); |
526 | 4334 } |
4335 | |
4336 if (do_gen_barrier && obj != NULL) { | |
4337 par_do_barrier(p); | |
4338 } | |
4339 } | |
4340 | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4341 template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(oop* p); |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4342 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
|
4343 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4344 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) { |
526 | 4345 assert(has_partial_array_mask(p), "invariant"); |
4346 oop old = clear_partial_array_mask(p); | |
342 | 4347 assert(old->is_objArray(), "must be obj array"); |
4348 assert(old->is_forwarded(), "must be forwarded"); | |
4349 assert(Universe::heap()->is_in_reserved(old), "must be in heap."); | |
4350 | |
4351 objArrayOop obj = objArrayOop(old->forwardee()); | |
4352 assert((void*)old != (void*)old->forwardee(), "self forwarding here?"); | |
4353 // Process ParGCArrayScanChunk elements now | |
4354 // and push the remainder back onto queue | |
4355 int start = arrayOop(old)->length(); | |
4356 int end = obj->length(); | |
4357 int remainder = end - start; | |
4358 assert(start <= end, "just checking"); | |
4359 if (remainder > 2 * ParGCArrayScanChunk) { | |
4360 // Test above combines last partial chunk with a full chunk | |
4361 end = start + ParGCArrayScanChunk; | |
4362 arrayOop(old)->set_length(end); | |
4363 // Push remainder. | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4364 oop* old_p = set_partial_array_mask(old); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4365 assert(arrayOop(old)->length() < obj->length(), "Empty push?"); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4366 _par_scan_state->push_on_queue(old_p); |
342 | 4367 } else { |
4368 // Restore length so that the heap remains parsable in | |
4369 // case of evacuation failure. | |
4370 arrayOop(old)->set_length(end); | |
4371 } | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4372 _scanner.set_region(_g1->heap_region_containing_raw(obj)); |
342 | 4373 // 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
|
4374 obj->oop_iterate_range(&_scanner, start, end); |
342 | 4375 } |
4376 | |
4377 class G1ParEvacuateFollowersClosure : public VoidClosure { | |
4378 protected: | |
4379 G1CollectedHeap* _g1h; | |
4380 G1ParScanThreadState* _par_scan_state; | |
4381 RefToScanQueueSet* _queues; | |
4382 ParallelTaskTerminator* _terminator; | |
4383 | |
4384 G1ParScanThreadState* par_scan_state() { return _par_scan_state; } | |
4385 RefToScanQueueSet* queues() { return _queues; } | |
4386 ParallelTaskTerminator* terminator() { return _terminator; } | |
4387 | |
4388 public: | |
4389 G1ParEvacuateFollowersClosure(G1CollectedHeap* g1h, | |
4390 G1ParScanThreadState* par_scan_state, | |
4391 RefToScanQueueSet* queues, | |
4392 ParallelTaskTerminator* terminator) | |
4393 : _g1h(g1h), _par_scan_state(par_scan_state), | |
4394 _queues(queues), _terminator(terminator) {} | |
4395 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4396 void do_void(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4397 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4398 private: |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4399 inline bool offer_termination(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4400 }; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4401 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4402 bool G1ParEvacuateFollowersClosure::offer_termination() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4403 G1ParScanThreadState* const pss = par_scan_state(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4404 pss->start_term_time(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4405 const bool res = terminator()->offer_termination(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4406 pss->end_term_time(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4407 return res; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4408 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4409 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4410 void G1ParEvacuateFollowersClosure::do_void() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4411 StarTask stolen_task; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4412 G1ParScanThreadState* const pss = par_scan_state(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4413 pss->trim_queue(); |
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 do { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4416 while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4417 assert(pss->verify_task(stolen_task), "sanity"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4418 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
|
4419 pss->deal_with_reference((narrowOop*) stolen_task); |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4420 } else { |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4421 pss->deal_with_reference((oop*) stolen_task); |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4422 } |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4423 |
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4424 // 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
|
4425 // 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
|
4426 // we drain the queues as necessary. |
342 | 4427 pss->trim_queue(); |
4428 } | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4429 } while (!offer_termination()); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4430 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4431 pss->retire_alloc_buffers(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4432 } |
342 | 4433 |
4434 class G1ParTask : public AbstractGangTask { | |
4435 protected: | |
4436 G1CollectedHeap* _g1h; | |
4437 RefToScanQueueSet *_queues; | |
4438 ParallelTaskTerminator _terminator; | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4439 int _n_workers; |
342 | 4440 |
4441 Mutex _stats_lock; | |
4442 Mutex* stats_lock() { return &_stats_lock; } | |
4443 | |
4444 size_t getNCards() { | |
4445 return (_g1h->capacity() + G1BlockOffsetSharedArray::N_bytes - 1) | |
4446 / G1BlockOffsetSharedArray::N_bytes; | |
4447 } | |
4448 | |
4449 public: | |
4450 G1ParTask(G1CollectedHeap* g1h, int workers, RefToScanQueueSet *task_queues) | |
4451 : AbstractGangTask("G1 collection"), | |
4452 _g1h(g1h), | |
4453 _queues(task_queues), | |
4454 _terminator(workers, _queues), | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4455 _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
|
4456 _n_workers(workers) |
342 | 4457 {} |
4458 | |
4459 RefToScanQueueSet* queues() { return _queues; } | |
4460 | |
4461 RefToScanQueue *work_queue(int i) { | |
4462 return queues()->queue(i); | |
4463 } | |
4464 | |
4465 void work(int i) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4466 if (i >= _n_workers) return; // no work needed this round |
1611 | 4467 |
4468 double start_time_ms = os::elapsedTime() * 1000.0; | |
4469 _g1h->g1_policy()->record_gc_worker_start_time(i, start_time_ms); | |
4470 | |
342 | 4471 ResourceMark rm; |
4472 HandleMark hm; | |
4473 | |
526 | 4474 G1ParScanThreadState pss(_g1h, i); |
4475 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss); | |
4476 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss); | |
4477 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss); | |
342 | 4478 |
4479 pss.set_evac_closure(&scan_evac_cl); | |
4480 pss.set_evac_failure_closure(&evac_failure_cl); | |
4481 pss.set_partial_scan_closure(&partial_scan_cl); | |
4482 | |
4483 G1ParScanExtRootClosure only_scan_root_cl(_g1h, &pss); | |
4484 G1ParScanPermClosure only_scan_perm_cl(_g1h, &pss); | |
4485 G1ParScanHeapRSClosure only_scan_heap_rs_cl(_g1h, &pss); | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4486 G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4487 |
342 | 4488 G1ParScanAndMarkExtRootClosure scan_mark_root_cl(_g1h, &pss); |
4489 G1ParScanAndMarkPermClosure scan_mark_perm_cl(_g1h, &pss); | |
4490 G1ParScanAndMarkHeapRSClosure scan_mark_heap_rs_cl(_g1h, &pss); | |
4491 | |
4492 OopsInHeapRegionClosure *scan_root_cl; | |
4493 OopsInHeapRegionClosure *scan_perm_cl; | |
4494 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
4495 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
342 | 4496 scan_root_cl = &scan_mark_root_cl; |
4497 scan_perm_cl = &scan_mark_perm_cl; | |
4498 } else { | |
4499 scan_root_cl = &only_scan_root_cl; | |
4500 scan_perm_cl = &only_scan_perm_cl; | |
4501 } | |
4502 | |
4503 pss.start_strong_roots(); | |
4504 _g1h->g1_process_strong_roots(/* not collecting perm */ false, | |
4505 SharedHeap::SO_AllClasses, | |
4506 scan_root_cl, | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4507 &push_heap_rs_cl, |
342 | 4508 scan_perm_cl, |
4509 i); | |
4510 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
|
4511 |
342 | 4512 { |
4513 double start = os::elapsedTime(); | |
4514 G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator); | |
4515 evac.do_void(); | |
4516 double elapsed_ms = (os::elapsedTime()-start)*1000.0; | |
4517 double term_ms = pss.term_time()*1000.0; | |
4518 _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms); | |
1611 | 4519 _g1h->g1_policy()->record_termination(i, term_ms, pss.term_attempts()); |
342 | 4520 } |
1282 | 4521 _g1h->g1_policy()->record_thread_age_table(pss.age_table()); |
342 | 4522 _g1h->update_surviving_young_words(pss.surviving_young_words()+1); |
4523 | |
4524 // Clean up any par-expanded rem sets. | |
4525 HeapRegionRemSet::par_cleanup(); | |
4526 | |
4527 if (ParallelGCVerbose) { | |
1709 | 4528 MutexLocker x(stats_lock()); |
4529 pss.print_termination_stats(i); | |
342 | 4530 } |
4531 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4532 assert(pss.refs()->is_empty(), "should be empty"); |
1611 | 4533 double end_time_ms = os::elapsedTime() * 1000.0; |
4534 _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms); | |
342 | 4535 } |
4536 }; | |
4537 | |
4538 // *** Common G1 Evacuation Stuff | |
4539 | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
4540 // This method is run in a GC worker. |
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
4541 |
342 | 4542 void |
4543 G1CollectedHeap:: | |
4544 g1_process_strong_roots(bool collecting_perm_gen, | |
4545 SharedHeap::ScanningOption so, | |
4546 OopClosure* scan_non_heap_roots, | |
4547 OopsInHeapRegionClosure* scan_rs, | |
4548 OopsInGenClosure* scan_perm, | |
4549 int worker_i) { | |
4550 // First scan the strong roots, including the perm gen. | |
4551 double ext_roots_start = os::elapsedTime(); | |
4552 double closure_app_time_sec = 0.0; | |
4553 | |
4554 BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); | |
4555 BufferingOopsInGenClosure buf_scan_perm(scan_perm); | |
4556 buf_scan_perm.set_generation(perm_gen()); | |
4557 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4558 // 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
|
4559 // unaligned oop locations. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4560 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
|
4561 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4562 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
|
4563 collecting_perm_gen, so, |
342 | 4564 &buf_scan_non_heap_roots, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4565 &eager_scan_code_roots, |
342 | 4566 &buf_scan_perm); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4567 |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4568 // 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
|
4569 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
|
4570 // 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
|
4571 // 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
|
4572 // 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
|
4573 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
|
4574 ref_processor()->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
|
4575 } |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4576 |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4577 // Finish up any enqueued closure apps (attributed as object copy time). |
342 | 4578 buf_scan_non_heap_roots.done(); |
4579 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
|
4580 |
342 | 4581 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
|
4582 |
342 | 4583 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
|
4584 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
|
4585 buf_scan_non_heap_roots.closure_app_seconds(); |
342 | 4586 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
|
4587 |
342 | 4588 double ext_root_time_ms = |
4589 ((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
|
4590 |
342 | 4591 g1_policy()->record_ext_root_scan_time(worker_i, ext_root_time_ms); |
4592 | |
4593 // Scan strong roots in mark stack. | |
4594 if (!_process_strong_tasks->is_task_claimed(G1H_PS_mark_stack_oops_do)) { | |
4595 concurrent_mark()->oops_do(scan_non_heap_roots); | |
4596 } | |
4597 double mark_stack_scan_ms = (os::elapsedTime() - ext_roots_end) * 1000.0; | |
4598 g1_policy()->record_mark_stack_scan_time(worker_i, mark_stack_scan_ms); | |
4599 | |
4600 // Now scan the complement of the collection set. | |
4601 if (scan_rs != NULL) { | |
4602 g1_rem_set()->oops_into_collection_set_do(scan_rs, worker_i); | |
4603 } | |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4604 |
342 | 4605 _process_strong_tasks->all_tasks_completed(); |
4606 } | |
4607 | |
4608 void | |
4609 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure, | |
4610 OopClosure* non_root_closure) { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4611 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
|
4612 SharedHeap::process_weak_roots(root_closure, &roots_in_blobs, non_root_closure); |
342 | 4613 } |
4614 | |
4615 void G1CollectedHeap::evacuate_collection_set() { | |
4616 set_evacuation_failed(false); | |
4617 | |
4618 g1_rem_set()->prepare_for_oops_into_collection_set_do(); | |
4619 concurrent_g1_refine()->set_use_cache(false); | |
889 | 4620 concurrent_g1_refine()->clear_hot_cache_claimed_index(); |
4621 | |
342 | 4622 int n_workers = (ParallelGCThreads > 0 ? workers()->total_workers() : 1); |
4623 set_par_threads(n_workers); | |
4624 G1ParTask g1_par_task(this, n_workers, _task_queues); | |
4625 | |
4626 init_for_evac_failure(NULL); | |
4627 | |
4628 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
|
4629 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4630 assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty"); |
342 | 4631 double start_par = os::elapsedTime(); |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
4632 if (G1CollectedHeap::use_parallel_gc_threads()) { |
342 | 4633 // 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
|
4634 StrongRootsScope srs(this); |
1709 | 4635 if (ParallelGCVerbose) G1ParScanThreadState::print_termination_stats_hdr(); |
342 | 4636 workers()->run_task(&g1_par_task); |
4637 } else { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4638 StrongRootsScope srs(this); |
342 | 4639 g1_par_task.work(0); |
4640 } | |
4641 | |
4642 double par_time = (os::elapsedTime() - start_par) * 1000.0; | |
4643 g1_policy()->record_par_time(par_time); | |
4644 set_par_threads(0); | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
4645 |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
4646 // Weak root processing. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
4647 // 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
|
4648 // 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
|
4649 // here too. |
342 | 4650 { |
4651 G1IsAliveClosure is_alive(this); | |
4652 G1KeepAliveClosure keep_alive(this); | |
4653 JNIHandles::weak_oops_do(&is_alive, &keep_alive); | |
4654 } | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4655 release_gc_alloc_regions(); |
342 | 4656 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
|
4657 |
889 | 4658 concurrent_g1_refine()->clear_hot_cache(); |
342 | 4659 concurrent_g1_refine()->set_use_cache(true); |
4660 | |
4661 finalize_for_evac_failure(); | |
4662 | |
4663 // Must do this before removing self-forwarding pointers, which clears | |
4664 // the per-region evac-failure flags. | |
4665 concurrent_mark()->complete_marking_in_collection_set(); | |
4666 | |
4667 if (evacuation_failed()) { | |
4668 remove_self_forwarding_pointers(); | |
4669 if (PrintGCDetails) { | |
1719
b63010841f78
6975964: G1: print out a more descriptive message for evacuation failure when +PrintGCDetails is set
tonyp
parents:
1718
diff
changeset
|
4670 gclog_or_tty->print(" (to-space overflow)"); |
342 | 4671 } else if (PrintGC) { |
4672 gclog_or_tty->print("--"); | |
4673 } | |
4674 } | |
4675 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4676 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4677 RedirtyLoggedCardTableEntryFastClosure redirty; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4678 dirty_card_queue_set().set_closure(&redirty); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4679 dirty_card_queue_set().apply_closure_to_all_completed_buffers(); |
1111 | 4680 |
4681 DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set(); | |
4682 dcq.merge_bufferlists(&dirty_card_queue_set()); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4683 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
|
4684 } |
342 | 4685 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); |
4686 } | |
4687 | |
2173 | 4688 void G1CollectedHeap::free_region_if_empty(HeapRegion* hr, |
2152 | 4689 size_t* pre_used, |
4690 FreeRegionList* free_list, | |
4691 HumongousRegionSet* humongous_proxy_set, | |
2173 | 4692 HRRSCleanupTask* hrrs_cleanup_task, |
2152 | 4693 bool par) { |
4694 if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young()) { | |
4695 if (hr->isHumongous()) { | |
4696 assert(hr->startsHumongous(), "we should only see starts humongous"); | |
4697 free_humongous_region(hr, pre_used, free_list, humongous_proxy_set, par); | |
4698 } else { | |
4699 free_region(hr, pre_used, free_list, par); | |
342 | 4700 } |
2173 | 4701 } else { |
4702 hr->rem_set()->do_cleanup_work(hrrs_cleanup_task); | |
342 | 4703 } |
4704 } | |
4705 | |
2152 | 4706 void G1CollectedHeap::free_region(HeapRegion* hr, |
4707 size_t* pre_used, | |
4708 FreeRegionList* free_list, | |
4709 bool par) { | |
4710 assert(!hr->isHumongous(), "this is only for non-humongous regions"); | |
4711 assert(!hr->is_empty(), "the region should not be empty"); | |
4712 assert(free_list != NULL, "pre-condition"); | |
4713 | |
4714 *pre_used += hr->used(); | |
4715 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
|
4716 free_list->add_as_head(hr); |
2152 | 4717 } |
4718 | |
4719 void G1CollectedHeap::free_humongous_region(HeapRegion* hr, | |
4720 size_t* pre_used, | |
4721 FreeRegionList* free_list, | |
4722 HumongousRegionSet* humongous_proxy_set, | |
4723 bool par) { | |
4724 assert(hr->startsHumongous(), "this is only for starts humongous regions"); | |
4725 assert(free_list != NULL, "pre-condition"); | |
4726 assert(humongous_proxy_set != NULL, "pre-condition"); | |
4727 | |
4728 size_t hr_used = hr->used(); | |
4729 size_t hr_capacity = hr->capacity(); | |
4730 size_t hr_pre_used = 0; | |
4731 _humongous_set.remove_with_proxy(hr, humongous_proxy_set); | |
4732 hr->set_notHumongous(); | |
4733 free_region(hr, &hr_pre_used, free_list, par); | |
4734 | |
3766 | 4735 size_t i = hr->hrs_index() + 1; |
2152 | 4736 size_t num = 1; |
3766 | 4737 while (i < n_regions()) { |
4738 HeapRegion* curr_hr = region_at(i); | |
2152 | 4739 if (!curr_hr->continuesHumongous()) { |
4740 break; | |
4741 } | |
4742 curr_hr->set_notHumongous(); | |
4743 free_region(curr_hr, &hr_pre_used, free_list, par); | |
4744 num += 1; | |
4745 i += 1; | |
4746 } | |
4747 assert(hr_pre_used == hr_used, | |
4748 err_msg("hr_pre_used: "SIZE_FORMAT" and hr_used: "SIZE_FORMAT" " | |
4749 "should be the same", hr_pre_used, hr_used)); | |
4750 *pre_used += hr_pre_used; | |
4751 } | |
4752 | |
4753 void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used, | |
4754 FreeRegionList* free_list, | |
4755 HumongousRegionSet* humongous_proxy_set, | |
4756 bool par) { | |
4757 if (pre_used > 0) { | |
4758 Mutex* lock = (par) ? ParGCRareEvent_lock : NULL; | |
342 | 4759 MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag); |
2152 | 4760 assert(_summary_bytes_used >= pre_used, |
4761 err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" " | |
4762 "should be >= pre_used: "SIZE_FORMAT, | |
4763 _summary_bytes_used, pre_used)); | |
342 | 4764 _summary_bytes_used -= pre_used; |
2152 | 4765 } |
4766 if (free_list != NULL && !free_list->is_empty()) { | |
4767 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
|
4768 _free_list.add_as_head(free_list); |
2152 | 4769 } |
4770 if (humongous_proxy_set != NULL && !humongous_proxy_set->is_empty()) { | |
4771 MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); | |
4772 _humongous_set.update_from_proxy(humongous_proxy_set); | |
342 | 4773 } |
4774 } | |
4775 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4776 class G1ParCleanupCTTask : public AbstractGangTask { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4777 CardTableModRefBS* _ct_bs; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4778 G1CollectedHeap* _g1h; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4779 HeapRegion* volatile _su_head; |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4780 public: |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4781 G1ParCleanupCTTask(CardTableModRefBS* ct_bs, |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4782 G1CollectedHeap* g1h) : |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4783 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
|
4784 _ct_bs(ct_bs), _g1h(g1h) { } |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4785 |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4786 void work(int i) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4787 HeapRegion* r; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4788 while (r = _g1h->pop_dirty_cards_region()) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4789 clear_cards(r); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4790 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4791 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4792 |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4793 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
|
4794 // 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
|
4795 if (!r->is_survivor()) { |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4796 _ct_bs->clear(MemRegion(r->bottom(), r->end())); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4797 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4798 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4799 }; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4800 |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4801 #ifndef PRODUCT |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4802 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
|
4803 G1CollectedHeap* _g1h; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4804 CardTableModRefBS* _ct_bs; |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4805 public: |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4806 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
|
4807 : _g1h(g1h), _ct_bs(ct_bs) { } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4808 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
|
4809 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
|
4810 _g1h->verify_dirty_region(r); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4811 } else { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4812 _g1h->verify_not_dirty_region(r); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4813 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4814 return false; |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4815 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4816 }; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4817 |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4818 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
|
4819 // 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
|
4820 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
|
4821 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
|
4822 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
|
4823 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4824 |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4825 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
|
4826 // 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
|
4827 // 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
|
4828 // 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
|
4829 // 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
|
4830 // 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
|
4831 // 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
|
4832 // is dirty. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4833 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
|
4834 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
|
4835 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
|
4836 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
4837 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4838 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
|
4839 CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4840 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
|
4841 verify_dirty_region(hr); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4842 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4843 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4844 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4845 void G1CollectedHeap::verify_dirty_young_regions() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4846 verify_dirty_young_list(_young_list->first_region()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4847 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
|
4848 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4849 #endif |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4850 |
342 | 4851 void G1CollectedHeap::cleanUpCardTable() { |
4852 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); | |
4853 double start = os::elapsedTime(); | |
4854 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4855 // 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
|
4856 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
|
4857 |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4858 if (ParallelGCThreads > 0) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4859 set_par_threads(workers()->total_workers()); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4860 workers()->run_task(&cleanup_task); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4861 set_par_threads(0); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4862 } else { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4863 while (_dirty_cards_region_list) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4864 HeapRegion* r = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4865 cleanup_task.clear_cards(r); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4866 _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
|
4867 if (_dirty_cards_region_list == r) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4868 // The last region. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4869 _dirty_cards_region_list = NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4870 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4871 r->set_next_dirty_cards_region(NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
4872 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4873 } |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4874 |
342 | 4875 double elapsed = os::elapsedTime() - start; |
4876 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
|
4877 #ifndef PRODUCT |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4878 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
|
4879 G1VerifyCardTableCleanup cleanup_verifier(this, ct_bs); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4880 heap_region_iterate(&cleanup_verifier); |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4881 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
4882 #endif |
342 | 4883 } |
4884 | |
4885 void G1CollectedHeap::free_collection_set(HeapRegion* cs_head) { | |
2152 | 4886 size_t pre_used = 0; |
4887 FreeRegionList local_free_list("Local List for CSet Freeing"); | |
4888 | |
342 | 4889 double young_time_ms = 0.0; |
4890 double non_young_time_ms = 0.0; | |
4891 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4892 // 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
|
4893 // 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
|
4894 // 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
|
4895 _young_list->clear(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4896 |
342 | 4897 G1CollectorPolicy* policy = g1_policy(); |
4898 | |
4899 double start_sec = os::elapsedTime(); | |
4900 bool non_young = true; | |
4901 | |
4902 HeapRegion* cur = cs_head; | |
4903 int age_bound = -1; | |
4904 size_t rs_lengths = 0; | |
4905 | |
4906 while (cur != NULL) { | |
2361 | 4907 assert(!is_on_master_free_list(cur), "sanity"); |
2152 | 4908 |
342 | 4909 if (non_young) { |
4910 if (cur->is_young()) { | |
4911 double end_sec = os::elapsedTime(); | |
4912 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
4913 non_young_time_ms += elapsed_ms; | |
4914 | |
4915 start_sec = os::elapsedTime(); | |
4916 non_young = false; | |
4917 } | |
4918 } else { | |
2152 | 4919 double end_sec = os::elapsedTime(); |
4920 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
4921 young_time_ms += elapsed_ms; | |
4922 | |
4923 start_sec = os::elapsedTime(); | |
4924 non_young = true; | |
342 | 4925 } |
4926 | |
4927 rs_lengths += cur->rem_set()->occupied(); | |
4928 | |
4929 HeapRegion* next = cur->next_in_collection_set(); | |
4930 assert(cur->in_collection_set(), "bad CS"); | |
4931 cur->set_next_in_collection_set(NULL); | |
4932 cur->set_in_collection_set(false); | |
4933 | |
4934 if (cur->is_young()) { | |
4935 int index = cur->young_index_in_cset(); | |
4936 guarantee( index != -1, "invariant" ); | |
4937 guarantee( (size_t)index < policy->young_cset_length(), "invariant" ); | |
4938 size_t words_survived = _surviving_young_words[index]; | |
4939 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
|
4940 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4941 // 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
|
4942 // (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
|
4943 // 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
|
4944 // _next_young_region field. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4945 cur->set_next_young_region(NULL); |
342 | 4946 } else { |
4947 int index = cur->young_index_in_cset(); | |
4948 guarantee( index == -1, "invariant" ); | |
4949 } | |
4950 | |
4951 assert( (cur->is_young() && cur->young_index_in_cset() > -1) || | |
4952 (!cur->is_young() && cur->young_index_in_cset() == -1), | |
4953 "invariant" ); | |
4954 | |
4955 if (!cur->evacuation_failed()) { | |
4956 // And the region is empty. | |
2152 | 4957 assert(!cur->is_empty(), "Should not have empty regions in a CS."); |
4958 free_region(cur, &pre_used, &local_free_list, false /* par */); | |
342 | 4959 } else { |
4960 cur->uninstall_surv_rate_group(); | |
4961 if (cur->is_young()) | |
4962 cur->set_young_index_in_cset(-1); | |
4963 cur->set_not_young(); | |
4964 cur->set_evacuation_failed(false); | |
4965 } | |
4966 cur = next; | |
4967 } | |
4968 | |
4969 policy->record_max_rs_lengths(rs_lengths); | |
4970 policy->cset_regions_freed(); | |
4971 | |
4972 double end_sec = os::elapsedTime(); | |
4973 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
4974 if (non_young) | |
4975 non_young_time_ms += elapsed_ms; | |
4976 else | |
4977 young_time_ms += elapsed_ms; | |
4978 | |
2152 | 4979 update_sets_after_freeing_regions(pre_used, &local_free_list, |
4980 NULL /* humongous_proxy_set */, | |
4981 false /* par */); | |
342 | 4982 policy->record_young_free_cset_time_ms(young_time_ms); |
4983 policy->record_non_young_free_cset_time_ms(non_young_time_ms); | |
4984 } | |
4985 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4986 // 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
|
4987 // 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
|
4988 // 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
|
4989 // 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
|
4990 // 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
|
4991 // 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
|
4992 // 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
|
4993 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4994 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
|
4995 HeapRegion* cur = cs_head; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4996 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4997 while (cur != NULL) { |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4998 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
|
4999 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
|
5000 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
|
5001 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
|
5002 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
|
5003 cur = next; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5004 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5005 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5006 |
2152 | 5007 void G1CollectedHeap::set_free_regions_coming() { |
5008 if (G1ConcRegionFreeingVerbose) { | |
5009 gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : " | |
5010 "setting free regions coming"); | |
5011 } | |
5012 | |
5013 assert(!free_regions_coming(), "pre-condition"); | |
5014 _free_regions_coming = true; | |
342 | 5015 } |
5016 | |
2152 | 5017 void G1CollectedHeap::reset_free_regions_coming() { |
5018 { | |
5019 assert(free_regions_coming(), "pre-condition"); | |
5020 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); | |
5021 _free_regions_coming = false; | |
5022 SecondaryFreeList_lock->notify_all(); | |
5023 } | |
5024 | |
5025 if (G1ConcRegionFreeingVerbose) { | |
5026 gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : " | |
5027 "reset free regions coming"); | |
342 | 5028 } |
5029 } | |
5030 | |
2152 | 5031 void G1CollectedHeap::wait_while_free_regions_coming() { |
5032 // Most of the time we won't have to wait, so let's do a quick test | |
5033 // first before we take the lock. | |
5034 if (!free_regions_coming()) { | |
5035 return; | |
5036 } | |
5037 | |
5038 if (G1ConcRegionFreeingVerbose) { | |
5039 gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : " | |
5040 "waiting for free regions"); | |
342 | 5041 } |
5042 | |
5043 { | |
2152 | 5044 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
5045 while (free_regions_coming()) { | |
5046 SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag); | |
342 | 5047 } |
2152 | 5048 } |
5049 | |
5050 if (G1ConcRegionFreeingVerbose) { | |
5051 gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : " | |
5052 "done waiting for free regions"); | |
5053 } | |
342 | 5054 } |
5055 | |
5056 void G1CollectedHeap::set_region_short_lived_locked(HeapRegion* hr) { | |
5057 assert(heap_lock_held_for_gc(), | |
5058 "the heap lock should already be held by or for this thread"); | |
5059 _young_list->push_region(hr); | |
5060 g1_policy()->set_region_short_lived(hr); | |
5061 } | |
5062 | |
5063 class NoYoungRegionsClosure: public HeapRegionClosure { | |
5064 private: | |
5065 bool _success; | |
5066 public: | |
5067 NoYoungRegionsClosure() : _success(true) { } | |
5068 bool doHeapRegion(HeapRegion* r) { | |
5069 if (r->is_young()) { | |
5070 gclog_or_tty->print_cr("Region ["PTR_FORMAT", "PTR_FORMAT") tagged as young", | |
5071 r->bottom(), r->end()); | |
5072 _success = false; | |
5073 } | |
5074 return false; | |
5075 } | |
5076 bool success() { return _success; } | |
5077 }; | |
5078 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5079 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
|
5080 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
|
5081 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5082 if (check_heap) { |
342 | 5083 NoYoungRegionsClosure closure; |
5084 heap_region_iterate(&closure); | |
5085 ret = ret && closure.success(); | |
5086 } | |
5087 | |
5088 return ret; | |
5089 } | |
5090 | |
5091 void G1CollectedHeap::empty_young_list() { | |
5092 assert(heap_lock_held_for_gc(), | |
5093 "the heap lock should already be held by or for this thread"); | |
5094 assert(g1_policy()->in_young_gc_mode(), "should be in young GC mode"); | |
5095 | |
5096 _young_list->empty_list(); | |
5097 } | |
5098 | |
5099 // Done at the start of full GC. | |
5100 void G1CollectedHeap::tear_down_region_lists() { | |
2152 | 5101 _free_list.remove_all(); |
342 | 5102 } |
5103 | |
5104 class RegionResetter: public HeapRegionClosure { | |
2152 | 5105 G1CollectedHeap* _g1h; |
5106 FreeRegionList _local_free_list; | |
5107 | |
342 | 5108 public: |
2152 | 5109 RegionResetter() : _g1h(G1CollectedHeap::heap()), |
5110 _local_free_list("Local Free List for RegionResetter") { } | |
5111 | |
342 | 5112 bool doHeapRegion(HeapRegion* r) { |
5113 if (r->continuesHumongous()) return false; | |
5114 if (r->top() > r->bottom()) { | |
5115 if (r->top() < r->end()) { | |
5116 Copy::fill_to_words(r->top(), | |
5117 pointer_delta(r->end(), r->top())); | |
5118 } | |
5119 } else { | |
5120 assert(r->is_empty(), "tautology"); | |
2152 | 5121 _local_free_list.add_as_tail(r); |
342 | 5122 } |
5123 return false; | |
5124 } | |
5125 | |
2152 | 5126 void update_free_lists() { |
5127 _g1h->update_sets_after_freeing_regions(0, &_local_free_list, NULL, | |
5128 false /* par */); | |
5129 } | |
342 | 5130 }; |
5131 | |
5132 // Done at the end of full GC. | |
5133 void G1CollectedHeap::rebuild_region_lists() { | |
5134 // This needs to go at the end of the full GC. | |
5135 RegionResetter rs; | |
5136 heap_region_iterate(&rs); | |
2152 | 5137 rs.update_free_lists(); |
342 | 5138 } |
5139 | |
5140 void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) { | |
5141 _refine_cte_cl->set_concurrent(concurrent); | |
5142 } | |
5143 | |
5144 bool G1CollectedHeap::is_in_closed_subset(const void* p) const { | |
5145 HeapRegion* hr = heap_region_containing(p); | |
5146 if (hr == NULL) { | |
5147 return is_in_permanent(p); | |
5148 } else { | |
5149 return hr->is_in(p); | |
5150 } | |
5151 } | |
2152 | 5152 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5153 // 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
|
5154 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5155 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
|
5156 bool force) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5157 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
|
5158 assert(!force || g1_policy()->can_expand_young_list(), |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5159 "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
|
5160 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
|
5161 if (force || !young_list_full) { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5162 HeapRegion* new_alloc_region = new_region(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5163 false /* do_expand */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5164 if (new_alloc_region != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5165 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
|
5166 set_region_short_lived_locked(new_alloc_region); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
5167 _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
|
5168 g1mm()->update_eden_counters(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5169 return new_alloc_region; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5170 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5171 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5172 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5173 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5174 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5175 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
|
5176 size_t allocated_bytes) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5177 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
|
5178 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
|
5179 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5180 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
|
5181 _summary_bytes_used += allocated_bytes; |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
5182 _hr_printer.retire(alloc_region); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5183 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5184 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5185 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
|
5186 bool force) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5187 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
|
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 MutatorAllocRegion::retire_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 _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
|
5193 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5194 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5195 // 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
|
5196 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5197 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
|
5198 size_t count, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5199 GCAllocPurpose ap) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5200 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
|
5201 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5202 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
|
5203 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
|
5204 true /* do_expand */); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5205 if (new_alloc_region != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5206 // 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
|
5207 // 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
|
5208 // for survivors too. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5209 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
|
5210 if (ap == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5211 new_alloc_region->set_survivor(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5212 _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
|
5213 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5214 _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
|
5215 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5216 return new_alloc_region; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5217 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5218 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
|
5219 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5220 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5221 return NULL; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5222 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5223 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5224 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
|
5225 size_t allocated_bytes, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5226 GCAllocPurpose ap) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5227 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
|
5228 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
|
5229 if (ap == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5230 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
|
5231 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5232 _hr_printer.retire(alloc_region); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5233 } |
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 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
|
5236 bool force) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5237 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
|
5238 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
|
5239 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5240 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5241 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
|
5242 size_t allocated_bytes) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5243 _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
|
5244 GCAllocForSurvived); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5245 } |
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 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
|
5248 bool force) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5249 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
|
5250 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
|
5251 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5252 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5253 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
|
5254 size_t allocated_bytes) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5255 _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
|
5256 GCAllocForTenured); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5257 } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5258 // Heap region set verification |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5259 |
2152 | 5260 class VerifyRegionListsClosure : public HeapRegionClosure { |
5261 private: | |
5262 HumongousRegionSet* _humongous_set; | |
5263 FreeRegionList* _free_list; | |
5264 size_t _region_count; | |
5265 | |
5266 public: | |
5267 VerifyRegionListsClosure(HumongousRegionSet* humongous_set, | |
5268 FreeRegionList* free_list) : | |
5269 _humongous_set(humongous_set), _free_list(free_list), | |
5270 _region_count(0) { } | |
5271 | |
5272 size_t region_count() { return _region_count; } | |
5273 | |
5274 bool doHeapRegion(HeapRegion* hr) { | |
5275 _region_count += 1; | |
5276 | |
5277 if (hr->continuesHumongous()) { | |
5278 return false; | |
5279 } | |
5280 | |
5281 if (hr->is_young()) { | |
5282 // TODO | |
5283 } else if (hr->startsHumongous()) { | |
5284 _humongous_set->verify_next_region(hr); | |
5285 } else if (hr->is_empty()) { | |
5286 _free_list->verify_next_region(hr); | |
5287 } | |
5288 return false; | |
5289 } | |
5290 }; | |
5291 | |
3766 | 5292 HeapRegion* G1CollectedHeap::new_heap_region(size_t hrs_index, |
5293 HeapWord* bottom) { | |
5294 HeapWord* end = bottom + HeapRegion::GrainWords; | |
5295 MemRegion mr(bottom, end); | |
5296 assert(_g1_reserved.contains(mr), "invariant"); | |
5297 // This might return NULL if the allocation fails | |
5298 return new HeapRegion(hrs_index, _bot_shared, mr, true /* is_zeroed */); | |
5299 } | |
5300 | |
2152 | 5301 void G1CollectedHeap::verify_region_sets() { |
5302 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); | |
5303 | |
5304 // First, check the explicit lists. | |
5305 _free_list.verify(); | |
5306 { | |
5307 // Given that a concurrent operation might be adding regions to | |
5308 // the secondary free list we have to take the lock before | |
5309 // verifying it. | |
5310 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); | |
5311 _secondary_free_list.verify(); | |
5312 } | |
5313 _humongous_set.verify(); | |
5314 | |
5315 // If a concurrent region freeing operation is in progress it will | |
5316 // be difficult to correctly attributed any free regions we come | |
5317 // across to the correct free list given that they might belong to | |
5318 // one of several (free_list, secondary_free_list, any local lists, | |
5319 // etc.). So, if that's the case we will skip the rest of the | |
5320 // verification operation. Alternatively, waiting for the concurrent | |
5321 // operation to complete will have a non-trivial effect on the GC's | |
5322 // operation (no concurrent operation will last longer than the | |
5323 // interval between two calls to verification) and it might hide | |
5324 // any issues that we would like to catch during testing. | |
5325 if (free_regions_coming()) { | |
5326 return; | |
5327 } | |
5328 | |
2361 | 5329 // Make sure we append the secondary_free_list on the free_list so |
5330 // that all free regions we will come across can be safely | |
5331 // attributed to the free_list. | |
5332 append_secondary_free_list_if_not_empty_with_lock(); | |
2152 | 5333 |
5334 // Finally, make sure that the region accounting in the lists is | |
5335 // consistent with what we see in the heap. | |
5336 _humongous_set.verify_start(); | |
5337 _free_list.verify_start(); | |
5338 | |
5339 VerifyRegionListsClosure cl(&_humongous_set, &_free_list); | |
5340 heap_region_iterate(&cl); | |
5341 | |
5342 _humongous_set.verify_end(); | |
5343 _free_list.verify_end(); | |
342 | 5344 } |