Mercurial > hg > truffle
annotate src/share/vm/memory/generation.cpp @ 453:c96030fff130
6684579: SoftReference processing can be made more efficient
Summary: For current soft-ref clearing policies, we can decide at marking time if a soft-reference will definitely not be cleared, postponing the decision of whether it will definitely be cleared to the final reference processing phase. This can be especially beneficial in the case of concurrent collectors where the marking is usually concurrent but reference processing is usually not.
Reviewed-by: jmasa
author | ysr |
---|---|
date | Thu, 20 Nov 2008 16:56:09 -0800 |
parents | 818a18cd69a8 |
children | e9be0e04635a |
rev | line source |
---|---|
0 | 1 /* |
196 | 2 * Copyright 1997-2008 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 # include "incls/_precompiled.incl" | |
26 # include "incls/_generation.cpp.incl" | |
27 | |
28 Generation::Generation(ReservedSpace rs, size_t initial_size, int level) : | |
29 _level(level), | |
30 _ref_processor(NULL) { | |
31 if (!_virtual_space.initialize(rs, initial_size)) { | |
32 vm_exit_during_initialization("Could not reserve enough space for " | |
33 "object heap"); | |
34 } | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
35 // Mangle all of the the initial generation. |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
36 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
37 MemRegion mangle_region((HeapWord*)_virtual_space.low(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
38 (HeapWord*)_virtual_space.high()); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
39 SpaceMangler::mangle_region(mangle_region); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
40 } |
0 | 41 _reserved = MemRegion((HeapWord*)_virtual_space.low_boundary(), |
42 (HeapWord*)_virtual_space.high_boundary()); | |
43 } | |
44 | |
45 GenerationSpec* Generation::spec() { | |
46 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
47 assert(0 <= level() && level() < gch->_n_gens, "Bad gen level"); | |
48 return gch->_gen_specs[level()]; | |
49 } | |
50 | |
51 size_t Generation::max_capacity() const { | |
52 return reserved().byte_size(); | |
53 } | |
54 | |
55 void Generation::print_heap_change(size_t prev_used) const { | |
56 if (PrintGCDetails && Verbose) { | |
57 gclog_or_tty->print(" " SIZE_FORMAT | |
58 "->" SIZE_FORMAT | |
59 "(" SIZE_FORMAT ")", | |
60 prev_used, used(), capacity()); | |
61 } else { | |
62 gclog_or_tty->print(" " SIZE_FORMAT "K" | |
63 "->" SIZE_FORMAT "K" | |
64 "(" SIZE_FORMAT "K)", | |
65 prev_used / K, used() / K, capacity() / K); | |
66 } | |
67 } | |
68 | |
69 // By default we get a single threaded default reference processor; | |
70 // generations needing multi-threaded refs discovery override this method. | |
71 void Generation::ref_processor_init() { | |
72 assert(_ref_processor == NULL, "a reference processor already exists"); | |
73 assert(!_reserved.is_empty(), "empty generation?"); | |
74 _ref_processor = | |
75 new ReferenceProcessor(_reserved, // span | |
76 refs_discovery_is_atomic(), // atomic_discovery | |
77 refs_discovery_is_mt()); // mt_discovery | |
78 if (_ref_processor == NULL) { | |
79 vm_exit_during_initialization("Could not allocate ReferenceProcessor object"); | |
80 } | |
81 } | |
82 | |
83 void Generation::print() const { print_on(tty); } | |
84 | |
85 void Generation::print_on(outputStream* st) const { | |
86 st->print(" %-20s", name()); | |
87 st->print(" total " SIZE_FORMAT "K, used " SIZE_FORMAT "K", | |
88 capacity()/K, used()/K); | |
89 st->print_cr(" [" INTPTR_FORMAT ", " INTPTR_FORMAT ", " INTPTR_FORMAT ")", | |
90 _virtual_space.low_boundary(), | |
91 _virtual_space.high(), | |
92 _virtual_space.high_boundary()); | |
93 } | |
94 | |
95 void Generation::print_summary_info() { print_summary_info_on(tty); } | |
96 | |
97 void Generation::print_summary_info_on(outputStream* st) { | |
98 StatRecord* sr = stat_record(); | |
99 double time = sr->accumulated_time.seconds(); | |
100 st->print_cr("[Accumulated GC generation %d time %3.7f secs, " | |
101 "%d GC's, avg GC time %3.7f]", | |
102 level(), time, sr->invocations, | |
103 sr->invocations > 0 ? time / sr->invocations : 0.0); | |
104 } | |
105 | |
106 // Utility iterator classes | |
107 | |
108 class GenerationIsInReservedClosure : public SpaceClosure { | |
109 public: | |
110 const void* _p; | |
111 Space* sp; | |
112 virtual void do_space(Space* s) { | |
113 if (sp == NULL) { | |
114 if (s->is_in_reserved(_p)) sp = s; | |
115 } | |
116 } | |
117 GenerationIsInReservedClosure(const void* p) : _p(p), sp(NULL) {} | |
118 }; | |
119 | |
120 class GenerationIsInClosure : public SpaceClosure { | |
121 public: | |
122 const void* _p; | |
123 Space* sp; | |
124 virtual void do_space(Space* s) { | |
125 if (sp == NULL) { | |
126 if (s->is_in(_p)) sp = s; | |
127 } | |
128 } | |
129 GenerationIsInClosure(const void* p) : _p(p), sp(NULL) {} | |
130 }; | |
131 | |
132 bool Generation::is_in(const void* p) const { | |
133 GenerationIsInClosure blk(p); | |
134 ((Generation*)this)->space_iterate(&blk); | |
135 return blk.sp != NULL; | |
136 } | |
137 | |
138 DefNewGeneration* Generation::as_DefNewGeneration() { | |
139 assert((kind() == Generation::DefNew) || | |
140 (kind() == Generation::ParNew) || | |
141 (kind() == Generation::ASParNew), | |
142 "Wrong youngest generation type"); | |
143 return (DefNewGeneration*) this; | |
144 } | |
145 | |
146 Generation* Generation::next_gen() const { | |
147 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
148 int next = level() + 1; | |
149 if (next < gch->_n_gens) { | |
150 return gch->_gens[next]; | |
151 } else { | |
152 return NULL; | |
153 } | |
154 } | |
155 | |
156 size_t Generation::max_contiguous_available() const { | |
157 // The largest number of contiguous free words in this or any higher generation. | |
158 size_t max = 0; | |
159 for (const Generation* gen = this; gen != NULL; gen = gen->next_gen()) { | |
160 size_t avail = gen->contiguous_available(); | |
161 if (avail > max) { | |
162 max = avail; | |
163 } | |
164 } | |
165 return max; | |
166 } | |
167 | |
168 bool Generation::promotion_attempt_is_safe(size_t promotion_in_bytes, | |
169 bool not_used) const { | |
170 if (PrintGC && Verbose) { | |
171 gclog_or_tty->print_cr("Generation::promotion_attempt_is_safe" | |
172 " contiguous_available: " SIZE_FORMAT | |
173 " promotion_in_bytes: " SIZE_FORMAT, | |
174 max_contiguous_available(), promotion_in_bytes); | |
175 } | |
176 return max_contiguous_available() >= promotion_in_bytes; | |
177 } | |
178 | |
179 // Ignores "ref" and calls allocate(). | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
180 oop Generation::promote(oop obj, size_t obj_size) { |
0 | 181 assert(obj_size == (size_t)obj->size(), "bad obj_size passed in"); |
182 | |
183 #ifndef PRODUCT | |
184 if (Universe::heap()->promotion_should_fail()) { | |
185 return NULL; | |
186 } | |
187 #endif // #ifndef PRODUCT | |
188 | |
189 HeapWord* result = allocate(obj_size, false); | |
190 if (result != NULL) { | |
191 Copy::aligned_disjoint_words((HeapWord*)obj, result, obj_size); | |
192 return oop(result); | |
193 } else { | |
194 GenCollectedHeap* gch = GenCollectedHeap::heap(); | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
195 return gch->handle_failed_promotion(this, obj, obj_size); |
0 | 196 } |
197 } | |
198 | |
199 oop Generation::par_promote(int thread_num, | |
200 oop obj, markOop m, size_t word_sz) { | |
201 // Could do a bad general impl here that gets a lock. But no. | |
202 ShouldNotCallThis(); | |
203 return NULL; | |
204 } | |
205 | |
206 void Generation::par_promote_alloc_undo(int thread_num, | |
207 HeapWord* obj, size_t word_sz) { | |
208 // Could do a bad general impl here that gets a lock. But no. | |
209 guarantee(false, "No good general implementation."); | |
210 } | |
211 | |
212 Space* Generation::space_containing(const void* p) const { | |
213 GenerationIsInReservedClosure blk(p); | |
214 // Cast away const | |
215 ((Generation*)this)->space_iterate(&blk); | |
216 return blk.sp; | |
217 } | |
218 | |
219 // Some of these are mediocre general implementations. Should be | |
220 // overridden to get better performance. | |
221 | |
222 class GenerationBlockStartClosure : public SpaceClosure { | |
223 public: | |
224 const void* _p; | |
225 HeapWord* _start; | |
226 virtual void do_space(Space* s) { | |
227 if (_start == NULL && s->is_in_reserved(_p)) { | |
228 _start = s->block_start(_p); | |
229 } | |
230 } | |
231 GenerationBlockStartClosure(const void* p) { _p = p; _start = NULL; } | |
232 }; | |
233 | |
234 HeapWord* Generation::block_start(const void* p) const { | |
235 GenerationBlockStartClosure blk(p); | |
236 // Cast away const | |
237 ((Generation*)this)->space_iterate(&blk); | |
238 return blk._start; | |
239 } | |
240 | |
241 class GenerationBlockSizeClosure : public SpaceClosure { | |
242 public: | |
243 const HeapWord* _p; | |
244 size_t size; | |
245 virtual void do_space(Space* s) { | |
246 if (size == 0 && s->is_in_reserved(_p)) { | |
247 size = s->block_size(_p); | |
248 } | |
249 } | |
250 GenerationBlockSizeClosure(const HeapWord* p) { _p = p; size = 0; } | |
251 }; | |
252 | |
253 size_t Generation::block_size(const HeapWord* p) const { | |
254 GenerationBlockSizeClosure blk(p); | |
255 // Cast away const | |
256 ((Generation*)this)->space_iterate(&blk); | |
257 assert(blk.size > 0, "seems reasonable"); | |
258 return blk.size; | |
259 } | |
260 | |
261 class GenerationBlockIsObjClosure : public SpaceClosure { | |
262 public: | |
263 const HeapWord* _p; | |
264 bool is_obj; | |
265 virtual void do_space(Space* s) { | |
266 if (!is_obj && s->is_in_reserved(_p)) { | |
267 is_obj |= s->block_is_obj(_p); | |
268 } | |
269 } | |
270 GenerationBlockIsObjClosure(const HeapWord* p) { _p = p; is_obj = false; } | |
271 }; | |
272 | |
273 bool Generation::block_is_obj(const HeapWord* p) const { | |
274 GenerationBlockIsObjClosure blk(p); | |
275 // Cast away const | |
276 ((Generation*)this)->space_iterate(&blk); | |
277 return blk.is_obj; | |
278 } | |
279 | |
280 class GenerationOopIterateClosure : public SpaceClosure { | |
281 public: | |
282 OopClosure* cl; | |
283 MemRegion mr; | |
284 virtual void do_space(Space* s) { | |
285 s->oop_iterate(mr, cl); | |
286 } | |
287 GenerationOopIterateClosure(OopClosure* _cl, MemRegion _mr) : | |
288 cl(_cl), mr(_mr) {} | |
289 }; | |
290 | |
291 void Generation::oop_iterate(OopClosure* cl) { | |
292 GenerationOopIterateClosure blk(cl, _reserved); | |
293 space_iterate(&blk); | |
294 } | |
295 | |
296 void Generation::oop_iterate(MemRegion mr, OopClosure* cl) { | |
297 GenerationOopIterateClosure blk(cl, mr); | |
298 space_iterate(&blk); | |
299 } | |
300 | |
301 void Generation::younger_refs_in_space_iterate(Space* sp, | |
302 OopsInGenClosure* cl) { | |
303 GenRemSet* rs = SharedHeap::heap()->rem_set(); | |
304 rs->younger_refs_in_space_iterate(sp, cl); | |
305 } | |
306 | |
307 class GenerationObjIterateClosure : public SpaceClosure { | |
308 private: | |
309 ObjectClosure* _cl; | |
310 public: | |
311 virtual void do_space(Space* s) { | |
312 s->object_iterate(_cl); | |
313 } | |
314 GenerationObjIterateClosure(ObjectClosure* cl) : _cl(cl) {} | |
315 }; | |
316 | |
317 void Generation::object_iterate(ObjectClosure* cl) { | |
318 GenerationObjIterateClosure blk(cl); | |
319 space_iterate(&blk); | |
320 } | |
321 | |
322 void Generation::prepare_for_compaction(CompactPoint* cp) { | |
323 // Generic implementation, can be specialized | |
324 CompactibleSpace* space = first_compaction_space(); | |
325 while (space != NULL) { | |
326 space->prepare_for_compaction(cp); | |
327 space = space->next_compaction_space(); | |
328 } | |
329 } | |
330 | |
331 class AdjustPointersClosure: public SpaceClosure { | |
332 public: | |
333 void do_space(Space* sp) { | |
334 sp->adjust_pointers(); | |
335 } | |
336 }; | |
337 | |
338 void Generation::adjust_pointers() { | |
339 // Note that this is done over all spaces, not just the compactible | |
340 // ones. | |
341 AdjustPointersClosure blk; | |
342 space_iterate(&blk, true); | |
343 } | |
344 | |
345 void Generation::compact() { | |
346 CompactibleSpace* sp = first_compaction_space(); | |
347 while (sp != NULL) { | |
348 sp->compact(); | |
349 sp = sp->next_compaction_space(); | |
350 } | |
351 } | |
352 | |
353 CardGeneration::CardGeneration(ReservedSpace rs, size_t initial_byte_size, | |
354 int level, | |
355 GenRemSet* remset) : | |
356 Generation(rs, initial_byte_size, level), _rs(remset) | |
357 { | |
358 HeapWord* start = (HeapWord*)rs.base(); | |
359 size_t reserved_byte_size = rs.size(); | |
360 assert((uintptr_t(start) & 3) == 0, "bad alignment"); | |
361 assert((reserved_byte_size & 3) == 0, "bad alignment"); | |
362 MemRegion reserved_mr(start, heap_word_size(reserved_byte_size)); | |
363 _bts = new BlockOffsetSharedArray(reserved_mr, | |
364 heap_word_size(initial_byte_size)); | |
365 MemRegion committed_mr(start, heap_word_size(initial_byte_size)); | |
366 _rs->resize_covered_region(committed_mr); | |
367 if (_bts == NULL) | |
368 vm_exit_during_initialization("Could not allocate a BlockOffsetArray"); | |
369 | |
370 // Verify that the start and end of this generation is the start of a card. | |
371 // If this wasn't true, a single card could span more than on generation, | |
372 // which would cause problems when we commit/uncommit memory, and when we | |
373 // clear and dirty cards. | |
374 guarantee(_rs->is_aligned(reserved_mr.start()), "generation must be card aligned"); | |
375 if (reserved_mr.end() != Universe::heap()->reserved_region().end()) { | |
376 // Don't check at the very end of the heap as we'll assert that we're probing off | |
377 // the end if we try. | |
378 guarantee(_rs->is_aligned(reserved_mr.end()), "generation must be card aligned"); | |
379 } | |
380 } | |
381 | |
271
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
382 bool CardGeneration::expand(size_t bytes, size_t expand_bytes) { |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
383 assert_locked_or_safepoint(Heap_lock); |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
384 if (bytes == 0) { |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
385 return true; // That's what grow_by(0) would return |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
386 } |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
387 size_t aligned_bytes = ReservedSpace::page_align_size_up(bytes); |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
388 if (aligned_bytes == 0){ |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
389 // The alignment caused the number of bytes to wrap. An expand_by(0) will |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
390 // return true with the implication that an expansion was done when it |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
391 // was not. A call to expand implies a best effort to expand by "bytes" |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
392 // but not a guarantee. Align down to give a best effort. This is likely |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
393 // the most that the generation can expand since it has some capacity to |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
394 // start with. |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
395 aligned_bytes = ReservedSpace::page_align_size_down(bytes); |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
396 } |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
397 size_t aligned_expand_bytes = ReservedSpace::page_align_size_up(expand_bytes); |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
398 bool success = false; |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
399 if (aligned_expand_bytes > aligned_bytes) { |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
400 success = grow_by(aligned_expand_bytes); |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
401 } |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
402 if (!success) { |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
403 success = grow_by(aligned_bytes); |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
404 } |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
405 if (!success) { |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
406 success = grow_to_reserved(); |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
407 } |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
408 if (PrintGC && Verbose) { |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
409 if (success && GC_locker::is_active()) { |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
410 gclog_or_tty->print_cr("Garbage collection disabled, expanded heap instead"); |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
411 } |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
412 } |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
413 |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
414 return success; |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
415 } |
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
416 |
0 | 417 |
418 // No young generation references, clear this generation's cards. | |
419 void CardGeneration::clear_remembered_set() { | |
420 _rs->clear(reserved()); | |
421 } | |
422 | |
423 | |
424 // Objects in this generation may have moved, invalidate this | |
425 // generation's cards. | |
426 void CardGeneration::invalidate_remembered_set() { | |
427 _rs->invalidate(used_region()); | |
428 } | |
429 | |
430 | |
431 // Currently nothing to do. | |
432 void CardGeneration::prepare_for_verify() {} | |
433 | |
434 | |
435 void OneContigSpaceCardGeneration::collect(bool full, | |
436 bool clear_all_soft_refs, | |
437 size_t size, | |
438 bool is_tlab) { | |
439 SpecializationStats::clear(); | |
440 // Temporarily expand the span of our ref processor, so | |
441 // refs discovery is over the entire heap, not just this generation | |
442 ReferenceProcessorSpanMutator | |
443 x(ref_processor(), GenCollectedHeap::heap()->reserved_region()); | |
444 GenMarkSweep::invoke_at_safepoint(_level, ref_processor(), clear_all_soft_refs); | |
445 SpecializationStats::print(); | |
446 } | |
447 | |
448 HeapWord* | |
449 OneContigSpaceCardGeneration::expand_and_allocate(size_t word_size, | |
450 bool is_tlab, | |
451 bool parallel) { | |
452 assert(!is_tlab, "OneContigSpaceCardGeneration does not support TLAB allocation"); | |
453 if (parallel) { | |
454 MutexLocker x(ParGCRareEvent_lock); | |
455 HeapWord* result = NULL; | |
456 size_t byte_size = word_size * HeapWordSize; | |
457 while (true) { | |
458 expand(byte_size, _min_heap_delta_bytes); | |
459 if (GCExpandToAllocateDelayMillis > 0) { | |
460 os::sleep(Thread::current(), GCExpandToAllocateDelayMillis, false); | |
461 } | |
462 result = _the_space->par_allocate(word_size); | |
463 if ( result != NULL) { | |
464 return result; | |
465 } else { | |
466 // If there's not enough expansion space available, give up. | |
467 if (_virtual_space.uncommitted_size() < byte_size) { | |
468 return NULL; | |
469 } | |
470 // else try again | |
471 } | |
472 } | |
473 } else { | |
474 expand(word_size*HeapWordSize, _min_heap_delta_bytes); | |
475 return _the_space->allocate(word_size); | |
476 } | |
477 } | |
478 | |
271
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
479 bool OneContigSpaceCardGeneration::expand(size_t bytes, size_t expand_bytes) { |
0 | 480 GCMutexLocker x(ExpandHeap_lock); |
271
818a18cd69a8
6730514: assertion failure in mangling code when expanding by 0 bytes
jmasa
parents:
269
diff
changeset
|
481 return CardGeneration::expand(bytes, expand_bytes); |
0 | 482 } |
483 | |
484 | |
485 void OneContigSpaceCardGeneration::shrink(size_t bytes) { | |
486 assert_locked_or_safepoint(ExpandHeap_lock); | |
487 size_t size = ReservedSpace::page_align_size_down(bytes); | |
488 if (size > 0) { | |
489 shrink_by(size); | |
490 } | |
491 } | |
492 | |
493 | |
494 size_t OneContigSpaceCardGeneration::capacity() const { | |
495 return _the_space->capacity(); | |
496 } | |
497 | |
498 | |
499 size_t OneContigSpaceCardGeneration::used() const { | |
500 return _the_space->used(); | |
501 } | |
502 | |
503 | |
504 size_t OneContigSpaceCardGeneration::free() const { | |
505 return _the_space->free(); | |
506 } | |
507 | |
508 MemRegion OneContigSpaceCardGeneration::used_region() const { | |
509 return the_space()->used_region(); | |
510 } | |
511 | |
512 size_t OneContigSpaceCardGeneration::unsafe_max_alloc_nogc() const { | |
513 return _the_space->free(); | |
514 } | |
515 | |
516 size_t OneContigSpaceCardGeneration::contiguous_available() const { | |
517 return _the_space->free() + _virtual_space.uncommitted_size(); | |
518 } | |
519 | |
520 bool OneContigSpaceCardGeneration::grow_by(size_t bytes) { | |
521 assert_locked_or_safepoint(ExpandHeap_lock); | |
522 bool result = _virtual_space.expand_by(bytes); | |
523 if (result) { | |
524 size_t new_word_size = | |
525 heap_word_size(_virtual_space.committed_size()); | |
526 MemRegion mr(_the_space->bottom(), new_word_size); | |
527 // Expand card table | |
528 Universe::heap()->barrier_set()->resize_covered_region(mr); | |
529 // Expand shared block offset array | |
530 _bts->resize(new_word_size); | |
531 | |
532 // Fix for bug #4668531 | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
533 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
534 MemRegion mangle_region(_the_space->end(), |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
535 (HeapWord*)_virtual_space.high()); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
536 SpaceMangler::mangle_region(mangle_region); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
537 } |
0 | 538 |
539 // Expand space -- also expands space's BOT | |
540 // (which uses (part of) shared array above) | |
541 _the_space->set_end((HeapWord*)_virtual_space.high()); | |
542 | |
543 // update the space and generation capacity counters | |
544 update_counters(); | |
545 | |
546 if (Verbose && PrintGC) { | |
547 size_t new_mem_size = _virtual_space.committed_size(); | |
548 size_t old_mem_size = new_mem_size - bytes; | |
549 gclog_or_tty->print_cr("Expanding %s from " SIZE_FORMAT "K by " | |
550 SIZE_FORMAT "K to " SIZE_FORMAT "K", | |
551 name(), old_mem_size/K, bytes/K, new_mem_size/K); | |
552 } | |
553 } | |
554 return result; | |
555 } | |
556 | |
557 | |
558 bool OneContigSpaceCardGeneration::grow_to_reserved() { | |
559 assert_locked_or_safepoint(ExpandHeap_lock); | |
560 bool success = true; | |
561 const size_t remaining_bytes = _virtual_space.uncommitted_size(); | |
562 if (remaining_bytes > 0) { | |
563 success = grow_by(remaining_bytes); | |
564 DEBUG_ONLY(if (!success) warning("grow to reserved failed");) | |
565 } | |
566 return success; | |
567 } | |
568 | |
569 void OneContigSpaceCardGeneration::shrink_by(size_t bytes) { | |
570 assert_locked_or_safepoint(ExpandHeap_lock); | |
571 // Shrink committed space | |
572 _virtual_space.shrink_by(bytes); | |
573 // Shrink space; this also shrinks the space's BOT | |
574 _the_space->set_end((HeapWord*) _virtual_space.high()); | |
575 size_t new_word_size = heap_word_size(_the_space->capacity()); | |
576 // Shrink the shared block offset array | |
577 _bts->resize(new_word_size); | |
578 MemRegion mr(_the_space->bottom(), new_word_size); | |
579 // Shrink the card table | |
580 Universe::heap()->barrier_set()->resize_covered_region(mr); | |
581 | |
582 if (Verbose && PrintGC) { | |
583 size_t new_mem_size = _virtual_space.committed_size(); | |
584 size_t old_mem_size = new_mem_size + bytes; | |
585 gclog_or_tty->print_cr("Shrinking %s from " SIZE_FORMAT "K to " SIZE_FORMAT "K", | |
586 name(), old_mem_size/K, new_mem_size/K); | |
587 } | |
588 } | |
589 | |
590 // Currently nothing to do. | |
591 void OneContigSpaceCardGeneration::prepare_for_verify() {} | |
592 | |
593 | |
594 void OneContigSpaceCardGeneration::object_iterate(ObjectClosure* blk) { | |
595 _the_space->object_iterate(blk); | |
596 } | |
597 | |
598 void OneContigSpaceCardGeneration::space_iterate(SpaceClosure* blk, | |
599 bool usedOnly) { | |
600 blk->do_space(_the_space); | |
601 } | |
602 | |
603 void OneContigSpaceCardGeneration::object_iterate_since_last_GC(ObjectClosure* blk) { | |
604 // Deal with delayed initialization of _the_space, | |
605 // and lack of initialization of _last_gc. | |
606 if (_last_gc.space() == NULL) { | |
607 assert(the_space() != NULL, "shouldn't be NULL"); | |
608 _last_gc = the_space()->bottom_mark(); | |
609 } | |
610 the_space()->object_iterate_from(_last_gc, blk); | |
611 } | |
612 | |
613 void OneContigSpaceCardGeneration::younger_refs_iterate(OopsInGenClosure* blk) { | |
614 blk->set_generation(this); | |
615 younger_refs_in_space_iterate(_the_space, blk); | |
616 blk->reset_generation(); | |
617 } | |
618 | |
619 void OneContigSpaceCardGeneration::save_marks() { | |
620 _the_space->set_saved_mark(); | |
621 } | |
622 | |
623 | |
624 void OneContigSpaceCardGeneration::reset_saved_marks() { | |
625 _the_space->reset_saved_mark(); | |
626 } | |
627 | |
628 | |
629 bool OneContigSpaceCardGeneration::no_allocs_since_save_marks() { | |
630 return _the_space->saved_mark_at_top(); | |
631 } | |
632 | |
633 #define OneContig_SINCE_SAVE_MARKS_ITERATE_DEFN(OopClosureType, nv_suffix) \ | |
634 \ | |
635 void OneContigSpaceCardGeneration:: \ | |
636 oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) { \ | |
637 blk->set_generation(this); \ | |
638 _the_space->oop_since_save_marks_iterate##nv_suffix(blk); \ | |
639 blk->reset_generation(); \ | |
640 save_marks(); \ | |
641 } | |
642 | |
643 ALL_SINCE_SAVE_MARKS_CLOSURES(OneContig_SINCE_SAVE_MARKS_ITERATE_DEFN) | |
644 | |
645 #undef OneContig_SINCE_SAVE_MARKS_ITERATE_DEFN | |
646 | |
647 | |
648 void OneContigSpaceCardGeneration::gc_epilogue(bool full) { | |
649 _last_gc = WaterMark(the_space(), the_space()->top()); | |
650 | |
651 // update the generation and space performance counters | |
652 update_counters(); | |
263
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
653 if (ZapUnusedHeapArea) { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
654 the_space()->check_mangled_unused_area_complete(); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
655 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
656 } |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
657 |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
658 void OneContigSpaceCardGeneration::record_spaces_top() { |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
659 assert(ZapUnusedHeapArea, "Not mangling unused space"); |
12eea04c8b06
6672698: mangle_unused_area() should not remangle the entire heap at each collection.
jmasa
parents:
113
diff
changeset
|
660 the_space()->set_top_for_allocations(); |
0 | 661 } |
662 | |
663 void OneContigSpaceCardGeneration::verify(bool allow_dirty) { | |
664 the_space()->verify(allow_dirty); | |
665 } | |
666 | |
667 void OneContigSpaceCardGeneration::print_on(outputStream* st) const { | |
668 Generation::print_on(st); | |
669 st->print(" the"); | |
670 the_space()->print_on(st); | |
671 } |