1.1 --- a/src/share/vm/jfr/leakprofiler/leakProfiler.cpp Fri Sep 27 13:23:32 2019 +0800 1.2 +++ b/src/share/vm/jfr/leakprofiler/leakProfiler.cpp Wed Oct 09 16:11:58 2019 +0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -23,68 +23,80 @@ 1.11 */ 1.12 1.13 #include "precompiled.hpp" 1.14 -#include "jfr/leakprofiler/emitEventOperation.hpp" 1.15 #include "jfr/leakprofiler/leakProfiler.hpp" 1.16 #include "jfr/leakprofiler/startOperation.hpp" 1.17 #include "jfr/leakprofiler/stopOperation.hpp" 1.18 +#include "jfr/leakprofiler/checkpoint/eventEmitter.hpp" 1.19 #include "jfr/leakprofiler/sampling/objectSampler.hpp" 1.20 #include "jfr/recorder/service/jfrOptionSet.hpp" 1.21 #include "memory/iterator.hpp" 1.22 -#include "oops/oop.hpp" 1.23 -#include "runtime/atomic.hpp" 1.24 -#include "runtime/orderAccess.hpp" 1.25 #include "runtime/thread.inline.hpp" 1.26 #include "runtime/vmThread.hpp" 1.27 -#include "utilities/ostream.hpp" 1.28 1.29 -// Only to be updated during safepoint 1.30 -ObjectSampler* LeakProfiler::_object_sampler = NULL; 1.31 +bool LeakProfiler::is_running() { 1.32 + return ObjectSampler::is_created(); 1.33 +} 1.34 1.35 -static volatile jbyte suspended = 0; 1.36 -bool LeakProfiler::start(jint sample_count) { 1.37 - if (_object_sampler != NULL) { 1.38 - // already started 1.39 +bool LeakProfiler::start(int sample_count) { 1.40 + if (is_running()) { 1.41 return true; 1.42 } 1.43 + 1.44 // Allows user to disable leak profiler on command line by setting queue size to zero. 1.45 - if (sample_count > 0) { 1.46 - StartOperation op(sample_count); 1.47 - VMThread::execute(&op); 1.48 - return _object_sampler != NULL; 1.49 + if (sample_count == 0) { 1.50 + return false; 1.51 } 1.52 - return false; 1.53 + 1.54 + assert(!is_running(), "invariant"); 1.55 + assert(sample_count > 0, "invariant"); 1.56 + 1.57 + // schedule the safepoint operation for installing the object sampler 1.58 + StartOperation op(sample_count); 1.59 + VMThread::execute(&op); 1.60 + 1.61 + if (!is_running()) { 1.62 + if (LogJFR && Verbose) tty->print_cr("Object sampling could not be started because the sampler could not be allocated"); 1.63 + return false; 1.64 + } 1.65 + assert(is_running(), "invariant"); 1.66 + if (LogJFR && Verbose) tty->print_cr("Object sampling started"); 1.67 + return true; 1.68 } 1.69 1.70 bool LeakProfiler::stop() { 1.71 - if (_object_sampler == NULL) { 1.72 - // already stopped/not started 1.73 - return true; 1.74 + if (!is_running()) { 1.75 + return false; 1.76 } 1.77 + 1.78 + // schedule the safepoint operation for uninstalling and destroying the object sampler 1.79 StopOperation op; 1.80 VMThread::execute(&op); 1.81 - return _object_sampler == NULL; 1.82 + 1.83 + assert(!is_running(), "invariant"); 1.84 + if (LogJFR && Verbose) tty->print_cr("Object sampling stopped"); 1.85 + return true; 1.86 } 1.87 1.88 -void LeakProfiler::emit_events(jlong cutoff_ticks, bool emit_all) { 1.89 +void LeakProfiler::emit_events(int64_t cutoff_ticks, bool emit_all) { 1.90 if (!is_running()) { 1.91 return; 1.92 } 1.93 - EmitEventOperation op(cutoff_ticks, emit_all); 1.94 - VMThread::execute(&op); 1.95 + // exclusive access to object sampler instance 1.96 + ObjectSampler* const sampler = ObjectSampler::acquire(); 1.97 + assert(sampler != NULL, "invariant"); 1.98 + EventEmitter::emit(sampler, cutoff_ticks, emit_all); 1.99 + ObjectSampler::release(); 1.100 } 1.101 1.102 void LeakProfiler::oops_do(BoolObjectClosure* is_alive, OopClosure* f) { 1.103 assert(SafepointSynchronize::is_at_safepoint(), 1.104 "Leak Profiler::oops_do(...) may only be called during safepoint"); 1.105 - 1.106 - if (_object_sampler != NULL) { 1.107 - _object_sampler->oops_do(is_alive, f); 1.108 + if (is_running()) { 1.109 + ObjectSampler::oops_do(is_alive, f); 1.110 } 1.111 } 1.112 1.113 -void LeakProfiler::sample(HeapWord* object, 1.114 - size_t size, 1.115 - JavaThread* thread) { 1.116 +void LeakProfiler::sample(HeapWord* object, size_t size, JavaThread* thread) { 1.117 assert(is_running(), "invariant"); 1.118 assert(thread != NULL, "invariant"); 1.119 assert(thread->thread_state() == _thread_in_vm, "invariant"); 1.120 @@ -94,39 +106,5 @@ 1.121 return; 1.122 } 1.123 1.124 - _object_sampler->add(object, size, thread); 1.125 + ObjectSampler::sample(object, size, thread); 1.126 } 1.127 - 1.128 -ObjectSampler* LeakProfiler::object_sampler() { 1.129 - assert(is_suspended() || SafepointSynchronize::is_at_safepoint(), 1.130 - "Leak Profiler::object_sampler() may only be called during safepoint"); 1.131 - return _object_sampler; 1.132 -} 1.133 - 1.134 -void LeakProfiler::set_object_sampler(ObjectSampler* object_sampler) { 1.135 - assert(SafepointSynchronize::is_at_safepoint(), 1.136 - "Leak Profiler::set_object_sampler() may only be called during safepoint"); 1.137 - _object_sampler = object_sampler; 1.138 -} 1.139 - 1.140 -bool LeakProfiler::is_running() { 1.141 - return _object_sampler != NULL && !suspended; 1.142 -} 1.143 - 1.144 -bool LeakProfiler::is_suspended() { 1.145 - return _object_sampler != NULL && suspended; 1.146 -} 1.147 - 1.148 -void LeakProfiler::resume() { 1.149 - assert(is_suspended(), "invariant"); 1.150 - OrderAccess::storestore(); 1.151 - Atomic::store((jbyte)0, &suspended); 1.152 - assert(is_running(), "invariant"); 1.153 -} 1.154 - 1.155 -void LeakProfiler::suspend() { 1.156 - assert(SafepointSynchronize::is_at_safepoint(), "invariant"); 1.157 - assert(_object_sampler != NULL, "invariant"); 1.158 - assert(!is_suspended(), "invariant"); 1.159 - suspended = (jbyte)1; // safepoint visible 1.160 -}