Mercurial > hg > graal-compiler
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; |