56 // |
56 // |
57 // DefNewGeneration functions. |
57 // DefNewGeneration functions. |
58 |
58 |
59 // Methods of protected closure types. |
59 // Methods of protected closure types. |
60 |
60 |
61 DefNewGeneration::IsAliveClosure::IsAliveClosure(Generation* g) : _g(g) { |
61 DefNewGeneration::IsAliveClosure::IsAliveClosure(Generation* young_gen) : _young_gen(young_gen) { |
62 assert(g->level() == 0, "Optimized for youngest gen."); |
62 assert(_young_gen->kind() == Generation::ParNew || |
63 } |
63 _young_gen->kind() == Generation::DefNew, "Expected the young generation here"); |
|
64 } |
|
65 |
64 bool DefNewGeneration::IsAliveClosure::do_object_b(oop p) { |
66 bool DefNewGeneration::IsAliveClosure::do_object_b(oop p) { |
65 return (HeapWord*)p >= _g->reserved().end() || p->is_forwarded(); |
67 return (HeapWord*)p >= _young_gen->reserved().end() || p->is_forwarded(); |
66 } |
68 } |
67 |
69 |
68 DefNewGeneration::KeepAliveClosure:: |
70 DefNewGeneration::KeepAliveClosure:: |
69 KeepAliveClosure(ScanWeakRefClosure* cl) : _cl(cl) { |
71 KeepAliveClosure(ScanWeakRefClosure* cl) : _cl(cl) { |
70 GenRemSet* rs = GenCollectedHeap::heap()->rem_set(); |
72 GenRemSet* rs = GenCollectedHeap::heap()->rem_set(); |
83 |
85 |
84 void DefNewGeneration::FastKeepAliveClosure::do_oop(oop* p) { DefNewGeneration::FastKeepAliveClosure::do_oop_work(p); } |
86 void DefNewGeneration::FastKeepAliveClosure::do_oop(oop* p) { DefNewGeneration::FastKeepAliveClosure::do_oop_work(p); } |
85 void DefNewGeneration::FastKeepAliveClosure::do_oop(narrowOop* p) { DefNewGeneration::FastKeepAliveClosure::do_oop_work(p); } |
87 void DefNewGeneration::FastKeepAliveClosure::do_oop(narrowOop* p) { DefNewGeneration::FastKeepAliveClosure::do_oop_work(p); } |
86 |
88 |
87 DefNewGeneration::EvacuateFollowersClosure:: |
89 DefNewGeneration::EvacuateFollowersClosure:: |
88 EvacuateFollowersClosure(GenCollectedHeap* gch, int level, |
90 EvacuateFollowersClosure(GenCollectedHeap* gch, |
89 ScanClosure* cur, ScanClosure* older) : |
91 ScanClosure* cur, |
90 _gch(gch), _level(level), |
92 ScanClosure* older) : |
91 _scan_cur_or_nonheap(cur), _scan_older(older) |
93 _gch(gch), _scan_cur_or_nonheap(cur), _scan_older(older) |
92 {} |
94 {} |
93 |
95 |
94 void DefNewGeneration::EvacuateFollowersClosure::do_void() { |
96 void DefNewGeneration::EvacuateFollowersClosure::do_void() { |
95 do { |
97 do { |
96 _gch->oop_since_save_marks_iterate(_level, _scan_cur_or_nonheap, |
98 _gch->oop_since_save_marks_iterate(GenCollectedHeap::YoungGen, _scan_cur_or_nonheap, _scan_older); |
97 _scan_older); |
99 } while (!_gch->no_allocs_since_save_marks(GenCollectedHeap::YoungGen)); |
98 } while (!_gch->no_allocs_since_save_marks(_level)); |
|
99 } |
100 } |
100 |
101 |
101 DefNewGeneration::FastEvacuateFollowersClosure:: |
102 DefNewGeneration::FastEvacuateFollowersClosure:: |
102 FastEvacuateFollowersClosure(GenCollectedHeap* gch, int level, |
103 FastEvacuateFollowersClosure(GenCollectedHeap* gch, |
103 DefNewGeneration* gen, |
104 FastScanClosure* cur, |
104 FastScanClosure* cur, FastScanClosure* older) : |
105 FastScanClosure* older) : |
105 _gch(gch), _level(level), _gen(gen), |
106 _gch(gch), _scan_cur_or_nonheap(cur), _scan_older(older) |
106 _scan_cur_or_nonheap(cur), _scan_older(older) |
107 { |
107 {} |
108 assert(_gch->young_gen()->kind() == Generation::DefNew, "Generation should be DefNew"); |
|
109 _gen = (DefNewGeneration*)_gch->young_gen(); |
|
110 } |
108 |
111 |
109 void DefNewGeneration::FastEvacuateFollowersClosure::do_void() { |
112 void DefNewGeneration::FastEvacuateFollowersClosure::do_void() { |
110 do { |
113 do { |
111 _gch->oop_since_save_marks_iterate(_level, _scan_cur_or_nonheap, |
114 _gch->oop_since_save_marks_iterate(GenCollectedHeap::YoungGen, _scan_cur_or_nonheap, _scan_older); |
112 _scan_older); |
115 } while (!_gch->no_allocs_since_save_marks(GenCollectedHeap::YoungGen)); |
113 } while (!_gch->no_allocs_since_save_marks(_level)); |
|
114 guarantee(_gen->promo_failure_scan_is_complete(), "Failed to finish scan"); |
116 guarantee(_gen->promo_failure_scan_is_complete(), "Failed to finish scan"); |
115 } |
117 } |
116 |
118 |
117 ScanClosure::ScanClosure(DefNewGeneration* g, bool gc_barrier) : |
119 ScanClosure::ScanClosure(DefNewGeneration* g, bool gc_barrier) : |
118 OopsInKlassOrGenClosure(g), _g(g), _gc_barrier(gc_barrier) |
120 OopsInKlassOrGenClosure(g), _g(g), _gc_barrier(gc_barrier) |
119 { |
121 { |
120 assert(_g->level() == 0, "Optimized for youngest generation"); |
|
121 _boundary = _g->reserved().end(); |
122 _boundary = _g->reserved().end(); |
122 } |
123 } |
123 |
124 |
124 void ScanClosure::do_oop(oop* p) { ScanClosure::do_oop_work(p); } |
125 void ScanClosure::do_oop(oop* p) { ScanClosure::do_oop_work(p); } |
125 void ScanClosure::do_oop(narrowOop* p) { ScanClosure::do_oop_work(p); } |
126 void ScanClosure::do_oop(narrowOop* p) { ScanClosure::do_oop_work(p); } |
126 |
127 |
127 FastScanClosure::FastScanClosure(DefNewGeneration* g, bool gc_barrier) : |
128 FastScanClosure::FastScanClosure(DefNewGeneration* g, bool gc_barrier) : |
128 OopsInKlassOrGenClosure(g), _g(g), _gc_barrier(gc_barrier) |
129 OopsInKlassOrGenClosure(g), _g(g), _gc_barrier(gc_barrier) |
129 { |
130 { |
130 assert(_g->level() == 0, "Optimized for youngest generation"); |
|
131 _boundary = _g->reserved().end(); |
131 _boundary = _g->reserved().end(); |
132 } |
132 } |
133 |
133 |
134 void FastScanClosure::do_oop(oop* p) { FastScanClosure::do_oop_work(p); } |
134 void FastScanClosure::do_oop(oop* p) { FastScanClosure::do_oop_work(p); } |
135 void FastScanClosure::do_oop(narrowOop* p) { FastScanClosure::do_oop_work(p); } |
135 void FastScanClosure::do_oop(narrowOop* p) { FastScanClosure::do_oop_work(p); } |
184 _accumulate_modified_oops(klass_rem_set->accumulate_modified_oops()) {} |
183 _accumulate_modified_oops(klass_rem_set->accumulate_modified_oops()) {} |
185 |
184 |
186 |
185 |
187 DefNewGeneration::DefNewGeneration(ReservedSpace rs, |
186 DefNewGeneration::DefNewGeneration(ReservedSpace rs, |
188 size_t initial_size, |
187 size_t initial_size, |
189 int level, |
|
190 const char* policy) |
188 const char* policy) |
191 : Generation(rs, initial_size, level), |
189 : Generation(rs, initial_size), |
192 _promo_failure_drain_in_progress(false), |
190 _promo_failure_drain_in_progress(false), |
193 _should_allocate_from_space(false) |
191 _should_allocate_from_space(false) |
194 { |
192 { |
195 MemRegion cmr((HeapWord*)_virtual_space.low(), |
193 MemRegion cmr((HeapWord*)_virtual_space.low(), |
196 (HeapWord*)_virtual_space.high()); |
194 (HeapWord*)_virtual_space.high()); |
370 } |
368 } |
371 |
369 |
372 return success; |
370 return success; |
373 } |
371 } |
374 |
372 |
375 |
|
376 void DefNewGeneration::compute_new_size() { |
373 void DefNewGeneration::compute_new_size() { |
377 // This is called after a gc that includes the following generation |
374 // This is called after a GC that includes the old generation, so from-space |
378 // (which is required to exist.) So from-space will normally be empty. |
375 // will normally be empty. |
379 // Note that we check both spaces, since if scavenge failed they revert roles. |
376 // Note that we check both spaces, since if scavenge failed they revert roles. |
380 // If not we bail out (otherwise we would have to relocate the objects) |
377 // If not we bail out (otherwise we would have to relocate the objects). |
381 if (!from()->is_empty() || !to()->is_empty()) { |
378 if (!from()->is_empty() || !to()->is_empty()) { |
382 return; |
379 return; |
383 } |
380 } |
384 |
381 |
385 int next_level = level() + 1; |
|
386 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
382 GenCollectedHeap* gch = GenCollectedHeap::heap(); |
387 assert(next_level == 1, "DefNewGeneration must be a young gen"); |
383 |
388 |
384 size_t old_size = gch->old_gen()->capacity(); |
389 Generation* old_gen = gch->old_gen(); |
|
390 size_t old_size = old_gen->capacity(); |
|
391 size_t new_size_before = _virtual_space.committed_size(); |
385 size_t new_size_before = _virtual_space.committed_size(); |
392 size_t min_new_size = spec()->init_size(); |
386 size_t min_new_size = spec()->init_size(); |
393 size_t max_new_size = reserved().byte_size(); |
387 size_t max_new_size = reserved().byte_size(); |
394 assert(min_new_size <= new_size_before && |
388 assert(min_new_size <= new_size_before && |
395 new_size_before <= max_new_size, |
389 new_size_before <= max_new_size, |
617 CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure, |
611 CLDToKlassAndOopClosure cld_scan_closure(&klass_scan_closure, |
618 &fsc_with_no_gc_barrier, |
612 &fsc_with_no_gc_barrier, |
619 false); |
613 false); |
620 |
614 |
621 set_promo_failure_scan_stack_closure(&fsc_with_no_gc_barrier); |
615 set_promo_failure_scan_stack_closure(&fsc_with_no_gc_barrier); |
622 FastEvacuateFollowersClosure evacuate_followers(gch, _level, this, |
616 FastEvacuateFollowersClosure evacuate_followers(gch, |
623 &fsc_with_no_gc_barrier, |
617 &fsc_with_no_gc_barrier, |
624 &fsc_with_gc_barrier); |
618 &fsc_with_gc_barrier); |
625 |
619 |
626 assert(gch->no_allocs_since_save_marks(0), |
620 assert(gch->no_allocs_since_save_marks(GenCollectedHeap::YoungGen), |
627 "save marks have not been newly set."); |
621 "save marks have not been newly set."); |
628 |
622 |
629 { |
623 { |
630 // DefNew needs to run with n_threads == 0, to make sure the serial |
624 // DefNew needs to run with n_threads == 0, to make sure the serial |
631 // version of the card table scanning code is used. |
625 // version of the card table scanning code is used. |
632 // See: CardTableModRefBS::non_clean_card_iterate_possibly_parallel. |
626 // See: CardTableModRefBS::non_clean_card_iterate_possibly_parallel. |
633 StrongRootsScope srs(0); |
627 StrongRootsScope srs(0); |
634 |
628 |
635 gch->gen_process_roots(&srs, |
629 gch->gen_process_roots(&srs, |
636 _level, |
630 GenCollectedHeap::YoungGen, |
637 true, // Process younger gens, if any, |
631 true, // Process younger gens, if any, |
638 // as strong roots. |
632 // as strong roots. |
639 GenCollectedHeap::SO_ScavengeCodeCache, |
633 GenCollectedHeap::SO_ScavengeCodeCache, |
640 GenCollectedHeap::StrongAndWeakRoots, |
634 GenCollectedHeap::StrongAndWeakRoots, |
641 &fsc_with_no_gc_barrier, |
635 &fsc_with_no_gc_barrier, |
868 |
862 |
869 #undef DefNew_SINCE_SAVE_MARKS_DEFN |
863 #undef DefNew_SINCE_SAVE_MARKS_DEFN |
870 |
864 |
871 void DefNewGeneration::contribute_scratch(ScratchBlock*& list, Generation* requestor, |
865 void DefNewGeneration::contribute_scratch(ScratchBlock*& list, Generation* requestor, |
872 size_t max_alloc_words) { |
866 size_t max_alloc_words) { |
873 if (requestor == this || _promotion_failed) return; |
867 if (requestor == this || _promotion_failed) { |
874 assert(requestor->level() > level(), "DefNewGeneration must be youngest"); |
868 return; |
|
869 } |
|
870 assert(GenCollectedHeap::heap()->is_old_gen(requestor), "We should not call our own generation"); |
875 |
871 |
876 /* $$$ Assert this? "trace" is a "MarkSweep" function so that's not appropriate. |
872 /* $$$ Assert this? "trace" is a "MarkSweep" function so that's not appropriate. |
877 if (to_space->top() > to_space->bottom()) { |
873 if (to_space->top() > to_space->bottom()) { |
878 trace("to_space not empty when contribute_scratch called"); |
874 trace("to_space not empty when contribute_scratch called"); |
879 } |
875 } |