Mercurial > hg > truffle
annotate src/share/vm/memory/tenuredGeneration.cpp @ 20304:a22acf6d7598
8048112: G1 Full GC needs to support the case when the very first region is not available
Summary: Refactor preparation for compaction during Full GC so that it lazily initializes the first compaction point. This also avoids problems later when the first region may not be committed. Also reviewed by K. Barrett.
Reviewed-by: brutisso
author | tschatzl |
---|---|
date | Mon, 21 Jul 2014 10:00:31 +0200 |
parents | 55fb97c4c58d |
children | 63a4eb8bcd23 |
rev | line source |
---|---|
0 | 1 /* |
17467
55fb97c4c58d
8029233: Update copyright year to match last edit in jdk8 hotspot repository for 2013
mikael
parents:
9072
diff
changeset
|
2 * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 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:
579
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
579
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:
579
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "gc_implementation/shared/collectorCounters.hpp" | |
6595 | 27 #include "gc_implementation/shared/parGCAllocBuffer.hpp" |
1972 | 28 #include "memory/allocation.inline.hpp" |
29 #include "memory/blockOffsetTable.inline.hpp" | |
30 #include "memory/generation.inline.hpp" | |
31 #include "memory/generationSpec.hpp" | |
32 #include "memory/space.hpp" | |
33 #include "memory/tenuredGeneration.hpp" | |
34 #include "oops/oop.inline.hpp" | |
35 #include "runtime/java.hpp" | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7451
diff
changeset
|
36 #include "utilities/macros.hpp" |
0 | 37 |
38 TenuredGeneration::TenuredGeneration(ReservedSpace rs, | |
39 size_t initial_byte_size, int level, | |
40 GenRemSet* remset) : | |
41 OneContigSpaceCardGeneration(rs, initial_byte_size, | |
9072
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
42 level, remset, NULL) |
0 | 43 { |
44 HeapWord* bottom = (HeapWord*) _virtual_space.low(); | |
45 HeapWord* end = (HeapWord*) _virtual_space.high(); | |
46 _the_space = new TenuredSpace(_bts, MemRegion(bottom, end)); | |
47 _the_space->reset_saved_mark(); | |
48 _shrink_factor = 0; | |
49 _capacity_at_prologue = 0; | |
50 | |
51 _gc_stats = new GCStats(); | |
52 | |
53 // initialize performance counters | |
54 | |
55 const char* gen_name = "old"; | |
56 | |
57 // Generation Counters -- generation 1, 1 subspace | |
58 _gen_counters = new GenerationCounters(gen_name, 1, 1, &_virtual_space); | |
59 | |
60 _gc_counters = new CollectorCounters("MSC", 1); | |
61 | |
62 _space_counters = new CSpaceCounters(gen_name, 0, | |
63 _virtual_space.reserved_size(), | |
64 _the_space, _gen_counters); | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7451
diff
changeset
|
65 #if INCLUDE_ALL_GCS |
7451
ca0a78017dc7
8005396: Use ParNew with only one thread instead of DefNew as default for CMS on single CPU machines
brutisso
parents:
6595
diff
changeset
|
66 if (UseParNewGC) { |
0 | 67 typedef ParGCAllocBufferWithBOT* ParGCAllocBufferWithBOTPtr; |
68 _alloc_buffers = NEW_C_HEAP_ARRAY(ParGCAllocBufferWithBOTPtr, | |
6197 | 69 ParallelGCThreads, mtGC); |
0 | 70 if (_alloc_buffers == NULL) |
71 vm_exit_during_initialization("Could not allocate alloc_buffers"); | |
72 for (uint i = 0; i < ParallelGCThreads; i++) { | |
73 _alloc_buffers[i] = | |
74 new ParGCAllocBufferWithBOT(OldPLABSize, _bts); | |
75 if (_alloc_buffers[i] == NULL) | |
76 vm_exit_during_initialization("Could not allocate alloc_buffers"); | |
77 } | |
78 } else { | |
79 _alloc_buffers = NULL; | |
80 } | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7451
diff
changeset
|
81 #endif // INCLUDE_ALL_GCS |
0 | 82 } |
83 | |
84 | |
85 const char* TenuredGeneration::name() const { | |
86 return "tenured generation"; | |
87 } | |
88 | |
89 void TenuredGeneration::gc_prologue(bool full) { | |
90 _capacity_at_prologue = capacity(); | |
91 _used_at_prologue = used(); | |
92 if (VerifyBeforeGC) { | |
93 verify_alloc_buffers_clean(); | |
94 } | |
95 } | |
96 | |
97 void TenuredGeneration::gc_epilogue(bool full) { | |
98 if (VerifyAfterGC) { | |
99 verify_alloc_buffers_clean(); | |
100 } | |
101 OneContigSpaceCardGeneration::gc_epilogue(full); | |
102 } | |
103 | |
104 | |
105 bool TenuredGeneration::should_collect(bool full, | |
106 size_t size, | |
107 bool is_tlab) { | |
108 // This should be one big conditional or (||), but I want to be able to tell | |
109 // why it returns what it returns (without re-evaluating the conditionals | |
110 // in case they aren't idempotent), so I'm doing it this way. | |
111 // DeMorgan says it's okay. | |
112 bool result = false; | |
113 if (!result && full) { | |
114 result = true; | |
115 if (PrintGC && Verbose) { | |
116 gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" | |
117 " full"); | |
118 } | |
119 } | |
120 if (!result && should_allocate(size, is_tlab)) { | |
121 result = true; | |
122 if (PrintGC && Verbose) { | |
123 gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" | |
124 " should_allocate(" SIZE_FORMAT ")", | |
125 size); | |
126 } | |
127 } | |
128 // If we don't have very much free space. | |
129 // XXX: 10000 should be a percentage of the capacity!!! | |
130 if (!result && free() < 10000) { | |
131 result = true; | |
132 if (PrintGC && Verbose) { | |
133 gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" | |
134 " free(): " SIZE_FORMAT, | |
135 free()); | |
136 } | |
137 } | |
138 // If we had to expand to accomodate promotions from younger generations | |
139 if (!result && _capacity_at_prologue < capacity()) { | |
140 result = true; | |
141 if (PrintGC && Verbose) { | |
142 gclog_or_tty->print_cr("TenuredGeneration::should_collect: because" | |
143 "_capacity_at_prologue: " SIZE_FORMAT " < capacity(): " SIZE_FORMAT, | |
144 _capacity_at_prologue, capacity()); | |
145 } | |
146 } | |
147 return result; | |
148 } | |
149 | |
150 void TenuredGeneration::collect(bool full, | |
151 bool clear_all_soft_refs, | |
152 size_t size, | |
153 bool is_tlab) { | |
154 retire_alloc_buffers_before_full_gc(); | |
155 OneContigSpaceCardGeneration::collect(full, clear_all_soft_refs, | |
156 size, is_tlab); | |
157 } | |
158 | |
9072
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
159 void TenuredGeneration::compute_new_size() { |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
160 assert_locked_or_safepoint(Heap_lock); |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
161 |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
162 // Compute some numbers about the state of the heap. |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
163 const size_t used_after_gc = used(); |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
164 const size_t capacity_after_gc = capacity(); |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
165 |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
166 CardGeneration::compute_new_size(); |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
167 |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
168 assert(used() == used_after_gc && used_after_gc <= capacity(), |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
169 err_msg("used: " SIZE_FORMAT " used_after_gc: " SIZE_FORMAT |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
170 " capacity: " SIZE_FORMAT, used(), used_after_gc, capacity())); |
8617e38bb4cb
8008508: CMS does not correctly reduce heap size after a Full GC
jmasa
parents:
8001
diff
changeset
|
171 } |
0 | 172 void TenuredGeneration::update_gc_stats(int current_level, |
173 bool full) { | |
174 // If the next lower level(s) has been collected, gather any statistics | |
175 // that are of interest at this point. | |
176 if (!full && (current_level + 1) == level()) { | |
177 // Calculate size of data promoted from the younger generations | |
178 // before doing the collection. | |
179 size_t used_before_gc = used(); | |
180 | |
181 // If the younger gen collections were skipped, then the | |
182 // number of promoted bytes will be 0 and adding it to the | |
183 // average will incorrectly lessen the average. It is, however, | |
184 // also possible that no promotion was needed. | |
185 if (used_before_gc >= _used_at_prologue) { | |
186 size_t promoted_in_bytes = used_before_gc - _used_at_prologue; | |
187 gc_stats()->avg_promoted()->sample(promoted_in_bytes); | |
188 } | |
189 } | |
190 } | |
191 | |
192 void TenuredGeneration::update_counters() { | |
193 if (UsePerfData) { | |
194 _space_counters->update_all(); | |
195 _gen_counters->update_all(); | |
196 } | |
197 } | |
198 | |
199 | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7451
diff
changeset
|
200 #if INCLUDE_ALL_GCS |
0 | 201 oop TenuredGeneration::par_promote(int thread_num, |
202 oop old, markOop m, size_t word_sz) { | |
203 | |
204 ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num]; | |
205 HeapWord* obj_ptr = buf->allocate(word_sz); | |
206 bool is_lab = true; | |
207 if (obj_ptr == NULL) { | |
208 #ifndef PRODUCT | |
209 if (Universe::heap()->promotion_should_fail()) { | |
210 return NULL; | |
211 } | |
212 #endif // #ifndef PRODUCT | |
213 | |
214 // Slow path: | |
215 if (word_sz * 100 < ParallelGCBufferWastePct * buf->word_sz()) { | |
216 // Is small enough; abandon this buffer and start a new one. | |
217 size_t buf_size = buf->word_sz(); | |
218 HeapWord* buf_space = | |
219 TenuredGeneration::par_allocate(buf_size, false); | |
220 if (buf_space == NULL) { | |
221 buf_space = expand_and_allocate(buf_size, false, true /* parallel*/); | |
222 } | |
223 if (buf_space != NULL) { | |
224 buf->retire(false, false); | |
225 buf->set_buf(buf_space); | |
226 obj_ptr = buf->allocate(word_sz); | |
227 assert(obj_ptr != NULL, "Buffer was definitely big enough..."); | |
228 } | |
229 }; | |
230 // Otherwise, buffer allocation failed; try allocating object | |
231 // individually. | |
232 if (obj_ptr == NULL) { | |
233 obj_ptr = TenuredGeneration::par_allocate(word_sz, false); | |
234 if (obj_ptr == NULL) { | |
235 obj_ptr = expand_and_allocate(word_sz, false, true /* parallel */); | |
236 } | |
237 } | |
238 if (obj_ptr == NULL) return NULL; | |
239 } | |
240 assert(obj_ptr != NULL, "program logic"); | |
241 Copy::aligned_disjoint_words((HeapWord*)old, obj_ptr, word_sz); | |
242 oop obj = oop(obj_ptr); | |
243 // Restore the mark word copied above. | |
244 obj->set_mark(m); | |
245 return obj; | |
246 } | |
247 | |
248 void TenuredGeneration::par_promote_alloc_undo(int thread_num, | |
249 HeapWord* obj, | |
250 size_t word_sz) { | |
251 ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num]; | |
252 if (buf->contains(obj)) { | |
253 guarantee(buf->contains(obj + word_sz - 1), | |
254 "should contain whole object"); | |
255 buf->undo_allocation(obj, word_sz); | |
256 } else { | |
481
7d7a7c599c17
6578152: fill_region_with_object has usability and safety issues
jcoomes
parents:
196
diff
changeset
|
257 CollectedHeap::fill_with_object(obj, word_sz); |
0 | 258 } |
259 } | |
260 | |
261 void TenuredGeneration::par_promote_alloc_done(int thread_num) { | |
262 ParGCAllocBufferWithBOT* buf = _alloc_buffers[thread_num]; | |
263 buf->retire(true, ParallelGCRetainPLAB); | |
264 } | |
265 | |
266 void TenuredGeneration::retire_alloc_buffers_before_full_gc() { | |
267 if (UseParNewGC) { | |
268 for (uint i = 0; i < ParallelGCThreads; i++) { | |
269 _alloc_buffers[i]->retire(true /*end_of_gc*/, false /*retain*/); | |
270 } | |
271 } | |
272 } | |
273 | |
274 // Verify that any retained parallel allocation buffers do not | |
275 // intersect with dirty cards. | |
276 void TenuredGeneration::verify_alloc_buffers_clean() { | |
277 if (UseParNewGC) { | |
278 for (uint i = 0; i < ParallelGCThreads; i++) { | |
6
73e96e5c30df
6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents:
0
diff
changeset
|
279 _rs->verify_aligned_region_empty(_alloc_buffers[i]->range()); |
0 | 280 } |
281 } | |
282 } | |
6
73e96e5c30df
6624765: Guarantee failure "Unexpected dirty card found"
jmasa
parents:
0
diff
changeset
|
283 |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7451
diff
changeset
|
284 #else // INCLUDE_ALL_GCS |
0 | 285 void TenuredGeneration::retire_alloc_buffers_before_full_gc() {} |
286 void TenuredGeneration::verify_alloc_buffers_clean() {} | |
8001
db9981fd3124
8005915: Unify SERIALGC and INCLUDE_ALTERNATE_GCS
jprovino
parents:
7451
diff
changeset
|
287 #endif // INCLUDE_ALL_GCS |
0 | 288 |
1888
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
289 bool TenuredGeneration::promotion_attempt_is_safe(size_t max_promotion_in_bytes) const { |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
290 size_t available = max_contiguous_available(); |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
291 size_t av_promo = (size_t)gc_stats()->avg_promoted()->padded_average(); |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
292 bool res = (available >= av_promo) || (available >= max_promotion_in_bytes); |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
293 if (PrintGC && Verbose) { |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
294 gclog_or_tty->print_cr( |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
295 "Tenured: promo attempt is%s safe: available("SIZE_FORMAT") %s av_promo("SIZE_FORMAT")," |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
296 "max_promo("SIZE_FORMAT")", |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
297 res? "":" not", available, res? ">=":"<", |
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
298 av_promo, max_promotion_in_bytes); |
0 | 299 } |
1888
a7214d79fcf1
6896603: CMS/GCH: collection_attempt_is_safe() ergo should use more recent data
ysr
parents:
1552
diff
changeset
|
300 return res; |
0 | 301 } |