1 /* |
1 /* |
2 * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
567 } |
567 } |
568 |
568 |
569 |
569 |
570 static IntHistogram out_of_histo(50, 50); |
570 static IntHistogram out_of_histo(50, 50); |
571 |
571 |
572 class TriggerClosure : public OopClosure { |
572 |
573 bool _trigger; |
573 G1TriggerClosure::G1TriggerClosure() : |
574 public: |
574 _triggered(false) { } |
575 TriggerClosure() : _trigger(false) { } |
575 |
576 bool value() const { return _trigger; } |
576 G1InvokeIfNotTriggeredClosure::G1InvokeIfNotTriggeredClosure(G1TriggerClosure* t_cl, |
577 template <class T> void do_oop_nv(T* p) { _trigger = true; } |
577 OopClosure* oop_cl) : |
578 virtual void do_oop(oop* p) { do_oop_nv(p); } |
578 _trigger_cl(t_cl), _oop_cl(oop_cl) { } |
579 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } |
579 |
580 }; |
580 G1Mux2Closure::G1Mux2Closure(OopClosure *c1, OopClosure *c2) : |
581 |
581 _c1(c1), _c2(c2) { } |
582 class InvokeIfNotTriggeredClosure: public OopClosure { |
582 |
583 TriggerClosure* _t; |
583 G1UpdateRSOrPushRefOopClosure:: |
584 OopClosure* _oc; |
584 G1UpdateRSOrPushRefOopClosure(G1CollectedHeap* g1h, |
585 public: |
585 G1RemSet* rs, |
586 InvokeIfNotTriggeredClosure(TriggerClosure* t, OopClosure* oc): |
586 OopsInHeapRegionClosure* push_ref_cl, |
587 _t(t), _oc(oc) { } |
587 bool record_refs_into_cset, |
588 template <class T> void do_oop_nv(T* p) { |
588 int worker_i) : |
589 if (!_t->value()) _oc->do_oop(p); |
589 _g1(g1h), _g1_rem_set(rs), _from(NULL), |
590 } |
590 _record_refs_into_cset(record_refs_into_cset), |
591 virtual void do_oop(oop* p) { do_oop_nv(p); } |
591 _push_ref_cl(push_ref_cl), _worker_i(worker_i) { } |
592 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } |
|
593 }; |
|
594 |
|
595 class Mux2Closure : public OopClosure { |
|
596 OopClosure* _c1; |
|
597 OopClosure* _c2; |
|
598 public: |
|
599 Mux2Closure(OopClosure *c1, OopClosure *c2) : _c1(c1), _c2(c2) { } |
|
600 template <class T> void do_oop_nv(T* p) { |
|
601 _c1->do_oop(p); _c2->do_oop(p); |
|
602 } |
|
603 virtual void do_oop(oop* p) { do_oop_nv(p); } |
|
604 virtual void do_oop(narrowOop* p) { do_oop_nv(p); } |
|
605 }; |
|
606 |
592 |
607 bool G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i, |
593 bool G1RemSet::concurrentRefineOneCard_impl(jbyte* card_ptr, int worker_i, |
608 bool check_for_refs_into_cset) { |
594 bool check_for_refs_into_cset) { |
609 // Construct the region representing the card. |
595 // Construct the region representing the card. |
610 HeapWord* start = _ct_bs->addr_for(card_ptr); |
596 HeapWord* start = _ct_bs->addr_for(card_ptr); |
627 // only be active outside of a collection which means that when they |
613 // only be active outside of a collection which means that when they |
628 // reach here they should have check_for_refs_into_cset == false. |
614 // reach here they should have check_for_refs_into_cset == false. |
629 assert((size_t)worker_i < n_workers(), "index of worker larger than _cset_rs_update_cl[].length"); |
615 assert((size_t)worker_i < n_workers(), "index of worker larger than _cset_rs_update_cl[].length"); |
630 oops_in_heap_closure = _cset_rs_update_cl[worker_i]; |
616 oops_in_heap_closure = _cset_rs_update_cl[worker_i]; |
631 } |
617 } |
632 UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1, |
618 G1UpdateRSOrPushRefOopClosure update_rs_oop_cl(_g1, |
633 _g1->g1_rem_set(), |
619 _g1->g1_rem_set(), |
634 oops_in_heap_closure, |
620 oops_in_heap_closure, |
635 check_for_refs_into_cset, |
621 check_for_refs_into_cset, |
636 worker_i); |
622 worker_i); |
637 update_rs_oop_cl.set_from(r); |
623 update_rs_oop_cl.set_from(r); |
638 |
624 |
639 TriggerClosure trigger_cl; |
625 G1TriggerClosure trigger_cl; |
640 FilterIntoCSClosure into_cs_cl(NULL, _g1, &trigger_cl); |
626 FilterIntoCSClosure into_cs_cl(NULL, _g1, &trigger_cl); |
641 InvokeIfNotTriggeredClosure invoke_cl(&trigger_cl, &into_cs_cl); |
627 G1InvokeIfNotTriggeredClosure invoke_cl(&trigger_cl, &into_cs_cl); |
642 Mux2Closure mux(&invoke_cl, &update_rs_oop_cl); |
628 G1Mux2Closure mux(&invoke_cl, &update_rs_oop_cl); |
643 |
629 |
644 FilterOutOfRegionClosure filter_then_update_rs_oop_cl(r, |
630 FilterOutOfRegionClosure filter_then_update_rs_oop_cl(r, |
645 (check_for_refs_into_cset ? |
631 (check_for_refs_into_cset ? |
646 (OopClosure*)&mux : |
632 (OopClosure*)&mux : |
647 (OopClosure*)&update_rs_oop_cl)); |
633 (OopClosure*)&update_rs_oop_cl)); |
686 } else { |
672 } else { |
687 out_of_histo.add_entry(filter_then_update_rs_oop_cl.out_of_region()); |
673 out_of_histo.add_entry(filter_then_update_rs_oop_cl.out_of_region()); |
688 _conc_refine_cards++; |
674 _conc_refine_cards++; |
689 } |
675 } |
690 |
676 |
691 return trigger_cl.value(); |
677 return trigger_cl.triggered(); |
692 } |
678 } |
693 |
679 |
694 bool G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i, |
680 bool G1RemSet::concurrentRefineOneCard(jbyte* card_ptr, int worker_i, |
695 bool check_for_refs_into_cset) { |
681 bool check_for_refs_into_cset) { |
696 // If the card is no longer dirty, nothing to do. |
682 // If the card is no longer dirty, nothing to do. |