src/hotspot/share/jfr/dcmd/jfrDcmds.cpp
changeset 50113 caf115bb98ad
child 50195 ec881a19d294
equal deleted inserted replaced
50112:7a2a740815b7 50113:caf115bb98ad
       
     1 /*
       
     2  * Copyright (c) 2012, 2018, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    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.hpp"
       
    27 #include "classfile/vmSymbols.hpp"
       
    28 #include "jfr/jfr.hpp"
       
    29 #include "jfr/dcmd/jfrDcmds.hpp"
       
    30 #include "jfr/jni/jfrJavaSupport.hpp"
       
    31 #include "jfr/recorder/jfrRecorder.hpp"
       
    32 #include "jfr/recorder/service/jfrOptionSet.hpp"
       
    33 #include "memory/resourceArea.hpp"
       
    34 #include "oops/oop.inline.hpp"
       
    35 #include "oops/symbol.hpp"
       
    36 #include "runtime/handles.inline.hpp"
       
    37 #include "services/diagnosticArgument.hpp"
       
    38 #include "services/diagnosticFramework.hpp"
       
    39 #include "utilities/globalDefinitions.hpp"
       
    40 
       
    41 #ifdef _WINDOWS
       
    42 #define JFR_FILENAME_EXAMPLE "C:\\Users\\user\\My Recording.jfr"
       
    43 #endif
       
    44 
       
    45 #ifdef __APPLE__
       
    46 #define JFR_FILENAME_EXAMPLE  "/Users/user/My Recording.jfr"
       
    47 #endif
       
    48 
       
    49 #ifndef JFR_FILENAME_EXAMPLE
       
    50 #define JFR_FILENAME_EXAMPLE "/home/user/My Recording.jfr"
       
    51 #endif
       
    52 
       
    53 // JNIHandle management
       
    54 
       
    55 // ------------------------------------------------------------------
       
    56 // push_jni_handle_block
       
    57 //
       
    58 // Push on a new block of JNI handles.
       
    59 static void push_jni_handle_block(Thread* const thread) {
       
    60   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread));
       
    61 
       
    62   // Allocate a new block for JNI handles.
       
    63   // Inlined code from jni_PushLocalFrame()
       
    64   JNIHandleBlock* prev_handles = thread->active_handles();
       
    65   JNIHandleBlock* entry_handles = JNIHandleBlock::allocate_block(thread);
       
    66   assert(entry_handles != NULL && prev_handles != NULL, "should not be NULL");
       
    67   entry_handles->set_pop_frame_link(prev_handles);  // make sure prev handles get gc'd.
       
    68   thread->set_active_handles(entry_handles);
       
    69 }
       
    70 
       
    71 // ------------------------------------------------------------------
       
    72 // pop_jni_handle_block
       
    73 //
       
    74 // Pop off the current block of JNI handles.
       
    75 static void pop_jni_handle_block(Thread* const thread) {
       
    76   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread));
       
    77 
       
    78   // Release our JNI handle block
       
    79   JNIHandleBlock* entry_handles = thread->active_handles();
       
    80   JNIHandleBlock* prev_handles = entry_handles->pop_frame_link();
       
    81   // restore
       
    82   thread->set_active_handles(prev_handles);
       
    83   entry_handles->set_pop_frame_link(NULL);
       
    84   JNIHandleBlock::release_block(entry_handles, thread); // may block
       
    85 }
       
    86 
       
    87 class JNIHandleBlockManager : public StackObj {
       
    88  private:
       
    89   Thread* const _thread;
       
    90  public:
       
    91   JNIHandleBlockManager(Thread* thread) : _thread(thread) {
       
    92     push_jni_handle_block(_thread);
       
    93   }
       
    94 
       
    95   ~JNIHandleBlockManager() {
       
    96     pop_jni_handle_block(_thread);
       
    97   }
       
    98 };
       
    99 
       
   100 static bool is_module_available(outputStream* output, TRAPS) {
       
   101   return JfrJavaSupport::is_jdk_jfr_module_available(output, THREAD);
       
   102 }
       
   103 
       
   104 static bool is_disabled(outputStream* output) {
       
   105   if (Jfr::is_disabled()) {
       
   106     if (output != NULL) {
       
   107       output->print_cr("Flight Recorder is disabled.\n");
       
   108     }
       
   109     return true;
       
   110   }
       
   111   return false;
       
   112 }
       
   113 
       
   114 static bool is_recorder_instance_created(outputStream* output) {
       
   115   if (!JfrRecorder::is_created()) {
       
   116     if (output != NULL) {
       
   117       output->print_cr("No available recordings.\n");
       
   118       output->print_cr("Use JFR.start to start a recording.\n");
       
   119     }
       
   120     return false;
       
   121   }
       
   122   return true;
       
   123 }
       
   124 
       
   125 static bool invalid_state(outputStream* out, TRAPS) {
       
   126   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   127   return is_disabled(out) || !is_module_available(out, THREAD);
       
   128 }
       
   129 
       
   130 static void print_pending_exception(outputStream* output, oop throwable) {
       
   131   assert(throwable != NULL, "invariant");
       
   132 
       
   133   oop msg = java_lang_Throwable::message(throwable);
       
   134 
       
   135   if (msg != NULL) {
       
   136     char* text = java_lang_String::as_utf8_string(msg);
       
   137     output->print_raw_cr(text);
       
   138   }
       
   139 }
       
   140 
       
   141 static void print_message(outputStream* output, const char* message) {
       
   142   if (message != NULL) {
       
   143     output->print_raw(message);
       
   144   }
       
   145 }
       
   146 
       
   147 static void handle_dcmd_result(outputStream* output,
       
   148                                const oop result,
       
   149                                const DCmdSource source,
       
   150                                TRAPS) {
       
   151   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   152   assert(output != NULL, "invariant");
       
   153   if (HAS_PENDING_EXCEPTION) {
       
   154     print_pending_exception(output, PENDING_EXCEPTION);
       
   155     // Don't clear excption on startup, JVM should fail initialization.
       
   156     if (DCmd_Source_Internal != source) {
       
   157       CLEAR_PENDING_EXCEPTION;
       
   158     }
       
   159     return;
       
   160   }
       
   161 
       
   162   assert(!HAS_PENDING_EXCEPTION, "invariant");
       
   163 
       
   164   if (result != NULL) {
       
   165     const char* result_chars = java_lang_String::as_utf8_string(result);
       
   166     print_message(output, result_chars);
       
   167   }
       
   168 }
       
   169 
       
   170 static oop construct_dcmd_instance(JfrJavaArguments* args, TRAPS) {
       
   171   assert(args != NULL, "invariant");
       
   172   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   173   assert(args->klass() != NULL, "invariant");
       
   174   args->set_name("<init>", CHECK_NULL);
       
   175   args->set_signature("()V", CHECK_NULL);
       
   176   JfrJavaSupport::new_object(args, CHECK_NULL);
       
   177   return (oop)args->result()->get_jobject();
       
   178 }
       
   179 
       
   180 JfrDumpFlightRecordingDCmd::JfrDumpFlightRecordingDCmd(outputStream* output,
       
   181                                                        bool heap) : DCmdWithParser(output, heap),
       
   182   _name("name", "Recording name, e.g. \\\"My Recording\\\"", "STRING", true, NULL),
       
   183   _filename("filename", "Copy recording data to file, i.e \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", true),
       
   184   _path_to_gc_roots("path-to-gc-roots", "Collect path to GC roots", "BOOLEAN", false, "false") {
       
   185   _dcmdparser.add_dcmd_option(&_name);
       
   186   _dcmdparser.add_dcmd_option(&_filename);
       
   187   _dcmdparser.add_dcmd_option(&_path_to_gc_roots);
       
   188 };
       
   189 
       
   190 int JfrDumpFlightRecordingDCmd::num_arguments() {
       
   191   ResourceMark rm;
       
   192   JfrDumpFlightRecordingDCmd* dcmd = new JfrDumpFlightRecordingDCmd(NULL, false);
       
   193   if (dcmd != NULL) {
       
   194     DCmdMark mark(dcmd);
       
   195     return dcmd->_dcmdparser.num_arguments();
       
   196   }
       
   197   return 0;
       
   198 }
       
   199 
       
   200 void JfrDumpFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
       
   201   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   202 
       
   203   if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
       
   204     return;
       
   205   }
       
   206 
       
   207   ResourceMark rm(THREAD);
       
   208   HandleMark hm(THREAD);
       
   209   JNIHandleBlockManager jni_handle_management(THREAD);
       
   210 
       
   211   JavaValue result(T_OBJECT);
       
   212   JfrJavaArguments constructor_args(&result);
       
   213   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdDump", CHECK);
       
   214   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
       
   215   Handle h_dcmd_instance(THREAD, dcmd);
       
   216   assert(h_dcmd_instance.not_null(), "invariant");
       
   217 
       
   218   jstring name = NULL;
       
   219   if (_name.is_set() && _name.value()  != NULL) {
       
   220     name = JfrJavaSupport::new_string(_name.value(), CHECK);
       
   221   }
       
   222 
       
   223   jstring filepath = NULL;
       
   224   if (_filename.is_set() && _filename.value() != NULL) {
       
   225     filepath = JfrJavaSupport::new_string(_filename.value(), CHECK);
       
   226   }
       
   227 
       
   228   jobject path_to_gc_roots = NULL;
       
   229   if (_path_to_gc_roots.is_set()) {
       
   230     path_to_gc_roots = JfrJavaSupport::new_java_lang_Boolean(_path_to_gc_roots.value(), CHECK);
       
   231   }
       
   232 
       
   233   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdDump";
       
   234   static const char method[] = "execute";
       
   235   static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;)Ljava/lang/String;";
       
   236 
       
   237   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
       
   238   execute_args.set_receiver(h_dcmd_instance);
       
   239 
       
   240   // arguments
       
   241   execute_args.push_jobject(name);
       
   242   execute_args.push_jobject(filepath);
       
   243   execute_args.push_jobject(path_to_gc_roots);
       
   244 
       
   245   JfrJavaSupport::call_virtual(&execute_args, THREAD);
       
   246   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
       
   247 }
       
   248 
       
   249 JfrCheckFlightRecordingDCmd::JfrCheckFlightRecordingDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
       
   250   _name("name","Recording text, e.g. \\\"My Recording\\\" or omit to see all recordings","STRING",false, NULL),
       
   251   _verbose("verbose","Print event settings for the recording(s)","BOOLEAN",
       
   252            false, "false") {
       
   253   _dcmdparser.add_dcmd_option(&_name);
       
   254   _dcmdparser.add_dcmd_option(&_verbose);
       
   255 };
       
   256 
       
   257 int JfrCheckFlightRecordingDCmd::num_arguments() {
       
   258   ResourceMark rm;
       
   259   JfrCheckFlightRecordingDCmd* dcmd = new JfrCheckFlightRecordingDCmd(NULL, false);
       
   260   if (dcmd != NULL) {
       
   261     DCmdMark mark(dcmd);
       
   262     return dcmd->_dcmdparser.num_arguments();
       
   263   }
       
   264   return 0;
       
   265 }
       
   266 
       
   267 void JfrCheckFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
       
   268   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   269 
       
   270   if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
       
   271     return;
       
   272   }
       
   273 
       
   274   ResourceMark rm(THREAD);
       
   275   HandleMark hm(THREAD);
       
   276   JNIHandleBlockManager jni_handle_management(THREAD);
       
   277 
       
   278   JavaValue result(T_OBJECT);
       
   279   JfrJavaArguments constructor_args(&result);
       
   280   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdCheck", CHECK);
       
   281   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
       
   282   Handle h_dcmd_instance(THREAD, dcmd);
       
   283   assert(h_dcmd_instance.not_null(), "invariant");
       
   284 
       
   285   jstring name = NULL;
       
   286   if (_name.is_set() && _name.value() != NULL) {
       
   287     name = JfrJavaSupport::new_string(_name.value(), CHECK);
       
   288   }
       
   289 
       
   290   jobject verbose = NULL;
       
   291   if (_verbose.is_set()) {
       
   292     verbose = JfrJavaSupport::new_java_lang_Boolean(_verbose.value(), CHECK);
       
   293   }
       
   294 
       
   295   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdCheck";
       
   296   static const char method[] = "execute";
       
   297   static const char signature[] = "(Ljava/lang/String;Ljava/lang/Boolean;)Ljava/lang/String;";
       
   298 
       
   299   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
       
   300   execute_args.set_receiver(h_dcmd_instance);
       
   301 
       
   302   // arguments
       
   303   execute_args.push_jobject(name);
       
   304   execute_args.push_jobject(verbose);
       
   305 
       
   306   JfrJavaSupport::call_virtual(&execute_args, THREAD);
       
   307   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
       
   308 }
       
   309 
       
   310 JfrStartFlightRecordingDCmd::JfrStartFlightRecordingDCmd(outputStream* output,
       
   311                                                          bool heap) : DCmdWithParser(output, heap),
       
   312   _name("name", "Name that can be used to identify recording, e.g. \\\"My Recording\\\"", "STRING", false, NULL),
       
   313   _settings("settings", "Settings file(s), e.g. profile or default. See JRE_HOME/lib/jfr", "STRING SET", false),
       
   314   _delay("delay", "Delay recording start with (s)econds, (m)inutes), (h)ours), or (d)ays, e.g. 5h.", "NANOTIME", false, "0"),
       
   315   _duration("duration", "Duration of recording in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 300s.", "NANOTIME", false, "0"),
       
   316   _filename("filename", "Resulting recording filename, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false),
       
   317   _disk("disk", "Recording should be persisted to disk", "BOOLEAN", false),
       
   318   _maxage("maxage", "Maximum time to keep recorded data (on disk) in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, or 0 for no limit", "NANOTIME", false, "0"),
       
   319   _maxsize("maxsize", "Maximum amount of bytes to keep (on disk) in (k)B, (M)B or (G)B, e.g. 500M, or 0 for no limit", "MEMORY SIZE", false, "0"),
       
   320   _dump_on_exit("dumponexit", "Dump running recording when JVM shuts down", "BOOLEAN", false),
       
   321   _path_to_gc_roots("path-to-gc-roots", "Collect path to GC roots", "BOOLEAN", false, "false") {
       
   322   _dcmdparser.add_dcmd_option(&_name);
       
   323   _dcmdparser.add_dcmd_option(&_settings);
       
   324   _dcmdparser.add_dcmd_option(&_delay);
       
   325   _dcmdparser.add_dcmd_option(&_duration);
       
   326   _dcmdparser.add_dcmd_option(&_disk);
       
   327   _dcmdparser.add_dcmd_option(&_filename);
       
   328   _dcmdparser.add_dcmd_option(&_maxage);
       
   329   _dcmdparser.add_dcmd_option(&_maxsize);
       
   330   _dcmdparser.add_dcmd_option(&_dump_on_exit);
       
   331   _dcmdparser.add_dcmd_option(&_path_to_gc_roots);
       
   332 };
       
   333 
       
   334 int JfrStartFlightRecordingDCmd::num_arguments() {
       
   335   ResourceMark rm;
       
   336   JfrStartFlightRecordingDCmd* dcmd = new JfrStartFlightRecordingDCmd(NULL, false);
       
   337   if (dcmd != NULL) {
       
   338     DCmdMark mark(dcmd);
       
   339     return dcmd->_dcmdparser.num_arguments();
       
   340   }
       
   341   return 0;
       
   342 }
       
   343 
       
   344 void JfrStartFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
       
   345   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   346 
       
   347   if (invalid_state(output(), THREAD)) {
       
   348     return;
       
   349   }
       
   350 
       
   351   ResourceMark rm(THREAD);
       
   352   HandleMark hm(THREAD);
       
   353   JNIHandleBlockManager jni_handle_management(THREAD);
       
   354 
       
   355   JavaValue result(T_OBJECT);
       
   356   JfrJavaArguments constructor_args(&result);
       
   357   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdStart", THREAD);
       
   358   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
       
   359   Handle h_dcmd_instance(THREAD, dcmd);
       
   360   assert(h_dcmd_instance.not_null(), "invariant");
       
   361 
       
   362   jstring name = NULL;
       
   363   if (_name.is_set() && _name.value() != NULL) {
       
   364     name = JfrJavaSupport::new_string(_name.value(), CHECK);
       
   365   }
       
   366 
       
   367   jstring filename = NULL;
       
   368   if (_filename.is_set() && _filename.value() != NULL) {
       
   369     filename = JfrJavaSupport::new_string(_filename.value(), CHECK);
       
   370   }
       
   371 
       
   372   jobject maxage = NULL;
       
   373   if (_maxage.is_set()) {
       
   374     maxage = JfrJavaSupport::new_java_lang_Long(_maxage.value()._nanotime, CHECK);
       
   375   }
       
   376 
       
   377   jobject maxsize = NULL;
       
   378   if (_maxsize.is_set()) {
       
   379     maxsize = JfrJavaSupport::new_java_lang_Long(_maxsize.value()._size, CHECK);
       
   380   }
       
   381 
       
   382   jobject duration = NULL;
       
   383   if (_duration.is_set()) {
       
   384     duration = JfrJavaSupport::new_java_lang_Long(_duration.value()._nanotime, CHECK);
       
   385   }
       
   386 
       
   387   jobject delay = NULL;
       
   388   if (_delay.is_set()) {
       
   389     delay = JfrJavaSupport::new_java_lang_Long(_delay.value()._nanotime, CHECK);
       
   390   }
       
   391 
       
   392   jobject disk = NULL;
       
   393   if (_disk.is_set()) {
       
   394     disk = JfrJavaSupport::new_java_lang_Boolean(_disk.value(), CHECK);
       
   395   }
       
   396 
       
   397   jobject dump_on_exit = NULL;
       
   398   if (_dump_on_exit.is_set()) {
       
   399     dump_on_exit = JfrJavaSupport::new_java_lang_Boolean(_dump_on_exit.value(), CHECK);
       
   400   }
       
   401 
       
   402   jobject path_to_gc_roots = NULL;
       
   403   if (_path_to_gc_roots.is_set()) {
       
   404     path_to_gc_roots = JfrJavaSupport::new_java_lang_Boolean(_path_to_gc_roots.value(), CHECK);
       
   405   }
       
   406 
       
   407   jobjectArray settings = NULL;
       
   408   if (_settings.is_set()) {
       
   409     const int length = _settings.value()->array()->length();
       
   410     settings = JfrJavaSupport::new_string_array(length, CHECK);
       
   411     assert(settings != NULL, "invariant");
       
   412     for (int i = 0; i < length; ++i) {
       
   413       jobject element = JfrJavaSupport::new_string(_settings.value()->array()->at(i), CHECK);
       
   414       assert(element != NULL, "invariant");
       
   415       JfrJavaSupport::set_array_element(settings, element, i, CHECK);
       
   416     }
       
   417   }
       
   418 
       
   419   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStart";
       
   420   static const char method[] = "execute";
       
   421   static const char signature[] = "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/Long;"
       
   422     "Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/String;"
       
   423     "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/lang/String;";
       
   424 
       
   425   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
       
   426   execute_args.set_receiver(h_dcmd_instance);
       
   427 
       
   428   // arguments
       
   429   execute_args.push_jobject(name);
       
   430   execute_args.push_jobject(settings);
       
   431   execute_args.push_jobject(delay);
       
   432   execute_args.push_jobject(duration);
       
   433   execute_args.push_jobject(disk);
       
   434   execute_args.push_jobject(filename);
       
   435   execute_args.push_jobject(maxage);
       
   436   execute_args.push_jobject(maxsize);
       
   437   execute_args.push_jobject(dump_on_exit);
       
   438   execute_args.push_jobject(path_to_gc_roots);
       
   439 
       
   440   JfrJavaSupport::call_virtual(&execute_args, THREAD);
       
   441   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
       
   442 }
       
   443 
       
   444 JfrStopFlightRecordingDCmd::JfrStopFlightRecordingDCmd(outputStream* output,
       
   445                                                        bool heap) : DCmdWithParser(output, heap),
       
   446   _name("name", "Recording text,.e.g \\\"My Recording\\\"", "STRING", false, NULL),
       
   447   _filename("filename", "Copy recording data to file, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false, NULL) {
       
   448   _dcmdparser.add_dcmd_option(&_name);
       
   449   _dcmdparser.add_dcmd_option(&_filename);
       
   450 };
       
   451 
       
   452 int JfrStopFlightRecordingDCmd::num_arguments() {
       
   453   ResourceMark rm;
       
   454   JfrStopFlightRecordingDCmd* dcmd = new JfrStopFlightRecordingDCmd(NULL, false);
       
   455   if (dcmd != NULL) {
       
   456     DCmdMark mark(dcmd);
       
   457     return dcmd->_dcmdparser.num_arguments();
       
   458   }
       
   459   return 0;
       
   460 }
       
   461 
       
   462 void JfrStopFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
       
   463   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   464 
       
   465   if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
       
   466     return;
       
   467   }
       
   468 
       
   469   ResourceMark rm(THREAD);
       
   470   HandleMark hm(THREAD);
       
   471   JNIHandleBlockManager jni_handle_management(THREAD);
       
   472 
       
   473   JavaValue result(T_OBJECT);
       
   474   JfrJavaArguments constructor_args(&result);
       
   475   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdStop", CHECK);
       
   476   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
       
   477   Handle h_dcmd_instance(THREAD, dcmd);
       
   478   assert(h_dcmd_instance.not_null(), "invariant");
       
   479 
       
   480   jstring name = NULL;
       
   481   if (_name.is_set() && _name.value()  != NULL) {
       
   482     name = JfrJavaSupport::new_string(_name.value(), CHECK);
       
   483   }
       
   484 
       
   485   jstring filepath = NULL;
       
   486   if (_filename.is_set() && _filename.value() != NULL) {
       
   487     filepath = JfrJavaSupport::new_string(_filename.value(), CHECK);
       
   488   }
       
   489 
       
   490   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStop";
       
   491   static const char method[] = "execute";
       
   492   static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
       
   493 
       
   494   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
       
   495   execute_args.set_receiver(h_dcmd_instance);
       
   496 
       
   497   // arguments
       
   498   execute_args.push_jobject(name);
       
   499   execute_args.push_jobject(filepath);
       
   500 
       
   501   JfrJavaSupport::call_virtual(&execute_args, THREAD);
       
   502   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
       
   503 }
       
   504 
       
   505 JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* output,
       
   506                                                                bool heap) : DCmdWithParser(output, heap),
       
   507   _repository_path("repositorypath", "Path to repository,.e.g \\\"My Repository\\\"", "STRING", false, NULL),
       
   508   _dump_path("dumppath", "Path to dump,.e.g \\\"My Dump path\\\"", "STRING", false, NULL),
       
   509   _stack_depth("stackdepth", "Stack Depth", "JLONG", false, "64"),
       
   510   _global_buffer_count("globalbuffercount", "Number of global buffers,", "JLONG", false, "32"),
       
   511   _global_buffer_size("globalbuffersize", "Size of a global buffers,", "JLONG", false, "524288"),
       
   512   _thread_buffer_size("thread_buffer_size", "Size of a thread buffer", "JLONG", false, "8192"),
       
   513   _memory_size("memorysize", "Overall memory size, ", "JLONG", false, "16777216"),
       
   514   _max_chunk_size("maxchunksize", "Size of an individual disk chunk", "JLONG", false, "12582912"),
       
   515   _sample_threads("samplethreads", "Activate Thread sampling", "BOOLEAN", false, "true") {
       
   516   _dcmdparser.add_dcmd_option(&_repository_path);
       
   517   _dcmdparser.add_dcmd_option(&_dump_path);
       
   518   _dcmdparser.add_dcmd_option(&_stack_depth);
       
   519   _dcmdparser.add_dcmd_option(&_global_buffer_count);
       
   520   _dcmdparser.add_dcmd_option(&_global_buffer_size);
       
   521   _dcmdparser.add_dcmd_option(&_thread_buffer_size);
       
   522   _dcmdparser.add_dcmd_option(&_memory_size);
       
   523   _dcmdparser.add_dcmd_option(&_max_chunk_size);
       
   524   _dcmdparser.add_dcmd_option(&_sample_threads);
       
   525 };
       
   526 
       
   527 int JfrConfigureFlightRecorderDCmd::num_arguments() {
       
   528   ResourceMark rm;
       
   529   JfrConfigureFlightRecorderDCmd* dcmd = new JfrConfigureFlightRecorderDCmd(NULL, false);
       
   530   if (dcmd != NULL) {
       
   531     DCmdMark mark(dcmd);
       
   532     return dcmd->_dcmdparser.num_arguments();
       
   533   }
       
   534   return 0;
       
   535 }
       
   536 
       
   537 void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
       
   538   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
       
   539 
       
   540   if (invalid_state(output(), THREAD)) {
       
   541     return;
       
   542   }
       
   543 
       
   544   ResourceMark rm(THREAD);
       
   545   HandleMark hm(THREAD);
       
   546   JNIHandleBlockManager jni_handle_management(THREAD);
       
   547 
       
   548   JavaValue result(T_OBJECT);
       
   549   JfrJavaArguments constructor_args(&result);
       
   550   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdConfigure", CHECK);
       
   551   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
       
   552   Handle h_dcmd_instance(THREAD, dcmd);
       
   553   assert(h_dcmd_instance.not_null(), "invariant");
       
   554 
       
   555   jstring repository_path = NULL;
       
   556   if (_repository_path.is_set() && _repository_path.value() != NULL) {
       
   557     repository_path = JfrJavaSupport::new_string(_repository_path.value(), CHECK);
       
   558   }
       
   559 
       
   560   jstring dump_path = NULL;
       
   561   if (_dump_path.is_set() && _dump_path.value() != NULL) {
       
   562     dump_path = JfrJavaSupport::new_string(_dump_path.value(), CHECK);
       
   563   }
       
   564 
       
   565   jobject stack_depth = NULL;
       
   566   if (_stack_depth.is_set()) {
       
   567     stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK);
       
   568   }
       
   569 
       
   570   jobject global_buffer_count = NULL;
       
   571   if (_global_buffer_count.is_set()) {
       
   572     global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK);
       
   573   }
       
   574 
       
   575   jobject global_buffer_size = NULL;
       
   576   if (_global_buffer_size.is_set()) {
       
   577     global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value(), CHECK);
       
   578   }
       
   579 
       
   580   jobject thread_buffer_size = NULL;
       
   581   if (_thread_buffer_size.is_set()) {
       
   582     thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value(), CHECK);
       
   583   }
       
   584 
       
   585   jobject max_chunk_size = NULL;
       
   586   if (_max_chunk_size.is_set()) {
       
   587     max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value(), CHECK);
       
   588   }
       
   589 
       
   590   jobject memory_size = NULL;
       
   591   if (_memory_size.is_set()) {
       
   592     memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value(), CHECK);
       
   593   }
       
   594 
       
   595   jobject sample_threads = NULL;
       
   596   if (_sample_threads.is_set()) {
       
   597     sample_threads = JfrJavaSupport::new_java_lang_Boolean(_sample_threads.value(), CHECK);
       
   598   }
       
   599 
       
   600   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdConfigure";
       
   601   static const char method[] = "execute";
       
   602   static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;"
       
   603     "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
       
   604     "Ljava/lang/Long;Ljava/lang/Boolean;)Ljava/lang/String;";
       
   605 
       
   606   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
       
   607   execute_args.set_receiver(h_dcmd_instance);
       
   608 
       
   609   // params
       
   610   execute_args.push_jobject(repository_path);
       
   611   execute_args.push_jobject(dump_path);
       
   612   execute_args.push_jobject(stack_depth);
       
   613   execute_args.push_jobject(global_buffer_count);
       
   614   execute_args.push_jobject(global_buffer_size);
       
   615   execute_args.push_jobject(thread_buffer_size);
       
   616   execute_args.push_jobject(memory_size);
       
   617   execute_args.push_jobject(max_chunk_size);
       
   618   execute_args.push_jobject(sample_threads);
       
   619 
       
   620   JfrJavaSupport::call_virtual(&execute_args, THREAD);
       
   621   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
       
   622 }
       
   623 
       
   624 bool register_jfr_dcmds() {
       
   625   uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
       
   626   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export, true, false));
       
   627   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export, true, false));
       
   628   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export, true, false));
       
   629   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export, true, false));
       
   630   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export, true, false));
       
   631   return true;
       
   632 }
       
   633