comparison src/share/vm/gc_implementation/parNew/parNewGeneration.cpp @ 0:a61af66fc99e jdk7-b24

Initial load
author duke
date Sat, 01 Dec 2007 00:00:00 +0000
parents
children 73e96e5c30df
comparison
equal deleted inserted replaced
-1:000000000000 0:a61af66fc99e
1 /*
2 * Copyright 2001-2007 Sun Microsystems, Inc. All Rights Reserved.
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/_parNewGeneration.cpp.incl"
27
28 #ifdef _MSC_VER
29 #pragma warning( push )
30 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
31 #endif
32 ParScanThreadState::ParScanThreadState(Space* to_space_,
33 ParNewGeneration* gen_,
34 Generation* old_gen_,
35 int thread_num_,
36 ObjToScanQueueSet* work_queue_set_,
37 size_t desired_plab_sz_,
38 ParallelTaskTerminator& term_) :
39 _to_space(to_space_), _old_gen(old_gen_), _thread_num(thread_num_),
40 _work_queue(work_queue_set_->queue(thread_num_)), _to_space_full(false),
41 _ageTable(false), // false ==> not the global age table, no perf data.
42 _to_space_alloc_buffer(desired_plab_sz_),
43 _to_space_closure(gen_, this), _old_gen_closure(gen_, this),
44 _to_space_root_closure(gen_, this), _old_gen_root_closure(gen_, this),
45 _older_gen_closure(gen_, this),
46 _evacuate_followers(this, &_to_space_closure, &_old_gen_closure,
47 &_to_space_root_closure, gen_, &_old_gen_root_closure,
48 work_queue_set_, &term_),
49 _is_alive_closure(gen_), _scan_weak_ref_closure(gen_, this),
50 _keep_alive_closure(&_scan_weak_ref_closure),
51 _pushes(0), _pops(0), _steals(0), _steal_attempts(0), _term_attempts(0),
52 _strong_roots_time(0.0), _term_time(0.0)
53 {
54 _survivor_chunk_array =
55 (ChunkArray*) old_gen()->get_data_recorder(thread_num());
56 _hash_seed = 17; // Might want to take time-based random value.
57 _start = os::elapsedTime();
58 _old_gen_closure.set_generation(old_gen_);
59 _old_gen_root_closure.set_generation(old_gen_);
60 }
61 #ifdef _MSC_VER
62 #pragma warning( pop )
63 #endif
64
65 void ParScanThreadState::record_survivor_plab(HeapWord* plab_start,
66 size_t plab_word_size) {
67 ChunkArray* sca = survivor_chunk_array();
68 if (sca != NULL) {
69 // A non-null SCA implies that we want the PLAB data recorded.
70 sca->record_sample(plab_start, plab_word_size);
71 }
72 }
73
74 bool ParScanThreadState::should_be_partially_scanned(oop new_obj, oop old_obj) const {
75 return new_obj->is_objArray() &&
76 arrayOop(new_obj)->length() > ParGCArrayScanChunk &&
77 new_obj != old_obj;
78 }
79
80 void ParScanThreadState::scan_partial_array_and_push_remainder(oop old) {
81 assert(old->is_objArray(), "must be obj array");
82 assert(old->is_forwarded(), "must be forwarded");
83 assert(Universe::heap()->is_in_reserved(old), "must be in heap.");
84 assert(!_old_gen->is_in(old), "must be in young generation.");
85
86 objArrayOop obj = objArrayOop(old->forwardee());
87 // Process ParGCArrayScanChunk elements now
88 // and push the remainder back onto queue
89 int start = arrayOop(old)->length();
90 int end = obj->length();
91 int remainder = end - start;
92 assert(start <= end, "just checking");
93 if (remainder > 2 * ParGCArrayScanChunk) {
94 // Test above combines last partial chunk with a full chunk
95 end = start + ParGCArrayScanChunk;
96 arrayOop(old)->set_length(end);
97 // Push remainder.
98 bool ok = work_queue()->push(old);
99 assert(ok, "just popped, push must be okay");
100 note_push();
101 } else {
102 // Restore length so that it can be used if there
103 // is a promotion failure and forwarding pointers
104 // must be removed.
105 arrayOop(old)->set_length(end);
106 }
107 // process our set of indices (include header in first chunk)
108 oop* start_addr = start == 0 ? (oop*)obj : obj->obj_at_addr(start);
109 oop* end_addr = obj->base() + end; // obj_at_addr(end) asserts end < length
110 MemRegion mr((HeapWord*)start_addr, (HeapWord*)end_addr);
111 if ((HeapWord *)obj < young_old_boundary()) {
112 // object is in to_space
113 obj->oop_iterate(&_to_space_closure, mr);
114 } else {
115 // object is in old generation
116 obj->oop_iterate(&_old_gen_closure, mr);
117 }
118 }
119
120
121 void ParScanThreadState::trim_queues(int max_size) {
122 ObjToScanQueue* queue = work_queue();
123 while (queue->size() > (juint)max_size) {
124 oop obj_to_scan;
125 if (queue->pop_local(obj_to_scan)) {
126 note_pop();
127
128 if ((HeapWord *)obj_to_scan < young_old_boundary()) {
129 if (obj_to_scan->is_objArray() &&
130 obj_to_scan->is_forwarded() &&
131 obj_to_scan->forwardee() != obj_to_scan) {
132 scan_partial_array_and_push_remainder(obj_to_scan);
133 } else {
134 // object is in to_space
135 obj_to_scan->oop_iterate(&_to_space_closure);
136 }
137 } else {
138 // object is in old generation
139 obj_to_scan->oop_iterate(&_old_gen_closure);
140 }
141 }
142 }
143 }
144
145 HeapWord* ParScanThreadState::alloc_in_to_space_slow(size_t word_sz) {
146
147 // Otherwise, if the object is small enough, try to reallocate the
148 // buffer.
149 HeapWord* obj = NULL;
150 if (!_to_space_full) {
151 ParGCAllocBuffer* const plab = to_space_alloc_buffer();
152 Space* const sp = to_space();
153 if (word_sz * 100 <
154 ParallelGCBufferWastePct * plab->word_sz()) {
155 // Is small enough; abandon this buffer and start a new one.
156 plab->retire(false, false);
157 size_t buf_size = plab->word_sz();
158 HeapWord* buf_space = sp->par_allocate(buf_size);
159 if (buf_space == NULL) {
160 const size_t min_bytes =
161 ParGCAllocBuffer::min_size() << LogHeapWordSize;
162 size_t free_bytes = sp->free();
163 while(buf_space == NULL && free_bytes >= min_bytes) {
164 buf_size = free_bytes >> LogHeapWordSize;
165 assert(buf_size == (size_t)align_object_size(buf_size),
166 "Invariant");
167 buf_space = sp->par_allocate(buf_size);
168 free_bytes = sp->free();
169 }
170 }
171 if (buf_space != NULL) {
172 plab->set_word_size(buf_size);
173 plab->set_buf(buf_space);
174 record_survivor_plab(buf_space, buf_size);
175 obj = plab->allocate(word_sz);
176 // Note that we cannot compare buf_size < word_sz below
177 // because of AlignmentReserve (see ParGCAllocBuffer::allocate()).
178 assert(obj != NULL || plab->words_remaining() < word_sz,
179 "Else should have been able to allocate");
180 // It's conceivable that we may be able to use the
181 // buffer we just grabbed for subsequent small requests
182 // even if not for this one.
183 } else {
184 // We're used up.
185 _to_space_full = true;
186 }
187
188 } else {
189 // Too large; allocate the object individually.
190 obj = sp->par_allocate(word_sz);
191 }
192 }
193 return obj;
194 }
195
196
197 void ParScanThreadState::undo_alloc_in_to_space(HeapWord* obj,
198 size_t word_sz) {
199 // Is the alloc in the current alloc buffer?
200 if (to_space_alloc_buffer()->contains(obj)) {
201 assert(to_space_alloc_buffer()->contains(obj + word_sz - 1),
202 "Should contain whole object.");
203 to_space_alloc_buffer()->undo_allocation(obj, word_sz);
204 } else {
205 SharedHeap::fill_region_with_object(MemRegion(obj, word_sz));
206 }
207 }
208
209 class ParScanThreadStateSet: private ResourceArray {
210 public:
211 // Initializes states for the specified number of threads;
212 ParScanThreadStateSet(int num_threads,
213 Space& to_space,
214 ParNewGeneration& gen,
215 Generation& old_gen,
216 ObjToScanQueueSet& queue_set,
217 size_t desired_plab_sz,
218 ParallelTaskTerminator& term);
219 inline ParScanThreadState& thread_sate(int i);
220 int pushes() { return _pushes; }
221 int pops() { return _pops; }
222 int steals() { return _steals; }
223 void reset();
224 void flush();
225 private:
226 ParallelTaskTerminator& _term;
227 ParNewGeneration& _gen;
228 Generation& _next_gen;
229 // staticstics
230 int _pushes;
231 int _pops;
232 int _steals;
233 };
234
235
236 ParScanThreadStateSet::ParScanThreadStateSet(
237 int num_threads, Space& to_space, ParNewGeneration& gen,
238 Generation& old_gen, ObjToScanQueueSet& queue_set,
239 size_t desired_plab_sz, ParallelTaskTerminator& term)
240 : ResourceArray(sizeof(ParScanThreadState), num_threads),
241 _gen(gen), _next_gen(old_gen), _term(term),
242 _pushes(0), _pops(0), _steals(0)
243 {
244 assert(num_threads > 0, "sanity check!");
245 // Initialize states.
246 for (int i = 0; i < num_threads; ++i) {
247 new ((ParScanThreadState*)_data + i)
248 ParScanThreadState(&to_space, &gen, &old_gen, i, &queue_set,
249 desired_plab_sz, term);
250 }
251 }
252
253 inline ParScanThreadState& ParScanThreadStateSet::thread_sate(int i)
254 {
255 assert(i >= 0 && i < length(), "sanity check!");
256 return ((ParScanThreadState*)_data)[i];
257 }
258
259
260 void ParScanThreadStateSet::reset()
261 {
262 _term.reset_for_reuse();
263 }
264
265 void ParScanThreadStateSet::flush()
266 {
267 for (int i = 0; i < length(); ++i) {
268 ParScanThreadState& par_scan_state = thread_sate(i);
269
270 // Flush stats related to To-space PLAB activity and
271 // retire the last buffer.
272 par_scan_state.to_space_alloc_buffer()->
273 flush_stats_and_retire(_gen.plab_stats(),
274 false /* !retain */);
275
276 // Every thread has its own age table. We need to merge
277 // them all into one.
278 ageTable *local_table = par_scan_state.age_table();
279 _gen.age_table()->merge(local_table);
280
281 // Inform old gen that we're done.
282 _next_gen.par_promote_alloc_done(i);
283 _next_gen.par_oop_since_save_marks_iterate_done(i);
284
285 // Flush stats related to work queue activity (push/pop/steal)
286 // This could conceivably become a bottleneck; if so, we'll put the
287 // stat's gathering under the flag.
288 if (PAR_STATS_ENABLED) {
289 _pushes += par_scan_state.pushes();
290 _pops += par_scan_state.pops();
291 _steals += par_scan_state.steals();
292 if (ParallelGCVerbose) {
293 gclog_or_tty->print("Thread %d complete:\n"
294 " Pushes: %7d Pops: %7d Steals %7d (in %d attempts)\n",
295 i, par_scan_state.pushes(), par_scan_state.pops(),
296 par_scan_state.steals(), par_scan_state.steal_attempts());
297 if (par_scan_state.overflow_pushes() > 0 ||
298 par_scan_state.overflow_refills() > 0) {
299 gclog_or_tty->print(" Overflow pushes: %7d "
300 "Overflow refills: %7d for %d objs.\n",
301 par_scan_state.overflow_pushes(),
302 par_scan_state.overflow_refills(),
303 par_scan_state.overflow_refill_objs());
304 }
305
306 double elapsed = par_scan_state.elapsed();
307 double strong_roots = par_scan_state.strong_roots_time();
308 double term = par_scan_state.term_time();
309 gclog_or_tty->print(
310 " Elapsed: %7.2f ms.\n"
311 " Strong roots: %7.2f ms (%6.2f%%)\n"
312 " Termination: %7.2f ms (%6.2f%%) (in %d entries)\n",
313 elapsed * 1000.0,
314 strong_roots * 1000.0, (strong_roots*100.0/elapsed),
315 term * 1000.0, (term*100.0/elapsed),
316 par_scan_state.term_attempts());
317 }
318 }
319 }
320 }
321
322
323 ParScanClosure::ParScanClosure(ParNewGeneration* g,
324 ParScanThreadState* par_scan_state) :
325 OopsInGenClosure(g), _par_scan_state(par_scan_state), _g(g)
326 {
327 assert(_g->level() == 0, "Optimized for youngest generation");
328 _boundary = _g->reserved().end();
329 }
330
331 ParScanWeakRefClosure::ParScanWeakRefClosure(ParNewGeneration* g,
332 ParScanThreadState* par_scan_state)
333 : ScanWeakRefClosure(g), _par_scan_state(par_scan_state)
334 {
335 }
336
337 #ifdef WIN32
338 #pragma warning(disable: 4786) /* identifier was truncated to '255' characters in the browser information */
339 #endif
340
341 ParEvacuateFollowersClosure::ParEvacuateFollowersClosure(
342 ParScanThreadState* par_scan_state_,
343 ParScanWithoutBarrierClosure* to_space_closure_,
344 ParScanWithBarrierClosure* old_gen_closure_,
345 ParRootScanWithoutBarrierClosure* to_space_root_closure_,
346 ParNewGeneration* par_gen_,
347 ParRootScanWithBarrierTwoGensClosure* old_gen_root_closure_,
348 ObjToScanQueueSet* task_queues_,
349 ParallelTaskTerminator* terminator_) :
350
351 _par_scan_state(par_scan_state_),
352 _to_space_closure(to_space_closure_),
353 _old_gen_closure(old_gen_closure_),
354 _to_space_root_closure(to_space_root_closure_),
355 _old_gen_root_closure(old_gen_root_closure_),
356 _par_gen(par_gen_),
357 _task_queues(task_queues_),
358 _terminator(terminator_)
359 {}
360
361 void ParEvacuateFollowersClosure::do_void() {
362 ObjToScanQueue* work_q = par_scan_state()->work_queue();
363
364 while (true) {
365
366 // Scan to-space and old-gen objs until we run out of both.
367 oop obj_to_scan;
368 par_scan_state()->trim_queues(0);
369
370 // We have no local work, attempt to steal from other threads.
371
372 // attempt to steal work from promoted.
373 par_scan_state()->note_steal_attempt();
374 if (task_queues()->steal(par_scan_state()->thread_num(),
375 par_scan_state()->hash_seed(),
376 obj_to_scan)) {
377 par_scan_state()->note_steal();
378 bool res = work_q->push(obj_to_scan);
379 assert(res, "Empty queue should have room for a push.");
380
381 par_scan_state()->note_push();
382 // if successful, goto Start.
383 continue;
384
385 // try global overflow list.
386 } else if (par_gen()->take_from_overflow_list(par_scan_state())) {
387 continue;
388 }
389
390 // Otherwise, offer termination.
391 par_scan_state()->start_term_time();
392 if (terminator()->offer_termination()) break;
393 par_scan_state()->end_term_time();
394 }
395 // Finish the last termination pause.
396 par_scan_state()->end_term_time();
397 }
398
399 ParNewGenTask::ParNewGenTask(ParNewGeneration* gen, Generation* next_gen,
400 HeapWord* young_old_boundary, ParScanThreadStateSet* state_set) :
401 AbstractGangTask("ParNewGeneration collection"),
402 _gen(gen), _next_gen(next_gen),
403 _young_old_boundary(young_old_boundary),
404 _state_set(state_set)
405 {}
406
407 void ParNewGenTask::work(int i) {
408 GenCollectedHeap* gch = GenCollectedHeap::heap();
409 // Since this is being done in a separate thread, need new resource
410 // and handle marks.
411 ResourceMark rm;
412 HandleMark hm;
413 // We would need multiple old-gen queues otherwise.
414 guarantee(gch->n_gens() == 2,
415 "Par young collection currently only works with one older gen.");
416
417 Generation* old_gen = gch->next_gen(_gen);
418
419 ParScanThreadState& par_scan_state = _state_set->thread_sate(i);
420 par_scan_state.set_young_old_boundary(_young_old_boundary);
421
422 par_scan_state.start_strong_roots();
423 gch->gen_process_strong_roots(_gen->level(),
424 true, // Process younger gens, if any,
425 // as strong roots.
426 false,// not collecting perm generation.
427 SharedHeap::SO_AllClasses,
428 &par_scan_state.older_gen_closure(),
429 &par_scan_state.to_space_root_closure());
430 par_scan_state.end_strong_roots();
431
432 // "evacuate followers".
433 par_scan_state.evacuate_followers_closure().do_void();
434 }
435
436 #ifdef _MSC_VER
437 #pragma warning( push )
438 #pragma warning( disable:4355 ) // 'this' : used in base member initializer list
439 #endif
440 ParNewGeneration::
441 ParNewGeneration(ReservedSpace rs, size_t initial_byte_size, int level)
442 : DefNewGeneration(rs, initial_byte_size, level, "PCopy"),
443 _overflow_list(NULL),
444 _is_alive_closure(this),
445 _plab_stats(YoungPLABSize, PLABWeight)
446 {
447 _task_queues = new ObjToScanQueueSet(ParallelGCThreads);
448 guarantee(_task_queues != NULL, "task_queues allocation failure.");
449
450 for (uint i1 = 0; i1 < ParallelGCThreads; i1++) {
451 ObjToScanQueuePadded *q_padded = new ObjToScanQueuePadded();
452 guarantee(q_padded != NULL, "work_queue Allocation failure.");
453
454 _task_queues->register_queue(i1, &q_padded->work_queue);
455 }
456
457 for (uint i2 = 0; i2 < ParallelGCThreads; i2++)
458 _task_queues->queue(i2)->initialize();
459
460 if (UsePerfData) {
461 EXCEPTION_MARK;
462 ResourceMark rm;
463
464 const char* cname =
465 PerfDataManager::counter_name(_gen_counters->name_space(), "threads");
466 PerfDataManager::create_constant(SUN_GC, cname, PerfData::U_None,
467 ParallelGCThreads, CHECK);
468 }
469 }
470 #ifdef _MSC_VER
471 #pragma warning( pop )
472 #endif
473
474 // ParNewGeneration::
475 ParKeepAliveClosure::ParKeepAliveClosure(ParScanWeakRefClosure* cl) :
476 DefNewGeneration::KeepAliveClosure(cl), _par_cl(cl) {}
477
478 void
479 // ParNewGeneration::
480 ParKeepAliveClosure::do_oop(oop* p) {
481 // We never expect to see a null reference being processed
482 // as a weak reference.
483 assert (*p != NULL, "expected non-null ref");
484 assert ((*p)->is_oop(), "expected an oop while scanning weak refs");
485
486 _par_cl->do_oop_nv(p);
487
488 if (Universe::heap()->is_in_reserved(p)) {
489 _rs->write_ref_field_gc_par(p, *p);
490 }
491 }
492
493 // ParNewGeneration::
494 KeepAliveClosure::KeepAliveClosure(ScanWeakRefClosure* cl) :
495 DefNewGeneration::KeepAliveClosure(cl) {}
496
497 void
498 // ParNewGeneration::
499 KeepAliveClosure::do_oop(oop* p) {
500 // We never expect to see a null reference being processed
501 // as a weak reference.
502 assert (*p != NULL, "expected non-null ref");
503 assert ((*p)->is_oop(), "expected an oop while scanning weak refs");
504
505 _cl->do_oop_nv(p);
506
507 if (Universe::heap()->is_in_reserved(p)) {
508 _rs->write_ref_field_gc_par(p, *p);
509 }
510 }
511
512 void ScanClosureWithParBarrier::do_oop(oop* p) {
513 oop obj = *p;
514 // Should we copy the obj?
515 if (obj != NULL) {
516 if ((HeapWord*)obj < _boundary) {
517 assert(!_g->to()->is_in_reserved(obj), "Scanning field twice?");
518 if (obj->is_forwarded()) {
519 *p = obj->forwardee();
520 } else {
521 *p = _g->DefNewGeneration::copy_to_survivor_space(obj, p);
522 }
523 }
524 if (_gc_barrier) {
525 // If p points to a younger generation, mark the card.
526 if ((HeapWord*)obj < _gen_boundary) {
527 _rs->write_ref_field_gc_par(p, obj);
528 }
529 }
530 }
531 }
532
533 class ParNewRefProcTaskProxy: public AbstractGangTask {
534 typedef AbstractRefProcTaskExecutor::ProcessTask ProcessTask;
535 public:
536 ParNewRefProcTaskProxy(ProcessTask& task, ParNewGeneration& gen,
537 Generation& next_gen,
538 HeapWord* young_old_boundary,
539 ParScanThreadStateSet& state_set);
540
541 private:
542 virtual void work(int i);
543
544 private:
545 ParNewGeneration& _gen;
546 ProcessTask& _task;
547 Generation& _next_gen;
548 HeapWord* _young_old_boundary;
549 ParScanThreadStateSet& _state_set;
550 };
551
552 ParNewRefProcTaskProxy::ParNewRefProcTaskProxy(
553 ProcessTask& task, ParNewGeneration& gen,
554 Generation& next_gen,
555 HeapWord* young_old_boundary,
556 ParScanThreadStateSet& state_set)
557 : AbstractGangTask("ParNewGeneration parallel reference processing"),
558 _gen(gen),
559 _task(task),
560 _next_gen(next_gen),
561 _young_old_boundary(young_old_boundary),
562 _state_set(state_set)
563 {
564 }
565
566 void ParNewRefProcTaskProxy::work(int i)
567 {
568 ResourceMark rm;
569 HandleMark hm;
570 ParScanThreadState& par_scan_state = _state_set.thread_sate(i);
571 par_scan_state.set_young_old_boundary(_young_old_boundary);
572 _task.work(i, par_scan_state.is_alive_closure(),
573 par_scan_state.keep_alive_closure(),
574 par_scan_state.evacuate_followers_closure());
575 }
576
577 class ParNewRefEnqueueTaskProxy: public AbstractGangTask {
578 typedef AbstractRefProcTaskExecutor::EnqueueTask EnqueueTask;
579 EnqueueTask& _task;
580
581 public:
582 ParNewRefEnqueueTaskProxy(EnqueueTask& task)
583 : AbstractGangTask("ParNewGeneration parallel reference enqueue"),
584 _task(task)
585 { }
586
587 virtual void work(int i)
588 {
589 _task.work(i);
590 }
591 };
592
593
594 void ParNewRefProcTaskExecutor::execute(ProcessTask& task)
595 {
596 GenCollectedHeap* gch = GenCollectedHeap::heap();
597 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
598 "not a generational heap");
599 WorkGang* workers = gch->workers();
600 assert(workers != NULL, "Need parallel worker threads.");
601 ParNewRefProcTaskProxy rp_task(task, _generation, *_generation.next_gen(),
602 _generation.reserved().end(), _state_set);
603 workers->run_task(&rp_task);
604 _state_set.reset();
605 }
606
607 void ParNewRefProcTaskExecutor::execute(EnqueueTask& task)
608 {
609 GenCollectedHeap* gch = GenCollectedHeap::heap();
610 WorkGang* workers = gch->workers();
611 assert(workers != NULL, "Need parallel worker threads.");
612 ParNewRefEnqueueTaskProxy enq_task(task);
613 workers->run_task(&enq_task);
614 }
615
616 void ParNewRefProcTaskExecutor::set_single_threaded_mode()
617 {
618 _state_set.flush();
619 GenCollectedHeap* gch = GenCollectedHeap::heap();
620 gch->set_par_threads(0); // 0 ==> non-parallel.
621 gch->save_marks();
622 }
623
624 ScanClosureWithParBarrier::
625 ScanClosureWithParBarrier(ParNewGeneration* g, bool gc_barrier) :
626 ScanClosure(g, gc_barrier) {}
627
628 EvacuateFollowersClosureGeneral::
629 EvacuateFollowersClosureGeneral(GenCollectedHeap* gch, int level,
630 OopsInGenClosure* cur,
631 OopsInGenClosure* older) :
632 _gch(gch), _level(level),
633 _scan_cur_or_nonheap(cur), _scan_older(older)
634 {}
635
636 void EvacuateFollowersClosureGeneral::do_void() {
637 do {
638 // Beware: this call will lead to closure applications via virtual
639 // calls.
640 _gch->oop_since_save_marks_iterate(_level,
641 _scan_cur_or_nonheap,
642 _scan_older);
643 } while (!_gch->no_allocs_since_save_marks(_level));
644 }
645
646
647 bool ParNewGeneration::_avoid_promotion_undo = false;
648
649 void ParNewGeneration::adjust_desired_tenuring_threshold() {
650 // Set the desired survivor size to half the real survivor space
651 _tenuring_threshold =
652 age_table()->compute_tenuring_threshold(to()->capacity()/HeapWordSize);
653 }
654
655 // A Generation that does parallel young-gen collection.
656
657 void ParNewGeneration::collect(bool full,
658 bool clear_all_soft_refs,
659 size_t size,
660 bool is_tlab) {
661 assert(full || size > 0, "otherwise we don't want to collect");
662 GenCollectedHeap* gch = GenCollectedHeap::heap();
663 assert(gch->kind() == CollectedHeap::GenCollectedHeap,
664 "not a CMS generational heap");
665 AdaptiveSizePolicy* size_policy = gch->gen_policy()->size_policy();
666 WorkGang* workers = gch->workers();
667 _next_gen = gch->next_gen(this);
668 assert(_next_gen != NULL,
669 "This must be the youngest gen, and not the only gen");
670 assert(gch->n_gens() == 2,
671 "Par collection currently only works with single older gen.");
672 // Do we have to avoid promotion_undo?
673 if (gch->collector_policy()->is_concurrent_mark_sweep_policy()) {
674 set_avoid_promotion_undo(true);
675 }
676
677 // If the next generation is too full to accomodate worst-case promotion
678 // from this generation, pass on collection; let the next generation
679 // do it.
680 if (!collection_attempt_is_safe()) {
681 gch->set_incremental_collection_will_fail();
682 return;
683 }
684 assert(to()->is_empty(), "Else not collection_attempt_is_safe");
685
686 init_assuming_no_promotion_failure();
687
688 if (UseAdaptiveSizePolicy) {
689 set_survivor_overflow(false);
690 size_policy->minor_collection_begin();
691 }
692
693 TraceTime t1("GC", PrintGC && !PrintGCDetails, true, gclog_or_tty);
694 // Capture heap used before collection (for printing).
695 size_t gch_prev_used = gch->used();
696
697 SpecializationStats::clear();
698
699 age_table()->clear();
700 to()->clear();
701
702 gch->save_marks();
703 assert(workers != NULL, "Need parallel worker threads.");
704 ParallelTaskTerminator _term(workers->total_workers(), task_queues());
705 ParScanThreadStateSet thread_state_set(workers->total_workers(),
706 *to(), *this, *_next_gen, *task_queues(),
707 desired_plab_sz(), _term);
708
709 ParNewGenTask tsk(this, _next_gen, reserved().end(), &thread_state_set);
710 int n_workers = workers->total_workers();
711 gch->set_par_threads(n_workers);
712 gch->change_strong_roots_parity();
713 gch->rem_set()->prepare_for_younger_refs_iterate(true);
714 // It turns out that even when we're using 1 thread, doing the work in a
715 // separate thread causes wide variance in run times. We can't help this
716 // in the multi-threaded case, but we special-case n=1 here to get
717 // repeatable measurements of the 1-thread overhead of the parallel code.
718 if (n_workers > 1) {
719 workers->run_task(&tsk);
720 } else {
721 tsk.work(0);
722 }
723 thread_state_set.reset();
724
725 if (PAR_STATS_ENABLED && ParallelGCVerbose) {
726 gclog_or_tty->print("Thread totals:\n"
727 " Pushes: %7d Pops: %7d Steals %7d (sum = %7d).\n",
728 thread_state_set.pushes(), thread_state_set.pops(),
729 thread_state_set.steals(),
730 thread_state_set.pops()+thread_state_set.steals());
731 }
732 assert(thread_state_set.pushes() == thread_state_set.pops() + thread_state_set.steals(),
733 "Or else the queues are leaky.");
734
735 // For now, process discovered weak refs sequentially.
736 #ifdef COMPILER2
737 ReferencePolicy *soft_ref_policy = new LRUMaxHeapPolicy();
738 #else
739 ReferencePolicy *soft_ref_policy = new LRUCurrentHeapPolicy();
740 #endif // COMPILER2
741
742 // Process (weak) reference objects found during scavenge.
743 IsAliveClosure is_alive(this);
744 ScanWeakRefClosure scan_weak_ref(this);
745 KeepAliveClosure keep_alive(&scan_weak_ref);
746 ScanClosure scan_without_gc_barrier(this, false);
747 ScanClosureWithParBarrier scan_with_gc_barrier(this, true);
748 set_promo_failure_scan_stack_closure(&scan_without_gc_barrier);
749 EvacuateFollowersClosureGeneral evacuate_followers(gch, _level,
750 &scan_without_gc_barrier, &scan_with_gc_barrier);
751 if (ref_processor()->processing_is_mt()) {
752 ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
753 ref_processor()->process_discovered_references(
754 soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers,
755 &task_executor);
756 } else {
757 thread_state_set.flush();
758 gch->set_par_threads(0); // 0 ==> non-parallel.
759 gch->save_marks();
760 ref_processor()->process_discovered_references(
761 soft_ref_policy, &is_alive, &keep_alive, &evacuate_followers,
762 NULL);
763 }
764 if (!promotion_failed()) {
765 // Swap the survivor spaces.
766 eden()->clear();
767 from()->clear();
768 swap_spaces();
769
770 assert(to()->is_empty(), "to space should be empty now");
771 } else {
772 assert(HandlePromotionFailure,
773 "Should only be here if promotion failure handling is on");
774 if (_promo_failure_scan_stack != NULL) {
775 // Can be non-null because of reference processing.
776 // Free stack with its elements.
777 delete _promo_failure_scan_stack;
778 _promo_failure_scan_stack = NULL;
779 }
780 remove_forwarding_pointers();
781 if (PrintGCDetails) {
782 gclog_or_tty->print(" (promotion failed)");
783 }
784 // All the spaces are in play for mark-sweep.
785 swap_spaces(); // Make life simpler for CMS || rescan; see 6483690.
786 from()->set_next_compaction_space(to());
787 gch->set_incremental_collection_will_fail();
788 }
789 // set new iteration safe limit for the survivor spaces
790 from()->set_concurrent_iteration_safe_limit(from()->top());
791 to()->set_concurrent_iteration_safe_limit(to()->top());
792
793 adjust_desired_tenuring_threshold();
794 if (ResizePLAB) {
795 plab_stats()->adjust_desired_plab_sz();
796 }
797
798 if (PrintGC && !PrintGCDetails) {
799 gch->print_heap_change(gch_prev_used);
800 }
801
802 if (UseAdaptiveSizePolicy) {
803 size_policy->minor_collection_end(gch->gc_cause());
804 size_policy->avg_survived()->sample(from()->used());
805 }
806
807 update_time_of_last_gc(os::javaTimeMillis());
808
809 SpecializationStats::print();
810
811 ref_processor()->set_enqueuing_is_done(true);
812 if (ref_processor()->processing_is_mt()) {
813 ParNewRefProcTaskExecutor task_executor(*this, thread_state_set);
814 ref_processor()->enqueue_discovered_references(&task_executor);
815 } else {
816 ref_processor()->enqueue_discovered_references(NULL);
817 }
818 ref_processor()->verify_no_references_recorded();
819 }
820
821 static int sum;
822 void ParNewGeneration::waste_some_time() {
823 for (int i = 0; i < 100; i++) {
824 sum += i;
825 }
826 }
827
828 static const oop ClaimedForwardPtr = oop(0x4);
829
830 // Because of concurrency, there are times where an object for which
831 // "is_forwarded()" is true contains an "interim" forwarding pointer
832 // value. Such a value will soon be overwritten with a real value.
833 // This method requires "obj" to have a forwarding pointer, and waits, if
834 // necessary for a real one to be inserted, and returns it.
835
836 oop ParNewGeneration::real_forwardee(oop obj) {
837 oop forward_ptr = obj->forwardee();
838 if (forward_ptr != ClaimedForwardPtr) {
839 return forward_ptr;
840 } else {
841 return real_forwardee_slow(obj);
842 }
843 }
844
845 oop ParNewGeneration::real_forwardee_slow(oop obj) {
846 // Spin-read if it is claimed but not yet written by another thread.
847 oop forward_ptr = obj->forwardee();
848 while (forward_ptr == ClaimedForwardPtr) {
849 waste_some_time();
850 assert(obj->is_forwarded(), "precondition");
851 forward_ptr = obj->forwardee();
852 }
853 return forward_ptr;
854 }
855
856 #ifdef ASSERT
857 bool ParNewGeneration::is_legal_forward_ptr(oop p) {
858 return
859 (_avoid_promotion_undo && p == ClaimedForwardPtr)
860 || Universe::heap()->is_in_reserved(p);
861 }
862 #endif
863
864 void ParNewGeneration::preserve_mark_if_necessary(oop obj, markOop m) {
865 if ((m != markOopDesc::prototype()) &&
866 (!UseBiasedLocking || (m != markOopDesc::biased_locking_prototype()))) {
867 MutexLocker ml(ParGCRareEvent_lock);
868 DefNewGeneration::preserve_mark_if_necessary(obj, m);
869 }
870 }
871
872 // Multiple GC threads may try to promote an object. If the object
873 // is successfully promoted, a forwarding pointer will be installed in
874 // the object in the young generation. This method claims the right
875 // to install the forwarding pointer before it copies the object,
876 // thus avoiding the need to undo the copy as in
877 // copy_to_survivor_space_avoiding_with_undo.
878
879 oop ParNewGeneration::copy_to_survivor_space_avoiding_promotion_undo(
880 ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
881 // In the sequential version, this assert also says that the object is
882 // not forwarded. That might not be the case here. It is the case that
883 // the caller observed it to be not forwarded at some time in the past.
884 assert(is_in_reserved(old), "shouldn't be scavenging this oop");
885
886 // The sequential code read "old->age()" below. That doesn't work here,
887 // since the age is in the mark word, and that might be overwritten with
888 // a forwarding pointer by a parallel thread. So we must save the mark
889 // word in a local and then analyze it.
890 oopDesc dummyOld;
891 dummyOld.set_mark(m);
892 assert(!dummyOld.is_forwarded(),
893 "should not be called with forwarding pointer mark word.");
894
895 oop new_obj = NULL;
896 oop forward_ptr;
897
898 // Try allocating obj in to-space (unless too old)
899 if (dummyOld.age() < tenuring_threshold()) {
900 new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
901 if (new_obj == NULL) {
902 set_survivor_overflow(true);
903 }
904 }
905
906 if (new_obj == NULL) {
907 // Either to-space is full or we decided to promote
908 // try allocating obj tenured
909
910 // Attempt to install a null forwarding pointer (atomically),
911 // to claim the right to install the real forwarding pointer.
912 forward_ptr = old->forward_to_atomic(ClaimedForwardPtr);
913 if (forward_ptr != NULL) {
914 // someone else beat us to it.
915 return real_forwardee(old);
916 }
917
918 new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
919 old, m, sz);
920
921 if (new_obj == NULL) {
922 if (!HandlePromotionFailure) {
923 // A failed promotion likely means the MaxLiveObjectEvacuationRatio flag
924 // is incorrectly set. In any case, its seriously wrong to be here!
925 vm_exit_out_of_memory(sz*wordSize, "promotion");
926 }
927 // promotion failed, forward to self
928 _promotion_failed = true;
929 new_obj = old;
930
931 preserve_mark_if_necessary(old, m);
932 }
933
934 old->forward_to(new_obj);
935 forward_ptr = NULL;
936 } else {
937 // Is in to-space; do copying ourselves.
938 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
939 forward_ptr = old->forward_to_atomic(new_obj);
940 // Restore the mark word copied above.
941 new_obj->set_mark(m);
942 // Increment age if obj still in new generation
943 new_obj->incr_age();
944 par_scan_state->age_table()->add(new_obj, sz);
945 }
946 assert(new_obj != NULL, "just checking");
947
948 if (forward_ptr == NULL) {
949 oop obj_to_push = new_obj;
950 if (par_scan_state->should_be_partially_scanned(obj_to_push, old)) {
951 // Length field used as index of next element to be scanned.
952 // Real length can be obtained from real_forwardee()
953 arrayOop(old)->set_length(0);
954 obj_to_push = old;
955 assert(obj_to_push->is_forwarded() && obj_to_push->forwardee() != obj_to_push,
956 "push forwarded object");
957 }
958 // Push it on one of the queues of to-be-scanned objects.
959 if (!par_scan_state->work_queue()->push(obj_to_push)) {
960 // Add stats for overflow pushes.
961 if (Verbose && PrintGCDetails) {
962 gclog_or_tty->print("queue overflow!\n");
963 }
964 push_on_overflow_list(old);
965 par_scan_state->note_overflow_push();
966 }
967 par_scan_state->note_push();
968
969 return new_obj;
970 }
971
972 // Oops. Someone beat us to it. Undo the allocation. Where did we
973 // allocate it?
974 if (is_in_reserved(new_obj)) {
975 // Must be in to_space.
976 assert(to()->is_in_reserved(new_obj), "Checking");
977 if (forward_ptr == ClaimedForwardPtr) {
978 // Wait to get the real forwarding pointer value.
979 forward_ptr = real_forwardee(old);
980 }
981 par_scan_state->undo_alloc_in_to_space((HeapWord*)new_obj, sz);
982 }
983
984 return forward_ptr;
985 }
986
987
988 // Multiple GC threads may try to promote the same object. If two
989 // or more GC threads copy the object, only one wins the race to install
990 // the forwarding pointer. The other threads have to undo their copy.
991
992 oop ParNewGeneration::copy_to_survivor_space_with_undo(
993 ParScanThreadState* par_scan_state, oop old, size_t sz, markOop m) {
994
995 // In the sequential version, this assert also says that the object is
996 // not forwarded. That might not be the case here. It is the case that
997 // the caller observed it to be not forwarded at some time in the past.
998 assert(is_in_reserved(old), "shouldn't be scavenging this oop");
999
1000 // The sequential code read "old->age()" below. That doesn't work here,
1001 // since the age is in the mark word, and that might be overwritten with
1002 // a forwarding pointer by a parallel thread. So we must save the mark
1003 // word here, install it in a local oopDesc, and then analyze it.
1004 oopDesc dummyOld;
1005 dummyOld.set_mark(m);
1006 assert(!dummyOld.is_forwarded(),
1007 "should not be called with forwarding pointer mark word.");
1008
1009 bool failed_to_promote = false;
1010 oop new_obj = NULL;
1011 oop forward_ptr;
1012
1013 // Try allocating obj in to-space (unless too old)
1014 if (dummyOld.age() < tenuring_threshold()) {
1015 new_obj = (oop)par_scan_state->alloc_in_to_space(sz);
1016 if (new_obj == NULL) {
1017 set_survivor_overflow(true);
1018 }
1019 }
1020
1021 if (new_obj == NULL) {
1022 // Either to-space is full or we decided to promote
1023 // try allocating obj tenured
1024 new_obj = _next_gen->par_promote(par_scan_state->thread_num(),
1025 old, m, sz);
1026
1027 if (new_obj == NULL) {
1028 if (!HandlePromotionFailure) {
1029 // A failed promotion likely means the MaxLiveObjectEvacuationRatio
1030 // flag is incorrectly set. In any case, its seriously wrong to be
1031 // here!
1032 vm_exit_out_of_memory(sz*wordSize, "promotion");
1033 }
1034 // promotion failed, forward to self
1035 forward_ptr = old->forward_to_atomic(old);
1036 new_obj = old;
1037
1038 if (forward_ptr != NULL) {
1039 return forward_ptr; // someone else succeeded
1040 }
1041
1042 _promotion_failed = true;
1043 failed_to_promote = true;
1044
1045 preserve_mark_if_necessary(old, m);
1046 }
1047 } else {
1048 // Is in to-space; do copying ourselves.
1049 Copy::aligned_disjoint_words((HeapWord*)old, (HeapWord*)new_obj, sz);
1050 // Restore the mark word copied above.
1051 new_obj->set_mark(m);
1052 // Increment age if new_obj still in new generation
1053 new_obj->incr_age();
1054 par_scan_state->age_table()->add(new_obj, sz);
1055 }
1056 assert(new_obj != NULL, "just checking");
1057
1058 // Now attempt to install the forwarding pointer (atomically).
1059 // We have to copy the mark word before overwriting with forwarding
1060 // ptr, so we can restore it below in the copy.
1061 if (!failed_to_promote) {
1062 forward_ptr = old->forward_to_atomic(new_obj);
1063 }
1064
1065 if (forward_ptr == NULL) {
1066 oop obj_to_push = new_obj;
1067 if (par_scan_state->should_be_partially_scanned(obj_to_push, old)) {
1068 // Length field used as index of next element to be scanned.
1069 // Real length can be obtained from real_forwardee()
1070 arrayOop(old)->set_length(0);
1071 obj_to_push = old;
1072 assert(obj_to_push->is_forwarded() && obj_to_push->forwardee() != obj_to_push,
1073 "push forwarded object");
1074 }
1075 // Push it on one of the queues of to-be-scanned objects.
1076 if (!par_scan_state->work_queue()->push(obj_to_push)) {
1077 // Add stats for overflow pushes.
1078 push_on_overflow_list(old);
1079 par_scan_state->note_overflow_push();
1080 }
1081 par_scan_state->note_push();
1082
1083 return new_obj;
1084 }
1085
1086 // Oops. Someone beat us to it. Undo the allocation. Where did we
1087 // allocate it?
1088 if (is_in_reserved(new_obj)) {
1089 // Must be in to_space.
1090 assert(to()->is_in_reserved(new_obj), "Checking");
1091 par_scan_state->undo_alloc_in_to_space((HeapWord*)new_obj, sz);
1092 } else {
1093 assert(!_avoid_promotion_undo, "Should not be here if avoiding.");
1094 _next_gen->par_promote_alloc_undo(par_scan_state->thread_num(),
1095 (HeapWord*)new_obj, sz);
1096 }
1097
1098 return forward_ptr;
1099 }
1100
1101 void ParNewGeneration::push_on_overflow_list(oop from_space_obj) {
1102 oop cur_overflow_list = _overflow_list;
1103 // if the object has been forwarded to itself, then we cannot
1104 // use the klass pointer for the linked list. Instead we have
1105 // to allocate an oopDesc in the C-Heap and use that for the linked list.
1106 if (from_space_obj->forwardee() == from_space_obj) {
1107 oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1);
1108 listhead->forward_to(from_space_obj);
1109 from_space_obj = listhead;
1110 }
1111 while (true) {
1112 from_space_obj->set_klass_to_list_ptr(cur_overflow_list);
1113 oop observed_overflow_list =
1114 (oop)Atomic::cmpxchg_ptr(from_space_obj, &_overflow_list, cur_overflow_list);
1115 if (observed_overflow_list == cur_overflow_list) break;
1116 // Otherwise...
1117 cur_overflow_list = observed_overflow_list;
1118 }
1119 }
1120
1121 bool
1122 ParNewGeneration::take_from_overflow_list(ParScanThreadState* par_scan_state) {
1123 ObjToScanQueue* work_q = par_scan_state->work_queue();
1124 // How many to take?
1125 int objsFromOverflow = MIN2(work_q->max_elems()/4,
1126 (juint)ParGCDesiredObjsFromOverflowList);
1127
1128 if (_overflow_list == NULL) return false;
1129
1130 // Otherwise, there was something there; try claiming the list.
1131 oop prefix = (oop)Atomic::xchg_ptr(NULL, &_overflow_list);
1132
1133 if (prefix == NULL) {
1134 return false;
1135 }
1136 // Trim off a prefix of at most objsFromOverflow items
1137 int i = 1;
1138 oop cur = prefix;
1139 while (i < objsFromOverflow && cur->klass() != NULL) {
1140 i++; cur = oop(cur->klass());
1141 }
1142
1143 // Reattach remaining (suffix) to overflow list
1144 if (cur->klass() != NULL) {
1145 oop suffix = oop(cur->klass());
1146 cur->set_klass_to_list_ptr(NULL);
1147
1148 // Find last item of suffix list
1149 oop last = suffix;
1150 while (last->klass() != NULL) {
1151 last = oop(last->klass());
1152 }
1153 // Atomically prepend suffix to current overflow list
1154 oop cur_overflow_list = _overflow_list;
1155 while (true) {
1156 last->set_klass_to_list_ptr(cur_overflow_list);
1157 oop observed_overflow_list =
1158 (oop)Atomic::cmpxchg_ptr(suffix, &_overflow_list, cur_overflow_list);
1159 if (observed_overflow_list == cur_overflow_list) break;
1160 // Otherwise...
1161 cur_overflow_list = observed_overflow_list;
1162 }
1163 }
1164
1165 // Push objects on prefix list onto this thread's work queue
1166 assert(cur != NULL, "program logic");
1167 cur = prefix;
1168 int n = 0;
1169 while (cur != NULL) {
1170 oop obj_to_push = cur->forwardee();
1171 oop next = oop(cur->klass());
1172 cur->set_klass(obj_to_push->klass());
1173 if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
1174 obj_to_push = cur;
1175 assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
1176 }
1177 work_q->push(obj_to_push);
1178 cur = next;
1179 n++;
1180 }
1181 par_scan_state->note_overflow_refill(n);
1182 return true;
1183 }
1184
1185 void ParNewGeneration::ref_processor_init()
1186 {
1187 if (_ref_processor == NULL) {
1188 // Allocate and initialize a reference processor
1189 _ref_processor = ReferenceProcessor::create_ref_processor(
1190 _reserved, // span
1191 refs_discovery_is_atomic(), // atomic_discovery
1192 refs_discovery_is_mt(), // mt_discovery
1193 NULL, // is_alive_non_header
1194 ParallelGCThreads,
1195 ParallelRefProcEnabled);
1196 }
1197 }
1198
1199 const char* ParNewGeneration::name() const {
1200 return "par new generation";
1201 }