19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.inline.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "gc/shared/collectedHeap.hpp"
29 #include "gc/shared/collectedHeap.inline.hpp"
30 #include "gc/shared/gcTimer.hpp"
31 #include "gc/shared/gcTraceTime.inline.hpp"
32 #include "gc/shared/referencePolicy.hpp"
33 #include "gc/shared/referenceProcessor.inline.hpp"
34 #include "logging/log.hpp"
35 #include "memory/allocation.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "runtime/java.hpp"
39 #include "runtime/jniHandles.hpp"
40
41 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
42 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL;
43 jlong ReferenceProcessor::_soft_ref_timestamp_clock = 0;
44
45 void referenceProcessor_init() {
46 ReferenceProcessor::init_statics();
47 }
48
49 void ReferenceProcessor::init_statics() {
50 // We need a monotonically non-decreasing time in ms but
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();
228 {
229 RefProcPhaseTimesTracker tt(REF_WEAK, phase_times, this);
230 process_discovered_reflist(_discoveredWeakRefs, NULL, true,
231 is_alive, keep_alive, complete_gc, task_executor, phase_times);
232 }
233
234 // Final references
235 {
236 RefProcPhaseTimesTracker tt(REF_FINAL, phase_times, this);
237 process_discovered_reflist(_discoveredFinalRefs, NULL, false,
238 is_alive, keep_alive, complete_gc, task_executor, phase_times);
239 }
240
241 // Phantom references
242 {
243 RefProcPhaseTimesTracker tt(REF_PHANTOM, phase_times, this);
244 process_discovered_reflist(_discoveredPhantomRefs, NULL, true,
245 is_alive, keep_alive, complete_gc, task_executor, phase_times);
246 }
247
248 // Weak global JNI references. It would make more sense (semantically) to
249 // traverse these simultaneously with the regular weak references above, but
250 // that is not how the JDK1.2 specification is. See #4126360. Native code can
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 }
260
261 phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000);
262
263 log_develop_trace(gc, ref)("JNI Weak Reference count: " SIZE_FORMAT, count_jni_refs());
264
265 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 }
292
293 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor,
294 ReferenceProcessorPhaseTimes* phase_times) {
295 // Enqueue references that are not made active again, and
296 // clear the decks for the next collection (cycle).
297 enqueue_discovered_reflists(task_executor, phase_times);
298
299 // Stop treating discovered references specially.
300 disable_discovery();
301 }
302
303 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
304 // Given a list of refs linked through the "discovered" field
305 // (java.lang.ref.Reference.discovered), self-loop their "next" field
306 // thus distinguishing them from active References, then
307 // prepend them to the pending list.
308 //
309 // The Java threads will see the Reference objects linked together through
310 // the discovered field. Instead of trying to do the write barrier updates
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #include "precompiled.hpp"
26 #include "classfile/javaClasses.inline.hpp"
27 #include "classfile/systemDictionary.hpp"
28 #include "gc/shared/collectedHeap.hpp"
29 #include "gc/shared/collectedHeap.inline.hpp"
30 #include "gc/shared/gcTimer.hpp"
31 #include "gc/shared/gcTraceTime.inline.hpp"
32 #include "gc/shared/referencePolicy.hpp"
33 #include "gc/shared/referenceProcessor.inline.hpp"
34 #include "logging/log.hpp"
35 #include "memory/allocation.hpp"
36 #include "memory/resourceArea.hpp"
37 #include "oops/oop.inline.hpp"
38 #include "runtime/java.hpp"
39
40 ReferencePolicy* ReferenceProcessor::_always_clear_soft_ref_policy = NULL;
41 ReferencePolicy* ReferenceProcessor::_default_soft_ref_policy = NULL;
42 jlong ReferenceProcessor::_soft_ref_timestamp_clock = 0;
43
44 void referenceProcessor_init() {
45 ReferenceProcessor::init_statics();
46 }
47
48 void ReferenceProcessor::init_statics() {
49 // We need a monotonically non-decreasing time in ms but
50 // os::javaTimeMillis() does not guarantee monotonicity.
51 jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
52
53 // Initialize the soft ref timestamp clock.
54 _soft_ref_timestamp_clock = now;
55 // Also update the soft ref clock in j.l.r.SoftReference
56 java_lang_ref_SoftReference::set_clock(_soft_ref_timestamp_clock);
57
58 _always_clear_soft_ref_policy = new AlwaysClearPolicy();
227 {
228 RefProcPhaseTimesTracker tt(REF_WEAK, phase_times, this);
229 process_discovered_reflist(_discoveredWeakRefs, NULL, true,
230 is_alive, keep_alive, complete_gc, task_executor, phase_times);
231 }
232
233 // Final references
234 {
235 RefProcPhaseTimesTracker tt(REF_FINAL, phase_times, this);
236 process_discovered_reflist(_discoveredFinalRefs, NULL, false,
237 is_alive, keep_alive, complete_gc, task_executor, phase_times);
238 }
239
240 // Phantom references
241 {
242 RefProcPhaseTimesTracker tt(REF_PHANTOM, phase_times, this);
243 process_discovered_reflist(_discoveredPhantomRefs, NULL, true,
244 is_alive, keep_alive, complete_gc, task_executor, phase_times);
245 }
246
247 phase_times->set_total_time_ms((os::elapsedTime() - start_time) * 1000);
248
249 return stats;
250 }
251
252 void ReferenceProcessor::enqueue_discovered_references(AbstractRefProcTaskExecutor* task_executor,
253 ReferenceProcessorPhaseTimes* phase_times) {
254 // Enqueue references that are not made active again, and
255 // clear the decks for the next collection (cycle).
256 enqueue_discovered_reflists(task_executor, phase_times);
257
258 // Stop treating discovered references specially.
259 disable_discovery();
260 }
261
262 void ReferenceProcessor::enqueue_discovered_reflist(DiscoveredList& refs_list) {
263 // Given a list of refs linked through the "discovered" field
264 // (java.lang.ref.Reference.discovered), self-loop their "next" field
265 // thus distinguishing them from active References, then
266 // prepend them to the pending list.
267 //
268 // The Java threads will see the Reference objects linked together through
269 // the discovered field. Instead of trying to do the write barrier updates
|