34 #include "logging/log.hpp" |
34 #include "logging/log.hpp" |
35 #include "memory/allocation.hpp" |
35 #include "memory/allocation.hpp" |
36 #include "memory/resourceArea.hpp" |
36 #include "memory/resourceArea.hpp" |
37 #include "oops/oop.inline.hpp" |
37 #include "oops/oop.inline.hpp" |
38 #include "runtime/java.hpp" |
38 #include "runtime/java.hpp" |
39 #include "runtime/jniHandles.hpp" |
|
40 |
39 |
41 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL; |
40 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL; |
42 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL; |
41 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL; |
43 jlong ReferenceProcessor::_soft_ref_timestamp_clock = 0; |
42 jlong ReferenceProcessor::_soft_ref_timestamp_clock = 0; |
44 |
43 |
243 RefProcPhaseTimesTracker tt(REF_PHANTOM, phase_times, this); |
242 RefProcPhaseTimesTracker tt(REF_PHANTOM, phase_times, this); |
244 process_discovered_reflist(_discoveredPhantomRefs, NULL, true, |
243 process_discovered_reflist(_discoveredPhantomRefs, NULL, true, |
245 is_alive, keep_alive, complete_gc, task_executor, phase_times); |
244 is_alive, keep_alive, complete_gc, task_executor, phase_times); |
246 } |
245 } |
247 |
246 |
248 // Weak global JNI references. It would make more sense (semantically) to |
247 if (task_executor != NULL) { |
249 // traverse these simultaneously with the regular weak references above, but |
248 // Record the work done by the parallel workers. |
250 // that is not how the JDK1.2 specification is. See #4126360. Native code can |
249 task_executor->set_single_threaded_mode(); |
251 // thus use JNI weak references to circumvent the phantom references and |
|
252 // resurrect a "post-mortem" object. |
|
253 { |
|
254 GCTraceTime(Debug, gc, ref) tt("JNI Weak Reference", phase_times->gc_timer()); |
|
255 if (task_executor != NULL) { |
|
256 task_executor->set_single_threaded_mode(); |
|
257 } |
|
258 process_phaseJNI(is_alive, keep_alive, complete_gc); |
|
259 } |
250 } |
260 |
251 |
261 phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000); |
252 phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000); |
262 |
253 |
263 log_develop_trace(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs()); |
|
264 |
|
265 return stats; |
254 return stats; |
266 } |
|
267 |
|
268 #ifndef PRODUCT |
|
269 // Calculate the number of jni handles. |
|
270 size_t ReferenceProcessor::count_jni_refs() { |
|
271 class CountHandleClosure: public OopClosure { |
|
272 private: |
|
273 size_t _count; |
|
274 public: |
|
275 CountHandleClosure(): _count(0) {} |
|
276 void do_oop(oop* unused) { _count++; } |
|
277 void do_oop(narrowOop* unused) { ShouldNotReachHere(); } |
|
278 size_t count() { return _count; } |
|
279 }; |
|
280 CountHandleClosure global_handle_count; |
|
281 JNIHandles::weak_oops_do(&global_handle_count); |
|
282 return global_handle_count.count(); |
|
283 } |
|
284 #endif |
|
285 |
|
286 void ReferenceProcessor::process_phaseJNI(BoolObjectClosure* is_alive, |
|
287 OopClosure* keep_alive, |
|
288 VoidClosure* complete_gc) { |
|
289 JNIHandles::weak_oops_do(is_alive, keep_alive); |
|
290 complete_gc->do_void(); |
|
291 } |
255 } |
292 |
256 |
293 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor, |
257 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor, |
294 ReferenceProcessorPhaseTimes* phase_times) { |
258 ReferenceProcessorPhaseTimes* phase_times) { |
295 // Enqueue references that are not made active again, and |
259 // Enqueue references that are not made active again, and |