Mercurial > hg > truffle
annotate src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 12233:40136aa2cdb1
8010722: assert: failed: heap size is too big for compressed oops
Summary: Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation.
Reviewed-by: stefank, dholmes
author | tschatzl |
---|---|
date | Wed, 11 Sep 2013 16:25:02 +0200 |
parents | f175e3678be2 |
children | a19bea467577 190899198332 |
rev | line source |
---|---|
342 | 1 /* |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
2 * Copyright (c) 2001, 2013, 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" |
12080 | 26 #include "code/codeCache.hpp" |
1972 | 27 #include "code/icBuffer.hpp" |
28 #include "gc_implementation/g1/bufferingOopClosure.hpp" | |
29 #include "gc_implementation/g1/concurrentG1Refine.hpp" | |
30 #include "gc_implementation/g1/concurrentG1RefineThread.hpp" | |
31 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp" | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
32 #include "gc_implementation/g1/g1AllocRegion.inline.hpp" |
1972 | 33 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" |
34 #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
|
35 #include "gc_implementation/g1/g1ErgoVerbose.hpp" |
4783
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
36 #include "gc_implementation/g1/g1EvacFailure.hpp" |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
37 #include "gc_implementation/g1/g1GCPhaseTimes.hpp" |
6007
5c86f8211d1e
7160728: Introduce an extra logging level for G1 logging
brutisso
parents:
5987
diff
changeset
|
38 #include "gc_implementation/g1/g1Log.hpp" |
1972 | 39 #include "gc_implementation/g1/g1MarkSweep.hpp" |
40 #include "gc_implementation/g1/g1OopClosures.inline.hpp" | |
41 #include "gc_implementation/g1/g1RemSet.inline.hpp" | |
10405 | 42 #include "gc_implementation/g1/g1YCTypes.hpp" |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
43 #include "gc_implementation/g1/heapRegion.inline.hpp" |
1972 | 44 #include "gc_implementation/g1/heapRegionRemSet.hpp" |
45 #include "gc_implementation/g1/heapRegionSeq.inline.hpp" | |
46 #include "gc_implementation/g1/vm_operations_g1.hpp" | |
10405 | 47 #include "gc_implementation/shared/gcHeapSummary.hpp" |
48 #include "gc_implementation/shared/gcTimer.hpp" | |
49 #include "gc_implementation/shared/gcTrace.hpp" | |
50 #include "gc_implementation/shared/gcTraceTime.hpp" | |
1972 | 51 #include "gc_implementation/shared/isGCActiveMark.hpp" |
52 #include "memory/gcLocker.inline.hpp" | |
53 #include "memory/genOopClosures.inline.hpp" | |
54 #include "memory/generationSpec.hpp" | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
55 #include "memory/referenceProcessor.hpp" |
1972 | 56 #include "oops/oop.inline.hpp" |
57 #include "oops/oop.pcgc.inline.hpp" | |
58 #include "runtime/vmThread.hpp" | |
342 | 59 |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
60 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
|
61 |
342 | 62 // turn it on so that the contents of the young list (scan-only / |
63 // to-be-collected) are printed at "strategic" points before / during | |
64 // / 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
|
65 #define YOUNG_LIST_VERBOSE 0 |
342 | 66 // CURRENT STATUS |
67 // This file is under construction. Search for "FIXME". | |
68 | |
69 // INVARIANTS/NOTES | |
70 // | |
71 // All allocation activity covered by the G1CollectedHeap interface is | |
1973 | 72 // serialized by acquiring the HeapLock. This happens in mem_allocate |
73 // and allocate_new_tlab, which are the "entry" points to the | |
74 // allocation code from the rest of the JVM. (Note that this does not | |
75 // apply to TLAB allocation, which is not part of this interface: it | |
76 // is done by clients of this interface.) | |
342 | 77 |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
78 // Notes on implementation of parallelism in different tasks. |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
79 // |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
80 // G1ParVerifyTask uses heap_region_par_iterate_chunked() for parallelism. |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
81 // The number of GC workers is passed to heap_region_par_iterate_chunked(). |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
82 // It does use run_task() which sets _n_workers in the task. |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
83 // G1ParTask executes g1_process_strong_roots() -> |
10405 | 84 // SharedHeap::process_strong_roots() which calls eventually to |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
85 // CardTableModRefBS::par_non_clean_card_iterate_work() which uses |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
86 // SequentialSubTasksDone. SharedHeap::process_strong_roots() also |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
87 // directly uses SubTasksDone (_process_strong_tasks field in SharedHeap). |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
88 // |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
89 |
342 | 90 // Local to this file. |
91 | |
92 class RefineCardTableEntryClosure: public CardTableEntryClosure { | |
93 SuspendibleThreadSet* _sts; | |
94 G1RemSet* _g1rs; | |
95 ConcurrentG1Refine* _cg1r; | |
96 bool _concurrent; | |
97 public: | |
98 RefineCardTableEntryClosure(SuspendibleThreadSet* sts, | |
99 G1RemSet* g1rs, | |
100 ConcurrentG1Refine* cg1r) : | |
101 _sts(sts), _g1rs(g1rs), _cg1r(cg1r), _concurrent(true) | |
102 {} | |
103 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
104 bool oops_into_cset = _g1rs->refine_card(card_ptr, worker_i, false); |
1705 | 105 // This path is executed by the concurrent refine or mutator threads, |
106 // concurrently, and so we do not care if card_ptr contains references | |
107 // that point into the collection set. | |
108 assert(!oops_into_cset, "should be"); | |
109 | |
342 | 110 if (_concurrent && _sts->should_yield()) { |
111 // Caller will actually yield. | |
112 return false; | |
113 } | |
114 // Otherwise, we finished successfully; return true. | |
115 return true; | |
116 } | |
117 void set_concurrent(bool b) { _concurrent = b; } | |
118 }; | |
119 | |
120 | |
121 class ClearLoggedCardTableEntryClosure: public CardTableEntryClosure { | |
122 int _calls; | |
123 G1CollectedHeap* _g1h; | |
124 CardTableModRefBS* _ctbs; | |
125 int _histo[256]; | |
126 public: | |
127 ClearLoggedCardTableEntryClosure() : | |
128 _calls(0) | |
129 { | |
130 _g1h = G1CollectedHeap::heap(); | |
131 _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); | |
132 for (int i = 0; i < 256; i++) _histo[i] = 0; | |
133 } | |
134 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
135 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { | |
136 _calls++; | |
137 unsigned char* ujb = (unsigned char*)card_ptr; | |
138 int ind = (int)(*ujb); | |
139 _histo[ind]++; | |
140 *card_ptr = -1; | |
141 } | |
142 return true; | |
143 } | |
144 int calls() { return _calls; } | |
145 void print_histo() { | |
146 gclog_or_tty->print_cr("Card table value histogram:"); | |
147 for (int i = 0; i < 256; i++) { | |
148 if (_histo[i] != 0) { | |
149 gclog_or_tty->print_cr(" %d: %d", i, _histo[i]); | |
150 } | |
151 } | |
152 } | |
153 }; | |
154 | |
155 class RedirtyLoggedCardTableEntryClosure: public CardTableEntryClosure { | |
156 int _calls; | |
157 G1CollectedHeap* _g1h; | |
158 CardTableModRefBS* _ctbs; | |
159 public: | |
160 RedirtyLoggedCardTableEntryClosure() : | |
161 _calls(0) | |
162 { | |
163 _g1h = G1CollectedHeap::heap(); | |
164 _ctbs = (CardTableModRefBS*)_g1h->barrier_set(); | |
165 } | |
166 bool do_card_ptr(jbyte* card_ptr, int worker_i) { | |
167 if (_g1h->is_in_reserved(_ctbs->addr_for(card_ptr))) { | |
168 _calls++; | |
169 *card_ptr = 0; | |
170 } | |
171 return true; | |
172 } | |
173 int calls() { return _calls; } | |
174 }; | |
175 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
176 class RedirtyLoggedCardTableEntryFastClosure : public CardTableEntryClosure { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
177 public: |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
178 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
|
179 *card_ptr = CardTableModRefBS::dirty_card_val(); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
180 return true; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
181 } |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
182 }; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
183 |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
184 YoungList::YoungList(G1CollectedHeap* g1h) : |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
185 _g1h(g1h), _head(NULL), _length(0), _last_sampled_rs_lengths(0), |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
186 _survivor_head(NULL), _survivor_tail(NULL), _survivor_length(0) { |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
187 guarantee(check_list_empty(false), "just making sure..."); |
342 | 188 } |
189 | |
190 void YoungList::push_region(HeapRegion *hr) { | |
191 assert(!hr->is_young(), "should not already be young"); | |
192 assert(hr->get_next_young_region() == NULL, "cause it should!"); | |
193 | |
194 hr->set_next_young_region(_head); | |
195 _head = hr; | |
196 | |
4090
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
197 _g1h->g1_policy()->set_region_eden(hr, (int) _length); |
342 | 198 ++_length; |
199 } | |
200 | |
201 void YoungList::add_survivor_region(HeapRegion* hr) { | |
545 | 202 assert(hr->is_survivor(), "should be flagged as survivor region"); |
342 | 203 assert(hr->get_next_young_region() == NULL, "cause it should!"); |
204 | |
205 hr->set_next_young_region(_survivor_head); | |
206 if (_survivor_head == NULL) { | |
545 | 207 _survivor_tail = hr; |
342 | 208 } |
209 _survivor_head = hr; | |
210 ++_survivor_length; | |
211 } | |
212 | |
213 void YoungList::empty_list(HeapRegion* list) { | |
214 while (list != NULL) { | |
215 HeapRegion* next = list->get_next_young_region(); | |
216 list->set_next_young_region(NULL); | |
217 list->uninstall_surv_rate_group(); | |
218 list->set_not_young(); | |
219 list = next; | |
220 } | |
221 } | |
222 | |
223 void YoungList::empty_list() { | |
224 assert(check_list_well_formed(), "young list should be well formed"); | |
225 | |
226 empty_list(_head); | |
227 _head = NULL; | |
228 _length = 0; | |
229 | |
230 empty_list(_survivor_head); | |
231 _survivor_head = NULL; | |
545 | 232 _survivor_tail = NULL; |
342 | 233 _survivor_length = 0; |
234 | |
235 _last_sampled_rs_lengths = 0; | |
236 | |
237 assert(check_list_empty(false), "just making sure..."); | |
238 } | |
239 | |
240 bool YoungList::check_list_well_formed() { | |
241 bool ret = true; | |
242 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
243 uint length = 0; |
342 | 244 HeapRegion* curr = _head; |
245 HeapRegion* last = NULL; | |
246 while (curr != NULL) { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
247 if (!curr->is_young()) { |
342 | 248 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
|
249 "incorrectly tagged (y: %d, surv: %d)", |
342 | 250 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
|
251 curr->is_young(), curr->is_survivor()); |
342 | 252 ret = false; |
253 } | |
254 ++length; | |
255 last = curr; | |
256 curr = curr->get_next_young_region(); | |
257 } | |
258 ret = ret && (length == _length); | |
259 | |
260 if (!ret) { | |
261 gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!"); | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
262 gclog_or_tty->print_cr("### list has %u entries, _length is %u", |
342 | 263 length, _length); |
264 } | |
265 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
266 return ret; |
342 | 267 } |
268 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
269 bool YoungList::check_list_empty(bool check_sample) { |
342 | 270 bool ret = true; |
271 | |
272 if (_length != 0) { | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
273 gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %u", |
342 | 274 _length); |
275 ret = false; | |
276 } | |
277 if (check_sample && _last_sampled_rs_lengths != 0) { | |
278 gclog_or_tty->print_cr("### YOUNG LIST has non-zero last sampled RS lengths"); | |
279 ret = false; | |
280 } | |
281 if (_head != NULL) { | |
282 gclog_or_tty->print_cr("### YOUNG LIST does not have a NULL head"); | |
283 ret = false; | |
284 } | |
285 if (!ret) { | |
286 gclog_or_tty->print_cr("### YOUNG LIST does not seem empty"); | |
287 } | |
288 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
289 return ret; |
342 | 290 } |
291 | |
292 void | |
293 YoungList::rs_length_sampling_init() { | |
294 _sampled_rs_lengths = 0; | |
295 _curr = _head; | |
296 } | |
297 | |
298 bool | |
299 YoungList::rs_length_sampling_more() { | |
300 return _curr != NULL; | |
301 } | |
302 | |
303 void | |
304 YoungList::rs_length_sampling_next() { | |
305 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
|
306 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
|
307 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
308 _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
|
309 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
310 // 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
|
311 // 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
|
312 // 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
|
313 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
|
314 // 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
|
315 _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
|
316 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
317 |
342 | 318 _curr = _curr->get_next_young_region(); |
319 if (_curr == NULL) { | |
320 _last_sampled_rs_lengths = _sampled_rs_lengths; | |
321 // gclog_or_tty->print_cr("last sampled RS lengths = %d", _last_sampled_rs_lengths); | |
322 } | |
323 } | |
324 | |
325 void | |
326 YoungList::reset_auxilary_lists() { | |
327 guarantee( is_empty(), "young list should be empty" ); | |
328 assert(check_list_well_formed(), "young list should be well formed"); | |
329 | |
330 // Add survivor regions to SurvRateGroup. | |
331 _g1h->g1_policy()->note_start_adding_survivor_regions(); | |
545 | 332 _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
|
333 |
4090
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
334 int young_index_in_cset = 0; |
342 | 335 for (HeapRegion* curr = _survivor_head; |
336 curr != NULL; | |
337 curr = curr->get_next_young_region()) { | |
4090
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
338 _g1h->g1_policy()->set_region_survivor(curr, young_index_in_cset); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
339 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
340 // 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
|
341 // 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
|
342 // pause. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
343 _g1h->g1_policy()->add_region_to_incremental_cset_rhs(curr); |
4090
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
344 young_index_in_cset += 1; |
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
345 } |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
346 assert((uint) young_index_in_cset == _survivor_length, "post-condition"); |
342 | 347 _g1h->g1_policy()->note_stop_adding_survivor_regions(); |
348 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
349 _head = _survivor_head; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
350 _length = _survivor_length; |
342 | 351 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
|
352 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
|
353 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
|
354 _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
|
355 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
356 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
357 // 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
|
358 // 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
|
359 // 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
|
360 // 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
|
361 |
545 | 362 _g1h->g1_policy()->finished_recalculating_age_indexes(false /* is_survivors */); |
342 | 363 |
364 assert(check_list_well_formed(), "young list should be well formed"); | |
365 } | |
366 | |
367 void YoungList::print() { | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
368 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
|
369 const char* names[] = {"YOUNG", "SURVIVOR"}; |
342 | 370 |
371 for (unsigned int list = 0; list < ARRAY_SIZE(lists); ++list) { | |
372 gclog_or_tty->print_cr("%s LIST CONTENTS", names[list]); | |
373 HeapRegion *curr = lists[list]; | |
374 if (curr == NULL) | |
375 gclog_or_tty->print_cr(" empty"); | |
376 while (curr != NULL) { | |
6027
8a2e5a6a19a4
7143490: G1: Remove HeapRegion::_top_at_conc_mark_count
johnc
parents:
6011
diff
changeset
|
377 gclog_or_tty->print_cr(" "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d", |
8a2e5a6a19a4
7143490: G1: Remove HeapRegion::_top_at_conc_mark_count
johnc
parents:
6011
diff
changeset
|
378 HR_FORMAT_PARAMS(curr), |
342 | 379 curr->prev_top_at_mark_start(), |
380 curr->next_top_at_mark_start(), | |
6027
8a2e5a6a19a4
7143490: G1: Remove HeapRegion::_top_at_conc_mark_count
johnc
parents:
6011
diff
changeset
|
381 curr->age_in_surv_rate_group_cond()); |
342 | 382 curr = curr->get_next_young_region(); |
383 } | |
384 } | |
385 | |
386 gclog_or_tty->print_cr(""); | |
387 } | |
388 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
389 void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
390 { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
391 // 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
|
392 // by installing a self pointer. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
393 HeapRegion* next = hr->get_next_dirty_cards_region(); |
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 HeapRegion* res = (HeapRegion*) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
396 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
|
397 NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
398 if (res == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
399 HeapRegion* head; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
400 do { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
401 // Put the region to the dirty cards region list. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
402 head = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
403 next = (HeapRegion*) |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
404 Atomic::cmpxchg_ptr(hr, &_dirty_cards_region_list, head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
405 if (next == head) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
406 assert(hr->get_next_dirty_cards_region() == hr, |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
407 "hr->get_next_dirty_cards_region() != hr"); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
408 if (next == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
409 // The last region in the list points to itself. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
410 hr->set_next_dirty_cards_region(hr); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
411 } else { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
412 hr->set_next_dirty_cards_region(next); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
413 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
414 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
415 } while (next != head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
416 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
417 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
418 } |
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 HeapRegion* G1CollectedHeap::pop_dirty_cards_region() |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
421 { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
422 HeapRegion* head; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
423 HeapRegion* hr; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
424 do { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
425 head = _dirty_cards_region_list; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
426 if (head == NULL) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
427 return NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
428 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
429 HeapRegion* new_head = head->get_next_dirty_cards_region(); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
430 if (head == new_head) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
431 // The last region. |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
432 new_head = NULL; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
433 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
434 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
|
435 head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
436 } while (hr != head); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
437 assert(hr != NULL, "invariant"); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
438 hr->set_next_dirty_cards_region(NULL); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
439 return hr; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
440 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
441 |
342 | 442 void G1CollectedHeap::stop_conc_gc_threads() { |
794 | 443 _cg1r->stop(); |
342 | 444 _cmThread->stop(); |
445 } | |
446 | |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
447 #ifdef ASSERT |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
448 // 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
|
449 // 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
|
450 // 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
|
451 // 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
|
452 // regions have been retired. It is used for debugging |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
453 // 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
|
454 // 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
|
455 // inaccurate, it is sufficient for G1 because the conservative |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
456 // implementation of is_scavengable() for G1 will indicate that |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
457 // all nmethods must be scanned during a partial collection. |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
458 bool G1CollectedHeap::is_in_partial_collection(const void* p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
459 HeapRegion* hr = heap_region_containing(p); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
460 return hr != NULL && hr->in_collection_set(); |
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 #endif |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
463 |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
464 // Returns true if the reference points to an object that |
10405 | 465 // can move in an incremental collection. |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
466 bool G1CollectedHeap::is_scavengable(const void* p) { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
467 G1CollectedHeap* g1h = G1CollectedHeap::heap(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
468 G1CollectorPolicy* g1p = g1h->g1_policy(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
469 HeapRegion* hr = heap_region_containing(p); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
470 if (hr == NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
471 // null |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
472 assert(p == NULL, err_msg("Not NULL " PTR_FORMAT ,p)); |
3377
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
473 return false; |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
474 } else { |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
475 return !hr->isHumongous(); |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
476 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
477 } |
2aa9ddbb9e60
7041789: 30% perf regression with c2/arm following 7017732
jmasa
parents:
3356
diff
changeset
|
478 |
342 | 479 void G1CollectedHeap::check_ct_logs_at_safepoint() { |
480 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
481 CardTableModRefBS* ct_bs = (CardTableModRefBS*)barrier_set(); | |
482 | |
483 // Count the dirty cards at the start. | |
484 CountNonCleanMemRegionClosure count1(this); | |
485 ct_bs->mod_card_iterate(&count1); | |
486 int orig_count = count1.n(); | |
487 | |
488 // First clear the logged cards. | |
489 ClearLoggedCardTableEntryClosure clear; | |
490 dcqs.set_closure(&clear); | |
491 dcqs.apply_closure_to_all_completed_buffers(); | |
492 dcqs.iterate_closure_all_threads(false); | |
493 clear.print_histo(); | |
494 | |
495 // Now ensure that there's no dirty cards. | |
496 CountNonCleanMemRegionClosure count2(this); | |
497 ct_bs->mod_card_iterate(&count2); | |
498 if (count2.n() != 0) { | |
499 gclog_or_tty->print_cr("Card table has %d entries; %d originally", | |
500 count2.n(), orig_count); | |
501 } | |
502 guarantee(count2.n() == 0, "Card table should be clean."); | |
503 | |
504 RedirtyLoggedCardTableEntryClosure redirty; | |
505 JavaThread::dirty_card_queue_set().set_closure(&redirty); | |
506 dcqs.apply_closure_to_all_completed_buffers(); | |
507 dcqs.iterate_closure_all_threads(false); | |
508 gclog_or_tty->print_cr("Log entries = %d, dirty cards = %d.", | |
509 clear.calls(), orig_count); | |
510 guarantee(redirty.calls() == clear.calls(), | |
511 "Or else mechanism is broken."); | |
512 | |
513 CountNonCleanMemRegionClosure count3(this); | |
514 ct_bs->mod_card_iterate(&count3); | |
515 if (count3.n() != orig_count) { | |
516 gclog_or_tty->print_cr("Should have restored them all: orig = %d, final = %d.", | |
517 orig_count, count3.n()); | |
518 guarantee(count3.n() >= orig_count, "Should have restored them all."); | |
519 } | |
520 | |
521 JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); | |
522 } | |
523 | |
524 // Private class members. | |
525 | |
526 G1CollectedHeap* G1CollectedHeap::_g1h; | |
527 | |
528 // Private methods. | |
529 | |
2152 | 530 HeapRegion* |
2361 | 531 G1CollectedHeap::new_region_try_secondary_free_list() { |
2152 | 532 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
533 while (!_secondary_free_list.is_empty() || free_regions_coming()) { | |
534 if (!_secondary_free_list.is_empty()) { | |
535 if (G1ConcRegionFreeingVerbose) { | |
536 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
537 "secondary_free_list has %u entries", |
2152 | 538 _secondary_free_list.length()); |
539 } | |
540 // It looks as if there are free regions available on the | |
541 // secondary_free_list. Let's move them to the free_list and try | |
542 // again to allocate from it. | |
543 append_secondary_free_list(); | |
544 | |
545 assert(!_free_list.is_empty(), "if the secondary_free_list was not " | |
546 "empty we should have moved at least one entry to the free_list"); | |
547 HeapRegion* res = _free_list.remove_head(); | |
548 if (G1ConcRegionFreeingVerbose) { | |
549 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
550 "allocated "HR_FORMAT" from secondary_free_list", | |
551 HR_FORMAT_PARAMS(res)); | |
552 } | |
553 return res; | |
554 } | |
555 | |
10405 | 556 // Wait here until we get notified either when (a) there are no |
2152 | 557 // more free regions coming or (b) some regions have been moved on |
558 // the secondary_free_list. | |
559 SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag); | |
560 } | |
561 | |
562 if (G1ConcRegionFreeingVerbose) { | |
563 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
564 "could not allocate from secondary_free_list"); | |
565 } | |
566 return NULL; | |
567 } | |
568 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
569 HeapRegion* G1CollectedHeap::new_region(size_t word_size, bool do_expand) { |
3986
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
570 assert(!isHumongous(word_size) || word_size <= HeapRegion::GrainWords, |
2152 | 571 "the only time we use this to allocate a humongous region is " |
572 "when we are allocating a single humongous region"); | |
573 | |
574 HeapRegion* res; | |
575 if (G1StressConcRegionFreeing) { | |
576 if (!_secondary_free_list.is_empty()) { | |
577 if (G1ConcRegionFreeingVerbose) { | |
578 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
579 "forced to look at the secondary_free_list"); | |
580 } | |
2361 | 581 res = new_region_try_secondary_free_list(); |
2152 | 582 if (res != NULL) { |
583 return res; | |
584 } | |
585 } | |
586 } | |
587 res = _free_list.remove_head_or_null(); | |
588 if (res == NULL) { | |
589 if (G1ConcRegionFreeingVerbose) { | |
590 gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : " | |
591 "res == NULL, trying the secondary_free_list"); | |
592 } | |
2361 | 593 res = new_region_try_secondary_free_list(); |
2152 | 594 } |
4781
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
595 if (res == NULL && do_expand && _expand_heap_after_alloc_failure) { |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
596 // Currently, only attempts to allocate GC alloc regions set |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
597 // do_expand to true. So, we should only reach here during a |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
598 // safepoint. If this assumption changes we might have to |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
599 // reconsider the use of _expand_heap_after_alloc_failure. |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
600 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
601 |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
602 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
603 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
604 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
|
605 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
606 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
607 if (expand(word_size * HeapWordSize)) { |
4781
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
608 // Given that expand() succeeded in expanding the heap, and we |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
609 // always expand the heap by an amount aligned to the heap |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
610 // region size, the free list should in theory not be empty. So |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
611 // it would probably be OK to use remove_head(). But the extra |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
612 // check for NULL is unlikely to be a performance issue here (we |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
613 // just expanded the heap!) so let's just be conservative and |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
614 // use remove_head_or_null(). |
3766 | 615 res = _free_list.remove_head_or_null(); |
4781
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
616 } else { |
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
617 _expand_heap_after_alloc_failure = false; |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
618 } |
342 | 619 } |
620 return res; | |
621 } | |
622 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
623 uint G1CollectedHeap::humongous_obj_allocate_find_first(uint num_regions, |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
624 size_t word_size) { |
2361 | 625 assert(isHumongous(word_size), "word_size should be humongous"); |
626 assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); | |
627 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
628 uint first = G1_NULL_HRS_INDEX; |
2152 | 629 if (num_regions == 1) { |
630 // Only one region to allocate, no need to go through the slower | |
10405 | 631 // path. The caller will attempt the expansion if this fails, so |
2152 | 632 // 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
|
633 HeapRegion* hr = new_region(word_size, false /* do_expand */); |
2152 | 634 if (hr != NULL) { |
635 first = hr->hrs_index(); | |
636 } else { | |
3766 | 637 first = G1_NULL_HRS_INDEX; |
2152 | 638 } |
639 } else { | |
640 // We can't allocate humongous regions while cleanupComplete() is | |
641 // running, since some of the regions we find to be empty might not | |
642 // yet be added to the free list and it is not straightforward to | |
643 // know which list they are on so that we can remove them. Note | |
644 // that we only need to do this if we need to allocate more than | |
645 // one region to satisfy the current humongous allocation | |
646 // request. If we are only allocating one region we use the common | |
647 // region allocation code (see above). | |
648 wait_while_free_regions_coming(); | |
2361 | 649 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 650 |
651 if (free_regions() >= num_regions) { | |
3766 | 652 first = _hrs.find_contiguous(num_regions); |
653 if (first != G1_NULL_HRS_INDEX) { | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
654 for (uint i = first; i < first + num_regions; ++i) { |
3766 | 655 HeapRegion* hr = region_at(i); |
2152 | 656 assert(hr->is_empty(), "sanity"); |
2361 | 657 assert(is_on_master_free_list(hr), "sanity"); |
2152 | 658 hr->set_pending_removal(true); |
659 } | |
660 _free_list.remove_all_pending(num_regions); | |
661 } | |
662 } | |
663 } | |
664 return first; | |
665 } | |
666 | |
2361 | 667 HeapWord* |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
668 G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first, |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
669 uint num_regions, |
2361 | 670 size_t word_size) { |
3766 | 671 assert(first != G1_NULL_HRS_INDEX, "pre-condition"); |
2361 | 672 assert(isHumongous(word_size), "word_size should be humongous"); |
673 assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition"); | |
674 | |
675 // Index of last region in the series + 1. | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
676 uint last = first + num_regions; |
2361 | 677 |
678 // We need to initialize the region(s) we just discovered. This is | |
679 // a bit tricky given that it can happen concurrently with | |
680 // refinement threads refining cards on these regions and | |
681 // potentially wanting to refine the BOT as they are scanning | |
682 // those cards (this can happen shortly after a cleanup; see CR | |
683 // 6991377). So we have to set up the region(s) carefully and in | |
684 // a specific order. | |
685 | |
686 // The word size sum of all the regions we will allocate. | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
687 size_t word_size_sum = (size_t) num_regions * HeapRegion::GrainWords; |
2361 | 688 assert(word_size <= word_size_sum, "sanity"); |
689 | |
690 // This will be the "starts humongous" region. | |
3766 | 691 HeapRegion* first_hr = region_at(first); |
2361 | 692 // The header of the new object will be placed at the bottom of |
693 // the first region. | |
694 HeapWord* new_obj = first_hr->bottom(); | |
695 // This will be the new end of the first region in the series that | |
10405 | 696 // should also match the end of the last region in the series. |
2361 | 697 HeapWord* new_end = new_obj + word_size_sum; |
698 // This will be the new top of the first region that will reflect | |
699 // this allocation. | |
700 HeapWord* new_top = new_obj + word_size; | |
701 | |
702 // First, we need to zero the header of the space that we will be | |
703 // allocating. When we update top further down, some refinement | |
704 // threads might try to scan the region. By zeroing the header we | |
705 // ensure that any thread that will try to scan the region will | |
706 // come across the zero klass word and bail out. | |
707 // | |
708 // NOTE: It would not have been correct to have used | |
709 // CollectedHeap::fill_with_object() and make the space look like | |
710 // an int array. The thread that is doing the allocation will | |
711 // later update the object header to a potentially different array | |
712 // type and, for a very short period of time, the klass and length | |
713 // fields will be inconsistent. This could cause a refinement | |
714 // thread to calculate the object size incorrectly. | |
715 Copy::fill_to_words(new_obj, oopDesc::header_size(), 0); | |
716 | |
717 // We will set up the first region as "starts humongous". This | |
718 // will also update the BOT covering all the regions to reflect | |
719 // that there is a single object that starts at the bottom of the | |
720 // first region. | |
721 first_hr->set_startsHumongous(new_top, new_end); | |
722 | |
723 // Then, if there are any, we will set up the "continues | |
724 // humongous" regions. | |
725 HeapRegion* hr = NULL; | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
726 for (uint i = first + 1; i < last; ++i) { |
3766 | 727 hr = region_at(i); |
2361 | 728 hr->set_continuesHumongous(first_hr); |
729 } | |
730 // If we have "continues humongous" regions (hr != NULL), then the | |
731 // end of the last one should match new_end. | |
732 assert(hr == NULL || hr->end() == new_end, "sanity"); | |
733 | |
734 // Up to this point no concurrent thread would have been able to | |
735 // do any scanning on any region in this series. All the top | |
736 // fields still point to bottom, so the intersection between | |
737 // [bottom,top] and [card_start,card_end] will be empty. Before we | |
738 // update the top fields, we'll do a storestore to make sure that | |
739 // no thread sees the update to top before the zeroing of the | |
740 // object header and the BOT initialization. | |
741 OrderAccess::storestore(); | |
742 | |
743 // Now that the BOT and the object header have been initialized, | |
744 // we can update top of the "starts humongous" region. | |
745 assert(first_hr->bottom() < new_top && new_top <= first_hr->end(), | |
746 "new_top should be in this region"); | |
747 first_hr->set_top(new_top); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
748 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
749 HeapWord* bottom = first_hr->bottom(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
750 HeapWord* end = first_hr->orig_end(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
751 if ((first + 1) == last) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
752 // the series has a single humongous region |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
753 _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, new_top); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
754 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
755 // the series has more than one humongous regions |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
756 _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
757 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
758 } |
2361 | 759 |
760 // Now, we will update the top fields of the "continues humongous" | |
761 // regions. The reason we need to do this is that, otherwise, | |
762 // these regions would look empty and this will confuse parts of | |
763 // G1. For example, the code that looks for a consecutive number | |
764 // of empty regions will consider them empty and try to | |
765 // re-allocate them. We can extend is_empty() to also include | |
766 // !continuesHumongous(), but it is easier to just update the top | |
767 // fields here. The way we set top for all regions (i.e., top == | |
768 // end for all regions but the last one, top == new_top for the | |
769 // last one) is actually used when we will free up the humongous | |
770 // region in free_humongous_region(). | |
771 hr = NULL; | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
772 for (uint i = first + 1; i < last; ++i) { |
3766 | 773 hr = region_at(i); |
2361 | 774 if ((i + 1) == last) { |
775 // last continues humongous region | |
776 assert(hr->bottom() < new_top && new_top <= hr->end(), | |
777 "new_top should fall on this region"); | |
778 hr->set_top(new_top); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
779 _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top); |
2361 | 780 } else { |
781 // not last one | |
782 assert(new_top > hr->end(), "new_top should be above this region"); | |
783 hr->set_top(hr->end()); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
784 _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end()); |
2361 | 785 } |
786 } | |
787 // If we have continues humongous regions (hr != NULL), then the | |
788 // end of the last one should match new_end and its top should | |
789 // match new_top. | |
790 assert(hr == NULL || | |
791 (hr->end() == new_end && hr->top() == new_top), "sanity"); | |
792 | |
793 assert(first_hr->used() == word_size * HeapWordSize, "invariant"); | |
794 _summary_bytes_used += first_hr->used(); | |
795 _humongous_set.add(first_hr); | |
796 | |
797 return new_obj; | |
798 } | |
799 | |
342 | 800 // If could fit into free regions w/o expansion, try. |
801 // Otherwise, if can expand, do so. | |
802 // Otherwise, if using ex regions might help, try with ex given back. | |
1973 | 803 HeapWord* G1CollectedHeap::humongous_obj_allocate(size_t word_size) { |
2152 | 804 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); |
805 | |
806 verify_region_sets_optional(); | |
342 | 807 |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
808 size_t word_size_rounded = round_to(word_size, HeapRegion::GrainWords); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
809 uint num_regions = (uint) (word_size_rounded / HeapRegion::GrainWords); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
810 uint x_num = expansion_regions(); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
811 uint fs = _hrs.free_suffix(); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
812 uint first = humongous_obj_allocate_find_first(num_regions, word_size); |
3766 | 813 if (first == G1_NULL_HRS_INDEX) { |
2152 | 814 // The only thing we can do now is attempt expansion. |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
815 if (fs + x_num >= num_regions) { |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
816 // 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
|
817 // 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
|
818 // 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
|
819 // should have succeeded and we wouldn't be here. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
820 // |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
821 // 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
|
822 // 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
|
823 // room available. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
824 assert(num_regions > fs, "earlier allocation should have succeeded"); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
825 |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
826 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
827 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
828 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
|
829 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
830 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
831 if (expand((num_regions - fs) * HeapRegion::GrainBytes)) { |
3766 | 832 // Even though the heap was expanded, it might not have |
833 // reached the desired size. So, we cannot assume that the | |
834 // allocation will succeed. | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
835 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
|
836 } |
2152 | 837 } |
838 } | |
839 | |
2361 | 840 HeapWord* result = NULL; |
3766 | 841 if (first != G1_NULL_HRS_INDEX) { |
2361 | 842 result = |
843 humongous_obj_allocate_initialize_regions(first, num_regions, word_size); | |
844 assert(result != NULL, "it should always return a valid result"); | |
3980
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
845 |
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
846 // A successful humongous object allocation changes the used space |
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
847 // information of the old generation so we need to recalculate the |
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
848 // sizes and update the jstat counters here. |
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
849 g1mm()->update_sizes(); |
2152 | 850 } |
851 | |
852 verify_region_sets_optional(); | |
2361 | 853 |
854 return result; | |
342 | 855 } |
856 | |
1973 | 857 HeapWord* G1CollectedHeap::allocate_new_tlab(size_t word_size) { |
858 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
|
859 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
|
860 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
861 unsigned int dummy_gc_count_before; |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
862 int dummy_gclocker_retry_count = 0; |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
863 return attempt_allocation(word_size, &dummy_gc_count_before, &dummy_gclocker_retry_count); |
342 | 864 } |
865 | |
866 HeapWord* | |
867 G1CollectedHeap::mem_allocate(size_t word_size, | |
1973 | 868 bool* gc_overhead_limit_was_exceeded) { |
869 assert_heap_not_locked_and_not_at_safepoint(); | |
342 | 870 |
10405 | 871 // Loop until the allocation is satisfied, or unsatisfied after GC. |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
872 for (int try_count = 1, gclocker_retry_count = 0; /* we'll return */; try_count += 1) { |
1973 | 873 unsigned int gc_count_before; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
874 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
875 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
876 if (!isHumongous(word_size)) { |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
877 result = attempt_allocation(word_size, &gc_count_before, &gclocker_retry_count); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
878 } else { |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
879 result = attempt_allocation_humongous(word_size, &gc_count_before, &gclocker_retry_count); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
880 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
881 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
882 return result; |
342 | 883 } |
884 | |
885 // Create the garbage collection operation... | |
1973 | 886 VM_G1CollectForAllocation op(gc_count_before, word_size); |
342 | 887 // ...and get the VM thread to execute it. |
888 VMThread::execute(&op); | |
1973 | 889 |
890 if (op.prologue_succeeded() && op.pause_succeeded()) { | |
891 // If the operation was successful we'll return the result even | |
892 // if it is NULL. If the allocation attempt failed immediately | |
893 // after a Full GC, it's unlikely we'll be able to allocate now. | |
894 HeapWord* result = op.result(); | |
895 if (result != NULL && !isHumongous(word_size)) { | |
896 // Allocations that take place on VM operations do not do any | |
897 // card dirtying and we have to do it here. We only have to do | |
898 // this for non-humongous allocations, though. | |
899 dirty_young_block(result, word_size); | |
900 } | |
342 | 901 return result; |
1973 | 902 } else { |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
903 if (gclocker_retry_count > GCLockerRetryAllocationCount) { |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
904 return NULL; |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
905 } |
1973 | 906 assert(op.result() == NULL, |
907 "the result should be NULL if the VM op did not succeed"); | |
342 | 908 } |
909 | |
910 // Give a warning if we seem to be looping forever. | |
911 if ((QueuedAllocationWarningCount > 0) && | |
912 (try_count % QueuedAllocationWarningCount == 0)) { | |
1973 | 913 warning("G1CollectedHeap::mem_allocate retries %d times", try_count); |
342 | 914 } |
915 } | |
1973 | 916 |
917 ShouldNotReachHere(); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
918 return NULL; |
342 | 919 } |
920 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
921 HeapWord* G1CollectedHeap::attempt_allocation_slow(size_t word_size, |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
922 unsigned int *gc_count_before_ret, |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
923 int* gclocker_retry_count_ret) { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
924 // 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
|
925 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
926 assert_heap_not_locked_and_not_at_safepoint(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
927 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
|
928 "be called for humongous allocation requests"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
929 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
930 // 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
|
931 // (attempt_allocation()) failed to allocate. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
932 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
933 // 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
|
934 // 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
|
935 // 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
|
936 // return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
937 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
938 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
|
939 bool should_try_gc; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
940 unsigned int gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
941 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
942 { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
943 MutexLockerEx x(Heap_lock); |
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 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
|
946 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
947 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
948 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
949 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
950 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
951 // 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
|
952 // 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
|
953 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
|
954 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
955 if (GC_locker::is_active_and_needs_gc()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
956 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
|
957 // 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
|
958 // 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
|
959 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
|
960 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
961 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
962 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
963 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
964 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
965 should_try_gc = false; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
966 } else { |
6106
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
967 // The GCLocker may not be active but the GCLocker initiated |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
968 // GC may not yet have been performed (GCLocker::needs_gc() |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
969 // returns true). In this case we do not try this GC and |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
970 // wait until the GCLocker initiated GC is performed, and |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
971 // then retry the allocation. |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
972 if (GC_locker::needs_gc()) { |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
973 should_try_gc = false; |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
974 } else { |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
975 // Read the GC count while still holding the Heap_lock. |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
976 gc_count_before = total_collections(); |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
977 should_try_gc = true; |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
978 } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
979 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
980 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
981 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
982 if (should_try_gc) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
983 bool succeeded; |
12113
f7d3b4387a16
8022872: G1: Use correct GC cause for young GC triggered by humongous allocations
brutisso
parents:
12082
diff
changeset
|
984 result = do_collection_pause(word_size, gc_count_before, &succeeded, |
f7d3b4387a16
8022872: G1: Use correct GC cause for young GC triggered by humongous allocations
brutisso
parents:
12082
diff
changeset
|
985 GCCause::_g1_inc_collection_pause); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
986 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
987 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
|
988 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
989 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
990 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
991 if (succeeded) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
992 // 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
|
993 // 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
|
994 // further. We'll just return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
995 MutexLockerEx x(Heap_lock); |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
996 *gc_count_before_ret = total_collections(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
997 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
998 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
999 } else { |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1000 if (*gclocker_retry_count_ret > GCLockerRetryAllocationCount) { |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1001 MutexLockerEx x(Heap_lock); |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1002 *gc_count_before_ret = total_collections(); |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1003 return NULL; |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1004 } |
6106
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1005 // The GCLocker is either active or the GCLocker initiated |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1006 // GC has not yet been performed. Stall until it is and |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1007 // then retry the allocation. |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1008 GC_locker::stall_until_clear(); |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1009 (*gclocker_retry_count_ret) += 1; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1010 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1011 |
10405 | 1012 // We can reach here if we were unsuccessful in scheduling a |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1013 // 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
|
1014 // 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
|
1015 // allocation attempt in case another thread successfully |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1016 // 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
|
1017 // 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
|
1018 // 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
|
1019 // iteration (after taking the Heap_lock). |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1020 result = _mutator_alloc_region.attempt_allocation(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1021 false /* bot_updates */); |
5963
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
1022 if (result != NULL) { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1023 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1024 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1025 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1026 // 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
|
1027 if ((QueuedAllocationWarningCount > 0) && |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1028 (try_count % QueuedAllocationWarningCount == 0)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1029 warning("G1CollectedHeap::attempt_allocation_slow() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1030 "retries %d times", try_count); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1031 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1032 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1033 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1034 ShouldNotReachHere(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1035 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1036 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1037 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1038 HeapWord* G1CollectedHeap::attempt_allocation_humongous(size_t word_size, |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1039 unsigned int * gc_count_before_ret, |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1040 int* gclocker_retry_count_ret) { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1041 // 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
|
1042 // 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
|
1043 // 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
|
1044 // 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
|
1045 // 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
|
1046 // 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
|
1047 // 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
|
1048 // 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
|
1049 // 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
|
1050 // much as possible. |
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 assert_heap_not_locked_and_not_at_safepoint(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1053 assert(isHumongous(word_size), "attempt_allocation_humongous() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1054 "should only be called for humongous allocations"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1055 |
4834
6a78aa6ac1ff
7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()...
brutisso
parents:
4833
diff
changeset
|
1056 // Humongous objects can exhaust the heap quickly, so we should check if we |
6a78aa6ac1ff
7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()...
brutisso
parents:
4833
diff
changeset
|
1057 // need to start a marking cycle at each humongous object allocation. We do |
6a78aa6ac1ff
7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()...
brutisso
parents:
4833
diff
changeset
|
1058 // the check before we do the actual allocation. The reason for doing it |
6a78aa6ac1ff
7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()...
brutisso
parents:
4833
diff
changeset
|
1059 // before the allocation is that we avoid having to keep track of the newly |
6a78aa6ac1ff
7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()...
brutisso
parents:
4833
diff
changeset
|
1060 // allocated memory while we do a GC. |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
1061 if (g1_policy()->need_to_start_conc_mark("concurrent humongous allocation", |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
1062 word_size)) { |
4834
6a78aa6ac1ff
7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()...
brutisso
parents:
4833
diff
changeset
|
1063 collect(GCCause::_g1_humongous_allocation); |
6a78aa6ac1ff
7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()...
brutisso
parents:
4833
diff
changeset
|
1064 } |
6a78aa6ac1ff
7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()...
brutisso
parents:
4833
diff
changeset
|
1065 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1066 // 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
|
1067 // 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
|
1068 // 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
|
1069 // return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1070 HeapWord* result = NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1071 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
|
1072 bool should_try_gc; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1073 unsigned int gc_count_before; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1074 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1075 { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1076 MutexLockerEx x(Heap_lock); |
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 // 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
|
1079 // 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
|
1080 // 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
|
1081 result = humongous_obj_allocate(word_size); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1082 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1083 return result; |
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 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1086 if (GC_locker::is_active_and_needs_gc()) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1087 should_try_gc = false; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1088 } else { |
6106
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1089 // The GCLocker may not be active but the GCLocker initiated |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1090 // GC may not yet have been performed (GCLocker::needs_gc() |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1091 // returns true). In this case we do not try this GC and |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1092 // wait until the GCLocker initiated GC is performed, and |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1093 // then retry the allocation. |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1094 if (GC_locker::needs_gc()) { |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1095 should_try_gc = false; |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1096 } else { |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1097 // Read the GC count while still holding the Heap_lock. |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1098 gc_count_before = total_collections(); |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1099 should_try_gc = true; |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1100 } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1101 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1102 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1103 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1104 if (should_try_gc) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1105 // 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
|
1106 // 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
|
1107 // 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
|
1108 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1109 bool succeeded; |
12113
f7d3b4387a16
8022872: G1: Use correct GC cause for young GC triggered by humongous allocations
brutisso
parents:
12082
diff
changeset
|
1110 result = do_collection_pause(word_size, gc_count_before, &succeeded, |
f7d3b4387a16
8022872: G1: Use correct GC cause for young GC triggered by humongous allocations
brutisso
parents:
12082
diff
changeset
|
1111 GCCause::_g1_humongous_allocation); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1112 if (result != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1113 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
|
1114 return result; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1115 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1116 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1117 if (succeeded) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1118 // 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
|
1119 // 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
|
1120 // further. We'll just return NULL. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1121 MutexLockerEx x(Heap_lock); |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
1122 *gc_count_before_ret = total_collections(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1123 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1124 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1125 } else { |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1126 if (*gclocker_retry_count_ret > GCLockerRetryAllocationCount) { |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1127 MutexLockerEx x(Heap_lock); |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1128 *gc_count_before_ret = total_collections(); |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1129 return NULL; |
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1130 } |
6106
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1131 // The GCLocker is either active or the GCLocker initiated |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1132 // GC has not yet been performed. Stall until it is and |
1d478c993020
7143858: G1: Back to back young GCs with the second GC having a minimally sized eden
johnc
parents:
6064
diff
changeset
|
1133 // then retry the allocation. |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1134 GC_locker::stall_until_clear(); |
8853
2e093b564241
7014552: gc/lock/jni/jnilockXXX works too slow on 1-processor machine
mgerdin
parents:
8038
diff
changeset
|
1135 (*gclocker_retry_count_ret) += 1; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1136 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1137 |
10405 | 1138 // We can reach here if we were unsuccessful in scheduling a |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1139 // 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
|
1140 // 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
|
1141 // allocation attempt in case another thread successfully |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1142 // 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
|
1143 // warning if we seem to be looping forever. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1144 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1145 if ((QueuedAllocationWarningCount > 0) && |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1146 (try_count % QueuedAllocationWarningCount == 0)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1147 warning("G1CollectedHeap::attempt_allocation_humongous() " |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1148 "retries %d times", try_count); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1149 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1150 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1151 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1152 ShouldNotReachHere(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1153 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1154 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1155 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1156 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
|
1157 bool expect_null_mutator_alloc_region) { |
2152 | 1158 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
|
1159 assert(_mutator_alloc_region.get() == NULL || |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1160 !expect_null_mutator_alloc_region, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1161 "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
|
1162 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1163 if (!isHumongous(word_size)) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1164 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
|
1165 false /* bot_updates */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1166 } else { |
4829
9509c20bba28
6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents:
4787
diff
changeset
|
1167 HeapWord* result = humongous_obj_allocate(word_size); |
9509c20bba28
6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents:
4787
diff
changeset
|
1168 if (result != NULL && g1_policy()->need_to_start_conc_mark("STW humongous allocation")) { |
9509c20bba28
6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents:
4787
diff
changeset
|
1169 g1_policy()->set_initiate_conc_mark_if_possible(); |
9509c20bba28
6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents:
4787
diff
changeset
|
1170 } |
9509c20bba28
6976060: G1: humongous object allocations should initiate marking cycles when necessary
brutisso
parents:
4787
diff
changeset
|
1171 return result; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1172 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1173 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1174 ShouldNotReachHere(); |
342 | 1175 } |
1176 | |
1177 class PostMCRemSetClearClosure: public HeapRegionClosure { | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1178 G1CollectedHeap* _g1h; |
342 | 1179 ModRefBarrierSet* _mr_bs; |
1180 public: | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1181 PostMCRemSetClearClosure(G1CollectedHeap* g1h, ModRefBarrierSet* mr_bs) : |
12080 | 1182 _g1h(g1h), _mr_bs(mr_bs) {} |
1183 | |
342 | 1184 bool doHeapRegion(HeapRegion* r) { |
12080 | 1185 HeapRegionRemSet* hrrs = r->rem_set(); |
1186 | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1187 if (r->continuesHumongous()) { |
12080 | 1188 // We'll assert that the strong code root list and RSet is empty |
1189 assert(hrrs->strong_code_roots_list_length() == 0, "sanity"); | |
1190 assert(hrrs->occupied() == 0, "RSet should be empty"); | |
342 | 1191 return false; |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1192 } |
12080 | 1193 |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1194 _g1h->reset_gc_time_stamps(r); |
12080 | 1195 hrrs->clear(); |
342 | 1196 // You might think here that we could clear just the cards |
1197 // corresponding to the used region. But no: if we leave a dirty card | |
1198 // in a region we might allocate into, then it would prevent that card | |
1199 // from being enqueued, and cause it to be missed. | |
1200 // Re: the performance cost: we shouldn't be doing full GC anyway! | |
1201 _mr_bs->clear(MemRegion(r->bottom(), r->end())); | |
12080 | 1202 |
342 | 1203 return false; |
1204 } | |
1205 }; | |
1206 | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1207 void G1CollectedHeap::clear_rsets_post_compaction() { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1208 PostMCRemSetClearClosure rs_clear(this, mr_bs()); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1209 heap_region_iterate(&rs_clear); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1210 } |
342 | 1211 |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1212 class RebuildRSOutOfRegionClosure: public HeapRegionClosure { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1213 G1CollectedHeap* _g1h; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1214 UpdateRSOopClosure _cl; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1215 int _worker_i; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1216 public: |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1217 RebuildRSOutOfRegionClosure(G1CollectedHeap* g1, int worker_i = 0) : |
1861 | 1218 _cl(g1->g1_rem_set(), worker_i), |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1219 _worker_i(worker_i), |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1220 _g1h(g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1221 { } |
1960
878b57474103
6978187: G1: assert(ParallelGCThreads> 1 || n_yielded() == _hrrs->occupied()) strikes again
johnc
parents:
1883
diff
changeset
|
1222 |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1223 bool doHeapRegion(HeapRegion* r) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1224 if (!r->continuesHumongous()) { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1225 _cl.set_from(r); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1226 r->oop_iterate(&_cl); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1227 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1228 return false; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1229 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1230 }; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1231 |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1232 class ParRebuildRSTask: public AbstractGangTask { |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1233 G1CollectedHeap* _g1; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1234 public: |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1235 ParRebuildRSTask(G1CollectedHeap* g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1236 : AbstractGangTask("ParRebuildRSTask"), |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1237 _g1(g1) |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1238 { } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1239 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
1240 void work(uint worker_id) { |
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
1241 RebuildRSOutOfRegionClosure rebuild_rs(_g1, worker_id); |
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
1242 _g1->heap_region_par_iterate_chunked(&rebuild_rs, worker_id, |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
1243 _g1->workers()->active_workers(), |
626
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1244 HeapRegion::RebuildRSClaimValue); |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1245 } |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1246 }; |
87fa6e083d82
6760309: G1: update remembered sets during Full GCs
apetrusenko
parents:
620
diff
changeset
|
1247 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1248 class PostCompactionPrinterClosure: public HeapRegionClosure { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1249 private: |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1250 G1HRPrinter* _hr_printer; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1251 public: |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1252 bool doHeapRegion(HeapRegion* hr) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1253 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
|
1254 // We only generate output for non-empty regions. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1255 if (!hr->is_empty()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1256 if (!hr->isHumongous()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1257 _hr_printer->post_compaction(hr, G1HRPrinter::Old); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1258 } else if (hr->startsHumongous()) { |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1259 if (hr->region_num() == 1) { |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1260 // single humongous region |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1261 _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1262 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1263 _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1264 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1265 } else { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1266 assert(hr->continuesHumongous(), "only way to get here"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1267 _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1268 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1269 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1270 return false; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1271 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1272 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1273 PostCompactionPrinterClosure(G1HRPrinter* hr_printer) |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1274 : _hr_printer(hr_printer) { } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1275 }; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1276 |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1277 void G1CollectedHeap::print_hrs_post_compaction() { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1278 PostCompactionPrinterClosure cl(hr_printer()); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1279 heap_region_iterate(&cl); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1280 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
1281 |
1973 | 1282 bool G1CollectedHeap::do_collection(bool explicit_gc, |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
1283 bool clear_all_soft_refs, |
342 | 1284 size_t word_size) { |
2152 | 1285 assert_at_safepoint(true /* should_be_vm_thread */); |
1286 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1287 if (GC_locker::check_active_before_gc()) { |
1973 | 1288 return false; |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1289 } |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
1290 |
10405 | 1291 STWGCTimer* gc_timer = G1MarkSweep::gc_timer(); |
1292 gc_timer->register_gc_start(os::elapsed_counter()); | |
1293 | |
1294 SerialOldTracer* gc_tracer = G1MarkSweep::gc_tracer(); | |
1295 gc_tracer->report_gc_start(gc_cause(), gc_timer->gc_start()); | |
1296 | |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
2039
diff
changeset
|
1297 SvcGCMarker sgcm(SvcGCMarker::FULL); |
342 | 1298 ResourceMark rm; |
1299 | |
4872
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4787
diff
changeset
|
1300 print_heap_before_gc(); |
10405 | 1301 trace_heap_before_gc(gc_tracer); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
1302 |
10183
868d87ed63c8
8008966: NPG: Inefficient Metaspace counter functions cause large young GC regressions
jmasa
parents:
10182
diff
changeset
|
1303 size_t metadata_prev_used = MetaspaceAux::allocated_used_bytes(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
1304 |
4072 | 1305 HRSPhaseSetter x(HRSPhaseFullGC); |
2152 | 1306 verify_region_sets_optional(); |
342 | 1307 |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1308 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
|
1309 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
|
1310 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1311 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
|
1312 |
342 | 1313 { |
1314 IsGCActiveMark x; | |
1315 | |
1316 // Timing | |
6030 | 1317 assert(gc_cause() != GCCause::_java_lang_system_gc || explicit_gc, "invariant"); |
6007
5c86f8211d1e
7160728: Introduce an extra logging level for G1 logging
brutisso
parents:
5987
diff
changeset
|
1318 gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps); |
5c86f8211d1e
7160728: Introduce an extra logging level for G1 logging
brutisso
parents:
5987
diff
changeset
|
1319 TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty); |
6030 | 1320 |
342 | 1321 { |
10405 | 1322 GCTraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, NULL); |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1323 TraceCollectorStats tcs(g1mm()->full_collection_counters()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1324 TraceMemoryManagerStats tms(true /* fullGC */, gc_cause()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1325 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1326 double start = os::elapsedTime(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1327 g1_policy()->record_full_collection_start(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1328 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1329 // Note: When we have a more flexible GC logging framework that |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1330 // allows us to add optional attributes to a GC log record we |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1331 // could consider timing and reporting how long we wait in the |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1332 // following two methods. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1333 wait_while_free_regions_coming(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1334 // If we start the compaction before the CM threads finish |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1335 // scanning the root regions we might trip them over as we'll |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1336 // be moving objects / updating references. So let's wait until |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1337 // they are done. By telling them to abort, they should complete |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1338 // early. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1339 _cm->root_regions()->abort(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1340 _cm->root_regions()->wait_until_scan_finished(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1341 append_secondary_free_list_if_not_empty_with_lock(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1342 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1343 gc_prologue(true); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1344 increment_total_collections(true /* full gc */); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1345 increment_old_marking_cycles_started(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1346 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1347 assert(used() == recalculate_used(), "Should be equal"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1348 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1349 verify_before_gc(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1350 |
10405 | 1351 pre_full_gc_dump(gc_timer); |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1352 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1353 COMPILER2_PRESENT(DerivedPointerTable::clear()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1354 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1355 // Disable discovery and empty the discovered lists |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1356 // for the CM ref processor. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1357 ref_processor_cm()->disable_discovery(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1358 ref_processor_cm()->abandon_partial_discovery(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1359 ref_processor_cm()->verify_no_references_recorded(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1360 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1361 // Abandon current iterations of concurrent marking and concurrent |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1362 // refinement, if any are in progress. We have to do this before |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1363 // wait_until_scan_finished() below. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1364 concurrent_mark()->abort(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1365 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1366 // Make sure we'll choose a new allocation region afterwards. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1367 release_mutator_alloc_region(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1368 abandon_gc_alloc_regions(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1369 g1_rem_set()->cleanupHRRS(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1370 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1371 // We should call this after we retire any currently active alloc |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1372 // regions so that all the ALLOC / RETIRE events are generated |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1373 // before the start GC event. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1374 _hr_printer.start_gc(true /* full */, (size_t) total_collections()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1375 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1376 // We may have added regions to the current incremental collection |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1377 // set between the last GC or pause and now. We need to clear the |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1378 // incremental collection set and then start rebuilding it afresh |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1379 // after this full GC. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1380 abandon_collection_set(g1_policy()->inc_cset_head()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1381 g1_policy()->clear_incremental_cset(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1382 g1_policy()->stop_incremental_cset_building(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1383 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1384 tear_down_region_sets(false /* free_list_only */); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1385 g1_policy()->set_gcs_are_young(true); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1386 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1387 // See the comments in g1CollectedHeap.hpp and |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1388 // G1CollectedHeap::ref_processing_init() about |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1389 // how reference processing currently works in G1. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1390 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1391 // Temporarily make discovery by the STW ref processor single threaded (non-MT). |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1392 ReferenceProcessorMTDiscoveryMutator stw_rp_disc_ser(ref_processor_stw(), false); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1393 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1394 // Temporarily clear the STW ref processor's _is_alive_non_header field. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1395 ReferenceProcessorIsAliveMutator stw_rp_is_alive_null(ref_processor_stw(), NULL); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1396 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1397 ref_processor_stw()->enable_discovery(true /*verify_disabled*/, true /*verify_no_refs*/); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1398 ref_processor_stw()->setup_policy(do_clear_all_soft_refs); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1399 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1400 // Do collection work |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1401 { |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1402 HandleMark hm; // Discard invalid handles created during gc |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1403 G1MarkSweep::invoke_at_safepoint(ref_processor_stw(), do_clear_all_soft_refs); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1404 } |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1405 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1406 assert(free_regions() == 0, "we should not have added any free regions"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1407 rebuild_region_sets(false /* free_list_only */); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1408 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1409 // Enqueue any discovered reference objects that have |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1410 // not been removed from the discovered lists. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1411 ref_processor_stw()->enqueue_discovered_references(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1412 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1413 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1414 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1415 MemoryService::track_memory_usage(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1416 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1417 assert(!ref_processor_stw()->discovery_enabled(), "Postcondition"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1418 ref_processor_stw()->verify_no_references_recorded(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1419 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1420 // Delete metaspaces for unloaded class loaders and clean up loader_data graph |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1421 ClassLoaderDataGraph::purge(); |
12080 | 1422 MetaspaceAux::verify_metrics(); |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1423 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1424 // Note: since we've just done a full GC, concurrent |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1425 // marking is no longer active. Therefore we need not |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1426 // re-enable reference discovery for the CM ref processor. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1427 // That will be done at the start of the next marking cycle. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1428 assert(!ref_processor_cm()->discovery_enabled(), "Postcondition"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1429 ref_processor_cm()->verify_no_references_recorded(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1430 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1431 reset_gc_time_stamp(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1432 // Since everything potentially moved, we will clear all remembered |
10405 | 1433 // sets, and clear all cards. Later we will rebuild remembered |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1434 // sets. We will also reset the GC time stamps of the regions. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1435 clear_rsets_post_compaction(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1436 check_gc_time_stamps(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1437 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1438 // Resize the heap if necessary. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1439 resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1440 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1441 if (_hr_printer.is_active()) { |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1442 // We should do this after we potentially resize the heap so |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1443 // that all the COMMIT / UNCOMMIT events are generated before |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1444 // the end GC event. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1445 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1446 print_hrs_post_compaction(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1447 _hr_printer.end_gc(true /* full */, (size_t) total_collections()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1448 } |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1449 |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
1450 G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache(); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
1451 if (hot_card_cache->use_cache()) { |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
1452 hot_card_cache->reset_card_counts(); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
1453 hot_card_cache->reset_hot_cache(); |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1454 } |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1455 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1456 // Rebuild remembered sets of all regions. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1457 if (G1CollectedHeap::use_parallel_gc_threads()) { |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1458 uint n_workers = |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1459 AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(), |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1460 workers()->active_workers(), |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1461 Threads::number_of_non_daemon_threads()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1462 assert(UseDynamicNumberOfGCThreads || |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1463 n_workers == workers()->total_workers(), |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1464 "If not dynamic should be using all the workers"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1465 workers()->set_active_workers(n_workers); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1466 // Set parallel threads in the heap (_n_par_threads) only |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1467 // before a parallel phase and always reset it to 0 after |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1468 // the phase so that the number of parallel threads does |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1469 // no get carried forward to a serial phase where there |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1470 // may be code that is "possibly_parallel". |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1471 set_par_threads(n_workers); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1472 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1473 ParRebuildRSTask rebuild_rs_task(this); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1474 assert(check_heap_region_claim_values( |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1475 HeapRegion::InitialClaimValue), "sanity check"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1476 assert(UseDynamicNumberOfGCThreads || |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1477 workers()->active_workers() == workers()->total_workers(), |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1478 "Unless dynamic should use total workers"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1479 // Use the most recent number of active workers |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1480 assert(workers()->active_workers() > 0, |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1481 "Active workers not properly set"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1482 set_par_threads(workers()->active_workers()); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1483 workers()->run_task(&rebuild_rs_task); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1484 set_par_threads(0); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1485 assert(check_heap_region_claim_values( |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1486 HeapRegion::RebuildRSClaimValue), "sanity check"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1487 reset_heap_region_claim_values(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1488 } else { |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1489 RebuildRSOutOfRegionClosure rebuild_rs(this); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1490 heap_region_iterate(&rebuild_rs); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1491 } |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1492 |
12080 | 1493 // Rebuild the strong code root lists for each region |
1494 rebuild_strong_code_roots(); | |
1495 | |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1496 if (true) { // FIXME |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1497 MetaspaceGC::compute_new_size(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1498 } |
342 | 1499 |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1500 #ifdef TRACESPINNING |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1501 ParallelTaskTerminator::print_termination_counts(); |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1502 #endif |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
1503 |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1504 // Discard all rset updates |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1505 JavaThread::dirty_card_queue_set().abandon_logs(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1506 assert(!G1DeferredRSUpdate |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1507 || (G1DeferredRSUpdate && |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1508 (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1509 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1510 _young_list->reset_sampled_info(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1511 // At this point there should be no regions in the |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1512 // entire heap tagged as young. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1513 assert(check_young_list_empty(true /* check_heap */), |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1514 "young list should be empty at this point"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1515 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1516 // Update the number of full collections that have been completed. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1517 increment_old_marking_cycles_completed(false /* concurrent */); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1518 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1519 _hrs.verify_optional(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1520 verify_region_sets_optional(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1521 |
10373
3a4805ad0005
8015244: G1: Verification after a full GC is incorrectly placed.
johnc
parents:
10372
diff
changeset
|
1522 verify_after_gc(); |
3a4805ad0005
8015244: G1: Verification after a full GC is incorrectly placed.
johnc
parents:
10372
diff
changeset
|
1523 |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1524 // Start a new incremental collection set for the next pause |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1525 assert(g1_policy()->collection_set() == NULL, "must be"); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1526 g1_policy()->start_incremental_cset_building(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1527 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1528 // Clear the _cset_fast_test bitmap in anticipation of adding |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1529 // regions to the incremental collection set for the next |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1530 // evacuation pause. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1531 clear_cset_fast_test(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1532 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1533 init_mutator_alloc_region(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1534 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1535 double end = os::elapsedTime(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1536 g1_policy()->record_full_collection_end(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1537 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1538 if (G1Log::fine()) { |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1539 g1_policy()->print_heap_transition(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1540 } |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1541 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1542 // We must call G1MonitoringSupport::update_sizes() in the same scoping level |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1543 // as an active TraceMemoryManagerStats object (i.e. before the destructor for the |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1544 // TraceMemoryManagerStats is called) so that the G1 memory pools are updated |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1545 // before any GC notifications are raised. |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1546 g1mm()->update_sizes(); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1547 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1548 gc_epilogue(true); |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1549 } |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1550 |
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1551 if (G1Log::finer()) { |
10291
48391ab0687e
8010738: G1: Output for full GCs with +PrintGCDetails should contain perm gen size/meta data change info
johnc
parents:
10246
diff
changeset
|
1552 g1_policy()->print_detailed_heap_transition(true /* full */); |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1553 } |
6121
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
1554 |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
1555 print_heap_after_gc(); |
10405 | 1556 trace_heap_after_gc(gc_tracer); |
1557 | |
1558 post_full_gc_dump(gc_timer); | |
1559 | |
1560 gc_timer->register_gc_end(os::elapsed_counter()); | |
1561 gc_tracer->report_gc_end(gc_timer->gc_end(), gc_timer->time_partitions()); | |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
1562 } |
1973 | 1563 |
1564 return true; | |
342 | 1565 } |
1566 | |
1567 void G1CollectedHeap::do_full_collection(bool clear_all_soft_refs) { | |
1973 | 1568 // do_collection() will return whether it succeeded in performing |
1569 // the GC. Currently, there is no facility on the | |
1570 // do_full_collection() API to notify the caller than the collection | |
1571 // did not succeed (e.g., because it was locked out by the GC | |
1572 // locker). So, right now, we'll ignore the return value. | |
1573 bool dummy = do_collection(true, /* explicit_gc */ | |
1574 clear_all_soft_refs, | |
1575 0 /* word_size */); | |
342 | 1576 } |
1577 | |
1578 // This code is mostly copied from TenuredGeneration. | |
1579 void | |
1580 G1CollectedHeap:: | |
1581 resize_if_necessary_after_full_collection(size_t word_size) { | |
1582 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, "sanity check"); | |
1583 | |
1584 // Include the current allocation, if any, and bytes that will be | |
1585 // pre-allocated to support collections, as "used". | |
1586 const size_t used_after_gc = used(); | |
1587 const size_t capacity_after_gc = capacity(); | |
1588 const size_t free_after_gc = capacity_after_gc - used_after_gc; | |
1589 | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1590 // This is enforced in arguments.cpp. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1591 assert(MinHeapFreeRatio <= MaxHeapFreeRatio, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1592 "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
|
1593 |
342 | 1594 // 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
|
1595 const double minimum_free_percentage = (double) MinHeapFreeRatio / 100.0; |
342 | 1596 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
|
1597 const double maximum_free_percentage = (double) MaxHeapFreeRatio / 100.0; |
342 | 1598 const double minimum_used_percentage = 1.0 - maximum_free_percentage; |
1599 | |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1600 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
|
1601 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
|
1602 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1603 // 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
|
1604 // 32-bit size_t's. |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1605 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
|
1606 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
|
1607 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
|
1608 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1609 // 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
|
1610 // 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
|
1611 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
|
1612 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
|
1613 desired_capacity_upper_bound); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1614 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
|
1615 desired_capacity_upper_bound); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1616 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1617 // 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
|
1618 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
|
1619 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
|
1620 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1621 // 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
|
1622 // 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
|
1623 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
|
1624 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
|
1625 "maximum_desired_capacity = "SIZE_FORMAT, |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1626 minimum_desired_capacity, maximum_desired_capacity)); |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1627 |
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1628 // 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
|
1629 // 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
|
1630 // 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
|
1631 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
|
1632 // 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
|
1633 // 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
|
1634 // 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
|
1635 maximum_desired_capacity = MAX2(maximum_desired_capacity, min_heap_size); |
342 | 1636 |
1717
688c3755d7af
6959014: G1: assert(minimum_desired_capacity <= maximum_desired_capacity) failed: sanity check
tonyp
parents:
1709
diff
changeset
|
1637 if (capacity_after_gc < minimum_desired_capacity) { |
342 | 1638 // Don't expand unless it's significant |
1639 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
|
1640 ergo_verbose4(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1641 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1642 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
|
1643 "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
|
1644 ergo_format_byte("capacity") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1645 ergo_format_byte("occupancy") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1646 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
|
1647 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
|
1648 minimum_desired_capacity, (double) MinHeapFreeRatio); |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1649 expand(expand_bytes); |
342 | 1650 |
1651 // 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
|
1652 } else if (capacity_after_gc > maximum_desired_capacity) { |
342 | 1653 // Capacity too large, compute shrinking size |
1654 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
|
1655 ergo_verbose4(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1656 "attempt heap shrinking", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1657 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
|
1658 "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
|
1659 ergo_format_byte("capacity") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1660 ergo_format_byte("occupancy") |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1661 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
|
1662 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
|
1663 maximum_desired_capacity, (double) MaxHeapFreeRatio); |
342 | 1664 shrink(shrink_bytes); |
1665 } | |
1666 } | |
1667 | |
1668 | |
1669 HeapWord* | |
1973 | 1670 G1CollectedHeap::satisfy_failed_allocation(size_t word_size, |
1671 bool* succeeded) { | |
2152 | 1672 assert_at_safepoint(true /* should_be_vm_thread */); |
1973 | 1673 |
1674 *succeeded = true; | |
1675 // Let's attempt the allocation first. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1676 HeapWord* result = |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1677 attempt_allocation_at_safepoint(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1678 false /* expect_null_mutator_alloc_region */); |
1973 | 1679 if (result != NULL) { |
1680 assert(*succeeded, "sanity"); | |
1681 return result; | |
1682 } | |
342 | 1683 |
1684 // In a G1 heap, we're supposed to keep allocation from failing by | |
1685 // incremental pauses. Therefore, at least for now, we'll favor | |
1686 // expansion over collection. (This might change in the future if we can | |
1687 // do something smarter than full collection to satisfy a failed alloc.) | |
1688 result = expand_and_allocate(word_size); | |
1689 if (result != NULL) { | |
1973 | 1690 assert(*succeeded, "sanity"); |
342 | 1691 return result; |
1692 } | |
1693 | |
1973 | 1694 // Expansion didn't work, we'll try to do a Full GC. |
1695 bool gc_succeeded = do_collection(false, /* explicit_gc */ | |
1696 false, /* clear_all_soft_refs */ | |
1697 word_size); | |
1698 if (!gc_succeeded) { | |
1699 *succeeded = false; | |
1700 return NULL; | |
1701 } | |
1702 | |
1703 // Retry the allocation | |
1704 result = attempt_allocation_at_safepoint(word_size, | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1705 true /* expect_null_mutator_alloc_region */); |
342 | 1706 if (result != NULL) { |
1973 | 1707 assert(*succeeded, "sanity"); |
342 | 1708 return result; |
1709 } | |
1710 | |
1973 | 1711 // Then, try a Full GC that will collect all soft references. |
1712 gc_succeeded = do_collection(false, /* explicit_gc */ | |
1713 true, /* clear_all_soft_refs */ | |
1714 word_size); | |
1715 if (!gc_succeeded) { | |
1716 *succeeded = false; | |
1717 return NULL; | |
1718 } | |
1719 | |
1720 // Retry the allocation once more | |
1721 result = attempt_allocation_at_safepoint(word_size, | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1722 true /* expect_null_mutator_alloc_region */); |
342 | 1723 if (result != NULL) { |
1973 | 1724 assert(*succeeded, "sanity"); |
342 | 1725 return result; |
1726 } | |
1727 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1360
diff
changeset
|
1728 assert(!collector_policy()->should_clear_all_soft_refs(), |
1973 | 1729 "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
|
1730 |
342 | 1731 // What else? We might try synchronous finalization later. If the total |
1732 // space available is large enough for the allocation, then a more | |
1733 // complete compaction phase than we've tried so far might be | |
1734 // appropriate. | |
1973 | 1735 assert(*succeeded, "sanity"); |
342 | 1736 return NULL; |
1737 } | |
1738 | |
1739 // Attempting to expand the heap sufficiently | |
1740 // to support an allocation of the given "word_size". If | |
1741 // successful, perform the allocation and return the address of the | |
1742 // allocated block, or else "NULL". | |
1743 | |
1744 HeapWord* G1CollectedHeap::expand_and_allocate(size_t word_size) { | |
2152 | 1745 assert_at_safepoint(true /* should_be_vm_thread */); |
1746 | |
1747 verify_region_sets_optional(); | |
1973 | 1748 |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1749 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
|
1750 ergo_verbose1(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1751 "attempt heap expansion", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1752 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
|
1753 ergo_format_byte("allocation request"), |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1754 word_size * HeapWordSize); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1755 if (expand(expand_bytes)) { |
3766 | 1756 _hrs.verify_optional(); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1757 verify_region_sets_optional(); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1758 return attempt_allocation_at_safepoint(word_size, |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
1759 false /* expect_null_mutator_alloc_region */); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1760 } |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1761 return NULL; |
342 | 1762 } |
1763 | |
3766 | 1764 void G1CollectedHeap::update_committed_space(HeapWord* old_end, |
1765 HeapWord* new_end) { | |
1766 assert(old_end != new_end, "don't call this otherwise"); | |
1767 assert((HeapWord*) _g1_storage.high() == new_end, "invariant"); | |
1768 | |
1769 // Update the committed mem region. | |
1770 _g1_committed.set_end(new_end); | |
1771 // Tell the card table about the update. | |
1772 Universe::heap()->barrier_set()->resize_covered_region(_g1_committed); | |
1773 // Tell the BOT about the update. | |
1774 _bot_shared->resize(_g1_committed.word_size()); | |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
1775 // Tell the hot card cache about the update |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
1776 _cg1r->hot_card_cache()->resize_card_counts(capacity()); |
3766 | 1777 } |
1778 | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1779 bool G1CollectedHeap::expand(size_t expand_bytes) { |
342 | 1780 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
|
1781 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); |
342 | 1782 aligned_expand_bytes = align_size_up(aligned_expand_bytes, |
1783 HeapRegion::GrainBytes); | |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1784 ergo_verbose2(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1785 "expand the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1786 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
|
1787 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
|
1788 expand_bytes, aligned_expand_bytes); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1789 |
3766 | 1790 // First commit the memory. |
1791 HeapWord* old_end = (HeapWord*) _g1_storage.high(); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1792 bool successful = _g1_storage.expand_by(aligned_expand_bytes); |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1793 if (successful) { |
3766 | 1794 // Then propagate this update to the necessary data structures. |
1795 HeapWord* new_end = (HeapWord*) _g1_storage.high(); | |
1796 update_committed_space(old_end, new_end); | |
1797 | |
1798 FreeRegionList expansion_list("Local Expansion List"); | |
1799 MemRegion mr = _hrs.expand_by(old_end, new_end, &expansion_list); | |
1800 assert(mr.start() == old_end, "post-condition"); | |
1801 // mr might be a smaller region than what was requested if | |
1802 // expand_by() was unable to allocate the HeapRegion instances | |
1803 assert(mr.end() <= new_end, "post-condition"); | |
1804 | |
1805 size_t actual_expand_bytes = mr.byte_size(); | |
1806 assert(actual_expand_bytes <= aligned_expand_bytes, "post-condition"); | |
1807 assert(actual_expand_bytes == expansion_list.total_capacity_bytes(), | |
1808 "post-condition"); | |
1809 if (actual_expand_bytes < aligned_expand_bytes) { | |
1810 // We could not expand _hrs to the desired size. In this case we | |
1811 // need to shrink the committed space accordingly. | |
1812 assert(mr.end() < new_end, "invariant"); | |
1813 | |
1814 size_t diff_bytes = aligned_expand_bytes - actual_expand_bytes; | |
1815 // First uncommit the memory. | |
1816 _g1_storage.shrink_by(diff_bytes); | |
1817 // Then propagate this update to the necessary data structures. | |
1818 update_committed_space(new_end, mr.end()); | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1819 } |
3766 | 1820 _free_list.add_as_tail(&expansion_list); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1821 |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1822 if (_hr_printer.is_active()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1823 HeapWord* curr = mr.start(); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1824 while (curr < mr.end()) { |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1825 HeapWord* curr_end = curr + HeapRegion::GrainWords; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1826 _hr_printer.commit(curr, curr_end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1827 curr = curr_end; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1828 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1829 assert(curr == mr.end(), "post-condition"); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1830 } |
3920
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
1831 g1_policy()->record_new_heap_size(n_regions()); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1832 } else { |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1833 ergo_verbose0(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1834 "did not expand the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1835 ergo_format_reason("heap expansion operation failed")); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1836 // The expansion of the virtual storage space was unsuccessful. |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1837 // 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
|
1838 if (G1ExitOnExpansionFailure && |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1839 _g1_storage.uncommitted_size() >= aligned_expand_bytes) { |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1840 // We had head room... |
10161
746b070f5022
8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents:
10099
diff
changeset
|
1841 vm_exit_out_of_memory(aligned_expand_bytes, OOM_MMAP_ERROR, "G1 heap expansion"); |
342 | 1842 } |
1843 } | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
1844 return successful; |
342 | 1845 } |
1846 | |
3766 | 1847 void G1CollectedHeap::shrink_helper(size_t shrink_bytes) { |
342 | 1848 size_t old_mem_size = _g1_storage.committed_size(); |
1849 size_t aligned_shrink_bytes = | |
1850 ReservedSpace::page_align_size_down(shrink_bytes); | |
1851 aligned_shrink_bytes = align_size_down(aligned_shrink_bytes, | |
1852 HeapRegion::GrainBytes); | |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1853 uint num_regions_to_remove = (uint)(shrink_bytes / HeapRegion::GrainBytes); |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1854 |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1855 uint num_regions_removed = _hrs.shrink_by(num_regions_to_remove); |
3766 | 1856 HeapWord* old_end = (HeapWord*) _g1_storage.high(); |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1857 size_t shrunk_bytes = num_regions_removed * HeapRegion::GrainBytes; |
3914
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1858 |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1859 ergo_verbose3(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1860 "shrink the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1861 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
|
1862 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
|
1863 ergo_format_byte("attempted shrinking amount"), |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1864 shrink_bytes, aligned_shrink_bytes, shrunk_bytes); |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1865 if (num_regions_removed > 0) { |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1866 _g1_storage.shrink_by(shrunk_bytes); |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1867 HeapWord* new_end = (HeapWord*) _g1_storage.high(); |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1868 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1869 if (_hr_printer.is_active()) { |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1870 HeapWord* curr = old_end; |
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1871 while (curr > new_end) { |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1872 HeapWord* curr_end = curr; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1873 curr -= HeapRegion::GrainWords; |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1874 _hr_printer.uncommit(curr, curr_end); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1875 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1876 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1877 |
10242
b0d20fa374b4
8013872: G1: HeapRegionSeq::shrink_by() has invalid assert
brutisso
parents:
10193
diff
changeset
|
1878 _expansion_regions += num_regions_removed; |
3766 | 1879 update_committed_space(old_end, new_end); |
1880 HeapRegionRemSet::shrink_heap(n_regions()); | |
3920
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
1881 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
|
1882 } else { |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1883 ergo_verbose0(ErgoHeapSizing, |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1884 "did not shrink the heap", |
20213c8a3c40
7050392: G1: Introduce flag to generate a log of the G1 ergonomic decisions
tonyp
parents:
3886
diff
changeset
|
1885 ergo_format_reason("heap shrinking operation failed")); |
342 | 1886 } |
1887 } | |
1888 | |
1889 void G1CollectedHeap::shrink(size_t shrink_bytes) { | |
2152 | 1890 verify_region_sets_optional(); |
1891 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1892 // 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
|
1893 // 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
|
1894 // 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
|
1895 abandon_gc_alloc_regions(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1896 |
2152 | 1897 // Instead of tearing down / rebuilding the free lists here, we |
1898 // could instead use the remove_all_pending() method on free_list to | |
1899 // remove only the ones that we need to remove. | |
4072 | 1900 tear_down_region_sets(true /* free_list_only */); |
342 | 1901 shrink_helper(shrink_bytes); |
4072 | 1902 rebuild_region_sets(true /* free_list_only */); |
2152 | 1903 |
3766 | 1904 _hrs.verify_optional(); |
2152 | 1905 verify_region_sets_optional(); |
342 | 1906 } |
1907 | |
1908 // Public methods. | |
1909 | |
1910 #ifdef _MSC_VER // the use of 'this' below gets a warning, make it go away | |
1911 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list | |
1912 #endif // _MSC_VER | |
1913 | |
1914 | |
1915 G1CollectedHeap::G1CollectedHeap(G1CollectorPolicy* policy_) : | |
1916 SharedHeap(policy_), | |
1917 _g1_policy(policy_), | |
1111 | 1918 _dirty_card_queue_set(false), |
1705 | 1919 _into_cset_dirty_card_queue_set(false), |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1920 _is_alive_closure_cm(this), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1921 _is_alive_closure_stw(this), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1922 _ref_processor_cm(NULL), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
1923 _ref_processor_stw(NULL), |
342 | 1924 _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)), |
1925 _bot_shared(NULL), | |
10405 | 1926 _evac_failure_scan_stack(NULL), |
342 | 1927 _mark_in_progress(false), |
2152 | 1928 _cg1r(NULL), _summary_bytes_used(0), |
3980
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
1929 _g1mm(NULL), |
342 | 1930 _refine_cte_cl(NULL), |
1931 _full_collection(false), | |
2152 | 1932 _free_list("Master Free List"), |
1933 _secondary_free_list("Secondary Free List"), | |
4072 | 1934 _old_set("Old Set"), |
2152 | 1935 _humongous_set("Master Humongous Set"), |
1936 _free_regions_coming(false), | |
342 | 1937 _young_list(new YoungList(this)), |
1938 _gc_time_stamp(0), | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
1939 _retained_old_gc_alloc_region(NULL), |
6595 | 1940 _survivor_plab_stats(YoungPLABSize, PLABWeight), |
1941 _old_plab_stats(OldPLABSize, PLABWeight), | |
4781
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
1942 _expand_heap_after_alloc_failure(true), |
526 | 1943 _surviving_young_words(NULL), |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
1944 _old_marking_cycles_started(0), |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
1945 _old_marking_cycles_completed(0), |
10405 | 1946 _concurrent_cycle_started(false), |
526 | 1947 _in_cset_fast_test(NULL), |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
1948 _in_cset_fast_test_base(NULL), |
4709
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
1949 _dirty_cards_region_list(NULL), |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
1950 _worker_cset_start_region(NULL), |
10405 | 1951 _worker_cset_start_region_time_stamp(NULL), |
1952 _gc_timer_stw(new (ResourceObj::C_HEAP, mtGC) STWGCTimer()), | |
1953 _gc_timer_cm(new (ResourceObj::C_HEAP, mtGC) ConcurrentGCTimer()), | |
1954 _gc_tracer_stw(new (ResourceObj::C_HEAP, mtGC) G1NewTracer()), | |
1955 _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) { | |
1956 | |
1957 _g1h = this; | |
342 | 1958 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { |
1959 vm_exit_during_initialization("Failed necessary allocation."); | |
1960 } | |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1961 |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1962 _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2; |
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
1963 |
342 | 1964 int n_queues = MAX2((int)ParallelGCThreads, 1); |
1965 _task_queues = new RefToScanQueueSet(n_queues); | |
1966 | |
1967 int n_rem_sets = HeapRegionRemSet::num_par_rem_sets(); | |
1968 assert(n_rem_sets > 0, "Invariant."); | |
1969 | |
6197 | 1970 _worker_cset_start_region = NEW_C_HEAP_ARRAY(HeapRegion*, n_queues, mtGC); |
1971 _worker_cset_start_region_time_stamp = NEW_C_HEAP_ARRAY(unsigned int, n_queues, mtGC); | |
10405 | 1972 _evacuation_failed_info_array = NEW_C_HEAP_ARRAY(EvacuationFailedInfo, n_queues, mtGC); |
4709
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
1973 |
342 | 1974 for (int i = 0; i < n_queues; i++) { |
1975 RefToScanQueue* q = new RefToScanQueue(); | |
1976 q->initialize(); | |
1977 _task_queues->register_queue(i, q); | |
10405 | 1978 ::new (&_evacuation_failed_info_array[i]) EvacuationFailedInfo(); |
1979 } | |
4709
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
1980 clear_cset_start_regions(); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
1981 |
6629
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
1982 // Initialize the G1EvacuationFailureALot counters and flags. |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
1983 NOT_PRODUCT(reset_evacuation_should_fail();) |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
1984 |
342 | 1985 guarantee(_task_queues != NULL, "task_queues allocation failure."); |
1986 } | |
1987 | |
1988 jint G1CollectedHeap::initialize() { | |
1166 | 1989 CollectedHeap::pre_initialize(); |
342 | 1990 os::enable_vtime(); |
1991 | |
6007
5c86f8211d1e
7160728: Introduce an extra logging level for G1 logging
brutisso
parents:
5987
diff
changeset
|
1992 G1Log::init(); |
5c86f8211d1e
7160728: Introduce an extra logging level for G1 logging
brutisso
parents:
5987
diff
changeset
|
1993 |
342 | 1994 // Necessary to satisfy locking discipline assertions. |
1995 | |
1996 MutexLocker x(Heap_lock); | |
1997 | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
1998 // 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
|
1999 // it will be used then. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
2000 _hr_printer.set_active(G1PrintHeapRegions); |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
2001 |
342 | 2002 // While there are no constraints in the GC code that HeapWordSize |
2003 // be any particular value, there are multiple other areas in the | |
2004 // system which believe this to be true (e.g. oop->object_size in some | |
2005 // cases incorrectly returns the size in wordSize units rather than | |
2006 // HeapWordSize). | |
2007 guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize"); | |
2008 | |
2009 size_t init_byte_size = collector_policy()->initial_heap_byte_size(); | |
2010 size_t max_byte_size = collector_policy()->max_heap_byte_size(); | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
12082
diff
changeset
|
2011 size_t heap_alignment = collector_policy()->max_alignment(); |
342 | 2012 |
2013 // Ensure that the sizes are properly aligned. | |
2014 Universe::check_alignment(init_byte_size, HeapRegion::GrainBytes, "g1 heap"); | |
2015 Universe::check_alignment(max_byte_size, HeapRegion::GrainBytes, "g1 heap"); | |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
12082
diff
changeset
|
2016 Universe::check_alignment(max_byte_size, heap_alignment, "g1 heap"); |
342 | 2017 |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2018 _cg1r = new ConcurrentG1Refine(this); |
342 | 2019 |
2020 // Reserve the maximum. | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
620
diff
changeset
|
2021 |
3824
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2022 // When compressed oops are enabled, the preferred heap base |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2023 // is calculated by subtracting the requested size from the |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2024 // 32Gb boundary and using the result as the base address for |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2025 // heap reservation. If the requested size is not aligned to |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2026 // HeapRegion::GrainBytes (i.e. the alignment that is passed |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2027 // into the ReservedHeapSpace constructor) then the actual |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2028 // base of the reserved heap may end up differing from the |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2029 // address that was requested (i.e. the preferred heap base). |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2030 // 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
|
2031 // compressed oops mode. |
6aa4feb8a366
7069863: G1: SIGSEGV running SPECjbb2011 and -UseBiasedLocking
johnc
parents:
3823
diff
changeset
|
2032 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2033 ReservedSpace heap_rs = Universe::reserve_heap(max_byte_size, |
12110
4c84d351cca9
8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents:
12082
diff
changeset
|
2034 heap_alignment); |
342 | 2035 |
2036 // It is important to do this in a way such that concurrent readers can't | |
10405 | 2037 // temporarily think something is in the heap. (I've actually seen this |
342 | 2038 // happen in asserts: DLD.) |
2039 _reserved.set_word_size(0); | |
2040 _reserved.set_start((HeapWord*)heap_rs.base()); | |
2041 _reserved.set_end((HeapWord*)(heap_rs.base() + heap_rs.size())); | |
2042 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2043 _expansion_regions = (uint) (max_byte_size / HeapRegion::GrainBytes); |
342 | 2044 |
2045 // Create the gen rem set (and barrier set) for the entire reserved region. | |
2046 _rem_set = collector_policy()->create_rem_set(_reserved, 2); | |
2047 set_barrier_set(rem_set()->bs()); | |
2048 if (barrier_set()->is_a(BarrierSet::ModRef)) { | |
2049 _mr_bs = (ModRefBarrierSet*)_barrier_set; | |
2050 } else { | |
2051 vm_exit_during_initialization("G1 requires a mod ref bs."); | |
2052 return JNI_ENOMEM; | |
2053 } | |
2054 | |
2055 // Also create a G1 rem set. | |
1861 | 2056 if (mr_bs()->is_a(BarrierSet::CardTableModRef)) { |
2057 _g1_rem_set = new G1RemSet(this, (CardTableModRefBS*)mr_bs()); | |
342 | 2058 } else { |
1861 | 2059 vm_exit_during_initialization("G1 requires a cardtable mod ref bs."); |
2060 return JNI_ENOMEM; | |
342 | 2061 } |
2062 | |
2063 // Carve out the G1 part of the heap. | |
2064 | |
2065 ReservedSpace g1_rs = heap_rs.first_part(max_byte_size); | |
2066 _g1_reserved = MemRegion((HeapWord*)g1_rs.base(), | |
2067 g1_rs.size()/HeapWordSize); | |
2068 | |
2069 _g1_storage.initialize(g1_rs, 0); | |
2070 _g1_committed = MemRegion((HeapWord*)_g1_storage.low(), (size_t) 0); | |
3766 | 2071 _hrs.initialize((HeapWord*) _g1_reserved.start(), |
2072 (HeapWord*) _g1_reserved.end(), | |
2073 _expansion_regions); | |
342 | 2074 |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2075 // Do later initialization work for concurrent refinement. |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2076 _cg1r->init(); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2077 |
807
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
2078 // 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
|
2079 // in the remembered set structures. |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2080 const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1; |
807
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
2081 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
|
2082 |
d44bdab1c03d
6843694: G1: assert(index < _vs.committed_size(),"bad index"), g1BlockOffsetTable.inline.hpp:55
johnc
parents:
796
diff
changeset
|
2083 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
|
2084 guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized"); |
3986
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
2085 guarantee(HeapRegion::CardsPerRegion < max_cards_per_region, |
942
2c79770d1f6e
6819085: G1: use larger and/or user settable region size
tonyp
parents:
941
diff
changeset
|
2086 "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
|
2087 |
2152 | 2088 HeapRegionSet::set_unrealistically_long_length(max_regions() + 1); |
2089 | |
342 | 2090 _bot_shared = new G1BlockOffsetSharedArray(_reserved, |
2091 heap_word_size(init_byte_size)); | |
2092 | |
2093 _g1h = this; | |
2094 | |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2095 _in_cset_fast_test_length = max_regions(); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2096 _in_cset_fast_test_base = |
6197 | 2097 NEW_C_HEAP_ARRAY(bool, (size_t) _in_cset_fast_test_length, mtGC); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
2098 |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2099 // We're biasing _in_cset_fast_test to avoid subtracting the |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2100 // beginning of the heap every time we want to index; basically |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2101 // it's the same with what we do with the card table. |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2102 _in_cset_fast_test = _in_cset_fast_test_base - |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2103 ((uintx) _g1_reserved.start() >> HeapRegion::LogOfHRGrainBytes); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
2104 |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2105 // Clear the _cset_fast_test bitmap in anticipation of adding |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2106 // regions to the incremental collection set for the first |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2107 // evacuation pause. |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2108 clear_cset_fast_test(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
2109 |
342 | 2110 // Create the ConcurrentMark data structure and thread. |
2111 // (Must do this late, so that "max_regions" is defined.) | |
7397
442f942757c0
8000244: G1: Ergonomically set MarkStackSize and use virtual space for global marking stack
johnc
parents:
7207
diff
changeset
|
2112 _cm = new ConcurrentMark(this, heap_rs); |
442f942757c0
8000244: G1: Ergonomically set MarkStackSize and use virtual space for global marking stack
johnc
parents:
7207
diff
changeset
|
2113 if (_cm == NULL || !_cm->completed_initialization()) { |
442f942757c0
8000244: G1: Ergonomically set MarkStackSize and use virtual space for global marking stack
johnc
parents:
7207
diff
changeset
|
2114 vm_shutdown_during_initialization("Could not create/initialize ConcurrentMark"); |
442f942757c0
8000244: G1: Ergonomically set MarkStackSize and use virtual space for global marking stack
johnc
parents:
7207
diff
changeset
|
2115 return JNI_ENOMEM; |
442f942757c0
8000244: G1: Ergonomically set MarkStackSize and use virtual space for global marking stack
johnc
parents:
7207
diff
changeset
|
2116 } |
342 | 2117 _cmThread = _cm->cmThread(); |
2118 | |
2119 // Initialize the from_card cache structure of HeapRegionRemSet. | |
2120 HeapRegionRemSet::init_heap(max_regions()); | |
2121 | |
677 | 2122 // Now expand into the initial heap size. |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2123 if (!expand(init_byte_size)) { |
7397
442f942757c0
8000244: G1: Ergonomically set MarkStackSize and use virtual space for global marking stack
johnc
parents:
7207
diff
changeset
|
2124 vm_shutdown_during_initialization("Failed to allocate initial heap."); |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2125 return JNI_ENOMEM; |
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
2126 } |
342 | 2127 |
2128 // Perform any initialization actions delegated to the policy. | |
2129 g1_policy()->init(); | |
2130 | |
2131 _refine_cte_cl = | |
2132 new RefineCardTableEntryClosure(ConcurrentG1RefineThread::sts(), | |
2133 g1_rem_set(), | |
2134 concurrent_g1_refine()); | |
2135 JavaThread::dirty_card_queue_set().set_closure(_refine_cte_cl); | |
2136 | |
2137 JavaThread::satb_mark_queue_set().initialize(SATB_Q_CBL_mon, | |
2138 SATB_Q_FL_lock, | |
1111 | 2139 G1SATBProcessCompletedThreshold, |
342 | 2140 Shared_SATB_Q_lock); |
794 | 2141 |
2142 JavaThread::dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, | |
2143 DirtyCardQ_FL_lock, | |
1111 | 2144 concurrent_g1_refine()->yellow_zone(), |
2145 concurrent_g1_refine()->red_zone(), | |
794 | 2146 Shared_DirtyCardQ_lock); |
2147 | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2148 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2149 dirty_card_queue_set().initialize(DirtyCardQ_CBL_mon, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2150 DirtyCardQ_FL_lock, |
1111 | 2151 -1, // never trigger processing |
2152 -1, // no limit on length | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2153 Shared_DirtyCardQ_lock, |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2154 &JavaThread::dirty_card_queue_set()); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
2155 } |
1705 | 2156 |
2157 // Initialize the card queue set used to hold cards containing | |
2158 // references into the collection set. | |
2159 _into_cset_dirty_card_queue_set.initialize(DirtyCardQ_CBL_mon, | |
2160 DirtyCardQ_FL_lock, | |
2161 -1, // never trigger processing | |
2162 -1, // no limit on length | |
2163 Shared_DirtyCardQ_lock, | |
2164 &JavaThread::dirty_card_queue_set()); | |
2165 | |
342 | 2166 // In case we're keeping closure specialization stats, initialize those |
2167 // counts and that mechanism. | |
2168 SpecializationStats::clear(); | |
2169 | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2170 // 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
|
2171 // 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
|
2172 // space here, lots of asserts fire. |
3766 | 2173 |
2174 HeapRegion* dummy_region = new_heap_region(0 /* index of bottom region */, | |
2175 _g1_reserved.start()); | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2176 // 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
|
2177 // 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
|
2178 // 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
|
2179 // 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
|
2180 dummy_region->set_young(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2181 // Make sure it's full. |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2182 dummy_region->set_top(dummy_region->end()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2183 G1AllocRegion::setup(this, dummy_region); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2184 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2185 init_mutator_alloc_region(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2186 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2187 // 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
|
2188 // values in the heap have been properly initialized. |
3980
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
2189 _g1mm = new G1MonitoringSupport(this); |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
2190 |
342 | 2191 return JNI_OK; |
2192 } | |
2193 | |
12233
40136aa2cdb1
8010722: assert: failed: heap size is too big for compressed oops
tschatzl
parents:
12179
diff
changeset
|
2194 size_t G1CollectedHeap::conservative_max_heap_alignment() { |
40136aa2cdb1
8010722: assert: failed: heap size is too big for compressed oops
tschatzl
parents:
12179
diff
changeset
|
2195 return HeapRegion::max_region_size(); |
40136aa2cdb1
8010722: assert: failed: heap size is too big for compressed oops
tschatzl
parents:
12179
diff
changeset
|
2196 } |
40136aa2cdb1
8010722: assert: failed: heap size is too big for compressed oops
tschatzl
parents:
12179
diff
changeset
|
2197 |
342 | 2198 void G1CollectedHeap::ref_processing_init() { |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2199 // Reference processing in G1 currently works as follows: |
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2200 // |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2201 // * There are two reference processor instances. One is |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2202 // used to record and process discovered references |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2203 // during concurrent marking; the other is used to |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2204 // record and process references during STW pauses |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2205 // (both full and incremental). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2206 // * Both ref processors need to 'span' the entire heap as |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2207 // the regions in the collection set may be dotted around. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2208 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2209 // * For the concurrent marking ref processor: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2210 // * Reference discovery is enabled at initial marking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2211 // * Reference discovery is disabled and the discovered |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2212 // references processed etc during remarking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2213 // * Reference discovery is MT (see below). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2214 // * Reference discovery requires a barrier (see below). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2215 // * Reference processing may or may not be MT |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2216 // (depending on the value of ParallelRefProcEnabled |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2217 // and ParallelGCThreads). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2218 // * A full GC disables reference discovery by the CM |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2219 // ref processor and abandons any entries on it's |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2220 // discovered lists. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2221 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2222 // * For the STW processor: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2223 // * 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
|
2224 // * Processing and enqueueing during a full GC is non-MT. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2225 // * During a full GC, references are processed after marking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2226 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2227 // * 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
|
2228 // of an incremental evacuation pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2229 // * References are processed near the end of a STW evacuation pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2230 // * For both types of GC: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2231 // * Discovery is atomic - i.e. not concurrent. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2232 // * Reference discovery will not need a barrier. |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
2233 |
342 | 2234 SharedHeap::ref_processing_init(); |
2235 MemRegion mr = reserved_region(); | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2236 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2237 // Concurrent Mark ref processor |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2238 _ref_processor_cm = |
2369
92da084fefc9
6668573: CMS: reference processing crash if ParallelCMSThreads > ParallelGCThreads
ysr
parents:
2361
diff
changeset
|
2239 new ReferenceProcessor(mr, // span |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2240 ParallelRefProcEnabled && (ParallelGCThreads > 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2241 // mt processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2242 (int) ParallelGCThreads, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2243 // degree of mt processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2244 (ParallelGCThreads > 1) || (ConcGCThreads > 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2245 // mt discovery |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2246 (int) MAX2(ParallelGCThreads, ConcGCThreads), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2247 // degree of mt discovery |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2248 false, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2249 // Reference discovery is not atomic |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2250 &_is_alive_closure_cm, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2251 // is alive closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2252 // (for efficiency/performance) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2253 true); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2254 // Setting next fields of discovered |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2255 // lists requires a barrier. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2256 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2257 // STW ref processor |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2258 _ref_processor_stw = |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2259 new ReferenceProcessor(mr, // span |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2260 ParallelRefProcEnabled && (ParallelGCThreads > 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2261 // mt processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2262 MAX2((int)ParallelGCThreads, 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2263 // degree of mt processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2264 (ParallelGCThreads > 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2265 // mt discovery |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2266 MAX2((int)ParallelGCThreads, 1), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2267 // degree of mt discovery |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2268 true, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2269 // Reference discovery is atomic |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2270 &_is_alive_closure_stw, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2271 // is alive closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2272 // (for efficiency/performance) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2273 false); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2274 // Setting next fields of discovered |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
2275 // lists requires a barrier. |
342 | 2276 } |
2277 | |
2278 size_t G1CollectedHeap::capacity() const { | |
2279 return _g1_committed.byte_size(); | |
2280 } | |
2281 | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2282 void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2283 assert(!hr->continuesHumongous(), "pre-condition"); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2284 hr->reset_gc_time_stamp(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2285 if (hr->startsHumongous()) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2286 uint first_index = hr->hrs_index() + 1; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2287 uint last_index = hr->last_hc_index(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2288 for (uint i = first_index; i < last_index; i += 1) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2289 HeapRegion* chr = region_at(i); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2290 assert(chr->continuesHumongous(), "sanity"); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2291 chr->reset_gc_time_stamp(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2292 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2293 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2294 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2295 |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2296 #ifndef PRODUCT |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2297 class CheckGCTimeStampsHRClosure : public HeapRegionClosure { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2298 private: |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2299 unsigned _gc_time_stamp; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2300 bool _failures; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2301 |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2302 public: |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2303 CheckGCTimeStampsHRClosure(unsigned gc_time_stamp) : |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2304 _gc_time_stamp(gc_time_stamp), _failures(false) { } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2305 |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2306 virtual bool doHeapRegion(HeapRegion* hr) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2307 unsigned region_gc_time_stamp = hr->get_gc_time_stamp(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2308 if (_gc_time_stamp != region_gc_time_stamp) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2309 gclog_or_tty->print_cr("Region "HR_FORMAT" has GC time stamp = %d, " |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2310 "expected %d", HR_FORMAT_PARAMS(hr), |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2311 region_gc_time_stamp, _gc_time_stamp); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2312 _failures = true; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2313 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2314 return false; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2315 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2316 |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2317 bool failures() { return _failures; } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2318 }; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2319 |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2320 void G1CollectedHeap::check_gc_time_stamps() { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2321 CheckGCTimeStampsHRClosure cl(_gc_time_stamp); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2322 heap_region_iterate(&cl); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2323 guarantee(!cl.failures(), "all GC time stamps should have been reset"); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2324 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2325 #endif // PRODUCT |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2326 |
1705 | 2327 void G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure* cl, |
2328 DirtyCardQueue* into_cset_dcq, | |
2329 bool concurrent, | |
342 | 2330 int worker_i) { |
889 | 2331 // Clean cards in the hot card cache |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2332 G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache(); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
2333 hot_card_cache->drain(worker_i, g1_rem_set(), into_cset_dcq); |
889 | 2334 |
342 | 2335 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); |
2336 int n_completed_buffers = 0; | |
1705 | 2337 while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) { |
342 | 2338 n_completed_buffers++; |
2339 } | |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
2340 g1_policy()->phase_times()->record_update_rs_processed_buffers(worker_i, n_completed_buffers); |
342 | 2341 dcqs.clear_n_completed_buffers(); |
2342 assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!"); | |
2343 } | |
2344 | |
2345 | |
2346 // Computes the sum of the storage used by the various regions. | |
2347 | |
2348 size_t G1CollectedHeap::used() const { | |
862
36b5611220a7
6863216: Clean up debugging debris inadvertently pushed with 6700789
ysr
parents:
861
diff
changeset
|
2349 assert(Heap_lock->owner() != NULL, |
36b5611220a7
6863216: Clean up debugging debris inadvertently pushed with 6700789
ysr
parents:
861
diff
changeset
|
2350 "Should be owned on this thread's behalf."); |
342 | 2351 size_t result = _summary_bytes_used; |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2352 // 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
|
2353 HeapRegion* hr = _mutator_alloc_region.get(); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2354 if (hr != NULL) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
2355 result += hr->used(); |
342 | 2356 return result; |
2357 } | |
2358 | |
846
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2359 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
|
2360 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
|
2361 return result; |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2362 } |
42d84bbbecf4
6859911: G1: assert(Heap_lock->owner() = NULL, "Should be owned on this thread's behalf")
tonyp
parents:
845
diff
changeset
|
2363 |
342 | 2364 class SumUsedClosure: public HeapRegionClosure { |
2365 size_t _used; | |
2366 public: | |
2367 SumUsedClosure() : _used(0) {} | |
2368 bool doHeapRegion(HeapRegion* r) { | |
2369 if (!r->continuesHumongous()) { | |
2370 _used += r->used(); | |
2371 } | |
2372 return false; | |
2373 } | |
2374 size_t result() { return _used; } | |
2375 }; | |
2376 | |
2377 size_t G1CollectedHeap::recalculate_used() const { | |
2378 SumUsedClosure blk; | |
3766 | 2379 heap_region_iterate(&blk); |
342 | 2380 return blk.result(); |
2381 } | |
2382 | |
2383 size_t G1CollectedHeap::unsafe_max_alloc() { | |
2152 | 2384 if (free_regions() > 0) return HeapRegion::GrainBytes; |
342 | 2385 // otherwise, is there space in the current allocation region? |
2386 | |
2387 // We need to store the current allocation region in a local variable | |
2388 // here. The problem is that this method doesn't take any locks and | |
2389 // there may be other threads which overwrite the current allocation | |
2390 // region field. attempt_allocation(), for example, sets it to NULL | |
2391 // and this can happen *after* the NULL check here but before the call | |
2392 // to free(), resulting in a SIGSEGV. Note that this doesn't appear | |
2393 // to be a problem in the optimized build, since the two loads of the | |
2394 // current allocation region field are optimized away. | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2395 HeapRegion* hr = _mutator_alloc_region.get(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2396 if (hr == NULL) { |
342 | 2397 return 0; |
2398 } | |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
2399 return hr->free(); |
342 | 2400 } |
2401 | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2402 bool G1CollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2403 switch (cause) { |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2404 case GCCause::_gc_locker: return GCLockerInvokesConcurrent; |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2405 case GCCause::_java_lang_system_gc: return ExplicitGCInvokesConcurrent; |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2406 case GCCause::_g1_humongous_allocation: return true; |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2407 default: return false; |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2408 } |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2409 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2410 |
3285
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2411 #ifndef PRODUCT |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2412 void G1CollectedHeap::allocate_dummy_regions() { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2413 // Let's fill up most of the region |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2414 size_t word_size = HeapRegion::GrainWords - 1024; |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2415 // 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
|
2416 guarantee(isHumongous(word_size), "sanity"); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2417 |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2418 for (uintx i = 0; i < G1DummyRegionsPerGC; ++i) { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2419 // 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
|
2420 HeapWord* dummy_obj = humongous_obj_allocate(word_size); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2421 if (dummy_obj != NULL) { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2422 MemRegion mr(dummy_obj, word_size); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2423 CollectedHeap::fill_with_object(mr); |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2424 } else { |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2425 // 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
|
2426 // again. Let's get out of the loop. |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2427 break; |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2428 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2429 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2430 } |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2431 #endif // !PRODUCT |
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
2432 |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2433 void G1CollectedHeap::increment_old_marking_cycles_started() { |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2434 assert(_old_marking_cycles_started == _old_marking_cycles_completed || |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2435 _old_marking_cycles_started == _old_marking_cycles_completed + 1, |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2436 err_msg("Wrong marking cycle count (started: %d, completed: %d)", |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2437 _old_marking_cycles_started, _old_marking_cycles_completed)); |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2438 |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2439 _old_marking_cycles_started++; |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2440 } |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2441 |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2442 void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent) { |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2443 MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2444 |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2445 // 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
|
2446 // 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
|
2447 // 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
|
2448 // assert here. |
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2449 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2450 // 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
|
2451 // 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
|
2452 // interrupt a concurrent cycle), the number of full collections |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2453 // 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
|
2454 // 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
|
2455 // behind the number of full collections started. |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2456 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2457 // 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
|
2458 assert(concurrent || |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2459 (_old_marking_cycles_started == _old_marking_cycles_completed + 1) || |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2460 (_old_marking_cycles_started == _old_marking_cycles_completed + 2), |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2461 err_msg("for inner caller (Full GC): _old_marking_cycles_started = %u " |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2462 "is inconsistent with _old_marking_cycles_completed = %u", |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2463 _old_marking_cycles_started, _old_marking_cycles_completed)); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2464 |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2465 // 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
|
2466 assert(!concurrent || |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2467 (_old_marking_cycles_started == _old_marking_cycles_completed + 1), |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2468 err_msg("for outer caller (concurrent cycle): " |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2469 "_old_marking_cycles_started = %u " |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2470 "is inconsistent with _old_marking_cycles_completed = %u", |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2471 _old_marking_cycles_started, _old_marking_cycles_completed)); |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2472 |
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2473 _old_marking_cycles_completed += 1; |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2474 |
1840
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2475 // 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
|
2476 // we wake up any waiters (especially when ExplicitInvokesConcurrent |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2477 // is set) so that if a waiter requests another System.gc() it doesn't |
10405 | 2478 // incorrectly see that a marking cycle is still in progress. |
2030
fb712ff22571
7000559: G1: assertion failure !outer || (full_collections_started == _full_collections_completed + 1)
tonyp
parents:
1995
diff
changeset
|
2479 if (concurrent) { |
1840
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2480 _cmThread->clear_in_progress(); |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2481 } |
4e0094bc41fa
6983311: G1: LoopTest hangs when run with -XX:+ExplicitInvokesConcurrent
johnc
parents:
1833
diff
changeset
|
2482 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2483 // 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
|
2484 // System.gc() with (with ExplicitGCInvokesConcurrent set or not) |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2485 // 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
|
2486 // waiting in VM_G1IncCollectionPause::doit_epilogue(). |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2487 FullGCCount_lock->notify_all(); |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2488 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2489 |
10405 | 2490 void G1CollectedHeap::register_concurrent_cycle_start(jlong start_time) { |
2491 _concurrent_cycle_started = true; | |
2492 _gc_timer_cm->register_gc_start(start_time); | |
2493 | |
2494 _gc_tracer_cm->report_gc_start(gc_cause(), _gc_timer_cm->gc_start()); | |
2495 trace_heap_before_gc(_gc_tracer_cm); | |
2496 } | |
2497 | |
2498 void G1CollectedHeap::register_concurrent_cycle_end() { | |
2499 if (_concurrent_cycle_started) { | |
2500 if (_cm->has_aborted()) { | |
2501 _gc_tracer_cm->report_concurrent_mode_failure(); | |
2502 } | |
12179
f175e3678be2
8020692: TestGCEventMixed.java failed because of timestamp in event after end event
ehelin
parents:
12116
diff
changeset
|
2503 |
f175e3678be2
8020692: TestGCEventMixed.java failed because of timestamp in event after end event
ehelin
parents:
12116
diff
changeset
|
2504 _gc_timer_cm->register_gc_end(os::elapsed_counter()); |
10405 | 2505 _gc_tracer_cm->report_gc_end(_gc_timer_cm->gc_end(), _gc_timer_cm->time_partitions()); |
2506 | |
2507 _concurrent_cycle_started = false; | |
2508 } | |
2509 } | |
2510 | |
2511 void G1CollectedHeap::trace_heap_after_concurrent_cycle() { | |
2512 if (_concurrent_cycle_started) { | |
2513 trace_heap_after_gc(_gc_tracer_cm); | |
2514 } | |
2515 } | |
2516 | |
2517 G1YCType G1CollectedHeap::yc_type() { | |
2518 bool is_young = g1_policy()->gcs_are_young(); | |
2519 bool is_initial_mark = g1_policy()->during_initial_mark_pause(); | |
2520 bool is_during_mark = mark_in_progress(); | |
2521 | |
2522 if (is_initial_mark) { | |
2523 return InitialMark; | |
2524 } else if (is_during_mark) { | |
2525 return DuringMark; | |
2526 } else if (is_young) { | |
2527 return Normal; | |
2528 } else { | |
2529 return Mixed; | |
2530 } | |
2531 } | |
2532 | |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2533 void G1CollectedHeap::collect(GCCause::Cause cause) { |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2534 assert_heap_not_locked(); |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2535 |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2536 unsigned int gc_count_before; |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2537 unsigned int old_marking_count_before; |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2538 bool retry_gc; |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2539 |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2540 do { |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2541 retry_gc = false; |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2542 |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2543 { |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2544 MutexLocker ml(Heap_lock); |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2545 |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2546 // Read the GC count while holding the Heap_lock |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2547 gc_count_before = total_collections(); |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2548 old_marking_count_before = _old_marking_cycles_started; |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2549 } |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2550 |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2551 if (should_do_concurrent_full_gc(cause)) { |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2552 // Schedule an initial-mark evacuation pause that will start a |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2553 // concurrent cycle. We're setting word_size to 0 which means that |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2554 // we are not requesting a post-GC allocation. |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2555 VM_G1IncCollectionPause op(gc_count_before, |
1973 | 2556 0, /* word_size */ |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2557 true, /* should_initiate_conc_mark */ |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2558 g1_policy()->max_pause_time_ms(), |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2559 cause); |
5963
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
2560 |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2561 VMThread::execute(&op); |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2562 if (!op.pause_succeeded()) { |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2563 if (old_marking_count_before == _old_marking_cycles_started) { |
5963
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
2564 retry_gc = op.should_retry_gc(); |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2565 } else { |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2566 // A Full GC happened while we were trying to schedule the |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2567 // initial-mark GC. No point in starting a new cycle given |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2568 // that the whole heap was collected anyway. |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2569 } |
5963
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
2570 |
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
2571 if (retry_gc) { |
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
2572 if (GC_locker::is_active_and_needs_gc()) { |
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
2573 GC_locker::stall_until_clear(); |
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
2574 } |
64bf7c8270cb
7147724: G1: hang in SurrogateLockerThread::manipulatePLL
johnc
parents:
4912
diff
changeset
|
2575 } |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2576 } |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2577 } else { |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2578 if (cause == GCCause::_gc_locker |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2579 DEBUG_ONLY(|| cause == GCCause::_scavenge_alot)) { |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2580 |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2581 // Schedule a standard evacuation pause. We're setting word_size |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2582 // to 0 which means that we are not requesting a post-GC allocation. |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2583 VM_G1IncCollectionPause op(gc_count_before, |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2584 0, /* word_size */ |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2585 false, /* should_initiate_conc_mark */ |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2586 g1_policy()->max_pause_time_ms(), |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2587 cause); |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2588 VMThread::execute(&op); |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2589 } else { |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2590 // Schedule a Full GC. |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
2591 VM_G1CollectFull op(gc_count_before, old_marking_count_before, cause); |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2592 VMThread::execute(&op); |
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2593 } |
1088
3fc996d4edd2
6902303: G1: ScavengeALot should cause an incremental, rather than a full, collection
ysr
parents:
1045
diff
changeset
|
2594 } |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
2595 } while (retry_gc); |
342 | 2596 } |
2597 | |
2598 bool G1CollectedHeap::is_in(const void* p) const { | |
4708 | 2599 if (_g1_committed.contains(p)) { |
2600 // Given that we know that p is in the committed space, | |
2601 // heap_region_containing_raw() should successfully | |
2602 // return the containing region. | |
2603 HeapRegion* hr = heap_region_containing_raw(p); | |
342 | 2604 return hr->is_in(p); |
2605 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2606 return false; |
342 | 2607 } |
2608 } | |
2609 | |
2610 // Iteration functions. | |
2611 | |
2612 // Iterates an OopClosure over all ref-containing fields of objects | |
2613 // within a HeapRegion. | |
2614 | |
2615 class IterateOopClosureRegionClosure: public HeapRegionClosure { | |
2616 MemRegion _mr; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2617 ExtendedOopClosure* _cl; |
342 | 2618 public: |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2619 IterateOopClosureRegionClosure(MemRegion mr, ExtendedOopClosure* cl) |
342 | 2620 : _mr(mr), _cl(cl) {} |
2621 bool doHeapRegion(HeapRegion* r) { | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2622 if (!r->continuesHumongous()) { |
342 | 2623 r->oop_iterate(_cl); |
2624 } | |
2625 return false; | |
2626 } | |
2627 }; | |
2628 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2629 void G1CollectedHeap::oop_iterate(ExtendedOopClosure* cl) { |
342 | 2630 IterateOopClosureRegionClosure blk(_g1_committed, cl); |
3766 | 2631 heap_region_iterate(&blk); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2632 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2633 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2634 void G1CollectedHeap::oop_iterate(MemRegion mr, ExtendedOopClosure* cl) { |
342 | 2635 IterateOopClosureRegionClosure blk(mr, cl); |
3766 | 2636 heap_region_iterate(&blk); |
342 | 2637 } |
2638 | |
2639 // Iterates an ObjectClosure over all objects within a HeapRegion. | |
2640 | |
2641 class IterateObjectClosureRegionClosure: public HeapRegionClosure { | |
2642 ObjectClosure* _cl; | |
2643 public: | |
2644 IterateObjectClosureRegionClosure(ObjectClosure* cl) : _cl(cl) {} | |
2645 bool doHeapRegion(HeapRegion* r) { | |
2646 if (! r->continuesHumongous()) { | |
2647 r->object_iterate(_cl); | |
2648 } | |
2649 return false; | |
2650 } | |
2651 }; | |
2652 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
2653 void G1CollectedHeap::object_iterate(ObjectClosure* cl) { |
342 | 2654 IterateObjectClosureRegionClosure blk(cl); |
3766 | 2655 heap_region_iterate(&blk); |
342 | 2656 } |
2657 | |
2658 // Calls a SpaceClosure on a HeapRegion. | |
2659 | |
2660 class SpaceClosureRegionClosure: public HeapRegionClosure { | |
2661 SpaceClosure* _cl; | |
2662 public: | |
2663 SpaceClosureRegionClosure(SpaceClosure* cl) : _cl(cl) {} | |
2664 bool doHeapRegion(HeapRegion* r) { | |
2665 _cl->do_space(r); | |
2666 return false; | |
2667 } | |
2668 }; | |
2669 | |
2670 void G1CollectedHeap::space_iterate(SpaceClosure* cl) { | |
2671 SpaceClosureRegionClosure blk(cl); | |
3766 | 2672 heap_region_iterate(&blk); |
342 | 2673 } |
2674 | |
3766 | 2675 void G1CollectedHeap::heap_region_iterate(HeapRegionClosure* cl) const { |
2676 _hrs.iterate(cl); | |
342 | 2677 } |
2678 | |
2679 void | |
2680 G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl, | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2681 uint worker_id, |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
2682 uint no_of_par_workers, |
342 | 2683 jint claim_value) { |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2684 const uint regions = n_regions(); |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
2685 const uint max_workers = (G1CollectedHeap::use_parallel_gc_threads() ? |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
2686 no_of_par_workers : |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
2687 1); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
2688 assert(UseDynamicNumberOfGCThreads || |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
2689 no_of_par_workers == workers()->total_workers(), |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
2690 "Non dynamic should use fixed number of workers"); |
355 | 2691 // try to spread out the starting points of the workers |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2692 const HeapRegion* start_hr = |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2693 start_region_for_worker(worker_id, no_of_par_workers); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2694 const uint start_index = start_hr->hrs_index(); |
355 | 2695 |
2696 // each worker will actually look at all regions | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2697 for (uint count = 0; count < regions; ++count) { |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2698 const uint index = (start_index + count) % regions; |
355 | 2699 assert(0 <= index && index < regions, "sanity"); |
2700 HeapRegion* r = region_at(index); | |
2701 // we'll ignore "continues humongous" regions (we'll process them | |
2702 // when we come across their corresponding "start humongous" | |
2703 // region) and regions already claimed | |
2704 if (r->claim_value() == claim_value || r->continuesHumongous()) { | |
2705 continue; | |
2706 } | |
2707 // OK, try to claim it | |
342 | 2708 if (r->claimHeapRegion(claim_value)) { |
355 | 2709 // success! |
2710 assert(!r->continuesHumongous(), "sanity"); | |
2711 if (r->startsHumongous()) { | |
2712 // If the region is "starts humongous" we'll iterate over its | |
2713 // "continues humongous" first; in fact we'll do them | |
2714 // first. The order is important. In on case, calling the | |
2715 // closure on the "starts humongous" region might de-allocate | |
2716 // and clear all its "continues humongous" regions and, as a | |
2717 // result, we might end up processing them twice. So, we'll do | |
2718 // them first (notice: most closures will ignore them anyway) and | |
2719 // then we'll do the "starts humongous" region. | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2720 for (uint ch_index = index + 1; ch_index < regions; ++ch_index) { |
355 | 2721 HeapRegion* chr = region_at(ch_index); |
2722 | |
2723 // if the region has already been claimed or it's not | |
2724 // "continues humongous" we're done | |
2725 if (chr->claim_value() == claim_value || | |
2726 !chr->continuesHumongous()) { | |
2727 break; | |
2728 } | |
2729 | |
10405 | 2730 // No one should have claimed it directly. We can given |
355 | 2731 // that we claimed its "starts humongous" region. |
2732 assert(chr->claim_value() != claim_value, "sanity"); | |
2733 assert(chr->humongous_start_region() == r, "sanity"); | |
2734 | |
2735 if (chr->claimHeapRegion(claim_value)) { | |
10405 | 2736 // we should always be able to claim it; no one else should |
355 | 2737 // be trying to claim this region |
2738 | |
2739 bool res2 = cl->doHeapRegion(chr); | |
2740 assert(!res2, "Should not abort"); | |
2741 | |
2742 // Right now, this holds (i.e., no closure that actually | |
2743 // does something with "continues humongous" regions | |
2744 // clears them). We might have to weaken it in the future, | |
2745 // but let's leave these two asserts here for extra safety. | |
2746 assert(chr->continuesHumongous(), "should still be the case"); | |
2747 assert(chr->humongous_start_region() == r, "sanity"); | |
2748 } else { | |
2749 guarantee(false, "we should not reach here"); | |
2750 } | |
2751 } | |
2752 } | |
2753 | |
2754 assert(!r->continuesHumongous(), "sanity"); | |
2755 bool res = cl->doHeapRegion(r); | |
2756 assert(!res, "Should not abort"); | |
2757 } | |
2758 } | |
2759 } | |
2760 | |
390 | 2761 class ResetClaimValuesClosure: public HeapRegionClosure { |
2762 public: | |
2763 bool doHeapRegion(HeapRegion* r) { | |
2764 r->set_claim_value(HeapRegion::InitialClaimValue); | |
2765 return false; | |
2766 } | |
2767 }; | |
2768 | |
4783
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
2769 void G1CollectedHeap::reset_heap_region_claim_values() { |
390 | 2770 ResetClaimValuesClosure blk; |
2771 heap_region_iterate(&blk); | |
2772 } | |
2773 | |
4783
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
2774 void G1CollectedHeap::reset_cset_heap_region_claim_values() { |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
2775 ResetClaimValuesClosure blk; |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
2776 collection_set_iterate(&blk); |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
2777 } |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
2778 |
355 | 2779 #ifdef ASSERT |
2780 // This checks whether all regions in the heap have the correct claim | |
2781 // value. I also piggy-backed on this a check to ensure that the | |
2782 // humongous_start_region() information on "continues humongous" | |
2783 // regions is correct. | |
2784 | |
2785 class CheckClaimValuesClosure : public HeapRegionClosure { | |
2786 private: | |
2787 jint _claim_value; | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2788 uint _failures; |
355 | 2789 HeapRegion* _sh_region; |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2790 |
355 | 2791 public: |
2792 CheckClaimValuesClosure(jint claim_value) : | |
2793 _claim_value(claim_value), _failures(0), _sh_region(NULL) { } | |
2794 bool doHeapRegion(HeapRegion* r) { | |
2795 if (r->claim_value() != _claim_value) { | |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2796 gclog_or_tty->print_cr("Region " HR_FORMAT ", " |
355 | 2797 "claim value = %d, should be %d", |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2798 HR_FORMAT_PARAMS(r), |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2799 r->claim_value(), _claim_value); |
355 | 2800 ++_failures; |
2801 } | |
2802 if (!r->isHumongous()) { | |
2803 _sh_region = NULL; | |
2804 } else if (r->startsHumongous()) { | |
2805 _sh_region = r; | |
2806 } else if (r->continuesHumongous()) { | |
2807 if (r->humongous_start_region() != _sh_region) { | |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2808 gclog_or_tty->print_cr("Region " HR_FORMAT ", " |
355 | 2809 "HS = "PTR_FORMAT", should be "PTR_FORMAT, |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2810 HR_FORMAT_PARAMS(r), |
355 | 2811 r->humongous_start_region(), |
2812 _sh_region); | |
2813 ++_failures; | |
342 | 2814 } |
2815 } | |
355 | 2816 return false; |
2817 } | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2818 uint failures() { return _failures; } |
355 | 2819 }; |
2820 | |
2821 bool G1CollectedHeap::check_heap_region_claim_values(jint claim_value) { | |
2822 CheckClaimValuesClosure cl(claim_value); | |
2823 heap_region_iterate(&cl); | |
2824 return cl.failures() == 0; | |
2825 } | |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2826 |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2827 class CheckClaimValuesInCSetHRClosure: public HeapRegionClosure { |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2828 private: |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2829 jint _claim_value; |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2830 uint _failures; |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2831 |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2832 public: |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2833 CheckClaimValuesInCSetHRClosure(jint claim_value) : |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2834 _claim_value(claim_value), _failures(0) { } |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2835 |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2836 uint failures() { return _failures; } |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2837 |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2838 bool doHeapRegion(HeapRegion* hr) { |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2839 assert(hr->in_collection_set(), "how?"); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2840 assert(!hr->isHumongous(), "H-region in CSet"); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2841 if (hr->claim_value() != _claim_value) { |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2842 gclog_or_tty->print_cr("CSet Region " HR_FORMAT ", " |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2843 "claim value = %d, should be %d", |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2844 HR_FORMAT_PARAMS(hr), |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2845 hr->claim_value(), _claim_value); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2846 _failures += 1; |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2847 } |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2848 return false; |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2849 } |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2850 }; |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2851 |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2852 bool G1CollectedHeap::check_cset_heap_region_claim_values(jint claim_value) { |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2853 CheckClaimValuesInCSetHRClosure cl(claim_value); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2854 collection_set_iterate(&cl); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2855 return cl.failures() == 0; |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2856 } |
355 | 2857 #endif // ASSERT |
342 | 2858 |
4709
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2859 // Clear the cached CSet starting regions and (more importantly) |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2860 // the time stamps. Called when we reset the GC time stamp. |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2861 void G1CollectedHeap::clear_cset_start_regions() { |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2862 assert(_worker_cset_start_region != NULL, "sanity"); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2863 assert(_worker_cset_start_region_time_stamp != NULL, "sanity"); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2864 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2865 int n_queues = MAX2((int)ParallelGCThreads, 1); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2866 for (int i = 0; i < n_queues; i++) { |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2867 _worker_cset_start_region[i] = NULL; |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2868 _worker_cset_start_region_time_stamp[i] = 0; |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2869 } |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2870 } |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2871 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2872 // Given the id of a worker, obtain or calculate a suitable |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2873 // starting region for iterating over the current collection set. |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2874 HeapRegion* G1CollectedHeap::start_cset_region_for_worker(int worker_i) { |
4709
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2875 assert(get_gc_time_stamp() > 0, "should have been updated by now"); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2876 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2877 HeapRegion* result = NULL; |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2878 unsigned gc_time_stamp = get_gc_time_stamp(); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2879 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2880 if (_worker_cset_start_region_time_stamp[worker_i] == gc_time_stamp) { |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2881 // Cached starting region for current worker was set |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2882 // during the current pause - so it's valid. |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2883 // Note: the cached starting heap region may be NULL |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2884 // (when the collection set is empty). |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2885 result = _worker_cset_start_region[worker_i]; |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2886 assert(result == NULL || result->in_collection_set(), "sanity"); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2887 return result; |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2888 } |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2889 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2890 // The cached entry was not valid so let's calculate |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2891 // a suitable starting heap region for this worker. |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2892 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2893 // We want the parallel threads to start their collection |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2894 // set iteration at different collection set regions to |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2895 // avoid contention. |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2896 // If we have: |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2897 // n collection set regions |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2898 // p threads |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2899 // Then thread t will start at region floor ((t * n) / p) |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2900 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2901 result = g1_policy()->collection_set(); |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2902 if (G1CollectedHeap::use_parallel_gc_threads()) { |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2903 uint cs_size = g1_policy()->cset_region_length(); |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
2904 uint active_workers = workers()->active_workers(); |
4709
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2905 assert(UseDynamicNumberOfGCThreads || |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2906 active_workers == workers()->total_workers(), |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2907 "Unless dynamic should use total workers"); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2908 |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2909 uint end_ind = (cs_size * worker_i) / active_workers; |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2910 uint start_ind = 0; |
4709
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2911 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2912 if (worker_i > 0 && |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2913 _worker_cset_start_region_time_stamp[worker_i - 1] == gc_time_stamp) { |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2914 // Previous workers starting region is valid |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2915 // so let's iterate from there |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2916 start_ind = (cs_size * (worker_i - 1)) / active_workers; |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2917 result = _worker_cset_start_region[worker_i - 1]; |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2918 } |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2919 |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
2920 for (uint i = start_ind; i < end_ind; i++) { |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2921 result = result->next_in_collection_set(); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2922 } |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2923 } |
4709
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2924 |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2925 // Note: the calculated starting heap region may be NULL |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2926 // (when the collection set is empty). |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2927 assert(result == NULL || result->in_collection_set(), "sanity"); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2928 assert(_worker_cset_start_region_time_stamp[worker_i] != gc_time_stamp, |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2929 "should be updated only once per pause"); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2930 _worker_cset_start_region[worker_i] = result; |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2931 OrderAccess::storestore(); |
fd2b426c30db
7119908: G1: Cache CSet start region for each worker for subsequent reuse
johnc
parents:
4708
diff
changeset
|
2932 _worker_cset_start_region_time_stamp[worker_i] = gc_time_stamp; |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2933 return result; |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2934 } |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
2935 |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2936 HeapRegion* G1CollectedHeap::start_region_for_worker(uint worker_i, |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2937 uint no_of_par_workers) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2938 uint worker_num = |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2939 G1CollectedHeap::use_parallel_gc_threads() ? no_of_par_workers : 1U; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2940 assert(UseDynamicNumberOfGCThreads || |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2941 no_of_par_workers == workers()->total_workers(), |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2942 "Non dynamic should use fixed number of workers"); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2943 const uint start_index = n_regions() * worker_i / worker_num; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2944 return region_at(start_index); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2945 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
2946 |
342 | 2947 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) { |
2948 HeapRegion* r = g1_policy()->collection_set(); | |
2949 while (r != NULL) { | |
2950 HeapRegion* next = r->next_in_collection_set(); | |
2951 if (cl->doHeapRegion(r)) { | |
2952 cl->incomplete(); | |
2953 return; | |
2954 } | |
2955 r = next; | |
2956 } | |
2957 } | |
2958 | |
2959 void G1CollectedHeap::collection_set_iterate_from(HeapRegion* r, | |
2960 HeapRegionClosure *cl) { | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2961 if (r == NULL) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2962 // 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
|
2963 return; |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2964 } |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
2965 |
342 | 2966 assert(r->in_collection_set(), |
2967 "Start region must be a member of the collection set."); | |
2968 HeapRegion* cur = r; | |
2969 while (cur != NULL) { | |
2970 HeapRegion* next = cur->next_in_collection_set(); | |
2971 if (cl->doHeapRegion(cur) && false) { | |
2972 cl->incomplete(); | |
2973 return; | |
2974 } | |
2975 cur = next; | |
2976 } | |
2977 cur = g1_policy()->collection_set(); | |
2978 while (cur != r) { | |
2979 HeapRegion* next = cur->next_in_collection_set(); | |
2980 if (cl->doHeapRegion(cur) && false) { | |
2981 cl->incomplete(); | |
2982 return; | |
2983 } | |
2984 cur = next; | |
2985 } | |
2986 } | |
2987 | |
2988 CompactibleSpace* G1CollectedHeap::first_compactible_space() { | |
3766 | 2989 return n_regions() > 0 ? region_at(0) : NULL; |
342 | 2990 } |
2991 | |
2992 | |
2993 Space* G1CollectedHeap::space_containing(const void* addr) const { | |
2994 Space* res = heap_region_containing(addr); | |
2995 return res; | |
2996 } | |
2997 | |
2998 HeapWord* G1CollectedHeap::block_start(const void* addr) const { | |
2999 Space* sp = space_containing(addr); | |
3000 if (sp != NULL) { | |
3001 return sp->block_start(addr); | |
3002 } | |
3003 return NULL; | |
3004 } | |
3005 | |
3006 size_t G1CollectedHeap::block_size(const HeapWord* addr) const { | |
3007 Space* sp = space_containing(addr); | |
3008 assert(sp != NULL, "block_size of address outside of heap"); | |
3009 return sp->block_size(addr); | |
3010 } | |
3011 | |
3012 bool G1CollectedHeap::block_is_obj(const HeapWord* addr) const { | |
3013 Space* sp = space_containing(addr); | |
3014 return sp->block_is_obj(addr); | |
3015 } | |
3016 | |
3017 bool G1CollectedHeap::supports_tlab_allocation() const { | |
3018 return true; | |
3019 } | |
3020 | |
3021 size_t G1CollectedHeap::tlab_capacity(Thread* ignored) const { | |
3022 return HeapRegion::GrainBytes; | |
3023 } | |
3024 | |
3025 size_t G1CollectedHeap::unsafe_max_tlab_alloc(Thread* ignored) const { | |
3026 // Return the remaining space in the cur alloc region, but not less than | |
3027 // the min TLAB size. | |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
3028 |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
3029 // Also, this value can be at most the humongous object threshold, |
10405 | 3030 // since we can't allow tlabs to grow big enough to accommodate |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
3031 // humongous objects. |
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
3032 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3033 HeapRegion* hr = _mutator_alloc_region.get(); |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
3034 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
|
3035 if (hr == NULL) { |
1313
664ae0c5e0e5
6755988: G1: assert(new_obj != 0 || ... "should be forwarded")
johnc
parents:
1282
diff
changeset
|
3036 return max_tlab_size; |
342 | 3037 } else { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3038 return MIN2(MAX2(hr->free(), (size_t) MinTLABSize), max_tlab_size); |
342 | 3039 } |
3040 } | |
3041 | |
3042 size_t G1CollectedHeap::max_capacity() const { | |
2188
c33825b68624
6923430: G1: assert(res != 0,"This should have worked.")
johnc
parents:
2173
diff
changeset
|
3043 return _g1_reserved.byte_size(); |
342 | 3044 } |
3045 | |
3046 jlong G1CollectedHeap::millis_since_last_gc() { | |
3047 // assert(false, "NYI"); | |
3048 return 0; | |
3049 } | |
3050 | |
3051 void G1CollectedHeap::prepare_for_verify() { | |
3052 if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) { | |
3053 ensure_parsability(false); | |
3054 } | |
3055 g1_rem_set()->prepare_for_verify(); | |
3056 } | |
3057 | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3058 bool G1CollectedHeap::allocated_since_marking(oop obj, HeapRegion* hr, |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3059 VerifyOption vo) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3060 switch (vo) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3061 case VerifyOption_G1UsePrevMarking: |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3062 return hr->obj_allocated_since_prev_marking(obj); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3063 case VerifyOption_G1UseNextMarking: |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3064 return hr->obj_allocated_since_next_marking(obj); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3065 case VerifyOption_G1UseMarkWord: |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3066 return false; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3067 default: |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3068 ShouldNotReachHere(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3069 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3070 return false; // keep some compilers happy |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3071 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3072 |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3073 HeapWord* G1CollectedHeap::top_at_mark_start(HeapRegion* hr, VerifyOption vo) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3074 switch (vo) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3075 case VerifyOption_G1UsePrevMarking: return hr->prev_top_at_mark_start(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3076 case VerifyOption_G1UseNextMarking: return hr->next_top_at_mark_start(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3077 case VerifyOption_G1UseMarkWord: return NULL; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3078 default: ShouldNotReachHere(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3079 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3080 return NULL; // keep some compilers happy |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3081 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3082 |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3083 bool G1CollectedHeap::is_marked(oop obj, VerifyOption vo) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3084 switch (vo) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3085 case VerifyOption_G1UsePrevMarking: return isMarkedPrev(obj); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3086 case VerifyOption_G1UseNextMarking: return isMarkedNext(obj); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3087 case VerifyOption_G1UseMarkWord: return obj->is_gc_marked(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3088 default: ShouldNotReachHere(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3089 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3090 return false; // keep some compilers happy |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3091 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3092 |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3093 const char* G1CollectedHeap::top_at_mark_start_str(VerifyOption vo) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3094 switch (vo) { |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3095 case VerifyOption_G1UsePrevMarking: return "PTAMS"; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3096 case VerifyOption_G1UseNextMarking: return "NTAMS"; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3097 case VerifyOption_G1UseMarkWord: return "NONE"; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3098 default: ShouldNotReachHere(); |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3099 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3100 return NULL; // keep some compilers happy |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3101 } |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3102 |
12080 | 3103 // TODO: VerifyRootsClosure extends OopsInGenClosure so that we can |
3104 // pass it as the perm_blk to SharedHeap::process_strong_roots. | |
3105 // When process_strong_roots stop calling perm_blk->younger_refs_iterate | |
3106 // we can change this closure to extend the simpler OopClosure. | |
3107 class VerifyRootsClosure: public OopsInGenClosure { | |
3108 private: | |
3109 G1CollectedHeap* _g1h; | |
3110 VerifyOption _vo; | |
3111 bool _failures; | |
3112 public: | |
3113 // _vo == UsePrevMarking -> use "prev" marking information, | |
3114 // _vo == UseNextMarking -> use "next" marking information, | |
3115 // _vo == UseMarkWord -> use mark word from object header. | |
3116 VerifyRootsClosure(VerifyOption vo) : | |
3117 _g1h(G1CollectedHeap::heap()), | |
3118 _vo(vo), | |
3119 _failures(false) { } | |
3120 | |
3121 bool failures() { return _failures; } | |
3122 | |
3123 template <class T> void do_oop_nv(T* p) { | |
3124 T heap_oop = oopDesc::load_heap_oop(p); | |
3125 if (!oopDesc::is_null(heap_oop)) { | |
3126 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); | |
3127 if (_g1h->is_obj_dead_cond(obj, _vo)) { | |
3128 gclog_or_tty->print_cr("Root location "PTR_FORMAT" " | |
3129 "points to dead obj "PTR_FORMAT, p, (void*) obj); | |
3130 if (_vo == VerifyOption_G1UseMarkWord) { | |
3131 gclog_or_tty->print_cr(" Mark word: "PTR_FORMAT, (void*)(obj->mark())); | |
3132 } | |
3133 obj->print_on(gclog_or_tty); | |
3134 _failures = true; | |
3135 } | |
3136 } | |
3137 } | |
3138 | |
3139 void do_oop(oop* p) { do_oop_nv(p); } | |
3140 void do_oop(narrowOop* p) { do_oop_nv(p); } | |
3141 }; | |
3142 | |
3143 class G1VerifyCodeRootOopClosure: public OopsInGenClosure { | |
3144 G1CollectedHeap* _g1h; | |
3145 OopClosure* _root_cl; | |
3146 nmethod* _nm; | |
3147 VerifyOption _vo; | |
3148 bool _failures; | |
3149 | |
3150 template <class T> void do_oop_work(T* p) { | |
3151 // First verify that this root is live | |
3152 _root_cl->do_oop(p); | |
3153 | |
3154 if (!G1VerifyHeapRegionCodeRoots) { | |
3155 // We're not verifying the code roots attached to heap region. | |
3156 return; | |
3157 } | |
3158 | |
3159 // Don't check the code roots during marking verification in a full GC | |
3160 if (_vo == VerifyOption_G1UseMarkWord) { | |
3161 return; | |
3162 } | |
3163 | |
3164 // Now verify that the current nmethod (which contains p) is | |
3165 // in the code root list of the heap region containing the | |
3166 // object referenced by p. | |
3167 | |
3168 T heap_oop = oopDesc::load_heap_oop(p); | |
3169 if (!oopDesc::is_null(heap_oop)) { | |
3170 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); | |
3171 | |
3172 // Now fetch the region containing the object | |
3173 HeapRegion* hr = _g1h->heap_region_containing(obj); | |
3174 HeapRegionRemSet* hrrs = hr->rem_set(); | |
3175 // Verify that the strong code root list for this region | |
3176 // contains the nmethod | |
3177 if (!hrrs->strong_code_roots_list_contains(_nm)) { | |
3178 gclog_or_tty->print_cr("Code root location "PTR_FORMAT" " | |
3179 "from nmethod "PTR_FORMAT" not in strong " | |
3180 "code roots for region ["PTR_FORMAT","PTR_FORMAT")", | |
3181 p, _nm, hr->bottom(), hr->end()); | |
3182 _failures = true; | |
3183 } | |
3184 } | |
3185 } | |
3186 | |
3187 public: | |
3188 G1VerifyCodeRootOopClosure(G1CollectedHeap* g1h, OopClosure* root_cl, VerifyOption vo): | |
3189 _g1h(g1h), _root_cl(root_cl), _vo(vo), _nm(NULL), _failures(false) {} | |
3190 | |
3191 void do_oop(oop* p) { do_oop_work(p); } | |
3192 void do_oop(narrowOop* p) { do_oop_work(p); } | |
3193 | |
3194 void set_nmethod(nmethod* nm) { _nm = nm; } | |
3195 bool failures() { return _failures; } | |
3196 }; | |
3197 | |
3198 class G1VerifyCodeRootBlobClosure: public CodeBlobClosure { | |
3199 G1VerifyCodeRootOopClosure* _oop_cl; | |
3200 | |
3201 public: | |
3202 G1VerifyCodeRootBlobClosure(G1VerifyCodeRootOopClosure* oop_cl): | |
3203 _oop_cl(oop_cl) {} | |
3204 | |
3205 void do_code_blob(CodeBlob* cb) { | |
3206 nmethod* nm = cb->as_nmethod_or_null(); | |
3207 if (nm != NULL) { | |
3208 _oop_cl->set_nmethod(nm); | |
3209 nm->oops_do(_oop_cl); | |
3210 } | |
3211 } | |
3212 }; | |
3213 | |
3214 class YoungRefCounterClosure : public OopClosure { | |
3215 G1CollectedHeap* _g1h; | |
3216 int _count; | |
3217 public: | |
3218 YoungRefCounterClosure(G1CollectedHeap* g1h) : _g1h(g1h), _count(0) {} | |
3219 void do_oop(oop* p) { if (_g1h->is_in_young(*p)) { _count++; } } | |
3220 void do_oop(narrowOop* p) { ShouldNotReachHere(); } | |
3221 | |
3222 int count() { return _count; } | |
3223 void reset_count() { _count = 0; }; | |
3224 }; | |
3225 | |
3226 class VerifyKlassClosure: public KlassClosure { | |
3227 YoungRefCounterClosure _young_ref_counter_closure; | |
3228 OopClosure *_oop_closure; | |
3229 public: | |
3230 VerifyKlassClosure(G1CollectedHeap* g1h, OopClosure* cl) : _young_ref_counter_closure(g1h), _oop_closure(cl) {} | |
3231 void do_klass(Klass* k) { | |
3232 k->oops_do(_oop_closure); | |
3233 | |
3234 _young_ref_counter_closure.reset_count(); | |
3235 k->oops_do(&_young_ref_counter_closure); | |
3236 if (_young_ref_counter_closure.count() > 0) { | |
3237 guarantee(k->has_modified_oops(), err_msg("Klass %p, has young refs but is not dirty.", k)); | |
3238 } | |
3239 } | |
3240 }; | |
3241 | |
342 | 3242 class VerifyLivenessOopClosure: public OopClosure { |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3243 G1CollectedHeap* _g1h; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3244 VerifyOption _vo; |
342 | 3245 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3246 VerifyLivenessOopClosure(G1CollectedHeap* g1h, VerifyOption vo): |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3247 _g1h(g1h), _vo(vo) |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3248 { } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3249 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
|
3250 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
|
3251 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3252 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
|
3253 oop obj = oopDesc::load_decode_heap_oop(p); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3254 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
|
3255 "Dead object referenced by a not dead object"); |
342 | 3256 } |
3257 }; | |
3258 | |
3259 class VerifyObjsInRegionClosure: public ObjectClosure { | |
811 | 3260 private: |
342 | 3261 G1CollectedHeap* _g1h; |
3262 size_t _live_bytes; | |
3263 HeapRegion *_hr; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3264 VerifyOption _vo; |
342 | 3265 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3266 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3267 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3268 // _vo == UseMarkWord -> use mark word from object header. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3269 VerifyObjsInRegionClosure(HeapRegion *hr, VerifyOption vo) |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3270 : _live_bytes(0), _hr(hr), _vo(vo) { |
342 | 3271 _g1h = G1CollectedHeap::heap(); |
3272 } | |
3273 void do_object(oop o) { | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3274 VerifyLivenessOopClosure isLive(_g1h, _vo); |
342 | 3275 assert(o != NULL, "Huh?"); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3276 if (!_g1h->is_obj_dead_cond(o, _vo)) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3277 // If the object is alive according to the mark word, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3278 // then verify that the marking information agrees. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3279 // Note we can't verify the contra-positive of the |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3280 // above: if the object is dead (according to the mark |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3281 // 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
|
3282 // but has since became dead, or may have been allocated |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3283 // since the last marking. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3284 if (_vo == VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3285 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
|
3286 } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3287 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3288 o->oop_iterate_no_header(&isLive); |
1389
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
3289 if (!_hr->obj_allocated_since_prev_marking(o)) { |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
3290 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
|
3291 _live_bytes += (obj_size * HeapWordSize); |
5dbd9300cf9c
6943926: G1: Integer overflow during heap region verification
johnc
parents:
1388
diff
changeset
|
3292 } |
342 | 3293 } |
3294 } | |
3295 size_t live_bytes() { return _live_bytes; } | |
3296 }; | |
3297 | |
3298 class PrintObjsInRegionClosure : public ObjectClosure { | |
3299 HeapRegion *_hr; | |
3300 G1CollectedHeap *_g1; | |
3301 public: | |
3302 PrintObjsInRegionClosure(HeapRegion *hr) : _hr(hr) { | |
3303 _g1 = G1CollectedHeap::heap(); | |
3304 }; | |
3305 | |
3306 void do_object(oop o) { | |
3307 if (o != NULL) { | |
3308 HeapWord *start = (HeapWord *) o; | |
3309 size_t word_sz = o->size(); | |
3310 gclog_or_tty->print("\nPrinting obj "PTR_FORMAT" of size " SIZE_FORMAT | |
3311 " isMarkedPrev %d isMarkedNext %d isAllocSince %d\n", | |
3312 (void*) o, word_sz, | |
3313 _g1->isMarkedPrev(o), | |
3314 _g1->isMarkedNext(o), | |
3315 _hr->obj_allocated_since_prev_marking(o)); | |
3316 HeapWord *end = start + word_sz; | |
3317 HeapWord *cur; | |
3318 int *val; | |
3319 for (cur = start; cur < end; cur++) { | |
3320 val = (int *) cur; | |
3321 gclog_or_tty->print("\t "PTR_FORMAT":"PTR_FORMAT"\n", val, *val); | |
3322 } | |
3323 } | |
3324 } | |
3325 }; | |
3326 | |
3327 class VerifyRegionClosure: public HeapRegionClosure { | |
811 | 3328 private: |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3329 bool _par; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3330 VerifyOption _vo; |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
3331 bool _failures; |
811 | 3332 public: |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3333 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3334 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3335 // _vo == UseMarkWord -> use mark word from object header. |
6008 | 3336 VerifyRegionClosure(bool par, VerifyOption vo) |
3337 : _par(par), | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3338 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3339 _failures(false) {} |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3340 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3341 bool failures() { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3342 return _failures; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3343 } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3344 |
342 | 3345 bool doHeapRegion(HeapRegion* r) { |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
3346 if (!r->continuesHumongous()) { |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3347 bool failures = false; |
6008 | 3348 r->verify(_vo, &failures); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3349 if (failures) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3350 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3351 } else { |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3352 VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3353 r->object_iterate(¬_dead_yet_cl); |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3354 if (_vo != VerifyOption_G1UseNextMarking) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3355 if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3356 gclog_or_tty->print_cr("["PTR_FORMAT","PTR_FORMAT"] " |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3357 "max_live_bytes "SIZE_FORMAT" " |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3358 "< calculated "SIZE_FORMAT, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3359 r->bottom(), r->end(), |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3360 r->max_live_bytes(), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3361 not_dead_yet_cl.live_bytes()); |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3362 _failures = true; |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3363 } |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3364 } else { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3365 // When vo == UseNextMarking we cannot currently do a sanity |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3366 // check on the live bytes as the calculation has not been |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
3367 // finalized yet. |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3368 } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3369 } |
342 | 3370 } |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3371 return false; // stop the region iteration if we hit a failure |
342 | 3372 } |
3373 }; | |
3374 | |
12080 | 3375 // This is the task used for parallel verification of the heap regions |
390 | 3376 |
3377 class G1ParVerifyTask: public AbstractGangTask { | |
3378 private: | |
3379 G1CollectedHeap* _g1h; | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3380 VerifyOption _vo; |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3381 bool _failures; |
390 | 3382 |
3383 public: | |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3384 // _vo == UsePrevMarking -> use "prev" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3385 // _vo == UseNextMarking -> use "next" marking information, |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3386 // _vo == UseMarkWord -> use mark word from object header. |
6008 | 3387 G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) : |
390 | 3388 AbstractGangTask("Parallel verify task"), |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3389 _g1h(g1h), |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3390 _vo(vo), |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3391 _failures(false) { } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3392 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3393 bool failures() { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3394 return _failures; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3395 } |
390 | 3396 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
3397 void work(uint worker_id) { |
637
25e146966e7c
6817419: G1: Enable extensive verification for humongous regions
iveresov
parents:
636
diff
changeset
|
3398 HandleMark hm; |
6008 | 3399 VerifyRegionClosure blk(true, _vo); |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
3400 _g1h->heap_region_par_iterate_chunked(&blk, worker_id, |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3401 _g1h->workers()->active_workers(), |
390 | 3402 HeapRegion::ParVerifyClaimValue); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3403 if (blk.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3404 _failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3405 } |
390 | 3406 } |
3407 }; | |
3408 | |
12080 | 3409 void G1CollectedHeap::verify(bool silent, VerifyOption vo) { |
8855
24ef5fb05e0f
8010463: G1: Crashes with -UseTLAB and heap verification
johnc
parents:
8853
diff
changeset
|
3410 if (SafepointSynchronize::is_at_safepoint()) { |
12080 | 3411 assert(Thread::current()->is_VM_thread(), |
3412 "Expected to be executed serially by the VM thread at this point"); | |
3413 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3414 if (!silent) { gclog_or_tty->print("Roots "); } |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3415 VerifyRootsClosure rootsCl(vo); |
12080 | 3416 G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo); |
3417 G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3418 VerifyKlassClosure klassCl(this, &rootsCl); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3419 |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
3420 // 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
|
3421 // system dictionary, the string table and the code cache. |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
3422 const int so = SO_AllClasses | SO_Strings | SO_CodeCache; |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3423 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3424 // Need cleared claim bits for the strong roots processing |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3425 ClassLoaderDataGraph::clear_claimed_marks(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3426 |
3293
1f4413413144
7039089: G1: changeset for 7037276 broke heap verification, and related cleanups
ysr
parents:
3289
diff
changeset
|
3427 process_strong_roots(true, // activate StrongRootsScope |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3428 false, // we set "is scavenging" to false, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3429 // so we don't reset the dirty cards. |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
3430 ScanningOption(so), // roots scanning options |
342 | 3431 &rootsCl, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
3432 &blobsCl, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3433 &klassCl |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3434 ); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
3435 |
12080 | 3436 bool failures = rootsCl.failures() || codeRootsCl.failures(); |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3437 |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3438 if (vo != VerifyOption_G1UseMarkWord) { |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3439 // 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
|
3440 // 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
|
3441 // verifying the region sets will fail. So we only verify |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3442 // the region sets when not in a full GC. |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3443 if (!silent) { gclog_or_tty->print("HeapRegionSets "); } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3444 verify_region_sets(); |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3445 } |
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3446 |
2152 | 3447 if (!silent) { gclog_or_tty->print("HeapRegions "); } |
390 | 3448 if (GCParallelVerificationEnabled && ParallelGCThreads > 1) { |
3449 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
3450 "sanity check"); | |
3451 | |
6008 | 3452 G1ParVerifyTask task(this, vo); |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3453 assert(UseDynamicNumberOfGCThreads || |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3454 workers()->active_workers() == workers()->total_workers(), |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3455 "If not dynamic should be using all the workers"); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3456 int n_workers = workers()->active_workers(); |
390 | 3457 set_par_threads(n_workers); |
3458 workers()->run_task(&task); | |
3459 set_par_threads(0); | |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3460 if (task.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3461 failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3462 } |
390 | 3463 |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3464 // Checks that the expected amount of parallel work was done. |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3465 // The implication is that n_workers is > 0. |
390 | 3466 assert(check_heap_region_claim_values(HeapRegion::ParVerifyClaimValue), |
3467 "sanity check"); | |
3468 | |
3469 reset_heap_region_claim_values(); | |
3470 | |
3471 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
3472 "sanity check"); | |
3473 } else { | |
6008 | 3474 VerifyRegionClosure blk(false, vo); |
3766 | 3475 heap_region_iterate(&blk); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3476 if (blk.failures()) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3477 failures = true; |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3478 } |
390 | 3479 } |
2152 | 3480 if (!silent) gclog_or_tty->print("RemSet "); |
342 | 3481 rem_set()->verify(); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3482 |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3483 if (failures) { |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3484 gclog_or_tty->print_cr("Heap:"); |
4073
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3485 // It helps to have the per-region information in the output to |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3486 // help us track down what went wrong. This is why we call |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3487 // print_extended_on() instead of print_on(). |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3488 print_extended_on(gclog_or_tty); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3489 gclog_or_tty->print_cr(""); |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1545
diff
changeset
|
3490 #ifndef PRODUCT |
1044 | 3491 if (VerifyDuringGC && G1VerifyDuringGCPrintReachable) { |
1388 | 3492 concurrent_mark()->print_reachable("at-verification-failure", |
3772
6747fd0512e0
7004681: G1: Extend marking verification to Full GCs
johnc
parents:
3766
diff
changeset
|
3493 vo, false /* all */); |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3494 } |
1547
fb1a39993f69
6951319: enable solaris builds using Sun Studio 12 update 1
jcoomes
parents:
1545
diff
changeset
|
3495 #endif |
1020
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3496 gclog_or_tty->flush(); |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3497 } |
ff2402f6a50b
6882730: G1: parallel heap verification messes up region dump
tonyp
parents:
1019
diff
changeset
|
3498 guarantee(!failures, "there should not have been any failures"); |
342 | 3499 } else { |
8855
24ef5fb05e0f
8010463: G1: Crashes with -UseTLAB and heap verification
johnc
parents:
8853
diff
changeset
|
3500 if (!silent) |
24ef5fb05e0f
8010463: G1: Crashes with -UseTLAB and heap verification
johnc
parents:
8853
diff
changeset
|
3501 gclog_or_tty->print("(SKIPPING roots, heapRegionSets, heapRegions, remset) "); |
342 | 3502 } |
3503 } | |
3504 | |
12080 | 3505 void G1CollectedHeap::verify(bool silent) { |
3506 verify(silent, VerifyOption_G1UsePrevMarking); | |
3507 } | |
3508 | |
3509 double G1CollectedHeap::verify(bool guard, const char* msg) { | |
3510 double verify_time_ms = 0.0; | |
3511 | |
3512 if (guard && total_collections() >= VerifyGCStartAt) { | |
3513 double verify_start = os::elapsedTime(); | |
3514 HandleMark hm; // Discard invalid handles created during verification | |
3515 prepare_for_verify(); | |
3516 Universe::verify(VerifyOption_G1UsePrevMarking, msg); | |
3517 verify_time_ms = (os::elapsedTime() - verify_start) * 1000; | |
3518 } | |
3519 | |
3520 return verify_time_ms; | |
3521 } | |
3522 | |
3523 void G1CollectedHeap::verify_before_gc() { | |
3524 double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:"); | |
3525 g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms); | |
3526 } | |
3527 | |
3528 void G1CollectedHeap::verify_after_gc() { | |
3529 double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:"); | |
3530 g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms); | |
3531 } | |
3532 | |
342 | 3533 class PrintRegionClosure: public HeapRegionClosure { |
3534 outputStream* _st; | |
3535 public: | |
3536 PrintRegionClosure(outputStream* st) : _st(st) {} | |
3537 bool doHeapRegion(HeapRegion* r) { | |
3538 r->print_on(_st); | |
3539 return false; | |
3540 } | |
3541 }; | |
3542 | |
3543 void G1CollectedHeap::print_on(outputStream* st) const { | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3544 st->print(" %-20s", "garbage-first heap"); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3545 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
|
3546 capacity()/K, used_unlocked()/K); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3547 st->print(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3548 _g1_storage.low_boundary(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3549 _g1_storage.high(), |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3550 _g1_storage.high_boundary()); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3551 st->cr(); |
3986
65a8ff39a6da
7095194: G1: HeapRegion::GrainBytes, GrainWords, and CardsPerRegion should be size_t
johnc
parents:
3983
diff
changeset
|
3552 st->print(" region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K); |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3553 uint young_regions = _young_list->length(); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3554 st->print("%u young (" SIZE_FORMAT "K), ", young_regions, |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3555 (size_t) young_regions * HeapRegion::GrainBytes / K); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3556 uint survivor_regions = g1_policy()->recorded_survivor_regions(); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3557 st->print("%u survivors (" SIZE_FORMAT "K)", survivor_regions, |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3558 (size_t) survivor_regions * HeapRegion::GrainBytes / K); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3559 st->cr(); |
6863
04155d9c8c76
8000358: G1: metaspace information not printed in PrintHeapAtGC output nor in hs_err file
johnc
parents:
6819
diff
changeset
|
3560 MetaspaceAux::print_on(st); |
4073
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3561 } |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3562 |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3563 void G1CollectedHeap::print_extended_on(outputStream* st) const { |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3564 print_on(st); |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3565 |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3566 // Print the per-region information. |
53074c2c4600
7099849: G1: include heap region information in hs_err files
tonyp
parents:
4072
diff
changeset
|
3567 st->cr(); |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3568 st->print_cr("Heap Regions: (Y=young(eden), SU=young(survivor), " |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3569 "HS=humongous(starts), HC=humongous(continues), " |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3570 "CS=collection set, F=free, TS=gc time stamp, " |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3571 "PTAMS=previous top-at-mark-start, " |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3572 "NTAMS=next top-at-mark-start)"); |
342 | 3573 PrintRegionClosure blk(st); |
3766 | 3574 heap_region_iterate(&blk); |
342 | 3575 } |
3576 | |
9076
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3577 void G1CollectedHeap::print_on_error(outputStream* st) const { |
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3578 this->CollectedHeap::print_on_error(st); |
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3579 |
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3580 if (_cm != NULL) { |
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3581 st->cr(); |
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3582 _cm->print_on_error(st); |
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3583 } |
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3584 } |
7b835924c31c
8011872: Include Bit Map addresses in the hs_err files
stefank
parents:
8855
diff
changeset
|
3585 |
342 | 3586 void G1CollectedHeap::print_gc_threads_on(outputStream* st) const { |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
3587 if (G1CollectedHeap::use_parallel_gc_threads()) { |
1019 | 3588 workers()->print_worker_threads_on(st); |
3589 } | |
3590 _cmThread->print_on(st); | |
342 | 3591 st->cr(); |
1019 | 3592 _cm->print_worker_threads_on(st); |
3593 _cg1r->print_worker_threads_on(st); | |
342 | 3594 } |
3595 | |
3596 void G1CollectedHeap::gc_threads_do(ThreadClosure* tc) const { | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
3597 if (G1CollectedHeap::use_parallel_gc_threads()) { |
342 | 3598 workers()->threads_do(tc); |
3599 } | |
3600 tc->do_thread(_cmThread); | |
794 | 3601 _cg1r->threads_do(tc); |
342 | 3602 } |
3603 | |
3604 void G1CollectedHeap::print_tracing_info() const { | |
3605 // We'll overload this to mean "trace GC pause statistics." | |
3606 if (TraceGen0Time || TraceGen1Time) { | |
3607 // The "G1CollectorPolicy" is keeping track of these stats, so delegate | |
3608 // to that. | |
3609 g1_policy()->print_tracing_info(); | |
3610 } | |
751 | 3611 if (G1SummarizeRSetStats) { |
342 | 3612 g1_rem_set()->print_summary_info(); |
3613 } | |
1282 | 3614 if (G1SummarizeConcMark) { |
342 | 3615 concurrent_mark()->print_summary_info(); |
3616 } | |
3617 g1_policy()->print_yg_surv_rate_info(); | |
3618 SpecializationStats::print(); | |
3619 } | |
3620 | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3621 #ifndef PRODUCT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3622 // Helpful for debugging RSet issues. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3623 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3624 class PrintRSetsClosure : public HeapRegionClosure { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3625 private: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3626 const char* _msg; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3627 size_t _occupied_sum; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3628 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3629 public: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3630 bool doHeapRegion(HeapRegion* r) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3631 HeapRegionRemSet* hrrs = r->rem_set(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3632 size_t occupied = hrrs->occupied(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3633 _occupied_sum += occupied; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3634 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3635 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
|
3636 HR_FORMAT_PARAMS(r)); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3637 if (occupied == 0) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3638 gclog_or_tty->print_cr(" RSet is empty"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3639 } else { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3640 hrrs->print(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3641 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3642 gclog_or_tty->print_cr("----------"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3643 return false; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3644 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3645 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3646 PrintRSetsClosure(const char* msg) : _msg(msg), _occupied_sum(0) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3647 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3648 gclog_or_tty->print_cr("========================================"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3649 gclog_or_tty->print_cr(msg); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3650 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3651 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3652 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3653 ~PrintRSetsClosure() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3654 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
|
3655 gclog_or_tty->print_cr("========================================"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3656 gclog_or_tty->cr(); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3657 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3658 }; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3659 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3660 void G1CollectedHeap::print_cset_rsets() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3661 PrintRSetsClosure cl("Printing CSet RSets"); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3662 collection_set_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3663 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3664 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3665 void G1CollectedHeap::print_all_rsets() { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3666 PrintRSetsClosure cl("Printing All RSets");; |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3667 heap_region_iterate(&cl); |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3668 } |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3669 #endif // PRODUCT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3670 |
342 | 3671 G1CollectedHeap* G1CollectedHeap::heap() { |
3672 assert(_sh->kind() == CollectedHeap::G1CollectedHeap, | |
3673 "not a garbage-first heap"); | |
3674 return _g1h; | |
3675 } | |
3676 | |
3677 void G1CollectedHeap::gc_prologue(bool full /* Ignored */) { | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1166
diff
changeset
|
3678 // always_do_update_barrier = false; |
342 | 3679 assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); |
3680 // Fill TLAB's and such | |
3681 ensure_parsability(true); | |
3682 } | |
3683 | |
3684 void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) { | |
10372
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10327
diff
changeset
|
3685 |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10327
diff
changeset
|
3686 if (G1SummarizeRSetStats && |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10327
diff
changeset
|
3687 (G1SummarizeRSetStatsPeriod > 0) && |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10327
diff
changeset
|
3688 // we are at the end of the GC. Total collections has already been increased. |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10327
diff
changeset
|
3689 ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) { |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10327
diff
changeset
|
3690 g1_rem_set()->print_periodic_summary_info(); |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10327
diff
changeset
|
3691 } |
e72f7eecc96d
8013895: G1: G1SummarizeRSetStats output on Linux needs improvemen
tschatzl
parents:
10327
diff
changeset
|
3692 |
342 | 3693 // FIXME: what is this about? |
3694 // I'm ignoring the "fill_newgen()" call if "alloc_event_enabled" | |
3695 // is set. | |
3696 COMPILER2_PRESENT(assert(DerivedPointerTable::is_empty(), | |
3697 "derived pointer present")); | |
1245
6484c4ee11cb
6904516: More object array barrier fixes, following up on 6906727
ysr
parents:
1166
diff
changeset
|
3698 // always_do_update_barrier = true; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3699 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3700 // We have just completed a GC. Update the soft reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3701 // policy with the new heap occupancy |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3702 Universe::update_heap_info_at_gc(); |
342 | 3703 } |
3704 | |
1973 | 3705 HeapWord* G1CollectedHeap::do_collection_pause(size_t word_size, |
3706 unsigned int gc_count_before, | |
12113
f7d3b4387a16
8022872: G1: Use correct GC cause for young GC triggered by humongous allocations
brutisso
parents:
12082
diff
changeset
|
3707 bool* succeeded, |
f7d3b4387a16
8022872: G1: Use correct GC cause for young GC triggered by humongous allocations
brutisso
parents:
12082
diff
changeset
|
3708 GCCause::Cause gc_cause) { |
1973 | 3709 assert_heap_not_locked_and_not_at_safepoint(); |
342 | 3710 g1_policy()->record_stop_world_start(); |
1973 | 3711 VM_G1IncCollectionPause op(gc_count_before, |
3712 word_size, | |
3713 false, /* should_initiate_conc_mark */ | |
3714 g1_policy()->max_pause_time_ms(), | |
12113
f7d3b4387a16
8022872: G1: Use correct GC cause for young GC triggered by humongous allocations
brutisso
parents:
12082
diff
changeset
|
3715 gc_cause); |
1973 | 3716 VMThread::execute(&op); |
3717 | |
3718 HeapWord* result = op.result(); | |
3719 bool ret_succeeded = op.prologue_succeeded() && op.pause_succeeded(); | |
3720 assert(result == NULL || ret_succeeded, | |
3721 "the result should be NULL if the VM did not succeed"); | |
3722 *succeeded = ret_succeeded; | |
3723 | |
3724 assert_heap_not_locked(); | |
3725 return result; | |
342 | 3726 } |
3727 | |
3728 void | |
3729 G1CollectedHeap::doConcurrentMark() { | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3730 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
|
3731 if (!_cmThread->in_progress()) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3732 _cmThread->set_started(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3733 CGC_lock->notify(); |
342 | 3734 } |
3735 } | |
3736 | |
3737 size_t G1CollectedHeap::pending_card_num() { | |
3738 size_t extra_cards = 0; | |
3739 JavaThread *curr = Threads::first(); | |
3740 while (curr != NULL) { | |
3741 DirtyCardQueue& dcq = curr->dirty_card_queue(); | |
3742 extra_cards += dcq.size(); | |
3743 curr = curr->next(); | |
3744 } | |
3745 DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set(); | |
3746 size_t buffer_size = dcqs.buffer_size(); | |
3747 size_t buffer_num = dcqs.completed_buffers_num(); | |
6611 | 3748 |
3749 // PtrQueueSet::buffer_size() and PtrQueue:size() return sizes | |
3750 // in bytes - not the number of 'entries'. We need to convert | |
3751 // into a number of cards. | |
3752 return (buffer_size * buffer_num + extra_cards) / oopSize; | |
342 | 3753 } |
3754 | |
3755 size_t G1CollectedHeap::cards_scanned() { | |
1861 | 3756 return g1_rem_set()->cardsScanned(); |
342 | 3757 } |
3758 | |
3759 void | |
3760 G1CollectedHeap::setup_surviving_young_words() { | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3761 assert(_surviving_young_words == NULL, "pre-condition"); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3762 uint array_length = g1_policy()->young_cset_region_length(); |
6197 | 3763 _surviving_young_words = NEW_C_HEAP_ARRAY(size_t, (size_t) array_length, mtGC); |
342 | 3764 if (_surviving_young_words == NULL) { |
10161
746b070f5022
8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents:
10099
diff
changeset
|
3765 vm_exit_out_of_memory(sizeof(size_t) * array_length, OOM_MALLOC_ERROR, |
342 | 3766 "Not enough space for young surv words summary."); |
3767 } | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3768 memset(_surviving_young_words, 0, (size_t) array_length * sizeof(size_t)); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3769 #ifdef ASSERT |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3770 for (uint i = 0; i < array_length; ++i) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3771 assert( _surviving_young_words[i] == 0, "memset above" ); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3772 } |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
3773 #endif // !ASSERT |
342 | 3774 } |
3775 | |
3776 void | |
3777 G1CollectedHeap::update_surviving_young_words(size_t* surv_young_words) { | |
3778 MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag); | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3779 uint array_length = g1_policy()->young_cset_region_length(); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3780 for (uint i = 0; i < array_length; ++i) { |
342 | 3781 _surviving_young_words[i] += surv_young_words[i]; |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
3782 } |
342 | 3783 } |
3784 | |
3785 void | |
3786 G1CollectedHeap::cleanup_surviving_young_words() { | |
3787 guarantee( _surviving_young_words != NULL, "pre-condition" ); | |
6197 | 3788 FREE_C_HEAP_ARRAY(size_t, _surviving_young_words, mtGC); |
342 | 3789 _surviving_young_words = NULL; |
3790 } | |
3791 | |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3792 #ifdef ASSERT |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3793 class VerifyCSetClosure: public HeapRegionClosure { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3794 public: |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3795 bool doHeapRegion(HeapRegion* hr) { |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3796 // 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
|
3797 // 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
|
3798 // 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
|
3799 // 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
|
3800 // 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
|
3801 // 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
|
3802 // 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
|
3803 // 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
|
3804 // evacuation failure handling. |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3805 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
|
3806 |
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3807 // 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
|
3808 // perform on CSet regions. |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3809 return false; |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3810 } |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3811 }; |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
3812 #endif // ASSERT |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
3813 |
1709 | 3814 #if TASKQUEUE_STATS |
3815 void G1CollectedHeap::print_taskqueue_stats_hdr(outputStream* const st) { | |
3816 st->print_raw_cr("GC Task Stats"); | |
3817 st->print_raw("thr "); TaskQueueStats::print_header(1, st); st->cr(); | |
3818 st->print_raw("--- "); TaskQueueStats::print_header(2, st); st->cr(); | |
3819 } | |
3820 | |
3821 void G1CollectedHeap::print_taskqueue_stats(outputStream* const st) const { | |
3822 print_taskqueue_stats_hdr(st); | |
3823 | |
3824 TaskQueueStats totals; | |
1755
8e5955ddf8e4
6978300: G1: debug builds crash if ParallelGCThreads==0
jcoomes
parents:
1719
diff
changeset
|
3825 const int n = workers() != NULL ? workers()->total_workers() : 1; |
1709 | 3826 for (int i = 0; i < n; ++i) { |
3827 st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr(); | |
3828 totals += task_queue(i)->stats; | |
3829 } | |
3830 st->print_raw("tot "); totals.print(st); st->cr(); | |
3831 | |
3832 DEBUG_ONLY(totals.verify()); | |
3833 } | |
3834 | |
3835 void G1CollectedHeap::reset_taskqueue_stats() { | |
1755
8e5955ddf8e4
6978300: G1: debug builds crash if ParallelGCThreads==0
jcoomes
parents:
1719
diff
changeset
|
3836 const int n = workers() != NULL ? workers()->total_workers() : 1; |
1709 | 3837 for (int i = 0; i < n; ++i) { |
3838 task_queue(i)->stats.reset(); | |
3839 } | |
3840 } | |
3841 #endif // TASKQUEUE_STATS | |
3842 | |
6752
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3843 void G1CollectedHeap::log_gc_header() { |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3844 if (!G1Log::fine()) { |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3845 return; |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3846 } |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3847 |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3848 gclog_or_tty->date_stamp(PrintGCDateStamps); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3849 gclog_or_tty->stamp(PrintGCTimeStamps); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3850 |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3851 GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause()) |
7455
0b54ffe4c2d3
8005672: Clean up some changes to GC logging with GCCause's
jmasa
parents:
7397
diff
changeset
|
3852 .append(g1_policy()->gcs_are_young() ? "(young)" : "(mixed)") |
6752
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3853 .append(g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : ""); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3854 |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3855 gclog_or_tty->print("[%s", (const char*)gc_cause_str); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3856 } |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3857 |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3858 void G1CollectedHeap::log_gc_footer(double pause_time_sec) { |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3859 if (!G1Log::fine()) { |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3860 return; |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3861 } |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3862 |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3863 if (G1Log::finer()) { |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3864 if (evacuation_failed()) { |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3865 gclog_or_tty->print(" (to-space exhausted)"); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3866 } |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3867 gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3868 g1_policy()->phase_times()->note_gc_end(); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3869 g1_policy()->phase_times()->print(pause_time_sec); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3870 g1_policy()->print_detailed_heap_transition(); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3871 } else { |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3872 if (evacuation_failed()) { |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3873 gclog_or_tty->print("--"); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3874 } |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3875 g1_policy()->print_heap_transition(); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3876 gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec); |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3877 } |
7207
0f80645e9c26
8004170: G1: Verbose GC output is not getting flushed to log file using JDK 8
johnc
parents:
6863
diff
changeset
|
3878 gclog_or_tty->flush(); |
6752
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3879 } |
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3880 |
1973 | 3881 bool |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3882 G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) { |
2152 | 3883 assert_at_safepoint(true /* should_be_vm_thread */); |
3884 guarantee(!is_gc_active(), "collection is not reentrant"); | |
3885 | |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3886 if (GC_locker::check_active_before_gc()) { |
1973 | 3887 return false; |
1359
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3888 } |
23b1b27ac76c
6909756: G1: guarantee(G1CollectedHeap::heap()->mark_in_progress(),"Precondition.")
tonyp
parents:
1313
diff
changeset
|
3889 |
10405 | 3890 _gc_timer_stw->register_gc_start(os::elapsed_counter()); |
3891 | |
3892 _gc_tracer_stw->report_gc_start(gc_cause(), _gc_timer_stw->gc_start()); | |
3893 | |
2125
7246a374a9f2
6458402: 3 jvmti tests fail with CMS and +ExplicitGCInvokesConcurrent
kamg
parents:
2039
diff
changeset
|
3894 SvcGCMarker sgcm(SvcGCMarker::MINOR); |
2039
7c5250dbd584
6896624: G1: hotspot:::gc and hotspot:::mem-pool-gc probes are not fired
tonyp
parents:
2038
diff
changeset
|
3895 ResourceMark rm; |
7c5250dbd584
6896624: G1: hotspot:::gc and hotspot:::mem-pool-gc probes are not fired
tonyp
parents:
2038
diff
changeset
|
3896 |
4872
aa3d708d67c4
7141200: log some interesting information in ring buffers for crashes
never
parents:
4787
diff
changeset
|
3897 print_heap_before_gc(); |
10405 | 3898 trace_heap_before_gc(_gc_tracer_stw); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3899 |
4072 | 3900 HRSPhaseSetter x(HRSPhaseEvacuation); |
2152 | 3901 verify_region_sets_optional(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
3902 verify_dirty_young_regions(); |
2152 | 3903 |
4831
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3904 // This call will decide whether this pause is an initial-mark |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3905 // pause. If it is, during_initial_mark_pause() will return true |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3906 // for the duration of this pause. |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3907 g1_policy()->decide_on_conc_mark_initiation(); |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3908 |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3909 // We do not allow initial-mark to be piggy-backed on a mixed GC. |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3910 assert(!g1_policy()->during_initial_mark_pause() || |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3911 g1_policy()->gcs_are_young(), "sanity"); |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3912 |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3913 // We also do not allow mixed GCs during marking. |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3914 assert(!mark_in_progress() || g1_policy()->gcs_are_young(), "sanity"); |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3915 |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3916 // Record whether this pause is an initial mark. When the current |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3917 // thread has completed its logging output and it's safe to signal |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3918 // the CM thread, the flag's value in the policy has been reset. |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3919 bool should_start_conc_mark = g1_policy()->during_initial_mark_pause(); |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3920 |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
3921 // Inner scope for scope based logging, timers, and stats collection |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3922 { |
10405 | 3923 EvacuationInfo evacuation_info; |
3924 | |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3925 if (g1_policy()->during_initial_mark_pause()) { |
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3926 // 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
|
3927 // full collection counter. |
6120
37552638d24a
7172388: G1: _total_full_collections should not be incremented for concurrent cycles
brutisso
parents:
6109
diff
changeset
|
3928 increment_old_marking_cycles_started(); |
10405 | 3929 register_concurrent_cycle_start(_gc_timer_stw->gc_start()); |
1656
4e5661ba9d98
6944166: G1: explicit GCs are not always handled correctly
tonyp
parents:
1611
diff
changeset
|
3930 } |
10405 | 3931 |
3932 _gc_tracer_stw->report_yc_type(yc_type()); | |
3933 | |
6007
5c86f8211d1e
7160728: Introduce an extra logging level for G1 logging
brutisso
parents:
5987
diff
changeset
|
3934 TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty); |
6030 | 3935 |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
3936 int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ? |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
3937 workers()->active_workers() : 1); |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
3938 double pause_start_sec = os::elapsedTime(); |
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
3939 g1_policy()->phase_times()->note_gc_start(active_workers); |
6752
9646b7ff4d14
7198130: G1: PrintReferenceGC output comes out of order
brutisso
parents:
6725
diff
changeset
|
3940 log_gc_header(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3941 |
3289
b52782ae3880
6946417: G1: Java VisualVM does not support G1 properly.
jmasa
parents:
3285
diff
changeset
|
3942 TraceCollectorStats tcs(g1mm()->incremental_collection_counters()); |
3356
78542e2b5e35
7036199: Adding a notification to the implementation of GarbageCollectorMXBeans
fparain
parents:
3323
diff
changeset
|
3943 TraceMemoryManagerStats tms(false /* fullGC */, gc_cause()); |
1089
db0d5eba9d20
6815790: G1: Missing MemoryPoolMXBeans with -XX:+UseG1GC
tonyp
parents:
1088
diff
changeset
|
3944 |
2361 | 3945 // If the secondary_free_list is not empty, append it to the |
3946 // free_list. No need to wait for the cleanup operation to finish; | |
3947 // the region allocation code will check the secondary_free_list | |
3948 // and wait if necessary. If the G1StressConcRegionFreeing flag is | |
3949 // set, skip this step so that the region allocation code has to | |
3950 // get entries from the secondary_free_list. | |
2152 | 3951 if (!G1StressConcRegionFreeing) { |
2361 | 3952 append_secondary_free_list_if_not_empty_with_lock(); |
2152 | 3953 } |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3954 |
12080 | 3955 assert(check_young_list_well_formed(), "young list should be well formed"); |
3956 assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue), | |
3957 "sanity check"); | |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3958 |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3959 // Don't dynamically change the number of GC threads this early. A value of |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3960 // 0 is used to indicate serial work. When parallel work is done, |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3961 // it will be set. |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
3962 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3963 { // 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
|
3964 IsGCActiveMark x; |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3965 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3966 gc_prologue(false); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3967 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
|
3968 increment_gc_time_stamp(); |
342 | 3969 |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
3970 verify_before_gc(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3971 |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3972 COMPILER2_PRESENT(DerivedPointerTable::clear()); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
3973 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3974 // Please see comment in g1CollectedHeap.hpp and |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3975 // G1CollectedHeap::ref_processing_init() to see how |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3976 // reference processing currently works in G1. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3977 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3978 // Enable discovery in the STW reference processor |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3979 ref_processor_stw()->enable_discovery(true /*verify_disabled*/, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3980 true /*verify_no_refs*/); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3981 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3982 { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3983 // We want to temporarily turn off discovery by the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3984 // CM ref processor, if necessary, and turn it back on |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3985 // on again later if we do. Using a scoped |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3986 // NoRefDiscovery object will do this. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3987 NoRefDiscovery no_cm_discovery(ref_processor_cm()); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3988 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3989 // 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
|
3990 // of the collection set!). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3991 release_mutator_alloc_region(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3992 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3993 // We should call this after we retire the mutator alloc |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3994 // region(s) so that all the ALLOC / RETIRE events are generated |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3995 // before the start GC event. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3996 _hr_printer.start_gc(false /* full */, (size_t) total_collections()); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
3997 |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
3998 // This timing is only used by the ergonomics to handle our pause target. |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
3999 // It is unclear why this should not include the full pause. We will |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4000 // investigate this in CR 7178365. |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4001 // |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4002 // Preserving the old comment here if that helps the investigation: |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4003 // |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4004 // The elapsed time induced by the start time below deliberately elides |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4005 // the possible verification above. |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4006 double sample_start_time_sec = os::elapsedTime(); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
4007 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4008 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4009 gclog_or_tty->print_cr("\nBefore recording pause start.\nYoung_list:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4010 _young_list->print(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4011 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
|
4012 #endif // YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4013 |
10098
71013d764f6e
8010780: G1: Eden occupancy/capacity output wrong after a full GC
johnc
parents:
8855
diff
changeset
|
4014 g1_policy()->record_collection_pause_start(sample_start_time_sec); |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
4015 |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4016 double scan_wait_start = os::elapsedTime(); |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4017 // We have to wait until the CM threads finish scanning the |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4018 // root regions as it's the only way to ensure that all the |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4019 // objects on them have been correctly scanned before we start |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4020 // moving them during the GC. |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4021 bool waited = _cm->root_regions()->wait_until_scan_finished(); |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4022 double wait_time_ms = 0.0; |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4023 if (waited) { |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4024 double scan_wait_end = os::elapsedTime(); |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4025 wait_time_ms = (scan_wait_end - scan_wait_start) * 1000.0; |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4026 } |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4027 g1_policy()->phase_times()->record_root_region_scan_wait_time(wait_time_ms); |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4028 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4029 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4030 gclog_or_tty->print_cr("\nAfter recording pause start.\nYoung_list:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4031 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4032 #endif // YOUNG_LIST_VERBOSE |
342 | 4033 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4034 if (g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4035 concurrent_mark()->checkpointRootsInitialPre(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4036 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4037 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4038 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4039 gclog_or_tty->print_cr("\nBefore choosing collection set.\nYoung_list:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4040 _young_list->print(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4041 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
|
4042 #endif // YOUNG_LIST_VERBOSE |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4043 |
10405 | 4044 g1_policy()->finalize_cset(target_pause_time_ms, evacuation_info); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4045 |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4046 _cm->note_start_of_gc(); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4047 // We should not verify the per-thread SATB buffers given that |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4048 // we have not filtered them yet (we'll do so during the |
4912
a9647476d1a4
7132029: G1: mixed GC phase lasts for longer than it should
tonyp
parents:
4910
diff
changeset
|
4049 // GC). We also call this after finalize_cset() to |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4050 // ensure that the CSet has been finalized. |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4051 _cm->verify_no_cset_oops(true /* verify_stacks */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4052 true /* verify_enqueued_buffers */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4053 false /* verify_thread_buffers */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4054 true /* verify_fingers */); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4055 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4056 if (_hr_printer.is_active()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4057 HeapRegion* hr = g1_policy()->collection_set(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4058 while (hr != NULL) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4059 G1HRPrinter::RegionType type; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4060 if (!hr->is_young()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4061 type = G1HRPrinter::Old; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4062 } else if (hr->is_survivor()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4063 type = G1HRPrinter::Survivor; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4064 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4065 type = G1HRPrinter::Eden; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4066 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4067 _hr_printer.cset(hr); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4068 hr = hr->next_in_collection_set(); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
4069 } |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
4070 } |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4071 |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
4072 #ifdef ASSERT |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4073 VerifyCSetClosure cl; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4074 collection_set_iterate(&cl); |
3777
e8b0b0392037
7046182: G1: remove unnecessary iterations over the collection set
tonyp
parents:
3774
diff
changeset
|
4075 #endif // ASSERT |
1707 | 4076 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4077 setup_surviving_young_words(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4078 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4079 // Initialize the GC alloc regions. |
10405 | 4080 init_gc_alloc_regions(evacuation_info); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4081 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4082 // Actually do the work... |
10405 | 4083 evacuate_collection_set(evacuation_info); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4084 |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4085 // We do this to mainly verify the per-thread SATB buffers |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4086 // (which have been filtered by now) since we didn't verify |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4087 // them earlier. No point in re-checking the stacks / enqueued |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4088 // buffers given that the CSet has not changed since last time |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4089 // we checked. |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4090 _cm->verify_no_cset_oops(false /* verify_stacks */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4091 false /* verify_enqueued_buffers */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4092 true /* verify_thread_buffers */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4093 true /* verify_fingers */); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4094 |
10405 | 4095 free_collection_set(g1_policy()->collection_set(), evacuation_info); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4096 g1_policy()->clear_collection_set(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4097 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4098 cleanup_surviving_young_words(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4099 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4100 // Start a new incremental collection set for the next pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4101 g1_policy()->start_incremental_cset_building(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4102 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4103 // Clear the _cset_fast_test bitmap in anticipation of adding |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4104 // regions to the incremental collection set for the next |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4105 // evacuation pause. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4106 clear_cset_fast_test(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4107 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4108 _young_list->reset_sampled_info(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4109 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4110 // Don't check the whole heap at this point as the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4111 // GC alloc regions from this pause have been tagged |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4112 // as survivors and moved on to the survivor list. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4113 // Survivor regions will fail the !is_young() check. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4114 assert(check_young_list_empty(false /* check_heap */), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4115 "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
|
4116 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4117 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4118 gclog_or_tty->print_cr("Before recording survivors.\nYoung List:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4119 _young_list->print(); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4120 #endif // YOUNG_LIST_VERBOSE |
342 | 4121 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4122 g1_policy()->record_survivor_regions(_young_list->survivor_length(), |
10405 | 4123 _young_list->first_survivor_region(), |
4124 _young_list->last_survivor_region()); | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4125 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4126 _young_list->reset_auxilary_lists(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4127 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4128 if (evacuation_failed()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4129 _summary_bytes_used = recalculate_used(); |
10405 | 4130 uint n_queues = MAX2((int)ParallelGCThreads, 1); |
4131 for (uint i = 0; i < n_queues; i++) { | |
4132 if (_evacuation_failed_info_array[i].has_failed()) { | |
4133 _gc_tracer_stw->report_evacuation_failed(_evacuation_failed_info_array[i]); | |
4134 } | |
4135 } | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4136 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4137 // The "used" of the the collection set have already been subtracted |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4138 // when they were freed. Add in the bytes evacuated. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4139 _summary_bytes_used += g1_policy()->bytes_copied_during_gc(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4140 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4141 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4142 if (g1_policy()->during_initial_mark_pause()) { |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4143 // We have to do this before we notify the CM threads that |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4144 // they can start working to make sure that all the |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
4145 // appropriate initialization is done on the CM object. |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4146 concurrent_mark()->checkpointRootsInitialPost(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4147 set_marking_started(); |
4831
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4148 // Note that we don't actually trigger the CM thread at |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4149 // this point. We do that later when we're sure that |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4150 // the current thread has completed its logging output. |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4151 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4152 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4153 allocate_dummy_regions(); |
3285
49a67202bc67
7011855: G1: non-product flag to artificially grow the heap
tonyp
parents:
2433
diff
changeset
|
4154 |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
4155 #if YOUNG_LIST_VERBOSE |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4156 gclog_or_tty->print_cr("\nEnd of the pause.\nYoung_list:"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4157 _young_list->print(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4158 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
|
4159 #endif // YOUNG_LIST_VERBOSE |
342 | 4160 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4161 init_mutator_alloc_region(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4162 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4163 { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4164 size_t expand_bytes = g1_policy()->expansion_amount(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4165 if (expand_bytes > 0) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4166 size_t bytes_before = capacity(); |
4785 | 4167 // No need for an ergo verbose message here, |
4168 // expansion_amount() does this when it returns a value > 0. | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4169 if (!expand(expand_bytes)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4170 // We failed to expand the heap so let's verify that |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4171 // committed/uncommitted amount match the backing store |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4172 assert(capacity() == _g1_storage.committed_size(), "committed size mismatch"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4173 assert(max_capacity() == _g1_storage.reserved_size(), "reserved size mismatch"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4174 } |
3920
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
4175 } |
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
4176 } |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4177 |
10405 | 4178 // We redo the verification but now wrt to the new CSet which |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4179 // has just got initialized after the previous CSet was freed. |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4180 _cm->verify_no_cset_oops(true /* verify_stacks */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4181 true /* verify_enqueued_buffers */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4182 true /* verify_thread_buffers */, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4183 true /* verify_fingers */); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4184 _cm->note_end_of_gc(); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4185 |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4186 // This timing is only used by the ergonomics to handle our pause target. |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4187 // It is unclear why this should not include the full pause. We will |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4188 // investigate this in CR 7178365. |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4189 double sample_end_time_sec = os::elapsedTime(); |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4190 double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS; |
10405 | 4191 g1_policy()->record_collection_pause_end(pause_time_ms, evacuation_info); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4192 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4193 MemoryService::track_memory_usage(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4194 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4195 // 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
|
4196 // update buffers to bring the RSets up-to-date if |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4197 // G1HRRSFlushLogBuffersOnVerify has been set. While scanning |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4198 // 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
|
4199 // regions we just allocated to (i.e., the GC alloc |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4200 // regions). However, during the last GC we called |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4201 // set_saved_mark() on all the GC alloc regions, so card |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4202 // scanning might skip the [saved_mark_word()...top()] area of |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4203 // those regions (i.e., the area we allocated objects into |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4204 // during the last GC). But it shouldn't. Given that |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4205 // saved_mark_word() is conditional on whether the GC time stamp |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4206 // 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
|
4207 // 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
|
4208 // regions and saved_mark_word() will simply return top() for |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4209 // 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
|
4210 // than iterating over the regions and fixing them. In fact, the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4211 // GC time stamp increment here also ensures that |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4212 // saved_mark_word() will return top() between pauses, i.e., |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4213 // during concurrent refinement. So we don't need the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4214 // is_gc_active() check to decided which top to use when |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4215 // scanning cards (see CR 7039627). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4216 increment_gc_time_stamp(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4217 |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
4218 verify_after_gc(); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4219 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4220 assert(!ref_processor_stw()->discovery_enabled(), "Postcondition"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4221 ref_processor_stw()->verify_no_references_recorded(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4222 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4223 // 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
|
4224 } |
af2ab04e0038
6929868: G1: introduce min / max young gen size bounds
brutisso
parents:
3919
diff
changeset
|
4225 |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
4226 // 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
|
4227 // 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
|
4228 // 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
|
4229 // RETIRE events are generated before the end GC event. |
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
4230 _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
|
4231 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
4232 if (mark_in_progress()) { |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
4233 concurrent_mark()->update_g1_committed(); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
4234 } |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
4235 |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
4236 #ifdef TRACESPINNING |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
4237 ParallelTaskTerminator::print_termination_counts(); |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
545
diff
changeset
|
4238 #endif |
342 | 4239 |
838
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
4240 gc_epilogue(false); |
0316eac49d5a
6855834: G1: minimize the output when -XX:+PrintHeapAtGC is set
tonyp
parents:
811
diff
changeset
|
4241 } |
6121
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4242 |
7207
0f80645e9c26
8004170: G1: Verbose GC output is not getting flushed to log file using JDK 8
johnc
parents:
6863
diff
changeset
|
4243 // Print the remainder of the GC log output. |
0f80645e9c26
8004170: G1: Verbose GC output is not getting flushed to log file using JDK 8
johnc
parents:
6863
diff
changeset
|
4244 log_gc_footer(os::elapsedTime() - pause_start_sec); |
0f80645e9c26
8004170: G1: Verbose GC output is not getting flushed to log file using JDK 8
johnc
parents:
6863
diff
changeset
|
4245 |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
4246 // It is not yet to safe to tell the concurrent mark to |
6121
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4247 // start as we have some optional output below. We don't want the |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4248 // output from the concurrent mark thread interfering with this |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4249 // logging output either. |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4250 |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4251 _hrs.verify_optional(); |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4252 verify_region_sets_optional(); |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4253 |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4254 TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats()); |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4255 TASKQUEUE_STATS_ONLY(reset_taskqueue_stats()); |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4256 |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4257 print_heap_after_gc(); |
10405 | 4258 trace_heap_after_gc(_gc_tracer_stw); |
6121
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4259 |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4260 // We must call G1MonitoringSupport::update_sizes() in the same scoping level |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4261 // as an active TraceMemoryManagerStats object (i.e. before the destructor for the |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4262 // TraceMemoryManagerStats is called) so that the G1 memory pools are updated |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4263 // before any GC notifications are raised. |
b9442ac22f59
7173460: G1: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java failes with G1
brutisso
parents:
6120
diff
changeset
|
4264 g1mm()->update_sizes(); |
10405 | 4265 |
4266 _gc_tracer_stw->report_evacuation_info(&evacuation_info); | |
4267 _gc_tracer_stw->report_tenuring_threshold(_g1_policy->tenuring_threshold()); | |
4268 _gc_timer_stw->register_gc_end(os::elapsed_counter()); | |
4269 _gc_tracer_stw->report_gc_end(_gc_timer_stw->gc_end(), _gc_timer_stw->time_partitions()); | |
4270 } | |
4831
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4271 // It should now be safe to tell the concurrent mark thread to start |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4272 // without its logging output interfering with the logging output |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4273 // that came from the pause. |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4274 |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4275 if (should_start_conc_mark) { |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4276 // CAUTION: after the doConcurrentMark() call below, |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4277 // the concurrent marking thread(s) could be running |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4278 // concurrently with us. Make sure that anything after |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4279 // this point does not assume that we are the only GC thread |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4280 // running. Note: of course, the actual marking work will |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4281 // not start until the safepoint itself is released in |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4282 // ConcurrentGCThread::safepoint_desynchronize(). |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4283 doConcurrentMark(); |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4284 } |
7ca7be5a6a0b
7129271: G1: Interference from multiple threads in PrintGC/PrintGCDetails output
johnc
parents:
4829
diff
changeset
|
4285 |
1973 | 4286 return true; |
342 | 4287 } |
4288 | |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4289 size_t G1CollectedHeap::desired_plab_sz(GCAllocPurpose purpose) |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4290 { |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4291 size_t gclab_word_size; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4292 switch (purpose) { |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4293 case GCAllocForSurvived: |
6595 | 4294 gclab_word_size = _survivor_plab_stats.desired_plab_sz(); |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4295 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4296 case GCAllocForTenured: |
6595 | 4297 gclab_word_size = _old_plab_stats.desired_plab_sz(); |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4298 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4299 default: |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4300 assert(false, "unknown GCAllocPurpose"); |
6595 | 4301 gclab_word_size = _old_plab_stats.desired_plab_sz(); |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4302 break; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4303 } |
6595 | 4304 |
4305 // Prevent humongous PLAB sizes for two reasons: | |
4306 // * PLABs are allocated using a similar paths as oops, but should | |
4307 // never be in a humongous region | |
4308 // * Allowing humongous PLABs needlessly churns the region free lists | |
4309 return MIN2(_humongous_object_threshold_in_words, gclab_word_size); | |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4310 } |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4311 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4312 void G1CollectedHeap::init_mutator_alloc_region() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4313 assert(_mutator_alloc_region.get() == NULL, "pre-condition"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4314 _mutator_alloc_region.init(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4315 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4316 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4317 void G1CollectedHeap::release_mutator_alloc_region() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4318 _mutator_alloc_region.release(); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4319 assert(_mutator_alloc_region.get() == NULL, "post-condition"); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
4320 } |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4321 |
10405 | 4322 void G1CollectedHeap::init_gc_alloc_regions(EvacuationInfo& evacuation_info) { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4323 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
|
4324 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4325 _survivor_gc_alloc_region.init(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4326 _old_gc_alloc_region.init(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4327 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
|
4328 _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
|
4329 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4330 // 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
|
4331 // 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
|
4332 // 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
|
4333 // 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
|
4334 // 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
|
4335 // 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
|
4336 // during a cleanup and was added to the free list, but |
10405 | 4337 // has been subsequently used to allocate a humongous |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4338 // 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
|
4339 if (retained_region != NULL && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4340 !retained_region->in_collection_set() && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4341 !(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
|
4342 !retained_region->is_empty() && |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4343 !retained_region->isHumongous()) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4344 retained_region->set_saved_mark(); |
4072 | 4345 // The retained region was added to the old region set when it was |
4346 // retired. We have to remove it now, since we don't allow regions | |
4347 // we allocate to in the region sets. We'll re-add it later, when | |
4348 // it's retired again. | |
4349 _old_set.remove(retained_region); | |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4350 bool during_im = g1_policy()->during_initial_mark_pause(); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4351 retained_region->note_start_of_copying(during_im); |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4352 _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
|
4353 _hr_printer.reuse(retained_region); |
10405 | 4354 evacuation_info.set_alloc_regions_used_before(retained_region->used()); |
4355 } | |
4356 } | |
4357 | |
4358 void G1CollectedHeap::release_gc_alloc_regions(uint no_of_gc_workers, EvacuationInfo& evacuation_info) { | |
4359 evacuation_info.set_allocation_regions(_survivor_gc_alloc_region.count() + | |
4360 _old_gc_alloc_region.count()); | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4361 _survivor_gc_alloc_region.release(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4362 // 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
|
4363 // _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
|
4364 // _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
|
4365 // 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
|
4366 // condition. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4367 _retained_old_gc_alloc_region = _old_gc_alloc_region.release(); |
6595 | 4368 |
4369 if (ResizePLAB) { | |
6819 | 4370 _survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers); |
4371 _old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers); | |
6595 | 4372 } |
342 | 4373 } |
4374 | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4375 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
|
4376 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
|
4377 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
|
4378 _retained_old_gc_alloc_region = NULL; |
342 | 4379 } |
4380 | |
4381 void G1CollectedHeap::init_for_evac_failure(OopsInHeapRegionClosure* cl) { | |
4382 _drain_in_progress = false; | |
4383 set_evac_failure_closure(cl); | |
6197 | 4384 _evac_failure_scan_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<oop>(40, true); |
342 | 4385 } |
4386 | |
4387 void G1CollectedHeap::finalize_for_evac_failure() { | |
4388 assert(_evac_failure_scan_stack != NULL && | |
4389 _evac_failure_scan_stack->length() == 0, | |
4390 "Postcondition"); | |
4391 assert(!_drain_in_progress, "Postcondition"); | |
1045 | 4392 delete _evac_failure_scan_stack; |
342 | 4393 _evac_failure_scan_stack = NULL; |
4394 } | |
4395 | |
4396 void G1CollectedHeap::remove_self_forwarding_pointers() { | |
4783
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4397 assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity"); |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4398 |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4399 G1ParRemoveSelfForwardPtrsTask rsfp_task(this); |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4400 |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4401 if (G1CollectedHeap::use_parallel_gc_threads()) { |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4402 set_par_threads(); |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4403 workers()->run_task(&rsfp_task); |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4404 set_par_threads(0); |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
4405 } else { |
4783
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4406 rsfp_task.work(0); |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4407 } |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4408 |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4409 assert(check_cset_heap_region_claim_values(HeapRegion::ParEvacFailureClaimValue), "sanity"); |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4410 |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4411 // Reset the claim values in the regions in the collection set. |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4412 reset_cset_heap_region_claim_values(); |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4413 |
023652e49ac0
7121496: G1: do the per-region evacuation failure handling work in parallel
johnc
parents:
4781
diff
changeset
|
4414 assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity"); |
342 | 4415 |
4416 // Now restore saved marks, if any. | |
8038
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4417 assert(_objs_with_preserved_marks.size() == |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4418 _preserved_marks_of_objs.size(), "Both or none."); |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4419 while (!_objs_with_preserved_marks.is_empty()) { |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4420 oop obj = _objs_with_preserved_marks.pop(); |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4421 markOop m = _preserved_marks_of_objs.pop(); |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4422 obj->set_mark(m); |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4423 } |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4424 _objs_with_preserved_marks.clear(true); |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4425 _preserved_marks_of_objs.clear(true); |
342 | 4426 } |
4427 | |
4428 void G1CollectedHeap::push_on_evac_failure_scan_stack(oop obj) { | |
4429 _evac_failure_scan_stack->push(obj); | |
4430 } | |
4431 | |
4432 void G1CollectedHeap::drain_evac_failure_scan_stack() { | |
4433 assert(_evac_failure_scan_stack != NULL, "precondition"); | |
4434 | |
4435 while (_evac_failure_scan_stack->length() > 0) { | |
4436 oop obj = _evac_failure_scan_stack->pop(); | |
4437 _evac_failure_closure->set_region(heap_region_containing(obj)); | |
4438 obj->oop_iterate_backwards(_evac_failure_closure); | |
4439 } | |
4440 } | |
4441 | |
4442 oop | |
10405 | 4443 G1CollectedHeap::handle_evacuation_failure_par(G1ParScanThreadState* _par_scan_state, |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4444 oop old) { |
3323
75af3e8de182
7040450: G1: assert((_g1->evacuation_failed()) || (!_g1->obj_in_cs(obj))) failed: shouldn't still be in ...
tonyp
parents:
3317
diff
changeset
|
4445 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
|
4446 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
|
4447 (HeapWord*) old)); |
342 | 4448 markOop m = old->mark(); |
4449 oop forward_ptr = old->forward_to_atomic(old); | |
4450 if (forward_ptr == NULL) { | |
4451 // Forward-to-self succeeded. | |
10405 | 4452 assert(_par_scan_state != NULL, "par scan state"); |
4453 OopsInHeapRegionClosure* cl = _par_scan_state->evac_failure_closure(); | |
4454 uint queue_num = _par_scan_state->queue_num(); | |
4455 | |
4456 _evacuation_failed = true; | |
4457 _evacuation_failed_info_array[queue_num].register_copy_failure(old->size()); | |
342 | 4458 if (_evac_failure_closure != cl) { |
4459 MutexLockerEx x(EvacFailureStack_lock, Mutex::_no_safepoint_check_flag); | |
4460 assert(!_drain_in_progress, | |
4461 "Should only be true while someone holds the lock."); | |
4462 // Set the global evac-failure closure to the current thread's. | |
4463 assert(_evac_failure_closure == NULL, "Or locking has failed."); | |
4464 set_evac_failure_closure(cl); | |
4465 // Now do the common part. | |
4466 handle_evacuation_failure_common(old, m); | |
4467 // Reset to NULL. | |
4468 set_evac_failure_closure(NULL); | |
4469 } else { | |
4470 // The lock is already held, and this is recursive. | |
4471 assert(_drain_in_progress, "This should only be the recursive case."); | |
4472 handle_evacuation_failure_common(old, m); | |
4473 } | |
4474 return old; | |
4475 } 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
|
4476 // 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
|
4477 // 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
|
4478 // 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
|
4479 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
|
4480 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
|
4481 "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
|
4482 (HeapWord*) old, (HeapWord*) forward_ptr)); |
342 | 4483 return forward_ptr; |
4484 } | |
4485 } | |
4486 | |
4487 void G1CollectedHeap::handle_evacuation_failure_common(oop old, markOop m) { | |
4488 preserve_mark_if_necessary(old, m); | |
4489 | |
4490 HeapRegion* r = heap_region_containing(old); | |
4491 if (!r->evacuation_failed()) { | |
4492 r->set_evacuation_failed(true); | |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
4493 _hr_printer.evac_failure(r); |
342 | 4494 } |
4495 | |
4496 push_on_evac_failure_scan_stack(old); | |
4497 | |
4498 if (!_drain_in_progress) { | |
4499 // prevent recursion in copy_to_survivor_space() | |
4500 _drain_in_progress = true; | |
4501 drain_evac_failure_scan_stack(); | |
4502 _drain_in_progress = false; | |
4503 } | |
4504 } | |
4505 | |
4506 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
|
4507 assert(evacuation_failed(), "Oversaving!"); |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
4508 // 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
|
4509 // case of a promotion failure. |
74ee0db180fa
6807801: CMS: could save/restore fewer header words during scavenge
ysr
parents:
2037
diff
changeset
|
4510 if (m->must_be_preserved_for_promotion_failure(obj)) { |
8038
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4511 _objs_with_preserved_marks.push(obj); |
ad747ee9d0b1
8002144: G1: large number of evacuation failures may lead to large c heap memory usage
brutisso
parents:
7455
diff
changeset
|
4512 _preserved_marks_of_objs.push(m); |
342 | 4513 } |
4514 } | |
4515 | |
4516 HeapWord* G1CollectedHeap::par_allocate_during_gc(GCAllocPurpose purpose, | |
4517 size_t word_size) { | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4518 if (purpose == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4519 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
|
4520 if (result != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4521 return result; |
342 | 4522 } else { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4523 // 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
|
4524 // object there. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4525 return old_attempt_allocation(word_size); |
342 | 4526 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4527 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4528 assert(purpose == GCAllocForTenured, "sanity"); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4529 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
|
4530 if (result != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4531 return result; |
342 | 4532 } else { |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4533 // 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
|
4534 // object there. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4535 return survivor_attempt_allocation(word_size); |
342 | 4536 } |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4537 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4538 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4539 ShouldNotReachHere(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
4540 // 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
|
4541 return NULL; |
342 | 4542 } |
4543 | |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4544 G1ParGCAllocBuffer::G1ParGCAllocBuffer(size_t gclab_word_size) : |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4545 ParGCAllocBuffer(gclab_word_size), _retired(false) { } |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4546 |
4836
d30fa85f9994
6484965: G1: piggy-back liveness accounting phase on marking
johnc
parents:
4834
diff
changeset
|
4547 G1ParScanThreadState::G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num) |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4548 : _g1h(g1h), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4549 _refs(g1h->task_queue(queue_num)), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4550 _dcq(&g1h->dirty_card_queue_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4551 _ct_bs((CardTableModRefBS*)_g1h->barrier_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4552 _g1_rem(g1h->g1_rem_set()), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4553 _hash_seed(17), _queue_num(queue_num), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4554 _term_attempts(0), |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4555 _surviving_alloc_buffer(g1h->desired_plab_sz(GCAllocForSurvived)), |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4556 _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
|
4557 _age_table(false), |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4558 _strong_roots_time(0), _term_time(0), |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4559 _alloc_buffer_waste(0), _undo_waste(0) { |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4560 // we allocate G1YoungSurvRateNumRegions plus one entries, since |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4561 // 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
|
4562 // non-young regions (where the age is -1) |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4563 // 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
|
4564 // an attempt to eliminate cache contention |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
4565 uint real_length = 1 + _g1h->g1_policy()->young_cset_region_length(); |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
4566 uint array_length = PADDING_ELEM_NUM + |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
4567 real_length + |
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
4568 PADDING_ELEM_NUM; |
6197 | 4569 _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4570 if (_surviving_young_words_base == NULL) |
10161
746b070f5022
8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents:
10099
diff
changeset
|
4571 vm_exit_out_of_memory(array_length * sizeof(size_t), OOM_MALLOC_ERROR, |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4572 "Not enough space for young surv histo."); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4573 _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM; |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
4574 memset(_surviving_young_words, 0, (size_t) real_length * sizeof(size_t)); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4575 |
1391
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4576 _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4577 _alloc_buffers[GCAllocForTenured] = &_tenured_alloc_buffer; |
79e419e5ea3b
6942253: G1: replace G1ParallelGCAllocBufferSize with YoungPLABSize and OldPLABSize
apetrusenko
parents:
1390
diff
changeset
|
4578 |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4579 _start = os::elapsedTime(); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4580 } |
342 | 4581 |
1709 | 4582 void |
4583 G1ParScanThreadState::print_termination_stats_hdr(outputStream* const st) | |
4584 { | |
4585 st->print_raw_cr("GC Termination Stats"); | |
4586 st->print_raw_cr(" elapsed --strong roots-- -------termination-------" | |
4587 " ------waste (KiB)------"); | |
4588 st->print_raw_cr("thr ms ms % ms % attempts" | |
4589 " total alloc undo"); | |
4590 st->print_raw_cr("--- --------- --------- ------ --------- ------ --------" | |
4591 " ------- ------- -------"); | |
4592 } | |
4593 | |
4594 void | |
4595 G1ParScanThreadState::print_termination_stats(int i, | |
4596 outputStream* const st) const | |
4597 { | |
4598 const double elapsed_ms = elapsed_time() * 1000.0; | |
4599 const double s_roots_ms = strong_roots_time() * 1000.0; | |
4600 const double term_ms = term_time() * 1000.0; | |
4601 st->print_cr("%3d %9.2f %9.2f %6.2f " | |
4602 "%9.2f %6.2f " SIZE_FORMAT_W(8) " " | |
4603 SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7), | |
4604 i, elapsed_ms, s_roots_ms, s_roots_ms * 100 / elapsed_ms, | |
4605 term_ms, term_ms * 100 / elapsed_ms, term_attempts(), | |
4606 (alloc_buffer_waste() + undo_waste()) * HeapWordSize / K, | |
4607 alloc_buffer_waste() * HeapWordSize / K, | |
4608 undo_waste() * HeapWordSize / K); | |
4609 } | |
4610 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4611 #ifdef ASSERT |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4612 bool G1ParScanThreadState::verify_ref(narrowOop* ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4613 assert(ref != NULL, "invariant"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4614 assert(UseCompressedOops, "sanity"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4615 assert(!has_partial_array_mask(ref), err_msg("ref=" PTR_FORMAT, ref)); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4616 oop p = oopDesc::load_decode_heap_oop(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4617 assert(_g1h->is_in_g1_reserved(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4618 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4619 return true; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4620 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4621 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4622 bool G1ParScanThreadState::verify_ref(oop* ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4623 assert(ref != NULL, "invariant"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4624 if (has_partial_array_mask(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4625 // Must be in the collection set--it's already been copied. |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4626 oop p = clear_partial_array_mask(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4627 assert(_g1h->obj_in_cs(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4628 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4629 } else { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4630 oop p = oopDesc::load_decode_heap_oop(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4631 assert(_g1h->is_in_g1_reserved(p), |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4632 err_msg("ref=" PTR_FORMAT " p=" PTR_FORMAT, ref, intptr_t(p))); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4633 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4634 return true; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4635 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4636 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4637 bool G1ParScanThreadState::verify_task(StarTask ref) const { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4638 if (ref.is_narrow()) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4639 return verify_ref((narrowOop*) ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4640 } else { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4641 return verify_ref((oop*) ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4642 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4643 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4644 #endif // ASSERT |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4645 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4646 void G1ParScanThreadState::trim_queue() { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4647 assert(_evac_cl != NULL, "not set"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4648 assert(_evac_failure_cl != NULL, "not set"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4649 assert(_partial_scan_cl != NULL, "not set"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4650 |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4651 StarTask ref; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4652 do { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4653 // Drain the overflow stack first, so other threads can steal. |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4654 while (refs()->pop_overflow(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4655 deal_with_reference(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4656 } |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
4657 |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4658 while (refs()->pop_local(ref)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4659 deal_with_reference(ref); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4660 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4661 } while (!refs()->is_empty()); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4662 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4663 |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4664 G1ParClosureSuper::G1ParClosureSuper(G1CollectedHeap* g1, |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4665 G1ParScanThreadState* par_scan_state) : |
342 | 4666 _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
|
4667 _par_scan_state(par_scan_state), |
4836
d30fa85f9994
6484965: G1: piggy-back liveness accounting phase on marking
johnc
parents:
4834
diff
changeset
|
4668 _worker_id(par_scan_state->queue_num()), |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4669 _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
|
4670 _mark_in_progress(_g1->mark_in_progress()) { } |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4671 |
5987 | 4672 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
4673 void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object>::mark_object(oop obj) { | |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4674 #ifdef ASSERT |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4675 HeapRegion* hr = _g1->heap_region_containing(obj); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4676 assert(hr != NULL, "sanity"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4677 assert(!hr->in_collection_set(), "should not mark objects in the CSet"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4678 #endif // ASSERT |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4679 |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4680 // We know that the object is not moving so it's safe to read its size. |
4836
d30fa85f9994
6484965: G1: piggy-back liveness accounting phase on marking
johnc
parents:
4834
diff
changeset
|
4681 _cm->grayRoot(obj, (size_t) obj->size(), _worker_id); |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4682 } |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4683 |
5987 | 4684 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
4685 void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object> | |
4686 ::mark_forwarded_object(oop from_obj, oop to_obj) { | |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4687 #ifdef ASSERT |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4688 assert(from_obj->is_forwarded(), "from obj should be forwarded"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4689 assert(from_obj->forwardee() == to_obj, "to obj should be the forwardee"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4690 assert(from_obj != to_obj, "should not be self-forwarded"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4691 |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4692 HeapRegion* from_hr = _g1->heap_region_containing(from_obj); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4693 assert(from_hr != NULL, "sanity"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4694 assert(from_hr->in_collection_set(), "from obj should be in the CSet"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4695 |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4696 HeapRegion* to_hr = _g1->heap_region_containing(to_obj); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4697 assert(to_hr != NULL, "sanity"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4698 assert(!to_hr->in_collection_set(), "should not mark objects in the CSet"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4699 #endif // ASSERT |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4700 |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4701 // The object might be in the process of being copied by another |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4702 // worker so we cannot trust that its to-space image is |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4703 // well-formed. So we have to read its size from its from-space |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4704 // image which we know should not be changing. |
4836
d30fa85f9994
6484965: G1: piggy-back liveness accounting phase on marking
johnc
parents:
4834
diff
changeset
|
4705 _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id); |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4706 } |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4707 |
5987 | 4708 template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object> |
4709 oop G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object> | |
4710 ::copy_to_survivor_space(oop old) { | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
4711 size_t word_sz = old->size(); |
342 | 4712 HeapRegion* from_region = _g1->heap_region_containing_raw(old); |
4713 // +1 to make the -1 indexes valid... | |
4714 int young_index = from_region->young_index_in_cset()+1; | |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4715 assert( (from_region->is_young() && young_index > 0) || |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4716 (!from_region->is_young() && young_index == 0), "invariant" ); |
342 | 4717 G1CollectorPolicy* g1p = _g1->g1_policy(); |
4718 markOop m = old->mark(); | |
545 | 4719 int age = m->has_displaced_mark_helper() ? m->displaced_mark_helper()->age() |
4720 : m->age(); | |
4721 GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age, | |
342 | 4722 word_sz); |
4723 HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz); | |
6629
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4724 #ifndef PRODUCT |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4725 // Should this evacuation fail? |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4726 if (_g1->evacuation_should_fail()) { |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4727 if (obj_ptr != NULL) { |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4728 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4729 obj_ptr = NULL; |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4730 } |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4731 } |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4732 #endif // !PRODUCT |
342 | 4733 |
4734 if (obj_ptr == NULL) { | |
4735 // This will either forward-to-self, or detect that someone else has | |
4736 // installed a forwarding pointer. | |
10405 | 4737 return _g1->handle_evacuation_failure_par(_par_scan_state, old); |
342 | 4738 } |
4739 | |
6629
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4740 oop obj = oop(obj_ptr); |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
4741 |
526 | 4742 // We're going to allocate linearly, so might as well prefetch ahead. |
4743 Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes); | |
4744 | |
342 | 4745 oop forward_ptr = old->forward_to_atomic(obj); |
4746 if (forward_ptr == NULL) { | |
4747 Copy::aligned_disjoint_words((HeapWord*) old, obj_ptr, word_sz); | |
526 | 4748 if (g1p->track_object_age(alloc_purpose)) { |
4749 // We could simply do obj->incr_age(). However, this causes a | |
4750 // performance issue. obj->incr_age() will first check whether | |
4751 // the object has a displaced mark by checking its mark word; | |
4752 // getting the mark word from the new location of the object | |
4753 // stalls. So, given that we already have the mark word and we | |
4754 // are about to install it anyway, it's better to increase the | |
4755 // age on the mark word, when the object does not have a | |
4756 // displaced mark word. We're not expecting many objects to have | |
4757 // a displaced marked word, so that case is not optimized | |
4758 // further (it could be...) and we simply call obj->incr_age(). | |
4759 | |
4760 if (m->has_displaced_mark_helper()) { | |
4761 // in this case, we have to install the mark word first, | |
4762 // otherwise obj looks to be forwarded (the old mark word, | |
4763 // which contains the forward pointer, was copied) | |
4764 obj->set_mark(m); | |
4765 obj->incr_age(); | |
4766 } else { | |
4767 m = m->incr_age(); | |
545 | 4768 obj->set_mark(m); |
526 | 4769 } |
545 | 4770 _par_scan_state->age_table()->add(obj, word_sz); |
4771 } else { | |
4772 obj->set_mark(m); | |
526 | 4773 } |
4774 | |
342 | 4775 size_t* surv_young_words = _par_scan_state->surviving_young_words(); |
4776 surv_young_words[young_index] += word_sz; | |
4777 | |
4778 if (obj->is_objArray() && arrayOop(obj)->length() >= ParGCArrayScanChunk) { | |
4784
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4779 // We keep track of the next start index in the length field of |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4780 // the to-space object. The actual length can be found in the |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4781 // length field of the from-space object. |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4782 arrayOop(obj)->set_length(0); |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4783 oop* old_p = set_partial_array_mask(old); |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4784 _par_scan_state->push_on_queue(old_p); |
342 | 4785 } else { |
526 | 4786 // No point in using the slower heap_region_containing() method, |
4787 // given that we know obj is in the heap. | |
5987 | 4788 _scanner.set_region(_g1->heap_region_containing_raw(obj)); |
4789 obj->oop_iterate_backwards(&_scanner); | |
342 | 4790 } |
4791 } else { | |
4792 _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz); | |
4793 obj = forward_ptr; | |
4794 } | |
4795 return obj; | |
4796 } | |
4797 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4798 template <class T> |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4799 void G1ParCopyHelper::do_klass_barrier(T* p, oop new_obj) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4800 if (_g1->heap_region_containing_raw(new_obj)->is_young()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4801 _scanned_klass->record_modified_oops(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4802 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4803 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4804 |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4805 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
|
4806 template <class T> |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4807 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
|
4808 ::do_oop_work(T* p) { |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4809 oop obj = oopDesc::load_decode_heap_oop(p); |
342 | 4810 assert(barrier != G1BarrierRS || obj != NULL, |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4811 "Precondition: G1BarrierRS implies obj is non-NULL"); |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4812 |
4836
d30fa85f9994
6484965: G1: piggy-back liveness accounting phase on marking
johnc
parents:
4834
diff
changeset
|
4813 assert(_worker_id == _par_scan_state->queue_num(), "sanity"); |
d30fa85f9994
6484965: G1: piggy-back liveness accounting phase on marking
johnc
parents:
4834
diff
changeset
|
4814 |
526 | 4815 // 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
|
4816 if (_g1->in_cset_fast_test(obj)) { |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4817 oop forwardee; |
526 | 4818 if (obj->is_forwarded()) { |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4819 forwardee = obj->forwardee(); |
526 | 4820 } else { |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4821 forwardee = copy_to_survivor_space(obj); |
342 | 4822 } |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4823 assert(forwardee != NULL, "forwardee should not be NULL"); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4824 oopDesc::encode_store_heap_oop(p, forwardee); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4825 if (do_mark_object && forwardee != obj) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4826 // If the object is self-forwarded we don't need to explicitly |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4827 // mark it, the evacuation failure protocol will do so. |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4828 mark_forwarded_object(obj, forwardee); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4829 } |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4830 |
526 | 4831 // When scanning the RS, we only care about objs in CS. |
4832 if (barrier == G1BarrierRS) { | |
4836
d30fa85f9994
6484965: G1: piggy-back liveness accounting phase on marking
johnc
parents:
4834
diff
changeset
|
4833 _par_scan_state->update_rs(_from, p, _worker_id); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4834 } else if (barrier == G1BarrierKlass) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4835 do_klass_barrier(p, forwardee); |
342 | 4836 } |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4837 } else { |
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4838 // 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
|
4839 // 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
|
4840 // be true) then attempt to mark the object. |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4841 if (do_mark_object && _g1->is_in_g1_reserved(obj)) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
4842 mark_object(obj); |
3886
eeae91c9baba
7080389: G1: refactor marking code in evacuation pause copy closures
johnc
parents:
3869
diff
changeset
|
4843 } |
526 | 4844 } |
4845 | |
4846 if (barrier == G1BarrierEvac && obj != NULL) { | |
4836
d30fa85f9994
6484965: G1: piggy-back liveness accounting phase on marking
johnc
parents:
4834
diff
changeset
|
4847 _par_scan_state->update_rs(_from, p, _worker_id); |
526 | 4848 } |
4849 | |
4850 if (do_gen_barrier && obj != NULL) { | |
4851 par_do_barrier(p); | |
4852 } | |
4853 } | |
4854 | |
1261
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4855 template void G1ParCopyClosure<false, G1BarrierEvac, false>::do_oop_work(oop* p); |
0414c1049f15
6923991: G1: improve scalability of RSet scanning
iveresov
parents:
1245
diff
changeset
|
4856 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
|
4857 |
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
838
diff
changeset
|
4858 template <class T> void G1ParScanPartialArrayClosure::do_oop_nv(T* p) { |
526 | 4859 assert(has_partial_array_mask(p), "invariant"); |
4784
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4860 oop from_obj = clear_partial_array_mask(p); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4861 |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4862 assert(Universe::heap()->is_in_reserved(from_obj), "must be in heap."); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4863 assert(from_obj->is_objArray(), "must be obj array"); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4864 objArrayOop from_obj_array = objArrayOop(from_obj); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4865 // The from-space object contains the real length. |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4866 int length = from_obj_array->length(); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4867 |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4868 assert(from_obj->is_forwarded(), "must be forwarded"); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4869 oop to_obj = from_obj->forwardee(); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4870 assert(from_obj != to_obj, "should not be chunking self-forwarded objects"); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4871 objArrayOop to_obj_array = objArrayOop(to_obj); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4872 // We keep track of the next start index in the length field of the |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4873 // to-space object. |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4874 int next_index = to_obj_array->length(); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4875 assert(0 <= next_index && next_index < length, |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4876 err_msg("invariant, next index: %d, length: %d", next_index, length)); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4877 |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4878 int start = next_index; |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4879 int end = length; |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4880 int remainder = end - start; |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4881 // We'll try not to push a range that's smaller than ParGCArrayScanChunk. |
342 | 4882 if (remainder > 2 * ParGCArrayScanChunk) { |
4883 end = start + ParGCArrayScanChunk; | |
4784
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4884 to_obj_array->set_length(end); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4885 // Push the remainder before we process the range in case another |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4886 // worker has run out of things to do and can steal it. |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4887 oop* from_obj_p = set_partial_array_mask(from_obj); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4888 _par_scan_state->push_on_queue(from_obj_p); |
342 | 4889 } else { |
4784
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4890 assert(length == end, "sanity"); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4891 // We'll process the final range for this object. Restore the length |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4892 // so that the heap remains parsable in case of evacuation failure. |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4893 to_obj_array->set_length(end); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4894 } |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4895 _scanner.set_region(_g1->heap_region_containing_raw(to_obj)); |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4896 // Process indexes [start,end). It will also process the header |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4897 // along with the first chunk (i.e., the chunk with start == 0). |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4898 // Note that at this point the length field of to_obj_array is not |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4899 // correct given that we are using it to keep track of the next |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4900 // start index. oop_iterate_range() (thankfully!) ignores the length |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4901 // field and only relies on the start / end parameters. It does |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4902 // however return the size of the object which will be incorrect. So |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4903 // we have to ignore it even if we wanted to use it. |
02838862dec8
7121623: G1: always be able to reliably calculate the length of a forwarded chunked array
tonyp
parents:
4783
diff
changeset
|
4904 to_obj_array->oop_iterate_range(&_scanner, start, end); |
342 | 4905 } |
4906 | |
4907 class G1ParEvacuateFollowersClosure : public VoidClosure { | |
4908 protected: | |
4909 G1CollectedHeap* _g1h; | |
4910 G1ParScanThreadState* _par_scan_state; | |
4911 RefToScanQueueSet* _queues; | |
4912 ParallelTaskTerminator* _terminator; | |
4913 | |
4914 G1ParScanThreadState* par_scan_state() { return _par_scan_state; } | |
4915 RefToScanQueueSet* queues() { return _queues; } | |
4916 ParallelTaskTerminator* terminator() { return _terminator; } | |
4917 | |
4918 public: | |
4919 G1ParEvacuateFollowersClosure(G1CollectedHeap* g1h, | |
4920 G1ParScanThreadState* par_scan_state, | |
4921 RefToScanQueueSet* queues, | |
4922 ParallelTaskTerminator* terminator) | |
4923 : _g1h(g1h), _par_scan_state(par_scan_state), | |
4924 _queues(queues), _terminator(terminator) {} | |
4925 | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4926 void do_void(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4927 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4928 private: |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4929 inline bool offer_termination(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4930 }; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4931 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4932 bool G1ParEvacuateFollowersClosure::offer_termination() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4933 G1ParScanThreadState* const pss = par_scan_state(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4934 pss->start_term_time(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4935 const bool res = terminator()->offer_termination(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4936 pss->end_term_time(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4937 return res; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4938 } |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4939 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4940 void G1ParEvacuateFollowersClosure::do_void() { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4941 StarTask stolen_task; |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4942 G1ParScanThreadState* const pss = par_scan_state(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4943 pss->trim_queue(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4944 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4945 do { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4946 while (queues()->steal(pss->queue_num(), pss->hash_seed(), stolen_task)) { |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4947 assert(pss->verify_task(stolen_task), "sanity"); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4948 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
|
4949 pss->deal_with_reference((narrowOop*) stolen_task); |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4950 } else { |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4951 pss->deal_with_reference((oop*) stolen_task); |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4952 } |
1883
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4953 |
35e4e086d5f5
6990359: G1: don't push a stolen entry on the taskqueue, deal with it directly
tonyp
parents:
1862
diff
changeset
|
4954 // 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
|
4955 // 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
|
4956 // we drain the queues as necessary. |
342 | 4957 pss->trim_queue(); |
4958 } | |
1862
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4959 } while (!offer_termination()); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4960 |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4961 pss->retire_alloc_buffers(); |
b14ec34b1e07
6989448: G1: refactor and simplify G1ParScanThreadState
jcoomes
parents:
1861
diff
changeset
|
4962 } |
342 | 4963 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4964 class G1KlassScanClosure : public KlassClosure { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4965 G1ParCopyHelper* _closure; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4966 bool _process_only_dirty; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4967 int _count; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4968 public: |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4969 G1KlassScanClosure(G1ParCopyHelper* closure, bool process_only_dirty) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4970 : _process_only_dirty(process_only_dirty), _closure(closure), _count(0) {} |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4971 void do_klass(Klass* klass) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4972 // If the klass has not been dirtied we know that there's |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4973 // no references into the young gen and we can skip it. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4974 if (!_process_only_dirty || klass->has_modified_oops()) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4975 // Clean the klass since we're going to scavenge all the metadata. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4976 klass->clear_modified_oops(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4977 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4978 // Tell the closure that this klass is the Klass to scavenge |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4979 // and is the one to dirty if oops are left pointing into the young gen. |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4980 _closure->set_scanned_klass(klass); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4981 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4982 klass->oops_do(_closure); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4983 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4984 _closure->set_scanned_klass(NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4985 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4986 _count++; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4987 } |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4988 }; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
4989 |
342 | 4990 class G1ParTask : public AbstractGangTask { |
4991 protected: | |
4992 G1CollectedHeap* _g1h; | |
4993 RefToScanQueueSet *_queues; | |
4994 ParallelTaskTerminator _terminator; | |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
4995 uint _n_workers; |
342 | 4996 |
4997 Mutex _stats_lock; | |
4998 Mutex* stats_lock() { return &_stats_lock; } | |
4999 | |
5000 size_t getNCards() { | |
5001 return (_g1h->capacity() + G1BlockOffsetSharedArray::N_bytes - 1) | |
5002 / G1BlockOffsetSharedArray::N_bytes; | |
5003 } | |
5004 | |
5005 public: | |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5006 G1ParTask(G1CollectedHeap* g1h, |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5007 RefToScanQueueSet *task_queues) |
342 | 5008 : AbstractGangTask("G1 collection"), |
5009 _g1h(g1h), | |
5010 _queues(task_queues), | |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5011 _terminator(0, _queues), |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5012 _stats_lock(Mutex::leaf, "parallel G1 stats lock", true) |
342 | 5013 {} |
5014 | |
5015 RefToScanQueueSet* queues() { return _queues; } | |
5016 | |
5017 RefToScanQueue *work_queue(int i) { | |
5018 return queues()->queue(i); | |
5019 } | |
5020 | |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5021 ParallelTaskTerminator* terminator() { return &_terminator; } |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5022 |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5023 virtual void set_for_termination(int active_workers) { |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5024 // This task calls set_n_termination() in par_non_clean_card_iterate_work() |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5025 // in the young space (_par_seq_tasks) in the G1 heap |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5026 // for SequentialSubTasksDone. |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5027 // This task also uses SubTasksDone in SharedHeap and G1CollectedHeap |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5028 // both of which need setting by set_n_termination(). |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5029 _g1h->SharedHeap::set_n_termination(active_workers); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5030 _g1h->set_n_termination(active_workers); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5031 terminator()->reset_for_reuse(active_workers); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5032 _n_workers = active_workers; |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5033 } |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5034 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5035 void work(uint worker_id) { |
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5036 if (worker_id >= _n_workers) return; // no work needed this round |
1611 | 5037 |
5038 double start_time_ms = os::elapsedTime() * 1000.0; | |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5039 _g1h->g1_policy()->phase_times()->record_gc_worker_start_time(worker_id, start_time_ms); |
1611 | 5040 |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5041 { |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5042 ResourceMark rm; |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5043 HandleMark hm; |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5044 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5045 ReferenceProcessor* rp = _g1h->ref_processor_stw(); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5046 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5047 G1ParScanThreadState pss(_g1h, worker_id); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5048 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, rp); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5049 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5050 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, rp); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5051 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5052 pss.set_evac_closure(&scan_evac_cl); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5053 pss.set_evac_failure_closure(&evac_failure_cl); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5054 pss.set_partial_scan_closure(&partial_scan_cl); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5055 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5056 G1ParScanExtRootClosure only_scan_root_cl(_g1h, &pss, rp); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5057 G1ParScanMetadataClosure only_scan_metadata_cl(_g1h, &pss, rp); |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5058 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5059 G1ParScanAndMarkExtRootClosure scan_mark_root_cl(_g1h, &pss, rp); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5060 G1ParScanAndMarkMetadataClosure scan_mark_metadata_cl(_g1h, &pss, rp); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5061 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5062 bool only_young = _g1h->g1_policy()->gcs_are_young(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5063 G1KlassScanClosure scan_mark_klasses_cl_s(&scan_mark_metadata_cl, false); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5064 G1KlassScanClosure only_scan_klasses_cl_s(&only_scan_metadata_cl, only_young); |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5065 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5066 OopClosure* scan_root_cl = &only_scan_root_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5067 G1KlassScanClosure* scan_klasses_cl = &only_scan_klasses_cl_s; |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5068 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5069 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5070 // We also need to mark copied objects. |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5071 scan_root_cl = &scan_mark_root_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5072 scan_klasses_cl = &scan_mark_klasses_cl_s; |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5073 } |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5074 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5075 G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5076 |
12080 | 5077 // Don't scan the scavengable methods in the code cache as part |
5078 // of strong root scanning. The code roots that point into a | |
5079 // region in the collection set are scanned when we scan the | |
5080 // region's RSet. | |
5081 int so = SharedHeap::SO_AllClasses | SharedHeap::SO_Strings; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5082 |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5083 pss.start_strong_roots(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5084 _g1h->g1_process_strong_roots(/* is scavenging */ true, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5085 SharedHeap::ScanningOption(so), |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5086 scan_root_cl, |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5087 &push_heap_rs_cl, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5088 scan_klasses_cl, |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5089 worker_id); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5090 pss.end_strong_roots(); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5091 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5092 { |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5093 double start = os::elapsedTime(); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5094 G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5095 evac.do_void(); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5096 double elapsed_ms = (os::elapsedTime()-start)*1000.0; |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5097 double term_ms = pss.term_time()*1000.0; |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
5098 _g1h->g1_policy()->phase_times()->add_obj_copy_time(worker_id, elapsed_ms-term_ms); |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5099 _g1h->g1_policy()->phase_times()->record_termination(worker_id, term_ms, pss.term_attempts()); |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5100 } |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5101 _g1h->g1_policy()->record_thread_age_table(pss.age_table()); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5102 _g1h->update_surviving_young_words(pss.surviving_young_words()+1); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5103 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5104 if (ParallelGCVerbose) { |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5105 MutexLocker x(stats_lock()); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5106 pss.print_termination_stats(worker_id); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5107 } |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5108 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5109 assert(pss.refs()->is_empty(), "should be empty"); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5110 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5111 // Close the inner scope so that the ResourceMark and HandleMark |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5112 // destructors are executed here and are included as part of the |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5113 // "GC Worker Time". |
342 | 5114 } |
5115 | |
1611 | 5116 double end_time_ms = os::elapsedTime() * 1000.0; |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5117 _g1h->g1_policy()->phase_times()->record_gc_worker_end_time(worker_id, end_time_ms); |
342 | 5118 } |
5119 }; | |
5120 | |
5121 // *** Common G1 Evacuation Stuff | |
5122 | |
1833
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
5123 // This method is run in a GC worker. |
8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
jmasa
parents:
1755
diff
changeset
|
5124 |
342 | 5125 void |
5126 G1CollectedHeap:: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5127 g1_process_strong_roots(bool is_scavenging, |
4910
caa4652b4414
7129892: G1: explicit marking cycle initiation might fail to initiate a marking cycle
tonyp
parents:
4875
diff
changeset
|
5128 ScanningOption so, |
342 | 5129 OopClosure* scan_non_heap_roots, |
5130 OopsInHeapRegionClosure* scan_rs, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5131 G1KlassScanClosure* scan_klasses, |
342 | 5132 int worker_i) { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5133 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5134 // First scan the strong roots |
342 | 5135 double ext_roots_start = os::elapsedTime(); |
5136 double closure_app_time_sec = 0.0; | |
5137 | |
5138 BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); | |
5139 | |
12080 | 5140 assert(so & SO_CodeCache || scan_rs != NULL, "must scan code roots somehow"); |
5141 // Walk the code cache/strong code roots w/o buffering, because StarTask | |
5142 // cannot handle unaligned oop locations. | |
5143 CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, true /* do_marking */); | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
5144 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
5145 process_strong_roots(false, // no scoping; this is parallel code |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5146 is_scavenging, so, |
342 | 5147 &buf_scan_non_heap_roots, |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
5148 &eager_scan_code_roots, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5149 scan_klasses |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5150 ); |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
5151 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5152 // 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
|
5153 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
|
5154 // We need to treat the discovered reference lists of the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5155 // concurrent mark ref processor as roots and keep entries |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5156 // (which are added by the marking threads) on them live |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5157 // until they can be processed at the end of marking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5158 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
|
5159 } |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
5160 |
14a2fd14c0db
7068240: G1: Long "parallel other time" and "ext root scanning" when running specific benchmark
johnc
parents:
3778
diff
changeset
|
5161 // Finish up any enqueued closure apps (attributed as object copy time). |
342 | 5162 buf_scan_non_heap_roots.done(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5163 |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5164 double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5165 |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5166 g1_policy()->phase_times()->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
|
5167 |
342 | 5168 double ext_root_time_ms = |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
5169 ((os::elapsedTime() - 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
|
5170 |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5171 g1_policy()->phase_times()->record_ext_root_scan_time(worker_i, ext_root_time_ms); |
342 | 5172 |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
5173 // During conc marking we have to filter the per-thread SATB buffers |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
5174 // to make sure we remove any oops into the CSet (which will show up |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
5175 // as implicitly live). |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
5176 double satb_filtering_ms = 0.0; |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
5177 if (!_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers)) { |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
5178 if (mark_in_progress()) { |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
5179 double satb_filter_start = os::elapsedTime(); |
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
5180 |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
5181 JavaThread::satb_mark_queue_set().filter_thread_buffers(); |
6628
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
5182 |
bb3f6194fedb
7178363: G1: Remove the serial code for PrintGCDetails and make it a special case of the parallel code
brutisso
parents:
6611
diff
changeset
|
5183 satb_filtering_ms = (os::elapsedTime() - satb_filter_start) * 1000.0; |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
5184 } |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
5185 } |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5186 g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms); |
342 | 5187 |
12080 | 5188 // If this is an initial mark pause, and we're not scanning |
5189 // the entire code cache, we need to mark the oops in the | |
5190 // strong code root lists for the regions that are not in | |
5191 // the collection set. | |
5192 // Note all threads participate in this set of root tasks. | |
5193 double mark_strong_code_roots_ms = 0.0; | |
5194 if (g1_policy()->during_initial_mark_pause() && !(so & SO_CodeCache)) { | |
5195 double mark_strong_roots_start = os::elapsedTime(); | |
5196 mark_strong_code_roots(worker_i); | |
5197 mark_strong_code_roots_ms = (os::elapsedTime() - mark_strong_roots_start) * 1000.0; | |
5198 } | |
5199 g1_policy()->phase_times()->record_strong_code_root_mark_time(worker_i, mark_strong_code_roots_ms); | |
5200 | |
342 | 5201 // Now scan the complement of the collection set. |
5202 if (scan_rs != NULL) { | |
12080 | 5203 g1_rem_set()->oops_into_collection_set_do(scan_rs, &eager_scan_code_roots, worker_i); |
342 | 5204 } |
5205 _process_strong_tasks->all_tasks_completed(); | |
5206 } | |
5207 | |
5208 void | |
10179
a08c80e9e1e5
8012687: Remove unused is_root checks and closures
stefank
parents:
10099
diff
changeset
|
5209 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure) { |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
5210 CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false); |
10179
a08c80e9e1e5
8012687: Remove unused is_root checks and closures
stefank
parents:
10099
diff
changeset
|
5211 SharedHeap::process_weak_roots(root_closure, &roots_in_blobs); |
342 | 5212 } |
5213 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5214 // Weak Reference Processing support |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5215 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5216 // An always "is_alive" closure that is used to preserve referents. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5217 // 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
|
5218 // of referent objects that are pointed to by reference objects |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5219 // discovered by the CM ref processor. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5220 class G1AlwaysAliveClosure: public BoolObjectClosure { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5221 G1CollectedHeap* _g1; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5222 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5223 G1AlwaysAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5224 bool do_object_b(oop p) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5225 if (p != NULL) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5226 return true; |
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 return false; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5229 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5230 }; |
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 bool G1STWIsAliveClosure::do_object_b(oop p) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5233 // An object is reachable if it is outside the collection set, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5234 // or is inside and copied. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5235 return !_g1->obj_in_cs(p) || p->is_forwarded(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5236 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5237 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5238 // Non Copying Keep Alive closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5239 class G1KeepAliveClosure: public OopClosure { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5240 G1CollectedHeap* _g1; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5241 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5242 G1KeepAliveClosure(G1CollectedHeap* g1) : _g1(g1) {} |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5243 void do_oop(narrowOop* p) { guarantee(false, "Not needed"); } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5244 void do_oop( oop* p) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5245 oop obj = *p; |
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 if (_g1->obj_in_cs(obj)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5248 assert( obj->is_forwarded(), "invariant" ); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5249 *p = obj->forwardee(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5250 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5251 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5252 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5253 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5254 // Copying Keep Alive closure - can be called from both |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5255 // serial and parallel code as long as different worker |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5256 // threads utilize different G1ParScanThreadState instances |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5257 // and different queues. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5258 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5259 class G1CopyingKeepAliveClosure: public OopClosure { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5260 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5261 OopClosure* _copy_non_heap_obj_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5262 OopsInHeapRegionClosure* _copy_metadata_obj_cl; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5263 G1ParScanThreadState* _par_scan_state; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5264 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5265 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5266 G1CopyingKeepAliveClosure(G1CollectedHeap* g1h, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5267 OopClosure* non_heap_obj_cl, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5268 OopsInHeapRegionClosure* metadata_obj_cl, |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5269 G1ParScanThreadState* pss): |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5270 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5271 _copy_non_heap_obj_cl(non_heap_obj_cl), |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5272 _copy_metadata_obj_cl(metadata_obj_cl), |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5273 _par_scan_state(pss) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5274 {} |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5275 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5276 virtual void do_oop(narrowOop* p) { do_oop_work(p); } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5277 virtual void do_oop( oop* p) { do_oop_work(p); } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5278 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5279 template <class T> void do_oop_work(T* p) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5280 oop obj = oopDesc::load_decode_heap_oop(p); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5281 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5282 if (_g1h->obj_in_cs(obj)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5283 // If the referent object has been forwarded (either copied |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5284 // 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
|
5285 // evacuation failure) then we need to update the reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5286 // field and, if both reference and referent are in the G1 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5287 // heap, update the RSet for the referent. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5288 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5289 // 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
|
5290 // it alive by policy. Therefore we have copy the referent. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5291 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5292 // 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
|
5293 // on the PSS queue. When the queue is drained (after each |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5294 // phase of reference processing) the object and it's followers |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5295 // will be copied, the reference field set to point to the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5296 // new location, and the RSet updated. Otherwise we need to |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5297 // use the the non-heap or metadata closures directly to copy |
10405 | 5298 // the referent object and update the pointer, while avoiding |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5299 // updating the RSet. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5300 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5301 if (_g1h->is_in_g1_reserved(p)) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5302 _par_scan_state->push_on_queue(p); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5303 } else { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5304 assert(!ClassLoaderDataGraph::contains((address)p), |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5305 err_msg("Otherwise need to call _copy_metadata_obj_cl->do_oop(p) " |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5306 PTR_FORMAT, p)); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5307 _copy_non_heap_obj_cl->do_oop(p); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5308 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5309 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5310 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5311 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5312 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5313 // Serial drain queue closure. Called as the 'complete_gc' |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5314 // closure for each discovered list in some of the |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5315 // reference processing phases. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5316 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5317 class G1STWDrainQueueClosure: public VoidClosure { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5318 protected: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5319 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5320 G1ParScanThreadState* _par_scan_state; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5321 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5322 G1ParScanThreadState* par_scan_state() { return _par_scan_state; } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5323 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5324 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5325 G1STWDrainQueueClosure(G1CollectedHeap* g1h, G1ParScanThreadState* pss) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5326 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5327 _par_scan_state(pss) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5328 { } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5329 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5330 void do_void() { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5331 G1ParScanThreadState* const pss = par_scan_state(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5332 pss->trim_queue(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5333 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5334 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5335 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5336 // Parallel Reference Processing closures |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5337 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5338 // Implementation of AbstractRefProcTaskExecutor for parallel reference |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5339 // processing during G1 evacuation pauses. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5340 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5341 class G1STWRefProcTaskExecutor: public AbstractRefProcTaskExecutor { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5342 private: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5343 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5344 RefToScanQueueSet* _queues; |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5345 FlexibleWorkGang* _workers; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5346 int _active_workers; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5347 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5348 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5349 G1STWRefProcTaskExecutor(G1CollectedHeap* g1h, |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5350 FlexibleWorkGang* workers, |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5351 RefToScanQueueSet *task_queues, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5352 int n_workers) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5353 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5354 _queues(task_queues), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5355 _workers(workers), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5356 _active_workers(n_workers) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5357 { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5358 assert(n_workers > 0, "shouldn't call this otherwise"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5359 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5360 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5361 // Executes the given task using concurrent marking worker threads. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5362 virtual void execute(ProcessTask& task); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5363 virtual void execute(EnqueueTask& task); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5364 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5365 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5366 // Gang task for possibly parallel reference processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5367 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5368 class G1STWRefProcTaskProxy: public AbstractGangTask { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5369 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5370 ProcessTask& _proc_task; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5371 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5372 RefToScanQueueSet *_task_queues; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5373 ParallelTaskTerminator* _terminator; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5374 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5375 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5376 G1STWRefProcTaskProxy(ProcessTask& proc_task, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5377 G1CollectedHeap* g1h, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5378 RefToScanQueueSet *task_queues, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5379 ParallelTaskTerminator* terminator) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5380 AbstractGangTask("Process reference objects in parallel"), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5381 _proc_task(proc_task), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5382 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5383 _task_queues(task_queues), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5384 _terminator(terminator) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5385 {} |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5386 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5387 virtual void work(uint worker_id) { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5388 // The reference processing task executed by a single worker. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5389 ResourceMark rm; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5390 HandleMark hm; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5391 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5392 G1STWIsAliveClosure is_alive(_g1h); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5393 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5394 G1ParScanThreadState pss(_g1h, worker_id); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5395 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5396 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5397 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5398 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5399 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5400 pss.set_evac_closure(&scan_evac_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5401 pss.set_evac_failure_closure(&evac_failure_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5402 pss.set_partial_scan_closure(&partial_scan_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5403 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5404 G1ParScanExtRootClosure only_copy_non_heap_cl(_g1h, &pss, NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5405 G1ParScanMetadataClosure only_copy_metadata_cl(_g1h, &pss, NULL); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5406 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5407 G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(_g1h, &pss, NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5408 G1ParScanAndMarkMetadataClosure copy_mark_metadata_cl(_g1h, &pss, NULL); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5409 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5410 OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5411 OopsInHeapRegionClosure* copy_metadata_cl = &only_copy_metadata_cl; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5412 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5413 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5414 // We also need to mark copied objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5415 copy_non_heap_cl = ©_mark_non_heap_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5416 copy_metadata_cl = ©_mark_metadata_cl; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5417 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5418 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5419 // Keep alive closure. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5420 G1CopyingKeepAliveClosure keep_alive(_g1h, copy_non_heap_cl, copy_metadata_cl, &pss); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5421 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5422 // Complete GC closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5423 G1ParEvacuateFollowersClosure drain_queue(_g1h, &pss, _task_queues, _terminator); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5424 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5425 // Call the reference processing task's work routine. |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5426 _proc_task.work(worker_id, is_alive, keep_alive, drain_queue); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5427 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5428 // 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
|
5429 // of the processing tasks (specifically phase2 - pp2_work) execute |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5430 // the complete_gc closure (which ordinarily would drain the queue) so |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5431 // the queue may not be empty. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5432 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5433 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5434 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5435 // Driver routine for parallel reference processing. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5436 // Creates an instance of the ref processing gang |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5437 // task and has the worker threads execute it. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5438 void G1STWRefProcTaskExecutor::execute(ProcessTask& proc_task) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5439 assert(_workers != NULL, "Need parallel worker threads."); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5440 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5441 ParallelTaskTerminator terminator(_active_workers, _queues); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5442 G1STWRefProcTaskProxy proc_task_proxy(proc_task, _g1h, _queues, &terminator); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5443 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5444 _g1h->set_par_threads(_active_workers); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5445 _workers->run_task(&proc_task_proxy); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5446 _g1h->set_par_threads(0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5447 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5448 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5449 // Gang task for parallel reference enqueueing. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5450 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5451 class G1STWRefEnqueueTaskProxy: public AbstractGangTask { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5452 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5453 EnqueueTask& _enq_task; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5454 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5455 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5456 G1STWRefEnqueueTaskProxy(EnqueueTask& enq_task) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5457 AbstractGangTask("Enqueue reference objects in parallel"), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5458 _enq_task(enq_task) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5459 { } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5460 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5461 virtual void work(uint worker_id) { |
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5462 _enq_task.work(worker_id); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5463 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5464 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5465 |
10405 | 5466 // Driver routine for parallel reference enqueueing. |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5467 // Creates an instance of the ref enqueueing gang |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5468 // task and has the worker threads execute it. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5469 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5470 void G1STWRefProcTaskExecutor::execute(EnqueueTask& enq_task) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5471 assert(_workers != NULL, "Need parallel worker threads."); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5472 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5473 G1STWRefEnqueueTaskProxy enq_task_proxy(enq_task); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5474 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5475 _g1h->set_par_threads(_active_workers); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5476 _workers->run_task(&enq_task_proxy); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5477 _g1h->set_par_threads(0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5478 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5479 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5480 // End of weak reference support closures |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5481 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5482 // Abstract task used to preserve (i.e. copy) any referent objects |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5483 // 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
|
5484 // objects discovered by the CM ref processor. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5485 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5486 class G1ParPreserveCMReferentsTask: public AbstractGangTask { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5487 protected: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5488 G1CollectedHeap* _g1h; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5489 RefToScanQueueSet *_queues; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5490 ParallelTaskTerminator _terminator; |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5491 uint _n_workers; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5492 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5493 public: |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5494 G1ParPreserveCMReferentsTask(G1CollectedHeap* g1h,int workers, RefToScanQueueSet *task_queues) : |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5495 AbstractGangTask("ParPreserveCMReferents"), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5496 _g1h(g1h), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5497 _queues(task_queues), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5498 _terminator(workers, _queues), |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5499 _n_workers(workers) |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5500 { } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5501 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5502 void work(uint worker_id) { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5503 ResourceMark rm; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5504 HandleMark hm; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5505 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5506 G1ParScanThreadState pss(_g1h, worker_id); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5507 G1ParScanHeapEvacClosure scan_evac_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5508 G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5509 G1ParScanPartialArrayClosure partial_scan_cl(_g1h, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5510 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5511 pss.set_evac_closure(&scan_evac_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5512 pss.set_evac_failure_closure(&evac_failure_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5513 pss.set_partial_scan_closure(&partial_scan_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5514 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5515 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
|
5516 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5517 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5518 G1ParScanExtRootClosure only_copy_non_heap_cl(_g1h, &pss, NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5519 G1ParScanMetadataClosure only_copy_metadata_cl(_g1h, &pss, NULL); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5520 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5521 G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(_g1h, &pss, NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5522 G1ParScanAndMarkMetadataClosure copy_mark_metadata_cl(_g1h, &pss, NULL); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5523 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5524 OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5525 OopsInHeapRegionClosure* copy_metadata_cl = &only_copy_metadata_cl; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5526 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5527 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5528 // We also need to mark copied objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5529 copy_non_heap_cl = ©_mark_non_heap_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5530 copy_metadata_cl = ©_mark_metadata_cl; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5531 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5532 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5533 // Is alive closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5534 G1AlwaysAliveClosure always_alive(_g1h); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5535 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5536 // Copying keep alive closure. Applied to referent objects that need |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5537 // to be copied. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5538 G1CopyingKeepAliveClosure keep_alive(_g1h, copy_non_heap_cl, copy_metadata_cl, &pss); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5539 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5540 ReferenceProcessor* rp = _g1h->ref_processor_cm(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5541 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5542 uint limit = ReferenceProcessor::number_of_subclasses_of_ref() * rp->max_num_q(); |
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5543 uint stride = MIN2(MAX2(_n_workers, 1U), limit); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5544 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5545 // 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
|
5546 // 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
|
5547 // change the worker ids. |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5548 assert(0 <= worker_id && worker_id < limit, "sanity"); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5549 assert(!rp->discovery_is_atomic(), "check this code"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5550 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5551 // Select discovered lists [i, i+stride, i+2*stride,...,limit) |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5552 for (uint idx = worker_id; idx < limit; idx += stride) { |
4014
bf2d2b8b1726
7095243: Disambiguate ReferenceProcessor::_discoveredSoftRefs
johnc
parents:
4013
diff
changeset
|
5553 DiscoveredList& ref_list = rp->discovered_refs()[idx]; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5554 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5555 DiscoveredListIterator iter(ref_list, &keep_alive, &always_alive); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5556 while (iter.has_next()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5557 // Since discovery is not atomic for the CM ref processor, we |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5558 // can see some null referent objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5559 iter.load_ptrs(DEBUG_ONLY(true)); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5560 oop ref = iter.obj(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5561 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5562 // This will filter nulls. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5563 if (iter.is_referent_alive()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5564 iter.make_referent_alive(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5565 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5566 iter.move_to_next(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5567 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5568 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5569 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5570 // Drain the queue - which may cause stealing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5571 G1ParEvacuateFollowersClosure drain_queue(_g1h, &pss, _queues, &_terminator); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5572 drain_queue.do_void(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5573 // Allocation buffers were retired at the end of G1ParEvacuateFollowersClosure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5574 assert(pss.refs()->is_empty(), "should be"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5575 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5576 }; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5577 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5578 // Weak Reference processing during an evacuation pause (part 1). |
6819 | 5579 void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5580 double ref_proc_start = os::elapsedTime(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5581 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5582 ReferenceProcessor* rp = _ref_processor_stw; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5583 assert(rp->discovery_enabled(), "should have been enabled"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5584 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5585 // Any reference objects, in the collection set, that were 'discovered' |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5586 // 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
|
5587 // applying the external root copy closure to the discovered lists, or |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5588 // by following an RSet entry). |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5589 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5590 // 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
|
5591 // 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
|
5592 // processor would have seen that the reference object had already |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5593 // been 'discovered' and would have skipped discovering the reference, |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5594 // but would not have treated the reference object as a regular oop. |
10405 | 5595 // As a result the copy closure would not have been applied to the |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5596 // referent object. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5597 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5598 // We need to explicitly copy these referent objects - the references |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5599 // will be processed at the end of remarking. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5600 // |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5601 // 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
|
5602 // 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
|
5603 // referents points to another object which is also referenced by an |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5604 // object discovered by the STW ref processor. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5605 |
4711 | 5606 assert(!G1CollectedHeap::use_parallel_gc_threads() || |
6819 | 5607 no_of_gc_workers == workers()->active_workers(), |
5608 "Need to reset active GC workers"); | |
5609 | |
5610 set_par_threads(no_of_gc_workers); | |
5611 G1ParPreserveCMReferentsTask keep_cm_referents(this, | |
5612 no_of_gc_workers, | |
5613 _task_queues); | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5614 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5615 if (G1CollectedHeap::use_parallel_gc_threads()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5616 workers()->run_task(&keep_cm_referents); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5617 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5618 keep_cm_referents.work(0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5619 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5620 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5621 set_par_threads(0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5622 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5623 // Closure to test whether a referent is alive. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5624 G1STWIsAliveClosure is_alive(this); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5625 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5626 // Even when parallel reference processing is enabled, the processing |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5627 // 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
|
5628 // 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
|
5629 // JNI refs. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5630 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5631 // Use only a single queue for this PSS. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5632 G1ParScanThreadState pss(this, 0); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5633 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5634 // We do not embed a reference processor in the copying/scanning |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5635 // closures while we're actually processing the discovered |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5636 // reference objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5637 G1ParScanHeapEvacClosure scan_evac_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5638 G1ParScanHeapEvacFailureClosure evac_failure_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5639 G1ParScanPartialArrayClosure partial_scan_cl(this, &pss, NULL); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5640 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5641 pss.set_evac_closure(&scan_evac_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5642 pss.set_evac_failure_closure(&evac_failure_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5643 pss.set_partial_scan_closure(&partial_scan_cl); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5644 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5645 assert(pss.refs()->is_empty(), "pre-condition"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5646 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5647 G1ParScanExtRootClosure only_copy_non_heap_cl(this, &pss, NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5648 G1ParScanMetadataClosure only_copy_metadata_cl(this, &pss, NULL); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5649 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5650 G1ParScanAndMarkExtRootClosure copy_mark_non_heap_cl(this, &pss, NULL); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5651 G1ParScanAndMarkMetadataClosure copy_mark_metadata_cl(this, &pss, NULL); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5652 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5653 OopClosure* copy_non_heap_cl = &only_copy_non_heap_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5654 OopsInHeapRegionClosure* copy_metadata_cl = &only_copy_metadata_cl; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5655 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5656 if (_g1h->g1_policy()->during_initial_mark_pause()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5657 // We also need to mark copied objects. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5658 copy_non_heap_cl = ©_mark_non_heap_cl; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5659 copy_metadata_cl = ©_mark_metadata_cl; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5660 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5661 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5662 // Keep alive closure. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
5663 G1CopyingKeepAliveClosure keep_alive(this, copy_non_heap_cl, copy_metadata_cl, &pss); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5664 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5665 // Serial Complete GC closure |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5666 G1STWDrainQueueClosure drain_queue(this, &pss); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5667 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5668 // Setup the soft refs policy... |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5669 rp->setup_policy(false); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5670 |
10405 | 5671 ReferenceProcessorStats stats; |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5672 if (!rp->processing_is_mt()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5673 // Serial reference processing... |
10405 | 5674 stats = rp->process_discovered_references(&is_alive, |
5675 &keep_alive, | |
5676 &drain_queue, | |
5677 NULL, | |
5678 _gc_timer_stw); | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5679 } else { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5680 // Parallel reference processing |
6819 | 5681 assert(rp->num_q() == no_of_gc_workers, "sanity"); |
5682 assert(no_of_gc_workers <= rp->max_num_q(), "sanity"); | |
5683 | |
5684 G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers); | |
10405 | 5685 stats = rp->process_discovered_references(&is_alive, |
5686 &keep_alive, | |
5687 &drain_queue, | |
5688 &par_task_executor, | |
5689 _gc_timer_stw); | |
5690 } | |
5691 | |
5692 _gc_tracer_stw->report_gc_reference_stats(stats); | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5693 // We have completed copying any necessary live referent objects |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5694 // (that were not copied during the actual pause) so we can |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5695 // retire any active alloc buffers |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5696 pss.retire_alloc_buffers(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5697 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
|
5698 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5699 double ref_proc_time = os::elapsedTime() - ref_proc_start; |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5700 g1_policy()->phase_times()->record_ref_proc_time(ref_proc_time * 1000.0); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5701 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5702 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5703 // Weak Reference processing during an evacuation pause (part 2). |
6819 | 5704 void G1CollectedHeap::enqueue_discovered_references(uint no_of_gc_workers) { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5705 double ref_enq_start = os::elapsedTime(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5706 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5707 ReferenceProcessor* rp = _ref_processor_stw; |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5708 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
|
5709 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5710 // Now enqueue any remaining on the discovered lists on to |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5711 // the pending list. |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5712 if (!rp->processing_is_mt()) { |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5713 // Serial reference processing... |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5714 rp->enqueue_discovered_references(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5715 } else { |
10405 | 5716 // Parallel reference enqueueing |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5717 |
6819 | 5718 assert(no_of_gc_workers == workers()->active_workers(), |
5719 "Need to reset active workers"); | |
5720 assert(rp->num_q() == no_of_gc_workers, "sanity"); | |
5721 assert(no_of_gc_workers <= rp->max_num_q(), "sanity"); | |
5722 | |
5723 G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers); | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5724 rp->enqueue_discovered_references(&par_task_executor); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5725 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5726 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5727 rp->verify_no_references_recorded(); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5728 assert(!rp->discovery_enabled(), "should have been disabled"); |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5729 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5730 // FIXME |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5731 // 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
|
5732 // Should we do that here also? We could, but it is a serial operation |
10405 | 5733 // and could significantly increase the pause time. |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5734 |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5735 double ref_enq_time = os::elapsedTime() - ref_enq_start; |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5736 g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5737 } |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5738 |
10405 | 5739 void G1CollectedHeap::evacuate_collection_set(EvacuationInfo& evacuation_info) { |
4781
bacb651cf5bf
7113006: G1: excessive ergo output when an evac failure happens
tonyp
parents:
4728
diff
changeset
|
5740 _expand_heap_after_alloc_failure = true; |
10405 | 5741 _evacuation_failed = false; |
342 | 5742 |
6629
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
5743 // Should G1EvacuationFailureALot be in effect for this GC? |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
5744 NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();) |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
5745 |
342 | 5746 g1_rem_set()->prepare_for_oops_into_collection_set_do(); |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5747 |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5748 // Disable the hot card cache. |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5749 G1HotCardCache* hot_card_cache = _cg1r->hot_card_cache(); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5750 hot_card_cache->reset_hot_cache_claimed_index(); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5751 hot_card_cache->set_use_cache(false); |
889 | 5752 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5753 uint n_workers; |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5754 if (G1CollectedHeap::use_parallel_gc_threads()) { |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5755 n_workers = |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5756 AdaptiveSizePolicy::calc_active_workers(workers()->total_workers(), |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5757 workers()->active_workers(), |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5758 Threads::number_of_non_daemon_threads()); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5759 assert(UseDynamicNumberOfGCThreads || |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5760 n_workers == workers()->total_workers(), |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5761 "If not dynamic should be using all the workers"); |
4711 | 5762 workers()->set_active_workers(n_workers); |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5763 set_par_threads(n_workers); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5764 } else { |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5765 assert(n_par_threads() == 0, |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5766 "Should be the original non-parallel value"); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5767 n_workers = 1; |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5768 } |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5769 |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5770 G1ParTask g1_par_task(this, _task_queues); |
342 | 5771 |
5772 init_for_evac_failure(NULL); | |
5773 | |
5774 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
|
5775 |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5776 assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty"); |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5777 double start_par_time_sec = os::elapsedTime(); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5778 double end_par_time_sec; |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5779 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5780 { |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
890
diff
changeset
|
5781 StrongRootsScope srs(this); |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5782 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5783 if (G1CollectedHeap::use_parallel_gc_threads()) { |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5784 // The individual threads will set their evac-failure closures. |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5785 if (ParallelGCVerbose) G1ParScanThreadState::print_termination_stats_hdr(); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5786 // These tasks use ShareHeap::_process_strong_tasks |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5787 assert(UseDynamicNumberOfGCThreads || |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5788 workers()->active_workers() == workers()->total_workers(), |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5789 "If not dynamic should be using all the workers"); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5790 workers()->run_task(&g1_par_task); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5791 } else { |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5792 g1_par_task.set_for_termination(n_workers); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5793 g1_par_task.work(0); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5794 } |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5795 end_par_time_sec = os::elapsedTime(); |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5796 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5797 // Closing the inner scope will execute the destructor |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5798 // for the StrongRootsScope object. We record the current |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5799 // elapsed time before closing the scope so that time |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5800 // taken for the SRS destructor is NOT included in the |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5801 // reported parallel time. |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5802 } |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5803 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5804 double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0; |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5805 g1_policy()->phase_times()->record_par_time(par_time_ms); |
5986
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5806 |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5807 double code_root_fixup_time_ms = |
500023bd0818
7143511: G1: Another instance of high GC Worker Other time (50ms)
johnc
parents:
5963
diff
changeset
|
5808 (os::elapsedTime() - end_par_time_sec) * 1000.0; |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
5809 g1_policy()->phase_times()->record_code_root_fixup_time(code_root_fixup_time_ms); |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
5810 |
342 | 5811 set_par_threads(0); |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
5812 |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5813 // Process any discovered reference objects - we have |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5814 // to do this _before_ we retire the GC alloc regions |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5815 // as we may have to copy some 'reachable' referent |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5816 // objects (and their reachable sub-graphs) that were |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5817 // not copied during the pause. |
6819 | 5818 process_discovered_references(n_workers); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5819 |
1974
fd1d227ef1b9
6983204: G1: Nightly test nsk/regression/b4958615 failing with +ExplicitGCInvokesConcurrent
johnc
parents:
1973
diff
changeset
|
5820 // Weak root processing. |
342 | 5821 { |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5822 G1STWIsAliveClosure is_alive(this); |
342 | 5823 G1KeepAliveClosure keep_alive(this); |
5824 JNIHandles::weak_oops_do(&is_alive, &keep_alive); | |
5825 } | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5826 |
10405 | 5827 release_gc_alloc_regions(n_workers, evacuation_info); |
342 | 5828 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
|
5829 |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5830 // Reset and re-enable the hot card cache. |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5831 // Note the counts for the cards in the regions in the |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5832 // collection set are reset when the collection set is freed. |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5833 hot_card_cache->reset_hot_cache(); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5834 hot_card_cache->set_use_cache(true); |
342 | 5835 |
12080 | 5836 // Migrate the strong code roots attached to each region in |
5837 // the collection set. Ideally we would like to do this | |
5838 // after we have finished the scanning/evacuation of the | |
5839 // strong code roots for a particular heap region. | |
5840 migrate_strong_code_roots(); | |
5841 | |
5842 if (g1_policy()->during_initial_mark_pause()) { | |
5843 // Reset the claim values set during marking the strong code roots | |
5844 reset_heap_region_claim_values(); | |
5845 } | |
5846 | |
342 | 5847 finalize_for_evac_failure(); |
5848 | |
5849 if (evacuation_failed()) { | |
5850 remove_self_forwarding_pointers(); | |
6629
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
5851 |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
5852 // Reset the G1EvacuationFailureALot counters and flags |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
5853 // Note: the values are reset only when an actual |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
5854 // evacuation failure occurs. |
c9814fadeb38
7041879: G1: introduce stress testing parameter to cause frequent evacuation failures
johnc
parents:
6628
diff
changeset
|
5855 NOT_PRODUCT(reset_evacuation_should_fail();) |
342 | 5856 } |
5857 | |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5858 // Enqueue any remaining references remaining on the STW |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5859 // reference processor's discovered lists. We need to do |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5860 // this after the card table is cleaned (and verified) as |
10405 | 5861 // the act of enqueueing entries on to the pending list |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5862 // will log these updates (and dirty their associated |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5863 // cards). We need these updates logged to update any |
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5864 // RSets. |
6819 | 5865 enqueue_discovered_references(n_workers); |
3979
4dfb2df418f2
6484982: G1: process references during evacuation pauses
johnc
parents:
3973
diff
changeset
|
5866 |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5867 if (G1DeferredRSUpdate) { |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5868 RedirtyLoggedCardTableEntryFastClosure redirty; |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5869 dirty_card_queue_set().set_closure(&redirty); |
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5870 dirty_card_queue_set().apply_closure_to_all_completed_buffers(); |
1111 | 5871 |
5872 DirtyCardQueueSet& dcq = JavaThread::dirty_card_queue_set(); | |
5873 dcq.merge_bufferlists(&dirty_card_queue_set()); | |
616
4f360ec815ba
6720309: G1: don't synchronously update RSet during evacuation pauses
iveresov
parents:
595
diff
changeset
|
5874 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
|
5875 } |
342 | 5876 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); |
5877 } | |
5878 | |
2173 | 5879 void G1CollectedHeap::free_region_if_empty(HeapRegion* hr, |
2152 | 5880 size_t* pre_used, |
5881 FreeRegionList* free_list, | |
4072 | 5882 OldRegionSet* old_proxy_set, |
2152 | 5883 HumongousRegionSet* humongous_proxy_set, |
2173 | 5884 HRRSCleanupTask* hrrs_cleanup_task, |
2152 | 5885 bool par) { |
5886 if (hr->used() > 0 && hr->max_live_bytes() == 0 && !hr->is_young()) { | |
5887 if (hr->isHumongous()) { | |
5888 assert(hr->startsHumongous(), "we should only see starts humongous"); | |
5889 free_humongous_region(hr, pre_used, free_list, humongous_proxy_set, par); | |
5890 } else { | |
4072 | 5891 _old_set.remove_with_proxy(hr, old_proxy_set); |
2152 | 5892 free_region(hr, pre_used, free_list, par); |
342 | 5893 } |
2173 | 5894 } else { |
5895 hr->rem_set()->do_cleanup_work(hrrs_cleanup_task); | |
342 | 5896 } |
5897 } | |
5898 | |
2152 | 5899 void G1CollectedHeap::free_region(HeapRegion* hr, |
5900 size_t* pre_used, | |
5901 FreeRegionList* free_list, | |
5902 bool par) { | |
5903 assert(!hr->isHumongous(), "this is only for non-humongous regions"); | |
5904 assert(!hr->is_empty(), "the region should not be empty"); | |
5905 assert(free_list != NULL, "pre-condition"); | |
5906 | |
10246
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5907 // Clear the card counts for this region. |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5908 // Note: we only need to do this if the region is not young |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5909 // (since we don't refine cards in young regions). |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5910 if (!hr->is_young()) { |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5911 _cg1r->hot_card_cache()->reset_card_counts(hr); |
194f52aa2f23
7176479: G1: JVM crashes on T5-8 system with 1.5 TB heap
johnc
parents:
10242
diff
changeset
|
5912 } |
2152 | 5913 *pre_used += hr->used(); |
5914 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
|
5915 free_list->add_as_head(hr); |
2152 | 5916 } |
5917 | |
5918 void G1CollectedHeap::free_humongous_region(HeapRegion* hr, | |
5919 size_t* pre_used, | |
5920 FreeRegionList* free_list, | |
5921 HumongousRegionSet* humongous_proxy_set, | |
5922 bool par) { | |
5923 assert(hr->startsHumongous(), "this is only for starts humongous regions"); | |
5924 assert(free_list != NULL, "pre-condition"); | |
5925 assert(humongous_proxy_set != NULL, "pre-condition"); | |
5926 | |
5927 size_t hr_used = hr->used(); | |
5928 size_t hr_capacity = hr->capacity(); | |
5929 size_t hr_pre_used = 0; | |
5930 _humongous_set.remove_with_proxy(hr, humongous_proxy_set); | |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
5931 // We need to read this before we make the region non-humongous, |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
5932 // otherwise the information will be gone. |
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
5933 uint last_index = hr->last_hc_index(); |
2152 | 5934 hr->set_notHumongous(); |
5935 free_region(hr, &hr_pre_used, free_list, par); | |
5936 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
5937 uint i = hr->hrs_index() + 1; |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
5938 while (i < last_index) { |
3766 | 5939 HeapRegion* curr_hr = region_at(i); |
6254
a2f7274eb6ef
7114678: G1: various small fixes, code cleanup, and refactoring
tonyp
parents:
6220
diff
changeset
|
5940 assert(curr_hr->continuesHumongous(), "invariant"); |
2152 | 5941 curr_hr->set_notHumongous(); |
5942 free_region(curr_hr, &hr_pre_used, free_list, par); | |
5943 i += 1; | |
5944 } | |
5945 assert(hr_pre_used == hr_used, | |
5946 err_msg("hr_pre_used: "SIZE_FORMAT" and hr_used: "SIZE_FORMAT" " | |
5947 "should be the same", hr_pre_used, hr_used)); | |
5948 *pre_used += hr_pre_used; | |
5949 } | |
5950 | |
5951 void G1CollectedHeap::update_sets_after_freeing_regions(size_t pre_used, | |
5952 FreeRegionList* free_list, | |
4072 | 5953 OldRegionSet* old_proxy_set, |
2152 | 5954 HumongousRegionSet* humongous_proxy_set, |
5955 bool par) { | |
5956 if (pre_used > 0) { | |
5957 Mutex* lock = (par) ? ParGCRareEvent_lock : NULL; | |
342 | 5958 MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag); |
2152 | 5959 assert(_summary_bytes_used >= pre_used, |
5960 err_msg("invariant: _summary_bytes_used: "SIZE_FORMAT" " | |
5961 "should be >= pre_used: "SIZE_FORMAT, | |
5962 _summary_bytes_used, pre_used)); | |
342 | 5963 _summary_bytes_used -= pre_used; |
2152 | 5964 } |
5965 if (free_list != NULL && !free_list->is_empty()) { | |
5966 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
|
5967 _free_list.add_as_head(free_list); |
2152 | 5968 } |
4072 | 5969 if (old_proxy_set != NULL && !old_proxy_set->is_empty()) { |
5970 MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); | |
5971 _old_set.update_from_proxy(old_proxy_set); | |
5972 } | |
2152 | 5973 if (humongous_proxy_set != NULL && !humongous_proxy_set->is_empty()) { |
5974 MutexLockerEx x(OldSets_lock, Mutex::_no_safepoint_check_flag); | |
5975 _humongous_set.update_from_proxy(humongous_proxy_set); | |
342 | 5976 } |
5977 } | |
5978 | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5979 class G1ParCleanupCTTask : public AbstractGangTask { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5980 CardTableModRefBS* _ct_bs; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5981 G1CollectedHeap* _g1h; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5982 HeapRegion* volatile _su_head; |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5983 public: |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5984 G1ParCleanupCTTask(CardTableModRefBS* ct_bs, |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
5985 G1CollectedHeap* g1h) : |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5986 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
|
5987 _ct_bs(ct_bs), _g1h(g1h) { } |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5988 |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
5989 void work(uint worker_id) { |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5990 HeapRegion* r; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5991 while (r = _g1h->pop_dirty_cards_region()) { |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5992 clear_cards(r); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5993 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5994 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
5995 |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5996 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
|
5997 // 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
|
5998 if (!r->is_survivor()) { |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
5999 _ct_bs->clear(MemRegion(r->bottom(), r->end())); |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
6000 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
6001 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
6002 }; |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
6003 |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6004 #ifndef PRODUCT |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6005 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
|
6006 G1CollectedHeap* _g1h; |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6007 CardTableModRefBS* _ct_bs; |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6008 public: |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
6009 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
|
6010 : _g1h(g1h), _ct_bs(ct_bs) { } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6011 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
|
6012 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
|
6013 _g1h->verify_dirty_region(r); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6014 } else { |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
6015 _g1h->verify_not_dirty_region(r); |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6016 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6017 return false; |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6018 } |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6019 }; |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6020 |
3317
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
6021 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
|
6022 // 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
|
6023 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
|
6024 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
|
6025 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
|
6026 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
6027 |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
6028 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
|
6029 // 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
|
6030 // 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
|
6031 // 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
|
6032 // 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
|
6033 // 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
|
6034 // 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
|
6035 // is dirty. |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
6036 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
|
6037 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
|
6038 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
|
6039 } |
063382f9b575
7035144: G1: nightly failure: Non-dirty cards in region that should be dirty (failures still exist...)
tonyp
parents:
3293
diff
changeset
|
6040 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6041 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
|
6042 CardTableModRefBS* ct_bs = (CardTableModRefBS*) barrier_set(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6043 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
|
6044 verify_dirty_region(hr); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6045 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6046 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6047 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6048 void G1CollectedHeap::verify_dirty_young_regions() { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6049 verify_dirty_young_list(_young_list->first_region()); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6050 } |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6051 #endif |
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6052 |
342 | 6053 void G1CollectedHeap::cleanUpCardTable() { |
6054 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); | |
6055 double start = os::elapsedTime(); | |
6056 | |
4023 | 6057 { |
6058 // Iterate over the dirty cards region list. | |
6059 G1ParCleanupCTTask cleanup_task(ct_bs, this); | |
6060 | |
4711 | 6061 if (G1CollectedHeap::use_parallel_gc_threads()) { |
6062 set_par_threads(); | |
4023 | 6063 workers()->run_task(&cleanup_task); |
6064 set_par_threads(0); | |
6065 } else { | |
6066 while (_dirty_cards_region_list) { | |
6067 HeapRegion* r = _dirty_cards_region_list; | |
6068 cleanup_task.clear_cards(r); | |
6069 _dirty_cards_region_list = r->get_next_dirty_cards_region(); | |
6070 if (_dirty_cards_region_list == r) { | |
6071 // The last region. | |
6072 _dirty_cards_region_list = NULL; | |
6073 } | |
6074 r->set_next_dirty_cards_region(NULL); | |
796
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
6075 } |
29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
apetrusenko
parents:
794
diff
changeset
|
6076 } |
4023 | 6077 #ifndef PRODUCT |
6078 if (G1VerifyCTCleanup || VerifyAfterGC) { | |
6079 G1VerifyCardTableCleanup cleanup_verifier(this, ct_bs); | |
6080 heap_region_iterate(&cleanup_verifier); | |
6081 } | |
6082 #endif | |
940
8624da129f0b
6841313: G1: dirty cards of survivor regions in parallel
apetrusenko
parents:
936
diff
changeset
|
6083 } |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6084 |
342 | 6085 double elapsed = os::elapsedTime() - start; |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
6086 g1_policy()->phase_times()->record_clear_ct_time(elapsed * 1000.0); |
342 | 6087 } |
6088 | |
10405 | 6089 void G1CollectedHeap::free_collection_set(HeapRegion* cs_head, EvacuationInfo& evacuation_info) { |
2152 | 6090 size_t pre_used = 0; |
6091 FreeRegionList local_free_list("Local List for CSet Freeing"); | |
6092 | |
342 | 6093 double young_time_ms = 0.0; |
6094 double non_young_time_ms = 0.0; | |
6095 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6096 // 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
|
6097 // 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
|
6098 // 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
|
6099 _young_list->clear(); |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6100 |
342 | 6101 G1CollectorPolicy* policy = g1_policy(); |
6102 | |
6103 double start_sec = os::elapsedTime(); | |
6104 bool non_young = true; | |
6105 | |
6106 HeapRegion* cur = cs_head; | |
6107 int age_bound = -1; | |
6108 size_t rs_lengths = 0; | |
6109 | |
6110 while (cur != NULL) { | |
2361 | 6111 assert(!is_on_master_free_list(cur), "sanity"); |
342 | 6112 if (non_young) { |
6113 if (cur->is_young()) { | |
6114 double end_sec = os::elapsedTime(); | |
6115 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
6116 non_young_time_ms += elapsed_ms; | |
6117 | |
6118 start_sec = os::elapsedTime(); | |
6119 non_young = false; | |
6120 } | |
6121 } else { | |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6122 if (!cur->is_young()) { |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6123 double end_sec = os::elapsedTime(); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6124 double elapsed_ms = (end_sec - start_sec) * 1000.0; |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6125 young_time_ms += elapsed_ms; |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6126 |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6127 start_sec = os::elapsedTime(); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6128 non_young = true; |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6129 } |
342 | 6130 } |
6131 | |
6132 rs_lengths += cur->rem_set()->occupied(); | |
6133 | |
6134 HeapRegion* next = cur->next_in_collection_set(); | |
6135 assert(cur->in_collection_set(), "bad CS"); | |
6136 cur->set_next_in_collection_set(NULL); | |
6137 cur->set_in_collection_set(false); | |
6138 | |
6139 if (cur->is_young()) { | |
6140 int index = cur->young_index_in_cset(); | |
4090
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
6141 assert(index != -1, "invariant"); |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
6142 assert((uint) index < policy->young_cset_region_length(), "invariant"); |
342 | 6143 size_t words_survived = _surviving_young_words[index]; |
6144 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
|
6145 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6146 // 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
|
6147 // (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
|
6148 // 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
|
6149 // _next_young_region field. |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6150 cur->set_next_young_region(NULL); |
342 | 6151 } else { |
6152 int index = cur->young_index_in_cset(); | |
4090
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
6153 assert(index == -1, "invariant"); |
342 | 6154 } |
6155 | |
6156 assert( (cur->is_young() && cur->young_index_in_cset() > -1) || | |
6157 (!cur->is_young() && cur->young_index_in_cset() == -1), | |
6158 "invariant" ); | |
6159 | |
6160 if (!cur->evacuation_failed()) { | |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6161 MemRegion used_mr = cur->used_region(); |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6162 |
342 | 6163 // And the region is empty. |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6164 assert(!used_mr.is_empty(), "Should not have empty regions in a CS."); |
2152 | 6165 free_region(cur, &pre_used, &local_free_list, false /* par */); |
342 | 6166 } else { |
6167 cur->uninstall_surv_rate_group(); | |
4090
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
6168 if (cur->is_young()) { |
342 | 6169 cur->set_young_index_in_cset(-1); |
4090
a88de71c4e3a
7097002: G1: remove a lot of unused / redundant code from the G1CollectorPolicy class
tonyp
parents:
4073
diff
changeset
|
6170 } |
342 | 6171 cur->set_not_young(); |
6172 cur->set_evacuation_failed(false); | |
4072 | 6173 // The region is now considered to be old. |
6174 _old_set.add(cur); | |
10405 | 6175 evacuation_info.increment_collectionset_used_after(cur->used()); |
342 | 6176 } |
6177 cur = next; | |
6178 } | |
6179 | |
10405 | 6180 evacuation_info.set_regions_freed(local_free_list.length()); |
342 | 6181 policy->record_max_rs_lengths(rs_lengths); |
6182 policy->cset_regions_freed(); | |
6183 | |
6184 double end_sec = os::elapsedTime(); | |
6185 double elapsed_ms = (end_sec - start_sec) * 1000.0; | |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6186 |
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6187 if (non_young) { |
342 | 6188 non_young_time_ms += elapsed_ms; |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6189 } else { |
342 | 6190 young_time_ms += elapsed_ms; |
4097
dc467e8b2c5e
7112743: G1: Reduce overhead of marking closure during evacuation pauses
johnc
parents:
4095
diff
changeset
|
6191 } |
342 | 6192 |
2152 | 6193 update_sets_after_freeing_regions(pre_used, &local_free_list, |
4072 | 6194 NULL /* old_proxy_set */, |
2152 | 6195 NULL /* humongous_proxy_set */, |
6196 false /* par */); | |
6219
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
6197 policy->phase_times()->record_young_free_cset_time_ms(young_time_ms); |
922993931b3d
7178361: G1: Make sure that PrintGC and PrintGCDetails use the same timing for the GC pause
brutisso
parents:
6188
diff
changeset
|
6198 policy->phase_times()->record_non_young_free_cset_time_ms(non_young_time_ms); |
342 | 6199 } |
6200 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6201 // 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
|
6202 // 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
|
6203 // 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
|
6204 // 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
|
6205 // 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
|
6206 // 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
|
6207 // 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
|
6208 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6209 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
|
6210 HeapRegion* cur = cs_head; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6211 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6212 while (cur != NULL) { |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6213 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
|
6214 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
|
6215 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
|
6216 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
|
6217 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
|
6218 cur = next; |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6219 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6220 } |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6221 |
2152 | 6222 void G1CollectedHeap::set_free_regions_coming() { |
6223 if (G1ConcRegionFreeingVerbose) { | |
6224 gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : " | |
6225 "setting free regions coming"); | |
6226 } | |
6227 | |
6228 assert(!free_regions_coming(), "pre-condition"); | |
6229 _free_regions_coming = true; | |
342 | 6230 } |
6231 | |
2152 | 6232 void G1CollectedHeap::reset_free_regions_coming() { |
4837
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
6233 assert(free_regions_coming(), "pre-condition"); |
eff609af17d7
7127706: G1: re-enable survivors during the initial-mark pause
tonyp
parents:
4836
diff
changeset
|
6234 |
2152 | 6235 { |
6236 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); | |
6237 _free_regions_coming = false; | |
6238 SecondaryFreeList_lock->notify_all(); | |
6239 } | |
6240 | |
6241 if (G1ConcRegionFreeingVerbose) { | |
6242 gclog_or_tty->print_cr("G1ConcRegionFreeing [cm thread] : " | |
6243 "reset free regions coming"); | |
342 | 6244 } |
6245 } | |
6246 | |
2152 | 6247 void G1CollectedHeap::wait_while_free_regions_coming() { |
6248 // Most of the time we won't have to wait, so let's do a quick test | |
6249 // first before we take the lock. | |
6250 if (!free_regions_coming()) { | |
6251 return; | |
6252 } | |
6253 | |
6254 if (G1ConcRegionFreeingVerbose) { | |
6255 gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : " | |
6256 "waiting for free regions"); | |
342 | 6257 } |
6258 | |
6259 { | |
2152 | 6260 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); |
6261 while (free_regions_coming()) { | |
6262 SecondaryFreeList_lock->wait(Mutex::_no_safepoint_check_flag); | |
342 | 6263 } |
2152 | 6264 } |
6265 | |
6266 if (G1ConcRegionFreeingVerbose) { | |
6267 gclog_or_tty->print_cr("G1ConcRegionFreeing [other] : " | |
6268 "done waiting for free regions"); | |
6269 } | |
342 | 6270 } |
6271 | |
6272 void G1CollectedHeap::set_region_short_lived_locked(HeapRegion* hr) { | |
6273 assert(heap_lock_held_for_gc(), | |
6274 "the heap lock should already be held by or for this thread"); | |
6275 _young_list->push_region(hr); | |
6276 } | |
6277 | |
6278 class NoYoungRegionsClosure: public HeapRegionClosure { | |
6279 private: | |
6280 bool _success; | |
6281 public: | |
6282 NoYoungRegionsClosure() : _success(true) { } | |
6283 bool doHeapRegion(HeapRegion* r) { | |
6284 if (r->is_young()) { | |
6285 gclog_or_tty->print_cr("Region ["PTR_FORMAT", "PTR_FORMAT") tagged as young", | |
6286 r->bottom(), r->end()); | |
6287 _success = false; | |
6288 } | |
6289 return false; | |
6290 } | |
6291 bool success() { return _success; } | |
6292 }; | |
6293 | |
1394
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6294 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
|
6295 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
|
6296 |
1316cec51b4d
6819061: G1: eliminate serial Other times that are proportional to the collection set length
johnc
parents:
1391
diff
changeset
|
6297 if (check_heap) { |
342 | 6298 NoYoungRegionsClosure closure; |
6299 heap_region_iterate(&closure); | |
6300 ret = ret && closure.success(); | |
6301 } | |
6302 | |
6303 return ret; | |
6304 } | |
6305 | |
4072 | 6306 class TearDownRegionSetsClosure : public HeapRegionClosure { |
6307 private: | |
6308 OldRegionSet *_old_set; | |
2152 | 6309 |
342 | 6310 public: |
4072 | 6311 TearDownRegionSetsClosure(OldRegionSet* old_set) : _old_set(old_set) { } |
2152 | 6312 |
342 | 6313 bool doHeapRegion(HeapRegion* r) { |
4072 | 6314 if (r->is_empty()) { |
6315 // We ignore empty regions, we'll empty the free list afterwards | |
6316 } else if (r->is_young()) { | |
6317 // We ignore young regions, we'll empty the young list afterwards | |
6318 } else if (r->isHumongous()) { | |
6319 // We ignore humongous regions, we're not tearing down the | |
6320 // humongous region set | |
342 | 6321 } else { |
4072 | 6322 // The rest should be old |
6323 _old_set->remove(r); | |
342 | 6324 } |
6325 return false; | |
6326 } | |
6327 | |
4072 | 6328 ~TearDownRegionSetsClosure() { |
6329 assert(_old_set->is_empty(), "post-condition"); | |
2152 | 6330 } |
342 | 6331 }; |
6332 | |
4072 | 6333 void G1CollectedHeap::tear_down_region_sets(bool free_list_only) { |
6334 assert_at_safepoint(true /* should_be_vm_thread */); | |
6335 | |
6336 if (!free_list_only) { | |
6337 TearDownRegionSetsClosure cl(&_old_set); | |
6338 heap_region_iterate(&cl); | |
6339 | |
6340 // Need to do this after the heap iteration to be able to | |
6341 // recognize the young regions and ignore them during the iteration. | |
6342 _young_list->empty_list(); | |
6343 } | |
6344 _free_list.remove_all(); | |
6345 } | |
6346 | |
6347 class RebuildRegionSetsClosure : public HeapRegionClosure { | |
6348 private: | |
6349 bool _free_list_only; | |
6350 OldRegionSet* _old_set; | |
6351 FreeRegionList* _free_list; | |
6352 size_t _total_used; | |
6353 | |
6354 public: | |
6355 RebuildRegionSetsClosure(bool free_list_only, | |
6356 OldRegionSet* old_set, FreeRegionList* free_list) : | |
6357 _free_list_only(free_list_only), | |
6358 _old_set(old_set), _free_list(free_list), _total_used(0) { | |
6359 assert(_free_list->is_empty(), "pre-condition"); | |
6360 if (!free_list_only) { | |
6361 assert(_old_set->is_empty(), "pre-condition"); | |
6362 } | |
6363 } | |
6364 | |
6365 bool doHeapRegion(HeapRegion* r) { | |
6366 if (r->continuesHumongous()) { | |
6367 return false; | |
6368 } | |
6369 | |
6370 if (r->is_empty()) { | |
6371 // Add free regions to the free list | |
6372 _free_list->add_as_tail(r); | |
6373 } else if (!_free_list_only) { | |
6374 assert(!r->is_young(), "we should not come across young regions"); | |
6375 | |
6376 if (r->isHumongous()) { | |
6377 // We ignore humongous regions, we left the humongous set unchanged | |
6378 } else { | |
6379 // The rest should be old, add them to the old set | |
6380 _old_set->add(r); | |
6381 } | |
6382 _total_used += r->used(); | |
6383 } | |
6384 | |
6385 return false; | |
6386 } | |
6387 | |
6388 size_t total_used() { | |
6389 return _total_used; | |
6390 } | |
6391 }; | |
6392 | |
6393 void G1CollectedHeap::rebuild_region_sets(bool free_list_only) { | |
6394 assert_at_safepoint(true /* should_be_vm_thread */); | |
6395 | |
6396 RebuildRegionSetsClosure cl(free_list_only, &_old_set, &_free_list); | |
6397 heap_region_iterate(&cl); | |
6398 | |
6399 if (!free_list_only) { | |
6400 _summary_bytes_used = cl.total_used(); | |
6401 } | |
6402 assert(_summary_bytes_used == recalculate_used(), | |
6403 err_msg("inconsistent _summary_bytes_used, " | |
6404 "value: "SIZE_FORMAT" recalculated: "SIZE_FORMAT, | |
6405 _summary_bytes_used, recalculate_used())); | |
342 | 6406 } |
6407 | |
6408 void G1CollectedHeap::set_refine_cte_cl_concurrency(bool concurrent) { | |
6409 _refine_cte_cl->set_concurrent(concurrent); | |
6410 } | |
6411 | |
6412 bool G1CollectedHeap::is_in_closed_subset(const void* p) const { | |
6413 HeapRegion* hr = heap_region_containing(p); | |
6414 if (hr == NULL) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6629
diff
changeset
|
6415 return false; |
342 | 6416 } else { |
6417 return hr->is_in(p); | |
6418 } | |
6419 } | |
2152 | 6420 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6421 // 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
|
6422 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6423 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
|
6424 bool force) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6425 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
|
6426 assert(!force || g1_policy()->can_expand_young_list(), |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6427 "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
|
6428 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
|
6429 if (force || !young_list_full) { |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6430 HeapRegion* new_alloc_region = new_region(word_size, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6431 false /* do_expand */); |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6432 if (new_alloc_region != NULL) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6433 set_region_short_lived_locked(new_alloc_region); |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
6434 _hr_printer.alloc(new_alloc_region, G1HRPrinter::Eden, young_list_full); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6435 return new_alloc_region; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6436 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6437 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6438 return NULL; |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6439 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6440 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6441 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
|
6442 size_t allocated_bytes) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6443 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
|
6444 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
|
6445 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6446 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
|
6447 _summary_bytes_used += allocated_bytes; |
3778
5f6f2615433a
7049999: G1: Make the G1PrintHeapRegions output consistent and complete
tonyp
parents:
3777
diff
changeset
|
6448 _hr_printer.retire(alloc_region); |
3980
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
6449 // We update the eden sizes here, when the region is retired, |
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
6450 // instead of when it's allocated, since this is the point that its |
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
6451 // used space has been recored in _summary_bytes_used. |
8229bd737950
7075646: G1: fix inconsistencies in the monitoring data
tonyp
parents:
3979
diff
changeset
|
6452 g1mm()->update_eden_size(); |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6453 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6454 |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6455 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
|
6456 bool force) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6457 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
|
6458 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6459 |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6460 void G1CollectedHeap::set_par_threads() { |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6461 // Don't change the number of workers. Use the value previously set |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6462 // in the workgroup. |
4711 | 6463 assert(G1CollectedHeap::use_parallel_gc_threads(), "shouldn't be here otherwise"); |
4728
441e946dc1af
7121618: Change type of number of GC workers to unsigned int.
jmasa
parents:
4711
diff
changeset
|
6464 uint n_workers = workers()->active_workers(); |
4711 | 6465 assert(UseDynamicNumberOfGCThreads || |
4095
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6466 n_workers == workers()->total_workers(), |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6467 "Otherwise should be using the total number of workers"); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6468 if (n_workers == 0) { |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6469 assert(false, "Should have been set in prior evacuation pause."); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6470 n_workers = ParallelGCThreads; |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6471 workers()->set_active_workers(n_workers); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6472 } |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6473 set_par_threads(n_workers); |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6474 } |
bca17e38de00
6593758: RFE: Enhance GC ergonomics to dynamically choose ParallelGCThreads
jmasa
parents:
4090
diff
changeset
|
6475 |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6476 void MutatorAllocRegion::retire_region(HeapRegion* alloc_region, |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6477 size_t allocated_bytes) { |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6478 _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
|
6479 } |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6480 |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6481 // 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
|
6482 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6483 HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size, |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
6484 uint count, |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6485 GCAllocPurpose ap) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6486 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
|
6487 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6488 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
|
6489 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
|
6490 true /* do_expand */); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6491 if (new_alloc_region != NULL) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6492 // 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
|
6493 // 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
|
6494 // for survivors too. |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6495 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
|
6496 if (ap == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6497 new_alloc_region->set_survivor(); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6498 _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
|
6499 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6500 _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
|
6501 } |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
6502 bool during_im = g1_policy()->during_initial_mark_pause(); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
6503 new_alloc_region->note_start_of_copying(during_im); |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6504 return new_alloc_region; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6505 } else { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6506 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
|
6507 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6508 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6509 return NULL; |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6510 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6511 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6512 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
|
6513 size_t allocated_bytes, |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6514 GCAllocPurpose ap) { |
4787
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
6515 bool during_im = g1_policy()->during_initial_mark_pause(); |
2ace1c4ee8da
6888336: G1: avoid explicitly marking and pushing objects in survivor spaces
tonyp
parents:
4785
diff
changeset
|
6516 alloc_region->note_end_of_copying(during_im); |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6517 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
|
6518 if (ap == GCAllocForSurvived) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6519 young_list()->add_survivor_region(alloc_region); |
4072 | 6520 } else { |
6521 _old_set.add(alloc_region); | |
3830
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6522 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6523 _hr_printer.retire(alloc_region); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6524 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6525 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6526 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
|
6527 bool force) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6528 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
|
6529 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
|
6530 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6531 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6532 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
|
6533 size_t allocated_bytes) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6534 _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
|
6535 GCAllocForSurvived); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6536 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6537 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6538 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
|
6539 bool force) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6540 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
|
6541 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
|
6542 } |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6543 |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6544 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
|
6545 size_t allocated_bytes) { |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6546 _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
|
6547 GCAllocForTenured); |
f44782f04dd4
7039627: G1: avoid BOT updates for survivor allocations and dirty survivor regions incrementally
tonyp
parents:
3824
diff
changeset
|
6548 } |
2433
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6549 // Heap region set verification |
abdfc822206f
7023069: G1: Introduce symmetric locking in the slow allocation path
tonyp
parents:
2432
diff
changeset
|
6550 |
2152 | 6551 class VerifyRegionListsClosure : public HeapRegionClosure { |
6552 private: | |
4072 | 6553 FreeRegionList* _free_list; |
6554 OldRegionSet* _old_set; | |
2152 | 6555 HumongousRegionSet* _humongous_set; |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
6556 uint _region_count; |
2152 | 6557 |
6558 public: | |
4072 | 6559 VerifyRegionListsClosure(OldRegionSet* old_set, |
6560 HumongousRegionSet* humongous_set, | |
2152 | 6561 FreeRegionList* free_list) : |
4072 | 6562 _old_set(old_set), _humongous_set(humongous_set), |
6563 _free_list(free_list), _region_count(0) { } | |
2152 | 6564 |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
6565 uint region_count() { return _region_count; } |
2152 | 6566 |
6567 bool doHeapRegion(HeapRegion* hr) { | |
6568 _region_count += 1; | |
6569 | |
6570 if (hr->continuesHumongous()) { | |
6571 return false; | |
6572 } | |
6573 | |
6574 if (hr->is_young()) { | |
6575 // TODO | |
6576 } else if (hr->startsHumongous()) { | |
6577 _humongous_set->verify_next_region(hr); | |
6578 } else if (hr->is_empty()) { | |
6579 _free_list->verify_next_region(hr); | |
4072 | 6580 } else { |
6581 _old_set->verify_next_region(hr); | |
2152 | 6582 } |
6583 return false; | |
6584 } | |
6585 }; | |
6586 | |
6010
720b6a76dd9d
7157073: G1: type change size_t -> uint for region counts / indexes
tonyp
parents:
6008
diff
changeset
|
6587 HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index, |
3766 | 6588 HeapWord* bottom) { |
6589 HeapWord* end = bottom + HeapRegion::GrainWords; | |
6590 MemRegion mr(bottom, end); | |
6591 assert(_g1_reserved.contains(mr), "invariant"); | |
6592 // This might return NULL if the allocation fails | |
6754
8fbf05030e24
7016955: G1: remove the is_zeroed parameter from the HeapRegion constructor
johnc
parents:
6752
diff
changeset
|
6593 return new HeapRegion(hrs_index, _bot_shared, mr); |
3766 | 6594 } |
6595 | |
2152 | 6596 void G1CollectedHeap::verify_region_sets() { |
6597 assert_heap_locked_or_at_safepoint(true /* should_be_vm_thread */); | |
6598 | |
6599 // First, check the explicit lists. | |
6600 _free_list.verify(); | |
6601 { | |
6602 // Given that a concurrent operation might be adding regions to | |
6603 // the secondary free list we have to take the lock before | |
6604 // verifying it. | |
6605 MutexLockerEx x(SecondaryFreeList_lock, Mutex::_no_safepoint_check_flag); | |
6606 _secondary_free_list.verify(); | |
6607 } | |
4072 | 6608 _old_set.verify(); |
2152 | 6609 _humongous_set.verify(); |
6610 | |
6611 // If a concurrent region freeing operation is in progress it will | |
6612 // be difficult to correctly attributed any free regions we come | |
6613 // across to the correct free list given that they might belong to | |
6614 // one of several (free_list, secondary_free_list, any local lists, | |
6615 // etc.). So, if that's the case we will skip the rest of the | |
6616 // verification operation. Alternatively, waiting for the concurrent | |
6617 // operation to complete will have a non-trivial effect on the GC's | |
6618 // operation (no concurrent operation will last longer than the | |
6619 // interval between two calls to verification) and it might hide | |
6620 // any issues that we would like to catch during testing. | |
6621 if (free_regions_coming()) { | |
6622 return; | |
6623 } | |
6624 | |
2361 | 6625 // Make sure we append the secondary_free_list on the free_list so |
6626 // that all free regions we will come across can be safely | |
6627 // attributed to the free_list. | |
6628 append_secondary_free_list_if_not_empty_with_lock(); | |
2152 | 6629 |
6630 // Finally, make sure that the region accounting in the lists is | |
6631 // consistent with what we see in the heap. | |
4072 | 6632 _old_set.verify_start(); |
2152 | 6633 _humongous_set.verify_start(); |
6634 _free_list.verify_start(); | |
6635 | |
4072 | 6636 VerifyRegionListsClosure cl(&_old_set, &_humongous_set, &_free_list); |
2152 | 6637 heap_region_iterate(&cl); |
6638 | |
4072 | 6639 _old_set.verify_end(); |
2152 | 6640 _humongous_set.verify_end(); |
6641 _free_list.verify_end(); | |
342 | 6642 } |
12080 | 6643 |
6644 // Optimized nmethod scanning | |
6645 | |
6646 class RegisterNMethodOopClosure: public OopClosure { | |
6647 G1CollectedHeap* _g1h; | |
6648 nmethod* _nm; | |
6649 | |
6650 template <class T> void do_oop_work(T* p) { | |
6651 T heap_oop = oopDesc::load_heap_oop(p); | |
6652 if (!oopDesc::is_null(heap_oop)) { | |
6653 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); | |
6654 HeapRegion* hr = _g1h->heap_region_containing(obj); | |
6655 assert(!hr->isHumongous(), "code root in humongous region?"); | |
6656 | |
6657 // HeapRegion::add_strong_code_root() avoids adding duplicate | |
6658 // entries but having duplicates is OK since we "mark" nmethods | |
6659 // as visited when we scan the strong code root lists during the GC. | |
6660 hr->add_strong_code_root(_nm); | |
6661 assert(hr->rem_set()->strong_code_roots_list_contains(_nm), "add failed?"); | |
6662 } | |
6663 } | |
6664 | |
6665 public: | |
6666 RegisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : | |
6667 _g1h(g1h), _nm(nm) {} | |
6668 | |
6669 void do_oop(oop* p) { do_oop_work(p); } | |
6670 void do_oop(narrowOop* p) { do_oop_work(p); } | |
6671 }; | |
6672 | |
6673 class UnregisterNMethodOopClosure: public OopClosure { | |
6674 G1CollectedHeap* _g1h; | |
6675 nmethod* _nm; | |
6676 | |
6677 template <class T> void do_oop_work(T* p) { | |
6678 T heap_oop = oopDesc::load_heap_oop(p); | |
6679 if (!oopDesc::is_null(heap_oop)) { | |
6680 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); | |
6681 HeapRegion* hr = _g1h->heap_region_containing(obj); | |
6682 assert(!hr->isHumongous(), "code root in humongous region?"); | |
6683 hr->remove_strong_code_root(_nm); | |
6684 assert(!hr->rem_set()->strong_code_roots_list_contains(_nm), "remove failed?"); | |
6685 } | |
6686 } | |
6687 | |
6688 public: | |
6689 UnregisterNMethodOopClosure(G1CollectedHeap* g1h, nmethod* nm) : | |
6690 _g1h(g1h), _nm(nm) {} | |
6691 | |
6692 void do_oop(oop* p) { do_oop_work(p); } | |
6693 void do_oop(narrowOop* p) { do_oop_work(p); } | |
6694 }; | |
6695 | |
6696 void G1CollectedHeap::register_nmethod(nmethod* nm) { | |
6697 CollectedHeap::register_nmethod(nm); | |
6698 | |
6699 guarantee(nm != NULL, "sanity"); | |
6700 RegisterNMethodOopClosure reg_cl(this, nm); | |
6701 nm->oops_do(®_cl); | |
6702 } | |
6703 | |
6704 void G1CollectedHeap::unregister_nmethod(nmethod* nm) { | |
6705 CollectedHeap::unregister_nmethod(nm); | |
6706 | |
6707 guarantee(nm != NULL, "sanity"); | |
6708 UnregisterNMethodOopClosure reg_cl(this, nm); | |
6709 nm->oops_do(®_cl, true); | |
6710 } | |
6711 | |
6712 class MigrateCodeRootsHeapRegionClosure: public HeapRegionClosure { | |
6713 public: | |
6714 bool doHeapRegion(HeapRegion *hr) { | |
6715 assert(!hr->isHumongous(), "humongous region in collection set?"); | |
6716 hr->migrate_strong_code_roots(); | |
6717 return false; | |
6718 } | |
6719 }; | |
6720 | |
6721 void G1CollectedHeap::migrate_strong_code_roots() { | |
6722 MigrateCodeRootsHeapRegionClosure cl; | |
6723 double migrate_start = os::elapsedTime(); | |
6724 collection_set_iterate(&cl); | |
6725 double migration_time_ms = (os::elapsedTime() - migrate_start) * 1000.0; | |
6726 g1_policy()->phase_times()->record_strong_code_root_migration_time(migration_time_ms); | |
6727 } | |
6728 | |
6729 // Mark all the code roots that point into regions *not* in the | |
6730 // collection set. | |
6731 // | |
6732 // Note we do not want to use a "marking" CodeBlobToOopClosure while | |
6733 // walking the the code roots lists of regions not in the collection | |
6734 // set. Suppose we have an nmethod (M) that points to objects in two | |
6735 // separate regions - one in the collection set (R1) and one not (R2). | |
6736 // Using a "marking" CodeBlobToOopClosure here would result in "marking" | |
6737 // nmethod M when walking the code roots for R1. When we come to scan | |
6738 // the code roots for R2, we would see that M is already marked and it | |
6739 // would be skipped and the objects in R2 that are referenced from M | |
6740 // would not be evacuated. | |
6741 | |
6742 class MarkStrongCodeRootCodeBlobClosure: public CodeBlobClosure { | |
6743 | |
6744 class MarkStrongCodeRootOopClosure: public OopClosure { | |
6745 ConcurrentMark* _cm; | |
6746 HeapRegion* _hr; | |
6747 uint _worker_id; | |
6748 | |
6749 template <class T> void do_oop_work(T* p) { | |
6750 T heap_oop = oopDesc::load_heap_oop(p); | |
6751 if (!oopDesc::is_null(heap_oop)) { | |
6752 oop obj = oopDesc::decode_heap_oop_not_null(heap_oop); | |
6753 // Only mark objects in the region (which is assumed | |
6754 // to be not in the collection set). | |
6755 if (_hr->is_in(obj)) { | |
6756 _cm->grayRoot(obj, (size_t) obj->size(), _worker_id); | |
6757 } | |
6758 } | |
6759 } | |
6760 | |
6761 public: | |
6762 MarkStrongCodeRootOopClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id) : | |
6763 _cm(cm), _hr(hr), _worker_id(worker_id) { | |
6764 assert(!_hr->in_collection_set(), "sanity"); | |
6765 } | |
6766 | |
6767 void do_oop(narrowOop* p) { do_oop_work(p); } | |
6768 void do_oop(oop* p) { do_oop_work(p); } | |
6769 }; | |
6770 | |
6771 MarkStrongCodeRootOopClosure _oop_cl; | |
6772 | |
6773 public: | |
6774 MarkStrongCodeRootCodeBlobClosure(ConcurrentMark* cm, HeapRegion* hr, uint worker_id): | |
6775 _oop_cl(cm, hr, worker_id) {} | |
6776 | |
6777 void do_code_blob(CodeBlob* cb) { | |
6778 nmethod* nm = (cb == NULL) ? NULL : cb->as_nmethod_or_null(); | |
6779 if (nm != NULL) { | |
6780 nm->oops_do(&_oop_cl); | |
6781 } | |
6782 } | |
6783 }; | |
6784 | |
6785 class MarkStrongCodeRootsHRClosure: public HeapRegionClosure { | |
6786 G1CollectedHeap* _g1h; | |
6787 uint _worker_id; | |
6788 | |
6789 public: | |
6790 MarkStrongCodeRootsHRClosure(G1CollectedHeap* g1h, uint worker_id) : | |
6791 _g1h(g1h), _worker_id(worker_id) {} | |
6792 | |
6793 bool doHeapRegion(HeapRegion *hr) { | |
6794 HeapRegionRemSet* hrrs = hr->rem_set(); | |
6795 if (hr->isHumongous()) { | |
6796 // Code roots should never be attached to a humongous region | |
6797 assert(hrrs->strong_code_roots_list_length() == 0, "sanity"); | |
6798 return false; | |
6799 } | |
6800 | |
6801 if (hr->in_collection_set()) { | |
6802 // Don't mark code roots into regions in the collection set here. | |
6803 // They will be marked when we scan them. | |
6804 return false; | |
6805 } | |
6806 | |
6807 MarkStrongCodeRootCodeBlobClosure cb_cl(_g1h->concurrent_mark(), hr, _worker_id); | |
6808 hr->strong_code_roots_do(&cb_cl); | |
6809 return false; | |
6810 } | |
6811 }; | |
6812 | |
6813 void G1CollectedHeap::mark_strong_code_roots(uint worker_id) { | |
6814 MarkStrongCodeRootsHRClosure cl(this, worker_id); | |
12082
9720d338b1d5
8023145: G1: G1CollectedHeap::mark_strong_code_roots() needs to handle ParallelGCThreads=0
brutisso
parents:
12080
diff
changeset
|
6815 if (G1CollectedHeap::use_parallel_gc_threads()) { |
9720d338b1d5
8023145: G1: G1CollectedHeap::mark_strong_code_roots() needs to handle ParallelGCThreads=0
brutisso
parents:
12080
diff
changeset
|
6816 heap_region_par_iterate_chunked(&cl, |
9720d338b1d5
8023145: G1: G1CollectedHeap::mark_strong_code_roots() needs to handle ParallelGCThreads=0
brutisso
parents:
12080
diff
changeset
|
6817 worker_id, |
9720d338b1d5
8023145: G1: G1CollectedHeap::mark_strong_code_roots() needs to handle ParallelGCThreads=0
brutisso
parents:
12080
diff
changeset
|
6818 workers()->active_workers(), |
9720d338b1d5
8023145: G1: G1CollectedHeap::mark_strong_code_roots() needs to handle ParallelGCThreads=0
brutisso
parents:
12080
diff
changeset
|
6819 HeapRegion::ParMarkRootClaimValue); |
9720d338b1d5
8023145: G1: G1CollectedHeap::mark_strong_code_roots() needs to handle ParallelGCThreads=0
brutisso
parents:
12080
diff
changeset
|
6820 } else { |
9720d338b1d5
8023145: G1: G1CollectedHeap::mark_strong_code_roots() needs to handle ParallelGCThreads=0
brutisso
parents:
12080
diff
changeset
|
6821 heap_region_iterate(&cl); |
9720d338b1d5
8023145: G1: G1CollectedHeap::mark_strong_code_roots() needs to handle ParallelGCThreads=0
brutisso
parents:
12080
diff
changeset
|
6822 } |
12080 | 6823 } |
6824 | |
6825 class RebuildStrongCodeRootClosure: public CodeBlobClosure { | |
6826 G1CollectedHeap* _g1h; | |
6827 | |
6828 public: | |
6829 RebuildStrongCodeRootClosure(G1CollectedHeap* g1h) : | |
6830 _g1h(g1h) {} | |
6831 | |
6832 void do_code_blob(CodeBlob* cb) { | |
6833 nmethod* nm = (cb != NULL) ? cb->as_nmethod_or_null() : NULL; | |
6834 if (nm == NULL) { | |
6835 return; | |
6836 } | |
6837 | |
6838 if (ScavengeRootsInCode && nm->detect_scavenge_root_oops()) { | |
6839 _g1h->register_nmethod(nm); | |
6840 } | |
6841 } | |
6842 }; | |
6843 | |
6844 void G1CollectedHeap::rebuild_strong_code_roots() { | |
6845 RebuildStrongCodeRootClosure blob_cl(this); | |
6846 CodeCache::blobs_do(&blob_cl); | |
6847 } |