src/hotspot/share/services/dtraceAttacher.cpp
author chegar
Thu, 17 Oct 2019 20:54:25 +0100
branchdatagramsocketimpl-branch
changeset 58679 9c3209ff7550
parent 58678 9cf78a70fa4f
parent 58226 408c445d04e8
permissions -rw-r--r--
datagramsocketimpl-branch: merge with default

/*
 * Copyright (c) 2006, 2019, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "code/codeCache.hpp"
#include "memory/resourceArea.hpp"
#include "runtime/deoptimization.hpp"
#include "runtime/flags/jvmFlag.hpp"
#include "runtime/vmThread.hpp"
#include "runtime/vmOperations.hpp"
#include "services/dtraceAttacher.hpp"

#ifdef SOLARIS

static void set_bool_flag(const char* name, bool value) {
  JVMFlag* flag = JVMFlag::find_flag(name);
  JVMFlag::boolAtPut(flag, &value, JVMFlag::ATTACH_ON_DEMAND);
}

// Enable only the "fine grained" flags. Do *not* touch
// the overall "ExtendedDTraceProbes" flag.
void DTrace::enable_dprobes(int probes) {
  bool changed = false;
  if (!DTraceAllocProbes && (probes & DTRACE_ALLOC_PROBES)) {
    set_bool_flag("DTraceAllocProbes", true);
    changed = true;
  }
  if (!DTraceMethodProbes && (probes & DTRACE_METHOD_PROBES)) {
    set_bool_flag("DTraceMethodProbes", true);
    changed = true;
  }
  if (!DTraceMonitorProbes && (probes & DTRACE_MONITOR_PROBES)) {
    set_bool_flag("DTraceMonitorProbes", true);
    changed = true;
  }

  if (changed) {
    // one or more flags changed, need to deoptimize
    CodeCache::mark_all_nmethods_for_deoptimization();
    Deoptimization::deoptimize_all_marked();
  }
}

// Disable only the "fine grained" flags. Do *not* touch
// the overall "ExtendedDTraceProbes" flag.
void DTrace::disable_dprobes(int probes) {
  bool changed = false;
  if (DTraceAllocProbes && (probes & DTRACE_ALLOC_PROBES)) {
    set_bool_flag("DTraceAllocProbes", false);
    changed = true;
  }
  if (DTraceMethodProbes && (probes & DTRACE_METHOD_PROBES)) {
    set_bool_flag("DTraceMethodProbes", false);
    changed = true;
  }
  if (DTraceMonitorProbes && (probes & DTRACE_MONITOR_PROBES)) {
    set_bool_flag("DTraceMonitorProbes", false);
    changed = true;
  }
  if (changed) {
    // one or more flags changed, need to deoptimize
    CodeCache::mark_all_nmethods_for_deoptimization();
    Deoptimization::deoptimize_all_marked();
  }
}

// Do clean-up on "all door clients detached" event.
void DTrace::detach_all_clients() {
  /*
   * We restore the state of the fine grained flags
   * to be consistent with overall ExtendedDTraceProbes.
   * This way, we will honour command line setting or the
   * last explicit modification of ExtendedDTraceProbes by
   * a call to set_extended_dprobes.
   */
  if (ExtendedDTraceProbes) {
    enable_dprobes(DTRACE_ALL_PROBES);
  } else {
    disable_dprobes(DTRACE_ALL_PROBES);
  }
}

void DTrace::set_extended_dprobes(bool flag) {
  // explicit setting of ExtendedDTraceProbes flag
  set_bool_flag("ExtendedDTraceProbes", flag);

  // make sure that the fine grained flags reflect the change.
  if (flag) {
    enable_dprobes(DTRACE_ALL_PROBES);
  } else {
    /*
     * FIXME: Revisit this: currently all-client-detach detection
     * does not work and hence disabled. The following scheme does
     * not work. So, we have to disable fine-grained flags here.
     *
     * disable_dprobes call has to be delayed till next "detach all "event.
     * This is to be  done so that concurrent DTrace clients that may
     * have enabled one or more fine grained dprobes and may be running
     * still. On "detach all" clients event, we would sync ExtendedDTraceProbes
     * with  fine grained flags which would take care of disabling fine grained flags.
     */
    disable_dprobes(DTRACE_ALL_PROBES);
  }
}

void DTrace::set_monitor_dprobes(bool flag) {
  // explicit setting of DTraceMonitorProbes flag
  set_bool_flag("DTraceMonitorProbes", flag);
}

#endif /* SOLARIS */