/*
 * Copyright (c) 2012, 2023, 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 "classfile/javaClasses.inline.hpp"
#include "classfile/vmSymbols.hpp"
#include "jfr/jfr.hpp"
#include "jfr/dcmd/jfrDcmds.hpp"
#include "jfr/jni/jfrJavaSupport.hpp"
#include "jfr/recorder/jfrRecorder.hpp"
#include "jfr/recorder/service/jfrOptionSet.hpp"
#include "jfr/support/jfrThreadLocal.hpp"
#include "logging/log.hpp"
#include "logging/logConfiguration.hpp"
#include "logging/logMessage.hpp"
#include "memory/arena.hpp"
#include "memory/resourceArea.hpp"
#include "oops/objArrayOop.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/symbol.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/jniHandles.hpp"
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticFramework.hpp"
#include "utilities/globalDefinitions.hpp"


bool register_jfr_dcmds() {
  uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export, true, false));
  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export, true, false));
  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export, true, false));
  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export, true, false));
  // JFR.query Uncomment when developing new queries for the JFR.view command
  // DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrQueryFlightRecordingDCmd>(full_export, true, true));
  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrViewFlightRecordingDCmd>(full_export, true, false));
  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export, true, false));
  return true;
}

static bool is_disabled(outputStream* output) {
  if (Jfr::is_disabled()) {
    if (output != nullptr) {
      output->print_cr("Flight Recorder is disabled.\n");
    }
    return true;
  }
  return false;
}

static bool invalid_state(outputStream* out, TRAPS) {
  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
  if (is_disabled(out)) {
    return true;
  }
  if (!JfrJavaSupport::is_jdk_jfr_module_available()) {
    JfrJavaSupport::load_jdk_jfr_module(THREAD);
    if (HAS_PENDING_EXCEPTION) {
      // Log exception here, but let is_jdk_jfr_module_available(out, THREAD)
      // handle output to the user.
      ResourceMark rm(THREAD);
      oop throwable = PENDING_EXCEPTION;
      assert(throwable != nullptr, "invariant");
      oop msg = java_lang_Throwable::message(throwable);
      if (msg != nullptr) {
        char* text = java_lang_String::as_utf8_string(msg);
        if (text != nullptr) {
          log_debug(jfr, startup)("Flight Recorder can not be enabled. %s", text);
        }
      }
      CLEAR_PENDING_EXCEPTION;
    }
  }
  return !JfrJavaSupport::is_jdk_jfr_module_available(out, THREAD);
}

static void handle_pending_exception(outputStream* output, bool startup, oop throwable) {
  assert(throwable != nullptr, "invariant");

  oop msg = java_lang_Throwable::message(throwable);
  if (msg == nullptr) {
    return;
  }
  char* text = java_lang_String::as_utf8_string(msg);
  if (text != nullptr) {
    if (startup) {
      log_error(jfr,startup)("%s", text);
    } else {
      output->print_cr("%s", text);
    }
  }
}

static void print_message(outputStream* output, oop content, TRAPS) {
  objArrayOop lines = objArrayOop(content);
  assert(lines != nullptr, "invariant");
  assert(lines->is_array(), "must be array");
  const int length = lines->length();
  for (int i = 0; i < length; ++i) {
    const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
    if (text == nullptr) {
      // An oome has been thrown and is pending.
      break;
    }
    output->print_cr("%s", text);
  }
}

static void log(oop content, TRAPS) {
  LogMessage(jfr,startup) msg;
  objArrayOop lines = objArrayOop(content);
  assert(lines != nullptr, "invariant");
  assert(lines->is_array(), "must be array");
  const int length = lines->length();
  for (int i = 0; i < length; ++i) {
    const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
    if (text == nullptr) {
      // An oome has been thrown and is pending.
      break;
    }
    msg.info("%s", text);
  }
}

static void handle_dcmd_result(outputStream* output,
                               const oop result,
                               const DCmdSource source,
                               TRAPS) {
  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
  assert(output != nullptr, "invariant");
  ResourceMark rm(THREAD);
  const bool startup = DCmd_Source_Internal == source;
  if (HAS_PENDING_EXCEPTION) {
    handle_pending_exception(output, startup, PENDING_EXCEPTION);
    // Don't clear exception on startup, JVM should fail initialization.
    if (!startup) {
      CLEAR_PENDING_EXCEPTION;
    }
    return;
  }

  assert(!HAS_PENDING_EXCEPTION, "invariant");

  if (startup) {
    if (log_is_enabled(Warning, jfr, startup))  {
      // if warning is set, assume user hasn't configured log level
      // Log to Info and reset to Warning. This way user can disable
      // default output by setting -Xlog:jfr+startup=error/off
      LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(jfr, startup));
      log(result, THREAD);
      LogConfiguration::configure_stdout(LogLevel::Warning, true, LOG_TAGS(jfr, startup));
    } else {
      log(result, THREAD);
    }
  } else {
      // Print output for jcmd or MXBean
      print_message(output, result, THREAD);
  }
}

static oop construct_dcmd_instance(JfrJavaArguments* args, TRAPS) {
  assert(args != nullptr, "invariant");
  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
  assert(args->klass() != nullptr, "invariant");
  args->set_name("<init>");
  args->set_signature("()V");
  JfrJavaSupport::new_object(args, CHECK_NULL);
  return args->result()->get_oop();
}

JfrDCmd::JfrDCmd(outputStream* output, bool heap, int num_arguments) : DCmd(output, heap), _args(nullptr), _num_arguments(num_arguments), _delimiter('\0') {}

void JfrDCmd::invoke(JfrJavaArguments& method, TRAPS) const {
  JavaValue constructor_result(T_OBJECT);
  JfrJavaArguments constructor_args(&constructor_result);
  constructor_args.set_klass(javaClass(), CHECK);

  HandleMark hm(THREAD);
  JNIHandleMark jni_handle_management(THREAD);

  const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);

  Handle h_dcmd_instance(THREAD, dcmd);
  assert(h_dcmd_instance.not_null(), "invariant");

  method.set_receiver(h_dcmd_instance);
  JfrJavaSupport::call_virtual(&method, THREAD);
}

void JfrDCmd::parse(CmdLine* line, char delim, TRAPS) {
  _args = line->args_addr();
  _delimiter = delim;
  // Error checking done in execute.
  // Will not matter from DCmdFactory perspective
  // where parse and execute are called consecutively.
}

void JfrDCmd::execute(DCmdSource source, TRAPS) {
  if (invalid_state(output(), THREAD)) {
    return;
  }
  static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;C)[Ljava/lang/String;";
  JavaValue result(T_OBJECT);
  JfrJavaArguments execute(&result, javaClass(), "execute", signature, CHECK);
  jstring argument = JfrJavaSupport::new_string(_args, CHECK);
  jstring s = nullptr;
  if (source == DCmd_Source_Internal) {
    s = JfrJavaSupport::new_string("internal", CHECK);
  }
  if (source == DCmd_Source_MBean) {
    s = JfrJavaSupport::new_string("mbean", CHECK);
  }
  if (source == DCmd_Source_AttachAPI) {
    s = JfrJavaSupport::new_string("attach", CHECK);
  }
  execute.push_jobject(s);
  execute.push_jobject(argument);
  execute.push_int(_delimiter);
  invoke(execute, THREAD);
  handle_dcmd_result(output(), result.get_oop(), source, THREAD);
}

void JfrDCmd::print_help(const char* name) const {
  static const char signature[] = "()[Ljava/lang/String;";
  JavaThread* thread = JavaThread::current();
  JavaValue result(T_OBJECT);
  JfrJavaArguments printHelp(&result, javaClass(), "printHelp", signature, thread);
  invoke(printHelp, thread);
  handle_dcmd_result(output(), result.get_oop(), DCmd_Source_MBean, thread);
}

static void initialize_dummy_descriptors(GrowableArray<DCmdArgumentInfo*>* array) {
  assert(array != nullptr, "invariant");
  DCmdArgumentInfo * const dummy = new DCmdArgumentInfo(nullptr,
                                                        nullptr,
                                                        nullptr,
                                                        nullptr,
                                                        false,
                                                        true, // a DcmdFramework "option"
                                                        false);
  for (int i = 0; i < array->capacity(); ++i) {
    array->append(dummy);
  }
}

// Since the DcmdFramework does not support dynamically allocated strings,
// we keep them in a thread local arena. The arena is reset between invocations.
static THREAD_LOCAL Arena* dcmd_arena = nullptr;

static void prepare_dcmd_string_arena(JavaThread* jt) {
  dcmd_arena = JfrThreadLocal::dcmd_arena(jt);
  assert(dcmd_arena != nullptr, "invariant");
  dcmd_arena->destruct_contents(); // will grow on next allocation
}

static char* dcmd_arena_allocate(size_t size) {
  assert(dcmd_arena != nullptr, "invariant");
  return (char*)dcmd_arena->Amalloc(size);
}

static const char* get_as_dcmd_arena_string(oop string) {
  char* str = nullptr;
  const typeArrayOop value = java_lang_String::value(string);
  if (value != nullptr) {
    const size_t length = static_cast<size_t>(java_lang_String::utf8_length(string, value)) + 1;
    str = dcmd_arena_allocate(length);
    assert(str != nullptr, "invariant");
    java_lang_String::as_utf8_string(string, value, str, static_cast<int>(length));
  }
  return str;
}

static const char* read_string_field(oop argument, const char* field_name, TRAPS) {
  JavaValue result(T_OBJECT);
  JfrJavaArguments args(&result);
  args.set_klass(argument->klass());
  args.set_name(field_name);
  args.set_signature("Ljava/lang/String;");
  args.set_receiver(argument);
  JfrJavaSupport::get_field(&args, THREAD);
  const oop string_oop = result.get_oop();
  return string_oop != nullptr ? get_as_dcmd_arena_string(string_oop) : nullptr;
}

static bool read_boolean_field(oop argument, const char* field_name, TRAPS) {
  JavaValue result(T_BOOLEAN);
  JfrJavaArguments args(&result);
  args.set_klass(argument->klass());
  args.set_name(field_name);
  args.set_signature("Z");
  args.set_receiver(argument);
  JfrJavaSupport::get_field(&args, THREAD);
  return (result.get_jint() & 1) == 1;
}

static DCmdArgumentInfo* create_info(oop argument, TRAPS) {
  return new DCmdArgumentInfo(
    read_string_field(argument, "name", THREAD),
    read_string_field(argument, "description", THREAD),
    read_string_field(argument, "type", THREAD),
    read_string_field(argument, "defaultValue", THREAD),
    read_boolean_field(argument, "mandatory", THREAD),
    read_boolean_field(argument, "option", THREAD),
    read_boolean_field(argument, "allowMultiple", THREAD));
}

GrowableArray<DCmdArgumentInfo*>* JfrDCmd::argument_info_array() const {
  static const char signature[] = "()[Ljdk/jfr/internal/dcmd/Argument;";
  JavaThread* thread = JavaThread::current();
  GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>(_num_arguments);
  JavaValue result(T_OBJECT);
  JfrJavaArguments getArgumentInfos(&result, javaClass(), "getArgumentInfos", signature, thread);
  invoke(getArgumentInfos, thread);
  if (thread->has_pending_exception()) {
    // Most likely an OOME, but the DCmdFramework is not the best place to handle it.
    // We handle it locally by clearing the exception and returning an array with dummy descriptors.
    // This lets the MBean server initialization routine complete successfully,
    // but this particular command will have no argument descriptors exposed.
    // Hence we postpone, or delegate, handling of OOME's to code that is better suited.
    log_debug(jfr, system)("Exception in DCmd getArgumentInfos");
    thread->clear_pending_exception();
    initialize_dummy_descriptors(array);
    assert(array->length() == _num_arguments, "invariant");
    return array;
  }
  objArrayOop arguments = objArrayOop(result.get_oop());
  assert(arguments != nullptr, "invariant");
  assert(arguments->is_array(), "must be array");
  const int num_arguments = arguments->length();
  assert(num_arguments == _num_arguments, "invariant");
  prepare_dcmd_string_arena(thread);
  for (int i = 0; i < num_arguments; ++i) {
    DCmdArgumentInfo* const dai = create_info(arguments->obj_at(i), thread);
    assert(dai != nullptr, "invariant");
    array->append(dai);
  }
  return array;
}

GrowableArray<const char*>* JfrDCmd::argument_name_array() const {
  GrowableArray<DCmdArgumentInfo*>* argument_infos = argument_info_array();
  GrowableArray<const char*>* array = new GrowableArray<const char*>(argument_infos->length());
  for (int i = 0; i < argument_infos->length(); i++) {
    array->append(argument_infos->at(i)->name());
  }
  return array;
}

JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* output,
                                                               bool heap) : DCmdWithParser(output, heap),
  _repository_path("repositorypath", "Path to repository,.e.g \\\"My Repository\\\"", "STRING", false, nullptr),
  _dump_path("dumppath", "Path to dump, e.g. \\\"My Dump path\\\"", "STRING", false, nullptr),
  _stack_depth("stackdepth", "Stack depth", "JULONG", false, "64"),
  _global_buffer_count("globalbuffercount", "Number of global buffers,", "JULONG", false, "20"),
  _global_buffer_size("globalbuffersize", "Size of a global buffers,", "MEMORY SIZE", false, "512k"),
  _thread_buffer_size("thread_buffer_size", "Size of a thread buffer", "MEMORY SIZE", false, "8k"),
  _memory_size("memorysize", "Overall memory size, ", "MEMORY SIZE", false, "10m"),
  _max_chunk_size("maxchunksize", "Size of an individual disk chunk", "MEMORY SIZE", false, "12m"),
  _sample_threads("samplethreads", "Activate thread sampling", "BOOLEAN", false, "true"),
  _preserve_repository("preserve-repository", "Preserve the disk repository after JVM exit", "BOOLEAN", false, "false"),
  _verbose(true) {
  _dcmdparser.add_dcmd_option(&_repository_path);
  _dcmdparser.add_dcmd_option(&_dump_path);
  _dcmdparser.add_dcmd_option(&_stack_depth);
  _dcmdparser.add_dcmd_option(&_global_buffer_count);
  _dcmdparser.add_dcmd_option(&_global_buffer_size);
  _dcmdparser.add_dcmd_option(&_thread_buffer_size);
  _dcmdparser.add_dcmd_option(&_memory_size);
  _dcmdparser.add_dcmd_option(&_max_chunk_size);
  _dcmdparser.add_dcmd_option(&_sample_threads);
  _dcmdparser.add_dcmd_option(&_preserve_repository);
};

void JfrConfigureFlightRecorderDCmd::print_help(const char* name) const {
  outputStream* out = output();
              // 0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890
  out->print_cr("Options:");
  out->print_cr("");
  out->print_cr("  globalbuffercount   (Optional) Number of global buffers. This option is a legacy");
  out->print_cr("                      option: change the memorysize parameter to alter the number of");
  out->print_cr("                      global buffers. This value cannot be changed once JFR has been");
  out->print_cr("                      initialized. (STRING, default determined by the value for");
  out->print_cr("                      memorysize)");
  out->print_cr("");
  out->print_cr("  globalbuffersize    (Optional) Size of the global buffers, in bytes. This option is a");
  out->print_cr("                      legacy option: change the memorysize parameter to alter the size");
  out->print_cr("                      of the global buffers. This value cannot be changed once JFR has");
  out->print_cr("                      been initialized. (STRING, default determined by the value for");
  out->print_cr("                      memorysize)");
  out->print_cr("");
  out->print_cr("  maxchunksize        (Optional) Maximum size of an individual data chunk in bytes if");
  out->print_cr("                      one of the following suffixes is not used: 'm' or 'M' for");
  out->print_cr("                      megabytes OR 'g' or 'G' for gigabytes. This value cannot be");
  out->print_cr("                      changed once JFR has been initialized. (STRING, 12M)");
  out->print_cr("");
  out->print_cr("  memorysize          (Optional) Overall memory size, in bytes if one of the following");
  out->print_cr("                      suffixes is not used: 'm' or 'M' for megabytes OR 'g' or 'G' for");
  out->print_cr("                      gigabytes. This value cannot be changed once JFR has been");
  out->print_cr("                      initialized. (STRING, 10M)");
  out->print_cr("");
  out->print_cr("  repositorypath      (Optional) Path to the location where recordings are stored until");
  out->print_cr("                      they are written to a permanent file. (STRING, The default");
  out->print_cr("                      location is the temporary directory for the operating system. On");
  out->print_cr("                      Linux operating systems, the temporary directory is /tmp. On");
  out->print_cr("                      Windows, the temporary directory is specified by the TMP");
  out->print_cr("                      environment variable)");
  out->print_cr("");
  out->print_cr("  dumppath            (Optional) Path to the location where a recording file is written");
  out->print_cr("                      in case the VM runs into a critical error, such as a system");
  out->print_cr("                      crash. (STRING, The default location is the current directory)");
  out->print_cr("");
  out->print_cr("  stackdepth          (Optional) Stack depth for stack traces. Setting this value");
  out->print_cr("                      greater than the default of 64 may cause a performance");
  out->print_cr("                      degradation. This value cannot be changed once JFR has been");
  out->print_cr("                      initialized. (LONG, 64)");
  out->print_cr("");
  out->print_cr("  thread_buffer_size  (Optional) Local buffer size for each thread in bytes if one of");
  out->print_cr("                      the following suffixes is not used: 'k' or 'K' for kilobytes or");
  out->print_cr("                      'm' or 'M' for megabytes. Overriding this parameter could reduce");
  out->print_cr("                      performance and is not recommended. This value cannot be changed");
  out->print_cr("                      once JFR has been initialized. (STRING, 8k)");
  out->print_cr("");
  out->print_cr("  preserve-repository (Optional) Preserve files stored in the disk repository after the");
  out->print_cr("                      Java Virtual Machine has exited. (BOOLEAN, false)");
  out->print_cr("");
  out->print_cr("Options must be specified using the <key> or <key>=<value> syntax.");
  out->print_cr("");
  out->print_cr("Example usage:");
  out->print_cr("");
  out->print_cr(" $ jcmd <pid> JFR.configure");
  out->print_cr(" $ jcmd <pid> JFR.configure repositorypath=/temporary");
  out->print_cr(" $ jcmd <pid> JFR.configure stackdepth=256");
  out->print_cr(" $ jcmd <pid> JFR.configure memorysize=100M");
  out->print_cr("");
}

void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
  DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));

  if (invalid_state(output(), THREAD)) {
    return;
  }

  HandleMark hm(THREAD);
  JNIHandleMark jni_handle_management(THREAD);

  JavaValue result(T_OBJECT);
  JfrJavaArguments constructor_args(&result);
  constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdConfigure", CHECK);
  const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
  Handle h_dcmd_instance(THREAD, dcmd);
  assert(h_dcmd_instance.not_null(), "invariant");

  jstring repository_path = nullptr;
  if (_repository_path.is_set() && _repository_path.value() != nullptr) {
    repository_path = JfrJavaSupport::new_string(_repository_path.value(), CHECK);
  }

  jstring dump_path = nullptr;
  if (_dump_path.is_set() && _dump_path.value() != nullptr) {
    dump_path = JfrJavaSupport::new_string(_dump_path.value(), CHECK);
  }

  jobject stack_depth = nullptr;
  jobject global_buffer_count = nullptr;
  jobject global_buffer_size = nullptr;
  jobject thread_buffer_size = nullptr;
  jobject max_chunk_size = nullptr;
  jobject memory_size = nullptr;
  jobject preserve_repository = nullptr;

  if (!JfrRecorder::is_created()) {
    if (_stack_depth.is_set()) {
      stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK);
    }
    if (_global_buffer_count.is_set()) {
      global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK);
    }
    if (_global_buffer_size.is_set()) {
      global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value()._size, CHECK);
    }
    if (_thread_buffer_size.is_set()) {
      thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value()._size, CHECK);
    }
    if (_max_chunk_size.is_set()) {
      max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value()._size, CHECK);
    }
    if (_memory_size.is_set()) {
      memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value()._size, CHECK);
    }
    if (_sample_threads.is_set()) {
      bool startup = DCmd_Source_Internal == source;
      if (startup) {
        log_warning(jfr,startup)("%s", "Option samplethreads is deprecated. Use -XX:StartFlightRecording:method-profiling=<off|normal|high|max>");
      } else {
        output()->print_cr("%s", "Option samplethreads is deprecated. Use JFR.start method-profiling=<off|normal|high|max>");
        output()->print_cr("");
      }
    }
  }
  if (_preserve_repository.is_set()) {
    preserve_repository = JfrJavaSupport::new_java_lang_Boolean(_preserve_repository.value(), CHECK);
  }

  static const char klass[] = "jdk/jfr/internal/dcmd/DCmdConfigure";
  static const char method[] = "execute";
  static const char signature[] = "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;"
    "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
    "Ljava/lang/Long;Ljava/lang/Boolean;)[Ljava/lang/String;";

  JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
  execute_args.set_receiver(h_dcmd_instance);

  // params
  execute_args.push_int(_verbose ? 1 : 0);
  execute_args.push_jobject(repository_path);
  execute_args.push_jobject(dump_path);
  execute_args.push_jobject(stack_depth);
  execute_args.push_jobject(global_buffer_count);
  execute_args.push_jobject(global_buffer_size);
  execute_args.push_jobject(thread_buffer_size);
  execute_args.push_jobject(memory_size);
  execute_args.push_jobject(max_chunk_size);
  execute_args.push_jobject(preserve_repository);

  JfrJavaSupport::call_virtual(&execute_args, THREAD);
  handle_dcmd_result(output(), result.get_oop(), source, THREAD);
}
