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;