Mercurial > hg > truffle
comparison src/share/vm/memory/referenceProcessor.cpp @ 1833:8b10f48633dc
6984287: Regularize how GC parallel workers are specified.
Summary: Associate number of GC workers with the workgang as opposed to the task.
Reviewed-by: johnc, ysr
author | jmasa |
---|---|
date | Mon, 20 Sep 2010 14:38:38 -0700 |
parents | c18cbe5936b8 |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1781:97fbf5beff7b | 1833:8b10f48633dc |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2001, 2009, Oracle and/or its affiliates. All rights reserved. | 2 * Copyright (c) 2001, 2010, 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. |
135 { | 135 { |
136 _span = span; | 136 _span = span; |
137 _discovery_is_atomic = atomic_discovery; | 137 _discovery_is_atomic = atomic_discovery; |
138 _discovery_is_mt = mt_discovery; | 138 _discovery_is_mt = mt_discovery; |
139 _num_q = mt_degree; | 139 _num_q = mt_degree; |
140 _discoveredSoftRefs = NEW_C_HEAP_ARRAY(DiscoveredList, _num_q * subclasses_of_ref); | 140 _max_num_q = mt_degree; |
141 _discoveredSoftRefs = NEW_C_HEAP_ARRAY(DiscoveredList, _max_num_q * subclasses_of_ref); | |
141 if (_discoveredSoftRefs == NULL) { | 142 if (_discoveredSoftRefs == NULL) { |
142 vm_exit_during_initialization("Could not allocated RefProc Array"); | 143 vm_exit_during_initialization("Could not allocated RefProc Array"); |
143 } | 144 } |
144 _discoveredWeakRefs = &_discoveredSoftRefs[_num_q]; | 145 _discoveredWeakRefs = &_discoveredSoftRefs[_max_num_q]; |
145 _discoveredFinalRefs = &_discoveredWeakRefs[_num_q]; | 146 _discoveredFinalRefs = &_discoveredWeakRefs[_max_num_q]; |
146 _discoveredPhantomRefs = &_discoveredFinalRefs[_num_q]; | 147 _discoveredPhantomRefs = &_discoveredFinalRefs[_max_num_q]; |
147 assert(sentinel_ref() != NULL, "_sentinelRef is NULL"); | 148 assert(sentinel_ref() != NULL, "_sentinelRef is NULL"); |
148 // Initialized all entries to _sentinelRef | 149 // Initialized all entries to _sentinelRef |
149 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | 150 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { |
150 _discoveredSoftRefs[i].set_head(sentinel_ref()); | 151 _discoveredSoftRefs[i].set_head(sentinel_ref()); |
151 _discoveredSoftRefs[i].set_length(0); | 152 _discoveredSoftRefs[i].set_length(0); |
152 } | 153 } |
153 // If we do barreirs, cache a copy of the barrier set. | 154 // If we do barreirs, cache a copy of the barrier set. |
154 if (discovered_list_needs_barrier) { | 155 if (discovered_list_needs_barrier) { |
157 } | 158 } |
158 | 159 |
159 #ifndef PRODUCT | 160 #ifndef PRODUCT |
160 void ReferenceProcessor::verify_no_references_recorded() { | 161 void ReferenceProcessor::verify_no_references_recorded() { |
161 guarantee(!_discovering_refs, "Discovering refs?"); | 162 guarantee(!_discovering_refs, "Discovering refs?"); |
162 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | 163 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { |
163 guarantee(_discoveredSoftRefs[i].empty(), | 164 guarantee(_discoveredSoftRefs[i].empty(), |
164 "Found non-empty discovered list"); | 165 "Found non-empty discovered list"); |
165 } | 166 } |
166 } | 167 } |
167 #endif | 168 #endif |
168 | 169 |
169 void ReferenceProcessor::weak_oops_do(OopClosure* f) { | 170 void ReferenceProcessor::weak_oops_do(OopClosure* f) { |
170 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | 171 // Should this instead be |
172 // for (int i = 0; i < subclasses_of_ref; i++_ { | |
173 // for (int j = 0; j < _num_q; j++) { | |
174 // int index = i * _max_num_q + j; | |
175 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { | |
171 if (UseCompressedOops) { | 176 if (UseCompressedOops) { |
172 f->do_oop((narrowOop*)_discoveredSoftRefs[i].adr_head()); | 177 f->do_oop((narrowOop*)_discoveredSoftRefs[i].adr_head()); |
173 } else { | 178 } else { |
174 f->do_oop((oop*)_discoveredSoftRefs[i].adr_head()); | 179 f->do_oop((oop*)_discoveredSoftRefs[i].adr_head()); |
175 } | 180 } |
393 | 398 |
394 virtual void work(unsigned int work_id) { | 399 virtual void work(unsigned int work_id) { |
395 assert(work_id < (unsigned int)_ref_processor.num_q(), "Index out-of-bounds"); | 400 assert(work_id < (unsigned int)_ref_processor.num_q(), "Index out-of-bounds"); |
396 // Simplest first cut: static partitioning. | 401 // Simplest first cut: static partitioning. |
397 int index = work_id; | 402 int index = work_id; |
398 for (int j = 0; j < subclasses_of_ref; j++, index += _n_queues) { | 403 // The increment on "index" must correspond to the maximum number of queues |
404 // (n_queues) with which that ReferenceProcessor was created. That | |
405 // is because of the "clever" way the discovered references lists were | |
406 // allocated and are indexed into. That number is ParallelGCThreads | |
407 // currently. Assert that. | |
408 assert(_n_queues == (int) ParallelGCThreads, "Different number not expected"); | |
409 for (int j = 0; | |
410 j < subclasses_of_ref; | |
411 j++, index += _n_queues) { | |
399 _ref_processor.enqueue_discovered_reflist( | 412 _ref_processor.enqueue_discovered_reflist( |
400 _refs_lists[index], _pending_list_addr); | 413 _refs_lists[index], _pending_list_addr); |
401 _refs_lists[index].set_head(_sentinel_ref); | 414 _refs_lists[index].set_head(_sentinel_ref); |
402 _refs_lists[index].set_length(0); | 415 _refs_lists[index].set_length(0); |
403 } | 416 } |
408 void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr, | 421 void ReferenceProcessor::enqueue_discovered_reflists(HeapWord* pending_list_addr, |
409 AbstractRefProcTaskExecutor* task_executor) { | 422 AbstractRefProcTaskExecutor* task_executor) { |
410 if (_processing_is_mt && task_executor != NULL) { | 423 if (_processing_is_mt && task_executor != NULL) { |
411 // Parallel code | 424 // Parallel code |
412 RefProcEnqueueTask tsk(*this, _discoveredSoftRefs, | 425 RefProcEnqueueTask tsk(*this, _discoveredSoftRefs, |
413 pending_list_addr, sentinel_ref(), _num_q); | 426 pending_list_addr, sentinel_ref(), _max_num_q); |
414 task_executor->execute(tsk); | 427 task_executor->execute(tsk); |
415 } else { | 428 } else { |
416 // Serial code: call the parent class's implementation | 429 // Serial code: call the parent class's implementation |
417 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | 430 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { |
418 enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr); | 431 enqueue_discovered_reflist(_discoveredSoftRefs[i], pending_list_addr); |
419 _discoveredSoftRefs[i].set_head(sentinel_ref()); | 432 _discoveredSoftRefs[i].set_head(sentinel_ref()); |
420 _discoveredSoftRefs[i].set_length(0); | 433 _discoveredSoftRefs[i].set_length(0); |
421 } | 434 } |
422 } | 435 } |
612 } | 625 } |
613 // Close the reachable set | 626 // Close the reachable set |
614 complete_gc->do_void(); | 627 complete_gc->do_void(); |
615 NOT_PRODUCT( | 628 NOT_PRODUCT( |
616 if (PrintGCDetails && TraceReferenceGC) { | 629 if (PrintGCDetails && TraceReferenceGC) { |
617 gclog_or_tty->print(" Dropped %d dead Refs out of %d " | 630 gclog_or_tty->print_cr(" Dropped %d dead Refs out of %d " |
618 "discovered Refs by policy ", iter.removed(), iter.processed()); | 631 "discovered Refs by policy list " INTPTR_FORMAT, |
632 iter.removed(), iter.processed(), (address)refs_list.head()); | |
619 } | 633 } |
620 ) | 634 ) |
621 } | 635 } |
622 | 636 |
623 // Traverse the list and remove any Refs that are not active, or | 637 // Traverse the list and remove any Refs that are not active, or |
649 iter.next(); | 663 iter.next(); |
650 } | 664 } |
651 } | 665 } |
652 NOT_PRODUCT( | 666 NOT_PRODUCT( |
653 if (PrintGCDetails && TraceReferenceGC) { | 667 if (PrintGCDetails && TraceReferenceGC) { |
654 gclog_or_tty->print(" Dropped %d active Refs out of %d " | 668 gclog_or_tty->print_cr(" Dropped %d active Refs out of %d " |
655 "Refs in discovered list ", iter.removed(), iter.processed()); | 669 "Refs in discovered list " INTPTR_FORMAT, |
670 iter.removed(), iter.processed(), (address)refs_list.head()); | |
656 } | 671 } |
657 ) | 672 ) |
658 } | 673 } |
659 | 674 |
660 void | 675 void |
687 } | 702 } |
688 // Now close the newly reachable set | 703 // Now close the newly reachable set |
689 complete_gc->do_void(); | 704 complete_gc->do_void(); |
690 NOT_PRODUCT( | 705 NOT_PRODUCT( |
691 if (PrintGCDetails && TraceReferenceGC) { | 706 if (PrintGCDetails && TraceReferenceGC) { |
692 gclog_or_tty->print(" Dropped %d active Refs out of %d " | 707 gclog_or_tty->print_cr(" Dropped %d active Refs out of %d " |
693 "Refs in discovered list ", iter.removed(), iter.processed()); | 708 "Refs in discovered list " INTPTR_FORMAT, |
709 iter.removed(), iter.processed(), (address)refs_list.head()); | |
694 } | 710 } |
695 ) | 711 ) |
696 } | 712 } |
697 | 713 |
698 // Traverse the list and process the referents, by either | 714 // Traverse the list and process the referents, by either |
702 ReferenceProcessor::process_phase3(DiscoveredList& refs_list, | 718 ReferenceProcessor::process_phase3(DiscoveredList& refs_list, |
703 bool clear_referent, | 719 bool clear_referent, |
704 BoolObjectClosure* is_alive, | 720 BoolObjectClosure* is_alive, |
705 OopClosure* keep_alive, | 721 OopClosure* keep_alive, |
706 VoidClosure* complete_gc) { | 722 VoidClosure* complete_gc) { |
723 ResourceMark rm; | |
707 DiscoveredListIterator iter(refs_list, keep_alive, is_alive); | 724 DiscoveredListIterator iter(refs_list, keep_alive, is_alive); |
708 while (iter.has_next()) { | 725 while (iter.has_next()) { |
709 iter.update_discovered(); | 726 iter.update_discovered(); |
710 iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); | 727 iter.load_ptrs(DEBUG_ONLY(false /* allow_null_referent */)); |
711 if (clear_referent) { | 728 if (clear_referent) { |
741 refs_list.set_length(0); | 758 refs_list.set_length(0); |
742 } | 759 } |
743 | 760 |
744 void ReferenceProcessor::abandon_partial_discovery() { | 761 void ReferenceProcessor::abandon_partial_discovery() { |
745 // loop over the lists | 762 // loop over the lists |
746 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | 763 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { |
747 if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) { | 764 if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) { |
748 gclog_or_tty->print_cr( | 765 gclog_or_tty->print_cr( |
749 "\nAbandoning %s discovered list", | 766 "\nAbandoning %s discovered list", |
750 list_name(i)); | 767 list_name(i)); |
751 } | 768 } |
752 abandon_partial_discovered_list(_discoveredSoftRefs[i]); | 769 abandon_partial_discovered_list(_discoveredSoftRefs[i]); |
764 { } | 781 { } |
765 virtual void work(unsigned int i, BoolObjectClosure& is_alive, | 782 virtual void work(unsigned int i, BoolObjectClosure& is_alive, |
766 OopClosure& keep_alive, | 783 OopClosure& keep_alive, |
767 VoidClosure& complete_gc) | 784 VoidClosure& complete_gc) |
768 { | 785 { |
769 _ref_processor.process_phase1(_refs_lists[i], _policy, | 786 Thread* thr = Thread::current(); |
787 int refs_list_index = ((WorkerThread*)thr)->id(); | |
788 _ref_processor.process_phase1(_refs_lists[refs_list_index], _policy, | |
770 &is_alive, &keep_alive, &complete_gc); | 789 &is_alive, &keep_alive, &complete_gc); |
771 } | 790 } |
772 private: | 791 private: |
773 ReferencePolicy* _policy; | 792 ReferencePolicy* _policy; |
774 }; | 793 }; |
800 { } | 819 { } |
801 virtual void work(unsigned int i, BoolObjectClosure& is_alive, | 820 virtual void work(unsigned int i, BoolObjectClosure& is_alive, |
802 OopClosure& keep_alive, | 821 OopClosure& keep_alive, |
803 VoidClosure& complete_gc) | 822 VoidClosure& complete_gc) |
804 { | 823 { |
824 // Don't use "refs_list_index" calculated in this way because | |
825 // balance_queues() has moved the Ref's into the first n queues. | |
826 // Thread* thr = Thread::current(); | |
827 // int refs_list_index = ((WorkerThread*)thr)->id(); | |
828 // _ref_processor.process_phase3(_refs_lists[refs_list_index], _clear_referent, | |
805 _ref_processor.process_phase3(_refs_lists[i], _clear_referent, | 829 _ref_processor.process_phase3(_refs_lists[i], _clear_referent, |
806 &is_alive, &keep_alive, &complete_gc); | 830 &is_alive, &keep_alive, &complete_gc); |
807 } | 831 } |
808 private: | 832 private: |
809 bool _clear_referent; | 833 bool _clear_referent; |
810 }; | 834 }; |
811 | 835 |
812 // Balances reference queues. | 836 // Balances reference queues. |
837 // Move entries from all queues[0, 1, ..., _max_num_q-1] to | |
838 // queues[0, 1, ..., _num_q-1] because only the first _num_q | |
839 // corresponding to the active workers will be processed. | |
813 void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[]) | 840 void ReferenceProcessor::balance_queues(DiscoveredList ref_lists[]) |
814 { | 841 { |
815 // calculate total length | 842 // calculate total length |
816 size_t total_refs = 0; | 843 size_t total_refs = 0; |
817 for (int i = 0; i < _num_q; ++i) { | 844 if (TraceReferenceGC && PrintGCDetails) { |
845 gclog_or_tty->print_cr("\nBalance ref_lists "); | |
846 } | |
847 | |
848 for (int i = 0; i < _max_num_q; ++i) { | |
818 total_refs += ref_lists[i].length(); | 849 total_refs += ref_lists[i].length(); |
850 if (TraceReferenceGC && PrintGCDetails) { | |
851 gclog_or_tty->print("%d ", ref_lists[i].length()); | |
852 } | |
853 } | |
854 if (TraceReferenceGC && PrintGCDetails) { | |
855 gclog_or_tty->print_cr(" = %d", total_refs); | |
819 } | 856 } |
820 size_t avg_refs = total_refs / _num_q + 1; | 857 size_t avg_refs = total_refs / _num_q + 1; |
821 int to_idx = 0; | 858 int to_idx = 0; |
822 for (int from_idx = 0; from_idx < _num_q; from_idx++) { | 859 for (int from_idx = 0; from_idx < _max_num_q; from_idx++) { |
823 while (ref_lists[from_idx].length() > avg_refs) { | 860 bool move_all = false; |
861 if (from_idx >= _num_q) { | |
862 move_all = ref_lists[from_idx].length() > 0; | |
863 } | |
864 while ((ref_lists[from_idx].length() > avg_refs) || | |
865 move_all) { | |
824 assert(to_idx < _num_q, "Sanity Check!"); | 866 assert(to_idx < _num_q, "Sanity Check!"); |
825 if (ref_lists[to_idx].length() < avg_refs) { | 867 if (ref_lists[to_idx].length() < avg_refs) { |
826 // move superfluous refs | 868 // move superfluous refs |
827 size_t refs_to_move = | 869 size_t refs_to_move; |
828 MIN2(ref_lists[from_idx].length() - avg_refs, | 870 // Move all the Ref's if the from queue will not be processed. |
829 avg_refs - ref_lists[to_idx].length()); | 871 if (move_all) { |
872 refs_to_move = MIN2(ref_lists[from_idx].length(), | |
873 avg_refs - ref_lists[to_idx].length()); | |
874 } else { | |
875 refs_to_move = MIN2(ref_lists[from_idx].length() - avg_refs, | |
876 avg_refs - ref_lists[to_idx].length()); | |
877 } | |
830 oop move_head = ref_lists[from_idx].head(); | 878 oop move_head = ref_lists[from_idx].head(); |
831 oop move_tail = move_head; | 879 oop move_tail = move_head; |
832 oop new_head = move_head; | 880 oop new_head = move_head; |
833 // find an element to split the list on | 881 // find an element to split the list on |
834 for (size_t j = 0; j < refs_to_move; ++j) { | 882 for (size_t j = 0; j < refs_to_move; ++j) { |
838 java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head()); | 886 java_lang_ref_Reference::set_discovered(move_tail, ref_lists[to_idx].head()); |
839 ref_lists[to_idx].set_head(move_head); | 887 ref_lists[to_idx].set_head(move_head); |
840 ref_lists[to_idx].inc_length(refs_to_move); | 888 ref_lists[to_idx].inc_length(refs_to_move); |
841 ref_lists[from_idx].set_head(new_head); | 889 ref_lists[from_idx].set_head(new_head); |
842 ref_lists[from_idx].dec_length(refs_to_move); | 890 ref_lists[from_idx].dec_length(refs_to_move); |
891 if (ref_lists[from_idx].length() == 0) { | |
892 break; | |
893 } | |
843 } else { | 894 } else { |
844 ++to_idx; | 895 to_idx = (to_idx + 1) % _num_q; |
845 } | 896 } |
846 } | 897 } |
847 } | 898 } |
899 #ifdef ASSERT | |
900 size_t balanced_total_refs = 0; | |
901 for (int i = 0; i < _max_num_q; ++i) { | |
902 balanced_total_refs += ref_lists[i].length(); | |
903 if (TraceReferenceGC && PrintGCDetails) { | |
904 gclog_or_tty->print("%d ", ref_lists[i].length()); | |
905 } | |
906 } | |
907 if (TraceReferenceGC && PrintGCDetails) { | |
908 gclog_or_tty->print_cr(" = %d", balanced_total_refs); | |
909 gclog_or_tty->flush(); | |
910 } | |
911 assert(total_refs == balanced_total_refs, "Balancing was incomplete"); | |
912 #endif | |
913 } | |
914 | |
915 void ReferenceProcessor::balance_all_queues() { | |
916 balance_queues(_discoveredSoftRefs); | |
917 balance_queues(_discoveredWeakRefs); | |
918 balance_queues(_discoveredFinalRefs); | |
919 balance_queues(_discoveredPhantomRefs); | |
848 } | 920 } |
849 | 921 |
850 void | 922 void |
851 ReferenceProcessor::process_discovered_reflist( | 923 ReferenceProcessor::process_discovered_reflist( |
852 DiscoveredList refs_lists[], | 924 DiscoveredList refs_lists[], |
855 BoolObjectClosure* is_alive, | 927 BoolObjectClosure* is_alive, |
856 OopClosure* keep_alive, | 928 OopClosure* keep_alive, |
857 VoidClosure* complete_gc, | 929 VoidClosure* complete_gc, |
858 AbstractRefProcTaskExecutor* task_executor) | 930 AbstractRefProcTaskExecutor* task_executor) |
859 { | 931 { |
860 bool mt = task_executor != NULL && _processing_is_mt; | 932 bool mt_processing = task_executor != NULL && _processing_is_mt; |
861 if (mt && ParallelRefProcBalancingEnabled) { | 933 // If discovery used MT and a dynamic number of GC threads, then |
934 // the queues must be balanced for correctness if fewer than the | |
935 // maximum number of queues were used. The number of queue used | |
936 // during discovery may be different than the number to be used | |
937 // for processing so don't depend of _num_q < _max_num_q as part | |
938 // of the test. | |
939 bool must_balance = _discovery_is_mt; | |
940 | |
941 if ((mt_processing && ParallelRefProcBalancingEnabled) || | |
942 must_balance) { | |
862 balance_queues(refs_lists); | 943 balance_queues(refs_lists); |
863 } | 944 } |
864 if (PrintReferenceGC && PrintGCDetails) { | 945 if (PrintReferenceGC && PrintGCDetails) { |
865 size_t total = 0; | 946 size_t total = 0; |
866 for (int i = 0; i < _num_q; ++i) { | 947 for (int i = 0; i < _num_q; ++i) { |
873 // . Traverse the list and remove any SoftReferences whose | 954 // . Traverse the list and remove any SoftReferences whose |
874 // referents are not alive, but that should be kept alive for | 955 // referents are not alive, but that should be kept alive for |
875 // policy reasons. Keep alive the transitive closure of all | 956 // policy reasons. Keep alive the transitive closure of all |
876 // such referents. | 957 // such referents. |
877 if (policy != NULL) { | 958 if (policy != NULL) { |
878 if (mt) { | 959 if (mt_processing) { |
879 RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/); | 960 RefProcPhase1Task phase1(*this, refs_lists, policy, true /*marks_oops_alive*/); |
880 task_executor->execute(phase1); | 961 task_executor->execute(phase1); |
881 } else { | 962 } else { |
882 for (int i = 0; i < _num_q; i++) { | 963 for (int i = 0; i < _num_q; i++) { |
883 process_phase1(refs_lists[i], policy, | 964 process_phase1(refs_lists[i], policy, |
889 "Policy must be specified for soft references."); | 970 "Policy must be specified for soft references."); |
890 } | 971 } |
891 | 972 |
892 // Phase 2: | 973 // Phase 2: |
893 // . Traverse the list and remove any refs whose referents are alive. | 974 // . Traverse the list and remove any refs whose referents are alive. |
894 if (mt) { | 975 if (mt_processing) { |
895 RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/); | 976 RefProcPhase2Task phase2(*this, refs_lists, !discovery_is_atomic() /*marks_oops_alive*/); |
896 task_executor->execute(phase2); | 977 task_executor->execute(phase2); |
897 } else { | 978 } else { |
898 for (int i = 0; i < _num_q; i++) { | 979 for (int i = 0; i < _num_q; i++) { |
899 process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc); | 980 process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc); |
900 } | 981 } |
901 } | 982 } |
902 | 983 |
903 // Phase 3: | 984 // Phase 3: |
904 // . Traverse the list and process referents as appropriate. | 985 // . Traverse the list and process referents as appropriate. |
905 if (mt) { | 986 if (mt_processing) { |
906 RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/); | 987 RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/); |
907 task_executor->execute(phase3); | 988 task_executor->execute(phase3); |
908 } else { | 989 } else { |
909 for (int i = 0; i < _num_q; i++) { | 990 for (int i = 0; i < _num_q; i++) { |
910 process_phase3(refs_lists[i], clear_referent, | 991 process_phase3(refs_lists[i], clear_referent, |
913 } | 994 } |
914 } | 995 } |
915 | 996 |
916 void ReferenceProcessor::clean_up_discovered_references() { | 997 void ReferenceProcessor::clean_up_discovered_references() { |
917 // loop over the lists | 998 // loop over the lists |
918 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | 999 // Should this instead be |
1000 // for (int i = 0; i < subclasses_of_ref; i++_ { | |
1001 // for (int j = 0; j < _num_q; j++) { | |
1002 // int index = i * _max_num_q + j; | |
1003 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { | |
919 if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) { | 1004 if (TraceReferenceGC && PrintGCDetails && ((i % _num_q) == 0)) { |
920 gclog_or_tty->print_cr( | 1005 gclog_or_tty->print_cr( |
921 "\nScrubbing %s discovered list of Null referents", | 1006 "\nScrubbing %s discovered list of Null referents", |
922 list_name(i)); | 1007 list_name(i)); |
923 } | 1008 } |
974 // fashion to each of the lists. | 1059 // fashion to each of the lists. |
975 if (_processing_is_mt) { | 1060 if (_processing_is_mt) { |
976 id = next_id(); | 1061 id = next_id(); |
977 } | 1062 } |
978 } | 1063 } |
979 assert(0 <= id && id < _num_q, "Id is out-of-bounds (call Freud?)"); | 1064 assert(0 <= id && id < _max_num_q, "Id is out-of-bounds (call Freud?)"); |
980 | 1065 |
981 // Get the discovered queue to which we will add | 1066 // Get the discovered queue to which we will add |
982 DiscoveredList* list = NULL; | 1067 DiscoveredList* list = NULL; |
983 switch (rt) { | 1068 switch (rt) { |
984 case REF_OTHER: | 1069 case REF_OTHER: |
998 break; | 1083 break; |
999 case REF_NONE: | 1084 case REF_NONE: |
1000 // we should not reach here if we are an instanceRefKlass | 1085 // we should not reach here if we are an instanceRefKlass |
1001 default: | 1086 default: |
1002 ShouldNotReachHere(); | 1087 ShouldNotReachHere(); |
1088 } | |
1089 if (TraceReferenceGC && PrintGCDetails) { | |
1090 gclog_or_tty->print_cr("Thread %d gets list " INTPTR_FORMAT, | |
1091 id, list); | |
1003 } | 1092 } |
1004 return list; | 1093 return list; |
1005 } | 1094 } |
1006 | 1095 |
1007 inline void | 1096 inline void |
1241 #endif | 1330 #endif |
1242 // Soft references | 1331 // Soft references |
1243 { | 1332 { |
1244 TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, | 1333 TraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, |
1245 false, gclog_or_tty); | 1334 false, gclog_or_tty); |
1246 for (int i = 0; i < _num_q; i++) { | 1335 for (int i = 0; i < _max_num_q; i++) { |
1247 if (yield->should_return()) { | 1336 if (yield->should_return()) { |
1248 return; | 1337 return; |
1249 } | 1338 } |
1250 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, | 1339 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, |
1251 keep_alive, complete_gc, yield); | 1340 keep_alive, complete_gc, yield); |
1338 // Close the reachable set | 1427 // Close the reachable set |
1339 complete_gc->do_void(); | 1428 complete_gc->do_void(); |
1340 | 1429 |
1341 NOT_PRODUCT( | 1430 NOT_PRODUCT( |
1342 if (PrintGCDetails && PrintReferenceGC) { | 1431 if (PrintGCDetails && PrintReferenceGC) { |
1343 gclog_or_tty->print(" Dropped %d Refs out of %d " | 1432 gclog_or_tty->print_cr(" Dropped %d Refs out of %d " |
1344 "Refs in discovered list ", iter.removed(), iter.processed()); | 1433 "Refs in discovered list " INTPTR_FORMAT, |
1434 iter.removed(), iter.processed(), (address)refs_list.head()); | |
1345 } | 1435 } |
1346 ) | 1436 ) |
1347 } | 1437 } |
1348 | 1438 |
1349 const char* ReferenceProcessor::list_name(int i) { | 1439 const char* ReferenceProcessor::list_name(int i) { |
1350 assert(i >= 0 && i <= _num_q * subclasses_of_ref, "Out of bounds index"); | 1440 assert(i >= 0 && i <= _max_num_q * subclasses_of_ref, "Out of bounds index"); |
1351 int j = i / _num_q; | 1441 int j = i / _max_num_q; |
1352 switch (j) { | 1442 switch (j) { |
1353 case 0: return "SoftRef"; | 1443 case 0: return "SoftRef"; |
1354 case 1: return "WeakRef"; | 1444 case 1: return "WeakRef"; |
1355 case 2: return "FinalRef"; | 1445 case 2: return "FinalRef"; |
1356 case 3: return "PhantomRef"; | 1446 case 3: return "PhantomRef"; |
1370 } | 1460 } |
1371 | 1461 |
1372 #ifndef PRODUCT | 1462 #ifndef PRODUCT |
1373 void ReferenceProcessor::clear_discovered_references() { | 1463 void ReferenceProcessor::clear_discovered_references() { |
1374 guarantee(!_discovering_refs, "Discovering refs?"); | 1464 guarantee(!_discovering_refs, "Discovering refs?"); |
1375 for (int i = 0; i < _num_q * subclasses_of_ref; i++) { | 1465 for (int i = 0; i < _max_num_q * subclasses_of_ref; i++) { |
1376 oop obj = _discoveredSoftRefs[i].head(); | 1466 oop obj = _discoveredSoftRefs[i].head(); |
1377 while (obj != sentinel_ref()) { | 1467 while (obj != sentinel_ref()) { |
1378 oop next = java_lang_ref_Reference::discovered(obj); | 1468 oop next = java_lang_ref_Reference::discovered(obj); |
1379 java_lang_ref_Reference::set_discovered(obj, (oop) NULL); | 1469 java_lang_ref_Reference::set_discovered(obj, (oop) NULL); |
1380 obj = next; | 1470 obj = next; |