644 _gc_timer->register_gc_end();
645
646 _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
647
648 return !_promotion_failed;
649 }
650
651 void DefNewGeneration::init_assuming_no_promotion_failure() {
652 _promotion_failed = false;
653 _promotion_failed_info.reset();
654 }
655
656 void DefNewGeneration::remove_forwarding_pointers() {
657 assert(_promotion_failed, "precondition");
658
659 // Will enter Full GC soon due to failed promotion. Must reset the mark word
660 // of objs in young-gen so that no objs are marked (forwarded) when Full GC
661 // starts. (The mark word is overloaded: `is_marked()` == `is_forwarded()`.)
662 struct ResetForwardedMarkWord : ObjectClosure {
663 void do_object(oop obj) override {
664 if (obj->is_self_forwarded()) {
665 obj->unset_self_forwarded();
666 } else if (obj->is_forwarded()) {
667 // To restore the klass-bits in the header.
668 // Needed for object iteration to work properly.
669 obj->set_mark(obj->forwardee()->prototype_mark());
670 }
671 }
672 } cl;
673 eden()->object_iterate(&cl);
674 from()->object_iterate(&cl);
675 }
676
677 void DefNewGeneration::handle_promotion_failure(oop old) {
678 log_debug(gc, promotion)("Promotion failure size = %zu) ", old->size());
679
680 _promotion_failed = true;
681 _promotion_failed_info.register_copy_failure(old->size());
682
683 ContinuationGCSupport::transform_stack_chunk(old);
684
685 // forward to self
686 old->forward_to_self();
687
688 _promo_failure_scan_stack.push(old);
689
690 if (!_promo_failure_drain_in_progress) {
691 // prevent recursion in copy_to_survivor_space()
692 _promo_failure_drain_in_progress = true;
693 drain_promo_failure_scan_stack();
694 _promo_failure_drain_in_progress = false;
695 }
696 }
697
698 oop DefNewGeneration::copy_to_survivor_space(oop old) {
699 assert(is_in_reserved(old) && !old->is_forwarded(),
700 "shouldn't be scavenging this oop");
701 size_t s = old->size();
702 oop obj = nullptr;
703
704 // Try allocating obj in to-space (unless too old)
705 if (old->age() < tenuring_threshold()) {
706 obj = cast_to_oop(to()->allocate(s));
707 }
708
709 bool new_obj_is_tenured = false;
710 // Otherwise try allocating obj tenured
711 if (obj == nullptr) {
712 obj = _old_gen->allocate_for_promotion(old, s);
713 if (obj == nullptr) {
714 handle_promotion_failure(old);
715 return old;
716 }
717
718 new_obj_is_tenured = true;
719 }
720
721 // Prefetch beyond obj
722 const intx interval = PrefetchCopyIntervalInBytes;
723 Prefetch::write(obj, interval);
724
725 // Copy obj
726 Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(old), cast_from_oop<HeapWord*>(obj), s);
727
728 ContinuationGCSupport::transform_stack_chunk(obj);
729
730 if (!new_obj_is_tenured) {
731 // Increment age if obj still in new generation
732 obj->incr_age();
733 age_table()->add(obj, s);
734 }
735
736 // Done, insert forward pointer to obj in this header
737 old->forward_to(obj);
738
739 if (SerialStringDedup::is_candidate_from_evacuation(obj, new_obj_is_tenured)) {
740 // Record old; request adds a new weak reference, which reference
741 // processing expects to refer to a from-space object.
742 _string_dedup_requests.add(old);
743 }
744 return obj;
745 }
746
747 void DefNewGeneration::drain_promo_failure_scan_stack() {
748 PromoteFailureClosure cl{this};
749 while (!_promo_failure_scan_stack.is_empty()) {
750 oop obj = _promo_failure_scan_stack.pop();
751 obj->oop_iterate(&cl);
752 }
753 }
754
755 void DefNewGeneration::contribute_scratch(void*& scratch, size_t& num_words) {
|
644 _gc_timer->register_gc_end();
645
646 _gc_tracer->report_gc_end(_gc_timer->gc_end(), _gc_timer->time_partitions());
647
648 return !_promotion_failed;
649 }
650
651 void DefNewGeneration::init_assuming_no_promotion_failure() {
652 _promotion_failed = false;
653 _promotion_failed_info.reset();
654 }
655
656 void DefNewGeneration::remove_forwarding_pointers() {
657 assert(_promotion_failed, "precondition");
658
659 // Will enter Full GC soon due to failed promotion. Must reset the mark word
660 // of objs in young-gen so that no objs are marked (forwarded) when Full GC
661 // starts. (The mark word is overloaded: `is_marked()` == `is_forwarded()`.)
662 struct ResetForwardedMarkWord : ObjectClosure {
663 void do_object(oop obj) override {
664 obj->reset_forwarded();
665 }
666 } cl;
667 eden()->object_iterate(&cl);
668 from()->object_iterate(&cl);
669 }
670
671 void DefNewGeneration::handle_promotion_failure(oop old) {
672 log_debug(gc, promotion)("Promotion failure size = %zu) ", old->size());
673
674 _promotion_failed = true;
675 _promotion_failed_info.register_copy_failure(old->size());
676
677 ContinuationGCSupport::transform_stack_chunk(old);
678
679 // forward to self
680 old->forward_to_self();
681
682 _promo_failure_scan_stack.push(old);
683
684 if (!_promo_failure_drain_in_progress) {
685 // prevent recursion in copy_to_survivor_space()
686 _promo_failure_drain_in_progress = true;
687 drain_promo_failure_scan_stack();
688 _promo_failure_drain_in_progress = false;
689 }
690 }
691
692 oop DefNewGeneration::copy_to_survivor_space(oop old) {
693 assert(is_in_reserved(old) && !old->is_forwarded(),
694 "shouldn't be scavenging this oop");
695 size_t old_size = old->size();
696 size_t s = old->copy_size(old_size, old->mark());
697
698 oop obj = nullptr;
699
700 // Try allocating obj in to-space (unless too old)
701 if (old->age() < tenuring_threshold()) {
702 obj = cast_to_oop(to()->allocate(s));
703 }
704
705 bool new_obj_is_tenured = false;
706 // Otherwise try allocating obj tenured
707 if (obj == nullptr) {
708 obj = _old_gen->allocate_for_promotion(old, s);
709 if (obj == nullptr) {
710 handle_promotion_failure(old);
711 return old;
712 }
713
714 new_obj_is_tenured = true;
715 }
716
717 // Prefetch beyond obj
718 const intx interval = PrefetchCopyIntervalInBytes;
719 Prefetch::write(obj, interval);
720
721 // Copy obj
722 Copy::aligned_disjoint_words(cast_from_oop<HeapWord*>(old), cast_from_oop<HeapWord*>(obj), old_size);
723
724 ContinuationGCSupport::transform_stack_chunk(obj);
725
726 if (!new_obj_is_tenured) {
727 // Increment age if obj still in new generation
728 obj->incr_age();
729 age_table()->add(obj, s);
730 }
731
732 obj->initialize_hash_if_necessary(old);
733
734 // Done, insert forward pointer to obj in this header
735 old->forward_to(obj);
736
737 if (SerialStringDedup::is_candidate_from_evacuation(obj, new_obj_is_tenured)) {
738 // Record old; request adds a new weak reference, which reference
739 // processing expects to refer to a from-space object.
740 _string_dedup_requests.add(old);
741 }
742 return obj;
743 }
744
745 void DefNewGeneration::drain_promo_failure_scan_stack() {
746 PromoteFailureClosure cl{this};
747 while (!_promo_failure_scan_stack.is_empty()) {
748 oop obj = _promo_failure_scan_stack.pop();
749 obj->oop_iterate(&cl);
750 }
751 }
752
753 void DefNewGeneration::contribute_scratch(void*& scratch, size_t& num_words) {
|