src/share/vm/jfr/leakprofiler/leakProfiler.cpp

changeset 9885
8e875c964f41
parent 9858
b985cbb00e68
     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 -}

mercurial