51 // os::javaTimeMillis() does not guarantee monotonicity.
52 jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
53
54 // Initialize the soft ref timestamp clock.
55 _soft_ref_timestamp_clock = now;
56 // Also update the soft ref clock in j.l.r.SoftReference
57 java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
58
59 _always_clear_soft_ref_policy = new AlwaysClearPolicy();
60 _default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
61 NOT_COMPILER2(LRUCurrentHeapPolicy());
62 if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
63 vm_exit_during_initialization("Could not allocate reference policy object");
64 }
65 guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
66 RefDiscoveryPolicy == ReferentBasedDiscovery,
67 "Unrecognized RefDiscoveryPolicy");
68 _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
69 }
70
71 void ReferenceProcessor::enable_discovery(bool verify_disabled, bool check_no_refs) {
72 #ifdef ASSERT
73 // Verify that we're not currently discovering refs
74 assert(!verify_disabled || !_discovering_refs, "nested call?");
75
76 if (check_no_refs) {
77 // Verify that the discovered lists are empty
78 verify_no_references_recorded();
79 }
80 #endif // ASSERT
81
82 // Someone could have modified the value of the static
83 // field in the j.l.r.SoftReference class that holds the
84 // soft reference timestamp clock using reflection or
85 // Unsafe between GCs. Unconditionally update the static
86 // field in ReferenceProcessor here so that we use the new
87 // value during reference discovery.
88
89 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
90 _discovering_refs = true;
91 }
92
93 ReferenceProcessor::ReferenceProcessor(MemRegion span,
94 bool mt_processing,
944 task_executor->execute(phase2);
945 } else {
946 for (uint i = 0; i < _max_num_q; i++) {
947 process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
948 }
949 }
950
951 // Phase 3:
952 // . Traverse the list and process referents as appropriate.
953 if (mt_processing) {
954 RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
955 task_executor->execute(phase3);
956 } else {
957 for (uint i = 0; i < _max_num_q; i++) {
958 process_phase3(refs_lists[i], clear_referent,
959 is_alive, keep_alive, complete_gc);
960 }
961 }
962
963 return total_list_count;
964 }
965
966 void ReferenceProcessor::clean_up_discovered_references() {
967 // loop over the lists
968 for (uint i = 0; i < _max_num_q * number_of_subclasses_of_ref(); i++) {
969 if (TraceReferenceGC && PrintGCDetails && ((i % _max_num_q) == 0)) {
970 gclog_or_tty->print_cr(
971 "\nScrubbing %s discovered list of Null referents",
972 list_name(i));
973 }
974 clean_up_discovered_reflist(_discovered_refs[i]);
975 }
976 }
977
978 void ReferenceProcessor::clean_up_discovered_reflist(DiscoveredList& refs_list) {
979 assert(!discovery_is_atomic(), "Else why call this method?");
980 DiscoveredListIterator iter(refs_list, NULL, NULL);
981 while (iter.has_next()) {
982 iter.load_ptrs(DEBUG_ONLY(true /* allow_null_referent */));
983 oop next = java_lang_ref_Reference::next(iter.obj());
984 assert(next->is_oop_or_null(), err_msg("Expected an oop or NULL for next field at " PTR_FORMAT, p2i(next)));
985 // If referent has been cleared or Reference is not active,
986 // drop it.
987 if (iter.referent() == NULL || next != NULL) {
988 debug_only(
989 if (PrintGCDetails && TraceReferenceGC) {
990 gclog_or_tty->print_cr("clean_up_discovered_list: Dropping Reference: "
991 INTPTR_FORMAT " with next field: " INTPTR_FORMAT
992 " and referent: " INTPTR_FORMAT,
993 (void *)iter.obj(), (void *)next, (void *)iter.referent());
994 }
995 )
996 // Remove Reference object from list
997 iter.remove();
998 iter.move_to_next();
999 } else {
1000 iter.next();
1001 }
1002 }
1003 NOT_PRODUCT(
1004 if (PrintGCDetails && TraceReferenceGC) {
1005 gclog_or_tty->print(
1006 " Removed %d Refs with NULL referents out of %d discovered Refs",
1007 iter.removed(), iter.processed());
1008 }
1009 )
1010 }
1011
1012 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
1013 uint id = 0;
1014 // Determine the queue index to use for this object.
1015 if (_discovery_is_mt) {
1016 // During a multi-threaded discovery phase,
1017 // each thread saves to its "own" list.
1018 Thread* thr = Thread::current();
1019 id = thr->as_Worker_thread()->id();
1020 } else {
1021 // single-threaded discovery, we save in round-robin
1022 // fashion to each of the lists.
1023 if (_processing_is_mt) {
1024 id = next_id();
1025 }
1026 }
1027 assert(0 <= id && id < _max_num_q, "Id is out-of-bounds (call Freud?)");
1028
1029 // Get the discovered queue to which we will add
|
51 // os::javaTimeMillis() does not guarantee monotonicity.
52 jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
53
54 // Initialize the soft ref timestamp clock.
55 _soft_ref_timestamp_clock = now;
56 // Also update the soft ref clock in j.l.r.SoftReference
57 java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
58
59 _always_clear_soft_ref_policy = new AlwaysClearPolicy();
60 _default_soft_ref_policy = new COMPILER2_PRESENT(LRUMaxHeapPolicy())
61 NOT_COMPILER2(LRUCurrentHeapPolicy());
62 if (_always_clear_soft_ref_policy == NULL || _default_soft_ref_policy == NULL) {
63 vm_exit_during_initialization("Could not allocate reference policy object");
64 }
65 guarantee(RefDiscoveryPolicy == ReferenceBasedDiscovery ||
66 RefDiscoveryPolicy == ReferentBasedDiscovery,
67 "Unrecognized RefDiscoveryPolicy");
68 _pending_list_uses_discovered_field = JDK_Version::current().pending_list_uses_discovered_field();
69 }
70
71 void ReferenceProcessor::enable_discovery(bool check_no_refs) {
72 #ifdef ASSERT
73 // Verify that we're not currently discovering refs
74 assert(!_discovering_refs, "nested call?");
75
76 if (check_no_refs) {
77 // Verify that the discovered lists are empty
78 verify_no_references_recorded();
79 }
80 #endif // ASSERT
81
82 // Someone could have modified the value of the static
83 // field in the j.l.r.SoftReference class that holds the
84 // soft reference timestamp clock using reflection or
85 // Unsafe between GCs. Unconditionally update the static
86 // field in ReferenceProcessor here so that we use the new
87 // value during reference discovery.
88
89 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock();
90 _discovering_refs = true;
91 }
92
93 ReferenceProcessor::ReferenceProcessor(MemRegion span,
94 bool mt_processing,
944 task_executor->execute(phase2);
945 } else {
946 for (uint i = 0; i < _max_num_q; i++) {
947 process_phase2(refs_lists[i], is_alive, keep_alive, complete_gc);
948 }
949 }
950
951 // Phase 3:
952 // . Traverse the list and process referents as appropriate.
953 if (mt_processing) {
954 RefProcPhase3Task phase3(*this, refs_lists, clear_referent, true /*marks_oops_alive*/);
955 task_executor->execute(phase3);
956 } else {
957 for (uint i = 0; i < _max_num_q; i++) {
958 process_phase3(refs_lists[i], clear_referent,
959 is_alive, keep_alive, complete_gc);
960 }
961 }
962
963 return total_list_count;
964 }
965
966 inline DiscoveredList* ReferenceProcessor::get_discovered_list(ReferenceType rt) {
967 uint id = 0;
968 // Determine the queue index to use for this object.
969 if (_discovery_is_mt) {
970 // During a multi-threaded discovery phase,
971 // each thread saves to its "own" list.
972 Thread* thr = Thread::current();
973 id = thr->as_Worker_thread()->id();
974 } else {
975 // single-threaded discovery, we save in round-robin
976 // fashion to each of the lists.
977 if (_processing_is_mt) {
978 id = next_id();
979 }
980 }
981 assert(0 <= id && id < _max_num_q, "Id is out-of-bounds (call Freud?)");
982
983 // Get the discovered queue to which we will add
|