Mercurial > hg > truffle
annotate src/share/vm/memory/genCollectedHeap.cpp @ 1721:413ad0331a0c
6977924: Changes for 6975078 produce build error with certain gcc versions
Summary: The changes introduced for 6975078 assign badHeapOopVal to the _allocation field in the ResourceObj class. In 32 bit linux builds with certain versions of gcc this assignment will be flagged as an error while compiling allocation.cpp. In 32 bit builds the constant value badHeapOopVal (which is cast to an intptr_t) is negative. The _allocation field is typed as an unsigned intptr_t and gcc catches this as an error.
Reviewed-by: jcoomes, ysr, phh
author | johnc |
---|---|
date | Wed, 18 Aug 2010 10:59:06 -0700 |
parents | 126ea7725993 |
children | 8b10f48633dc |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1520
diff
changeset
|
2 * Copyright (c) 2000, 2010, 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:
1520
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1520
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:
1520
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_genCollectedHeap.cpp.incl" | |
27 | |
28 GenCollectedHeap* GenCollectedHeap::_gch; | |
29 NOT_PRODUCT(size_t GenCollectedHeap::_skip_header_HeapWords = 0;) | |
30 | |
31 // The set of potentially parallel tasks in strong root scanning. | |
32 enum GCH_process_strong_roots_tasks { | |
33 // We probably want to parallelize both of these internally, but for now... | |
34 GCH_PS_younger_gens, | |
35 // Leave this one last. | |
36 GCH_PS_NumElements | |
37 }; | |
38 | |
39 GenCollectedHeap::GenCollectedHeap(GenCollectorPolicy *policy) : | |
40 SharedHeap(policy), | |
41 _gen_policy(policy), | |
42 _gen_process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)), | |
43 _full_collections_completed(0) | |
44 { | |
45 if (_gen_process_strong_tasks == NULL || | |
46 !_gen_process_strong_tasks->valid()) { | |
47 vm_exit_during_initialization("Failed necessary allocation."); | |
48 } | |
49 assert(policy != NULL, "Sanity check"); | |
50 _preloading_shared_classes = false; | |
51 } | |
52 | |
53 jint GenCollectedHeap::initialize() { | |
1166 | 54 CollectedHeap::pre_initialize(); |
55 | |
0 | 56 int i; |
57 _n_gens = gen_policy()->number_of_generations(); | |
58 | |
59 // While there are no constraints in the GC code that HeapWordSize | |
60 // be any particular value, there are multiple other areas in the | |
61 // system which believe this to be true (e.g. oop->object_size in some | |
62 // cases incorrectly returns the size in wordSize units rather than | |
63 // HeapWordSize). | |
64 guarantee(HeapWordSize == wordSize, "HeapWordSize must equal wordSize"); | |
65 | |
66 // The heap must be at least as aligned as generations. | |
67 size_t alignment = Generation::GenGrain; | |
68 | |
69 _gen_specs = gen_policy()->generations(); | |
70 PermanentGenerationSpec *perm_gen_spec = | |
71 collector_policy()->permanent_generation(); | |
72 | |
73 // Make sure the sizes are all aligned. | |
74 for (i = 0; i < _n_gens; i++) { | |
75 _gen_specs[i]->align(alignment); | |
76 } | |
77 perm_gen_spec->align(alignment); | |
78 | |
79 // If we are dumping the heap, then allocate a wasted block of address | |
80 // space in order to push the heap to a lower address. This extra | |
81 // address range allows for other (or larger) libraries to be loaded | |
82 // without them occupying the space required for the shared spaces. | |
83 | |
84 if (DumpSharedSpaces) { | |
85 uintx reserved = 0; | |
86 uintx block_size = 64*1024*1024; | |
87 while (reserved < SharedDummyBlockSize) { | |
88 char* dummy = os::reserve_memory(block_size); | |
89 reserved += block_size; | |
90 } | |
91 } | |
92 | |
93 // Allocate space for the heap. | |
94 | |
95 char* heap_address; | |
96 size_t total_reserved = 0; | |
97 int n_covered_regions = 0; | |
98 ReservedSpace heap_rs(0); | |
99 | |
100 heap_address = allocate(alignment, perm_gen_spec, &total_reserved, | |
101 &n_covered_regions, &heap_rs); | |
102 | |
103 if (UseSharedSpaces) { | |
104 if (!heap_rs.is_reserved() || heap_address != heap_rs.base()) { | |
105 if (heap_rs.is_reserved()) { | |
106 heap_rs.release(); | |
107 } | |
108 FileMapInfo* mapinfo = FileMapInfo::current_info(); | |
109 mapinfo->fail_continue("Unable to reserve shared region."); | |
110 allocate(alignment, perm_gen_spec, &total_reserved, &n_covered_regions, | |
111 &heap_rs); | |
112 } | |
113 } | |
114 | |
115 if (!heap_rs.is_reserved()) { | |
116 vm_shutdown_during_initialization( | |
117 "Could not reserve enough space for object heap"); | |
118 return JNI_ENOMEM; | |
119 } | |
120 | |
121 _reserved = MemRegion((HeapWord*)heap_rs.base(), | |
122 (HeapWord*)(heap_rs.base() + heap_rs.size())); | |
123 | |
124 // It is important to do this in a way such that concurrent readers can't | |
125 // temporarily think somethings in the heap. (Seen this happen in asserts.) | |
126 _reserved.set_word_size(0); | |
127 _reserved.set_start((HeapWord*)heap_rs.base()); | |
128 size_t actual_heap_size = heap_rs.size() - perm_gen_spec->misc_data_size() | |
129 - perm_gen_spec->misc_code_size(); | |
130 _reserved.set_end((HeapWord*)(heap_rs.base() + actual_heap_size)); | |
131 | |
132 _rem_set = collector_policy()->create_rem_set(_reserved, n_covered_regions); | |
133 set_barrier_set(rem_set()->bs()); | |
1166 | 134 |
0 | 135 _gch = this; |
136 | |
137 for (i = 0; i < _n_gens; i++) { | |
138 ReservedSpace this_rs = heap_rs.first_part(_gen_specs[i]->max_size(), | |
139 UseSharedSpaces, UseSharedSpaces); | |
140 _gens[i] = _gen_specs[i]->init(this_rs, i, rem_set()); | |
141 heap_rs = heap_rs.last_part(_gen_specs[i]->max_size()); | |
142 } | |
143 _perm_gen = perm_gen_spec->init(heap_rs, PermSize, rem_set()); | |
144 | |
145 clear_incremental_collection_will_fail(); | |
146 clear_last_incremental_collection_failed(); | |
147 | |
148 #ifndef SERIALGC | |
149 // If we are running CMS, create the collector responsible | |
150 // for collecting the CMS generations. | |
151 if (collector_policy()->is_concurrent_mark_sweep_policy()) { | |
152 bool success = create_cms_collector(); | |
153 if (!success) return JNI_ENOMEM; | |
154 } | |
155 #endif // SERIALGC | |
156 | |
157 return JNI_OK; | |
158 } | |
159 | |
160 | |
161 char* GenCollectedHeap::allocate(size_t alignment, | |
162 PermanentGenerationSpec* perm_gen_spec, | |
163 size_t* _total_reserved, | |
164 int* _n_covered_regions, | |
165 ReservedSpace* heap_rs){ | |
166 const char overflow_msg[] = "The size of the object heap + VM data exceeds " | |
167 "the maximum representable size"; | |
168 | |
169 // Now figure out the total size. | |
170 size_t total_reserved = 0; | |
171 int n_covered_regions = 0; | |
172 const size_t pageSize = UseLargePages ? | |
173 os::large_page_size() : os::vm_page_size(); | |
174 | |
175 for (int i = 0; i < _n_gens; i++) { | |
176 total_reserved += _gen_specs[i]->max_size(); | |
177 if (total_reserved < _gen_specs[i]->max_size()) { | |
178 vm_exit_during_initialization(overflow_msg); | |
179 } | |
180 n_covered_regions += _gen_specs[i]->n_covered_regions(); | |
181 } | |
1626
1a11430e0326
6888573: class data sharing does not always disable large pages
jcoomes
parents:
1552
diff
changeset
|
182 assert(total_reserved % pageSize == 0, |
1a11430e0326
6888573: class data sharing does not always disable large pages
jcoomes
parents:
1552
diff
changeset
|
183 err_msg("Gen size; total_reserved=" SIZE_FORMAT ", pageSize=" |
1a11430e0326
6888573: class data sharing does not always disable large pages
jcoomes
parents:
1552
diff
changeset
|
184 SIZE_FORMAT, total_reserved, pageSize)); |
0 | 185 total_reserved += perm_gen_spec->max_size(); |
1626
1a11430e0326
6888573: class data sharing does not always disable large pages
jcoomes
parents:
1552
diff
changeset
|
186 assert(total_reserved % pageSize == 0, |
1a11430e0326
6888573: class data sharing does not always disable large pages
jcoomes
parents:
1552
diff
changeset
|
187 err_msg("Perm size; total_reserved=" SIZE_FORMAT ", pageSize=" |
1a11430e0326
6888573: class data sharing does not always disable large pages
jcoomes
parents:
1552
diff
changeset
|
188 SIZE_FORMAT ", perm gen max=" SIZE_FORMAT, total_reserved, |
1a11430e0326
6888573: class data sharing does not always disable large pages
jcoomes
parents:
1552
diff
changeset
|
189 pageSize, perm_gen_spec->max_size())); |
0 | 190 |
191 if (total_reserved < perm_gen_spec->max_size()) { | |
192 vm_exit_during_initialization(overflow_msg); | |
193 } | |
194 n_covered_regions += perm_gen_spec->n_covered_regions(); | |
195 | |
196 // Add the size of the data area which shares the same reserved area | |
197 // as the heap, but which is not actually part of the heap. | |
198 size_t s = perm_gen_spec->misc_data_size() + perm_gen_spec->misc_code_size(); | |
199 | |
200 total_reserved += s; | |
201 if (total_reserved < s) { | |
202 vm_exit_during_initialization(overflow_msg); | |
203 } | |
204 | |
205 if (UseLargePages) { | |
206 assert(total_reserved != 0, "total_reserved cannot be 0"); | |
207 total_reserved = round_to(total_reserved, os::large_page_size()); | |
208 if (total_reserved < os::large_page_size()) { | |
209 vm_exit_during_initialization(overflow_msg); | |
210 } | |
211 } | |
212 | |
213 // Calculate the address at which the heap must reside in order for | |
214 // the shared data to be at the required address. | |
215 | |
216 char* heap_address; | |
217 if (UseSharedSpaces) { | |
218 | |
219 // Calculate the address of the first word beyond the heap. | |
220 FileMapInfo* mapinfo = FileMapInfo::current_info(); | |
221 int lr = CompactingPermGenGen::n_regions - 1; | |
222 size_t capacity = align_size_up(mapinfo->space_capacity(lr), alignment); | |
223 heap_address = mapinfo->region_base(lr) + capacity; | |
224 | |
225 // Calculate the address of the first word of the heap. | |
226 heap_address -= total_reserved; | |
227 } else { | |
228 heap_address = NULL; // any address will do. | |
642
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
229 if (UseCompressedOops) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
230 heap_address = Universe::preferred_heap_base(total_reserved, Universe::UnscaledNarrowOop); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
231 *_total_reserved = total_reserved; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
232 *_n_covered_regions = n_covered_regions; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
233 *heap_rs = ReservedHeapSpace(total_reserved, alignment, |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
234 UseLargePages, heap_address); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
235 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
236 if (heap_address != NULL && !heap_rs->is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
237 // Failed to reserve at specified address - the requested memory |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
238 // region is taken already, for example, by 'java' launcher. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
239 // Try again to reserver heap higher. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
240 heap_address = Universe::preferred_heap_base(total_reserved, Universe::ZeroBasedNarrowOop); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
241 *heap_rs = ReservedHeapSpace(total_reserved, alignment, |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
242 UseLargePages, heap_address); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
243 |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
244 if (heap_address != NULL && !heap_rs->is_reserved()) { |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
245 // Failed to reserve at specified address again - give up. |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
246 heap_address = Universe::preferred_heap_base(total_reserved, Universe::HeapBasedNarrowOop); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
247 assert(heap_address == NULL, ""); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
248 *heap_rs = ReservedHeapSpace(total_reserved, alignment, |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
249 UseLargePages, heap_address); |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
250 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
251 } |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
252 return heap_address; |
660978a2a31a
6791178: Specialize for zero as the compressed oop vm heap base
kvn
parents:
615
diff
changeset
|
253 } |
0 | 254 } |
255 | |
256 *_total_reserved = total_reserved; | |
257 *_n_covered_regions = n_covered_regions; | |
237
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
196
diff
changeset
|
258 *heap_rs = ReservedHeapSpace(total_reserved, alignment, |
1fdb98a17101
6716785: implicit null checks not triggering with CompressedOops
coleenp
parents:
196
diff
changeset
|
259 UseLargePages, heap_address); |
0 | 260 |
261 return heap_address; | |
262 } | |
263 | |
264 | |
265 void GenCollectedHeap::post_initialize() { | |
266 SharedHeap::post_initialize(); | |
267 TwoGenerationCollectorPolicy *policy = | |
268 (TwoGenerationCollectorPolicy *)collector_policy(); | |
269 guarantee(policy->is_two_generation_policy(), "Illegal policy type"); | |
270 DefNewGeneration* def_new_gen = (DefNewGeneration*) get_gen(0); | |
271 assert(def_new_gen->kind() == Generation::DefNew || | |
272 def_new_gen->kind() == Generation::ParNew || | |
273 def_new_gen->kind() == Generation::ASParNew, | |
274 "Wrong generation kind"); | |
275 | |
276 Generation* old_gen = get_gen(1); | |
277 assert(old_gen->kind() == Generation::ConcurrentMarkSweep || | |
278 old_gen->kind() == Generation::ASConcurrentMarkSweep || | |
279 old_gen->kind() == Generation::MarkSweepCompact, | |
280 "Wrong generation kind"); | |
281 | |
282 policy->initialize_size_policy(def_new_gen->eden()->capacity(), | |
283 old_gen->capacity(), | |
284 def_new_gen->from()->capacity()); | |
285 policy->initialize_gc_policy_counters(); | |
286 } | |
287 | |
288 void GenCollectedHeap::ref_processing_init() { | |
289 SharedHeap::ref_processing_init(); | |
290 for (int i = 0; i < _n_gens; i++) { | |
291 _gens[i]->ref_processor_init(); | |
292 } | |
293 } | |
294 | |
295 size_t GenCollectedHeap::capacity() const { | |
296 size_t res = 0; | |
297 for (int i = 0; i < _n_gens; i++) { | |
298 res += _gens[i]->capacity(); | |
299 } | |
300 return res; | |
301 } | |
302 | |
303 size_t GenCollectedHeap::used() const { | |
304 size_t res = 0; | |
305 for (int i = 0; i < _n_gens; i++) { | |
306 res += _gens[i]->used(); | |
307 } | |
308 return res; | |
309 } | |
310 | |
311 // Save the "used_region" for generations level and lower, | |
312 // and, if perm is true, for perm gen. | |
313 void GenCollectedHeap::save_used_regions(int level, bool perm) { | |
314 assert(level < _n_gens, "Illegal level parameter"); | |
315 for (int i = level; i >= 0; i--) { | |
316 _gens[i]->save_used_region(); | |
317 } | |
318 if (perm) { | |
319 perm_gen()->save_used_region(); | |
320 } | |
321 } | |
322 | |
323 size_t GenCollectedHeap::max_capacity() const { | |
324 size_t res = 0; | |
325 for (int i = 0; i < _n_gens; i++) { | |
326 res += _gens[i]->max_capacity(); | |
327 } | |
328 return res; | |
329 } | |
330 | |
331 // Update the _full_collections_completed counter | |
332 // at the end of a stop-world full GC. | |
333 unsigned int GenCollectedHeap::update_full_collections_completed() { | |
334 MonitorLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag); | |
335 assert(_full_collections_completed <= _total_full_collections, | |
336 "Can't complete more collections than were started"); | |
337 _full_collections_completed = _total_full_collections; | |
338 ml.notify_all(); | |
339 return _full_collections_completed; | |
340 } | |
341 | |
342 // Update the _full_collections_completed counter, as appropriate, | |
343 // at the end of a concurrent GC cycle. Note the conditional update | |
344 // below to allow this method to be called by a concurrent collector | |
345 // without synchronizing in any manner with the VM thread (which | |
346 // may already have initiated a STW full collection "concurrently"). | |
347 unsigned int GenCollectedHeap::update_full_collections_completed(unsigned int count) { | |
348 MonitorLockerEx ml(FullGCCount_lock, Mutex::_no_safepoint_check_flag); | |
349 assert((_full_collections_completed <= _total_full_collections) && | |
350 (count <= _total_full_collections), | |
351 "Can't complete more collections than were started"); | |
352 if (count > _full_collections_completed) { | |
353 _full_collections_completed = count; | |
354 ml.notify_all(); | |
355 } | |
356 return _full_collections_completed; | |
357 } | |
358 | |
359 | |
360 #ifndef PRODUCT | |
361 // Override of memory state checking method in CollectedHeap: | |
362 // Some collectors (CMS for example) can't have badHeapWordVal written | |
363 // in the first two words of an object. (For instance , in the case of | |
364 // CMS these words hold state used to synchronize between certain | |
365 // (concurrent) GC steps and direct allocating mutators.) | |
366 // The skip_header_HeapWords() method below, allows us to skip | |
367 // over the requisite number of HeapWord's. Note that (for | |
368 // generational collectors) this means that those many words are | |
369 // skipped in each object, irrespective of the generation in which | |
370 // that object lives. The resultant loss of precision seems to be | |
371 // harmless and the pain of avoiding that imprecision appears somewhat | |
372 // higher than we are prepared to pay for such rudimentary debugging | |
373 // support. | |
374 void GenCollectedHeap::check_for_non_bad_heap_word_value(HeapWord* addr, | |
375 size_t size) { | |
376 if (CheckMemoryInitialization && ZapUnusedHeapArea) { | |
377 // We are asked to check a size in HeapWords, | |
378 // but the memory is mangled in juint words. | |
379 juint* start = (juint*) (addr + skip_header_HeapWords()); | |
380 juint* end = (juint*) (addr + size); | |
381 for (juint* slot = start; slot < end; slot += 1) { | |
382 assert(*slot == badHeapWordVal, | |
383 "Found non badHeapWordValue in pre-allocation check"); | |
384 } | |
385 } | |
386 } | |
387 #endif | |
388 | |
389 HeapWord* GenCollectedHeap::attempt_allocation(size_t size, | |
390 bool is_tlab, | |
391 bool first_only) { | |
392 HeapWord* res; | |
393 for (int i = 0; i < _n_gens; i++) { | |
394 if (_gens[i]->should_allocate(size, is_tlab)) { | |
395 res = _gens[i]->allocate(size, is_tlab); | |
396 if (res != NULL) return res; | |
397 else if (first_only) break; | |
398 } | |
399 } | |
400 // Otherwise... | |
401 return NULL; | |
402 } | |
403 | |
404 HeapWord* GenCollectedHeap::mem_allocate(size_t size, | |
405 bool is_large_noref, | |
406 bool is_tlab, | |
407 bool* gc_overhead_limit_was_exceeded) { | |
408 return collector_policy()->mem_allocate_work(size, | |
409 is_tlab, | |
410 gc_overhead_limit_was_exceeded); | |
411 } | |
412 | |
413 bool GenCollectedHeap::must_clear_all_soft_refs() { | |
414 return _gc_cause == GCCause::_last_ditch_collection; | |
415 } | |
416 | |
417 bool GenCollectedHeap::should_do_concurrent_full_gc(GCCause::Cause cause) { | |
1520
bb843ebc7c55
6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents:
1387
diff
changeset
|
418 return UseConcMarkSweepGC && |
bb843ebc7c55
6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents:
1387
diff
changeset
|
419 ((cause == GCCause::_gc_locker && GCLockerInvokesConcurrent) || |
bb843ebc7c55
6919638: CMS: ExplicitGCInvokesConcurrent misinteracts with gc locker
ysr
parents:
1387
diff
changeset
|
420 (cause == GCCause::_java_lang_system_gc && ExplicitGCInvokesConcurrent)); |
0 | 421 } |
422 | |
423 void GenCollectedHeap::do_collection(bool full, | |
424 bool clear_all_soft_refs, | |
425 size_t size, | |
426 bool is_tlab, | |
427 int max_level) { | |
428 bool prepared_for_verification = false; | |
429 ResourceMark rm; | |
430 DEBUG_ONLY(Thread* my_thread = Thread::current();) | |
431 | |
432 assert(SafepointSynchronize::is_at_safepoint(), "should be at safepoint"); | |
433 assert(my_thread->is_VM_thread() || | |
434 my_thread->is_ConcurrentGC_thread(), | |
435 "incorrect thread type capability"); | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1170
diff
changeset
|
436 assert(Heap_lock->is_locked(), |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1170
diff
changeset
|
437 "the requesting thread should have the Heap_lock"); |
0 | 438 guarantee(!is_gc_active(), "collection is not reentrant"); |
439 assert(max_level < n_gens(), "sanity check"); | |
440 | |
441 if (GC_locker::check_active_before_gc()) { | |
442 return; // GC is disabled (e.g. JNI GetXXXCritical operation) | |
443 } | |
444 | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1170
diff
changeset
|
445 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:
1170
diff
changeset
|
446 collector_policy()->should_clear_all_soft_refs(); |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1170
diff
changeset
|
447 |
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1170
diff
changeset
|
448 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:
1170
diff
changeset
|
449 |
0 | 450 const size_t perm_prev_used = perm_gen()->used(); |
451 | |
452 if (PrintHeapAtGC) { | |
453 Universe::print_heap_before_gc(); | |
454 if (Verbose) { | |
455 gclog_or_tty->print_cr("GC Cause: %s", GCCause::to_string(gc_cause())); | |
456 } | |
457 } | |
458 | |
459 { | |
460 FlagSetting fl(_is_gc_active, true); | |
461 | |
462 bool complete = full && (max_level == (n_gens()-1)); | |
463 const char* gc_cause_str = "GC "; | |
464 if (complete) { | |
465 GCCause::Cause cause = gc_cause(); | |
466 if (cause == GCCause::_java_lang_system_gc) { | |
467 gc_cause_str = "Full GC (System) "; | |
468 } else { | |
469 gc_cause_str = "Full GC "; | |
470 } | |
471 } | |
472 gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps); | |
473 TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty); | |
474 TraceTime t(gc_cause_str, PrintGCDetails, false, gclog_or_tty); | |
475 | |
476 gc_prologue(complete); | |
477 increment_total_collections(complete); | |
478 | |
479 size_t gch_prev_used = used(); | |
480 | |
481 int starting_level = 0; | |
482 if (full) { | |
483 // Search for the oldest generation which will collect all younger | |
484 // generations, and start collection loop there. | |
485 for (int i = max_level; i >= 0; i--) { | |
486 if (_gens[i]->full_collects_younger_generations()) { | |
487 starting_level = i; | |
488 break; | |
489 } | |
490 } | |
491 } | |
492 | |
493 bool must_restore_marks_for_biased_locking = false; | |
494 | |
495 int max_level_collected = starting_level; | |
496 for (int i = starting_level; i <= max_level; i++) { | |
497 if (_gens[i]->should_collect(full, size, is_tlab)) { | |
880
2b4230d1e589
6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents:
457
diff
changeset
|
498 if (i == n_gens() - 1) { // a major collection is to happen |
2b4230d1e589
6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents:
457
diff
changeset
|
499 if (!complete) { |
2b4230d1e589
6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents:
457
diff
changeset
|
500 // The full_collections increment was missed above. |
2b4230d1e589
6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents:
457
diff
changeset
|
501 increment_total_full_collections(); |
2b4230d1e589
6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents:
457
diff
changeset
|
502 } |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
503 pre_full_gc_dump(); // do any pre full gc dumps |
880
2b4230d1e589
6862295: JDWP threadid changes during debugging session (leading to ingored breakpoints)
dcubed
parents:
457
diff
changeset
|
504 } |
0 | 505 // Timer for individual generations. Last argument is false: no CR |
506 TraceTime t1(_gens[i]->short_name(), PrintGCDetails, false, gclog_or_tty); | |
507 TraceCollectorStats tcs(_gens[i]->counters()); | |
508 TraceMemoryManagerStats tmms(_gens[i]->kind()); | |
509 | |
510 size_t prev_used = _gens[i]->used(); | |
511 _gens[i]->stat_record()->invocations++; | |
512 _gens[i]->stat_record()->accumulated_time.start(); | |
513 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
514 // Must be done anew before each collection because |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
515 // a previous collection will do mangling and will |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
516 // change top of some spaces. |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
517 record_gen_tops_before_GC(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
518 |
0 | 519 if (PrintGC && Verbose) { |
520 gclog_or_tty->print("level=%d invoke=%d size=" SIZE_FORMAT, | |
521 i, | |
522 _gens[i]->stat_record()->invocations, | |
523 size*HeapWordSize); | |
524 } | |
525 | |
526 if (VerifyBeforeGC && i >= VerifyGCLevel && | |
527 total_collections() >= VerifyGCStartAt) { | |
528 HandleMark hm; // Discard invalid handles created during verification | |
529 if (!prepared_for_verification) { | |
530 prepare_for_verify(); | |
531 prepared_for_verification = true; | |
532 } | |
533 gclog_or_tty->print(" VerifyBeforeGC:"); | |
534 Universe::verify(true); | |
535 } | |
536 COMPILER2_PRESENT(DerivedPointerTable::clear()); | |
537 | |
538 if (!must_restore_marks_for_biased_locking && | |
539 _gens[i]->performs_in_place_marking()) { | |
540 // We perform this mark word preservation work lazily | |
541 // because it's only at this point that we know whether we | |
542 // absolutely have to do it; we want to avoid doing it for | |
543 // scavenge-only collections where it's unnecessary | |
544 must_restore_marks_for_biased_locking = true; | |
545 BiasedLocking::preserve_marks(); | |
546 } | |
547 | |
548 // Do collection work | |
549 { | |
550 // Note on ref discovery: For what appear to be historical reasons, | |
551 // GCH enables and disabled (by enqueing) refs discovery. | |
552 // In the future this should be moved into the generation's | |
553 // collect method so that ref discovery and enqueueing concerns | |
554 // are local to a generation. The collect method could return | |
555 // an appropriate indication in the case that notification on | |
556 // the ref lock was needed. This will make the treatment of | |
557 // weak refs more uniform (and indeed remove such concerns | |
558 // from GCH). XXX | |
559 | |
560 HandleMark hm; // Discard invalid handles created during gc | |
561 save_marks(); // save marks for all gens | |
562 // We want to discover references, but not process them yet. | |
563 // This mode is disabled in process_discovered_references if the | |
564 // generation does some collection work, or in | |
565 // enqueue_discovered_references if the generation returns | |
566 // without doing any work. | |
567 ReferenceProcessor* rp = _gens[i]->ref_processor(); | |
568 // If the discovery of ("weak") refs in this generation is | |
569 // atomic wrt other collectors in this configuration, we | |
570 // are guaranteed to have empty discovered ref lists. | |
571 if (rp->discovery_is_atomic()) { | |
572 rp->verify_no_references_recorded(); | |
573 rp->enable_discovery(); | |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1170
diff
changeset
|
574 rp->setup_policy(do_clear_all_soft_refs); |
0 | 575 } else { |
453
c96030fff130
6684579: SoftReference processing can be made more efficient
ysr
parents:
269
diff
changeset
|
576 // collect() below will enable discovery as appropriate |
0 | 577 } |
1387
0bfd3fb24150
6858496: Clear all SoftReferences before an out-of-memory due to GC overhead limit.
jmasa
parents:
1170
diff
changeset
|
578 _gens[i]->collect(full, do_clear_all_soft_refs, size, is_tlab); |
0 | 579 if (!rp->enqueuing_is_done()) { |
580 rp->enqueue_discovered_references(); | |
581 } else { | |
582 rp->set_enqueuing_is_done(false); | |
583 } | |
584 rp->verify_no_references_recorded(); | |
585 } | |
586 max_level_collected = i; | |
587 | |
588 // Determine if allocation request was met. | |
589 if (size > 0) { | |
590 if (!is_tlab || _gens[i]->supports_tlab_allocation()) { | |
591 if (size*HeapWordSize <= _gens[i]->unsafe_max_alloc_nogc()) { | |
592 size = 0; | |
593 } | |
594 } | |
595 } | |
596 | |
597 COMPILER2_PRESENT(DerivedPointerTable::update_pointers()); | |
598 | |
599 _gens[i]->stat_record()->accumulated_time.stop(); | |
600 | |
601 update_gc_stats(i, full); | |
602 | |
603 if (VerifyAfterGC && i >= VerifyGCLevel && | |
604 total_collections() >= VerifyGCStartAt) { | |
605 HandleMark hm; // Discard invalid handles created during verification | |
606 gclog_or_tty->print(" VerifyAfterGC:"); | |
607 Universe::verify(false); | |
608 } | |
609 | |
610 if (PrintGCDetails) { | |
611 gclog_or_tty->print(":"); | |
612 _gens[i]->print_heap_change(prev_used); | |
613 } | |
614 } | |
615 } | |
616 | |
617 // Update "complete" boolean wrt what actually transpired -- | |
618 // for instance, a promotion failure could have led to | |
619 // a whole heap collection. | |
620 complete = complete || (max_level_collected == n_gens() - 1); | |
621 | |
615
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
622 if (complete) { // We did a "major" collection |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
623 post_full_gc_dump(); // do any post full gc dumps |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
624 } |
c6c601a0f2d6
6797870: Add -XX:+{HeapDump,PrintClassHistogram}{Before,After}FullGC
ysr
parents:
546
diff
changeset
|
625 |
0 | 626 if (PrintGCDetails) { |
627 print_heap_change(gch_prev_used); | |
628 | |
629 // Print perm gen info for full GC with PrintGCDetails flag. | |
630 if (complete) { | |
631 print_perm_heap_change(perm_prev_used); | |
632 } | |
633 } | |
634 | |
635 for (int j = max_level_collected; j >= 0; j -= 1) { | |
636 // Adjust generation sizes. | |
637 _gens[j]->compute_new_size(); | |
638 } | |
639 | |
640 if (complete) { | |
641 // Ask the permanent generation to adjust size for full collections | |
642 perm()->compute_new_size(); | |
643 update_full_collections_completed(); | |
644 } | |
645 | |
646 // Track memory usage and detect low memory after GC finishes | |
647 MemoryService::track_memory_usage(); | |
648 | |
649 gc_epilogue(complete); | |
650 | |
651 if (must_restore_marks_for_biased_locking) { | |
652 BiasedLocking::restore_marks(); | |
653 } | |
654 } | |
655 | |
656 AdaptiveSizePolicy* sp = gen_policy()->size_policy(); | |
657 AdaptiveSizePolicyOutput(sp, total_collections()); | |
658 | |
659 if (PrintHeapAtGC) { | |
660 Universe::print_heap_after_gc(); | |
661 } | |
662 | |
546
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
517
diff
changeset
|
663 #ifdef TRACESPINNING |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
517
diff
changeset
|
664 ParallelTaskTerminator::print_termination_counts(); |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
517
diff
changeset
|
665 #endif |
05c6d52fa7a9
6690928: Use spinning in combination with yields for workstealing termination.
jmasa
parents:
517
diff
changeset
|
666 |
0 | 667 if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) { |
668 tty->print_cr("Stopping after GC #%d", ExitAfterGCNum); | |
669 vm_exit(-1); | |
670 } | |
671 } | |
672 | |
673 HeapWord* GenCollectedHeap::satisfy_failed_allocation(size_t size, bool is_tlab) { | |
674 return collector_policy()->satisfy_failed_allocation(size, is_tlab); | |
675 } | |
676 | |
677 void GenCollectedHeap::set_par_threads(int t) { | |
678 SharedHeap::set_par_threads(t); | |
679 _gen_process_strong_tasks->set_par_threads(t); | |
680 } | |
681 | |
682 class AssertIsPermClosure: public OopClosure { | |
683 public: | |
684 void do_oop(oop* p) { | |
685 assert((*p) == NULL || (*p)->is_perm(), "Referent should be perm."); | |
686 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
687 void do_oop(narrowOop* p) { ShouldNotReachHere(); } |
0 | 688 }; |
689 static AssertIsPermClosure assert_is_perm_closure; | |
690 | |
691 void GenCollectedHeap:: | |
692 gen_process_strong_roots(int level, | |
693 bool younger_gens_as_roots, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
694 bool activate_scope, |
0 | 695 bool collecting_perm_gen, |
696 SharedHeap::ScanningOption so, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
697 OopsInGenClosure* not_older_gens, |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
698 bool do_code_roots, |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
699 OopsInGenClosure* older_gens) { |
0 | 700 // General strong roots. |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
701 |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
702 if (!do_code_roots) { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
703 SharedHeap::process_strong_roots(activate_scope, collecting_perm_gen, so, |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
704 not_older_gens, NULL, older_gens); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
705 } else { |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
706 bool do_code_marking = (activate_scope || nmethod::oops_do_marking_is_active()); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
707 CodeBlobToOopClosure code_roots(not_older_gens, /*do_marking=*/ do_code_marking); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
708 SharedHeap::process_strong_roots(activate_scope, collecting_perm_gen, so, |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
709 not_older_gens, &code_roots, older_gens); |
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
710 } |
0 | 711 |
712 if (younger_gens_as_roots) { | |
713 if (!_gen_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) { | |
714 for (int i = 0; i < level; i++) { | |
715 not_older_gens->set_generation(_gens[i]); | |
716 _gens[i]->oop_iterate(not_older_gens); | |
717 } | |
718 not_older_gens->reset_generation(); | |
719 } | |
720 } | |
721 // When collection is parallel, all threads get to cooperate to do | |
722 // older-gen scanning. | |
723 for (int i = level+1; i < _n_gens; i++) { | |
724 older_gens->set_generation(_gens[i]); | |
725 rem_set()->younger_refs_iterate(_gens[i], older_gens); | |
726 older_gens->reset_generation(); | |
727 } | |
728 | |
729 _gen_process_strong_tasks->all_tasks_completed(); | |
730 } | |
731 | |
732 void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure, | |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
733 CodeBlobClosure* code_roots, |
0 | 734 OopClosure* non_root_closure) { |
989
148e5441d916
6863023: need non-perm oops in code cache for JSR 292
jrose
parents:
881
diff
changeset
|
735 SharedHeap::process_weak_roots(root_closure, code_roots, non_root_closure); |
0 | 736 // "Local" "weak" refs |
737 for (int i = 0; i < _n_gens; i++) { | |
738 _gens[i]->ref_processor()->weak_oops_do(root_closure); | |
739 } | |
740 } | |
741 | |
742 #define GCH_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \ | |
743 void GenCollectedHeap:: \ | |
744 oop_since_save_marks_iterate(int level, \ | |
745 OopClosureType* cur, \ | |
746 OopClosureType* older) { \ | |
747 _gens[level]->oop_since_save_marks_iterate##nv_suffix(cur); \ | |
748 for (int i = level+1; i < n_gens(); i++) { \ | |
749 _gens[i]->oop_since_save_marks_iterate##nv_suffix(older); \ | |
750 } \ | |
751 perm_gen()->oop_since_save_marks_iterate##nv_suffix(older); \ | |
752 } | |
753 | |
754 ALL_SINCE_SAVE_MARKS_CLOSURES(GCH_SINCE_SAVE_MARKS_ITERATE_DEFN) | |
755 | |
756 #undef GCH_SINCE_SAVE_MARKS_ITERATE_DEFN | |
757 | |
758 bool GenCollectedHeap::no_allocs_since_save_marks(int level) { | |
759 for (int i = level; i < _n_gens; i++) { | |
760 if (!_gens[i]->no_allocs_since_save_marks()) return false; | |
761 } | |
762 return perm_gen()->no_allocs_since_save_marks(); | |
763 } | |
764 | |
765 bool GenCollectedHeap::supports_inline_contig_alloc() const { | |
766 return _gens[0]->supports_inline_contig_alloc(); | |
767 } | |
768 | |
769 HeapWord** GenCollectedHeap::top_addr() const { | |
770 return _gens[0]->top_addr(); | |
771 } | |
772 | |
773 HeapWord** GenCollectedHeap::end_addr() const { | |
774 return _gens[0]->end_addr(); | |
775 } | |
776 | |
777 size_t GenCollectedHeap::unsafe_max_alloc() { | |
778 return _gens[0]->unsafe_max_alloc_nogc(); | |
779 } | |
780 | |
781 // public collection interfaces | |
782 | |
783 void GenCollectedHeap::collect(GCCause::Cause cause) { | |
784 if (should_do_concurrent_full_gc(cause)) { | |
785 #ifndef SERIALGC | |
786 // mostly concurrent full collection | |
787 collect_mostly_concurrent(cause); | |
788 #else // SERIALGC | |
789 ShouldNotReachHere(); | |
790 #endif // SERIALGC | |
791 } else { | |
792 #ifdef ASSERT | |
793 if (cause == GCCause::_scavenge_alot) { | |
794 // minor collection only | |
795 collect(cause, 0); | |
796 } else { | |
797 // Stop-the-world full collection | |
798 collect(cause, n_gens() - 1); | |
799 } | |
800 #else | |
801 // Stop-the-world full collection | |
802 collect(cause, n_gens() - 1); | |
803 #endif | |
804 } | |
805 } | |
806 | |
807 void GenCollectedHeap::collect(GCCause::Cause cause, int max_level) { | |
808 // The caller doesn't have the Heap_lock | |
809 assert(!Heap_lock->owned_by_self(), "this thread should not own the Heap_lock"); | |
810 MutexLocker ml(Heap_lock); | |
811 collect_locked(cause, max_level); | |
812 } | |
813 | |
814 // This interface assumes that it's being called by the | |
815 // vm thread. It collects the heap assuming that the | |
816 // heap lock is already held and that we are executing in | |
817 // the context of the vm thread. | |
818 void GenCollectedHeap::collect_as_vm_thread(GCCause::Cause cause) { | |
819 assert(Thread::current()->is_VM_thread(), "Precondition#1"); | |
820 assert(Heap_lock->is_locked(), "Precondition#2"); | |
821 GCCauseSetter gcs(this, cause); | |
822 switch (cause) { | |
823 case GCCause::_heap_inspection: | |
824 case GCCause::_heap_dump: { | |
825 HandleMark hm; | |
826 do_full_collection(false, // don't clear all soft refs | |
827 n_gens() - 1); | |
828 break; | |
829 } | |
830 default: // XXX FIX ME | |
831 ShouldNotReachHere(); // Unexpected use of this function | |
832 } | |
833 } | |
834 | |
835 void GenCollectedHeap::collect_locked(GCCause::Cause cause) { | |
836 // The caller has the Heap_lock | |
837 assert(Heap_lock->owned_by_self(), "this thread should own the Heap_lock"); | |
838 collect_locked(cause, n_gens() - 1); | |
839 } | |
840 | |
841 // this is the private collection interface | |
842 // The Heap_lock is expected to be held on entry. | |
843 | |
844 void GenCollectedHeap::collect_locked(GCCause::Cause cause, int max_level) { | |
845 if (_preloading_shared_classes) { | |
846 warning("\nThe permanent generation is not large enough to preload " | |
847 "requested classes.\nUse -XX:PermSize= to increase the initial " | |
848 "size of the permanent generation.\n"); | |
849 vm_exit(2); | |
850 } | |
851 // Read the GC count while holding the Heap_lock | |
852 unsigned int gc_count_before = total_collections(); | |
853 unsigned int full_gc_count_before = total_full_collections(); | |
854 { | |
855 MutexUnlocker mu(Heap_lock); // give up heap lock, execute gets it back | |
856 VM_GenCollectFull op(gc_count_before, full_gc_count_before, | |
857 cause, max_level); | |
858 VMThread::execute(&op); | |
859 } | |
860 } | |
861 | |
862 #ifndef SERIALGC | |
863 bool GenCollectedHeap::create_cms_collector() { | |
864 | |
865 assert(((_gens[1]->kind() == Generation::ConcurrentMarkSweep) || | |
866 (_gens[1]->kind() == Generation::ASConcurrentMarkSweep)) && | |
867 _perm_gen->as_gen()->kind() == Generation::ConcurrentMarkSweep, | |
868 "Unexpected generation kinds"); | |
869 // Skip two header words in the block content verification | |
870 NOT_PRODUCT(_skip_header_HeapWords = CMSCollector::skip_header_HeapWords();) | |
871 CMSCollector* collector = new CMSCollector( | |
872 (ConcurrentMarkSweepGeneration*)_gens[1], | |
873 (ConcurrentMarkSweepGeneration*)_perm_gen->as_gen(), | |
874 _rem_set->as_CardTableRS(), | |
875 (ConcurrentMarkSweepPolicy*) collector_policy()); | |
876 | |
877 if (collector == NULL || !collector->completed_initialization()) { | |
878 if (collector) { | |
879 delete collector; // Be nice in embedded situation | |
880 } | |
881 vm_shutdown_during_initialization("Could not create CMS collector"); | |
882 return false; | |
883 } | |
884 return true; // success | |
885 } | |
886 | |
887 void GenCollectedHeap::collect_mostly_concurrent(GCCause::Cause cause) { | |
888 assert(!Heap_lock->owned_by_self(), "Should not own Heap_lock"); | |
889 | |
890 MutexLocker ml(Heap_lock); | |
891 // Read the GC counts while holding the Heap_lock | |
892 unsigned int full_gc_count_before = total_full_collections(); | |
893 unsigned int gc_count_before = total_collections(); | |
894 { | |
895 MutexUnlocker mu(Heap_lock); | |
896 VM_GenCollectFullConcurrent op(gc_count_before, full_gc_count_before, cause); | |
897 VMThread::execute(&op); | |
898 } | |
899 } | |
900 #endif // SERIALGC | |
901 | |
902 | |
903 void GenCollectedHeap::do_full_collection(bool clear_all_soft_refs, | |
904 int max_level) { | |
905 int local_max_level; | |
906 if (!incremental_collection_will_fail() && | |
907 gc_cause() == GCCause::_gc_locker) { | |
908 local_max_level = 0; | |
909 } else { | |
910 local_max_level = max_level; | |
911 } | |
912 | |
913 do_collection(true /* full */, | |
914 clear_all_soft_refs /* clear_all_soft_refs */, | |
915 0 /* size */, | |
916 false /* is_tlab */, | |
917 local_max_level /* max_level */); | |
918 // Hack XXX FIX ME !!! | |
919 // A scavenge may not have been attempted, or may have | |
920 // been attempted and failed, because the old gen was too full | |
921 if (local_max_level == 0 && gc_cause() == GCCause::_gc_locker && | |
922 incremental_collection_will_fail()) { | |
923 if (PrintGCDetails) { | |
924 gclog_or_tty->print_cr("GC locker: Trying a full collection " | |
925 "because scavenge failed"); | |
926 } | |
927 // This time allow the old gen to be collected as well | |
928 do_collection(true /* full */, | |
929 clear_all_soft_refs /* clear_all_soft_refs */, | |
930 0 /* size */, | |
931 false /* is_tlab */, | |
932 n_gens() - 1 /* max_level */); | |
933 } | |
934 } | |
935 | |
936 // Returns "TRUE" iff "p" points into the allocated area of the heap. | |
937 bool GenCollectedHeap::is_in(const void* p) const { | |
938 #ifndef ASSERT | |
939 guarantee(VerifyBeforeGC || | |
940 VerifyDuringGC || | |
941 VerifyBeforeExit || | |
1155
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
989
diff
changeset
|
942 PrintAssembly || |
4e6abf09f540
6912062: disassembler plugin needs to produce symbolic information in product mode
jrose
parents:
989
diff
changeset
|
943 tty->count() != 0 || // already printing |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1626
diff
changeset
|
944 VerifyAfterGC || |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1626
diff
changeset
|
945 VMError::fatal_error_in_progress(), "too expensive"); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1626
diff
changeset
|
946 |
0 | 947 #endif |
948 // This might be sped up with a cache of the last generation that | |
949 // answered yes. | |
950 for (int i = 0; i < _n_gens; i++) { | |
951 if (_gens[i]->is_in(p)) return true; | |
952 } | |
953 if (_perm_gen->as_gen()->is_in(p)) return true; | |
954 // Otherwise... | |
955 return false; | |
956 } | |
957 | |
958 // Returns "TRUE" iff "p" points into the allocated area of the heap. | |
959 bool GenCollectedHeap::is_in_youngest(void* p) { | |
960 return _gens[0]->is_in(p); | |
961 } | |
962 | |
963 void GenCollectedHeap::oop_iterate(OopClosure* cl) { | |
964 for (int i = 0; i < _n_gens; i++) { | |
965 _gens[i]->oop_iterate(cl); | |
966 } | |
967 } | |
968 | |
969 void GenCollectedHeap::oop_iterate(MemRegion mr, OopClosure* cl) { | |
970 for (int i = 0; i < _n_gens; i++) { | |
971 _gens[i]->oop_iterate(mr, cl); | |
972 } | |
973 } | |
974 | |
975 void GenCollectedHeap::object_iterate(ObjectClosure* cl) { | |
976 for (int i = 0; i < _n_gens; i++) { | |
977 _gens[i]->object_iterate(cl); | |
978 } | |
979 perm_gen()->object_iterate(cl); | |
980 } | |
981 | |
517
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
457
diff
changeset
|
982 void GenCollectedHeap::safe_object_iterate(ObjectClosure* cl) { |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
457
diff
changeset
|
983 for (int i = 0; i < _n_gens; i++) { |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
457
diff
changeset
|
984 _gens[i]->safe_object_iterate(cl); |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
457
diff
changeset
|
985 } |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
457
diff
changeset
|
986 perm_gen()->safe_object_iterate(cl); |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
457
diff
changeset
|
987 } |
e9be0e04635a
6689653: JMapPerm fails with UseConcMarkSweepIncGC and compressed oops off
jmasa
parents:
457
diff
changeset
|
988 |
0 | 989 void GenCollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) { |
990 for (int i = 0; i < _n_gens; i++) { | |
991 _gens[i]->object_iterate_since_last_GC(cl); | |
992 } | |
993 } | |
994 | |
995 Space* GenCollectedHeap::space_containing(const void* addr) const { | |
996 for (int i = 0; i < _n_gens; i++) { | |
997 Space* res = _gens[i]->space_containing(addr); | |
998 if (res != NULL) return res; | |
999 } | |
1000 Space* res = perm_gen()->space_containing(addr); | |
1001 if (res != NULL) return res; | |
1002 // Otherwise... | |
1003 assert(false, "Could not find containing space"); | |
1004 return NULL; | |
1005 } | |
1006 | |
1007 | |
1008 HeapWord* GenCollectedHeap::block_start(const void* addr) const { | |
1009 assert(is_in_reserved(addr), "block_start of address outside of heap"); | |
1010 for (int i = 0; i < _n_gens; i++) { | |
1011 if (_gens[i]->is_in_reserved(addr)) { | |
1012 assert(_gens[i]->is_in(addr), | |
1013 "addr should be in allocated part of generation"); | |
1014 return _gens[i]->block_start(addr); | |
1015 } | |
1016 } | |
1017 if (perm_gen()->is_in_reserved(addr)) { | |
1018 assert(perm_gen()->is_in(addr), | |
1019 "addr should be in allocated part of perm gen"); | |
1020 return perm_gen()->block_start(addr); | |
1021 } | |
1022 assert(false, "Some generation should contain the address"); | |
1023 return NULL; | |
1024 } | |
1025 | |
1026 size_t GenCollectedHeap::block_size(const HeapWord* addr) const { | |
1027 assert(is_in_reserved(addr), "block_size of address outside of heap"); | |
1028 for (int i = 0; i < _n_gens; i++) { | |
1029 if (_gens[i]->is_in_reserved(addr)) { | |
1030 assert(_gens[i]->is_in(addr), | |
1031 "addr should be in allocated part of generation"); | |
1032 return _gens[i]->block_size(addr); | |
1033 } | |
1034 } | |
1035 if (perm_gen()->is_in_reserved(addr)) { | |
1036 assert(perm_gen()->is_in(addr), | |
1037 "addr should be in allocated part of perm gen"); | |
1038 return perm_gen()->block_size(addr); | |
1039 } | |
1040 assert(false, "Some generation should contain the address"); | |
1041 return 0; | |
1042 } | |
1043 | |
1044 bool GenCollectedHeap::block_is_obj(const HeapWord* addr) const { | |
1045 assert(is_in_reserved(addr), "block_is_obj of address outside of heap"); | |
1046 assert(block_start(addr) == addr, "addr must be a block start"); | |
1047 for (int i = 0; i < _n_gens; i++) { | |
1048 if (_gens[i]->is_in_reserved(addr)) { | |
1049 return _gens[i]->block_is_obj(addr); | |
1050 } | |
1051 } | |
1052 if (perm_gen()->is_in_reserved(addr)) { | |
1053 return perm_gen()->block_is_obj(addr); | |
1054 } | |
1055 assert(false, "Some generation should contain the address"); | |
1056 return false; | |
1057 } | |
1058 | |
1059 bool GenCollectedHeap::supports_tlab_allocation() const { | |
1060 for (int i = 0; i < _n_gens; i += 1) { | |
1061 if (_gens[i]->supports_tlab_allocation()) { | |
1062 return true; | |
1063 } | |
1064 } | |
1065 return false; | |
1066 } | |
1067 | |
1068 size_t GenCollectedHeap::tlab_capacity(Thread* thr) const { | |
1069 size_t result = 0; | |
1070 for (int i = 0; i < _n_gens; i += 1) { | |
1071 if (_gens[i]->supports_tlab_allocation()) { | |
1072 result += _gens[i]->tlab_capacity(); | |
1073 } | |
1074 } | |
1075 return result; | |
1076 } | |
1077 | |
1078 size_t GenCollectedHeap::unsafe_max_tlab_alloc(Thread* thr) const { | |
1079 size_t result = 0; | |
1080 for (int i = 0; i < _n_gens; i += 1) { | |
1081 if (_gens[i]->supports_tlab_allocation()) { | |
1082 result += _gens[i]->unsafe_max_tlab_alloc(); | |
1083 } | |
1084 } | |
1085 return result; | |
1086 } | |
1087 | |
1088 HeapWord* GenCollectedHeap::allocate_new_tlab(size_t size) { | |
1089 bool gc_overhead_limit_was_exceeded; | |
1090 HeapWord* result = mem_allocate(size /* size */, | |
1091 false /* is_large_noref */, | |
1092 true /* is_tlab */, | |
1093 &gc_overhead_limit_was_exceeded); | |
1094 return result; | |
1095 } | |
1096 | |
1097 // Requires "*prev_ptr" to be non-NULL. Deletes and a block of minimal size | |
1098 // from the list headed by "*prev_ptr". | |
1099 static ScratchBlock *removeSmallestScratch(ScratchBlock **prev_ptr) { | |
1100 bool first = true; | |
1101 size_t min_size = 0; // "first" makes this conceptually infinite. | |
1102 ScratchBlock **smallest_ptr, *smallest; | |
1103 ScratchBlock *cur = *prev_ptr; | |
1104 while (cur) { | |
1105 assert(*prev_ptr == cur, "just checking"); | |
1106 if (first || cur->num_words < min_size) { | |
1107 smallest_ptr = prev_ptr; | |
1108 smallest = cur; | |
1109 min_size = smallest->num_words; | |
1110 first = false; | |
1111 } | |
1112 prev_ptr = &cur->next; | |
1113 cur = cur->next; | |
1114 } | |
1115 smallest = *smallest_ptr; | |
1116 *smallest_ptr = smallest->next; | |
1117 return smallest; | |
1118 } | |
1119 | |
1120 // Sort the scratch block list headed by res into decreasing size order, | |
1121 // and set "res" to the result. | |
1122 static void sort_scratch_list(ScratchBlock*& list) { | |
1123 ScratchBlock* sorted = NULL; | |
1124 ScratchBlock* unsorted = list; | |
1125 while (unsorted) { | |
1126 ScratchBlock *smallest = removeSmallestScratch(&unsorted); | |
1127 smallest->next = sorted; | |
1128 sorted = smallest; | |
1129 } | |
1130 list = sorted; | |
1131 } | |
1132 | |
1133 ScratchBlock* GenCollectedHeap::gather_scratch(Generation* requestor, | |
1134 size_t max_alloc_words) { | |
1135 ScratchBlock* res = NULL; | |
1136 for (int i = 0; i < _n_gens; i++) { | |
1137 _gens[i]->contribute_scratch(res, requestor, max_alloc_words); | |
1138 } | |
1139 sort_scratch_list(res); | |
1140 return res; | |
1141 } | |
1142 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1143 void GenCollectedHeap::release_scratch() { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1144 for (int i = 0; i < _n_gens; i++) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1145 _gens[i]->reset_scratch(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1146 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1147 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1148 |
0 | 1149 size_t GenCollectedHeap::large_typearray_limit() { |
1150 return gen_policy()->large_typearray_limit(); | |
1151 } | |
1152 | |
1153 class GenPrepareForVerifyClosure: public GenCollectedHeap::GenClosure { | |
1154 void do_generation(Generation* gen) { | |
1155 gen->prepare_for_verify(); | |
1156 } | |
1157 }; | |
1158 | |
1159 void GenCollectedHeap::prepare_for_verify() { | |
1160 ensure_parsability(false); // no need to retire TLABs | |
1161 GenPrepareForVerifyClosure blk; | |
1162 generation_iterate(&blk, false); | |
1163 perm_gen()->prepare_for_verify(); | |
1164 } | |
1165 | |
1166 | |
1167 void GenCollectedHeap::generation_iterate(GenClosure* cl, | |
1168 bool old_to_young) { | |
1169 if (old_to_young) { | |
1170 for (int i = _n_gens-1; i >= 0; i--) { | |
1171 cl->do_generation(_gens[i]); | |
1172 } | |
1173 } else { | |
1174 for (int i = 0; i < _n_gens; i++) { | |
1175 cl->do_generation(_gens[i]); | |
1176 } | |
1177 } | |
1178 } | |
1179 | |
1180 void GenCollectedHeap::space_iterate(SpaceClosure* cl) { | |
1181 for (int i = 0; i < _n_gens; i++) { | |
1182 _gens[i]->space_iterate(cl, true); | |
1183 } | |
1184 perm_gen()->space_iterate(cl, true); | |
1185 } | |
1186 | |
1187 bool GenCollectedHeap::is_maximal_no_gc() const { | |
1188 for (int i = 0; i < _n_gens; i++) { // skip perm gen | |
1189 if (!_gens[i]->is_maximal_no_gc()) { | |
1190 return false; | |
1191 } | |
1192 } | |
1193 return true; | |
1194 } | |
1195 | |
1196 void GenCollectedHeap::save_marks() { | |
1197 for (int i = 0; i < _n_gens; i++) { | |
1198 _gens[i]->save_marks(); | |
1199 } | |
1200 perm_gen()->save_marks(); | |
1201 } | |
1202 | |
1203 void GenCollectedHeap::compute_new_generation_sizes(int collectedGen) { | |
1204 for (int i = 0; i <= collectedGen; i++) { | |
1205 _gens[i]->compute_new_size(); | |
1206 } | |
1207 } | |
1208 | |
1209 GenCollectedHeap* GenCollectedHeap::heap() { | |
1210 assert(_gch != NULL, "Uninitialized access to GenCollectedHeap::heap()"); | |
1211 assert(_gch->kind() == CollectedHeap::GenCollectedHeap, "not a generational heap"); | |
1212 return _gch; | |
1213 } | |
1214 | |
1215 | |
1216 void GenCollectedHeap::prepare_for_compaction() { | |
1217 Generation* scanning_gen = _gens[_n_gens-1]; | |
1218 // Start by compacting into same gen. | |
1219 CompactPoint cp(scanning_gen, NULL, NULL); | |
1220 while (scanning_gen != NULL) { | |
1221 scanning_gen->prepare_for_compaction(&cp); | |
1222 scanning_gen = prev_gen(scanning_gen); | |
1223 } | |
1224 } | |
1225 | |
1226 GCStats* GenCollectedHeap::gc_stats(int level) const { | |
1227 return _gens[level]->gc_stats(); | |
1228 } | |
1229 | |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
647
diff
changeset
|
1230 void GenCollectedHeap::verify(bool allow_dirty, bool silent, bool option /* ignored */) { |
0 | 1231 if (!silent) { |
1232 gclog_or_tty->print("permgen "); | |
1233 } | |
1234 perm_gen()->verify(allow_dirty); | |
1235 for (int i = _n_gens-1; i >= 0; i--) { | |
1236 Generation* g = _gens[i]; | |
1237 if (!silent) { | |
1238 gclog_or_tty->print(g->name()); | |
1239 gclog_or_tty->print(" "); | |
1240 } | |
1241 g->verify(allow_dirty); | |
1242 } | |
1243 if (!silent) { | |
1244 gclog_or_tty->print("remset "); | |
1245 } | |
1246 rem_set()->verify(); | |
1247 if (!silent) { | |
1248 gclog_or_tty->print("ref_proc "); | |
1249 } | |
1250 ReferenceProcessor::verify(); | |
1251 } | |
1252 | |
1253 void GenCollectedHeap::print() const { print_on(tty); } | |
1254 void GenCollectedHeap::print_on(outputStream* st) const { | |
1255 for (int i = 0; i < _n_gens; i++) { | |
1256 _gens[i]->print_on(st); | |
1257 } | |
1258 perm_gen()->print_on(st); | |
1259 } | |
1260 | |
1261 void GenCollectedHeap::gc_threads_do(ThreadClosure* tc) const { | |
1262 if (workers() != NULL) { | |
1263 workers()->threads_do(tc); | |
1264 } | |
1265 #ifndef SERIALGC | |
1266 if (UseConcMarkSweepGC) { | |
1267 ConcurrentMarkSweepThread::threads_do(tc); | |
1268 } | |
1269 #endif // SERIALGC | |
1270 } | |
1271 | |
1272 void GenCollectedHeap::print_gc_threads_on(outputStream* st) const { | |
1273 #ifndef SERIALGC | |
1274 if (UseParNewGC) { | |
1275 workers()->print_worker_threads_on(st); | |
1276 } | |
1277 if (UseConcMarkSweepGC) { | |
1278 ConcurrentMarkSweepThread::print_all_on(st); | |
1279 } | |
1280 #endif // SERIALGC | |
1281 } | |
1282 | |
1283 void GenCollectedHeap::print_tracing_info() const { | |
1284 if (TraceGen0Time) { | |
1285 get_gen(0)->print_summary_info(); | |
1286 } | |
1287 if (TraceGen1Time) { | |
1288 get_gen(1)->print_summary_info(); | |
1289 } | |
1290 } | |
1291 | |
1292 void GenCollectedHeap::print_heap_change(size_t prev_used) const { | |
1293 if (PrintGCDetails && Verbose) { | |
1294 gclog_or_tty->print(" " SIZE_FORMAT | |
1295 "->" SIZE_FORMAT | |
1296 "(" SIZE_FORMAT ")", | |
1297 prev_used, used(), capacity()); | |
1298 } else { | |
1299 gclog_or_tty->print(" " SIZE_FORMAT "K" | |
1300 "->" SIZE_FORMAT "K" | |
1301 "(" SIZE_FORMAT "K)", | |
1302 prev_used / K, used() / K, capacity() / K); | |
1303 } | |
1304 } | |
1305 | |
1306 //New method to print perm gen info with PrintGCDetails flag | |
1307 void GenCollectedHeap::print_perm_heap_change(size_t perm_prev_used) const { | |
1308 gclog_or_tty->print(", [%s :", perm_gen()->short_name()); | |
1309 perm_gen()->print_heap_change(perm_prev_used); | |
1310 gclog_or_tty->print("]"); | |
1311 } | |
1312 | |
1313 class GenGCPrologueClosure: public GenCollectedHeap::GenClosure { | |
1314 private: | |
1315 bool _full; | |
1316 public: | |
1317 void do_generation(Generation* gen) { | |
1318 gen->gc_prologue(_full); | |
1319 } | |
1320 GenGCPrologueClosure(bool full) : _full(full) {}; | |
1321 }; | |
1322 | |
1323 void GenCollectedHeap::gc_prologue(bool full) { | |
1324 assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer"); | |
1325 | |
1326 always_do_update_barrier = false; | |
1327 // Fill TLAB's and such | |
1328 CollectedHeap::accumulate_statistics_all_tlabs(); | |
1329 ensure_parsability(true); // retire TLABs | |
1330 | |
1331 // Call allocation profiler | |
1332 AllocationProfiler::iterate_since_last_gc(); | |
1333 // Walk generations | |
1334 GenGCPrologueClosure blk(full); | |
1335 generation_iterate(&blk, false); // not old-to-young. | |
1336 perm_gen()->gc_prologue(full); | |
1337 }; | |
1338 | |
1339 class GenGCEpilogueClosure: public GenCollectedHeap::GenClosure { | |
1340 private: | |
1341 bool _full; | |
1342 public: | |
1343 void do_generation(Generation* gen) { | |
1344 gen->gc_epilogue(_full); | |
1345 } | |
1346 GenGCEpilogueClosure(bool full) : _full(full) {}; | |
1347 }; | |
1348 | |
1349 void GenCollectedHeap::gc_epilogue(bool full) { | |
1350 // Remember if a partial collection of the heap failed, and | |
1351 // we did a complete collection. | |
1352 if (full && incremental_collection_will_fail()) { | |
1353 set_last_incremental_collection_failed(); | |
1354 } else { | |
1355 clear_last_incremental_collection_failed(); | |
1356 } | |
1357 // Clear the flag, if set; the generation gc_epilogues will set the | |
1358 // flag again if the condition persists despite the collection. | |
1359 clear_incremental_collection_will_fail(); | |
1360 | |
1361 #ifdef COMPILER2 | |
1362 assert(DerivedPointerTable::is_empty(), "derived pointer present"); | |
1363 size_t actual_gap = pointer_delta((HeapWord*) (max_uintx-3), *(end_addr())); | |
1364 guarantee(actual_gap > (size_t)FastAllocateSizeLimit, "inline allocation wraps"); | |
1365 #endif /* COMPILER2 */ | |
1366 | |
1367 resize_all_tlabs(); | |
1368 | |
1369 GenGCEpilogueClosure blk(full); | |
1370 generation_iterate(&blk, false); // not old-to-young. | |
1371 perm_gen()->gc_epilogue(full); | |
1372 | |
1373 always_do_update_barrier = UseConcMarkSweepGC; | |
1374 }; | |
1375 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1376 #ifndef PRODUCT |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1377 class GenGCSaveTopsBeforeGCClosure: public GenCollectedHeap::GenClosure { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1378 private: |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1379 public: |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1380 void do_generation(Generation* gen) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1381 gen->record_spaces_top(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1382 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1383 }; |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1384 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1385 void GenCollectedHeap::record_gen_tops_before_GC() { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1386 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1387 GenGCSaveTopsBeforeGCClosure blk; |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1388 generation_iterate(&blk, false); // not old-to-young. |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1389 perm_gen()->record_spaces_top(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1390 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1391 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1392 #endif // not PRODUCT |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
1393 |
0 | 1394 class GenEnsureParsabilityClosure: public GenCollectedHeap::GenClosure { |
1395 public: | |
1396 void do_generation(Generation* gen) { | |
1397 gen->ensure_parsability(); | |
1398 } | |
1399 }; | |
1400 | |
1401 void GenCollectedHeap::ensure_parsability(bool retire_tlabs) { | |
1402 CollectedHeap::ensure_parsability(retire_tlabs); | |
1403 GenEnsureParsabilityClosure ep_cl; | |
1404 generation_iterate(&ep_cl, false); | |
1405 perm_gen()->ensure_parsability(); | |
1406 } | |
1407 | |
1408 oop GenCollectedHeap::handle_failed_promotion(Generation* gen, | |
1409 oop obj, | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
1410 size_t obj_size) { |
0 | 1411 assert(obj_size == (size_t)obj->size(), "bad obj_size passed in"); |
1412 HeapWord* result = NULL; | |
1413 | |
1414 // First give each higher generation a chance to allocate the promoted object. | |
1415 Generation* allocator = next_gen(gen); | |
1416 if (allocator != NULL) { | |
1417 do { | |
1418 result = allocator->allocate(obj_size, false); | |
1419 } while (result == NULL && (allocator = next_gen(allocator)) != NULL); | |
1420 } | |
1421 | |
1422 if (result == NULL) { | |
1423 // Then give gen and higher generations a chance to expand and allocate the | |
1424 // object. | |
1425 do { | |
1426 result = gen->expand_and_allocate(obj_size, false); | |
1427 } while (result == NULL && (gen = next_gen(gen)) != NULL); | |
1428 } | |
1429 | |
1430 if (result != NULL) { | |
1431 Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size); | |
1432 } | |
1433 return oop(result); | |
1434 } | |
1435 | |
1436 class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure { | |
1437 jlong _time; // in ms | |
1438 jlong _now; // in ms | |
1439 | |
1440 public: | |
1441 GenTimeOfLastGCClosure(jlong now) : _time(now), _now(now) { } | |
1442 | |
1443 jlong time() { return _time; } | |
1444 | |
1445 void do_generation(Generation* gen) { | |
1446 _time = MIN2(_time, gen->time_of_last_gc(_now)); | |
1447 } | |
1448 }; | |
1449 | |
1450 jlong GenCollectedHeap::millis_since_last_gc() { | |
1451 jlong now = os::javaTimeMillis(); | |
1452 GenTimeOfLastGCClosure tolgc_cl(now); | |
1453 // iterate over generations getting the oldest | |
1454 // time that a generation was collected | |
1455 generation_iterate(&tolgc_cl, false); | |
1456 tolgc_cl.do_generation(perm_gen()); | |
1457 // XXX Despite the assert above, since javaTimeMillis() | |
1458 // doesnot guarantee monotonically increasing return | |
1459 // values (note, i didn't say "strictly monotonic"), | |
1460 // we need to guard against getting back a time | |
1461 // later than now. This should be fixed by basing | |
1462 // on someting like gethrtime() which guarantees | |
1463 // monotonicity. Note that cond_wait() is susceptible | |
1464 // to a similar problem, because its interface is | |
1465 // based on absolute time in the form of the | |
1466 // system time's notion of UCT. See also 4506635 | |
1467 // for yet another problem of similar nature. XXX | |
1468 jlong retVal = now - tolgc_cl.time(); | |
1469 if (retVal < 0) { | |
1470 NOT_PRODUCT(warning("time warp: %d", retVal);) | |
1471 return 0; | |
1472 } | |
1473 return retVal; | |
1474 } |