Mercurial > hg > graal-jvmci-8
annotate src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 3979:4dfb2df418f2
6484982: G1: process references during evacuation pauses
Summary: G1 now uses two reference processors - one is used by concurrent marking and the other is used by STW GCs (both full and incremental evacuation pauses). In an evacuation pause, the reference processor is embedded into the closures used to scan objects. Doing so causes causes reference objects to be 'discovered' by the reference processor. At the end of the evacuation pause, these discovered reference objects are processed - preserving (and copying) referent objects (and their reachable graphs) as appropriate.
Reviewed-by: ysr, jwilhelm, brutisso, stefank, tonyp
author | johnc |
---|---|
date | Thu, 22 Sep 2011 10:57:37 -0700 |
parents | 663cb89032b1 |
children | 8229bd737950 |
rev | line source |
---|---|
342 | 1 /* |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
342 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1547
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1547
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1547
diff
changeset
|
21 * questions. |
342 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "code/icBuffer.hpp" | |
27 #include "gc_implementation/g1/bufferingOopClosure.hpp" | |
28 #include "gc_implementation/g1/concurrentG1Refine.hpp" | |
29 #include "gc_implementation/g1/concurrentG1RefineThread.hpp" | |
30 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp" | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
31 #include "gc_implementation/g1/g1AllocRegion.inline.hpp" |
1972 | 32 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
33 #include "gc_implementation/g1/g1CollectorPolicy.hpp" | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
34 #include "gc_implementation/g1/g1ErgoVerbose.hpp" |
1972 | 35 #include "gc_implementation/g1/g1MarkSweep.hpp" |
36 #include "gc_implementation/g1/g1OopClosures.inline.hpp" | |
37 #include "gc_implementation/g1/g1RemSet.inline.hpp" | |
38 #include "gc_implementation/g1/heapRegionRemSet.hpp" | |
39 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
40 #include "gc_implementation/g1/vm_operations_g1.hpp" | |
41 #include "gc_implementation/shared/isGCActiveMark.hpp" | |
42 #include "memory/gcLocker.inline.hpp" | |
43 #include "memory/genOopClosures.inline.hpp" | |
44 #include "memory/generationSpec.hpp" | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
45 #include "memory/referenceProcessor.hpp" |
1972 | 46 #include "oops/oop.inline.hpp" |
47 #include "oops/oop.pcgc.inline.hpp" | |
48 #include "runtime/aprofiler.hpp" | |
49 #include "runtime/vmThread.hpp" | |
342 | 50 |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
51 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
|
52 |
342 | 53 // turn it on so that the contents of the young list (scan-only / |
54 // to-be-collected) are printed at "strategic" points before / during | |
55 // / 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
|
56 #define YOUNG_LIST_VERBOSE 0 |
342 | 57 // CURRENT STATUS |
58 // This file is under construction. Search for "FIXME". | |
59 | |
60 // INVARIANTS/NOTES | |
61 // | |
62 // All allocation activity covered by the G1CollectedHeap interface is | |
1973 | 63 // serialized by acquiring the HeapLock. This happens in mem_allocate |
64 // and allocate_new_tlab, which are the "entry" points to the | |
65 // allocation code from the rest of the JVM. (Note that this does not | |
66 // apply to TLAB allocation, which is not part of this interface: it | |
67 // is done by clients of this interface.) | |
342 | 68 |
69 // Local to this file. | |
70 | |
71 class RefineCardTableEntryClosure: public CardTableEntryClosure { | |
72 SuspendibleThreadSet* _sts; | |
73 G1RemSet* _g1rs; | |
74 ConcurrentG1Refine* _cg1r; | |
75 bool _concurrent; | |
76 public: | |
77 RefineCardTableEntryClosure(SuspendibleThreadSet* sts, | |
78 G1RemSet* g1rs, | |
79 ConcurrentG1Refine* cg1r) : | |
80 _sts(sts), _g1rs(g1rs), _cg1r(cg1r), _concurrent(true) | |
81 {} | |
82 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
1705 | 83 bool oops_into_cset = _g1rs->concurrentRefineOneCard(card_ptr, worker_i, false); |
84 // This path is executed by the concurrent refine or mutator threads, | |
85 // concurrently, and so we do not care if card_ptr contains references | |
86 // that point into the collection set. | |
87 assert(!oops_into_cset, "should be"); | |
88 | |
342 | 89 if (_concurrent && _sts->should_yield()) { |
90 // Caller will actually yield. | |
91 return false; | |
92 } | |
93 // Otherwise, we finished successfully; return true. | |
94 return true; | |
95 } | |
96 void set_concurrent(bool b) { _concurrent = b; } | |
97 }; | |
98 | |
99 | |
100 class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { | |
101 int _calls; | |
102 G1CollectedHeap* _g1h; | |
103 CardTableModRefBS* _ctbs; | |
104 int _histo[256]; | |
105 public: | |
106 ClearLoggedCardTableEntryClosure() : | |
107 _calls(0) | |
108 { | |
109 _g1h = G1CollectedHeap::heap(); | |
110 _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); | |
111 for (int i = 0; i < 256; i++) _histo[i] = 0; | |
112 } | |
113 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
114 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { | |
115 _calls++; | |
116 unsigned char* ujb = (unsigned char*)card_ptr; | |
117 int ind = (int)(*ujb); | |
118 _histo[ind]++; | |
119 *card_ptr = -1; | |
120 } | |
121 return true; | |
122 } | |
123 int calls() { return _calls; } | |
124 void print_histo() { | |
125 gclog_or_tty->print_cr("Card table value histogram:"); | |
126 for (int i = 0; i < 256; i++) { | |
127 if (_histo[i] != 0) { | |
128 gclog_or_tty->print_cr(" %d: %d", i, _histo[i]); | |
129 } | |
130 } | |
131 } | |
132 }; | |
133 | |
134 class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { | |
135 int _calls; | |
136 G1CollectedHeap* _g1h; | |
137 CardTableModRefBS* _ctbs; | |
138 public: | |
139 RedirtyLoggedCardTableEntryClosure() : | |
140 _calls(0) | |
141 { | |
142 _g1h = G1CollectedHeap::heap(); | |
143 _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); | |
144 } | |
145 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
146 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { | |
147 _calls++; | |
148 *card_ptr = 0; | |
149 } | |
150 return true; | |
151 } | |
152 int calls() { return _calls; } | |
153 }; | |
154 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
155 class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
156 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
157 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
|
158 *card_ptr = CardTableModRefBS::dirty_card_val(); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
159 return true; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
160 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
161 }; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
162 |
342 | 163 YoungList::YoungList(G1CollectedHeap* g1h) |
164 : _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
|
165 _length(0), |
342 | 166 _last_sampled_rs_lengths(0), |
545 | 167 _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) |
342 | 168 { |
169 guarantee( check_list_empty(false), "just making sure..." ); | |
170 } | |
171 | |
172 void YoungList::push_region(HeapRegion *hr) { | |
173 assert(!hr->is_young(), "should not already be young"); | |
174 assert(hr->get_next_young_region() == NULL, "cause it should!"); | |
175 | |
176 hr->set_next_young_region(_head); | |
177 _head = hr; | |
178 | |
179 hr->set_young(); | |
180 double yg_surv_rate = _g1h->g1_policy()->predict_yg_surv_rate((int)_length); | |
181 ++_length; | |
182 } | |
183 | |
184 void YoungList::add_survivor_region(HeapRegion* hr) { | |
545 | 185 assert(hr->is_survivor(), "should be flagged as survivor region"); |
342 | 186 assert(hr->get_next_young_region() == NULL, "cause it should!"); |
187 | |
188 hr->set_next_young_region(_survivor_head); | |
189 if (_survivor_head == NULL) { | |
545 | 190 _survivor_tail = hr; |
342 | 191 } |
192 _survivor_head = hr; | |
193 | |
194 ++_survivor_length; | |
195 } | |
196 | |
197 void YoungList::empty_list(HeapRegion* list) { | |
198 while (list != NULL) { | |
199 HeapRegion* next = list->get_next_young_region(); | |
200 list->set_next_young_region(NULL); | |
201 list->uninstall_surv_rate_group(); | |
202 list->set_not_young(); | |
203 list = next; | |
204 } | |
205 } | |
206 | |
207 void YoungList::empty_list() { | |
208 assert(check_list_well_formed(), "young list should be well formed"); | |
209 | |
210 empty_list(_head); | |
211 _head = NULL; | |
212 _length = 0; | |
213 | |
214 empty_list(_survivor_head); | |
215 _survivor_head = NULL; | |
545 | 216 _survivor_tail = NULL; |
342 | 217 _survivor_length = 0; |
218 | |
219 _last_sampled_rs_lengths = 0; | |
220 | |
221 assert(check_list_empty(false), "just making sure..."); | |
222 } | |
223 | |
224 bool YoungList::check_list_well_formed() { | |
225 bool ret = true; | |
226 | |
227 size_t length = 0; | |
228 HeapRegion* curr = _head; | |
229 HeapRegion* last = NULL; | |
230 while (curr != NULL) { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
231 if (!curr->is_young()) { |
342 | 232 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
|
233 "incorrectly tagged (y: %d, surv: %d)", |
342 | 234 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
|
235 curr->is_young(), curr->is_survivor()); |
342 | 236 ret = false; |
237 } | |
238 ++length; | |
239 last = curr; | |
240 curr = curr->get_next_young_region(); | |
241 } | |
242 ret = ret && (length == _length); | |
243 | |
244 if (!ret) { | |
245 gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!"); | |
246 gclog_or_tty->print_cr("### list has %d entries, _length is %d", | |
247 length, _length); | |
248 } | |
249 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
250 return ret; |
342 | 251 } |
252 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
253 bool YoungList::check_list_empty(bool check_sample) { |
342 | 254 bool ret = true; |
255 | |
256 if (_length != 0) { | |
257 gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %d", | |
258 _length); | |
259 ret = false; | |
260 } | |
261 if (check_sample && _last_sampled_rs_lengths != 0) { | |
262 gclog_or_tty->print_cr("### YOUNG LIST has non-zero last sampled RS lengths"); | |
263 ret = false; | |
264 } | |
265 if (_head != NULL) { | |
266 gclog_or_tty->print_cr("### YOUNG LIST does not have a NULL head"); | |
267 ret = false; | |
268 } | |
269 if (!ret) { | |
270 gclog_or_tty->print_cr("### YOUNG LIST does not seem empty"); | |
271 } | |
272 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
273 return ret; |
342 | 274 } |
275 | |
276 void | |
277 YoungList::rs_length_sampling_init() { | |
278 _sampled_rs_lengths = 0; | |
279 _curr = _head; | |
280 } | |
281 | |
282 bool | |
283 YoungList::rs_length_sampling_more() { | |
284 return _curr != NULL; | |
285 } | |
286 | |
287 void | |
288 YoungList::rs_length_sampling_next() { | |
289 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
|
290 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
|
291 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
292 _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
|
293 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
294 // 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
|
295 // 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
|
296 // 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
|
297 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
|
298 // 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
|
299 _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
|
300 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
301 |
342 | 302 _curr = _curr->get_next_young_region(); |
303 if (_curr == NULL) { | |
304 _last_sampled_rs_lengths = _sampled_rs_lengths; | |
305 // gclog_or_tty->print_cr("last sampled RS lengths = %d", _last_sampled_rs_lengths); | |
306 } | |
307 } | |
308 | |
309 void | |
310 YoungList::reset_auxilary_lists() { | |
311 guarantee( is_empty(), "young list should be empty" ); | |
312 assert(check_list_well_formed(), "young list should be well formed"); | |
313 | |
314 // Add survivor regions to SurvRateGroup. | |
315 _g1h->g1_policy()->note_start_adding_survivor_regions(); | |
545 | 316 _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
|
317 |
342 | 318 for (HeapRegion* curr = _survivor_head; |
319 curr != NULL; | |
320 curr = curr->get_next_young_region()) { | |
321 _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
|
322 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
323 // 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
|
324 // 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
|
325 // pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
326 _g1h->g1_policy()->add_region_to_incremental_cset_rhs(curr); |
342 | 327 } |
328 _g1h->g1_policy()->note_stop_adding_survivor_regions(); | |
329 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
330 _head = _survivor_head; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
331 _length = _survivor_length; |
342 | 332 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
|
333 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
|
334 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
|
335 _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
|
336 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
337 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
338 // 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
|
339 // 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
|
340 // 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
|
341 // 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
|
342 |
545 | 343 _g1h->g1_policy()->finished_recalculating_age_indexes(false /* is_survivors */); |
342 | 344 |
345 assert(check_list_well_formed(), "young list should be well formed"); | |
346 } | |
347 | |
348 void YoungList::print() { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
349 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
|
350 const char* names[] = {"YOUNG", "SURVIVOR"}; |
342 | 351 |
352 for (unsigned int list = 0; list < ARRAY_SIZE(lists); ++list) { | |
353 gclog_or_tty->print_cr("%s LIST CONTENTS", names[list]); | |
354 HeapRegion *curr = lists[list]; | |
355 if (curr == NULL) | |
356 gclog_or_tty->print_cr(" empty"); | |
357 while (curr != NULL) { | |
358 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
|
359 "age: %4d, y: %d, surv: %d", |
342 | 360 curr->bottom(), curr->end(), |
361 curr->top(), | |
362 curr->prev_top_at_mark_start(), | |
363 curr->next_top_at_mark_start(), | |
364 curr->top_at_conc_mark_count(), | |
365 curr->age_in_surv_rate_group_cond(), | |
366 curr->is_young(), | |
367 curr->is_survivor()); | |
368 curr = curr->get_next_young_region(); | |
369 } | |
370 } | |
371 | |
372 gclog_or_tty->print_cr(""); | |
373 } | |
374 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
375 void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
376 { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
377 // 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
|
378 // by installing a self pointer. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
379 HeapRegion* next = hr->get_next_dirty_cards_region(); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
380 if (next == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
381 HeapRegion* res = (HeapRegion*) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
382 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
|
383 NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
384 if (res == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
385 HeapRegion* head; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
386 do { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
387 // Put the region to the dirty cards region list. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
388 head = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
389 next = (HeapRegion*) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
390 Atomic::cmpxchg_ptr(hr, &_dirty_cards_region_list, head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
391 if (next == head) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
392 assert(hr->get_next_dirty_cards_region() == hr, |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
393 "hr->get_next_dirty_cards_region() != hr"); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
394 if (next == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
395 // The last region in the list points to itself. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
396 hr->set_next_dirty_cards_region(hr); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
397 } else { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
398 hr->set_next_dirty_cards_region(next); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
399 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
400 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
401 } while (next != head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
402 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
403 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
404 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
405 |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
406 HeapRegion* G1CollectedHeap::pop_dirty_cards_region() |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
407 { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
408 HeapRegion* head; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
409 HeapRegion* hr; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
410 do { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
411 head = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
412 if (head == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
413 return NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
414 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
415 HeapRegion* new_head = head->get_next_dirty_cards_region(); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
416 if (head == new_head) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
417 // The last region. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
418 new_head = NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
419 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
420 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
|
421 head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
422 } while (hr != head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
423 assert(hr != NULL, "invariant"); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
424 hr->set_next_dirty_cards_region(NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
425 return hr; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
426 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
427 |
342 | 428 void G1CollectedHeap::stop_conc_gc_threads() { |
794 | 429 _cg1r->stop(); |
342 | 430 _cmThread->stop(); |
431 } | |
432 | |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
433 #ifdef ASSERT |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
434 // 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
|
435 // 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
|
436 // 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
|
437 // 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
|
438 // regions have been retired. It is used for debugging |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
439 // 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
|
440 // 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
|
441 // inaccurate, it is sufficient for G1 because the conservative |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
442 // implementation of is_scavengable() for G1 will indicate that |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
443 // all nmethods must be scanned during a partial collection. |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
444 bool G1CollectedHeap::is_in_partial_collection(const void* p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
445 HeapRegion* hr = heap_region_containing(p); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
446 return hr != NULL && hr->in_collection_set(); |
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 #endif |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
449 |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
450 // 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
|
451 // can move in an incremental collecction. |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
452 bool G1CollectedHeap::is_scavengable(const void* p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
453 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
454 G1CollectorPolicy* g1p = g1h->g1_policy(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
455 HeapRegion* hr = heap_region_containing(p); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
456 if (hr == NULL) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
457 // perm gen (or null) |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
458 return false; |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
459 } else { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
460 return !hr->isHumongous(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
461 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
462 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
463 |
342 | 464 void G1CollectedHeap::check_ct_logs_at_safepoint() { |
465 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
466 CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); | |
467 | |
468 // Count the dirty cards at the start. | |
469 CountNonCleanMemRegionClosure count1(this); | |
470 ct_bs->mod_card_iterate(&count1); | |
471 int orig_count = count1.n(); | |
472 | |
473 // First clear the logged cards. | |
474 ClearLoggedCardTableEntryClosure clear; | |
475 dcqs.set_closure(&clear); | |
476 dcqs.apply_closure_to_all_completed_buffers(); | |
477 dcqs.iterate_closure_all_threads(false); | |
478 clear.print_histo(); | |
479 | |
480 // Now ensure that there's no dirty cards. | |
481 CountNonCleanMemRegionClosure count2(this); | |
482 ct_bs->mod_card_iterate(&count2); | |
483 if (count2.n() != 0) { | |
484 gclog_or_tty->print_cr("Card table has %d entries; %d originally", | |
485 count2.n(), orig_count); | |
486 } | |
487 guarantee(count2.n() == 0, "Card table should be clean."); | |
488 | |
489 RedirtyLoggedCardTableEntryClosure redirty; | |
490 JavaThread::dirty_card_queue_set().set_closure(&redirty); | |
491 dcqs.apply_closure_to_all_completed_buffers(); | |
492 dcqs.iterate_closure_all_threads(false); | |
493 gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", | |
494 clear.calls(), orig_count); | |
495 guarantee(redirty.calls() == clear.calls(), | |
496 "Or else mechanism is broken."); | |
497 | |
498 CountNonCleanMemRegionClosure count3(this); | |
499 ct_bs->mod_card_iterate(&count3); | |
500 if (count3.n() != orig_count) { | |
501 gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.", | |
502 orig_count, count3.n()); | |
503 guarantee(count3.n() >= orig_count, "Should have restored them all."); | |
504 } | |
505 | |
506 JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); | |
507 } | |
508 | |
509 // Private class members. | |
510 | |
511 G1CollectedHeap* G1CollectedHeap::_g1h; | |
512 | |
513 // Private methods. | |
514 | |
2152 | 515 HeapRegion* |
2361 | 516 G1CollectedHeap::new_region_try_secondary_free_list() { |
2152 | 517 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
518 while (!_secondary_free_list.is_empty() || free_regions_coming()) { | |
519 if (!_secondary_free_list.is_empty()) { | |
520 if (G1ConcRegionFreeingVerbose) { | |
521 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
522 "secondary_free_list has "SIZE_FORMAT" entries", | |
523 _secondary_free_list.length()); | |
524 } | |
525 // It looks as if there are free regions available on the | |
526 // secondary_free_list. Let's move them to the free_list and try | |
527 // again to allocate from it. | |
528 append_secondary_free_list(); | |
529 | |
530 assert(!_free_list.is_empty(), "if the secondary_free_list was not " | |
531 "empty we should have moved at least one entry to the free_list"); | |
532 HeapRegion* res = _free_list.remove_head(); | |
533 if (G1ConcRegionFreeingVerbose) { | |
534 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
535 "allocated "HR_FORMAT" from secondary_free_list", | |
536 HR_FORMAT_PARAMS(res)); | |
537 } | |
538 return res; | |
539 } | |
540 | |
541 // Wait here until we get notifed either when (a) there are no | |
542 // more free regions coming or (b) some regions have been moved on | |
543 // the secondary_free_list. | |
544 SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag); | |
545 } | |
546 | |
547 if (G1ConcRegionFreeingVerbose) { | |
548 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
549 "could not allocate from secondary_free_list"); | |
550 } | |
551 return NULL; | |
552 } | |
553 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
554 HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool do_expand) { |
2152 | 555 assert(!isHumongous(word_size) || |
556 word_size <= (size_t) HeapRegion::GrainWords, | |
557 "the only time we use this to allocate a humongous region is " | |
558 "when we are allocating a single humongous region"); | |
559 | |
560 HeapRegion* res; | |
561 if (G1StressConcRegionFreeing) { | |
562 if (!_secondary_free_list.is_empty()) { | |
563 if (G1ConcRegionFreeingVerbose) { | |
564 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
565 "forced to look at the secondary_free_list"); | |
566 } | |
2361 | 567 res = new_region_try_secondary_free_list(); |
2152 | 568 if (res != NULL) { |
569 return res; | |
570 } | |
571 } | |
572 } | |
573 res = _free_list.remove_head_or_null(); | |
574 if (res == NULL) { | |
575 if (G1ConcRegionFreeingVerbose) { | |
576 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
577 "res == NULL, trying the secondary_free_list"); | |
578 } | |
2361 | 579 res = new_region_try_secondary_free_list(); |
2152 | 580 } |
342 | 581 if (res == NULL && do_expand) { |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
582 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
583 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
584 ergo_format_reason("region allocation request failed") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
585 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
586 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
587 if (expand(word_size * HeapWordSize)) { |
3766 | 588 // Even though the heap was expanded, it might not have reached |
589 // the desired size. So, we cannot assume that the allocation | |
590 // will succeed. | |
591 res = _free_list.remove_head_or_null(); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
592 } |
342 | 593 } |
594 return res; | |
595 } | |
596 | |
3766 | 597 size_t G1CollectedHeap::humongous_obj_allocate_find_first(size_t num_regions, |
598 size_t word_size) { | |
2361 | 599 assert(isHumongous(word_size), "word_size should be humongous"); |
600 assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); | |
601 | |
3766 | 602 size_t first = G1_NULL_HRS_INDEX; |
2152 | 603 if (num_regions == 1) { |
604 // Only one region to allocate, no need to go through the slower | |
605 // path. The caller will attempt the expasion if this fails, so | |
606 // 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
|
607 HeapRegion* hr = new_region(word_size, false /* do_expand */); |
2152 | 608 if (hr != NULL) { |
609 first = hr->hrs_index(); | |
610 } else { | |
3766 | 611 first = G1_NULL_HRS_INDEX; |
2152 | 612 } |
613 } else { | |
614 // We can't allocate humongous regions while cleanupComplete() is | |
615 // running, since some of the regions we find to be empty might not | |
616 // yet be added to the free list and it is not straightforward to | |
617 // know which list they are on so that we can remove them. Note | |
618 // that we only need to do this if we need to allocate more than | |
619 // one region to satisfy the current humongous allocation | |
620 // request. If we are only allocating one region we use the common | |
621 // region allocation code (see above). | |
622 wait_while_free_regions_coming(); | |
2361 | 623 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 624 |
625 if (free_regions() >= num_regions) { | |
3766 | 626 first = _hrs.find_contiguous(num_regions); |
627 if (first != G1_NULL_HRS_INDEX) { | |
628 for (size_t i = first; i < first + num_regions; ++i) { | |
629 HeapRegion* hr = region_at(i); | |
2152 | 630 assert(hr->is_empty(), "sanity"); |
2361 | 631 assert(is_on_master_free_list(hr), "sanity"); |
2152 | 632 hr->set_pending_removal(true); |
633 } | |
634 _free_list.remove_all_pending(num_regions); | |
635 } | |
636 } | |
637 } | |
638 return first; | |
639 } | |
640 | |
2361 | 641 HeapWord* |
3766 | 642 G1CollectedHeap::humongous_obj_allocate_initialize_regions(size_t first, |
2361 | 643 size_t num_regions, |
644 size_t word_size) { | |
3766 | 645 assert(first != G1_NULL_HRS_INDEX, "pre-condition"); |
2361 | 646 assert(isHumongous(word_size), "word_size should be humongous"); |
647 assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); | |
648 | |
649 // Index of last region in the series + 1. | |
3766 | 650 size_t last = first + num_regions; |
2361 | 651 |
652 // We need to initialize the region(s) we just discovered. This is | |
653 // a bit tricky given that it can happen concurrently with | |
654 // refinement threads refining cards on these regions and | |
655 // potentially wanting to refine the BOT as they are scanning | |
656 // those cards (this can happen shortly after a cleanup; see CR | |
657 // 6991377). So we have to set up the region(s) carefully and in | |
658 // a specific order. | |
659 | |
660 // The word size sum of all the regions we will allocate. | |
661 size_t word_size_sum = num_regions * HeapRegion::GrainWords; | |
662 assert(word_size <= word_size_sum, "sanity"); | |
663 | |
664 // This will be the "starts humongous" region. | |
3766 | 665 HeapRegion* first_hr = region_at(first); |
2361 | 666 // The header of the new object will be placed at the bottom of |
667 // the first region. | |
668 HeapWord* new_obj = first_hr->bottom(); | |
669 // This will be the new end of the first region in the series that | |
670 // should also match the end of the last region in the seriers. | |
671 HeapWord* new_end = new_obj + word_size_sum; | |
672 // This will be the new top of the first region that will reflect | |
673 // this allocation. | |
674 HeapWord* new_top = new_obj + word_size; | |
675 | |
676 // First, we need to zero the header of the space that we will be | |
677 // allocating. When we update top further down, some refinement | |
678 // threads might try to scan the region. By zeroing the header we | |
679 // ensure that any thread that will try to scan the region will | |
680 // come across the zero klass word and bail out. | |
681 // | |
682 // NOTE: It would not have been correct to have used | |
683 // CollectedHeap::fill_with_object() and make the space look like | |
684 // an int array. The thread that is doing the allocation will | |
685 // later update the object header to a potentially different array | |
686 // type and, for a very short period of time, the klass and length | |
687 // fields will be inconsistent. This could cause a refinement | |
688 // thread to calculate the object size incorrectly. | |
689 Copy::fill_to_words(new_obj, oopDesc::header_size(), 0); | |
690 | |
691 // We will set up the first region as "starts humongous". This | |
692 // will also update the BOT covering all the regions to reflect | |
693 // that there is a single object that starts at the bottom of the | |
694 // first region. | |
695 first_hr->set_startsHumongous(new_top, new_end); | |
696 | |
697 // Then, if there are any, we will set up the "continues | |
698 // humongous" regions. | |
699 HeapRegion* hr = NULL; | |
3766 | 700 for (size_t i = first + 1; i < last; ++i) { |
701 hr = region_at(i); | |
2361 | 702 hr->set_continuesHumongous(first_hr); |
703 } | |
704 // If we have "continues humongous" regions (hr != NULL), then the | |
705 // end of the last one should match new_end. | |
706 assert(hr == NULL || hr->end() == new_end, "sanity"); | |
707 | |
708 // Up to this point no concurrent thread would have been able to | |
709 // do any scanning on any region in this series. All the top | |
710 // fields still point to bottom, so the intersection between | |
711 // [bottom,top] and [card_start,card_end] will be empty. Before we | |
712 // update the top fields, we'll do a storestore to make sure that | |
713 // no thread sees the update to top before the zeroing of the | |
714 // object header and the BOT initialization. | |
715 OrderAccess::storestore(); | |
716 | |
717 // Now that the BOT and the object header have been initialized, | |
718 // we can update top of the "starts humongous" region. | |
719 assert(first_hr->bottom() < new_top && new_top <= first_hr->end(), | |
720 "new_top should be in this region"); | |
721 first_hr->set_top(new_top); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
722 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
723 HeapWord* bottom = first_hr->bottom(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
724 HeapWord* end = first_hr->orig_end(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
725 if ((first + 1) == last) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
726 // the series has a single humongous region |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
727 _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, new_top); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
728 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
729 // the series has more than one humongous regions |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
730 _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
731 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
732 } |
2361 | 733 |
734 // Now, we will update the top fields of the "continues humongous" | |
735 // regions. The reason we need to do this is that, otherwise, | |
736 // these regions would look empty and this will confuse parts of | |
737 // G1. For example, the code that looks for a consecutive number | |
738 // of empty regions will consider them empty and try to | |
739 // re-allocate them. We can extend is_empty() to also include | |
740 // !continuesHumongous(), but it is easier to just update the top | |
741 // fields here. The way we set top for all regions (i.e., top == | |
742 // end for all regions but the last one, top == new_top for the | |
743 // last one) is actually used when we will free up the humongous | |
744 // region in free_humongous_region(). | |
745 hr = NULL; | |
3766 | 746 for (size_t i = first + 1; i < last; ++i) { |
747 hr = region_at(i); | |
2361 | 748 if ((i + 1) == last) { |
749 // last continues humongous region | |
750 assert(hr->bottom() < new_top && new_top <= hr->end(), | |
751 "new_top should fall on this region"); | |
752 hr->set_top(new_top); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
753 _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top); |
2361 | 754 } else { |
755 // not last one | |
756 assert(new_top > hr->end(), "new_top should be above this region"); | |
757 hr->set_top(hr->end()); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
758 _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end()); |
2361 | 759 } |
760 } | |
761 // If we have continues humongous regions (hr != NULL), then the | |
762 // end of the last one should match new_end and its top should | |
763 // match new_top. | |
764 assert(hr == NULL || | |
765 (hr->end() == new_end && hr->top() == new_top), "sanity"); | |
766 | |
767 assert(first_hr->used() == word_size * HeapWordSize, "invariant"); | |
768 _summary_bytes_used += first_hr->used(); | |
769 _humongous_set.add(first_hr); | |
770 | |
771 return new_obj; | |
772 } | |
773 | |
342 | 774 // If could fit into free regions w/o expansion, try. |
775 // Otherwise, if can expand, do so. | |
776 // Otherwise, if using ex regions might help, try with ex given back. | |
1973 | 777 HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) { |
2152 | 778 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); |
779 | |
780 verify_region_sets_optional(); | |
342 | 781 |
782 size_t num_regions = | |
1973 | 783 round_to(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords; |
342 | 784 size_t x_size = expansion_regions(); |
3766 | 785 size_t fs = _hrs.free_suffix(); |
786 size_t first = humongous_obj_allocate_find_first(num_regions, word_size); | |
787 if (first == G1_NULL_HRS_INDEX) { | |
2152 | 788 // The only thing we can do now is attempt expansion. |
342 | 789 if (fs + x_size >= num_regions) { |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
790 // 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
|
791 // 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
|
792 // 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
|
793 // should have succeeded and we wouldn't be here. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
794 // |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
795 // 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
|
796 // 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
|
797 // room available. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
798 assert(num_regions > fs, "earlier allocation should have succeeded"); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
799 |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
800 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
801 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
802 ergo_format_reason("humongous allocation request failed") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
803 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
804 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
805 if (expand((num_regions - fs) * HeapRegion::GrainBytes)) { |
3766 | 806 // Even though the heap was expanded, it might not have |
807 // reached the desired size. So, we cannot assume that the | |
808 // allocation will succeed. | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
809 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
|
810 } |
2152 | 811 } |
812 } | |
813 | |
2361 | 814 HeapWord* result = NULL; |
3766 | 815 if (first != G1_NULL_HRS_INDEX) { |
2361 | 816 result = |
817 humongous_obj_allocate_initialize_regions(first, num_regions, word_size); | |
818 assert(result != NULL, "it should always return a valid result"); | |
2152 | 819 } |
820 | |
821 verify_region_sets_optional(); | |
2361 | 822 |
823 return result; | |
342 | 824 } |
825 | |
1973 | 826 HeapWord* G1CollectedHeap::allocate_new_tlab(size_t word_size) { |
827 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
|
828 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
|
829 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
830 unsigned int dummy_gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
831 return attempt_allocation(word_size, &dummy_gc_count_before); |
342 | 832 } |
833 | |
834 HeapWord* | |
835 G1CollectedHeap::mem_allocate(size_t word_size, | |
1973 | 836 bool* gc_overhead_limit_was_exceeded) { |
837 assert_heap_not_locked_and_not_at_safepoint(); | |
342 | 838 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
839 // Loop until the allocation is satisified, or unsatisfied after GC. |
1973 | 840 for (int try_count = 1; /* we'll return */; try_count += 1) { |
841 unsigned int gc_count_before; | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
842 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
843 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
844 if (!isHumongous(word_size)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
845 result = attempt_allocation(word_size, &gc_count_before); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
846 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
847 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
|
848 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
849 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
850 return result; |
342 | 851 } |
852 | |
853 // Create the garbage collection operation... | |
1973 | 854 VM_G1CollectForAllocation op(gc_count_before, word_size); |
342 | 855 // ...and get the VM thread to execute it. |
856 VMThread::execute(&op); | |
1973 | 857 |
858 if (op.prologue_succeeded() && op.pause_succeeded()) { | |
859 // If the operation was successful we'll return the result even | |
860 // if it is NULL. If the allocation attempt failed immediately | |
861 // after a Full GC, it's unlikely we'll be able to allocate now. | |
862 HeapWord* result = op.result(); | |
863 if (result != NULL && !isHumongous(word_size)) { | |
864 // Allocations that take place on VM operations do not do any | |
865 // card dirtying and we have to do it here. We only have to do | |
866 // this for non-humongous allocations, though. | |
867 dirty_young_block(result, word_size); | |
868 } | |
342 | 869 return result; |
1973 | 870 } else { |
871 assert(op.result() == NULL, | |
872 "the result should be NULL if the VM op did not succeed"); | |
342 | 873 } |
874 | |
875 // Give a warning if we seem to be looping forever. | |
876 if ((QueuedAllocationWarningCount > 0) && | |
877 (try_count % QueuedAllocationWarningCount == 0)) { | |
1973 | 878 warning("G1CollectedHeap::mem_allocate retries %d times", try_count); |
342 | 879 } |
880 } | |
1973 | 881 |
882 ShouldNotReachHere(); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
883 return NULL; |
342 | 884 } |
885 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
886 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
|
887 unsigned int *gc_count_before_ret) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
888 // 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
|
889 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
890 assert_heap_not_locked_and_not_at_safepoint(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
891 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
|
892 "be called for humongous allocation requests"); |
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 // 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
|
895 // (attempt_allocation()) failed to allocate. |
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 // 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
|
898 // 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
|
899 // 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
|
900 // return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
901 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
902 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
|
903 bool should_try_gc; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
904 unsigned int gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
905 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
906 { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
907 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
908 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
909 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
|
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 // 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
|
916 // 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
|
917 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
|
918 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
919 if (GC_locker::is_active_and_needs_gc()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
920 if (g1_policy()->can_expand_young_list()) { |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
921 // No need for an ergo verbose message here, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
922 // can_expand_young_list() does this when it returns true. |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
923 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
|
924 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
925 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
926 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
927 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
928 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
929 should_try_gc = false; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
930 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
931 // 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
|
932 gc_count_before = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
933 should_try_gc = true; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
934 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
935 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
936 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
937 if (should_try_gc) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
938 bool succeeded; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
939 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
|
940 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
941 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
|
942 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
943 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
944 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
945 if (succeeded) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
946 // 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
|
947 // 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
|
948 // further. We'll just return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
949 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
950 *gc_count_before_ret = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
951 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
952 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
953 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
954 GC_locker::stall_until_clear(); |
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 // 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
|
958 // 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
|
959 // 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
|
960 // allocation attempt in case another thread successfully |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
961 // 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
|
962 // 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
|
963 // 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
|
964 // iteration (after taking the Heap_lock). |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
965 result = _mutator_alloc_region.attempt_allocation(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
966 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
967 if (result != NULL ){ |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
968 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
969 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
970 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
971 // 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
|
972 if ((QueuedAllocationWarningCount > 0) && |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
973 (try_count % QueuedAllocationWarningCount == 0)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
974 warning("G1CollectedHeap::attempt_allocation_slow() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
975 "retries %d times", try_count); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
976 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
977 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
978 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
979 ShouldNotReachHere(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
980 return NULL; |
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 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
983 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
|
984 unsigned int * gc_count_before_ret) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
985 // 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
|
986 // 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
|
987 // 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
|
988 // 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
|
989 // 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
|
990 // 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
|
991 // 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
|
992 // 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
|
993 // 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
|
994 // much as possible. |
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 assert_heap_not_locked_and_not_at_safepoint(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
997 assert(isHumongous(word_size), "attempt_allocation_humongous() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
998 "should only be called for humongous allocations"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
999 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1000 // 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
|
1001 // 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
|
1002 // 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
|
1003 // return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1004 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1005 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
|
1006 bool should_try_gc; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1007 unsigned int gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1008 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1009 { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1010 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1011 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1012 // 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
|
1013 // 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
|
1014 // 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
|
1015 result = humongous_obj_allocate(word_size); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1016 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1017 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1018 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1019 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1020 if (GC_locker::is_active_and_needs_gc()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1021 should_try_gc = false; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1022 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1023 // 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
|
1024 gc_count_before = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1025 should_try_gc = true; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1026 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1027 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1028 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1029 if (should_try_gc) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1030 // 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
|
1031 // 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
|
1032 // 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
|
1033 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1034 bool succeeded; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1035 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
|
1036 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1037 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
|
1038 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1039 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1040 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1041 if (succeeded) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1042 // 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
|
1043 // 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
|
1044 // further. We'll just return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1045 MutexLockerEx x(Heap_lock); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1046 *gc_count_before_ret = SharedHeap::heap()->total_collections(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1047 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1048 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1049 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1050 GC_locker::stall_until_clear(); |
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 // 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
|
1054 // 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
|
1055 // 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
|
1056 // allocation attempt in case another thread successfully |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1057 // 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
|
1058 // warning if we seem to be looping forever. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1059 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1060 if ((QueuedAllocationWarningCount > 0) && |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1061 (try_count % QueuedAllocationWarningCount == 0)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1062 warning("G1CollectedHeap::attempt_allocation_humongous() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1063 "retries %d times", try_count); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1064 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1065 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1066 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1067 ShouldNotReachHere(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1068 return NULL; |
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 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
|
1072 bool expect_null_mutator_alloc_region) { |
2152 | 1073 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
|
1074 assert(_mutator_alloc_region.get() == NULL || |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1075 !expect_null_mutator_alloc_region, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1076 "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
|
1077 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1078 if (!isHumongous(word_size)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1079 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
|
1080 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1081 } else { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1082 return humongous_obj_allocate(word_size); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1083 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1084 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1085 ShouldNotReachHere(); |
342 | 1086 } |
1087 | |
1088 class PostMCRemSetClearClosure: public HeapRegionClosure { | |
1089 ModRefBarrierSet* _mr_bs; | |
1090 public: | |
1091 PostMCRemSetClearClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {} | |
1092 bool doHeapRegion(HeapRegion* r) { | |
1093 r->reset_gc_time_stamp(); | |
1094 if (r->continuesHumongous()) | |
1095 return false; | |
1096 HeapRegionRemSet* hrrs = r->rem_set(); | |
1097 if (hrrs != NULL) hrrs->clear(); | |
1098 // You might think here that we could clear just the cards | |
1099 // corresponding to the used region. But no: if we leave a dirty card | |
1100 // in a region we might allocate into, then it would prevent that card | |
1101 // from being enqueued, and cause it to be missed. | |
1102 // Re: the performance cost: we shouldn't be doing full GC anyway! | |
1103 _mr_bs->clear(MemRegion(r->bottom(), r->end())); | |
1104 return false; | |
1105 } | |
1106 }; | |
1107 | |
1108 | |
1109 class PostMCRemSetInvalidateClosure: public HeapRegionClosure { | |
1110 ModRefBarrierSet* _mr_bs; | |
1111 public: | |
1112 PostMCRemSetInvalidateClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {} | |
1113 bool doHeapRegion(HeapRegion* r) { | |
1114 if (r->continuesHumongous()) return false; | |
1115 if (r->used_region().word_size() != 0) { | |
1116 _mr_bs->invalidate(r->used_region(), true /*whole heap*/); | |
1117 } | |
1118 return false; | |
1119 } | |
1120 }; | |
1121 | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1122 class RebuildRSOutOfRegionClosure: public HeapRegionClosure { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1123 G1CollectedHeap* _g1h; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1124 UpdateRSOopClosure _cl; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1125 int _worker_i; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1126 public: |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1127 RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) : |
1861 | 1128 _cl(g1->g1_rem_set(), worker_i), |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1129 _worker_i(worker_i), |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1130 _g1h(g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1131 { } |
1960
878b57474103
6978187: G1: assert(ParallelGCThreads> 1 || n_yielded() == _hrrs->occupied()) strikes again
johnc
parents:
1883
diff
changeset
|
1132 |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1133 bool doHeapRegion(HeapRegion* r) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1134 if (!r->continuesHumongous()) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1135 _cl.set_from(r); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1136 r->oop_iterate(&_cl); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1137 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1138 return false; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1139 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1140 }; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1141 |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1142 class ParRebuildRSTask: public AbstractGangTask { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1143 G1CollectedHeap* _g1; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1144 public: |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1145 ParRebuildRSTask(G1CollectedHeap* g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1146 : AbstractGangTask("ParRebuildRSTask"), |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1147 _g1(g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1148 { } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1149 |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1150 void work(int i) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1151 RebuildRSOutOfRegionClosure rebuild_rs(_g1, i); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1152 _g1->heap_region_par_iterate_chunked(&rebuild_rs, i, |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1153 HeapRegion::RebuildRSClaimValue); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1154 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1155 }; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1156 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1157 class PostCompactionPrinterClosure: public HeapRegionClosure { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1158 private: |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1159 G1HRPrinter* _hr_printer; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1160 public: |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1161 bool doHeapRegion(HeapRegion* hr) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1162 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
|
1163 // We only generate output for non-empty regions. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1164 if (!hr->is_empty()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1165 if (!hr->isHumongous()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1166 _hr_printer->post_compaction(hr, G1HRPrinter::Old); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1167 } else if (hr->startsHumongous()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1168 if (hr->capacity() == (size_t) HeapRegion::GrainBytes) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1169 // single humongous region |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1170 _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1171 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1172 _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1173 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1174 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1175 assert(hr->continuesHumongous(), "only way to get here"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1176 _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1177 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1178 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1179 return false; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1180 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1181 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1182 PostCompactionPrinterClosure(G1HRPrinter* hr_printer) |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1183 : _hr_printer(hr_printer) { } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1184 }; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1185 |
1973 | 1186 bool G1CollectedHeap::do_collection(bool explicit_gc, |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1187 bool clear_all_soft_refs, |
342 | 1188 size_t word_size) { |
2152 | 1189 assert_at_safepoint(true /* should_be_vm_thread */); |
1190 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1191 if (GC_locker::check_active_before_gc()) { |
1973 | 1192 return false; |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1193 } |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1194 |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
2039
diff
changeset
|
1195 SvcGCMarker sgcm(SvcGCMarker::FULL); |
342 | 1196 ResourceMark rm; |
1197 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1198 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1199 Universe::print_heap_before_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1200 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1201 |
2152 | 1202 verify_region_sets_optional(); |
342 | 1203 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1204 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
|
1205 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
|
1206 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1207 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
|
1208 |
342 | 1209 { |
1210 IsGCActiveMark x; | |
1211 | |
1212 // Timing | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1213 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
|
1214 assert(!system_gc || explicit_gc, "invariant"); |
342 | 1215 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
1216 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1217 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
|
1218 PrintGC, true, gclog_or_tty); |
342 | 1219 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
1220 TraceCollectorStats tcs(g1mm()->full_collection_counters()); |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
3323
diff
changeset
|
1221 TraceMemoryManagerStats tms(true /* fullGC */, gc_cause()); |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1222 |
342 | 1223 double start = os::elapsedTime(); |
1224 g1_policy()->record_full_collection_start(); | |
1225 | |
2152 | 1226 wait_while_free_regions_coming(); |
2361 | 1227 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 1228 |
342 | 1229 gc_prologue(true); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1230 increment_total_collections(true /* full gc */); |
342 | 1231 |
1232 size_t g1h_prev_used = used(); | |
1233 assert(used() == recalculate_used(), "Should be equal"); | |
1234 | |
1235 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { | |
1236 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
|
1237 gclog_or_tty->print(" VerifyBeforeGC:"); |
342 | 1238 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1239 Universe::verify(/* allow dirty */ true, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1240 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1241 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1242 |
342 | 1243 } |
3869
7f776886a215
6810861: G1: support -XX:+{PrintClassHistogram,HeapDump}{Before,After}FullGC
ysr
parents:
3867
diff
changeset
|
1244 pre_full_gc_dump(); |
342 | 1245 |
1246 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
1247 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1248 // Disable discovery and empty the discovered lists |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1249 // for the CM ref processor. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1250 ref_processor_cm()->disable_discovery(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1251 ref_processor_cm()->abandon_partial_discovery(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1252 ref_processor_cm()->verify_no_references_recorded(); |
342 | 1253 |
1254 // Abandon current iterations of concurrent marking and concurrent | |
1255 // refinement, if any are in progress. | |
1256 concurrent_mark()->abort(); | |
1257 | |
1258 // 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
|
1259 release_mutator_alloc_region(); |
636 | 1260 abandon_gc_alloc_regions(); |
1861 | 1261 g1_rem_set()->cleanupHRRS(); |
342 | 1262 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
|
1263 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1264 // 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
|
1265 // 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
|
1266 // before the start GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1267 _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
|
1268 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1269 // 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
|
1270 // 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
|
1271 // 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
|
1272 // after this full GC. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1273 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
|
1274 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
|
1275 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
|
1276 |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1277 empty_young_list(); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1278 g1_policy()->set_full_young_gcs(true); |
342 | 1279 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1280 // See the comments in g1CollectedHeap.hpp and |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1281 // G1CollectedHeap::ref_processing_init() about |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
1282 // how reference processing currently works in G1. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
1283 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1284 // Temporarily make discovery by the STW ref processor single threaded (non-MT). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1285 ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), false); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1286 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1287 // Temporarily clear the STW ref processor's _is_alive_non_header field. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1288 ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1289 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1290 ref_processor_stw()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1291 ref_processor_stw()->setup_policy(do_clear_all_soft_refs); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1292 |
342 | 1293 // Do collection work |
1294 { | |
1295 HandleMark hm; // Discard invalid handles created during gc | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1296 G1MarkSweep::invoke_at_safepoint(ref_processor_stw(), do_clear_all_soft_refs); |
342 | 1297 } |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1298 |
2152 | 1299 assert(free_regions() == 0, "we should not have added any free regions"); |
342 | 1300 rebuild_region_lists(); |
1301 | |
1302 _summary_bytes_used = recalculate_used(); | |
1303 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1304 // Enqueue any discovered reference objects that have |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1305 // not been removed from the discovered lists. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1306 ref_processor_stw()->enqueue_discovered_references(); |
342 | 1307 |
1308 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | |
1309 | |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1310 MemoryService::track_memory_usage(); |
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
1311 |
342 | 1312 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { |
1313 HandleMark hm; // Discard invalid handles created during verification | |
1314 gclog_or_tty->print(" VerifyAfterGC:"); | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
1315 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1316 Universe::verify(/* allow dirty */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1317 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1318 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
1319 |
342 | 1320 } |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1321 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1322 assert(!ref_processor_stw()->discovery_enabled(), "Postcondition"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1323 ref_processor_stw()->verify_no_references_recorded(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1324 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1325 // Note: since we've just done a full GC, concurrent |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1326 // marking is no longer active. Therefore we need not |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1327 // re-enable reference discovery for the CM ref processor. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1328 // That will be done at the start of the next marking cycle. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1329 assert(!ref_processor_cm()->discovery_enabled(), "Postcondition"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1330 ref_processor_cm()->verify_no_references_recorded(); |
342 | 1331 |
1332 reset_gc_time_stamp(); | |
1333 // Since everything potentially moved, we will clear all remembered | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1334 // sets, and clear all cards. Later we will rebuild remebered |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1335 // sets. We will also reset the GC time stamps of the regions. |
342 | 1336 PostMCRemSetClearClosure rs_clear(mr_bs()); |
1337 heap_region_iterate(&rs_clear); | |
1338 | |
1339 // Resize the heap if necessary. | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1340 resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); |
342 | 1341 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1342 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1343 // 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
|
1344 // that all the COMMIT / UNCOMMIT events are generated before |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1345 // the end GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1346 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1347 PostCompactionPrinterClosure cl(hr_printer()); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1348 heap_region_iterate(&cl); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1349 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1350 _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
|
1351 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1352 |
342 | 1353 if (_cg1r->use_cache()) { |
1354 _cg1r->clear_and_record_card_counts(); | |
1355 _cg1r->clear_hot_cache(); | |
1356 } | |
1357 | |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1358 // Rebuild remembered sets of all regions. |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
1359 |
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
1360 if (G1CollectedHeap::use_parallel_gc_threads()) { |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1361 ParRebuildRSTask rebuild_rs_task(this); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1362 assert(check_heap_region_claim_values( |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1363 HeapRegion::InitialClaimValue), "sanity check"); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1364 set_par_threads(workers()->total_workers()); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1365 workers()->run_task(&rebuild_rs_task); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1366 set_par_threads(0); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1367 assert(check_heap_region_claim_values( |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1368 HeapRegion::RebuildRSClaimValue), "sanity check"); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1369 reset_heap_region_claim_values(); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1370 } else { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1371 RebuildRSOutOfRegionClosure rebuild_rs(this); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1372 heap_region_iterate(&rebuild_rs); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1373 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1374 |
342 | 1375 if (PrintGC) { |
1376 print_size_transition(gclog_or_tty, g1h_prev_used, used(), capacity()); | |
1377 } | |
1378 | |
1379 if (true) { // FIXME | |
1380 // Ask the permanent generation to adjust size for full collections | |
1381 perm()->compute_new_size(); | |
1382 } | |
1383 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1384 // 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
|
1385 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
|
1386 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
|
1387 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1388 // 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
|
1389 // 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
|
1390 // evacuation pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1391 clear_cset_fast_test(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1392 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1393 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1394 |
342 | 1395 double end = os::elapsedTime(); |
1396 g1_policy()->record_full_collection_end(); | |
1397 | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1398 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1399 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1400 #endif |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1401 |
342 | 1402 gc_epilogue(true); |
1403 | |
794 | 1404 // Discard all rset updates |
1405 JavaThread::dirty_card_queue_set().abandon_logs(); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
1406 assert(!G1DeferredRSUpdate |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
1407 || (G1DeferredRSUpdate && (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any"); |
342 | 1408 } |
1409 | |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1410 _young_list->reset_sampled_info(); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1411 // At this point there should be no regions in the |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1412 // entire heap tagged as young. |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1413 assert( check_young_list_empty(true /* check_heap */), |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
1414 "young list should be empty at this point"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1415 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1416 // 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
|
1417 increment_full_collections_completed(false /* concurrent */); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1418 |
3766 | 1419 _hrs.verify_optional(); |
2152 | 1420 verify_region_sets_optional(); |
1421 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1422 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1423 Universe::print_heap_after_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1424 } |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
1425 g1mm()->update_counters(); |
3869
7f776886a215
6810861: G1: support -XX:+{PrintClassHistogram,HeapDump}{Before,After}FullGC
ysr
parents:
3867
diff
changeset
|
1426 post_full_gc_dump(); |
1973 | 1427 |
1428 return true; | |
342 | 1429 } |
1430 | |
1431 void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { | |
1973 | 1432 // do_collection() will return whether it succeeded in performing |
1433 // the GC. Currently, there is no facility on the | |
1434 // do_full_collection() API to notify the caller than the collection | |
1435 // did not succeed (e.g., because it was locked out by the GC | |
1436 // locker). So, right now, we'll ignore the return value. | |
1437 bool dummy = do_collection(true, /* explicit_gc */ | |
1438 clear_all_soft_refs, | |
1439 0 /* word_size */); | |
342 | 1440 } |
1441 | |
1442 // This code is mostly copied from TenuredGeneration. | |
1443 void | |
1444 G1CollectedHeap:: | |
1445 resize_if_necessary_after_full_collection(size_t word_size) { | |
1446 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, "sanity check"); | |
1447 | |
1448 // Include the current allocation, if any, and bytes that will be | |
1449 // pre-allocated to support collections, as "used". | |
1450 const size_t used_after_gc = used(); | |
1451 const size_t capacity_after_gc = capacity(); | |
1452 const size_t free_after_gc = capacity_after_gc - used_after_gc; | |
1453 | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1454 // This is enforced in arguments.cpp. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1455 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1456 "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
|
1457 |
342 | 1458 // 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
|
1459 const double minimum_free_percentage = (double) MinHeapFreeRatio / 100.0; |
342 | 1460 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
|
1461 const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100.0; |
342 | 1462 const double minimum_used_percentage = 1.0 - maximum_free_percentage; |
1463 | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1464 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
|
1465 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
|
1466 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1467 // 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
|
1468 // 32-bit size_t's. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1469 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
|
1470 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
|
1471 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
|
1472 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1473 // 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
|
1474 // 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
|
1475 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
|
1476 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
|
1477 desired_capacity_upper_bound); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1478 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
|
1479 desired_capacity_upper_bound); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1480 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1481 // 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
|
1482 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
|
1483 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
|
1484 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1485 // 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
|
1486 // 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
|
1487 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
|
1488 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
|
1489 "maximum_desired_capacity = "SIZE_FORMAT, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1490 minimum_desired_capacity, maximum_desired_capacity)); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1491 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1492 // 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
|
1493 // 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
|
1494 // 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
|
1495 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
|
1496 // 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
|
1497 // 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
|
1498 // 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
|
1499 maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size); |
342 | 1500 |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1501 if (capacity_after_gc < minimum_desired_capacity) { |
342 | 1502 // Don't expand unless it's significant |
1503 size_t expand_bytes = minimum_desired_capacity - capacity_after_gc; | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1504 ergo_verbose4(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1505 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1506 ergo_format_reason("capacity lower than " |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1507 "min desired capacity after Full GC") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1508 ergo_format_byte("capacity") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1509 ergo_format_byte("occupancy") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1510 ergo_format_byte_perc("min desired capacity"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1511 capacity_after_gc, used_after_gc, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1512 minimum_desired_capacity, (double) MinHeapFreeRatio); |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1513 expand(expand_bytes); |
342 | 1514 |
1515 // 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
|
1516 } else if (capacity_after_gc > maximum_desired_capacity) { |
342 | 1517 // Capacity too large, compute shrinking size |
1518 size_t shrink_bytes = capacity_after_gc - maximum_desired_capacity; | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1519 ergo_verbose4(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1520 "attempt heap shrinking", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1521 ergo_format_reason("capacity higher than " |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1522 "max desired capacity after Full GC") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1523 ergo_format_byte("capacity") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1524 ergo_format_byte("occupancy") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1525 ergo_format_byte_perc("max desired capacity"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1526 capacity_after_gc, used_after_gc, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1527 maximum_desired_capacity, (double) MaxHeapFreeRatio); |
342 | 1528 shrink(shrink_bytes); |
1529 } | |
1530 } | |
1531 | |
1532 | |
1533 HeapWord* | |
1973 | 1534 G1CollectedHeap::satisfy_failed_allocation(size_t word_size, |
1535 bool* succeeded) { | |
2152 | 1536 assert_at_safepoint(true /* should_be_vm_thread */); |
1973 | 1537 |
1538 *succeeded = true; | |
1539 // Let's attempt the allocation first. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1540 HeapWord* result = |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1541 attempt_allocation_at_safepoint(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1542 false /* expect_null_mutator_alloc_region */); |
1973 | 1543 if (result != NULL) { |
1544 assert(*succeeded, "sanity"); | |
1545 return result; | |
1546 } | |
342 | 1547 |
1548 // In a G1 heap, we're supposed to keep allocation from failing by | |
1549 // incremental pauses. Therefore, at least for now, we'll favor | |
1550 // expansion over collection. (This might change in the future if we can | |
1551 // do something smarter than full collection to satisfy a failed alloc.) | |
1552 result = expand_and_allocate(word_size); | |
1553 if (result != NULL) { | |
1973 | 1554 assert(*succeeded, "sanity"); |
342 | 1555 return result; |
1556 } | |
1557 | |
1973 | 1558 // Expansion didn't work, we'll try to do a Full GC. |
1559 bool gc_succeeded = do_collection(false, /* explicit_gc */ | |
1560 false, /* clear_all_soft_refs */ | |
1561 word_size); | |
1562 if (!gc_succeeded) { | |
1563 *succeeded = false; | |
1564 return NULL; | |
1565 } | |
1566 | |
1567 // Retry the allocation | |
1568 result = attempt_allocation_at_safepoint(word_size, | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1569 true /* expect_null_mutator_alloc_region */); |
342 | 1570 if (result != NULL) { |
1973 | 1571 assert(*succeeded, "sanity"); |
342 | 1572 return result; |
1573 } | |
1574 | |
1973 | 1575 // Then, try a Full GC that will collect all soft references. |
1576 gc_succeeded = do_collection(false, /* explicit_gc */ | |
1577 true, /* clear_all_soft_refs */ | |
1578 word_size); | |
1579 if (!gc_succeeded) { | |
1580 *succeeded = false; | |
1581 return NULL; | |
1582 } | |
1583 | |
1584 // Retry the allocation once more | |
1585 result = attempt_allocation_at_safepoint(word_size, | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1586 true /* expect_null_mutator_alloc_region */); |
342 | 1587 if (result != NULL) { |
1973 | 1588 assert(*succeeded, "sanity"); |
342 | 1589 return result; |
1590 } | |
1591 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1592 assert(!collector_policy()->should_clear_all_soft_refs(), |
1973 | 1593 "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
|
1594 |
342 | 1595 // What else? We might try synchronous finalization later. If the total |
1596 // space available is large enough for the allocation, then a more | |
1597 // complete compaction phase than we've tried so far might be | |
1598 // appropriate. | |
1973 | 1599 assert(*succeeded, "sanity"); |
342 | 1600 return NULL; |
1601 } | |
1602 | |
1603 // Attempting to expand the heap sufficiently | |
1604 // to support an allocation of the given "word_size". If | |
1605 // successful, perform the allocation and return the address of the | |
1606 // allocated block, or else "NULL". | |
1607 | |
1608 HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size) { | |
2152 | 1609 assert_at_safepoint(true /* should_be_vm_thread */); |
1610 | |
1611 verify_region_sets_optional(); | |
1973 | 1612 |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1613 size_t expand_bytes = MAX2(word_size * HeapWordSize, MinHeapDeltaBytes); |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1614 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1615 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1616 ergo_format_reason("allocation request failed") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1617 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1618 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1619 if (expand(expand_bytes)) { |
3766 | 1620 _hrs.verify_optional(); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1621 verify_region_sets_optional(); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1622 return attempt_allocation_at_safepoint(word_size, |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1623 false /* expect_null_mutator_alloc_region */); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1624 } |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1625 return NULL; |
342 | 1626 } |
1627 | |
3766 | 1628 void G1CollectedHeap::update_committed_space(HeapWord* old_end, |
1629 HeapWord* new_end) { | |
1630 assert(old_end != new_end, "don't call this otherwise"); | |
1631 assert((HeapWord*) _g1_storage.high() == new_end, "invariant"); | |
1632 | |
1633 // Update the committed mem region. | |
1634 _g1_committed.set_end(new_end); | |
1635 // Tell the card table about the update. | |
1636 Universe::heap()->barrier_set()->resize_covered_region(_g1_committed); | |
1637 // Tell the BOT about the update. | |
1638 _bot_shared->resize(_g1_committed.word_size()); | |
1639 } | |
1640 | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1641 bool G1CollectedHeap::expand(size_t expand_bytes) { |
342 | 1642 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
|
1643 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); |
342 | 1644 aligned_expand_bytes = align_size_up(aligned_expand_bytes, |
1645 HeapRegion::GrainBytes); | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1646 ergo_verbose2(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1647 "expand the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1648 ergo_format_byte("requested expansion amount") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1649 ergo_format_byte("attempted expansion amount"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1650 expand_bytes, aligned_expand_bytes); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1651 |
3766 | 1652 // First commit the memory. |
1653 HeapWord* old_end = (HeapWord*) _g1_storage.high(); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1654 bool successful = _g1_storage.expand_by(aligned_expand_bytes); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1655 if (successful) { |
3766 | 1656 // Then propagate this update to the necessary data structures. |
1657 HeapWord* new_end = (HeapWord*) _g1_storage.high(); | |
1658 update_committed_space(old_end, new_end); | |
1659 | |
1660 FreeRegionList expansion_list("Local Expansion List"); | |
1661 MemRegion mr = _hrs.expand_by(old_end, new_end, &expansion_list); | |
1662 assert(mr.start() == old_end, "post-condition"); | |
1663 // mr might be a smaller region than what was requested if | |
1664 // expand_by() was unable to allocate the HeapRegion instances | |
1665 assert(mr.end() <= new_end, "post-condition"); | |
1666 | |
1667 size_t actual_expand_bytes = mr.byte_size(); | |
1668 assert(actual_expand_bytes <= aligned_expand_bytes, "post-condition"); | |
1669 assert(actual_expand_bytes == expansion_list.total_capacity_bytes(), | |
1670 "post-condition"); | |
1671 if (actual_expand_bytes < aligned_expand_bytes) { | |
1672 // We could not expand _hrs to the desired size. In this case we | |
1673 // need to shrink the committed space accordingly. | |
1674 assert(mr.end() < new_end, "invariant"); | |
1675 | |
1676 size_t diff_bytes = aligned_expand_bytes - actual_expand_bytes; | |
1677 // First uncommit the memory. | |
1678 _g1_storage.shrink_by(diff_bytes); | |
1679 // Then propagate this update to the necessary data structures. | |
1680 update_committed_space(new_end, mr.end()); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1681 } |
3766 | 1682 _free_list.add_as_tail(&expansion_list); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1683 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1684 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1685 HeapWord* curr = mr.start(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1686 while (curr < mr.end()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1687 HeapWord* curr_end = curr + HeapRegion::GrainWords; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1688 _hr_printer.commit(curr, curr_end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1689 curr = curr_end; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1690 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1691 assert(curr == mr.end(), "post-condition"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1692 } |
3920
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
1693 g1_policy()->record_new_heap_size(n_regions()); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1694 } else { |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1695 ergo_verbose0(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1696 "did not expand the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1697 ergo_format_reason("heap expansion operation failed")); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1698 // The expansion of the virtual storage space was unsuccessful. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1699 // 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
|
1700 if (G1ExitOnExpansionFailure && |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1701 _g1_storage.uncommitted_size() >= aligned_expand_bytes) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1702 // We had head room... |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1703 vm_exit_out_of_memory(aligned_expand_bytes, "G1 heap expansion"); |
342 | 1704 } |
1705 } | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1706 return successful; |
342 | 1707 } |
1708 | |
3766 | 1709 void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { |
342 | 1710 size_t old_mem_size = _g1_storage.committed_size(); |
1711 size_t aligned_shrink_bytes = | |
1712 ReservedSpace::page_align_size_down(shrink_bytes); | |
1713 aligned_shrink_bytes = align_size_down(aligned_shrink_bytes, | |
1714 HeapRegion::GrainBytes); | |
1715 size_t num_regions_deleted = 0; | |
3766 | 1716 MemRegion mr = _hrs.shrink_by(aligned_shrink_bytes, &num_regions_deleted); |
1717 HeapWord* old_end = (HeapWord*) _g1_storage.high(); | |
1718 assert(mr.end() == old_end, "post-condition"); | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1719 |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1720 ergo_verbose3(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1721 "shrink the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1722 ergo_format_byte("requested shrinking amount") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1723 ergo_format_byte("aligned shrinking amount") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1724 ergo_format_byte("attempted shrinking amount"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1725 shrink_bytes, aligned_shrink_bytes, mr.byte_size()); |
3766 | 1726 if (mr.byte_size() > 0) { |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1727 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1728 HeapWord* curr = mr.end(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1729 while (curr > mr.start()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1730 HeapWord* curr_end = curr; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1731 curr -= HeapRegion::GrainWords; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1732 _hr_printer.uncommit(curr, curr_end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1733 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1734 assert(curr == mr.start(), "post-condition"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1735 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1736 |
342 | 1737 _g1_storage.shrink_by(mr.byte_size()); |
3766 | 1738 HeapWord* new_end = (HeapWord*) _g1_storage.high(); |
1739 assert(mr.start() == new_end, "post-condition"); | |
1740 | |
1741 _expansion_regions += num_regions_deleted; | |
1742 update_committed_space(old_end, new_end); | |
1743 HeapRegionRemSet::shrink_heap(n_regions()); | |
3920
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
1744 g1_policy()->record_new_heap_size(n_regions()); |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1745 } else { |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1746 ergo_verbose0(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1747 "did not shrink the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1748 ergo_format_reason("heap shrinking operation failed")); |
342 | 1749 } |
1750 } | |
1751 | |
1752 void G1CollectedHeap::shrink(size_t shrink_bytes) { | |
2152 | 1753 verify_region_sets_optional(); |
1754 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1755 // 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
|
1756 // 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
|
1757 // 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
|
1758 abandon_gc_alloc_regions(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1759 |
2152 | 1760 // Instead of tearing down / rebuilding the free lists here, we |
1761 // could instead use the remove_all_pending() method on free_list to | |
1762 // remove only the ones that we need to remove. | |
342 | 1763 tear_down_region_lists(); // We will rebuild them in a moment. |
1764 shrink_helper(shrink_bytes); | |
1765 rebuild_region_lists(); | |
2152 | 1766 |
3766 | 1767 _hrs.verify_optional(); |
2152 | 1768 verify_region_sets_optional(); |
342 | 1769 } |
1770 | |
1771 // Public methods. | |
1772 | |
1773 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
1774 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
1775 #endif // _MSC_VER | |
1776 | |
1777 | |
1778 G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) : | |
1779 SharedHeap(policy_), | |
1780 _g1_policy(policy_), | |
1111 | 1781 _dirty_card_queue_set(false), |
1705 | 1782 _into_cset_dirty_card_queue_set(false), |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1783 _is_alive_closure_cm(this), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1784 _is_alive_closure_stw(this), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1785 _ref_processor_cm(NULL), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1786 _ref_processor_stw(NULL), |
342 | 1787 _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)), |
1788 _bot_shared(NULL), | |
1789 _objs_with_preserved_marks(NULL), _preserved_marks_of_objs(NULL), | |
1790 _evac_failure_scan_stack(NULL) , | |
1791 _mark_in_progress(false), | |
2152 | 1792 _cg1r(NULL), _summary_bytes_used(0), |
342 | 1793 _refine_cte_cl(NULL), |
1794 _full_collection(false), | |
2152 | 1795 _free_list("Master Free List"), |
1796 _secondary_free_list("Secondary Free List"), | |
1797 _humongous_set("Master Humongous Set"), | |
1798 _free_regions_coming(false), | |
342 | 1799 _young_list(new YoungList(this)), |
1800 _gc_time_stamp(0), | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1801 _retained_old_gc_alloc_region(NULL), |
526 | 1802 _surviving_young_words(NULL), |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1803 _full_collections_completed(0), |
526 | 1804 _in_cset_fast_test(NULL), |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
1805 _in_cset_fast_test_base(NULL), |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
1806 _dirty_cards_region_list(NULL) { |
342 | 1807 _g1h = this; // To catch bugs. |
1808 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { | |
1809 vm_exit_during_initialization("Failed necessary allocation."); | |
1810 } | |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1811 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1812 _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1813 |
342 | 1814 int n_queues = MAX2((int)ParallelGCThreads, 1); |
1815 _task_queues = new RefToScanQueueSet(n_queues); | |
1816 | |
1817 int n_rem_sets = HeapRegionRemSet::num_par_rem_sets(); | |
1818 assert(n_rem_sets > 0, "Invariant."); | |
1819 | |
1820 HeapRegionRemSetIterator** iter_arr = | |
1821 NEW_C_HEAP_ARRAY(HeapRegionRemSetIterator*, n_queues); | |
1822 for (int i = 0; i < n_queues; i++) { | |
1823 iter_arr[i] = new HeapRegionRemSetIterator(); | |
1824 } | |
1825 _rem_set_iterator = iter_arr; | |
1826 | |
1827 for (int i = 0; i < n_queues; i++) { | |
1828 RefToScanQueue* q = new RefToScanQueue(); | |
1829 q->initialize(); | |
1830 _task_queues->register_queue(i, q); | |
1831 } | |
1832 | |
1833 guarantee(_task_queues != NULL, "task_queues allocation failure."); | |
1834 } | |
1835 | |
1836 jint G1CollectedHeap::initialize() { | |
1166 | 1837 CollectedHeap::pre_initialize(); |
342 | 1838 os::enable_vtime(); |
1839 | |
1840 // Necessary to satisfy locking discipline assertions. | |
1841 | |
1842 MutexLocker x(Heap_lock); | |
1843 | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1844 // 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
|
1845 // it will be used then. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1846 _hr_printer.set_active(G1PrintHeapRegions); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1847 |
342 | 1848 // While there are no constraints in the GC code that HeapWordSize |
1849 // be any particular value, there are multiple other areas in the | |
1850 // system which believe this to be true (e.g. oop->object_size in some | |
1851 // cases incorrectly returns the size in wordSize units rather than | |
1852 // HeapWordSize). | |
1853 guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize"); | |
1854 | |
1855 size_t init_byte_size = collector_policy()->initial_heap_byte_size(); | |
1856 size_t max_byte_size = collector_policy()->max_heap_byte_size(); | |
1857 | |
1858 // Ensure that the sizes are properly aligned. | |
1859 Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap"); | |
1860 Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap"); | |
1861 | |
1862 _cg1r = new ConcurrentG1Refine(); | |
1863 | |
1864 // Reserve the maximum. | |
1865 PermanentGenerationSpec* pgs = collector_policy()->permanent_generation(); | |
1866 // Includes the perm-gen. | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1867 |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1868 // When compressed oops are enabled, the preferred heap base |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1869 // is calculated by subtracting the requested size from the |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1870 // 32Gb boundary and using the result as the base address for |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1871 // heap reservation. If the requested size is not aligned to |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1872 // HeapRegion::GrainBytes (i.e. the alignment that is passed |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1873 // into the ReservedHeapSpace constructor) then the actual |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1874 // base of the reserved heap may end up differing from the |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1875 // address that was requested (i.e. the preferred heap base). |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1876 // 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
|
1877 // compressed oops mode. |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1878 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1879 // 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
|
1880 // 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
|
1881 const size_t total_reserved = max_byte_size + |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1882 align_size_up(pgs->max_size(), HeapRegion::GrainBytes); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1883 Universe::check_alignment(total_reserved, HeapRegion::GrainBytes, "g1 heap and perm"); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1884 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1885 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
|
1886 |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1887 ReservedHeapSpace heap_rs(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1888 UseLargePages, addr); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1889 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1890 if (UseCompressedOops) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1891 if (addr != NULL && !heap_rs.is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1892 // 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
|
1893 // 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
|
1894 // Try again to reserver heap higher. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1895 addr = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop); |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1896 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1897 ReservedHeapSpace heap_rs0(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1898 UseLargePages, addr); |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1899 |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1900 if (addr != NULL && !heap_rs0.is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1901 // 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
|
1902 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
|
1903 assert(addr == NULL, ""); |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1904 |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1905 ReservedHeapSpace heap_rs1(total_reserved, HeapRegion::GrainBytes, |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
1906 UseLargePages, addr); |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1907 heap_rs = heap_rs1; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1908 } else { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1909 heap_rs = heap_rs0; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
1910 } |
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 } |
342 | 1913 |
1914 if (!heap_rs.is_reserved()) { | |
1915 vm_exit_during_initialization("Could not reserve enough space for object heap"); | |
1916 return JNI_ENOMEM; | |
1917 } | |
1918 | |
1919 // It is important to do this in a way such that concurrent readers can't | |
1920 // temporarily think somethings in the heap. (I've actually seen this | |
1921 // happen in asserts: DLD.) | |
1922 _reserved.set_word_size(0); | |
1923 _reserved.set_start((HeapWord*)heap_rs.base()); | |
1924 _reserved.set_end((HeapWord*)(heap_rs.base() + heap_rs.size())); | |
1925 | |
1926 _expansion_regions = max_byte_size/HeapRegion::GrainBytes; | |
1927 | |
1928 // Create the gen rem set (and barrier set) for the entire reserved region. | |
1929 _rem_set = collector_policy()->create_rem_set(_reserved, 2); | |
1930 set_barrier_set(rem_set()->bs()); | |
1931 if (barrier_set()->is_a(BarrierSet::ModRef)) { | |
1932 _mr_bs = (ModRefBarrierSet*)_barrier_set; | |
1933 } else { | |
1934 vm_exit_during_initialization("G1 requires a mod ref bs."); | |
1935 return JNI_ENOMEM; | |
1936 } | |
1937 | |
1938 // Also create a G1 rem set. | |
1861 | 1939 if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { |
1940 _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs()); | |
342 | 1941 } else { |
1861 | 1942 vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); |
1943 return JNI_ENOMEM; | |
342 | 1944 } |
1945 | |
1946 // Carve out the G1 part of the heap. | |
1947 | |
1948 ReservedSpace g1_rs = heap_rs.first_part(max_byte_size); | |
1949 _g1_reserved = MemRegion((HeapWord*)g1_rs.base(), | |
1950 g1_rs.size()/HeapWordSize); | |
1951 ReservedSpace perm_gen_rs = heap_rs.last_part(max_byte_size); | |
1952 | |
1953 _perm_gen = pgs->init(perm_gen_rs, pgs->init_size(), rem_set()); | |
1954 | |
1955 _g1_storage.initialize(g1_rs, 0); | |
1956 _g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0); | |
3766 | 1957 _hrs.initialize((HeapWord*) _g1_reserved.start(), |
1958 (HeapWord*) _g1_reserved.end(), | |
1959 _expansion_regions); | |
342 | 1960 |
807
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1961 // 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
|
1962 // in the remembered set structures. |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1963 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
|
1964 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
|
1965 |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
1966 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
|
1967 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
|
1968 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
|
1969 "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
|
1970 |
2152 | 1971 HeapRegionSet::set_unrealistically_long_length(max_regions() + 1); |
1972 | |
342 | 1973 _bot_shared = new G1BlockOffsetSharedArray(_reserved, |
1974 heap_word_size(init_byte_size)); | |
1975 | |
1976 _g1h = this; | |
1977 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1978 _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
|
1979 _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
|
1980 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1981 // 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
|
1982 // 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
|
1983 // 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
|
1984 _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
|
1985 ((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
|
1986 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1987 // 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
|
1988 // 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
|
1989 // evacuation pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1990 clear_cset_fast_test(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
1991 |
342 | 1992 // Create the ConcurrentMark data structure and thread. |
1993 // (Must do this late, so that "max_regions" is defined.) | |
1994 _cm = new ConcurrentMark(heap_rs, (int) max_regions()); | |
1995 _cmThread = _cm->cmThread(); | |
1996 | |
1997 // Initialize the from_card cache structure of HeapRegionRemSet. | |
1998 HeapRegionRemSet::init_heap(max_regions()); | |
1999 | |
677 | 2000 // Now expand into the initial heap size. |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2001 if (!expand(init_byte_size)) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2002 vm_exit_during_initialization("Failed to allocate initial heap."); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2003 return JNI_ENOMEM; |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2004 } |
342 | 2005 |
2006 // Perform any initialization actions delegated to the policy. | |
2007 g1_policy()->init(); | |
2008 | |
2009 g1_policy()->note_start_of_mark_thread(); | |
2010 | |
2011 _refine_cte_cl = | |
2012 new RefineCardTableEntryClosure(ConcurrentG1RefineThread::sts(), | |
2013 g1_rem_set(), | |
2014 concurrent_g1_refine()); | |
2015 JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); | |
2016 | |
2017 JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon, | |
2018 SATB_Q_FL_lock, | |
1111 | 2019 G1SATBProcessCompletedThreshold, |
342 | 2020 Shared_SATB_Q_lock); |
794 | 2021 |
2022 JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, | |
2023 DirtyCardQ_FL_lock, | |
1111 | 2024 concurrent_g1_refine()->yellow_zone(), |
2025 concurrent_g1_refine()->red_zone(), | |
794 | 2026 Shared_DirtyCardQ_lock); |
2027 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2028 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2029 dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2030 DirtyCardQ_FL_lock, |
1111 | 2031 -1, // never trigger processing |
2032 -1, // no limit on length | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2033 Shared_DirtyCardQ_lock, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2034 &JavaThread::dirty_card_queue_set()); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2035 } |
1705 | 2036 |
2037 // Initialize the card queue set used to hold cards containing | |
2038 // references into the collection set. | |
2039 _into_cset_dirty_card_queue_set.initialize(DirtyCardQ_CBL_mon, | |
2040 DirtyCardQ_FL_lock, | |
2041 -1, // never trigger processing | |
2042 -1, // no limit on length | |
2043 Shared_DirtyCardQ_lock, | |
2044 &JavaThread::dirty_card_queue_set()); | |
2045 | |
342 | 2046 // In case we're keeping closure specialization stats, initialize those |
2047 // counts and that mechanism. | |
2048 SpecializationStats::clear(); | |
2049 | |
2050 // Do later initialization work for concurrent refinement. | |
2051 _cg1r->init(); | |
2052 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2053 // 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
|
2054 // 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
|
2055 // space here, lots of asserts fire. |
3766 | 2056 |
2057 HeapRegion* dummy_region = new_heap_region(0 /* index of bottom region */, | |
2058 _g1_reserved.start()); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2059 // 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
|
2060 // 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
|
2061 // 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
|
2062 // 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
|
2063 dummy_region->set_young(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2064 // Make sure it's full. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2065 dummy_region->set_top(dummy_region->end()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2066 G1AllocRegion::setup(this, dummy_region); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2067 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2068 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2069 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2070 // 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
|
2071 // values in the heap have been properly initialized. |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2072 _g1mm = new G1MonitoringSupport(this, &_g1_storage); |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2073 |
342 | 2074 return JNI_OK; |
2075 } | |
2076 | |
2077 void G1CollectedHeap::ref_processing_init() { | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2078 // Reference processing in G1 currently works as follows: |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2079 // |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2080 // * There are two reference processor instances. One is |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2081 // used to record and process discovered references |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2082 // during concurrent marking; the other is used to |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2083 // record and process references during STW pauses |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2084 // (both full and incremental). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2085 // * Both ref processors need to 'span' the entire heap as |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2086 // the regions in the collection set may be dotted around. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2087 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2088 // * For the concurrent marking ref processor: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2089 // * Reference discovery is enabled at initial marking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2090 // * Reference discovery is disabled and the discovered |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2091 // references processed etc during remarking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2092 // * Reference discovery is MT (see below). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2093 // * Reference discovery requires a barrier (see below). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2094 // * Reference processing may or may not be MT |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2095 // (depending on the value of ParallelRefProcEnabled |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2096 // and ParallelGCThreads). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2097 // * A full GC disables reference discovery by the CM |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2098 // ref processor and abandons any entries on it's |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2099 // discovered lists. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2100 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2101 // * For the STW processor: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2102 // * Non MT discovery is enabled at the start of a full GC. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2103 // * Processing and enqueueing during a full GC is non-MT. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2104 // * During a full GC, references are processed after marking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2105 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2106 // * Discovery (may or may not be MT) is enabled at the start |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2107 // of an incremental evacuation pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2108 // * References are processed near the end of a STW evacuation pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2109 // * For both types of GC: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2110 // * Discovery is atomic - i.e. not concurrent. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2111 // * Reference discovery will not need a barrier. |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2112 |
342 | 2113 SharedHeap::ref_processing_init(); |
2114 MemRegion mr = reserved_region(); | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2115 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2116 // Concurrent Mark ref processor |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2117 _ref_processor_cm = |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2118 new ReferenceProcessor(mr, // span |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2119 ParallelRefProcEnabled && (ParallelGCThreads > 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2120 // mt processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2121 (int) ParallelGCThreads, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2122 // degree of mt processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2123 (ParallelGCThreads > 1) || (ConcGCThreads > 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2124 // mt discovery |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2125 (int) MAX2(ParallelGCThreads, ConcGCThreads), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2126 // degree of mt discovery |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2127 false, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2128 // Reference discovery is not atomic |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2129 &_is_alive_closure_cm, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2130 // is alive closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2131 // (for efficiency/performance) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2132 true); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2133 // Setting next fields of discovered |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2134 // lists requires a barrier. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2135 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2136 // STW ref processor |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2137 _ref_processor_stw = |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2138 new ReferenceProcessor(mr, // span |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2139 ParallelRefProcEnabled && (ParallelGCThreads > 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2140 // mt processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2141 MAX2((int)ParallelGCThreads, 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2142 // degree of mt processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2143 (ParallelGCThreads > 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2144 // mt discovery |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2145 MAX2((int)ParallelGCThreads, 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2146 // degree of mt discovery |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2147 true, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2148 // Reference discovery is atomic |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2149 &_is_alive_closure_stw, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2150 // is alive closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2151 // (for efficiency/performance) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2152 false); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2153 // Setting next fields of discovered |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2154 // lists requires a barrier. |
342 | 2155 } |
2156 | |
2157 size_t G1CollectedHeap::capacity() const { | |
2158 return _g1_committed.byte_size(); | |
2159 } | |
2160 | |
1705 | 2161 void G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure* cl, |
2162 DirtyCardQueue* into_cset_dcq, | |
2163 bool concurrent, | |
342 | 2164 int worker_i) { |
889 | 2165 // Clean cards in the hot card cache |
1705 | 2166 concurrent_g1_refine()->clean_up_cache(worker_i, g1_rem_set(), into_cset_dcq); |
889 | 2167 |
342 | 2168 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); |
2169 int n_completed_buffers = 0; | |
1705 | 2170 while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) { |
342 | 2171 n_completed_buffers++; |
2172 } | |
2173 g1_policy()->record_update_rs_processed_buffers(worker_i, | |
2174 (double) n_completed_buffers); | |
2175 dcqs.clear_n_completed_buffers(); | |
2176 assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!"); | |
2177 } | |
2178 | |
2179 | |
2180 // Computes the sum of the storage used by the various regions. | |
2181 | |
2182 size_t G1CollectedHeap::used() const { | |
862
36b5611220a7
6863216: Clean up debugging debris inadvertently pushed with 6700789
ysr
parents:
861
diff
changeset
|
2183 assert(Heap_lock->owner() != NULL, |
36b5611220a7
6863216: Clean up debugging debris inadvertently pushed with 6700789
ysr
parents:
861
diff
changeset
|
2184 "Should be owned on this thread's behalf."); |
342 | 2185 size_t result = _summary_bytes_used; |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2186 // 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
|
2187 HeapRegion* hr = _mutator_alloc_region.get(); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2188 if (hr != NULL) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2189 result += hr->used(); |
342 | 2190 return result; |
2191 } | |
2192 | |
846
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2193 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
|
2194 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
|
2195 return result; |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2196 } |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2197 |
342 | 2198 class SumUsedClosure: public HeapRegionClosure { |
2199 size_t _used; | |
2200 public: | |
2201 SumUsedClosure() : _used(0) {} | |
2202 bool doHeapRegion(HeapRegion* r) { | |
2203 if (!r->continuesHumongous()) { | |
2204 _used += r->used(); | |
2205 } | |
2206 return false; | |
2207 } | |
2208 size_t result() { return _used; } | |
2209 }; | |
2210 | |
2211 size_t G1CollectedHeap::recalculate_used() const { | |
2212 SumUsedClosure blk; | |
3766 | 2213 heap_region_iterate(&blk); |
342 | 2214 return blk.result(); |
2215 } | |
2216 | |
2217 size_t G1CollectedHeap::unsafe_max_alloc() { | |
2152 | 2218 if (free_regions() > 0) return HeapRegion::GrainBytes; |
342 | 2219 // otherwise, is there space in the current allocation region? |
2220 | |
2221 // We need to store the current allocation region in a local variable | |
2222 // here. The problem is that this method doesn't take any locks and | |
2223 // there may be other threads which overwrite the current allocation | |
2224 // region field. attempt_allocation(), for example, sets it to NULL | |
2225 // and this can happen *after* the NULL check here but before the call | |
2226 // to free(), resulting in a SIGSEGV. Note that this doesn't appear | |
2227 // to be a problem in the optimized build, since the two loads of the | |
2228 // current allocation region field are optimized away. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2229 HeapRegion* hr = _mutator_alloc_region.get(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2230 if (hr == NULL) { |
342 | 2231 return 0; |
2232 } | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2233 return hr->free(); |
342 | 2234 } |
2235 | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2236 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
|
2237 return |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2238 ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2239 (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2240 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2241 |
3285
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2242 #ifndef PRODUCT |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2243 void G1CollectedHeap::allocate_dummy_regions() { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2244 // Let's fill up most of the region |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2245 size_t word_size = HeapRegion::GrainWords - 1024; |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2246 // 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
|
2247 guarantee(isHumongous(word_size), "sanity"); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2248 |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2249 for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2250 // 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
|
2251 HeapWord* dummy_obj = humongous_obj_allocate(word_size); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2252 if (dummy_obj != NULL) { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2253 MemRegion mr(dummy_obj, word_size); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2254 CollectedHeap::fill_with_object(mr); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2255 } else { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2256 // 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
|
2257 // again. Let's get out of the loop. |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2258 break; |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2259 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2260 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2261 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2262 #endif // !PRODUCT |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2263 |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2264 void G1CollectedHeap::increment_full_collections_completed(bool concurrent) { |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2265 MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2266 |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2267 // 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
|
2268 // 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
|
2269 // 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
|
2270 // assert here. |
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2271 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2272 // 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
|
2273 // 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
|
2274 // collections have been started. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2275 unsigned int full_collections_started = total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2276 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2277 // 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
|
2278 // 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
|
2279 // interrupt a concurrent cycle), the number of full collections |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2280 // 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
|
2281 // 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
|
2282 // behind the number of full collections started. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2283 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2284 // 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
|
2285 assert(concurrent || |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2286 (full_collections_started == _full_collections_completed + 1) || |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2287 (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
|
2288 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
|
2289 "is inconsistent with _full_collections_completed = %u", |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2290 full_collections_started, _full_collections_completed)); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2291 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2292 // 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
|
2293 assert(!concurrent || |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2294 (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
|
2295 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
|
2296 "full_collections_started = %u " |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2297 "is inconsistent with _full_collections_completed = %u", |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2298 full_collections_started, _full_collections_completed)); |
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 _full_collections_completed += 1; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2301 |
1840
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2302 // 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
|
2303 // we wake up any waiters (especially when ExplicitInvokesConcurrent |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2304 // 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
|
2305 // 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
|
2306 if (concurrent) { |
1840
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2307 _cmThread->clear_in_progress(); |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2308 } |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2309 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2310 // 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
|
2311 // System.gc() with (with ExplicitGCInvokesConcurrent set or not) |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2312 // 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
|
2313 // waiting in VM_G1IncCollectionPause::doit_epilogue(). |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2314 FullGCCount_lock->notify_all(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2315 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2316 |
342 | 2317 void G1CollectedHeap::collect_as_vm_thread(GCCause::Cause cause) { |
2152 | 2318 assert_at_safepoint(true /* should_be_vm_thread */); |
342 | 2319 GCCauseSetter gcs(this, cause); |
2320 switch (cause) { | |
2321 case GCCause::_heap_inspection: | |
2322 case GCCause::_heap_dump: { | |
2323 HandleMark hm; | |
2324 do_full_collection(false); // don't clear all soft refs | |
2325 break; | |
2326 } | |
2327 default: // XXX FIX ME | |
2328 ShouldNotReachHere(); // Unexpected use of this function | |
2329 } | |
2330 } | |
2331 | |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2332 void G1CollectedHeap::collect(GCCause::Cause cause) { |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2333 // 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
|
2334 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
|
2335 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2336 unsigned int gc_count_before; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2337 unsigned int full_gc_count_before; |
342 | 2338 { |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2339 MutexLocker ml(Heap_lock); |
1973 | 2340 |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2341 // 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
|
2342 gc_count_before = SharedHeap::heap()->total_collections(); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2343 full_gc_count_before = SharedHeap::heap()->total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2344 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2345 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2346 if (should_do_concurrent_full_gc(cause)) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2347 // Schedule an initial-mark evacuation pause that will start a |
1973 | 2348 // concurrent cycle. We're setting word_size to 0 which means that |
2349 // we are not requesting a post-GC allocation. | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2350 VM_G1IncCollectionPause op(gc_count_before, |
1973 | 2351 0, /* word_size */ |
2352 true, /* should_initiate_conc_mark */ | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2353 g1_policy()->max_pause_time_ms(), |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2354 cause); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2355 VMThread::execute(&op); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2356 } else { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2357 if (cause == GCCause::_gc_locker |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2358 DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2359 |
1973 | 2360 // Schedule a standard evacuation pause. We're setting word_size |
2361 // 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
|
2362 VM_G1IncCollectionPause op(gc_count_before, |
1973 | 2363 0, /* word_size */ |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2364 false, /* should_initiate_conc_mark */ |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2365 g1_policy()->max_pause_time_ms(), |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2366 cause); |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2367 VMThread::execute(&op); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2368 } else { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2369 // Schedule a Full GC. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2370 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
|
2371 VMThread::execute(&op); |
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2372 } |
342 | 2373 } |
2374 } | |
2375 | |
2376 bool G1CollectedHeap::is_in(const void* p) const { | |
3766 | 2377 HeapRegion* hr = _hrs.addr_to_region((HeapWord*) p); |
2378 if (hr != NULL) { | |
342 | 2379 return hr->is_in(p); |
2380 } else { | |
2381 return _perm_gen->as_gen()->is_in(p); | |
2382 } | |
2383 } | |
2384 | |
2385 // Iteration functions. | |
2386 | |
2387 // Iterates an OopClosure over all ref-containing fields of objects | |
2388 // within a HeapRegion. | |
2389 | |
2390 class IterateOopClosureRegionClosure: public HeapRegionClosure { | |
2391 MemRegion _mr; | |
2392 OopClosure* _cl; | |
2393 public: | |
2394 IterateOopClosureRegionClosure(MemRegion mr, OopClosure* cl) | |
2395 : _mr(mr), _cl(cl) {} | |
2396 bool doHeapRegion(HeapRegion* r) { | |
2397 if (! r->continuesHumongous()) { | |
2398 r->oop_iterate(_cl); | |
2399 } | |
2400 return false; | |
2401 } | |
2402 }; | |
2403 | |
678 | 2404 void G1CollectedHeap::oop_iterate(OopClosure* cl, bool do_perm) { |
342 | 2405 IterateOopClosureRegionClosure blk(_g1_committed, cl); |
3766 | 2406 heap_region_iterate(&blk); |
678 | 2407 if (do_perm) { |
2408 perm_gen()->oop_iterate(cl); | |
2409 } | |
342 | 2410 } |
2411 | |
678 | 2412 void G1CollectedHeap::oop_iterate(MemRegion mr, OopClosure* cl, bool do_perm) { |
342 | 2413 IterateOopClosureRegionClosure blk(mr, cl); |
3766 | 2414 heap_region_iterate(&blk); |
678 | 2415 if (do_perm) { |
2416 perm_gen()->oop_iterate(cl); | |
2417 } | |
342 | 2418 } |
2419 | |
2420 // Iterates an ObjectClosure over all objects within a HeapRegion. | |
2421 | |
2422 class IterateObjectClosureRegionClosure: public HeapRegionClosure { | |
2423 ObjectClosure* _cl; | |
2424 public: | |
2425 IterateObjectClosureRegionClosure(ObjectClosure* cl) : _cl(cl) {} | |
2426 bool doHeapRegion(HeapRegion* r) { | |
2427 if (! r->continuesHumongous()) { | |
2428 r->object_iterate(_cl); | |
2429 } | |
2430 return false; | |
2431 } | |
2432 }; | |
2433 | |
678 | 2434 void G1CollectedHeap::object_iterate(ObjectClosure* cl, bool do_perm) { |
342 | 2435 IterateObjectClosureRegionClosure blk(cl); |
3766 | 2436 heap_region_iterate(&blk); |
678 | 2437 if (do_perm) { |
2438 perm_gen()->object_iterate(cl); | |
2439 } | |
342 | 2440 } |
2441 | |
2442 void G1CollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) { | |
2443 // FIXME: is this right? | |
2444 guarantee(false, "object_iterate_since_last_GC not supported by G1 heap"); | |
2445 } | |
2446 | |
2447 // Calls a SpaceClosure on a HeapRegion. | |
2448 | |
2449 class SpaceClosureRegionClosure: public HeapRegionClosure { | |
2450 SpaceClosure* _cl; | |
2451 public: | |
2452 SpaceClosureRegionClosure(SpaceClosure* cl) : _cl(cl) {} | |
2453 bool doHeapRegion(HeapRegion* r) { | |
2454 _cl->do_space(r); | |
2455 return false; | |
2456 } | |
2457 }; | |
2458 | |
2459 void G1CollectedHeap::space_iterate(SpaceClosure* cl) { | |
2460 SpaceClosureRegionClosure blk(cl); | |
3766 | 2461 heap_region_iterate(&blk); |
342 | 2462 } |
2463 | |
3766 | 2464 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { |
2465 _hrs.iterate(cl); | |
342 | 2466 } |
2467 | |
2468 void G1CollectedHeap::heap_region_iterate_from(HeapRegion* r, | |
3766 | 2469 HeapRegionClosure* cl) const { |
2470 _hrs.iterate_from(r, cl); | |
342 | 2471 } |
2472 | |
2473 void | |
2474 G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl, | |
2475 int worker, | |
2476 jint claim_value) { | |
355 | 2477 const size_t regions = n_regions(); |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
2478 const size_t worker_num = (G1CollectedHeap::use_parallel_gc_threads() ? ParallelGCThreads : 1); |
355 | 2479 // try to spread out the starting points of the workers |
2480 const size_t start_index = regions / worker_num * (size_t) worker; | |
2481 | |
2482 // each worker will actually look at all regions | |
2483 for (size_t count = 0; count < regions; ++count) { | |
2484 const size_t index = (start_index + count) % regions; | |
2485 assert(0 <= index && index < regions, "sanity"); | |
2486 HeapRegion* r = region_at(index); | |
2487 // we'll ignore "continues humongous" regions (we'll process them | |
2488 // when we come across their corresponding "start humongous" | |
2489 // region) and regions already claimed | |
2490 if (r->claim_value() == claim_value || r->continuesHumongous()) { | |
2491 continue; | |
2492 } | |
2493 // OK, try to claim it | |
342 | 2494 if (r->claimHeapRegion(claim_value)) { |
355 | 2495 // success! |
2496 assert(!r->continuesHumongous(), "sanity"); | |
2497 if (r->startsHumongous()) { | |
2498 // If the region is "starts humongous" we'll iterate over its | |
2499 // "continues humongous" first; in fact we'll do them | |
2500 // first. The order is important. In on case, calling the | |
2501 // closure on the "starts humongous" region might de-allocate | |
2502 // and clear all its "continues humongous" regions and, as a | |
2503 // result, we might end up processing them twice. So, we'll do | |
2504 // them first (notice: most closures will ignore them anyway) and | |
2505 // then we'll do the "starts humongous" region. | |
2506 for (size_t ch_index = index + 1; ch_index < regions; ++ch_index) { | |
2507 HeapRegion* chr = region_at(ch_index); | |
2508 | |
2509 // if the region has already been claimed or it's not | |
2510 // "continues humongous" we're done | |
2511 if (chr->claim_value() == claim_value || | |
2512 !chr->continuesHumongous()) { | |
2513 break; | |
2514 } | |
2515 | |
2516 // Noone should have claimed it directly. We can given | |
2517 // that we claimed its "starts humongous" region. | |
2518 assert(chr->claim_value() != claim_value, "sanity"); | |
2519 assert(chr->humongous_start_region() == r, "sanity"); | |
2520 | |
2521 if (chr->claimHeapRegion(claim_value)) { | |
2522 // we should always be able to claim it; noone else should | |
2523 // be trying to claim this region | |
2524 | |
2525 bool res2 = cl->doHeapRegion(chr); | |
2526 assert(!res2, "Should not abort"); | |
2527 | |
2528 // Right now, this holds (i.e., no closure that actually | |
2529 // does something with "continues humongous" regions | |
2530 // clears them). We might have to weaken it in the future, | |
2531 // but let's leave these two asserts here for extra safety. | |
2532 assert(chr->continuesHumongous(), "should still be the case"); | |
2533 assert(chr->humongous_start_region() == r, "sanity"); | |
2534 } else { | |
2535 guarantee(false, "we should not reach here"); | |
2536 } | |
2537 } | |
2538 } | |
2539 | |
2540 assert(!r->continuesHumongous(), "sanity"); | |
2541 bool res = cl->doHeapRegion(r); | |
2542 assert(!res, "Should not abort"); | |
2543 } | |
2544 } | |
2545 } | |
2546 | |
390 | 2547 class ResetClaimValuesClosure: public HeapRegionClosure { |
2548 public: | |
2549 bool doHeapRegion(HeapRegion* r) { | |
2550 r->set_claim_value(HeapRegion::InitialClaimValue); | |
2551 return false; | |
2552 } | |
2553 }; | |
2554 | |
2555 void | |
2556 G1CollectedHeap::reset_heap_region_claim_values() { | |
2557 ResetClaimValuesClosure blk; | |
2558 heap_region_iterate(&blk); | |
2559 } | |
2560 | |
355 | 2561 #ifdef ASSERT |
2562 // This checks whether all regions in the heap have the correct claim | |
2563 // value. I also piggy-backed on this a check to ensure that the | |
2564 // humongous_start_region() information on "continues humongous" | |
2565 // regions is correct. | |
2566 | |
2567 class CheckClaimValuesClosure : public HeapRegionClosure { | |
2568 private: | |
2569 jint _claim_value; | |
2570 size_t _failures; | |
2571 HeapRegion* _sh_region; | |
2572 public: | |
2573 CheckClaimValuesClosure(jint claim_value) : | |
2574 _claim_value(claim_value), _failures(0), _sh_region(NULL) { } | |
2575 bool doHeapRegion(HeapRegion* r) { | |
2576 if (r->claim_value() != _claim_value) { | |
2577 gclog_or_tty->print_cr("Region ["PTR_FORMAT","PTR_FORMAT"), " | |
2578 "claim value = %d, should be %d", | |
2579 r->bottom(), r->end(), r->claim_value(), | |
2580 _claim_value); | |
2581 ++_failures; | |
2582 } | |
2583 if (!r->isHumongous()) { | |
2584 _sh_region = NULL; | |
2585 } else if (r->startsHumongous()) { | |
2586 _sh_region = r; | |
2587 } else if (r->continuesHumongous()) { | |
2588 if (r->humongous_start_region() != _sh_region) { | |
2589 gclog_or_tty->print_cr("Region ["PTR_FORMAT","PTR_FORMAT"), " | |
2590 "HS = "PTR_FORMAT", should be "PTR_FORMAT, | |
2591 r->bottom(), r->end(), | |
2592 r->humongous_start_region(), | |
2593 _sh_region); | |
2594 ++_failures; | |
342 | 2595 } |
2596 } | |
355 | 2597 return false; |
2598 } | |
2599 size_t failures() { | |
2600 return _failures; | |
2601 } | |
2602 }; | |
2603 | |
2604 bool G1CollectedHeap::check_heap_region_claim_values(jint claim_value) { | |
2605 CheckClaimValuesClosure cl(claim_value); | |
2606 heap_region_iterate(&cl); | |
2607 return cl.failures() == 0; | |
2608 } | |
2609 #endif // ASSERT | |
342 | 2610 |
2611 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) { | |
2612 HeapRegion* r = g1_policy()->collection_set(); | |
2613 while (r != NULL) { | |
2614 HeapRegion* next = r->next_in_collection_set(); | |
2615 if (cl->doHeapRegion(r)) { | |
2616 cl->incomplete(); | |
2617 return; | |
2618 } | |
2619 r = next; | |
2620 } | |
2621 } | |
2622 | |
2623 void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r, | |
2624 HeapRegionClosure *cl) { | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2625 if (r == NULL) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2626 // 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
|
2627 return; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2628 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2629 |
342 | 2630 assert(r->in_collection_set(), |
2631 "Start region must be a member of the collection set."); | |
2632 HeapRegion* cur = r; | |
2633 while (cur != NULL) { | |
2634 HeapRegion* next = cur->next_in_collection_set(); | |
2635 if (cl->doHeapRegion(cur) && false) { | |
2636 cl->incomplete(); | |
2637 return; | |
2638 } | |
2639 cur = next; | |
2640 } | |
2641 cur = g1_policy()->collection_set(); | |
2642 while (cur != r) { | |
2643 HeapRegion* next = cur->next_in_collection_set(); | |
2644 if (cl->doHeapRegion(cur) && false) { | |
2645 cl->incomplete(); | |
2646 return; | |
2647 } | |
2648 cur = next; | |
2649 } | |
2650 } | |
2651 | |
2652 CompactibleSpace* G1CollectedHeap::first_compactible_space() { | |
3766 | 2653 return n_regions() > 0 ? region_at(0) : NULL; |
342 | 2654 } |
2655 | |
2656 | |
2657 Space* G1CollectedHeap::space_containing(const void* addr) const { | |
2658 Space* res = heap_region_containing(addr); | |
2659 if (res == NULL) | |
2660 res = perm_gen()->space_containing(addr); | |
2661 return res; | |
2662 } | |
2663 | |
2664 HeapWord* G1CollectedHeap::block_start(const void* addr) const { | |
2665 Space* sp = space_containing(addr); | |
2666 if (sp != NULL) { | |
2667 return sp->block_start(addr); | |
2668 } | |
2669 return NULL; | |
2670 } | |
2671 | |
2672 size_t G1CollectedHeap::block_size(const HeapWord* addr) const { | |
2673 Space* sp = space_containing(addr); | |
2674 assert(sp != NULL, "block_size of address outside of heap"); | |
2675 return sp->block_size(addr); | |
2676 } | |
2677 | |
2678 bool G1CollectedHeap::block_is_obj(const HeapWord* addr) const { | |
2679 Space* sp = space_containing(addr); | |
2680 return sp->block_is_obj(addr); | |
2681 } | |
2682 | |
2683 bool G1CollectedHeap::supports_tlab_allocation() const { | |
2684 return true; | |
2685 } | |
2686 | |
2687 size_t G1CollectedHeap::tlab_capacity(Thread* ignored) const { | |
2688 return HeapRegion::GrainBytes; | |
2689 } | |
2690 | |
2691 size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const { | |
2692 // Return the remaining space in the cur alloc region, but not less than | |
2693 // the min TLAB size. | |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2694 |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2695 // 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
|
2696 // 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
|
2697 // humongous objects. |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2698 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2699 HeapRegion* hr = _mutator_alloc_region.get(); |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2700 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
|
2701 if (hr == NULL) { |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
2702 return max_tlab_size; |
342 | 2703 } else { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2704 return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab_size); |
342 | 2705 } |
2706 } | |
2707 | |
2708 size_t G1CollectedHeap::max_capacity() const { | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2709 return _g1_reserved.byte_size(); |
342 | 2710 } |
2711 | |
2712 jlong G1CollectedHeap::millis_since_last_gc() { | |
2713 // assert(false, "NYI"); | |
2714 return 0; | |
2715 } | |
2716 | |
2717 void G1CollectedHeap::prepare_for_verify() { | |
2718 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { | |
2719 ensure_parsability(false); | |
2720 } | |
2721 g1_rem_set()->prepare_for_verify(); | |
2722 } | |
2723 | |
2724 class VerifyLivenessOopClosure: public OopClosure { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2725 G1CollectedHeap* _g1h; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2726 VerifyOption _vo; |
342 | 2727 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2728 VerifyLivenessOopClosure(G1CollectedHeap* g1h, VerifyOption vo): |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2729 _g1h(g1h), _vo(vo) |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2730 { } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2731 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
|
2732 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
|
2733 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2734 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
|
2735 oop obj = oopDesc::load_decode_heap_oop(p); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2736 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
|
2737 "Dead object referenced by a not dead object"); |
342 | 2738 } |
2739 }; | |
2740 | |
2741 class VerifyObjsInRegionClosure: public ObjectClosure { | |
811 | 2742 private: |
342 | 2743 G1CollectedHeap* _g1h; |
2744 size_t _live_bytes; | |
2745 HeapRegion *_hr; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2746 VerifyOption _vo; |
342 | 2747 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2748 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2749 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2750 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2751 VerifyObjsInRegionClosure(HeapRegion *hr, VerifyOption vo) |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2752 : _live_bytes(0), _hr(hr), _vo(vo) { |
342 | 2753 _g1h = G1CollectedHeap::heap(); |
2754 } | |
2755 void do_object(oop o) { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2756 VerifyLivenessOopClosure isLive(_g1h, _vo); |
342 | 2757 assert(o != NULL, "Huh?"); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2758 if (!_g1h->is_obj_dead_cond(o, _vo)) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2759 // If the object is alive according to the mark word, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2760 // then verify that the marking information agrees. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2761 // Note we can't verify the contra-positive of the |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2762 // above: if the object is dead (according to the mark |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2763 // 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
|
2764 // but has since became dead, or may have been allocated |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2765 // since the last marking. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2766 if (_vo == VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2767 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
|
2768 } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2769 |
342 | 2770 o->oop_iterate(&isLive); |
1389
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2771 if (!_hr->obj_allocated_since_prev_marking(o)) { |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2772 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
|
2773 _live_bytes += (obj_size * HeapWordSize); |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
2774 } |
342 | 2775 } |
2776 } | |
2777 size_t live_bytes() { return _live_bytes; } | |
2778 }; | |
2779 | |
2780 class PrintObjsInRegionClosure : public ObjectClosure { | |
2781 HeapRegion *_hr; | |
2782 G1CollectedHeap *_g1; | |
2783 public: | |
2784 PrintObjsInRegionClosure(HeapRegion *hr) : _hr(hr) { | |
2785 _g1 = G1CollectedHeap::heap(); | |
2786 }; | |
2787 | |
2788 void do_object(oop o) { | |
2789 if (o != NULL) { | |
2790 HeapWord *start = (HeapWord *) o; | |
2791 size_t word_sz = o->size(); | |
2792 gclog_or_tty->print("\nPrinting obj "PTR_FORMAT" of size " SIZE_FORMAT | |
2793 " isMarkedPrev %d isMarkedNext %d isAllocSince %d\n", | |
2794 (void*) o, word_sz, | |
2795 _g1->isMarkedPrev(o), | |
2796 _g1->isMarkedNext(o), | |
2797 _hr->obj_allocated_since_prev_marking(o)); | |
2798 HeapWord *end = start + word_sz; | |
2799 HeapWord *cur; | |
2800 int *val; | |
2801 for (cur = start; cur < end; cur++) { | |
2802 val = (int *) cur; | |
2803 gclog_or_tty->print("\t "PTR_FORMAT":"PTR_FORMAT"\n", val, *val); | |
2804 } | |
2805 } | |
2806 } | |
2807 }; | |
2808 | |
2809 class VerifyRegionClosure: public HeapRegionClosure { | |
811 | 2810 private: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2811 bool _allow_dirty; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2812 bool _par; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2813 VerifyOption _vo; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2814 bool _failures; |
811 | 2815 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2816 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2817 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2818 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2819 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
|
2820 : _allow_dirty(allow_dirty), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2821 _par(par), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2822 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2823 _failures(false) {} |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2824 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2825 bool failures() { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2826 return _failures; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2827 } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2828 |
342 | 2829 bool doHeapRegion(HeapRegion* r) { |
390 | 2830 guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue, |
2831 "Should be unclaimed at verify points."); | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
2832 if (!r->continuesHumongous()) { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2833 bool failures = false; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2834 r->verify(_allow_dirty, _vo, &failures); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2835 if (failures) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2836 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2837 } else { |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2838 VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2839 r->object_iterate(¬_dead_yet_cl); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2840 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
|
2841 gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] " |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2842 "max_live_bytes "SIZE_FORMAT" " |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2843 "< calculated "SIZE_FORMAT, |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2844 r->bottom(), r->end(), |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2845 r->max_live_bytes(), |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2846 not_dead_yet_cl.live_bytes()); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2847 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2848 } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2849 } |
342 | 2850 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2851 return false; // stop the region iteration if we hit a failure |
342 | 2852 } |
2853 }; | |
2854 | |
2855 class VerifyRootsClosure: public OopsInGenClosure { | |
2856 private: | |
2857 G1CollectedHeap* _g1h; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2858 VerifyOption _vo; |
342 | 2859 bool _failures; |
2860 public: | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2861 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2862 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2863 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2864 VerifyRootsClosure(VerifyOption vo) : |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2865 _g1h(G1CollectedHeap::heap()), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2866 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2867 _failures(false) { } |
342 | 2868 |
2869 bool failures() { return _failures; } | |
2870 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2871 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
|
2872 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2873 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2874 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
|
2875 if (_g1h->is_obj_dead_cond(obj, _vo)) { |
342 | 2876 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
|
2877 "points to dead obj "PTR_FORMAT, p, (void*) obj); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2878 if (_vo == VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2879 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
|
2880 } |
342 | 2881 obj->print_on(gclog_or_tty); |
2882 _failures = true; | |
2883 } | |
2884 } | |
2885 } | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2886 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2887 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
|
2888 void do_oop(narrowOop* p) { do_oop_nv(p); } |
342 | 2889 }; |
2890 | |
390 | 2891 // This is the task used for parallel heap verification. |
2892 | |
2893 class G1ParVerifyTask: public AbstractGangTask { | |
2894 private: | |
2895 G1CollectedHeap* _g1h; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2896 bool _allow_dirty; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2897 VerifyOption _vo; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2898 bool _failures; |
390 | 2899 |
2900 public: | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2901 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2902 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2903 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2904 G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty, VerifyOption vo) : |
390 | 2905 AbstractGangTask("Parallel verify task"), |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2906 _g1h(g1h), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2907 _allow_dirty(allow_dirty), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2908 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2909 _failures(false) { } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2910 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2911 bool failures() { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2912 return _failures; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2913 } |
390 | 2914 |
2915 void work(int worker_i) { | |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
2916 HandleMark hm; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2917 VerifyRegionClosure blk(_allow_dirty, true, _vo); |
390 | 2918 _g1h->heap_region_par_iterate_chunked(&blk, worker_i, |
2919 HeapRegion::ParVerifyClaimValue); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2920 if (blk.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2921 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2922 } |
390 | 2923 } |
2924 }; | |
2925 | |
342 | 2926 void G1CollectedHeap::verify(bool allow_dirty, bool silent) { |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2927 verify(allow_dirty, silent, VerifyOption_G1UsePrevMarking); |
811 | 2928 } |
2929 | |
2930 void G1CollectedHeap::verify(bool allow_dirty, | |
2931 bool silent, | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2932 VerifyOption vo) { |
342 | 2933 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2934 if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); } |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2935 VerifyRootsClosure rootsCl(vo); |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
2936 CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2937 |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2938 // 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
|
2939 // 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
|
2940 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
|
2941 |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2942 process_strong_roots(true, // activate StrongRootsScope |
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
2943 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
|
2944 // 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
|
2945 SharedHeap::ScanningOption(so), // roots scanning options |
342 | 2946 &rootsCl, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
2947 &blobsCl, |
342 | 2948 &rootsCl); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2949 |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2950 // 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
|
2951 // 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
|
2952 // 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
|
2953 // 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
|
2954 // "Root location <x> points to dead ob <y>" failure. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2955 if (vo != VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2956 // 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
|
2957 // 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
|
2958 // references explicitly below. Whether the relevant cards are dirty |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2959 // is checked further below in the rem set verification. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2960 if (!silent) { gclog_or_tty->print("Permgen roots "); } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2961 perm_gen()->oop_iterate(&rootsCl); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2962 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2963 bool failures = rootsCl.failures(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2964 |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2965 if (vo != VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2966 // 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
|
2967 // 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
|
2968 // verifying the region sets will fail. So we only verify |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2969 // the region sets when not in a full GC. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2970 if (!silent) { gclog_or_tty->print("HeapRegionSets "); } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2971 verify_region_sets(); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2972 } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2973 |
2152 | 2974 if (!silent) { gclog_or_tty->print("HeapRegions "); } |
390 | 2975 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
2976 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
2977 "sanity check"); | |
2978 | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2979 G1ParVerifyTask task(this, allow_dirty, vo); |
390 | 2980 int n_workers = workers()->total_workers(); |
2981 set_par_threads(n_workers); | |
2982 workers()->run_task(&task); | |
2983 set_par_threads(0); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2984 if (task.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2985 failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2986 } |
390 | 2987 |
2988 assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue), | |
2989 "sanity check"); | |
2990 | |
2991 reset_heap_region_claim_values(); | |
2992 | |
2993 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
2994 "sanity check"); | |
2995 } else { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
2996 VerifyRegionClosure blk(allow_dirty, false, vo); |
3766 | 2997 heap_region_iterate(&blk); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2998 if (blk.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
2999 failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3000 } |
390 | 3001 } |
2152 | 3002 if (!silent) gclog_or_tty->print("RemSet "); |
342 | 3003 rem_set()->verify(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3004 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3005 if (failures) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3006 gclog_or_tty->print_cr("Heap:"); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3007 print_on(gclog_or_tty, true /* extended */); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3008 gclog_or_tty->print_cr(""); |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1545
diff
changeset
|
3009 #ifndef PRODUCT |
1044 | 3010 if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { |
1388 | 3011 concurrent_mark()->print_reachable("at-verification-failure", |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3012 vo, false /* all */); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3013 } |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1545
diff
changeset
|
3014 #endif |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3015 gclog_or_tty->flush(); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3016 } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3017 guarantee(!failures, "there should not have been any failures"); |
342 | 3018 } else { |
3019 if (!silent) gclog_or_tty->print("(SKIPPING roots, heapRegions, remset) "); | |
3020 } | |
3021 } | |
3022 | |
3023 class PrintRegionClosure: public HeapRegionClosure { | |
3024 outputStream* _st; | |
3025 public: | |
3026 PrintRegionClosure(outputStream* st) : _st(st) {} | |
3027 bool doHeapRegion(HeapRegion* r) { | |
3028 r->print_on(_st); | |
3029 return false; | |
3030 } | |
3031 }; | |
3032 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3033 void G1CollectedHeap::print() const { print_on(tty); } |
342 | 3034 |
3035 void G1CollectedHeap::print_on(outputStream* st) const { | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3036 print_on(st, PrintHeapAtGCExtended); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3037 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3038 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3039 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
|
3040 st->print(" %-20s", "garbage-first heap"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3041 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
|
3042 capacity()/K, used_unlocked()/K); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3043 st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3044 _g1_storage.low_boundary(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3045 _g1_storage.high(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3046 _g1_storage.high_boundary()); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3047 st->cr(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3048 st->print(" region size " SIZE_FORMAT "K, ", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3049 HeapRegion::GrainBytes/K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3050 size_t young_regions = _young_list->length(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3051 st->print(SIZE_FORMAT " young (" SIZE_FORMAT "K), ", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3052 young_regions, young_regions * HeapRegion::GrainBytes / K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3053 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
|
3054 st->print(SIZE_FORMAT " survivors (" SIZE_FORMAT "K)", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3055 survivor_regions, survivor_regions * HeapRegion::GrainBytes / K); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3056 st->cr(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3057 perm()->as_gen()->print_on(st); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3058 if (extended) { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3059 st->cr(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3060 print_on_extended(st); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3061 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3062 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3063 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3064 void G1CollectedHeap::print_on_extended(outputStream* st) const { |
342 | 3065 PrintRegionClosure blk(st); |
3766 | 3066 heap_region_iterate(&blk); |
342 | 3067 } |
3068 | |
3069 void G1CollectedHeap::print_gc_threads_on(outputStream* st) const { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
3070 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1019 | 3071 workers()->print_worker_threads_on(st); |
3072 } | |
3073 _cmThread->print_on(st); | |
342 | 3074 st->cr(); |
1019 | 3075 _cm->print_worker_threads_on(st); |
3076 _cg1r->print_worker_threads_on(st); | |
342 | 3077 st->cr(); |
3078 } | |
3079 | |
3080 void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
3081 if (G1CollectedHeap::use_parallel_gc_threads()) { |
342 | 3082 workers()->threads_do(tc); |
3083 } | |
3084 tc->do_thread(_cmThread); | |
794 | 3085 _cg1r->threads_do(tc); |
342 | 3086 } |
3087 | |
3088 void G1CollectedHeap::print_tracing_info() const { | |
3089 // We'll overload this to mean "trace GC pause statistics." | |
3090 if (TraceGen0Time || TraceGen1Time) { | |
3091 // The "G1CollectorPolicy" is keeping track of these stats, so delegate | |
3092 // to that. | |
3093 g1_policy()->print_tracing_info(); | |
3094 } | |
751 | 3095 if (G1SummarizeRSetStats) { |
342 | 3096 g1_rem_set()->print_summary_info(); |
3097 } | |
1282 | 3098 if (G1SummarizeConcMark) { |
342 | 3099 concurrent_mark()->print_summary_info(); |
3100 } | |
3101 g1_policy()->print_yg_surv_rate_info(); | |
3102 SpecializationStats::print(); | |
3103 } | |
3104 | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3105 #ifndef PRODUCT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3106 // Helpful for debugging RSet issues. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3107 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3108 class PrintRSetsClosure : public HeapRegionClosure { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3109 private: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3110 const char* _msg; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3111 size_t _occupied_sum; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3112 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3113 public: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3114 bool doHeapRegion(HeapRegion* r) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3115 HeapRegionRemSet* hrrs = r->rem_set(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3116 size_t occupied = hrrs->occupied(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3117 _occupied_sum += occupied; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3118 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3119 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
|
3120 HR_FORMAT_PARAMS(r)); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3121 if (occupied == 0) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3122 gclog_or_tty->print_cr(" RSet is empty"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3123 } else { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3124 hrrs->print(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3125 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3126 gclog_or_tty->print_cr("----------"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3127 return false; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3128 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3129 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3130 PrintRSetsClosure(const char* msg) : _msg(msg), _occupied_sum(0) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3131 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3132 gclog_or_tty->print_cr("========================================"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3133 gclog_or_tty->print_cr(msg); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3134 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3135 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3136 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3137 ~PrintRSetsClosure() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3138 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
|
3139 gclog_or_tty->print_cr("========================================"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3140 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3141 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3142 }; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3143 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3144 void G1CollectedHeap::print_cset_rsets() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3145 PrintRSetsClosure cl("Printing CSet RSets"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3146 collection_set_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3147 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3148 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3149 void G1CollectedHeap::print_all_rsets() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3150 PrintRSetsClosure cl("Printing All RSets");; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3151 heap_region_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3152 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3153 #endif // PRODUCT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3154 |
342 | 3155 G1CollectedHeap* G1CollectedHeap::heap() { |
3156 assert(_sh->kind() == CollectedHeap::G1CollectedHeap, | |
3157 "not a garbage-first heap"); | |
3158 return _g1h; | |
3159 } | |
3160 | |
3161 void G1CollectedHeap::gc_prologue(bool full /* Ignored */) { | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1166
diff
changeset
|
3162 // always_do_update_barrier = false; |
342 | 3163 assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); |
3164 // Call allocation profiler | |
3165 AllocationProfiler::iterate_since_last_gc(); | |
3166 // Fill TLAB's and such | |
3167 ensure_parsability(true); | |
3168 } | |
3169 | |
3170 void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { | |
3171 // FIXME: what is this about? | |
3172 // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled" | |
3173 // is set. | |
3174 COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), | |
3175 "derived pointer present")); | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1166
diff
changeset
|
3176 // always_do_update_barrier = true; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3177 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3178 // We have just completed a GC. Update the soft reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3179 // policy with the new heap occupancy |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3180 Universe::update_heap_info_at_gc(); |
342 | 3181 } |
3182 | |
1973 | 3183 HeapWord* G1CollectedHeap::do_collection_pause(size_t word_size, |
3184 unsigned int gc_count_before, | |
3185 bool* succeeded) { | |
3186 assert_heap_not_locked_and_not_at_safepoint(); | |
342 | 3187 g1_policy()->record_stop_world_start(); |
1973 | 3188 VM_G1IncCollectionPause op(gc_count_before, |
3189 word_size, | |
3190 false, /* should_initiate_conc_mark */ | |
3191 g1_policy()->max_pause_time_ms(), | |
3192 GCCause::_g1_inc_collection_pause); | |
3193 VMThread::execute(&op); | |
3194 | |
3195 HeapWord* result = op.result(); | |
3196 bool ret_succeeded = op.prologue_succeeded() && op.pause_succeeded(); | |
3197 assert(result == NULL || ret_succeeded, | |
3198 "the result should be NULL if the VM did not succeed"); | |
3199 *succeeded = ret_succeeded; | |
3200 | |
3201 assert_heap_not_locked(); | |
3202 return result; | |
342 | 3203 } |
3204 | |
3205 void | |
3206 G1CollectedHeap::doConcurrentMark() { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3207 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
|
3208 if (!_cmThread->in_progress()) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3209 _cmThread->set_started(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3210 CGC_lock->notify(); |
342 | 3211 } |
3212 } | |
3213 | |
3214 // <NEW PREDICTION> | |
3215 | |
3216 double G1CollectedHeap::predict_region_elapsed_time_ms(HeapRegion *hr, | |
3217 bool young) { | |
3218 return _g1_policy->predict_region_elapsed_time_ms(hr, young); | |
3219 } | |
3220 | |
3221 void G1CollectedHeap::check_if_region_is_too_expensive(double | |
3222 predicted_time_ms) { | |
3223 _g1_policy->check_if_region_is_too_expensive(predicted_time_ms); | |
3224 } | |
3225 | |
3226 size_t G1CollectedHeap::pending_card_num() { | |
3227 size_t extra_cards = 0; | |
3228 JavaThread *curr = Threads::first(); | |
3229 while (curr != NULL) { | |
3230 DirtyCardQueue& dcq = curr->dirty_card_queue(); | |
3231 extra_cards += dcq.size(); | |
3232 curr = curr->next(); | |
3233 } | |
3234 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
3235 size_t buffer_size = dcqs.buffer_size(); | |
3236 size_t buffer_num = dcqs.completed_buffers_num(); | |
3237 return buffer_size * buffer_num + extra_cards; | |
3238 } | |
3239 | |
3240 size_t G1CollectedHeap::max_pending_card_num() { | |
3241 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
3242 size_t buffer_size = dcqs.buffer_size(); | |
3243 size_t buffer_num = dcqs.completed_buffers_num(); | |
3244 int thread_num = Threads::number_of_threads(); | |
3245 return (buffer_num + thread_num) * buffer_size; | |
3246 } | |
3247 | |
3248 size_t G1CollectedHeap::cards_scanned() { | |
1861 | 3249 return g1_rem_set()->cardsScanned(); |
342 | 3250 } |
3251 | |
3252 void | |
3253 G1CollectedHeap::setup_surviving_young_words() { | |
3254 guarantee( _surviving_young_words == NULL, "pre-condition" ); | |
3255 size_t array_length = g1_policy()->young_cset_length(); | |
3256 _surviving_young_words = NEW_C_HEAP_ARRAY(size_t, array_length); | |
3257 if (_surviving_young_words == NULL) { | |
3258 vm_exit_out_of_memory(sizeof(size_t) * array_length, | |
3259 "Not enough space for young surv words summary."); | |
3260 } | |
3261 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
|
3262 #ifdef ASSERT |
342 | 3263 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
|
3264 assert( _surviving_young_words[i] == 0, "memset above" ); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3265 } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3266 #endif // !ASSERT |
342 | 3267 } |
3268 | |
3269 void | |
3270 G1CollectedHeap::update_surviving_young_words(size_t* surv_young_words) { | |
3271 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); | |
3272 size_t array_length = g1_policy()->young_cset_length(); | |
3273 for (size_t i = 0; i < array_length; ++i) | |
3274 _surviving_young_words[i] += surv_young_words[i]; | |
3275 } | |
3276 | |
3277 void | |
3278 G1CollectedHeap::cleanup_surviving_young_words() { | |
3279 guarantee( _surviving_young_words != NULL, "pre-condition" ); | |
3280 FREE_C_HEAP_ARRAY(size_t, _surviving_young_words); | |
3281 _surviving_young_words = NULL; | |
3282 } | |
3283 | |
3284 // </NEW PREDICTION> | |
3285 | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3286 #ifdef ASSERT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3287 class VerifyCSetClosure: public HeapRegionClosure { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3288 public: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3289 bool doHeapRegion(HeapRegion* hr) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3290 // 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
|
3291 // 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
|
3292 // 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
|
3293 // 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
|
3294 // 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
|
3295 // 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
|
3296 // 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
|
3297 // 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
|
3298 // evacuation failure handling. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3299 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
|
3300 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3301 // 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
|
3302 // perform on CSet regions. |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3303 return false; |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3304 } |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3305 }; |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3306 #endif // ASSERT |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3307 |
1709 | 3308 #if TASKQUEUE_STATS |
3309 void G1CollectedHeap::print_taskqueue_stats_hdr(outputStream* const st) { | |
3310 st->print_raw_cr("GC Task Stats"); | |
3311 st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr(); | |
3312 st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr(); | |
3313 } | |
3314 | |
3315 void G1CollectedHeap::print_taskqueue_stats(outputStream* const st) const { | |
3316 print_taskqueue_stats_hdr(st); | |
3317 | |
3318 TaskQueueStats totals; | |
1755
8e5955ddf8e4
6978300: G1: debug builds crash if ParallelGCThreads==0
jcoomes
parents:
1719
diff
changeset
|
3319 const int n = workers() != NULL ? workers()->total_workers() : 1; |
1709 | 3320 for (int i = 0; i < n; ++i) { |
3321 st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr(); | |
3322 totals += task_queue(i)->stats; | |
3323 } | |
3324 st->print_raw("tot "); totals.print(st); st->cr(); | |
3325 | |
3326 DEBUG_ONLY(totals.verify()); | |
3327 } | |
3328 | |
3329 void G1CollectedHeap::reset_taskqueue_stats() { | |
1755
8e5955ddf8e4
6978300: G1: debug builds crash if ParallelGCThreads==0
jcoomes
parents:
1719
diff
changeset
|
3330 const int n = workers() != NULL ? workers()->total_workers() : 1; |
1709 | 3331 for (int i = 0; i < n; ++i) { |
3332 task_queue(i)->stats.reset(); | |
3333 } | |
3334 } | |
3335 #endif // TASKQUEUE_STATS | |
3336 | |
1973 | 3337 bool |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3338 G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { |
2152 | 3339 assert_at_safepoint(true /* should_be_vm_thread */); |
3340 guarantee(!is_gc_active(), "collection is not reentrant"); | |
3341 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3342 if (GC_locker::check_active_before_gc()) { |
1973 | 3343 return false; |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3344 } |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3345 |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
2039
diff
changeset
|
3346 SvcGCMarker sgcm(SvcGCMarker::MINOR); |
2039
7c5250dbd584
6896624: G1: hotspot:::gc and hotspot:::mem-pool-gc probes are not fired
tonyp
parents:
2038
diff
changeset
|
3347 ResourceMark rm; |
7c5250dbd584
6896624: G1: hotspot:::gc and hotspot:::mem-pool-gc probes are not fired
tonyp
parents:
2038
diff
changeset
|
3348 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3349 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3350 Universe::print_heap_before_gc(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3351 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3352 |
2152 | 3353 verify_region_sets_optional(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3354 verify_dirty_young_regions(); |
2152 | 3355 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3356 { |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3357 // 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
|
3358 // 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
|
3359 // for the duration of this pause. |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3360 g1_policy()->decide_on_conc_mark_initiation(); |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3361 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3362 char verbose_str[128]; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3363 sprintf(verbose_str, "GC pause "); |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3364 if (g1_policy()->full_young_gcs()) { |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3365 strcat(verbose_str, "(young)"); |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3366 } else { |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3367 strcat(verbose_str, "(partial)"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3368 } |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3369 if (g1_policy()->during_initial_mark_pause()) { |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3370 strcat(verbose_str, " (initial-mark)"); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3371 // 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
|
3372 // full collection counter. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3373 increment_total_full_collections(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3374 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3375 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3376 // 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
|
3377 // 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
|
3378 // is messy if we do. |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3379 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3380 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3381 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
|
3382 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3383 TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
3323
diff
changeset
|
3384 TraceMemoryManagerStats tms(false /* fullGC */, gc_cause()); |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
3385 |
2361 | 3386 // If the secondary_free_list is not empty, append it to the |
3387 // free_list. No need to wait for the cleanup operation to finish; | |
3388 // the region allocation code will check the secondary_free_list | |
3389 // and wait if necessary. If the G1StressConcRegionFreeing flag is | |
3390 // set, skip this step so that the region allocation code has to | |
3391 // get entries from the secondary_free_list. | |
2152 | 3392 if (!G1StressConcRegionFreeing) { |
2361 | 3393 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 3394 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3395 |
3867
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3396 assert(check_young_list_well_formed(), |
ff53346271fe
6814390: G1: remove the concept of non-generational G1
brutisso
parents:
3830
diff
changeset
|
3397 "young list should be well formed"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3398 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3399 { // 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
|
3400 IsGCActiveMark x; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3401 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3402 gc_prologue(false); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3403 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
|
3404 increment_gc_time_stamp(); |
342 | 3405 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3406 if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3407 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
|
3408 gclog_or_tty->print(" VerifyBeforeGC:"); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3409 prepare_for_verify(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3410 Universe::verify(/* allow dirty */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3411 /* silent */ false, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3412 /* option */ VerifyOption_G1UsePrevMarking); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3413 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3414 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3415 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3416 COMPILER2_PRESENT(DerivedPointerTable::clear()); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3417 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3418 // Please see comment in g1CollectedHeap.hpp and |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3419 // G1CollectedHeap::ref_processing_init() to see how |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3420 // reference processing currently works in G1. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3421 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3422 // Enable discovery in the STW reference processor |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3423 ref_processor_stw()->enable_discovery(true /*verify_disabled*/, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3424 true /*verify_no_refs*/); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3425 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3426 { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3427 // We want to temporarily turn off discovery by the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3428 // CM ref processor, if necessary, and turn it back on |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3429 // on again later if we do. Using a scoped |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3430 // NoRefDiscovery object will do this. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3431 NoRefDiscovery no_cm_discovery(ref_processor_cm()); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3432 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3433 // Forget the current alloc region (we might even choose it to be part |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3434 // of the collection set!). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3435 release_mutator_alloc_region(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3436 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3437 // We should call this after we retire the mutator alloc |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3438 // region(s) so that all the ALLOC / RETIRE events are generated |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3439 // before the start GC event. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3440 _hr_printer.start_gc(false /* full */, (size_t) total_collections()); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3441 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3442 // The elapsed time induced by the start time below deliberately elides |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3443 // the possible verification above. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3444 double start_time_sec = os::elapsedTime(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3445 size_t start_used_bytes = used(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3446 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3447 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3448 gclog_or_tty->print_cr("\nBefore recording pause start.\nYoung_list:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3449 _young_list->print(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3450 g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3451 #endif // YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3452 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3453 g1_policy()->record_collection_pause_start(start_time_sec, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3454 start_used_bytes); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3455 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3456 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3457 gclog_or_tty->print_cr("\nAfter recording pause start.\nYoung_list:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3458 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3459 #endif // YOUNG_LIST_VERBOSE |
342 | 3460 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3461 if (g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3462 concurrent_mark()->checkpointRootsInitialPre(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3463 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3464 perm_gen()->save_marks(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3465 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3466 // We must do this before any possible evacuation that should propagate |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3467 // marks. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3468 if (mark_in_progress()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3469 double start_time_sec = os::elapsedTime(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3470 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3471 _cm->drainAllSATBBuffers(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3472 double finish_mark_ms = (os::elapsedTime() - start_time_sec) * 1000.0; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3473 g1_policy()->record_satb_drain_time(finish_mark_ms); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3474 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3475 // Record the number of elements currently on the mark stack, so we |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3476 // only iterate over these. (Since evacuation may add to the mark |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3477 // stack, doing more exposes race conditions.) If no mark is in |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3478 // progress, this will be zero. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3479 _cm->set_oops_do_bound(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3480 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3481 if (mark_in_progress()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3482 concurrent_mark()->newCSet(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3483 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3484 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3485 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3486 gclog_or_tty->print_cr("\nBefore choosing collection set.\nYoung_list:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3487 _young_list->print(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3488 g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3489 #endif // YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3490 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3491 g1_policy()->choose_collection_set(target_pause_time_ms); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3492 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3493 if (_hr_printer.is_active()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3494 HeapRegion* hr = g1_policy()->collection_set(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3495 while (hr != NULL) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3496 G1HRPrinter::RegionType type; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3497 if (!hr->is_young()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3498 type = G1HRPrinter::Old; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3499 } else if (hr->is_survivor()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3500 type = G1HRPrinter::Survivor; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3501 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3502 type = G1HRPrinter::Eden; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3503 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3504 _hr_printer.cset(hr); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3505 hr = hr->next_in_collection_set(); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3506 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3507 } |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3508 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3509 // We have chosen the complete collection set. If marking is |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3510 // active then, we clear the region fields of any of the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3511 // concurrent marking tasks whose region fields point into |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3512 // the collection set as these values will become stale. This |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3513 // will cause the owning marking threads to claim a new region |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3514 // when marking restarts. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3515 if (mark_in_progress()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3516 concurrent_mark()->reset_active_task_region_fields_in_cset(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3517 } |
3378
69293e516993
7041440: G1: assert(obj->is_oop_or_null(true )) failed: Error #
johnc
parents:
3377
diff
changeset
|
3518 |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3519 #ifdef ASSERT |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3520 VerifyCSetClosure cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3521 collection_set_iterate(&cl); |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3522 #endif // ASSERT |
1707 | 3523 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3524 setup_surviving_young_words(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3525 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3526 // Initialize the GC alloc regions. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3527 init_gc_alloc_regions(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3528 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3529 // Actually do the work... |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3530 evacuate_collection_set(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3531 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3532 free_collection_set(g1_policy()->collection_set()); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3533 g1_policy()->clear_collection_set(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3534 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3535 cleanup_surviving_young_words(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3536 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3537 // Start a new incremental collection set for the next pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3538 g1_policy()->start_incremental_cset_building(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3539 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3540 // Clear the _cset_fast_test bitmap in anticipation of adding |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3541 // regions to the incremental collection set for the next |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3542 // evacuation pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3543 clear_cset_fast_test(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3544 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3545 _young_list->reset_sampled_info(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3546 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3547 // Don't check the whole heap at this point as the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3548 // GC alloc regions from this pause have been tagged |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3549 // as survivors and moved on to the survivor list. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3550 // Survivor regions will fail the !is_young() check. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3551 assert(check_young_list_empty(false /* check_heap */), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3552 "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
|
3553 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3554 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3555 gclog_or_tty->print_cr("Before recording survivors.\nYoung List:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3556 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3557 #endif // YOUNG_LIST_VERBOSE |
342 | 3558 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3559 g1_policy()->record_survivor_regions(_young_list->survivor_length(), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3560 _young_list->first_survivor_region(), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3561 _young_list->last_survivor_region()); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3562 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3563 _young_list->reset_auxilary_lists(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3564 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3565 if (evacuation_failed()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3566 _summary_bytes_used = recalculate_used(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3567 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3568 // The "used" of the the collection set have already been subtracted |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3569 // when they were freed. Add in the bytes evacuated. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3570 _summary_bytes_used += g1_policy()->bytes_copied_during_gc(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3571 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3572 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3573 if (g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3574 concurrent_mark()->checkpointRootsInitialPost(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3575 set_marking_started(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3576 // CAUTION: after the doConcurrentMark() call below, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3577 // the concurrent marking thread(s) could be running |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3578 // concurrently with us. Make sure that anything after |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3579 // this point does not assume that we are the only GC thread |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3580 // running. Note: of course, the actual marking work will |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3581 // not start until the safepoint itself is released in |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3582 // ConcurrentGCThread::safepoint_desynchronize(). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3583 doConcurrentMark(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3584 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3585 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3586 allocate_dummy_regions(); |
3285
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
3587 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3588 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3589 gclog_or_tty->print_cr("\nEnd of the pause.\nYoung_list:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3590 _young_list->print(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3591 g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
3592 #endif // YOUNG_LIST_VERBOSE |
342 | 3593 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3594 init_mutator_alloc_region(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3595 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3596 { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3597 size_t expand_bytes = g1_policy()->expansion_amount(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3598 if (expand_bytes > 0) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3599 size_t bytes_before = capacity(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3600 if (!expand(expand_bytes)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3601 // We failed to expand the heap so let's verify that |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3602 // committed/uncommitted amount match the backing store |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3603 assert(capacity() == _g1_storage.committed_size(), "committed size mismatch"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3604 assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3605 } |
3920
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
3606 } |
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
3607 } |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3608 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3609 double end_time_sec = os::elapsedTime(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3610 double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3611 g1_policy()->record_pause_time_ms(pause_time_ms); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3612 g1_policy()->record_collection_pause_end(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3613 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3614 MemoryService::track_memory_usage(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3615 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3616 // In prepare_for_verify() below we'll need to scan the deferred |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3617 // update buffers to bring the RSets up-to-date if |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3618 // G1HRRSFlushLogBuffersOnVerify has been set. While scanning |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3619 // the update buffers we'll probably need to scan cards on the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3620 // regions we just allocated to (i.e., the GC alloc |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3621 // regions). However, during the last GC we called |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3622 // set_saved_mark() on all the GC alloc regions, so card |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3623 // scanning might skip the [saved_mark_word()...top()] area of |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3624 // those regions (i.e., the area we allocated objects into |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3625 // during the last GC). But it shouldn't. Given that |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3626 // saved_mark_word() is conditional on whether the GC time stamp |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3627 // on the region is current or not, by incrementing the GC time |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3628 // stamp here we invalidate all the GC time stamps on all the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3629 // regions and saved_mark_word() will simply return top() for |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3630 // all the regions. This is a nicer way of ensuring this rather |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3631 // than iterating over the regions and fixing them. In fact, the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3632 // GC time stamp increment here also ensures that |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3633 // saved_mark_word() will return top() between pauses, i.e., |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3634 // during concurrent refinement. So we don't need the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3635 // is_gc_active() check to decided which top to use when |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3636 // scanning cards (see CR 7039627). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3637 increment_gc_time_stamp(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3638 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3639 if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3640 HandleMark hm; // Discard invalid handles created during verification |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3641 gclog_or_tty->print(" VerifyAfterGC:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3642 prepare_for_verify(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3643 Universe::verify(/* allow dirty */ true, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3644 /* silent */ false, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3645 /* option */ VerifyOption_G1UsePrevMarking); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3646 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3647 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3648 assert(!ref_processor_stw()->discovery_enabled(), "Postcondition"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3649 ref_processor_stw()->verify_no_references_recorded(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3650 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3651 // CM reference discovery will be re-enabled if necessary. |
3920
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
3652 } |
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
3653 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3654 { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3655 size_t expand_bytes = g1_policy()->expansion_amount(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3656 if (expand_bytes > 0) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3657 size_t bytes_before = capacity(); |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
3658 // No need for an ergo verbose message here, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
3659 // expansion_amount() does this when it returns a value > 0. |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3660 if (!expand(expand_bytes)) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3661 // 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
|
3662 // committed/uncommitted amount match the backing store |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3663 assert(capacity() == _g1_storage.committed_size(), "committed size mismatch"); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3664 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
|
3665 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3666 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3667 } |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3668 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3669 // 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
|
3670 // 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
|
3671 // 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
|
3672 // RETIRE events are generated before the end GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
3673 _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
|
3674 |
3764
053d84a76d3d
7032531: G1: enhance GC logging to include more accurate eden / survivor size transitions
tonyp
parents:
3378
diff
changeset
|
3675 // 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
|
3676 g1_policy()->print_heap_transition(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3677 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3678 if (mark_in_progress()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3679 concurrent_mark()->update_g1_committed(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3680 } |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3681 |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3682 #ifdef TRACESPINNING |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3683 ParallelTaskTerminator::print_termination_counts(); |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
3684 #endif |
342 | 3685 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3686 gc_epilogue(false); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3687 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3688 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3689 if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3690 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
|
3691 print_tracing_info(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3692 vm_exit(-1); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3693 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3694 } |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3695 |
3766 | 3696 _hrs.verify_optional(); |
2152 | 3697 verify_region_sets_optional(); |
3698 | |
1709 | 3699 TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats()); |
3700 TASKQUEUE_STATS_ONLY(reset_taskqueue_stats()); | |
3701 | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3702 if (PrintHeapAtGC) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3703 Universe::print_heap_after_gc(); |
342 | 3704 } |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3705 g1mm()->update_counters(); |
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3706 |
884
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3707 if (G1SummarizeRSetStats && |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3708 (G1SummarizeRSetStatsPeriod > 0) && |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3709 (total_collections() % G1SummarizeRSetStatsPeriod == 0)) { |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3710 g1_rem_set()->print_summary_info(); |
83b687ce3090
6866591: G1: print update buffer processing stats more often
tonyp
parents:
883
diff
changeset
|
3711 } |
1973 | 3712 |
3713 return true; | |
342 | 3714 } |
3715 | |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3716 size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose) |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3717 { |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3718 size_t gclab_word_size; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3719 switch (purpose) { |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3720 case GCAllocForSurvived: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3721 gclab_word_size = YoungPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3722 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3723 case GCAllocForTenured: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3724 gclab_word_size = OldPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3725 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3726 default: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3727 assert(false, "unknown GCAllocPurpose"); |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3728 gclab_word_size = OldPLABSize; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3729 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3730 } |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3731 return gclab_word_size; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3732 } |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3733 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3734 void G1CollectedHeap::init_mutator_alloc_region() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3735 assert(_mutator_alloc_region.get() == NULL, "pre-condition"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3736 _mutator_alloc_region.init(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3737 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3738 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3739 void G1CollectedHeap::release_mutator_alloc_region() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3740 _mutator_alloc_region.release(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3741 assert(_mutator_alloc_region.get() == NULL, "post-condition"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3742 } |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
3743 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3744 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
|
3745 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
|
3746 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3747 _survivor_gc_alloc_region.init(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3748 _old_gc_alloc_region.init(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3749 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
|
3750 _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
|
3751 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3752 // 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
|
3753 // 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
|
3754 // 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
|
3755 // 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
|
3756 // 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
|
3757 // 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
|
3758 // 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
|
3759 // 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
|
3760 // 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
|
3761 if (retained_region != NULL && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3762 !retained_region->in_collection_set() && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3763 !(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
|
3764 !retained_region->is_empty() && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3765 !retained_region->isHumongous()) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3766 retained_region->set_saved_mark(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3767 _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
|
3768 _hr_printer.reuse(retained_region); |
342 | 3769 } |
3770 } | |
3771 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3772 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
|
3773 _survivor_gc_alloc_region.release(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3774 // 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
|
3775 // _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
|
3776 // _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
|
3777 // 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
|
3778 // condition. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3779 _retained_old_gc_alloc_region = _old_gc_alloc_region.release(); |
342 | 3780 } |
3781 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
3782 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
|
3783 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
|
3784 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
|
3785 _retained_old_gc_alloc_region = NULL; |
342 | 3786 } |
3787 | |
3788 void G1CollectedHeap::init_for_evac_failure(OopsInHeapRegionClosure* cl) { | |
3789 _drain_in_progress = false; | |
3790 set_evac_failure_closure(cl); | |
3791 _evac_failure_scan_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true); | |
3792 } | |
3793 | |
3794 void G1CollectedHeap::finalize_for_evac_failure() { | |
3795 assert(_evac_failure_scan_stack != NULL && | |
3796 _evac_failure_scan_stack->length() == 0, | |
3797 "Postcondition"); | |
3798 assert(!_drain_in_progress, "Postcondition"); | |
1045 | 3799 delete _evac_failure_scan_stack; |
342 | 3800 _evac_failure_scan_stack = NULL; |
3801 } | |
3802 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3803 class UpdateRSetDeferred : public OopsInHeapRegionClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3804 private: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3805 G1CollectedHeap* _g1; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3806 DirtyCardQueue *_dcq; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3807 CardTableModRefBS* _ct_bs; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3808 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3809 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3810 UpdateRSetDeferred(G1CollectedHeap* g1, DirtyCardQueue* dcq) : |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3811 _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
|
3812 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3813 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
|
3814 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
|
3815 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
|
3816 assert(_from->is_in_reserved(p), "paranoia"); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3817 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
|
3818 !_from->is_survivor()) { |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3819 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
|
3820 if (_ct_bs->mark_card_deferred(card_index)) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3821 _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
|
3822 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3823 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3824 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3825 }; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3826 |
342 | 3827 class RemoveSelfPointerClosure: public ObjectClosure { |
3828 private: | |
3829 G1CollectedHeap* _g1; | |
3830 ConcurrentMark* _cm; | |
3831 HeapRegion* _hr; | |
3832 size_t _prev_marked_bytes; | |
3833 size_t _next_marked_bytes; | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3834 OopsInHeapRegionClosure *_cl; |
342 | 3835 public: |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3836 RemoveSelfPointerClosure(G1CollectedHeap* g1, HeapRegion* hr, |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3837 OopsInHeapRegionClosure* cl) : |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3838 _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
|
3839 _next_marked_bytes(0), _cl(cl) {} |
342 | 3840 |
3841 size_t prev_marked_bytes() { return _prev_marked_bytes; } | |
3842 size_t next_marked_bytes() { return _next_marked_bytes; } | |
3843 | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3844 // <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
|
3845 // 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
|
3846 // 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
|
3847 // 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
|
3848 // |----- 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
|
3849 // 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
|
3850 // 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
|
3851 // 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
|
3852 // would point into middle of the filler object. |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3853 // 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
|
3854 // </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
|
3855 // |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3856 // 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
|
3857 // 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
|
3858 // 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
|
3859 // 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
|
3860 void do_object(oop obj) { |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3861 HeapWord* obj_addr = (HeapWord*) obj; |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3862 assert(_hr->is_in(obj_addr), "sanity"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3863 size_t obj_size = obj->size(); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3864 _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
|
3865 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
|
3866 // 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
|
3867 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
|
3868 _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
|
3869 assert(_cm->isPrevMarked(obj), "Should be marked!"); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3870 _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
|
3871 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
|
3872 _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
|
3873 } |
e0c09f7ec5c4
6702387: G1: assertion failure: assert(p == current_top || oop(p)->is_oop(),"p is not a block start")
iveresov
parents:
342
diff
changeset
|
3874 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
|
3875 // 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
|
3876 // 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
|
3877 // 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
|
3878 // 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
|
3879 // 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
|
3880 // 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
|
3881 // 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
|
3882 // 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
|
3883 // 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
|
3884 // 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
|
3885 // 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
|
3886 // 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
|
3887 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
|
3888 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
|
3889 } 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
|
3890 // 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
|
3891 // dummy object. |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3892 MemRegion mr((HeapWord*)obj, obj_size); |
481
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
457
diff
changeset
|
3893 CollectedHeap::fill_with_object(mr); |
342 | 3894 _cm->clearRangeBothMaps(mr); |
3895 } | |
3896 } | |
3897 }; | |
3898 | |
3899 void G1CollectedHeap::remove_self_forwarding_pointers() { | |
1705 | 3900 UpdateRSetImmediate immediate_update(_g1h->g1_rem_set()); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3901 DirtyCardQueue dcq(&_g1h->dirty_card_queue_set()); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3902 UpdateRSetDeferred deferred_update(_g1h, &dcq); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3903 OopsInHeapRegionClosure *cl; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3904 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3905 cl = &deferred_update; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3906 } else { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3907 cl = &immediate_update; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3908 } |
342 | 3909 HeapRegion* cur = g1_policy()->collection_set(); |
3910 while (cur != NULL) { | |
3911 assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!"); | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3912 assert(!cur->isHumongous(), "sanity"); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3913 |
342 | 3914 if (cur->evacuation_failed()) { |
3915 assert(cur->in_collection_set(), "bad CS"); | |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3916 RemoveSelfPointerClosure rspc(_g1h, cur, cl); |
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3917 |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3918 // 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
|
3919 // 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
|
3920 // re-allocated. However, when evacuation failure happens, a |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3921 // 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
|
3922 // 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
|
3923 // 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
|
3924 // whenever this might be required in the future. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3925 cur->rem_set()->reset_for_par_iteration(); |
2133
2250ee17e258
7007068: G1: refine the BOT during evac failure handling
tonyp
parents:
2039
diff
changeset
|
3926 cur->reset_bot(); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
3927 cl->set_region(cur); |
342 | 3928 cur->object_iterate(&rspc); |
3929 | |
3930 // A number of manipulations to make the TAMS be the current top, | |
3931 // and the marked bytes be the ones observed in the iteration. | |
3932 if (_g1h->concurrent_mark()->at_least_one_mark_complete()) { | |
3933 // The comments below are the postconditions achieved by the | |
3934 // calls. Note especially the last such condition, which says that | |
3935 // the count of marked bytes has been properly restored. | |
3936 cur->note_start_of_marking(false); | |
3937 // _next_top_at_mark_start == top, _next_marked_bytes == 0 | |
3938 cur->add_to_marked_bytes(rspc.prev_marked_bytes()); | |
3939 // _next_marked_bytes == prev_marked_bytes. | |
3940 cur->note_end_of_marking(); | |
3941 // _prev_top_at_mark_start == top(), | |
3942 // _prev_marked_bytes == prev_marked_bytes | |
3943 } | |
3944 // If there is no mark in progress, we modified the _next variables | |
3945 // above needlessly, but harmlessly. | |
3946 if (_g1h->mark_in_progress()) { | |
3947 cur->note_start_of_marking(false); | |
3948 // _next_top_at_mark_start == top, _next_marked_bytes == 0 | |
3949 // _next_marked_bytes == next_marked_bytes. | |
3950 } | |
3951 | |
3952 // Now make sure the region has the right index in the sorted array. | |
3953 g1_policy()->note_change_in_marked_bytes(cur); | |
3954 } | |
3955 cur = cur->next_in_collection_set(); | |
3956 } | |
3957 assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!"); | |
3958 | |
3959 // Now restore saved marks, if any. | |
3960 if (_objs_with_preserved_marks != NULL) { | |
3961 assert(_preserved_marks_of_objs != NULL, "Both or none."); | |
3962 guarantee(_objs_with_preserved_marks->length() == | |
3963 _preserved_marks_of_objs->length(), "Both or none."); | |
3964 for (int i = 0; i < _objs_with_preserved_marks->length(); i++) { | |
3965 oop obj = _objs_with_preserved_marks->at(i); | |
3966 markOop m = _preserved_marks_of_objs->at(i); | |
3967 obj->set_mark(m); | |
3968 } | |
3969 // Delete the preserved marks growable arrays (allocated on the C heap). | |
3970 delete _objs_with_preserved_marks; | |
3971 delete _preserved_marks_of_objs; | |
3972 _objs_with_preserved_marks = NULL; | |
3973 _preserved_marks_of_objs = NULL; | |
3974 } | |
3975 } | |
3976 | |
3977 void G1CollectedHeap::push_on_evac_failure_scan_stack(oop obj) { | |
3978 _evac_failure_scan_stack->push(obj); | |
3979 } | |
3980 | |
3981 void G1CollectedHeap::drain_evac_failure_scan_stack() { | |
3982 assert(_evac_failure_scan_stack != NULL, "precondition"); | |
3983 | |
3984 while (_evac_failure_scan_stack->length() > 0) { | |
3985 oop obj = _evac_failure_scan_stack->pop(); | |
3986 _evac_failure_closure->set_region(heap_region_containing(obj)); | |
3987 obj->oop_iterate_backwards(_evac_failure_closure); | |
3988 } | |
3989 } | |
3990 | |
3991 oop | |
3992 G1CollectedHeap::handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, | |
3973
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
3993 oop old, |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
3994 bool should_mark_root) { |
3323
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
3995 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
|
3996 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
|
3997 (HeapWord*) old)); |
342 | 3998 markOop m = old->mark(); |
3999 oop forward_ptr = old->forward_to_atomic(old); | |
4000 if (forward_ptr == NULL) { | |
4001 // Forward-to-self succeeded. | |
3973
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4002 |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4003 // should_mark_root will be true when this routine is called |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4004 // from a root scanning closure during an initial mark pause. |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4005 // In this case the thread that succeeds in self-forwarding the |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4006 // object is also responsible for marking the object. |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4007 if (should_mark_root) { |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4008 assert(!oopDesc::is_null(old), "shouldn't be"); |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4009 _cm->grayRoot(old); |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4010 } |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4011 |
342 | 4012 if (_evac_failure_closure != cl) { |
4013 MutexLockerEx x(EvacFailureStack_lock, Mutex::_no_safepoint_check_flag); | |
4014 assert(!_drain_in_progress, | |
4015 "Should only be true while someone holds the lock."); | |
4016 // Set the global evac-failure closure to the current thread's. | |
4017 assert(_evac_failure_closure == NULL, "Or locking has failed."); | |
4018 set_evac_failure_closure(cl); | |
4019 // Now do the common part. | |
4020 handle_evacuation_failure_common(old, m); | |
4021 // Reset to NULL. | |
4022 set_evac_failure_closure(NULL); | |
4023 } else { | |
4024 // The lock is already held, and this is recursive. | |
4025 assert(_drain_in_progress, "This should only be the recursive case."); | |
4026 handle_evacuation_failure_common(old, m); | |
4027 } | |
4028 return old; | |
4029 } 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
|
4030 // 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
|
4031 // 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
|
4032 // 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
|
4033 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
|
4034 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
|
4035 "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
|
4036 (HeapWord*) old, (HeapWord*) forward_ptr)); |
342 | 4037 return forward_ptr; |
4038 } | |
4039 } | |
4040 | |
4041 void G1CollectedHeap::handle_evacuation_failure_common(oop old, markOop m) { | |
4042 set_evacuation_failed(true); | |
4043 | |
4044 preserve_mark_if_necessary(old, m); | |
4045 | |
4046 HeapRegion* r = heap_region_containing(old); | |
4047 if (!r->evacuation_failed()) { | |
4048 r->set_evacuation_failed(true); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
4049 _hr_printer.evac_failure(r); |
342 | 4050 } |
4051 | |
4052 push_on_evac_failure_scan_stack(old); | |
4053 | |
4054 if (!_drain_in_progress) { | |
4055 // prevent recursion in copy_to_survivor_space() | |
4056 _drain_in_progress = true; | |
4057 drain_evac_failure_scan_stack(); | |
4058 _drain_in_progress = false; | |
4059 } | |
4060 } | |
4061 | |
4062 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
|
4063 assert(evacuation_failed(), "Oversaving!"); |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
4064 // 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
|
4065 // case of a promotion failure. |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
4066 if (m->must_be_preserved_for_promotion_failure(obj)) { |
342 | 4067 if (_objs_with_preserved_marks == NULL) { |
4068 assert(_preserved_marks_of_objs == NULL, "Both or none."); | |
4069 _objs_with_preserved_marks = | |
4070 new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true); | |
4071 _preserved_marks_of_objs = | |
4072 new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true); | |
4073 } | |
4074 _objs_with_preserved_marks->push(obj); | |
4075 _preserved_marks_of_objs->push(m); | |
4076 } | |
4077 } | |
4078 | |
4079 HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose, | |
4080 size_t word_size) { | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4081 if (purpose == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4082 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
|
4083 if (result != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4084 return result; |
342 | 4085 } else { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4086 // 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
|
4087 // object there. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4088 return old_attempt_allocation(word_size); |
342 | 4089 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4090 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4091 assert(purpose == GCAllocForTenured, "sanity"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4092 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
|
4093 if (result != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4094 return result; |
342 | 4095 } else { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4096 // 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
|
4097 // object there. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4098 return survivor_attempt_allocation(word_size); |
342 | 4099 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4100 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4101 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4102 ShouldNotReachHere(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4103 // 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
|
4104 return NULL; |
342 | 4105 } |
4106 | |
4107 #ifndef PRODUCT | |
4108 bool GCLabBitMapClosure::do_bit(size_t offset) { | |
4109 HeapWord* addr = _bitmap->offsetToHeapWord(offset); | |
4110 guarantee(_cm->isMarked(oop(addr)), "it should be!"); | |
4111 return true; | |
4112 } | |
4113 #endif // PRODUCT | |
4114 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4115 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4116 ParGCAllocBuffer(gclab_word_size), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4117 _should_mark_objects(false), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4118 _bitmap(G1CollectedHeap::heap()->reserved_region().start(), gclab_word_size), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4119 _retired(false) |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4120 { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4121 //_should_mark_objects is set to true when G1ParCopyHelper needs to |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4122 // mark the forwarded location of an evacuated object. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4123 // We set _should_mark_objects to true if marking is active, i.e. when we |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4124 // need to propagate a mark, or during an initial mark pause, i.e. when we |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4125 // need to mark objects immediately reachable by the roots. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4126 if (G1CollectedHeap::heap()->mark_in_progress() || |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4127 G1CollectedHeap::heap()->g1_policy()->during_initial_mark_pause()) { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4128 _should_mark_objects = true; |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4129 } |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4130 } |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4131 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4132 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, int queue_num) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4133 : _g1h(g1h), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4134 _refs(g1h->task_queue(queue_num)), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4135 _dcq(&g1h->dirty_card_queue_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4136 _ct_bs((CardTableModRefBS*)_g1h->barrier_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4137 _g1_rem(g1h->g1_rem_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4138 _hash_seed(17), _queue_num(queue_num), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4139 _term_attempts(0), |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4140 _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4141 _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
|
4142 _age_table(false), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4143 _strong_roots_time(0), _term_time(0), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4144 _alloc_buffer_waste(0), _undo_waste(0) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4145 { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4146 // we allocate G1YoungSurvRateNumRegions plus one entries, since |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4147 // 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
|
4148 // non-young regions (where the age is -1) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4149 // 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
|
4150 // an attempt to eliminate cache contention |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4151 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
|
4152 size_t array_length = PADDING_ELEM_NUM + |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4153 real_length + |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4154 PADDING_ELEM_NUM; |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4155 _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
|
4156 if (_surviving_young_words_base == NULL) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4157 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
|
4158 "Not enough space for young surv histo."); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4159 _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
|
4160 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
|
4161 |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4162 _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4163 _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4164 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4165 _start = os::elapsedTime(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4166 } |
342 | 4167 |
1709 | 4168 void |
4169 G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st) | |
4170 { | |
4171 st->print_raw_cr("GC Termination Stats"); | |
4172 st->print_raw_cr(" elapsed --strong roots-- -------termination-------" | |
4173 " ------waste (KiB)------"); | |
4174 st->print_raw_cr("thr ms ms % ms % attempts" | |
4175 " total alloc undo"); | |
4176 st->print_raw_cr("--- --------- --------- ------ --------- ------ --------" | |
4177 " ------- ------- -------"); | |
4178 } | |
4179 | |
4180 void | |
4181 G1ParScanThreadState::print_termination_stats(int i, | |
4182 outputStream* const st) const | |
4183 { | |
4184 const double elapsed_ms = elapsed_time() * 1000.0; | |
4185 const double s_roots_ms = strong_roots_time() * 1000.0; | |
4186 const double term_ms = term_time() * 1000.0; | |
4187 st->print_cr("%3d %9.2f %9.2f %6.2f " | |
4188 "%9.2f %6.2f " SIZE_FORMAT_W(8) " " | |
4189 SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7), | |
4190 i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms, | |
4191 term_ms, term_ms * 100 / elapsed_ms, term_attempts(), | |
4192 (alloc_buffer_waste() + undo_waste()) * HeapWordSize / K, | |
4193 alloc_buffer_waste() * HeapWordSize / K, | |
4194 undo_waste() * HeapWordSize / K); | |
4195 } | |
4196 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4197 #ifdef ASSERT |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4198 bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4199 assert(ref != NULL, "invariant"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4200 assert(UseCompressedOops, "sanity"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4201 assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref)); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4202 oop p = oopDesc::load_decode_heap_oop(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4203 assert(_g1h->is_in_g1_reserved(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4204 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4205 return true; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4206 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4207 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4208 bool G1ParScanThreadState::verify_ref(oop* ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4209 assert(ref != NULL, "invariant"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4210 if (has_partial_array_mask(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4211 // Must be in the collection set--it's already been copied. |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4212 oop p = clear_partial_array_mask(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4213 assert(_g1h->obj_in_cs(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4214 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4215 } else { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4216 oop p = oopDesc::load_decode_heap_oop(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4217 assert(_g1h->is_in_g1_reserved(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4218 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4219 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4220 return true; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4221 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4222 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4223 bool G1ParScanThreadState::verify_task(StarTask ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4224 if (ref.is_narrow()) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4225 return verify_ref((narrowOop*) ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4226 } else { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4227 return verify_ref((oop*) ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4228 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4229 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4230 #endif // ASSERT |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4231 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4232 void G1ParScanThreadState::trim_queue() { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4233 assert(_evac_cl != NULL, "not set"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4234 assert(_evac_failure_cl != NULL, "not set"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4235 assert(_partial_scan_cl != NULL, "not set"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4236 |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4237 StarTask ref; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4238 do { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4239 // Drain the overflow stack first, so other threads can steal. |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4240 while (refs()->pop_overflow(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4241 deal_with_reference(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4242 } |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4243 |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4244 while (refs()->pop_local(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4245 deal_with_reference(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4246 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4247 } while (!refs()->is_empty()); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4248 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4249 |
342 | 4250 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state) : |
4251 _g1(g1), _g1_rem(_g1->g1_rem_set()), _cm(_g1->concurrent_mark()), | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4252 _par_scan_state(par_scan_state), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4253 _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()), |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4254 _mark_in_progress(_g1->mark_in_progress()) { } |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4255 |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4256 template <class T> void G1ParCopyHelper::mark_object(T* p) { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4257 // This is called from do_oop_work for objects that are not |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4258 // in the collection set. Objects in the collection set |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4259 // are marked after they have been evacuated. |
342 | 4260 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4261 T heap_oop = oopDesc::load_heap_oop(p); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4262 if (!oopDesc::is_null(heap_oop)) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4263 oop obj = oopDesc::decode_heap_oop(heap_oop); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4264 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
|
4265 if (_g1->is_in_g1_reserved(addr)) { |
342 | 4266 _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
|
4267 } |
342 | 4268 } |
4269 } | |
4270 | |
3973
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4271 oop G1ParCopyHelper::copy_to_survivor_space(oop old, bool should_mark_root, |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4272 bool should_mark_copy) { |
342 | 4273 size_t word_sz = old->size(); |
4274 HeapRegion* from_region = _g1->heap_region_containing_raw(old); | |
4275 // +1 to make the -1 indexes valid... | |
4276 int young_index = from_region->young_index_in_cset()+1; | |
4277 assert( (from_region->is_young() && young_index > 0) || | |
4278 (!from_region->is_young() && young_index == 0), "invariant" ); | |
4279 G1CollectorPolicy* g1p = _g1->g1_policy(); | |
4280 markOop m = old->mark(); | |
545 | 4281 int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() |
4282 : m->age(); | |
4283 GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, | |
342 | 4284 word_sz); |
4285 HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz); | |
4286 oop obj = oop(obj_ptr); | |
4287 | |
4288 if (obj_ptr == NULL) { | |
4289 // This will either forward-to-self, or detect that someone else has | |
4290 // installed a forwarding pointer. | |
4291 OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure(); | |
3973
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4292 return _g1->handle_evacuation_failure_par(cl, old, should_mark_root); |
342 | 4293 } |
4294 | |
526 | 4295 // We're going to allocate linearly, so might as well prefetch ahead. |
4296 Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes); | |
4297 | |
342 | 4298 oop forward_ptr = old->forward_to_atomic(obj); |
4299 if (forward_ptr == NULL) { | |
4300 Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); | |
526 | 4301 if (g1p->track_object_age(alloc_purpose)) { |
4302 // We could simply do obj->incr_age(). However, this causes a | |
4303 // performance issue. obj->incr_age() will first check whether | |
4304 // the object has a displaced mark by checking its mark word; | |
4305 // getting the mark word from the new location of the object | |
4306 // stalls. So, given that we already have the mark word and we | |
4307 // are about to install it anyway, it's better to increase the | |
4308 // age on the mark word, when the object does not have a | |
4309 // displaced mark word. We're not expecting many objects to have | |
4310 // a displaced marked word, so that case is not optimized | |
4311 // further (it could be...) and we simply call obj->incr_age(). | |
4312 | |
4313 if (m->has_displaced_mark_helper()) { | |
4314 // in this case, we have to install the mark word first, | |
4315 // otherwise obj looks to be forwarded (the old mark word, | |
4316 // which contains the forward pointer, was copied) | |
4317 obj->set_mark(m); | |
4318 obj->incr_age(); | |
4319 } else { | |
4320 m = m->incr_age(); | |
545 | 4321 obj->set_mark(m); |
526 | 4322 } |
545 | 4323 _par_scan_state->age_table()->add(obj, word_sz); |
4324 } else { | |
4325 obj->set_mark(m); | |
526 | 4326 } |
4327 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4328 // Mark the evacuated object or propagate "next" mark bit |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4329 if (should_mark_copy) { |
342 | 4330 if (!use_local_bitmaps || |
4331 !_par_scan_state->alloc_buffer(alloc_purpose)->mark(obj_ptr)) { | |
4332 // if we couldn't mark it on the local bitmap (this happens when | |
4333 // the object was not allocated in the GCLab), we have to bite | |
4334 // the bullet and do the standard parallel mark | |
4335 _cm->markAndGrayObjectIfNecessary(obj); | |
4336 } | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4337 |
342 | 4338 if (_g1->isMarkedNext(old)) { |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4339 // Unmark the object's old location so that marking |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4340 // doesn't think the old object is alive. |
342 | 4341 _cm->nextMarkBitMap()->parClear((HeapWord*)old); |
4342 } | |
4343 } | |
4344 | |
4345 size_t* surv_young_words = _par_scan_state->surviving_young_words(); | |
4346 surv_young_words[young_index] += word_sz; | |
4347 | |
4348 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { | |
4349 arrayOop(old)->set_length(0); | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4350 oop* old_p = set_partial_array_mask(old); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4351 _par_scan_state->push_on_queue(old_p); |
342 | 4352 } else { |
526 | 4353 // No point in using the slower heap_region_containing() method, |
4354 // given that we know obj is in the heap. | |
4355 _scanner->set_region(_g1->heap_region_containing_raw(obj)); | |
342 | 4356 obj->oop_iterate_backwards(_scanner); |
4357 } | |
4358 } else { | |
4359 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); | |
4360 obj = forward_ptr; | |
4361 } | |
4362 return obj; | |
4363 } | |
4364 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4365 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4366 template <class T> |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4367 void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object> |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4368 ::do_oop_work(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4369 oop obj = oopDesc::load_decode_heap_oop(p); |
342 | 4370 assert(barrier != G1BarrierRS || obj != NULL, |
4371 "Precondition: G1BarrierRS implies obj is nonNull"); | |
4372 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4373 // Marking: |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4374 // If the object is in the collection set, then the thread |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4375 // that copies the object should mark, or propagate the |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4376 // mark to, the evacuated object. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4377 // If the object is not in the collection set then we |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4378 // should call the mark_object() method depending on the |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4379 // value of the template parameter do_mark_object (which will |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4380 // be true for root scanning closures during an initial mark |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4381 // pause). |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4382 // The mark_object() method first checks whether the object |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4383 // is marked and, if not, attempts to mark the object. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4384 |
526 | 4385 // 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
|
4386 if (_g1->in_cset_fast_test(obj)) { |
526 | 4387 if (obj->is_forwarded()) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4388 oopDesc::encode_store_heap_oop(p, obj->forwardee()); |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4389 // If we are a root scanning closure during an initial |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4390 // mark pause (i.e. do_mark_object will be true) then |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4391 // we also need to handle marking of roots in the |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4392 // event of an evacuation failure. In the event of an |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4393 // evacuation failure, the object is forwarded to itself |
3973
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4394 // and not copied. For root-scanning closures, the |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4395 // object would be marked after a successful self-forward |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4396 // but an object could be pointed to by both a root and non |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4397 // root location and be self-forwarded by a non-root-scanning |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4398 // closure. Therefore we also have to attempt to mark the |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4399 // self-forwarded root object here. |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4400 if (do_mark_object && obj->forwardee() == obj) { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4401 mark_object(p); |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4402 } |
526 | 4403 } else { |
3973
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4404 // During an initial mark pause, objects that are pointed to |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4405 // by the roots need to be marked - even in the event of an |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4406 // evacuation failure. We pass the template parameter |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4407 // do_mark_object (which is true for root scanning closures |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4408 // during an initial mark pause) to copy_to_survivor_space |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4409 // which will pass it on to the evacuation failure handling |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4410 // code. The thread that successfully self-forwards a root |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4411 // object to itself is responsible for marking the object. |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4412 bool should_mark_root = do_mark_object; |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4413 |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4414 // We need to mark the copied object if we're a root scanning |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4415 // closure during an initial mark pause (i.e. do_mark_object |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4416 // will be true), or the object is already marked and we need |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4417 // to propagate the mark to the evacuated copy. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4418 bool should_mark_copy = do_mark_object || |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4419 _during_initial_mark || |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4420 (_mark_in_progress && !_g1->is_obj_ill(obj)); |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4421 |
3973
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4422 oop copy_oop = copy_to_survivor_space(obj, should_mark_root, |
663cb89032b1
7092412: G1: Some roots not marked during an initial mark that gets an evacuation failure
johnc
parents:
3920
diff
changeset
|
4423 should_mark_copy); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4424 oopDesc::encode_store_heap_oop(p, copy_oop); |
342 | 4425 } |
526 | 4426 // When scanning the RS, we only care about objs in CS. |
4427 if (barrier == G1BarrierRS) { | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4428 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); |
342 | 4429 } |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4430 } else { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4431 // The object is not in collection set. If we're a root scanning |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4432 // closure during an initial mark pause (i.e. do_mark_object will |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4433 // be true) then attempt to mark the object. |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4434 if (do_mark_object) { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4435 mark_object(p); |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4436 } |
526 | 4437 } |
4438 | |
4439 if (barrier == G1BarrierEvac && obj != NULL) { | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4440 _par_scan_state->update_rs(_from, p, _par_scan_state->queue_num()); |
526 | 4441 } |
4442 | |
4443 if (do_gen_barrier && obj != NULL) { | |
4444 par_do_barrier(p); | |
4445 } | |
4446 } | |
4447 | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4448 template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(oop* p); |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4449 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
|
4450 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4451 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) { |
526 | 4452 assert(has_partial_array_mask(p), "invariant"); |
4453 oop old = clear_partial_array_mask(p); | |
342 | 4454 assert(old->is_objArray(), "must be obj array"); |
4455 assert(old->is_forwarded(), "must be forwarded"); | |
4456 assert(Universe::heap()->is_in_reserved(old), "must be in heap."); | |
4457 | |
4458 objArrayOop obj = objArrayOop(old->forwardee()); | |
4459 assert((void*)old != (void*)old->forwardee(), "self forwarding here?"); | |
4460 // Process ParGCArrayScanChunk elements now | |
4461 // and push the remainder back onto queue | |
4462 int start = arrayOop(old)->length(); | |
4463 int end = obj->length(); | |
4464 int remainder = end - start; | |
4465 assert(start <= end, "just checking"); | |
4466 if (remainder > 2 * ParGCArrayScanChunk) { | |
4467 // Test above combines last partial chunk with a full chunk | |
4468 end = start + ParGCArrayScanChunk; | |
4469 arrayOop(old)->set_length(end); | |
4470 // Push remainder. | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4471 oop* old_p = set_partial_array_mask(old); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4472 assert(arrayOop(old)->length() < obj->length(), "Empty push?"); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4473 _par_scan_state->push_on_queue(old_p); |
342 | 4474 } else { |
4475 // Restore length so that the heap remains parsable in | |
4476 // case of evacuation failure. | |
4477 arrayOop(old)->set_length(end); | |
4478 } | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4479 _scanner.set_region(_g1->heap_region_containing_raw(obj)); |
342 | 4480 // 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
|
4481 obj->oop_iterate_range(&_scanner, start, end); |
342 | 4482 } |
4483 | |
4484 class G1ParEvacuateFollowersClosure : public VoidClosure { | |
4485 protected: | |
4486 G1CollectedHeap* _g1h; | |
4487 G1ParScanThreadState* _par_scan_state; | |
4488 RefToScanQueueSet* _queues; | |
4489 ParallelTaskTerminator* _terminator; | |
4490 | |
4491 G1ParScanThreadState* par_scan_state() { return _par_scan_state; } | |
4492 RefToScanQueueSet* queues() { return _queues; } | |
4493 ParallelTaskTerminator* terminator() { return _terminator; } | |
4494 | |
4495 public: | |
4496 G1ParEvacuateFollowersClosure(G1CollectedHeap* g1h, | |
4497 G1ParScanThreadState* par_scan_state, | |
4498 RefToScanQueueSet* queues, | |
4499 ParallelTaskTerminator* terminator) | |
4500 : _g1h(g1h), _par_scan_state(par_scan_state), | |
4501 _queues(queues), _terminator(terminator) {} | |
4502 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4503 void do_void(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4504 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4505 private: |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4506 inline bool offer_termination(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4507 }; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4508 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4509 bool G1ParEvacuateFollowersClosure::offer_termination() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4510 G1ParScanThreadState* const pss = par_scan_state(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4511 pss->start_term_time(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4512 const bool res = terminator()->offer_termination(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4513 pss->end_term_time(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4514 return res; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4515 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4516 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4517 void G1ParEvacuateFollowersClosure::do_void() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4518 StarTask stolen_task; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4519 G1ParScanThreadState* const pss = par_scan_state(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4520 pss->trim_queue(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4521 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4522 do { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4523 while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4524 assert(pss->verify_task(stolen_task), "sanity"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4525 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
|
4526 pss->deal_with_reference((narrowOop*) stolen_task); |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4527 } else { |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4528 pss->deal_with_reference((oop*) stolen_task); |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4529 } |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4530 |
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4531 // 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
|
4532 // 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
|
4533 // we drain the queues as necessary. |
342 | 4534 pss->trim_queue(); |
4535 } | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4536 } while (!offer_termination()); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4537 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4538 pss->retire_alloc_buffers(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4539 } |
342 | 4540 |
4541 class G1ParTask : public AbstractGangTask { | |
4542 protected: | |
4543 G1CollectedHeap* _g1h; | |
4544 RefToScanQueueSet *_queues; | |
4545 ParallelTaskTerminator _terminator; | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4546 int _n_workers; |
342 | 4547 |
4548 Mutex _stats_lock; | |
4549 Mutex* stats_lock() { return &_stats_lock; } | |
4550 | |
4551 size_t getNCards() { | |
4552 return (_g1h->capacity() + G1BlockOffsetSharedArray::N_bytes - 1) | |
4553 / G1BlockOffsetSharedArray::N_bytes; | |
4554 } | |
4555 | |
4556 public: | |
4557 G1ParTask(G1CollectedHeap* g1h, int workers, RefToScanQueueSet *task_queues) | |
4558 : AbstractGangTask("G1 collection"), | |
4559 _g1h(g1h), | |
4560 _queues(task_queues), | |
4561 _terminator(workers, _queues), | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4562 _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
|
4563 _n_workers(workers) |
342 | 4564 {} |
4565 | |
4566 RefToScanQueueSet* queues() { return _queues; } | |
4567 | |
4568 RefToScanQueue *work_queue(int i) { | |
4569 return queues()->queue(i); | |
4570 } | |
4571 | |
4572 void work(int i) { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4573 if (i >= _n_workers) return; // no work needed this round |
1611 | 4574 |
4575 double start_time_ms = os::elapsedTime() * 1000.0; | |
4576 _g1h->g1_policy()->record_gc_worker_start_time(i, start_time_ms); | |
4577 | |
342 | 4578 ResourceMark rm; |
4579 HandleMark hm; | |
4580 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4581 ReferenceProcessor* rp = _g1h->ref_processor_stw(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4582 |
526 | 4583 G1ParScanThreadState pss(_g1h, i); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4584 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, rp); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4585 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4586 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, rp); |
342 | 4587 |
4588 pss.set_evac_closure(&scan_evac_cl); | |
4589 pss.set_evac_failure_closure(&evac_failure_cl); | |
4590 pss.set_partial_scan_closure(&partial_scan_cl); | |
4591 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4592 G1ParScanExtRootClosure only_scan_root_cl(_g1h, &pss, rp); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4593 G1ParScanPermClosure only_scan_perm_cl(_g1h, &pss, rp); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4594 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4595 G1ParScanAndMarkExtRootClosure scan_mark_root_cl(_g1h, &pss, rp); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4596 G1ParScanAndMarkPermClosure scan_mark_perm_cl(_g1h, &pss, rp); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4597 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4598 OopClosure* scan_root_cl = &only_scan_root_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4599 OopsInHeapRegionClosure* scan_perm_cl = &only_scan_perm_cl; |
342 | 4600 |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
4601 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4602 // We also need to mark copied objects. |
342 | 4603 scan_root_cl = &scan_mark_root_cl; |
4604 scan_perm_cl = &scan_mark_perm_cl; | |
4605 } | |
4606 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4607 // The following closure is used to scan RSets looking for reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4608 // fields that point into the collection set. The actual field iteration |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4609 // is performed by a FilterIntoCSClosure, whose do_oop method calls the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4610 // do_oop method of the following closure. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4611 // Therefore we want to record the reference processor in the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4612 // FilterIntoCSClosure. To do so we record the STW reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4613 // processor into the following closure and pass it to the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4614 // FilterIntoCSClosure in HeapRegionDCTOC::walk_mem_region_with_cl. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4615 G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss, rp); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4616 |
342 | 4617 pss.start_strong_roots(); |
4618 _g1h->g1_process_strong_roots(/* not collecting perm */ false, | |
4619 SharedHeap::SO_AllClasses, | |
4620 scan_root_cl, | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4621 &push_heap_rs_cl, |
342 | 4622 scan_perm_cl, |
4623 i); | |
4624 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
|
4625 |
342 | 4626 { |
4627 double start = os::elapsedTime(); | |
4628 G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator); | |
4629 evac.do_void(); | |
4630 double elapsed_ms = (os::elapsedTime()-start)*1000.0; | |
4631 double term_ms = pss.term_time()*1000.0; | |
4632 _g1h->g1_policy()->record_obj_copy_time(i, elapsed_ms-term_ms); | |
1611 | 4633 _g1h->g1_policy()->record_termination(i, term_ms, pss.term_attempts()); |
342 | 4634 } |
1282 | 4635 _g1h->g1_policy()->record_thread_age_table(pss.age_table()); |
342 | 4636 _g1h->update_surviving_young_words(pss.surviving_young_words()+1); |
4637 | |
4638 // Clean up any par-expanded rem sets. | |
4639 HeapRegionRemSet::par_cleanup(); | |
4640 | |
4641 if (ParallelGCVerbose) { | |
1709 | 4642 MutexLocker x(stats_lock()); |
4643 pss.print_termination_stats(i); | |
342 | 4644 } |
4645 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4646 assert(pss.refs()->is_empty(), "should be empty"); |
1611 | 4647 double end_time_ms = os::elapsedTime() * 1000.0; |
4648 _g1h->g1_policy()->record_gc_worker_end_time(i, end_time_ms); | |
342 | 4649 } |
4650 }; | |
4651 | |
4652 // *** Common G1 Evacuation Stuff | |
4653 | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
4654 // This method is run in a GC worker. |
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
4655 |
342 | 4656 void |
4657 G1CollectedHeap:: | |
4658 g1_process_strong_roots(bool collecting_perm_gen, | |
4659 SharedHeap::ScanningOption so, | |
4660 OopClosure* scan_non_heap_roots, | |
4661 OopsInHeapRegionClosure* scan_rs, | |
4662 OopsInGenClosure* scan_perm, | |
4663 int worker_i) { | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4664 |
342 | 4665 // First scan the strong roots, including the perm gen. |
4666 double ext_roots_start = os::elapsedTime(); | |
4667 double closure_app_time_sec = 0.0; | |
4668 | |
4669 BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); | |
4670 BufferingOopsInGenClosure buf_scan_perm(scan_perm); | |
4671 buf_scan_perm.set_generation(perm_gen()); | |
4672 | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4673 // 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
|
4674 // unaligned oop locations. |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4675 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
|
4676 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4677 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
|
4678 collecting_perm_gen, so, |
342 | 4679 &buf_scan_non_heap_roots, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4680 &eager_scan_code_roots, |
342 | 4681 &buf_scan_perm); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4682 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4683 // Now the CM ref_processor roots. |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4684 if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4685 // We need to treat the discovered reference lists of the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4686 // concurrent mark ref processor as roots and keep entries |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4687 // (which are added by the marking threads) on them live |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4688 // until they can be processed at the end of marking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4689 ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots); |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4690 } |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4691 |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4692 // Finish up any enqueued closure apps (attributed as object copy time). |
342 | 4693 buf_scan_non_heap_roots.done(); |
4694 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
|
4695 |
342 | 4696 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
|
4697 |
342 | 4698 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
|
4699 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
|
4700 buf_scan_non_heap_roots.closure_app_seconds(); |
342 | 4701 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
|
4702 |
342 | 4703 double ext_root_time_ms = |
4704 ((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
|
4705 |
342 | 4706 g1_policy()->record_ext_root_scan_time(worker_i, ext_root_time_ms); |
4707 | |
4708 // Scan strong roots in mark stack. | |
4709 if (!_process_strong_tasks->is_task_claimed(G1H_PS_mark_stack_oops_do)) { | |
4710 concurrent_mark()->oops_do(scan_non_heap_roots); | |
4711 } | |
4712 double mark_stack_scan_ms = (os::elapsedTime() - ext_roots_end) * 1000.0; | |
4713 g1_policy()->record_mark_stack_scan_time(worker_i, mark_stack_scan_ms); | |
4714 | |
4715 // Now scan the complement of the collection set. | |
4716 if (scan_rs != NULL) { | |
4717 g1_rem_set()->oops_into_collection_set_do(scan_rs, worker_i); | |
4718 } | |
3823
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
4719 |
342 | 4720 _process_strong_tasks->all_tasks_completed(); |
4721 } | |
4722 | |
4723 void | |
4724 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure, | |
4725 OopClosure* non_root_closure) { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
4726 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
|
4727 SharedHeap::process_weak_roots(root_closure, &roots_in_blobs, non_root_closure); |
342 | 4728 } |
4729 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4730 // Weak Reference Processing support |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4731 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4732 // An always "is_alive" closure that is used to preserve referents. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4733 // If the object is non-null then it's alive. Used in the preservation |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4734 // of referent objects that are pointed to by reference objects |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4735 // discovered by the CM ref processor. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4736 class G1AlwaysAliveClosure: public BoolObjectClosure { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4737 G1CollectedHeap* _g1; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4738 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4739 G1AlwaysAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4740 void do_object(oop p) { assert(false, "Do not call."); } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4741 bool do_object_b(oop p) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4742 if (p != NULL) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4743 return true; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4744 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4745 return false; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4746 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4747 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4748 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4749 bool G1STWIsAliveClosure::do_object_b(oop p) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4750 // An object is reachable if it is outside the collection set, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4751 // or is inside and copied. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4752 return !_g1->obj_in_cs(p) || p->is_forwarded(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4753 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4754 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4755 // Non Copying Keep Alive closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4756 class G1KeepAliveClosure: public OopClosure { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4757 G1CollectedHeap* _g1; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4758 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4759 G1KeepAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4760 void do_oop(narrowOop* p) { guarantee(false, "Not needed"); } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4761 void do_oop( oop* p) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4762 oop obj = *p; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4763 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4764 if (_g1->obj_in_cs(obj)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4765 assert( obj->is_forwarded(), "invariant" ); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4766 *p = obj->forwardee(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4767 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4768 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4769 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4770 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4771 // Copying Keep Alive closure - can be called from both |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4772 // serial and parallel code as long as different worker |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4773 // threads utilize different G1ParScanThreadState instances |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4774 // and different queues. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4775 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4776 class G1CopyingKeepAliveClosure: public OopClosure { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4777 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4778 OopClosure* _copy_non_heap_obj_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4779 OopsInHeapRegionClosure* _copy_perm_obj_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4780 G1ParScanThreadState* _par_scan_state; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4781 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4782 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4783 G1CopyingKeepAliveClosure(G1CollectedHeap* g1h, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4784 OopClosure* non_heap_obj_cl, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4785 OopsInHeapRegionClosure* perm_obj_cl, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4786 G1ParScanThreadState* pss): |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4787 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4788 _copy_non_heap_obj_cl(non_heap_obj_cl), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4789 _copy_perm_obj_cl(perm_obj_cl), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4790 _par_scan_state(pss) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4791 {} |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4792 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4793 virtual void do_oop(narrowOop* p) { do_oop_work(p); } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4794 virtual void do_oop( oop* p) { do_oop_work(p); } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4795 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4796 template <class T> void do_oop_work(T* p) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4797 oop obj = oopDesc::load_decode_heap_oop(p); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4798 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4799 if (_g1h->obj_in_cs(obj)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4800 // If the referent object has been forwarded (either copied |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4801 // to a new location or to itself in the event of an |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4802 // evacuation failure) then we need to update the reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4803 // field and, if both reference and referent are in the G1 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4804 // heap, update the RSet for the referent. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4805 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4806 // If the referent has not been forwarded then we have to keep |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4807 // it alive by policy. Therefore we have copy the referent. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4808 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4809 // If the reference field is in the G1 heap then we can push |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4810 // on the PSS queue. When the queue is drained (after each |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4811 // phase of reference processing) the object and it's followers |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4812 // will be copied, the reference field set to point to the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4813 // new location, and the RSet updated. Otherwise we need to |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4814 // use the the non-heap or perm closures directly to copy |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4815 // the refernt object and update the pointer, while avoiding |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4816 // updating the RSet. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4817 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4818 if (_g1h->is_in_g1_reserved(p)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4819 _par_scan_state->push_on_queue(p); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4820 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4821 // The reference field is not in the G1 heap. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4822 if (_g1h->perm_gen()->is_in(p)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4823 _copy_perm_obj_cl->do_oop(p); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4824 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4825 _copy_non_heap_obj_cl->do_oop(p); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4826 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4827 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4828 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4829 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4830 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4831 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4832 // Serial drain queue closure. Called as the 'complete_gc' |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4833 // closure for each discovered list in some of the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4834 // reference processing phases. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4835 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4836 class G1STWDrainQueueClosure: public VoidClosure { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4837 protected: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4838 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4839 G1ParScanThreadState* _par_scan_state; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4840 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4841 G1ParScanThreadState* par_scan_state() { return _par_scan_state; } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4842 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4843 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4844 G1STWDrainQueueClosure(G1CollectedHeap* g1h, G1ParScanThreadState* pss) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4845 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4846 _par_scan_state(pss) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4847 { } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4848 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4849 void do_void() { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4850 G1ParScanThreadState* const pss = par_scan_state(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4851 pss->trim_queue(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4852 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4853 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4854 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4855 // Parallel Reference Processing closures |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4856 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4857 // Implementation of AbstractRefProcTaskExecutor for parallel reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4858 // processing during G1 evacuation pauses. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4859 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4860 class G1STWRefProcTaskExecutor: public AbstractRefProcTaskExecutor { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4861 private: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4862 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4863 RefToScanQueueSet* _queues; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4864 WorkGang* _workers; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4865 int _active_workers; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4866 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4867 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4868 G1STWRefProcTaskExecutor(G1CollectedHeap* g1h, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4869 WorkGang* workers, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4870 RefToScanQueueSet *task_queues, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4871 int n_workers) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4872 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4873 _queues(task_queues), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4874 _workers(workers), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4875 _active_workers(n_workers) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4876 { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4877 assert(n_workers > 0, "shouldn't call this otherwise"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4878 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4879 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4880 // Executes the given task using concurrent marking worker threads. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4881 virtual void execute(ProcessTask& task); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4882 virtual void execute(EnqueueTask& task); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4883 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4884 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4885 // Gang task for possibly parallel reference processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4886 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4887 class G1STWRefProcTaskProxy: public AbstractGangTask { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4888 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4889 ProcessTask& _proc_task; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4890 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4891 RefToScanQueueSet *_task_queues; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4892 ParallelTaskTerminator* _terminator; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4893 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4894 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4895 G1STWRefProcTaskProxy(ProcessTask& proc_task, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4896 G1CollectedHeap* g1h, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4897 RefToScanQueueSet *task_queues, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4898 ParallelTaskTerminator* terminator) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4899 AbstractGangTask("Process reference objects in parallel"), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4900 _proc_task(proc_task), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4901 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4902 _task_queues(task_queues), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4903 _terminator(terminator) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4904 {} |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4905 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4906 virtual void work(int i) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4907 // The reference processing task executed by a single worker. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4908 ResourceMark rm; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4909 HandleMark hm; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4910 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4911 G1STWIsAliveClosure is_alive(_g1h); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4912 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4913 G1ParScanThreadState pss(_g1h, i); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4914 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4915 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4916 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4917 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4918 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4919 pss.set_evac_closure(&scan_evac_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4920 pss.set_evac_failure_closure(&evac_failure_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4921 pss.set_partial_scan_closure(&partial_scan_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4922 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4923 G1ParScanExtRootClosure only_copy_non_heap_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4924 G1ParScanPermClosure only_copy_perm_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4925 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4926 G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4927 G1ParScanAndMarkPermClosure copy_mark_perm_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4928 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4929 OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4930 OopsInHeapRegionClosure* copy_perm_cl = &only_copy_perm_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4931 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4932 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4933 // We also need to mark copied objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4934 copy_non_heap_cl = ©_mark_non_heap_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4935 copy_perm_cl = ©_mark_perm_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4936 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4937 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4938 // Keep alive closure. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4939 G1CopyingKeepAliveClosure keep_alive(_g1h, copy_non_heap_cl, copy_perm_cl, &pss); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4940 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4941 // Complete GC closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4942 G1ParEvacuateFollowersClosure drain_queue(_g1h, &pss, _task_queues, _terminator); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4943 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4944 // Call the reference processing task's work routine. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4945 _proc_task.work(i, is_alive, keep_alive, drain_queue); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4946 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4947 // Note we cannot assert that the refs array is empty here as not all |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4948 // of the processing tasks (specifically phase2 - pp2_work) execute |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4949 // the complete_gc closure (which ordinarily would drain the queue) so |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4950 // the queue may not be empty. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4951 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4952 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4953 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4954 // Driver routine for parallel reference processing. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4955 // Creates an instance of the ref processing gang |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4956 // task and has the worker threads execute it. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4957 void G1STWRefProcTaskExecutor::execute(ProcessTask& proc_task) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4958 assert(_workers != NULL, "Need parallel worker threads."); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4959 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4960 ParallelTaskTerminator terminator(_active_workers, _queues); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4961 G1STWRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _queues, &terminator); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4962 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4963 _g1h->set_par_threads(_active_workers); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4964 _workers->run_task(&proc_task_proxy); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4965 _g1h->set_par_threads(0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4966 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4967 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4968 // Gang task for parallel reference enqueueing. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4969 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4970 class G1STWRefEnqueueTaskProxy: public AbstractGangTask { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4971 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4972 EnqueueTask& _enq_task; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4973 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4974 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4975 G1STWRefEnqueueTaskProxy(EnqueueTask& enq_task) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4976 AbstractGangTask("Enqueue reference objects in parallel"), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4977 _enq_task(enq_task) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4978 { } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4979 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4980 virtual void work(int i) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4981 _enq_task.work(i); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4982 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4983 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4984 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4985 // Driver routine for parallel reference enqueing. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4986 // Creates an instance of the ref enqueueing gang |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4987 // task and has the worker threads execute it. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4988 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4989 void G1STWRefProcTaskExecutor::execute(EnqueueTask& enq_task) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4990 assert(_workers != NULL, "Need parallel worker threads."); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4991 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4992 G1STWRefEnqueueTaskProxy enq_task_proxy(enq_task); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4993 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4994 _g1h->set_par_threads(_active_workers); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4995 _workers->run_task(&enq_task_proxy); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4996 _g1h->set_par_threads(0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4997 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4998 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4999 // End of weak reference support closures |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5000 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5001 // Abstract task used to preserve (i.e. copy) any referent objects |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5002 // that are in the collection set and are pointed to by reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5003 // objects discovered by the CM ref processor. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5004 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5005 class G1ParPreserveCMReferentsTask: public AbstractGangTask { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5006 protected: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5007 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5008 RefToScanQueueSet *_queues; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5009 ParallelTaskTerminator _terminator; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5010 int _n_workers; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5011 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5012 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5013 G1ParPreserveCMReferentsTask(G1CollectedHeap* g1h,int workers, RefToScanQueueSet *task_queues) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5014 AbstractGangTask("ParPreserveCMReferents"), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5015 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5016 _queues(task_queues), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5017 _terminator(workers, _queues), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5018 _n_workers(workers) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5019 { } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5020 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5021 void work(int i) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5022 ResourceMark rm; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5023 HandleMark hm; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5024 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5025 G1ParScanThreadState pss(_g1h, i); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5026 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5027 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5028 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5029 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5030 pss.set_evac_closure(&scan_evac_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5031 pss.set_evac_failure_closure(&evac_failure_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5032 pss.set_partial_scan_closure(&partial_scan_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5033 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5034 assert(pss.refs()->is_empty(), "both queue and overflow should be empty"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5035 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5036 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5037 G1ParScanExtRootClosure only_copy_non_heap_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5038 G1ParScanPermClosure only_copy_perm_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5039 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5040 G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5041 G1ParScanAndMarkPermClosure copy_mark_perm_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5042 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5043 OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5044 OopsInHeapRegionClosure* copy_perm_cl = &only_copy_perm_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5045 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5046 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5047 // We also need to mark copied objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5048 copy_non_heap_cl = ©_mark_non_heap_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5049 copy_perm_cl = ©_mark_perm_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5050 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5051 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5052 // Is alive closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5053 G1AlwaysAliveClosure always_alive(_g1h); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5054 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5055 // Copying keep alive closure. Applied to referent objects that need |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5056 // to be copied. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5057 G1CopyingKeepAliveClosure keep_alive(_g1h, copy_non_heap_cl, copy_perm_cl, &pss); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5058 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5059 ReferenceProcessor* rp = _g1h->ref_processor_cm(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5060 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5061 int limit = ReferenceProcessor::number_of_subclasses_of_ref() * rp->max_num_q(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5062 int stride = MIN2(MAX2(_n_workers, 1), limit); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5063 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5064 // limit is set using max_num_q() - which was set using ParallelGCThreads. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5065 // So this must be true - but assert just in case someone decides to |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5066 // change the worker ids. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5067 assert(0 <= i && i < limit, "sanity"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5068 assert(!rp->discovery_is_atomic(), "check this code"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5069 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5070 // Select discovered lists [i, i+stride, i+2*stride,...,limit) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5071 for (int idx = i; idx < limit; idx += stride) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5072 DiscoveredList& ref_list = rp->discovered_soft_refs()[idx]; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5073 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5074 DiscoveredListIterator iter(ref_list, &keep_alive, &always_alive); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5075 while (iter.has_next()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5076 // Since discovery is not atomic for the CM ref processor, we |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5077 // can see some null referent objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5078 iter.load_ptrs(DEBUG_ONLY(true)); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5079 oop ref = iter.obj(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5080 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5081 // This will filter nulls. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5082 if (iter.is_referent_alive()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5083 iter.make_referent_alive(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5084 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5085 iter.move_to_next(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5086 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5087 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5088 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5089 // Drain the queue - which may cause stealing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5090 G1ParEvacuateFollowersClosure drain_queue(_g1h, &pss, _queues, &_terminator); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5091 drain_queue.do_void(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5092 // Allocation buffers were retired at the end of G1ParEvacuateFollowersClosure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5093 assert(pss.refs()->is_empty(), "should be"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5094 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5095 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5096 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5097 // Weak Reference processing during an evacuation pause (part 1). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5098 void G1CollectedHeap::process_discovered_references() { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5099 double ref_proc_start = os::elapsedTime(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5100 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5101 ReferenceProcessor* rp = _ref_processor_stw; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5102 assert(rp->discovery_enabled(), "should have been enabled"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5103 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5104 // Any reference objects, in the collection set, that were 'discovered' |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5105 // by the CM ref processor should have already been copied (either by |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5106 // applying the external root copy closure to the discovered lists, or |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5107 // by following an RSet entry). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5108 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5109 // But some of the referents, that are in the collection set, that these |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5110 // reference objects point to may not have been copied: the STW ref |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5111 // processor would have seen that the reference object had already |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5112 // been 'discovered' and would have skipped discovering the reference, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5113 // but would not have treated the reference object as a regular oop. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5114 // As a reult the copy closure would not have been applied to the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5115 // referent object. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5116 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5117 // We need to explicitly copy these referent objects - the references |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5118 // will be processed at the end of remarking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5119 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5120 // We also need to do this copying before we process the reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5121 // objects discovered by the STW ref processor in case one of these |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5122 // referents points to another object which is also referenced by an |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5123 // object discovered by the STW ref processor. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5124 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5125 int n_workers = (G1CollectedHeap::use_parallel_gc_threads() ? |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5126 workers()->total_workers() : 1); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5127 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5128 set_par_threads(n_workers); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5129 G1ParPreserveCMReferentsTask keep_cm_referents(this, n_workers, _task_queues); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5130 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5131 if (G1CollectedHeap::use_parallel_gc_threads()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5132 workers()->run_task(&keep_cm_referents); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5133 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5134 keep_cm_referents.work(0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5135 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5136 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5137 set_par_threads(0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5138 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5139 // Closure to test whether a referent is alive. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5140 G1STWIsAliveClosure is_alive(this); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5141 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5142 // Even when parallel reference processing is enabled, the processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5143 // of JNI refs is serial and performed serially by the current thread |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5144 // rather than by a worker. The following PSS will be used for processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5145 // JNI refs. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5146 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5147 // Use only a single queue for this PSS. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5148 G1ParScanThreadState pss(this, 0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5149 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5150 // We do not embed a reference processor in the copying/scanning |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5151 // closures while we're actually processing the discovered |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5152 // reference objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5153 G1ParScanHeapEvacClosure scan_evac_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5154 G1ParScanHeapEvacFailureClosure evac_failure_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5155 G1ParScanPartialArrayClosure partial_scan_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5156 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5157 pss.set_evac_closure(&scan_evac_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5158 pss.set_evac_failure_closure(&evac_failure_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5159 pss.set_partial_scan_closure(&partial_scan_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5160 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5161 assert(pss.refs()->is_empty(), "pre-condition"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5162 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5163 G1ParScanExtRootClosure only_copy_non_heap_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5164 G1ParScanPermClosure only_copy_perm_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5165 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5166 G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5167 G1ParScanAndMarkPermClosure copy_mark_perm_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5168 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5169 OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5170 OopsInHeapRegionClosure* copy_perm_cl = &only_copy_perm_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5171 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5172 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5173 // We also need to mark copied objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5174 copy_non_heap_cl = ©_mark_non_heap_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5175 copy_perm_cl = ©_mark_perm_cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5176 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5177 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5178 // Keep alive closure. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5179 G1CopyingKeepAliveClosure keep_alive(this, copy_non_heap_cl, copy_perm_cl, &pss); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5180 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5181 // Serial Complete GC closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5182 G1STWDrainQueueClosure drain_queue(this, &pss); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5183 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5184 // Setup the soft refs policy... |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5185 rp->setup_policy(false); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5186 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5187 if (!rp->processing_is_mt()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5188 // Serial reference processing... |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5189 rp->process_discovered_references(&is_alive, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5190 &keep_alive, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5191 &drain_queue, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5192 NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5193 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5194 // Parallel reference processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5195 int active_workers = (ParallelGCThreads > 0 ? workers()->total_workers() : 1); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5196 assert(rp->num_q() == active_workers, "sanity"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5197 assert(active_workers <= rp->max_num_q(), "sanity"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5198 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5199 G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, active_workers); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5200 rp->process_discovered_references(&is_alive, &keep_alive, &drain_queue, &par_task_executor); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5201 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5202 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5203 // We have completed copying any necessary live referent objects |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5204 // (that were not copied during the actual pause) so we can |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5205 // retire any active alloc buffers |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5206 pss.retire_alloc_buffers(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5207 assert(pss.refs()->is_empty(), "both queue and overflow should be empty"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5208 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5209 double ref_proc_time = os::elapsedTime() - ref_proc_start; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5210 g1_policy()->record_ref_proc_time(ref_proc_time * 1000.0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5211 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5212 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5213 // Weak Reference processing during an evacuation pause (part 2). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5214 void G1CollectedHeap::enqueue_discovered_references() { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5215 double ref_enq_start = os::elapsedTime(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5216 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5217 ReferenceProcessor* rp = _ref_processor_stw; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5218 assert(!rp->discovery_enabled(), "should have been disabled as part of processing"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5219 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5220 // Now enqueue any remaining on the discovered lists on to |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5221 // the pending list. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5222 if (!rp->processing_is_mt()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5223 // Serial reference processing... |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5224 rp->enqueue_discovered_references(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5225 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5226 // Parallel reference enqueuing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5227 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5228 int active_workers = (ParallelGCThreads > 0 ? workers()->total_workers() : 1); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5229 assert(rp->num_q() == active_workers, "sanity"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5230 assert(active_workers <= rp->max_num_q(), "sanity"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5231 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5232 G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, active_workers); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5233 rp->enqueue_discovered_references(&par_task_executor); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5234 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5235 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5236 rp->verify_no_references_recorded(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5237 assert(!rp->discovery_enabled(), "should have been disabled"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5238 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5239 // FIXME |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5240 // CM's reference processing also cleans up the string and symbol tables. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5241 // Should we do that here also? We could, but it is a serial operation |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5242 // and could signicantly increase the pause time. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5243 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5244 double ref_enq_time = os::elapsedTime() - ref_enq_start; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5245 g1_policy()->record_ref_enq_time(ref_enq_time * 1000.0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5246 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5247 |
342 | 5248 void G1CollectedHeap::evacuate_collection_set() { |
5249 set_evacuation_failed(false); | |
5250 | |
5251 g1_rem_set()->prepare_for_oops_into_collection_set_do(); | |
5252 concurrent_g1_refine()->set_use_cache(false); | |
889 | 5253 concurrent_g1_refine()->clear_hot_cache_claimed_index(); |
5254 | |
342 | 5255 int n_workers = (ParallelGCThreads > 0 ? workers()->total_workers() : 1); |
5256 set_par_threads(n_workers); | |
5257 G1ParTask g1_par_task(this, n_workers, _task_queues); | |
5258 | |
5259 init_for_evac_failure(NULL); | |
5260 | |
5261 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
|
5262 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5263 assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty"); |
342 | 5264 double start_par = os::elapsedTime(); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5265 |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
5266 if (G1CollectedHeap::use_parallel_gc_threads()) { |
342 | 5267 // 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
|
5268 StrongRootsScope srs(this); |
1709 | 5269 if (ParallelGCVerbose) G1ParScanThreadState::print_termination_stats_hdr(); |
342 | 5270 workers()->run_task(&g1_par_task); |
5271 } else { | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
5272 StrongRootsScope srs(this); |
342 | 5273 g1_par_task.work(0); |
5274 } | |
5275 | |
5276 double par_time = (os::elapsedTime() - start_par) * 1000.0; | |
5277 g1_policy()->record_par_time(par_time); | |
5278 set_par_threads(0); | |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
5279 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5280 // Process any discovered reference objects - we have |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5281 // to do this _before_ we retire the GC alloc regions |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5282 // as we may have to copy some 'reachable' referent |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5283 // objects (and their reachable sub-graphs) that were |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5284 // not copied during the pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5285 process_discovered_references(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5286 |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
5287 // Weak root processing. |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
5288 // 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
|
5289 // 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
|
5290 // here too. |
342 | 5291 { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5292 G1STWIsAliveClosure is_alive(this); |
342 | 5293 G1KeepAliveClosure keep_alive(this); |
5294 JNIHandles::weak_oops_do(&is_alive, &keep_alive); | |
5295 } | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5296 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5297 release_gc_alloc_regions(); |
342 | 5298 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
|
5299 |
889 | 5300 concurrent_g1_refine()->clear_hot_cache(); |
342 | 5301 concurrent_g1_refine()->set_use_cache(true); |
5302 | |
5303 finalize_for_evac_failure(); | |
5304 | |
5305 // Must do this before removing self-forwarding pointers, which clears | |
5306 // the per-region evac-failure flags. | |
5307 concurrent_mark()->complete_marking_in_collection_set(); | |
5308 | |
5309 if (evacuation_failed()) { | |
5310 remove_self_forwarding_pointers(); | |
5311 if (PrintGCDetails) { | |
1719
b63010841f78
6975964: G1: print out a more descriptive message for evacuation failure when +PrintGCDetails is set
tonyp
parents:
1718
diff
changeset
|
5312 gclog_or_tty->print(" (to-space overflow)"); |
342 | 5313 } else if (PrintGC) { |
5314 gclog_or_tty->print("--"); | |
5315 } | |
5316 } | |
5317 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5318 // Enqueue any remaining references remaining on the STW |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5319 // reference processor's discovered lists. We need to do |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5320 // this after the card table is cleaned (and verified) as |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5321 // the act of enqueuing entries on to the pending list |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5322 // will log these updates (and dirty their associated |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5323 // cards). We need these updates logged to update any |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5324 // RSets. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5325 enqueue_discovered_references(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5326 |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5327 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5328 RedirtyLoggedCardTableEntryFastClosure redirty; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5329 dirty_card_queue_set().set_closure(&redirty); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5330 dirty_card_queue_set().apply_closure_to_all_completed_buffers(); |
1111 | 5331 |
5332 DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set(); | |
5333 dcq.merge_bufferlists(&dirty_card_queue_set()); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5334 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
|
5335 } |
342 | 5336 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); |
5337 } | |
5338 | |
2173 | 5339 void G1CollectedHeap::free_region_if_empty(HeapRegion* hr, |
2152 | 5340 size_t* pre_used, |
5341 FreeRegionList* free_list, | |
5342 HumongousRegionSet* humongous_proxy_set, | |
2173 | 5343 HRRSCleanupTask* hrrs_cleanup_task, |
2152 | 5344 bool par) { |
5345 if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young()) { | |
5346 if (hr->isHumongous()) { | |
5347 assert(hr->startsHumongous(), "we should only see starts humongous"); | |
5348 free_humongous_region(hr, pre_used, free_list, humongous_proxy_set, par); | |
5349 } else { | |
5350 free_region(hr, pre_used, free_list, par); | |
342 | 5351 } |
2173 | 5352 } else { |
5353 hr->rem_set()->do_cleanup_work(hrrs_cleanup_task); | |
342 | 5354 } |
5355 } | |
5356 | |
2152 | 5357 void G1CollectedHeap::free_region(HeapRegion* hr, |
5358 size_t* pre_used, | |
5359 FreeRegionList* free_list, | |
5360 bool par) { | |
5361 assert(!hr->isHumongous(), "this is only for non-humongous regions"); | |
5362 assert(!hr->is_empty(), "the region should not be empty"); | |
5363 assert(free_list != NULL, "pre-condition"); | |
5364 | |
5365 *pre_used += hr->used(); | |
5366 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
|
5367 free_list->add_as_head(hr); |
2152 | 5368 } |
5369 | |
5370 void G1CollectedHeap::free_humongous_region(HeapRegion* hr, | |
5371 size_t* pre_used, | |
5372 FreeRegionList* free_list, | |
5373 HumongousRegionSet* humongous_proxy_set, | |
5374 bool par) { | |
5375 assert(hr->startsHumongous(), "this is only for starts humongous regions"); | |
5376 assert(free_list != NULL, "pre-condition"); | |
5377 assert(humongous_proxy_set != NULL, "pre-condition"); | |
5378 | |
5379 size_t hr_used = hr->used(); | |
5380 size_t hr_capacity = hr->capacity(); | |
5381 size_t hr_pre_used = 0; | |
5382 _humongous_set.remove_with_proxy(hr, humongous_proxy_set); | |
5383 hr->set_notHumongous(); | |
5384 free_region(hr, &hr_pre_used, free_list, par); | |
5385 | |
3766 | 5386 size_t i = hr->hrs_index() + 1; |
2152 | 5387 size_t num = 1; |
3766 | 5388 while (i < n_regions()) { |
5389 HeapRegion* curr_hr = region_at(i); | |
2152 | 5390 if (!curr_hr->continuesHumongous()) { |
5391 break; | |
5392 } | |
5393 curr_hr->set_notHumongous(); | |
5394 free_region(curr_hr, &hr_pre_used, free_list, par); | |
5395 num += 1; | |
5396 i += 1; | |
5397 } | |
5398 assert(hr_pre_used == hr_used, | |
5399 err_msg("hr_pre_used: "SIZE_FORMAT" and hr_used: "SIZE_FORMAT" " | |
5400 "should be the same", hr_pre_used, hr_used)); | |
5401 *pre_used += hr_pre_used; | |
5402 } | |
5403 | |
5404 void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used, | |
5405 FreeRegionList* free_list, | |
5406 HumongousRegionSet* humongous_proxy_set, | |
5407 bool par) { | |
5408 if (pre_used > 0) { | |
5409 Mutex* lock = (par) ? ParGCRareEvent_lock : NULL; | |
342 | 5410 MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag); |
2152 | 5411 assert(_summary_bytes_used >= pre_used, |
5412 err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" " | |
5413 "should be >= pre_used: "SIZE_FORMAT, | |
5414 _summary_bytes_used, pre_used)); | |
342 | 5415 _summary_bytes_used -= pre_used; |
2152 | 5416 } |
5417 if (free_list != NULL && !free_list->is_empty()) { | |
5418 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
|
5419 _free_list.add_as_head(free_list); |
2152 | 5420 } |
5421 if (humongous_proxy_set != NULL && !humongous_proxy_set->is_empty()) { | |
5422 MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); | |
5423 _humongous_set.update_from_proxy(humongous_proxy_set); | |
342 | 5424 } |
5425 } | |
5426 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5427 class G1ParCleanupCTTask : public AbstractGangTask { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5428 CardTableModRefBS* _ct_bs; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5429 G1CollectedHeap* _g1h; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5430 HeapRegion* volatile _su_head; |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5431 public: |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5432 G1ParCleanupCTTask(CardTableModRefBS* ct_bs, |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5433 G1CollectedHeap* g1h) : |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5434 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
|
5435 _ct_bs(ct_bs), _g1h(g1h) { } |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5436 |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5437 void work(int i) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5438 HeapRegion* r; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5439 while (r = _g1h->pop_dirty_cards_region()) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5440 clear_cards(r); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5441 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5442 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5443 |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5444 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
|
5445 // 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
|
5446 if (!r->is_survivor()) { |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5447 _ct_bs->clear(MemRegion(r->bottom(), r->end())); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5448 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5449 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5450 }; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5451 |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5452 #ifndef PRODUCT |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5453 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
|
5454 G1CollectedHeap* _g1h; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5455 CardTableModRefBS* _ct_bs; |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5456 public: |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
5457 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
|
5458 : _g1h(g1h), _ct_bs(ct_bs) { } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5459 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
|
5460 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
|
5461 _g1h->verify_dirty_region(r); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5462 } else { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
5463 _g1h->verify_not_dirty_region(r); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5464 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5465 return false; |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5466 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5467 }; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5468 |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
5469 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
|
5470 // 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
|
5471 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
|
5472 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
|
5473 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
|
5474 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
5475 |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
5476 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
|
5477 // 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
|
5478 // 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
|
5479 // 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
|
5480 // 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
|
5481 // 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
|
5482 // 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
|
5483 // is dirty. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
5484 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
|
5485 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
|
5486 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
|
5487 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
5488 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5489 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
|
5490 CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5491 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
|
5492 verify_dirty_region(hr); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5493 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5494 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5495 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5496 void G1CollectedHeap::verify_dirty_young_regions() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5497 verify_dirty_young_list(_young_list->first_region()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5498 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
|
5499 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5500 #endif |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5501 |
342 | 5502 void G1CollectedHeap::cleanUpCardTable() { |
5503 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); | |
5504 double start = os::elapsedTime(); | |
5505 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5506 // 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
|
5507 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
|
5508 |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5509 if (ParallelGCThreads > 0) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5510 set_par_threads(workers()->total_workers()); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5511 workers()->run_task(&cleanup_task); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5512 set_par_threads(0); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5513 } else { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5514 while (_dirty_cards_region_list) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5515 HeapRegion* r = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5516 cleanup_task.clear_cards(r); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5517 _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
|
5518 if (_dirty_cards_region_list == r) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5519 // The last region. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5520 _dirty_cards_region_list = NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5521 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5522 r->set_next_dirty_cards_region(NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5523 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5524 } |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5525 |
342 | 5526 double elapsed = os::elapsedTime() - start; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5527 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
|
5528 #ifndef PRODUCT |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5529 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
|
5530 G1VerifyCardTableCleanup cleanup_verifier(this, ct_bs); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5531 heap_region_iterate(&cleanup_verifier); |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5532 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5533 #endif |
342 | 5534 } |
5535 | |
5536 void G1CollectedHeap::free_collection_set(HeapRegion* cs_head) { | |
2152 | 5537 size_t pre_used = 0; |
5538 FreeRegionList local_free_list("Local List for CSet Freeing"); | |
5539 | |
342 | 5540 double young_time_ms = 0.0; |
5541 double non_young_time_ms = 0.0; | |
5542 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5543 // 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
|
5544 // 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
|
5545 // 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
|
5546 _young_list->clear(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5547 |
342 | 5548 G1CollectorPolicy* policy = g1_policy(); |
5549 | |
5550 double start_sec = os::elapsedTime(); | |
5551 bool non_young = true; | |
5552 | |
5553 HeapRegion* cur = cs_head; | |
5554 int age_bound = -1; | |
5555 size_t rs_lengths = 0; | |
5556 | |
5557 while (cur != NULL) { | |
2361 | 5558 assert(!is_on_master_free_list(cur), "sanity"); |
2152 | 5559 |
342 | 5560 if (non_young) { |
5561 if (cur->is_young()) { | |
5562 double end_sec = os::elapsedTime(); | |
5563 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
5564 non_young_time_ms += elapsed_ms; | |
5565 | |
5566 start_sec = os::elapsedTime(); | |
5567 non_young = false; | |
5568 } | |
5569 } else { | |
2152 | 5570 double end_sec = os::elapsedTime(); |
5571 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
5572 young_time_ms += elapsed_ms; | |
5573 | |
5574 start_sec = os::elapsedTime(); | |
5575 non_young = true; | |
342 | 5576 } |
5577 | |
5578 rs_lengths += cur->rem_set()->occupied(); | |
5579 | |
5580 HeapRegion* next = cur->next_in_collection_set(); | |
5581 assert(cur->in_collection_set(), "bad CS"); | |
5582 cur->set_next_in_collection_set(NULL); | |
5583 cur->set_in_collection_set(false); | |
5584 | |
5585 if (cur->is_young()) { | |
5586 int index = cur->young_index_in_cset(); | |
5587 guarantee( index != -1, "invariant" ); | |
5588 guarantee( (size_t)index < policy->young_cset_length(), "invariant" ); | |
5589 size_t words_survived = _surviving_young_words[index]; | |
5590 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
|
5591 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5592 // 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
|
5593 // (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
|
5594 // 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
|
5595 // _next_young_region field. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5596 cur->set_next_young_region(NULL); |
342 | 5597 } else { |
5598 int index = cur->young_index_in_cset(); | |
5599 guarantee( index == -1, "invariant" ); | |
5600 } | |
5601 | |
5602 assert( (cur->is_young() && cur->young_index_in_cset() > -1) || | |
5603 (!cur->is_young() && cur->young_index_in_cset() == -1), | |
5604 "invariant" ); | |
5605 | |
5606 if (!cur->evacuation_failed()) { | |
5607 // And the region is empty. | |
2152 | 5608 assert(!cur->is_empty(), "Should not have empty regions in a CS."); |
5609 free_region(cur, &pre_used, &local_free_list, false /* par */); | |
342 | 5610 } else { |
5611 cur->uninstall_surv_rate_group(); | |
5612 if (cur->is_young()) | |
5613 cur->set_young_index_in_cset(-1); | |
5614 cur->set_not_young(); | |
5615 cur->set_evacuation_failed(false); | |
5616 } | |
5617 cur = next; | |
5618 } | |
5619 | |
5620 policy->record_max_rs_lengths(rs_lengths); | |
5621 policy->cset_regions_freed(); | |
5622 | |
5623 double end_sec = os::elapsedTime(); | |
5624 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
5625 if (non_young) | |
5626 non_young_time_ms += elapsed_ms; | |
5627 else | |
5628 young_time_ms += elapsed_ms; | |
5629 | |
2152 | 5630 update_sets_after_freeing_regions(pre_used, &local_free_list, |
5631 NULL /* humongous_proxy_set */, | |
5632 false /* par */); | |
342 | 5633 policy->record_young_free_cset_time_ms(young_time_ms); |
5634 policy->record_non_young_free_cset_time_ms(non_young_time_ms); | |
5635 } | |
5636 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5637 // 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
|
5638 // 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
|
5639 // 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
|
5640 // 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
|
5641 // 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
|
5642 // 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
|
5643 // 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
|
5644 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5645 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
|
5646 HeapRegion* cur = cs_head; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5647 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5648 while (cur != NULL) { |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5649 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
|
5650 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
|
5651 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
|
5652 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
|
5653 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
|
5654 cur = next; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5655 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5656 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5657 |
2152 | 5658 void G1CollectedHeap::set_free_regions_coming() { |
5659 if (G1ConcRegionFreeingVerbose) { | |
5660 gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : " | |
5661 "setting free regions coming"); | |
5662 } | |
5663 | |
5664 assert(!free_regions_coming(), "pre-condition"); | |
5665 _free_regions_coming = true; | |
342 | 5666 } |
5667 | |
2152 | 5668 void G1CollectedHeap::reset_free_regions_coming() { |
5669 { | |
5670 assert(free_regions_coming(), "pre-condition"); | |
5671 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); | |
5672 _free_regions_coming = false; | |
5673 SecondaryFreeList_lock->notify_all(); | |
5674 } | |
5675 | |
5676 if (G1ConcRegionFreeingVerbose) { | |
5677 gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : " | |
5678 "reset free regions coming"); | |
342 | 5679 } |
5680 } | |
5681 | |
2152 | 5682 void G1CollectedHeap::wait_while_free_regions_coming() { |
5683 // Most of the time we won't have to wait, so let's do a quick test | |
5684 // first before we take the lock. | |
5685 if (!free_regions_coming()) { | |
5686 return; | |
5687 } | |
5688 | |
5689 if (G1ConcRegionFreeingVerbose) { | |
5690 gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : " | |
5691 "waiting for free regions"); | |
342 | 5692 } |
5693 | |
5694 { | |
2152 | 5695 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
5696 while (free_regions_coming()) { | |
5697 SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag); | |
342 | 5698 } |
2152 | 5699 } |
5700 | |
5701 if (G1ConcRegionFreeingVerbose) { | |
5702 gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : " | |
5703 "done waiting for free regions"); | |
5704 } | |
342 | 5705 } |
5706 | |
5707 void G1CollectedHeap::set_region_short_lived_locked(HeapRegion* hr) { | |
5708 assert(heap_lock_held_for_gc(), | |
5709 "the heap lock should already be held by or for this thread"); | |
5710 _young_list->push_region(hr); | |
5711 g1_policy()->set_region_short_lived(hr); | |
5712 } | |
5713 | |
5714 class NoYoungRegionsClosure: public HeapRegionClosure { | |
5715 private: | |
5716 bool _success; | |
5717 public: | |
5718 NoYoungRegionsClosure() : _success(true) { } | |
5719 bool doHeapRegion(HeapRegion* r) { | |
5720 if (r->is_young()) { | |
5721 gclog_or_tty->print_cr("Region ["PTR_FORMAT", "PTR_FORMAT") tagged as young", | |
5722 r->bottom(), r->end()); | |
5723 _success = false; | |
5724 } | |
5725 return false; | |
5726 } | |
5727 bool success() { return _success; } | |
5728 }; | |
5729 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5730 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
|
5731 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
|
5732 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5733 if (check_heap) { |
342 | 5734 NoYoungRegionsClosure closure; |
5735 heap_region_iterate(&closure); | |
5736 ret = ret && closure.success(); | |
5737 } | |
5738 | |
5739 return ret; | |
5740 } | |
5741 | |
5742 void G1CollectedHeap::empty_young_list() { | |
5743 assert(heap_lock_held_for_gc(), | |
5744 "the heap lock should already be held by or for this thread"); | |
5745 | |
5746 _young_list->empty_list(); | |
5747 } | |
5748 | |
5749 // Done at the start of full GC. | |
5750 void G1CollectedHeap::tear_down_region_lists() { | |
2152 | 5751 _free_list.remove_all(); |
342 | 5752 } |
5753 | |
5754 class RegionResetter: public HeapRegionClosure { | |
2152 | 5755 G1CollectedHeap* _g1h; |
5756 FreeRegionList _local_free_list; | |
5757 | |
342 | 5758 public: |
2152 | 5759 RegionResetter() : _g1h(G1CollectedHeap::heap()), |
5760 _local_free_list("Local Free List for RegionResetter") { } | |
5761 | |
342 | 5762 bool doHeapRegion(HeapRegion* r) { |
5763 if (r->continuesHumongous()) return false; | |
5764 if (r->top() > r->bottom()) { | |
5765 if (r->top() < r->end()) { | |
5766 Copy::fill_to_words(r->top(), | |
5767 pointer_delta(r->end(), r->top())); | |
5768 } | |
5769 } else { | |
5770 assert(r->is_empty(), "tautology"); | |
2152 | 5771 _local_free_list.add_as_tail(r); |
342 | 5772 } |
5773 return false; | |
5774 } | |
5775 | |
2152 | 5776 void update_free_lists() { |
5777 _g1h->update_sets_after_freeing_regions(0, &_local_free_list, NULL, | |
5778 false /* par */); | |
5779 } | |
342 | 5780 }; |
5781 | |
5782 // Done at the end of full GC. | |
5783 void G1CollectedHeap::rebuild_region_lists() { | |
5784 // This needs to go at the end of the full GC. | |
5785 RegionResetter rs; | |
5786 heap_region_iterate(&rs); | |
2152 | 5787 rs.update_free_lists(); |
342 | 5788 } |
5789 | |
5790 void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) { | |
5791 _refine_cte_cl->set_concurrent(concurrent); | |
5792 } | |
5793 | |
5794 bool G1CollectedHeap::is_in_closed_subset(const void* p) const { | |
5795 HeapRegion* hr = heap_region_containing(p); | |
5796 if (hr == NULL) { | |
5797 return is_in_permanent(p); | |
5798 } else { | |
5799 return hr->is_in(p); | |
5800 } | |
5801 } | |
2152 | 5802 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5803 // 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
|
5804 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5805 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
|
5806 bool force) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5807 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
|
5808 assert(!force || g1_policy()->can_expand_young_list(), |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5809 "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
|
5810 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
|
5811 if (force || !young_list_full) { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5812 HeapRegion* new_alloc_region = new_region(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5813 false /* do_expand */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5814 if (new_alloc_region != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5815 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
|
5816 set_region_short_lived_locked(new_alloc_region); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
5817 _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
|
5818 g1mm()->update_eden_counters(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5819 return new_alloc_region; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5820 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5821 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5822 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5823 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5824 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5825 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
|
5826 size_t allocated_bytes) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5827 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
|
5828 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
|
5829 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5830 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
|
5831 _summary_bytes_used += allocated_bytes; |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
5832 _hr_printer.retire(alloc_region); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5833 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5834 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5835 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
|
5836 bool force) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5837 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
|
5838 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5839 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5840 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5841 size_t allocated_bytes) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5842 _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
|
5843 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5844 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5845 // 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
|
5846 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5847 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
|
5848 size_t count, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5849 GCAllocPurpose ap) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5850 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
|
5851 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5852 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
|
5853 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
|
5854 true /* do_expand */); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5855 if (new_alloc_region != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5856 // 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
|
5857 // 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
|
5858 // for survivors too. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5859 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
|
5860 if (ap == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5861 new_alloc_region->set_survivor(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5862 _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
|
5863 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5864 _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
|
5865 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5866 return new_alloc_region; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5867 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5868 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
|
5869 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5870 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5871 return NULL; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5872 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5873 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5874 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
|
5875 size_t allocated_bytes, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5876 GCAllocPurpose ap) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5877 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
|
5878 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
|
5879 if (ap == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5880 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
|
5881 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5882 _hr_printer.retire(alloc_region); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5883 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5884 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5885 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
|
5886 bool force) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5887 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
|
5888 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
|
5889 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5890 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5891 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
|
5892 size_t allocated_bytes) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5893 _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
|
5894 GCAllocForSurvived); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5895 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5896 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5897 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
|
5898 bool force) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5899 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
|
5900 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
|
5901 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5902 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5903 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
|
5904 size_t allocated_bytes) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5905 _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
|
5906 GCAllocForTenured); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5907 } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5908 // Heap region set verification |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
5909 |
2152 | 5910 class VerifyRegionListsClosure : public HeapRegionClosure { |
5911 private: | |
5912 HumongousRegionSet* _humongous_set; | |
5913 FreeRegionList* _free_list; | |
5914 size_t _region_count; | |
5915 | |
5916 public: | |
5917 VerifyRegionListsClosure(HumongousRegionSet* humongous_set, | |
5918 FreeRegionList* free_list) : | |
5919 _humongous_set(humongous_set), _free_list(free_list), | |
5920 _region_count(0) { } | |
5921 | |
5922 size_t region_count() { return _region_count; } | |
5923 | |
5924 bool doHeapRegion(HeapRegion* hr) { | |
5925 _region_count += 1; | |
5926 | |
5927 if (hr->continuesHumongous()) { | |
5928 return false; | |
5929 } | |
5930 | |
5931 if (hr->is_young()) { | |
5932 // TODO | |
5933 } else if (hr->startsHumongous()) { | |
5934 _humongous_set->verify_next_region(hr); | |
5935 } else if (hr->is_empty()) { | |
5936 _free_list->verify_next_region(hr); | |
5937 } | |
5938 return false; | |
5939 } | |
5940 }; | |
5941 | |
3766 | 5942 HeapRegion* G1CollectedHeap::new_heap_region(size_t hrs_index, |
5943 HeapWord* bottom) { | |
5944 HeapWord* end = bottom + HeapRegion::GrainWords; | |
5945 MemRegion mr(bottom, end); | |
5946 assert(_g1_reserved.contains(mr), "invariant"); | |
5947 // This might return NULL if the allocation fails | |
5948 return new HeapRegion(hrs_index, _bot_shared, mr, true /* is_zeroed */); | |
5949 } | |
5950 | |
2152 | 5951 void G1CollectedHeap::verify_region_sets() { |
5952 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); | |
5953 | |
5954 // First, check the explicit lists. | |
5955 _free_list.verify(); | |
5956 { | |
5957 // Given that a concurrent operation might be adding regions to | |
5958 // the secondary free list we have to take the lock before | |
5959 // verifying it. | |
5960 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); | |
5961 _secondary_free_list.verify(); | |
5962 } | |
5963 _humongous_set.verify(); | |
5964 | |
5965 // If a concurrent region freeing operation is in progress it will | |
5966 // be difficult to correctly attributed any free regions we come | |
5967 // across to the correct free list given that they might belong to | |
5968 // one of several (free_list, secondary_free_list, any local lists, | |
5969 // etc.). So, if that's the case we will skip the rest of the | |
5970 // verification operation. Alternatively, waiting for the concurrent | |
5971 // operation to complete will have a non-trivial effect on the GC's | |
5972 // operation (no concurrent operation will last longer than the | |
5973 // interval between two calls to verification) and it might hide | |
5974 // any issues that we would like to catch during testing. | |
5975 if (free_regions_coming()) { | |
5976 return; | |
5977 } | |
5978 | |
2361 | 5979 // Make sure we append the secondary_free_list on the free_list so |
5980 // that all free regions we will come across can be safely | |
5981 // attributed to the free_list. | |
5982 append_secondary_free_list_if_not_empty_with_lock(); | |
2152 | 5983 |
5984 // Finally, make sure that the region accounting in the lists is | |
5985 // consistent with what we see in the heap. | |
5986 _humongous_set.verify_start(); | |
5987 _free_list.verify_start(); | |
5988 | |
5989 VerifyRegionListsClosure cl(&_humongous_set, &_free_list); | |
5990 heap_region_iterate(&cl); | |
5991 | |
5992 _humongous_set.verify_end(); | |
5993 _free_list.verify_end(); | |
342 | 5994 } |