1 /*
2 * Copyright (c) 2001, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
510 G1CollectedHeap* _g1h;
511 G1CardLiveData* _live_data;
512 public:
513 G1ScrubRSClosure(G1CardLiveData* live_data) :
514 _g1h(G1CollectedHeap::heap()),
515 _live_data(live_data) { }
516
517 bool doHeapRegion(HeapRegion* r) {
518 if (!r->is_continues_humongous()) {
519 r->rem_set()->scrub(_live_data);
520 }
521 return false;
522 }
523 };
524
525 void G1RemSet::scrub(uint worker_num, HeapRegionClaimer *hrclaimer) {
526 G1ScrubRSClosure scrub_cl(&_card_live_data);
527 _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
528 }
529
530 G1TriggerClosure::G1TriggerClosure() :
531 _triggered(false) { }
532
533 G1InvokeIfNotTriggeredClosure::G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t_cl,
534 OopClosure* oop_cl) :
535 _trigger_cl(t_cl), _oop_cl(oop_cl) { }
536
537 G1Mux2Closure::G1Mux2Closure(OopClosure *c1, OopClosure *c2) :
538 _c1(c1), _c2(c2) { }
539
540 G1UpdateRSOrPushRefOopClosure::
541 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
542 G1RemSet* rs,
543 G1ParPushHeapRSClosure* push_ref_cl,
544 bool record_refs_into_cset,
545 uint worker_i) :
546 _g1(g1h), _g1_rem_set(rs), _from(NULL),
547 _record_refs_into_cset(record_refs_into_cset),
548 _push_ref_cl(push_ref_cl), _worker_i(worker_i) { }
549
550 // Returns true if the given card contains references that point
551 // into the collection set, if we're checking for such references;
552 // false otherwise.
553
554 bool G1RemSet::refine_card(jbyte* card_ptr,
555 uint worker_i,
556 G1ParPushHeapRSClosure* oops_in_heap_closure) {
557 assert(_g1->is_in_exact(_ct_bs->addr_for(card_ptr)),
558 "Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap",
559 p2i(card_ptr),
560 _ct_bs->index_for(_ct_bs->addr_for(card_ptr)),
561 p2i(_ct_bs->addr_for(card_ptr)),
562 _g1->addr_to_region(_ct_bs->addr_for(card_ptr)));
563
564 bool check_for_refs_into_cset = oops_in_heap_closure != NULL;
565
566 // If the card is no longer dirty, nothing to do.
567 if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
568 // No need to return that this card contains refs that point
673 // Okay to clean and process the card now. There are still some
674 // stale card cases that may be detected by iteration and dealt with
675 // as iteration failure.
676 *const_cast<volatile jbyte*>(card_ptr) = CardTableModRefBS::clean_card_val();
677
678 // This fence serves two purposes. First, the card must be cleaned
679 // before processing the contents. Second, we can't proceed with
680 // processing until after the read of top, for synchronization with
681 // possibly concurrent humongous object allocation. It's okay that
682 // reading top and reading type were racy wrto each other. We need
683 // both set, in any order, to proceed.
684 OrderAccess::fence();
685
686 // Don't use addr_for(card_ptr + 1) which can ask for
687 // a card beyond the heap.
688 HeapWord* end = start + CardTableModRefBS::card_size_in_words;
689 MemRegion dirty_region(start, MIN2(scan_limit, end));
690 assert(!dirty_region.is_empty(), "sanity");
691
692 G1UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
693 _g1->g1_rem_set(),
694 oops_in_heap_closure,
695 check_for_refs_into_cset,
696 worker_i);
697 update_rs_oop_cl.set_from(r);
698
699 G1TriggerClosure trigger_cl;
700 FilterIntoCSClosure into_cs_cl(_g1, &trigger_cl);
701 G1InvokeIfNotTriggeredClosure invoke_cl(&trigger_cl, &into_cs_cl);
702 G1Mux2Closure mux(&invoke_cl, &update_rs_oop_cl);
703
704 FilterOutOfRegionClosure filter_then_update_rs_oop_cl(r,
705 (check_for_refs_into_cset ?
706 (OopClosure*)&mux :
707 (OopClosure*)&update_rs_oop_cl));
708
709 bool card_processed =
710 r->oops_on_card_seq_iterate_careful(dirty_region,
711 &filter_then_update_rs_oop_cl);
712
713 // If unable to process the card then we encountered an unparsable
714 // part of the heap (e.g. a partially allocated object) while
715 // processing a stale card. Despite the card being stale, redirty
716 // and re-enqueue, because we've already cleaned the card. Without
717 // this we could incorrectly discard a non-stale card.
718 if (!card_processed) {
719 assert(!_g1->is_gc_active(), "Unparsable heap during GC");
720 // The card might have gotten re-dirtied and re-enqueued while we
721 // worked. (In fact, it's pretty likely.)
722 if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
723 *card_ptr = CardTableModRefBS::dirty_card_val();
724 MutexLockerEx x(Shared_DirtyCardQ_lock,
725 Mutex::_no_safepoint_check_flag);
726 DirtyCardQueue* sdcq =
727 JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
728 sdcq->enqueue(card_ptr);
729 }
730 } else {
731 _conc_refine_cards++;
732 }
733
734 // This gets set to true if the card being refined has
735 // references that point into the collection set.
736 bool has_refs_into_cset = trigger_cl.triggered();
737
738 // We should only be detecting that the card contains references
739 // that point into the collection set if the current thread is
740 // a GC worker thread.
741 assert(!has_refs_into_cset || SafepointSynchronize::is_at_safepoint(),
742 "invalid result at non safepoint");
743
744 return has_refs_into_cset;
745 }
746
747 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
748 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
749 (period_count % G1SummarizeRSetStatsPeriod == 0)) {
750
751 if (!_prev_period_summary.initialized()) {
752 _prev_period_summary.initialize(this);
753 }
754
755 G1RemSetSummary current;
756 current.initialize(this);
|
1 /*
2 * Copyright (c) 2001, 2017, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
510 G1CollectedHeap* _g1h;
511 G1CardLiveData* _live_data;
512 public:
513 G1ScrubRSClosure(G1CardLiveData* live_data) :
514 _g1h(G1CollectedHeap::heap()),
515 _live_data(live_data) { }
516
517 bool doHeapRegion(HeapRegion* r) {
518 if (!r->is_continues_humongous()) {
519 r->rem_set()->scrub(_live_data);
520 }
521 return false;
522 }
523 };
524
525 void G1RemSet::scrub(uint worker_num, HeapRegionClaimer *hrclaimer) {
526 G1ScrubRSClosure scrub_cl(&_card_live_data);
527 _g1->heap_region_par_iterate(&scrub_cl, worker_num, hrclaimer);
528 }
529
530 G1UpdateRSOrPushRefOopClosure::G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h,
531 G1ParPushHeapRSClosure* push_ref_cl,
532 bool record_refs_into_cset,
533 uint worker_i) :
534 _g1(g1h),
535 _from(NULL),
536 _record_refs_into_cset(record_refs_into_cset),
537 _has_refs_into_cset(false),
538 _push_ref_cl(push_ref_cl),
539 _worker_i(worker_i) { }
540
541 // Returns true if the given card contains references that point
542 // into the collection set, if we're checking for such references;
543 // false otherwise.
544
545 bool G1RemSet::refine_card(jbyte* card_ptr,
546 uint worker_i,
547 G1ParPushHeapRSClosure* oops_in_heap_closure) {
548 assert(_g1->is_in_exact(_ct_bs->addr_for(card_ptr)),
549 "Card at " PTR_FORMAT " index " SIZE_FORMAT " representing heap at " PTR_FORMAT " (%u) must be in committed heap",
550 p2i(card_ptr),
551 _ct_bs->index_for(_ct_bs->addr_for(card_ptr)),
552 p2i(_ct_bs->addr_for(card_ptr)),
553 _g1->addr_to_region(_ct_bs->addr_for(card_ptr)));
554
555 bool check_for_refs_into_cset = oops_in_heap_closure != NULL;
556
557 // If the card is no longer dirty, nothing to do.
558 if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
559 // No need to return that this card contains refs that point
664 // Okay to clean and process the card now. There are still some
665 // stale card cases that may be detected by iteration and dealt with
666 // as iteration failure.
667 *const_cast<volatile jbyte*>(card_ptr) = CardTableModRefBS::clean_card_val();
668
669 // This fence serves two purposes. First, the card must be cleaned
670 // before processing the contents. Second, we can't proceed with
671 // processing until after the read of top, for synchronization with
672 // possibly concurrent humongous object allocation. It's okay that
673 // reading top and reading type were racy wrto each other. We need
674 // both set, in any order, to proceed.
675 OrderAccess::fence();
676
677 // Don't use addr_for(card_ptr + 1) which can ask for
678 // a card beyond the heap.
679 HeapWord* end = start + CardTableModRefBS::card_size_in_words;
680 MemRegion dirty_region(start, MIN2(scan_limit, end));
681 assert(!dirty_region.is_empty(), "sanity");
682
683 G1UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1,
684 oops_in_heap_closure,
685 check_for_refs_into_cset,
686 worker_i);
687 update_rs_oop_cl.set_from(r);
688
689 bool card_processed =
690 r->oops_on_card_seq_iterate_careful(dirty_region,
691 &update_rs_oop_cl);
692
693 // If unable to process the card then we encountered an unparsable
694 // part of the heap (e.g. a partially allocated object) while
695 // processing a stale card. Despite the card being stale, redirty
696 // and re-enqueue, because we've already cleaned the card. Without
697 // this we could incorrectly discard a non-stale card.
698 if (!card_processed) {
699 assert(!_g1->is_gc_active(), "Unparsable heap during GC");
700 // The card might have gotten re-dirtied and re-enqueued while we
701 // worked. (In fact, it's pretty likely.)
702 if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
703 *card_ptr = CardTableModRefBS::dirty_card_val();
704 MutexLockerEx x(Shared_DirtyCardQ_lock,
705 Mutex::_no_safepoint_check_flag);
706 DirtyCardQueue* sdcq =
707 JavaThread::dirty_card_queue_set().shared_dirty_card_queue();
708 sdcq->enqueue(card_ptr);
709 }
710 } else {
711 _conc_refine_cards++;
712 }
713
714 // This gets set to true if the card being refined has references that point
715 // into the collection set.
716 bool has_refs_into_cset = update_rs_oop_cl.has_refs_into_cset();
717
718 // We should only be detecting that the card contains references
719 // that point into the collection set if the current thread is
720 // a GC worker thread.
721 assert(!has_refs_into_cset || SafepointSynchronize::is_at_safepoint(),
722 "invalid result at non safepoint");
723
724 return has_refs_into_cset;
725 }
726
727 void G1RemSet::print_periodic_summary_info(const char* header, uint period_count) {
728 if ((G1SummarizeRSetStatsPeriod > 0) && log_is_enabled(Trace, gc, remset) &&
729 (period_count % G1SummarizeRSetStatsPeriod == 0)) {
730
731 if (!_prev_period_summary.initialized()) {
732 _prev_period_summary.initialize(this);
733 }
734
735 G1RemSetSummary current;
736 current.initialize(this);
|