comparison src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp @ 1311:2a1472c30599

4396719: Mark Sweep stack overflow on deeply nested Object arrays Summary: Use an explicit stack for object arrays and process them in chunks. Reviewed-by: iveresov, apetrusenko
author jcoomes
date Wed, 03 Mar 2010 14:48:26 -0800
parents 46b819ba120b
children 0bfd3fb24150
comparison
equal deleted inserted replaced
1289:d47555d7aca8 1311:2a1472c30599
783 PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure(false); 783 PSParallelCompact::AdjustPointerClosure PSParallelCompact::_adjust_pointer_closure(false);
784 784
785 void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); } 785 void PSParallelCompact::AdjustPointerClosure::do_oop(oop* p) { adjust_pointer(p, _is_root); }
786 void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); } 786 void PSParallelCompact::AdjustPointerClosure::do_oop(narrowOop* p) { adjust_pointer(p, _is_root); }
787 787
788 void PSParallelCompact::FollowStackClosure::do_void() { follow_stack(_compaction_manager); } 788 void PSParallelCompact::FollowStackClosure::do_void() { _compaction_manager->follow_marking_stacks(); }
789 789
790 void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(_compaction_manager, p); } 790 void PSParallelCompact::MarkAndPushClosure::do_oop(oop* p) { mark_and_push(_compaction_manager, p); }
791 void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); } 791 void PSParallelCompact::MarkAndPushClosure::do_oop(narrowOop* p) { mark_and_push(_compaction_manager, p); }
792 792
793 void PSParallelCompact::post_initialize() { 793 void PSParallelCompact::post_initialize() {
2374 bool purged_class = SystemDictionary::do_unloading(is_alive_closure()); 2374 bool purged_class = SystemDictionary::do_unloading(is_alive_closure());
2375 2375
2376 // Follow code cache roots. 2376 // Follow code cache roots.
2377 CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure, 2377 CodeCache::do_unloading(is_alive_closure(), &mark_and_push_closure,
2378 purged_class); 2378 purged_class);
2379 follow_stack(cm); // Flush marking stack. 2379 cm->follow_marking_stacks(); // Flush marking stack.
2380 2380
2381 // Update subklass/sibling/implementor links of live klasses 2381 // Update subklass/sibling/implementor links of live klasses
2382 // revisit_klass_stack is used in follow_weak_klass_links(). 2382 // revisit_klass_stack is used in follow_weak_klass_links().
2383 follow_weak_klass_links(); 2383 follow_weak_klass_links();
2384 2384
2387 2387
2388 // Visit symbol and interned string tables and delete unmarked oops 2388 // Visit symbol and interned string tables and delete unmarked oops
2389 SymbolTable::unlink(is_alive_closure()); 2389 SymbolTable::unlink(is_alive_closure());
2390 StringTable::unlink(is_alive_closure()); 2390 StringTable::unlink(is_alive_closure());
2391 2391
2392 assert(cm->marking_stack()->size() == 0, "stack should be empty by now"); 2392 assert(cm->marking_stacks_empty(), "marking stacks should be empty");
2393 assert(cm->overflow_stack()->is_empty(), "stack should be empty by now");
2394 } 2393 }
2395 2394
2396 // This should be moved to the shared markSweep code! 2395 // This should be moved to the shared markSweep code!
2397 class PSAlwaysTrueClosure: public BoolObjectClosure { 2396 class PSAlwaysTrueClosure: public BoolObjectClosure {
2398 public: 2397 public:
2707 old_gen->start_array()->reset(); 2706 old_gen->start_array()->reset();
2708 old_gen->move_and_update(cm); 2707 old_gen->move_and_update(cm);
2709 young_gen->move_and_update(cm); 2708 young_gen->move_and_update(cm);
2710 } 2709 }
2711 2710
2712
2713 void PSParallelCompact::follow_stack(ParCompactionManager* cm) {
2714 while(!cm->overflow_stack()->is_empty()) {
2715 oop obj = cm->overflow_stack()->pop();
2716 obj->follow_contents(cm);
2717 }
2718
2719 oop obj;
2720 // obj is a reference!!!
2721 while (cm->marking_stack()->pop_local(obj)) {
2722 // It would be nice to assert about the type of objects we might
2723 // pop, but they can come from anywhere, unfortunately.
2724 obj->follow_contents(cm);
2725 }
2726 }
2727
2728 void 2711 void
2729 PSParallelCompact::follow_weak_klass_links() { 2712 PSParallelCompact::follow_weak_klass_links() {
2730 // All klasses on the revisit stack are marked at this point. 2713 // All klasses on the revisit stack are marked at this point.
2731 // Update and follow all subklass, sibling and implementor links. 2714 // Update and follow all subklass, sibling and implementor links.
2732 if (PrintRevisitStats) { 2715 if (PrintRevisitStats) {
2743 cm->revisit_klass_stack()->at(j)->follow_weak_klass_links( 2726 cm->revisit_klass_stack()->at(j)->follow_weak_klass_links(
2744 is_alive_closure(), 2727 is_alive_closure(),
2745 &keep_alive_closure); 2728 &keep_alive_closure);
2746 } 2729 }
2747 // revisit_klass_stack is cleared in reset() 2730 // revisit_klass_stack is cleared in reset()
2748 follow_stack(cm); 2731 cm->follow_marking_stacks();
2749 } 2732 }
2750 } 2733 }
2751 2734
2752 void 2735 void
2753 PSParallelCompact::revisit_weak_klass_link(ParCompactionManager* cm, Klass* k) { 2736 PSParallelCompact::revisit_weak_klass_link(ParCompactionManager* cm, Klass* k) {
2774 } 2757 }
2775 for (int j = 0; j < length; j++) { 2758 for (int j = 0; j < length; j++) {
2776 rms->at(j)->follow_weak_refs(is_alive_closure()); 2759 rms->at(j)->follow_weak_refs(is_alive_closure());
2777 } 2760 }
2778 // revisit_mdo_stack is cleared in reset() 2761 // revisit_mdo_stack is cleared in reset()
2779 follow_stack(cm); 2762 cm->follow_marking_stacks();
2780 } 2763 }
2781 } 2764 }
2782 2765
2783 2766
2784 #ifdef VALIDATE_MARK_SWEEP 2767 #ifdef VALIDATE_MARK_SWEEP