comparison src/share/vm/gc_implementation/g1/g1RemSet.cpp @ 890:6cb8e9df7174

6819077: G1: first GC thread coming late into the GC. Summary: The first worker thread is delayed when entering the GC because it clears the card count table that is used in identifying hot cards. Replace the card count table with a dynamically sized evicting hash table that includes an epoch based counter. Reviewed-by: iveresov, tonyp
author johnc
date Tue, 04 Aug 2009 16:00:17 -0700
parents df6caf649ff7
children 0414c1049f15
comparison
equal deleted inserted replaced
889:15c5903cf9e1 890:6cb8e9df7174
674 } 674 }
675 675
676 676
677 static IntHistogram out_of_histo(50, 50); 677 static IntHistogram out_of_histo(50, 50);
678 678
679 void HRInto_G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i) { 679 void HRInto_G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i) {
680 // If the card is no longer dirty, nothing to do.
681 if (*card_ptr != CardTableModRefBS::dirty_card_val()) return;
682
683 // Construct the region representing the card. 680 // Construct the region representing the card.
684 HeapWord* start = _ct_bs->addr_for(card_ptr); 681 HeapWord* start = _ct_bs->addr_for(card_ptr);
685 // And find the region containing it. 682 // And find the region containing it.
686 HeapRegion* r = _g1->heap_region_containing(start); 683 HeapRegion* r = _g1->heap_region_containing(start);
687 if (r == NULL) { 684 assert(r != NULL, "unexpected null");
688 guarantee(_g1->is_in_permanent(start), "Or else where?");
689 return; // Not in the G1 heap (might be in perm, for example.)
690 }
691 // Why do we have to check here whether a card is on a young region,
692 // given that we dirty young regions and, as a result, the
693 // post-barrier is supposed to filter them out and never to enqueue
694 // them? When we allocate a new region as the "allocation region" we
695 // actually dirty its cards after we release the lock, since card
696 // dirtying while holding the lock was a performance bottleneck. So,
697 // as a result, it is possible for other threads to actually
698 // allocate objects in the region (after the acquire the lock)
699 // before all the cards on the region are dirtied. This is unlikely,
700 // and it doesn't happen often, but it can happen. So, the extra
701 // check below filters out those cards.
702 if (r->is_young()) {
703 return;
704 }
705 // While we are processing RSet buffers during the collection, we
706 // actually don't want to scan any cards on the collection set,
707 // since we don't want to update remebered sets with entries that
708 // point into the collection set, given that live objects from the
709 // collection set are about to move and such entries will be stale
710 // very soon. This change also deals with a reliability issue which
711 // involves scanning a card in the collection set and coming across
712 // an array that was being chunked and looking malformed. Note,
713 // however, that if evacuation fails, we have to scan any objects
714 // that were not moved and create any missing entries.
715 if (r->in_collection_set()) {
716 return;
717 }
718
719 // Should we defer it?
720 if (_cg1r->use_cache()) {
721 card_ptr = _cg1r->cache_insert(card_ptr);
722 // If it was not an eviction, nothing to do.
723 if (card_ptr == NULL) return;
724
725 // OK, we have to reset the card start, region, etc.
726 start = _ct_bs->addr_for(card_ptr);
727 r = _g1->heap_region_containing(start);
728 if (r == NULL) {
729 guarantee(_g1->is_in_permanent(start), "Or else where?");
730 return; // Not in the G1 heap (might be in perm, for example.)
731 }
732 guarantee(!r->is_young(), "It was evicted in the current minor cycle.");
733 }
734 685
735 HeapWord* end = _ct_bs->addr_for(card_ptr + 1); 686 HeapWord* end = _ct_bs->addr_for(card_ptr + 1);
736 MemRegion dirtyRegion(start, end); 687 MemRegion dirtyRegion(start, end);
737 688
738 #if CARD_REPEAT_HISTO 689 #if CARD_REPEAT_HISTO
772 out_of_histo.add_entry(filter_then_update_rs_oop_cl.out_of_region()); 723 out_of_histo.add_entry(filter_then_update_rs_oop_cl.out_of_region());
773 _conc_refine_cards++; 724 _conc_refine_cards++;
774 } 725 }
775 } 726 }
776 727
728 void HRInto_G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i) {
729 // If the card is no longer dirty, nothing to do.
730 if (*card_ptr != CardTableModRefBS::dirty_card_val()) return;
731
732 // Construct the region representing the card.
733 HeapWord* start = _ct_bs->addr_for(card_ptr);
734 // And find the region containing it.
735 HeapRegion* r = _g1->heap_region_containing(start);
736 if (r == NULL) {
737 guarantee(_g1->is_in_permanent(start), "Or else where?");
738 return; // Not in the G1 heap (might be in perm, for example.)
739 }
740 // Why do we have to check here whether a card is on a young region,
741 // given that we dirty young regions and, as a result, the
742 // post-barrier is supposed to filter them out and never to enqueue
743 // them? When we allocate a new region as the "allocation region" we
744 // actually dirty its cards after we release the lock, since card
745 // dirtying while holding the lock was a performance bottleneck. So,
746 // as a result, it is possible for other threads to actually
747 // allocate objects in the region (after the acquire the lock)
748 // before all the cards on the region are dirtied. This is unlikely,
749 // and it doesn't happen often, but it can happen. So, the extra
750 // check below filters out those cards.
751 if (r->is_young()) {
752 return;
753 }
754 // While we are processing RSet buffers during the collection, we
755 // actually don't want to scan any cards on the collection set,
756 // since we don't want to update remebered sets with entries that
757 // point into the collection set, given that live objects from the
758 // collection set are about to move and such entries will be stale
759 // very soon. This change also deals with a reliability issue which
760 // involves scanning a card in the collection set and coming across
761 // an array that was being chunked and looking malformed. Note,
762 // however, that if evacuation fails, we have to scan any objects
763 // that were not moved and create any missing entries.
764 if (r->in_collection_set()) {
765 return;
766 }
767
768 // Should we defer processing the card?
769 //
770 // Previously the result from the insert_cache call would be
771 // either card_ptr (implying that card_ptr was currently "cold"),
772 // null (meaning we had inserted the card ptr into the "hot"
773 // cache, which had some headroom), or a "hot" card ptr
774 // extracted from the "hot" cache.
775 //
776 // Now that the _card_counts cache in the ConcurrentG1Refine
777 // instance is an evicting hash table, the result we get back
778 // could be from evicting the card ptr in an already occupied
779 // bucket (in which case we have replaced the card ptr in the
780 // bucket with card_ptr and "defer" is set to false). To avoid
781 // having a data structure (updates to which would need a lock)
782 // to hold these unprocessed dirty cards, we need to immediately
783 // process card_ptr. The actions needed to be taken on return
784 // from cache_insert are summarized in the following table:
785 //
786 // res defer action
787 // --------------------------------------------------------------
788 // null false card evicted from _card_counts & replaced with
789 // card_ptr; evicted ptr added to hot cache.
790 // No need to process res; immediately process card_ptr
791 //
792 // null true card not evicted from _card_counts; card_ptr added
793 // to hot cache.
794 // Nothing to do.
795 //
796 // non-null false card evicted from _card_counts & replaced with
797 // card_ptr; evicted ptr is currently "cold" or
798 // caused an eviction from the hot cache.
799 // Immediately process res; process card_ptr.
800 //
801 // non-null true card not evicted from _card_counts; card_ptr is
802 // currently cold, or caused an eviction from hot
803 // cache.
804 // Immediately process res; no need to process card_ptr.
805
806 jbyte* res = card_ptr;
807 bool defer = false;
808 if (_cg1r->use_cache()) {
809 jbyte* res = _cg1r->cache_insert(card_ptr, &defer);
810 if (res != NULL && (res != card_ptr || defer)) {
811 start = _ct_bs->addr_for(res);
812 r = _g1->heap_region_containing(start);
813 if (r == NULL) {
814 assert(_g1->is_in_permanent(start), "Or else where?");
815 } else {
816 guarantee(!r->is_young(), "It was evicted in the current minor cycle.");
817 // Process card pointer we get back from the hot card cache
818 concurrentRefineOneCard_impl(res, worker_i);
819 }
820 }
821 }
822
823 if (!defer) {
824 concurrentRefineOneCard_impl(card_ptr, worker_i);
825 }
826 }
827
777 class HRRSStatsIter: public HeapRegionClosure { 828 class HRRSStatsIter: public HeapRegionClosure {
778 size_t _occupied; 829 size_t _occupied;
779 size_t _total_mem_sz; 830 size_t _total_mem_sz;
780 size_t _max_mem_sz; 831 size_t _max_mem_sz;
781 HeapRegion* _max_mem_sz_region; 832 HeapRegion* _max_mem_sz_region;