170 _soft_ref_timestamp_clock = now; 171 java_lang_ref_SoftReference::set_clock(now); 172 } 173 // Else leave clock stalled at its old value until time progresses 174 // past clock value. 175 } 176 177 size_t ReferenceProcessor::total_count(DiscoveredList lists[]) { 178 size_t total = 0; 179 for (uint i = 0; i < _max_num_q; ++i) { 180 total += lists[i].length(); 181 } 182 return total; 183 } 184 185 ReferenceProcessorStats ReferenceProcessor::process_discovered_references( 186 BoolObjectClosure* is_alive, 187 OopClosure* keep_alive, 188 VoidClosure* complete_gc, 189 AbstractRefProcTaskExecutor* task_executor, 190 GCTimer* gc_timer, 191 GCId gc_id) { 192 193 assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); 194 // Stop treating discovered references specially. 195 disable_discovery(); 196 197 // If discovery was concurrent, someone could have modified 198 // the value of the static field in the j.l.r.SoftReference 199 // class that holds the soft reference timestamp clock using 200 // reflection or Unsafe between when discovery was enabled and 201 // now. Unconditionally update the static field in ReferenceProcessor 202 // here so that we use the new value during processing of the 203 // discovered soft refs. 204 205 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); 206 207 bool trace_time = PrintGCDetails && PrintReferenceGC; 208 209 // Soft references 210 size_t soft_count = 0; 211 { 212 GCTraceTime tt("SoftReference", trace_time, false, gc_timer, gc_id); 213 soft_count = 214 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, 215 is_alive, keep_alive, complete_gc, task_executor); 216 } 217 218 update_soft_ref_master_clock(); 219 220 // Weak references 221 size_t weak_count = 0; 222 { 223 GCTraceTime tt("WeakReference", trace_time, false, gc_timer, gc_id); 224 weak_count = 225 process_discovered_reflist(_discoveredWeakRefs, NULL, true, 226 is_alive, keep_alive, complete_gc, task_executor); 227 } 228 229 // Final references 230 size_t final_count = 0; 231 { 232 GCTraceTime tt("FinalReference", trace_time, false, gc_timer, gc_id); 233 final_count = 234 process_discovered_reflist(_discoveredFinalRefs, NULL, false, 235 is_alive, keep_alive, complete_gc, task_executor); 236 } 237 238 // Phantom references 239 size_t phantom_count = 0; 240 { 241 GCTraceTime tt("PhantomReference", trace_time, false, gc_timer, gc_id); 242 phantom_count = 243 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, 244 is_alive, keep_alive, complete_gc, task_executor); 245 246 } 247 248 // Cleaners 249 size_t cleaner_count = 0; 250 { 251 GCTraceTime tt("Cleaners", trace_time, false, gc_timer, gc_id); 252 cleaner_count = 253 process_discovered_reflist(_discoveredCleanerRefs, NULL, true, 254 is_alive, keep_alive, complete_gc, task_executor); 255 } 256 257 // Weak global JNI references. It would make more sense (semantically) to 258 // traverse these simultaneously with the regular weak references above, but 259 // that is not how the JDK1.2 specification is. See #4126360. Native code can 260 // thus use JNI weak references to circumvent the phantom references and 261 // resurrect a "post-mortem" object. 262 size_t jni_weak_ref_count = 0; 263 { 264 GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer, gc_id); 265 if (task_executor != NULL) { 266 task_executor->set_single_threaded_mode(); 267 } 268 jni_weak_ref_count = 269 process_phaseJNI(is_alive, keep_alive, complete_gc); 270 } 271 272 return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count, cleaner_count, jni_weak_ref_count); 273 } 274 275 #ifndef PRODUCT 276 // Calculate the number of jni handles. 277 uint ReferenceProcessor::count_jni_refs() { 278 class AlwaysAliveClosure: public BoolObjectClosure { 279 public: 280 virtual bool do_object_b(oop obj) { return true; } 281 }; 282 283 class CountHandleClosure: public OopClosure { 284 private: 1139 1140 if (TraceReferenceGC) { 1141 gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)", 1142 p2i(obj), obj->klass()->internal_name()); 1143 } 1144 } 1145 assert(obj->is_oop(), "Discovered a bad reference"); 1146 verify_referent(obj); 1147 return true; 1148 } 1149 1150 // Preclean the discovered references by removing those 1151 // whose referents are alive, and by marking from those that 1152 // are not active. These lists can be handled here 1153 // in any order and, indeed, concurrently. 1154 void ReferenceProcessor::preclean_discovered_references( 1155 BoolObjectClosure* is_alive, 1156 OopClosure* keep_alive, 1157 VoidClosure* complete_gc, 1158 YieldClosure* yield, 1159 GCTimer* gc_timer, 1160 GCId gc_id) { 1161 1162 // Soft references 1163 { 1164 GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, 1165 false, gc_timer, gc_id); 1166 for (uint i = 0; i < _max_num_q; i++) { 1167 if (yield->should_return()) { 1168 return; 1169 } 1170 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, 1171 keep_alive, complete_gc, yield); 1172 } 1173 } 1174 1175 // Weak references 1176 { 1177 GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, 1178 false, gc_timer, gc_id); 1179 for (uint i = 0; i < _max_num_q; i++) { 1180 if (yield->should_return()) { 1181 return; 1182 } 1183 preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, 1184 keep_alive, complete_gc, yield); 1185 } 1186 } 1187 1188 // Final references 1189 { 1190 GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, 1191 false, gc_timer, gc_id); 1192 for (uint i = 0; i < _max_num_q; i++) { 1193 if (yield->should_return()) { 1194 return; 1195 } 1196 preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, 1197 keep_alive, complete_gc, yield); 1198 } 1199 } 1200 1201 // Phantom references 1202 { 1203 GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, 1204 false, gc_timer, gc_id); 1205 for (uint i = 0; i < _max_num_q; i++) { 1206 if (yield->should_return()) { 1207 return; 1208 } 1209 preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, 1210 keep_alive, complete_gc, yield); 1211 } 1212 1213 // Cleaner references. Included in timing for phantom references. We 1214 // expect Cleaner references to be temporary, and don't want to deal with 1215 // possible incompatibilities arising from making it more visible. 1216 for (uint i = 0; i < _max_num_q; i++) { 1217 if (yield->should_return()) { 1218 return; 1219 } 1220 preclean_discovered_reflist(_discoveredCleanerRefs[i], is_alive, 1221 keep_alive, complete_gc, yield); 1222 } 1223 } 1224 } | 170 _soft_ref_timestamp_clock = now; 171 java_lang_ref_SoftReference::set_clock(now); 172 } 173 // Else leave clock stalled at its old value until time progresses 174 // past clock value. 175 } 176 177 size_t ReferenceProcessor::total_count(DiscoveredList lists[]) { 178 size_t total = 0; 179 for (uint i = 0; i < _max_num_q; ++i) { 180 total += lists[i].length(); 181 } 182 return total; 183 } 184 185 ReferenceProcessorStats ReferenceProcessor::process_discovered_references( 186 BoolObjectClosure* is_alive, 187 OopClosure* keep_alive, 188 VoidClosure* complete_gc, 189 AbstractRefProcTaskExecutor* task_executor, 190 GCTimer* gc_timer) { 191 192 assert(!enqueuing_is_done(), "If here enqueuing should not be complete"); 193 // Stop treating discovered references specially. 194 disable_discovery(); 195 196 // If discovery was concurrent, someone could have modified 197 // the value of the static field in the j.l.r.SoftReference 198 // class that holds the soft reference timestamp clock using 199 // reflection or Unsafe between when discovery was enabled and 200 // now. Unconditionally update the static field in ReferenceProcessor 201 // here so that we use the new value during processing of the 202 // discovered soft refs. 203 204 _soft_ref_timestamp_clock = java_lang_ref_SoftReference::clock(); 205 206 bool trace_time = PrintGCDetails && PrintReferenceGC; 207 208 // Soft references 209 size_t soft_count = 0; 210 { 211 GCTraceTime tt("SoftReference", trace_time, false, gc_timer); 212 soft_count = 213 process_discovered_reflist(_discoveredSoftRefs, _current_soft_ref_policy, true, 214 is_alive, keep_alive, complete_gc, task_executor); 215 } 216 217 update_soft_ref_master_clock(); 218 219 // Weak references 220 size_t weak_count = 0; 221 { 222 GCTraceTime tt("WeakReference", trace_time, false, gc_timer); 223 weak_count = 224 process_discovered_reflist(_discoveredWeakRefs, NULL, true, 225 is_alive, keep_alive, complete_gc, task_executor); 226 } 227 228 // Final references 229 size_t final_count = 0; 230 { 231 GCTraceTime tt("FinalReference", trace_time, false, gc_timer); 232 final_count = 233 process_discovered_reflist(_discoveredFinalRefs, NULL, false, 234 is_alive, keep_alive, complete_gc, task_executor); 235 } 236 237 // Phantom references 238 size_t phantom_count = 0; 239 { 240 GCTraceTime tt("PhantomReference", trace_time, false, gc_timer); 241 phantom_count = 242 process_discovered_reflist(_discoveredPhantomRefs, NULL, false, 243 is_alive, keep_alive, complete_gc, task_executor); 244 245 } 246 247 // Cleaners 248 size_t cleaner_count = 0; 249 { 250 GCTraceTime tt("Cleaners", trace_time, false, gc_timer, gc_id); 251 cleaner_count = 252 process_discovered_reflist(_discoveredCleanerRefs, NULL, true, 253 is_alive, keep_alive, complete_gc, task_executor); 254 } 255 256 // Weak global JNI references. It would make more sense (semantically) to 257 // traverse these simultaneously with the regular weak references above, but 258 // that is not how the JDK1.2 specification is. See #4126360. Native code can 259 // thus use JNI weak references to circumvent the phantom references and 260 // resurrect a "post-mortem" object. 261 size_t jni_weak_ref_count = 0; 262 { 263 GCTraceTime tt("JNI Weak Reference", trace_time, false, gc_timer); 264 if (task_executor != NULL) { 265 task_executor->set_single_threaded_mode(); 266 } 267 jni_weak_ref_count = 268 process_phaseJNI(is_alive, keep_alive, complete_gc); 269 } 270 271 return ReferenceProcessorStats(soft_count, weak_count, final_count, phantom_count, cleaner_count, jni_weak_ref_count); 272 } 273 274 #ifndef PRODUCT 275 // Calculate the number of jni handles. 276 uint ReferenceProcessor::count_jni_refs() { 277 class AlwaysAliveClosure: public BoolObjectClosure { 278 public: 279 virtual bool do_object_b(oop obj) { return true; } 280 }; 281 282 class CountHandleClosure: public OopClosure { 283 private: 1138 1139 if (TraceReferenceGC) { 1140 gclog_or_tty->print_cr("Discovered reference (" INTPTR_FORMAT ": %s)", 1141 p2i(obj), obj->klass()->internal_name()); 1142 } 1143 } 1144 assert(obj->is_oop(), "Discovered a bad reference"); 1145 verify_referent(obj); 1146 return true; 1147 } 1148 1149 // Preclean the discovered references by removing those 1150 // whose referents are alive, and by marking from those that 1151 // are not active. These lists can be handled here 1152 // in any order and, indeed, concurrently. 1153 void ReferenceProcessor::preclean_discovered_references( 1154 BoolObjectClosure* is_alive, 1155 OopClosure* keep_alive, 1156 VoidClosure* complete_gc, 1157 YieldClosure* yield, 1158 GCTimer* gc_timer) { 1159 1160 // Soft references 1161 { 1162 GCTraceTime tt("Preclean SoftReferences", PrintGCDetails && PrintReferenceGC, 1163 false, gc_timer); 1164 for (uint i = 0; i < _max_num_q; i++) { 1165 if (yield->should_return()) { 1166 return; 1167 } 1168 preclean_discovered_reflist(_discoveredSoftRefs[i], is_alive, 1169 keep_alive, complete_gc, yield); 1170 } 1171 } 1172 1173 // Weak references 1174 { 1175 GCTraceTime tt("Preclean WeakReferences", PrintGCDetails && PrintReferenceGC, 1176 false, gc_timer); 1177 for (uint i = 0; i < _max_num_q; i++) { 1178 if (yield->should_return()) { 1179 return; 1180 } 1181 preclean_discovered_reflist(_discoveredWeakRefs[i], is_alive, 1182 keep_alive, complete_gc, yield); 1183 } 1184 } 1185 1186 // Final references 1187 { 1188 GCTraceTime tt("Preclean FinalReferences", PrintGCDetails && PrintReferenceGC, 1189 false, gc_timer); 1190 for (uint i = 0; i < _max_num_q; i++) { 1191 if (yield->should_return()) { 1192 return; 1193 } 1194 preclean_discovered_reflist(_discoveredFinalRefs[i], is_alive, 1195 keep_alive, complete_gc, yield); 1196 } 1197 } 1198 1199 // Phantom references 1200 { 1201 GCTraceTime tt("Preclean PhantomReferences", PrintGCDetails && PrintReferenceGC, 1202 false, gc_timer); 1203 for (uint i = 0; i < _max_num_q; i++) { 1204 if (yield->should_return()) { 1205 return; 1206 } 1207 preclean_discovered_reflist(_discoveredPhantomRefs[i], is_alive, 1208 keep_alive, complete_gc, yield); 1209 } 1210 1211 // Cleaner references. Included in timing for phantom references. We 1212 // expect Cleaner references to be temporary, and don't want to deal with 1213 // possible incompatibilities arising from making it more visible. 1214 for (uint i = 0; i < _max_num_q; i++) { 1215 if (yield->should_return()) { 1216 return; 1217 } 1218 preclean_discovered_reflist(_discoveredCleanerRefs[i], is_alive, 1219 keep_alive, complete_gc, yield); 1220 } 1221 } 1222 } |