src/share/vm/jfr/dcmd/jfrDcmds.cpp

Fri, 27 Sep 2019 10:27:29 +0800

author
egahlin
date
Fri, 27 Sep 2019 10:27:29 +0800
changeset 9883
02a4c08a8777
parent 9870
830105382dbd
child 9889
63a1206b8286
permissions
-rw-r--r--

8216064: -XX:StartFlightRecording:settings= doesn't work properly
Reviewed-by: mgronlun

     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  */
    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"
    41 #ifdef _WINDOWS
    42 #define JFR_FILENAME_EXAMPLE "C:\\Users\\user\\My Recording.jfr"
    43 #endif
    45 #ifdef __APPLE__
    46 #define JFR_FILENAME_EXAMPLE  "/Users/user/My Recording.jfr"
    47 #endif
    49 #ifndef JFR_FILENAME_EXAMPLE
    50 #define JFR_FILENAME_EXAMPLE "/home/user/My Recording.jfr"
    51 #endif
    53 // JNIHandle management
    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));
    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 }
    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));
    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 }
    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   }
    95   ~JNIHandleBlockManager() {
    96     pop_jni_handle_block(_thread);
    97   }
    98 };
   100 static bool is_disabled(outputStream* output) {
   101   if (Jfr::is_disabled()) {
   102     if (output != NULL) {
   103       output->print_cr("Flight Recorder is disabled.\n");
   104     }
   105     return true;
   106   }
   107   return false;
   108 }
   110 static bool is_recorder_instance_created(outputStream* output) {
   111   if (!JfrRecorder::is_created()) {
   112     if (output != NULL) {
   113       output->print_cr("No available recordings.\n");
   114       output->print_cr("Use JFR.start to start a recording.\n");
   115     }
   116     return false;
   117   }
   118   return true;
   119 }
   121 static bool invalid_state(outputStream* out, TRAPS) {
   122   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   123   return is_disabled(out);
   124 }
   126 static void print_pending_exception(outputStream* output, oop throwable) {
   127   assert(throwable != NULL, "invariant");
   129   oop msg = java_lang_Throwable::message(throwable);
   131   if (msg != NULL) {
   132     char* text = java_lang_String::as_utf8_string(msg);
   133     output->print_raw_cr(text);
   134   }
   135 }
   137 static void print_message(outputStream* output, const char* message) {
   138   if (message != NULL) {
   139     output->print_raw(message);
   140   }
   141 }
   143 static void handle_dcmd_result(outputStream* output,
   144                                const oop result,
   145                                const DCmdSource source,
   146                                TRAPS) {
   147   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   148   assert(output != NULL, "invariant");
   149   if (HAS_PENDING_EXCEPTION) {
   150     print_pending_exception(output, PENDING_EXCEPTION);
   151     // Don't clear excption on startup, JVM should fail initialization.
   152     if (DCmd_Source_Internal != source) {
   153       CLEAR_PENDING_EXCEPTION;
   154     }
   155     return;
   156   }
   158   assert(!HAS_PENDING_EXCEPTION, "invariant");
   160   if (result != NULL) {
   161     const char* result_chars = java_lang_String::as_utf8_string(result);
   162     print_message(output, result_chars);
   163   }
   164 }
   166 static oop construct_dcmd_instance(JfrJavaArguments* args, TRAPS) {
   167   assert(args != NULL, "invariant");
   168   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   169   assert(args->klass() != NULL, "invariant");
   170   args->set_name("<init>", CHECK_NULL);
   171   args->set_signature("()V", CHECK_NULL);
   172   JfrJavaSupport::new_object(args, CHECK_NULL);
   173   return (oop)args->result()->get_jobject();
   174 }
   176 JfrDumpFlightRecordingDCmd::JfrDumpFlightRecordingDCmd(outputStream* output,
   177                                                        bool heap) : DCmdWithParser(output, heap),
   178   _name("name", "Recording name, e.g. \\\"My Recording\\\"", "STRING", false, NULL),
   179   _filename("filename", "Copy recording data to file, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false),
   180   _maxage("maxage", "Maximum duration to dump, in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 60m, or 0 for no limit", "NANOTIME", false, "0"),
   181   _maxsize("maxsize", "Maximum amount of bytes to dump, in (M)B or (G)B, e.g. 500M, or 0 for no limit", "MEMORY SIZE", false, "0"),
   182   _begin("begin", "Point in time to dump data from, e.g. 09:00, 21:35:00, 2018-06-03T18:12:56.827Z, 2018-06-03T20:13:46.832, -10m, -3h, or -1d", "STRING", false),
   183   _end("end", "Point in time to dump data to, e.g. 09:00, 21:35:00, 2018-06-03T18:12:56.827Z, 2018-06-03T20:13:46.832, -10m, -3h, or -1d", "STRING", false),
   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(&_maxage);
   188   _dcmdparser.add_dcmd_option(&_maxsize);
   189   _dcmdparser.add_dcmd_option(&_begin);
   190   _dcmdparser.add_dcmd_option(&_end);
   191   _dcmdparser.add_dcmd_option(&_path_to_gc_roots);
   192 };
   194 int JfrDumpFlightRecordingDCmd::num_arguments() {
   195   ResourceMark rm;
   196   JfrDumpFlightRecordingDCmd* dcmd = new JfrDumpFlightRecordingDCmd(NULL, false);
   197   if (dcmd != NULL) {
   198     DCmdMark mark(dcmd);
   199     return dcmd->_dcmdparser.num_arguments();
   200   }
   201   return 0;
   202 }
   204 void JfrDumpFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
   205   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   207   if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
   208     return;
   209   }
   211   ResourceMark rm(THREAD);
   212   HandleMark hm(THREAD);
   213   JNIHandleBlockManager jni_handle_management(THREAD);
   215   JavaValue result(T_OBJECT);
   216   JfrJavaArguments constructor_args(&result);
   217   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdDump", CHECK);
   218   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
   219   Handle h_dcmd_instance(THREAD, dcmd);
   220   assert(h_dcmd_instance.not_null(), "invariant");
   222   jstring name = NULL;
   223   if (_name.is_set() && _name.value()  != NULL) {
   224     name = JfrJavaSupport::new_string(_name.value(), CHECK);
   225   }
   227   jstring filepath = NULL;
   228   if (_filename.is_set() && _filename.value() != NULL) {
   229     filepath = JfrJavaSupport::new_string(_filename.value(), CHECK);
   230   }
   232   jobject maxage = NULL;
   233   if (_maxage.is_set()) {
   234     maxage = JfrJavaSupport::new_java_lang_Long(_maxage.value()._nanotime, CHECK);
   235   }
   237   jobject maxsize = NULL;
   238   if (_maxsize.is_set()) {
   239     maxsize = JfrJavaSupport::new_java_lang_Long(_maxsize.value()._size, CHECK);
   240   }
   242   jstring begin = NULL;
   243   if (_begin.is_set() && _begin.value() != NULL) {
   244     begin = JfrJavaSupport::new_string(_begin.value(), CHECK);
   245   }
   247   jstring end = NULL;
   248   if (_end.is_set() && _end.value() != NULL) {
   249     end = JfrJavaSupport::new_string(_end.value(), CHECK);
   250   }
   252   jobject path_to_gc_roots = NULL;
   253   if (_path_to_gc_roots.is_set()) {
   254     path_to_gc_roots = JfrJavaSupport::new_java_lang_Boolean(_path_to_gc_roots.value(), CHECK);
   255   }
   257   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdDump";
   258   static const char method[] = "execute";
   259   static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/String;Ljava/lang/String;Ljava/lang/Boolean;)Ljava/lang/String;";
   261   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
   262   execute_args.set_receiver(h_dcmd_instance);
   264   // arguments
   265   execute_args.push_jobject(name);
   266   execute_args.push_jobject(filepath);
   267   execute_args.push_jobject(maxage);
   268   execute_args.push_jobject(maxsize);
   269   execute_args.push_jobject(begin);
   270   execute_args.push_jobject(end);
   271   execute_args.push_jobject(path_to_gc_roots);
   273   JfrJavaSupport::call_virtual(&execute_args, THREAD);
   274   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
   275 }
   277 JfrCheckFlightRecordingDCmd::JfrCheckFlightRecordingDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
   278   _name("name","Recording name, e.g. \\\"My Recording\\\" or omit to see all recordings","STRING",false, NULL),
   279   _verbose("verbose","Print event settings for the recording(s)","BOOLEAN",
   280            false, "false") {
   281   _dcmdparser.add_dcmd_option(&_name);
   282   _dcmdparser.add_dcmd_option(&_verbose);
   283 };
   285 int JfrCheckFlightRecordingDCmd::num_arguments() {
   286   ResourceMark rm;
   287   JfrCheckFlightRecordingDCmd* dcmd = new JfrCheckFlightRecordingDCmd(NULL, false);
   288   if (dcmd != NULL) {
   289     DCmdMark mark(dcmd);
   290     return dcmd->_dcmdparser.num_arguments();
   291   }
   292   return 0;
   293 }
   295 void JfrCheckFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
   296   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   298   if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
   299     return;
   300   }
   302   ResourceMark rm(THREAD);
   303   HandleMark hm(THREAD);
   304   JNIHandleBlockManager jni_handle_management(THREAD);
   306   JavaValue result(T_OBJECT);
   307   JfrJavaArguments constructor_args(&result);
   308   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdCheck", CHECK);
   309   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
   310   Handle h_dcmd_instance(THREAD, dcmd);
   311   assert(h_dcmd_instance.not_null(), "invariant");
   313   jstring name = NULL;
   314   if (_name.is_set() && _name.value() != NULL) {
   315     name = JfrJavaSupport::new_string(_name.value(), CHECK);
   316   }
   318   jobject verbose = NULL;
   319   if (_verbose.is_set()) {
   320     verbose = JfrJavaSupport::new_java_lang_Boolean(_verbose.value(), CHECK);
   321   }
   323   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdCheck";
   324   static const char method[] = "execute";
   325   static const char signature[] = "(Ljava/lang/String;Ljava/lang/Boolean;)Ljava/lang/String;";
   327   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
   328   execute_args.set_receiver(h_dcmd_instance);
   330   // arguments
   331   execute_args.push_jobject(name);
   332   execute_args.push_jobject(verbose);
   334   JfrJavaSupport::call_virtual(&execute_args, THREAD);
   335   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
   336 }
   338 JfrStartFlightRecordingDCmd::JfrStartFlightRecordingDCmd(outputStream* output,
   339                                                          bool heap) : DCmdWithParser(output, heap),
   340   _name("name", "Name that can be used to identify recording, e.g. \\\"My Recording\\\"", "STRING", false, NULL),
   341   _settings("settings", "Settings file(s), e.g. profile or default. See JRE_HOME/lib/jfr", "STRING SET", false),
   342   _delay("delay", "Delay recording start with (s)econds, (m)inutes), (h)ours), or (d)ays, e.g. 5h.", "NANOTIME", false, "0"),
   343   _duration("duration", "Duration of recording in (s)econds, (m)inutes, (h)ours, or (d)ays, e.g. 300s.", "NANOTIME", false, "0"),
   344   _filename("filename", "Resulting recording filename, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false),
   345   _disk("disk", "Recording should be persisted to disk", "BOOLEAN", false),
   346   _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"),
   347   _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"),
   348   _dump_on_exit("dumponexit", "Dump running recording when JVM shuts down", "BOOLEAN", false),
   349   _path_to_gc_roots("path-to-gc-roots", "Collect path to GC roots", "BOOLEAN", false, "false") {
   350   _dcmdparser.add_dcmd_option(&_name);
   351   _dcmdparser.add_dcmd_option(&_settings);
   352   _dcmdparser.add_dcmd_option(&_delay);
   353   _dcmdparser.add_dcmd_option(&_duration);
   354   _dcmdparser.add_dcmd_option(&_disk);
   355   _dcmdparser.add_dcmd_option(&_filename);
   356   _dcmdparser.add_dcmd_option(&_maxage);
   357   _dcmdparser.add_dcmd_option(&_maxsize);
   358   _dcmdparser.add_dcmd_option(&_dump_on_exit);
   359   _dcmdparser.add_dcmd_option(&_path_to_gc_roots);
   360 };
   362 int JfrStartFlightRecordingDCmd::num_arguments() {
   363   ResourceMark rm;
   364   JfrStartFlightRecordingDCmd* dcmd = new JfrStartFlightRecordingDCmd(NULL, false);
   365   if (dcmd != NULL) {
   366     DCmdMark mark(dcmd);
   367     return dcmd->_dcmdparser.num_arguments();
   368   }
   369   return 0;
   370 }
   372 void JfrStartFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
   373   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   375   if (invalid_state(output(), THREAD)) {
   376     return;
   377   }
   379   ResourceMark rm(THREAD);
   380   HandleMark hm(THREAD);
   381   JNIHandleBlockManager jni_handle_management(THREAD);
   383   JavaValue result(T_OBJECT);
   384   JfrJavaArguments constructor_args(&result);
   385   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdStart", THREAD);
   386   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
   387   Handle h_dcmd_instance(THREAD, dcmd);
   388   assert(h_dcmd_instance.not_null(), "invariant");
   390   jstring name = NULL;
   391   if (_name.is_set() && _name.value() != NULL) {
   392     name = JfrJavaSupport::new_string(_name.value(), CHECK);
   393   }
   395   jstring filename = NULL;
   396   if (_filename.is_set() && _filename.value() != NULL) {
   397     filename = JfrJavaSupport::new_string(_filename.value(), CHECK);
   398   }
   400   jobject maxage = NULL;
   401   if (_maxage.is_set()) {
   402     maxage = JfrJavaSupport::new_java_lang_Long(_maxage.value()._nanotime, CHECK);
   403   }
   405   jobject maxsize = NULL;
   406   if (_maxsize.is_set()) {
   407     maxsize = JfrJavaSupport::new_java_lang_Long(_maxsize.value()._size, CHECK);
   408   }
   410   jobject duration = NULL;
   411   if (_duration.is_set()) {
   412     duration = JfrJavaSupport::new_java_lang_Long(_duration.value()._nanotime, CHECK);
   413   }
   415   jobject delay = NULL;
   416   if (_delay.is_set()) {
   417     delay = JfrJavaSupport::new_java_lang_Long(_delay.value()._nanotime, CHECK);
   418   }
   420   jobject disk = NULL;
   421   if (_disk.is_set()) {
   422     disk = JfrJavaSupport::new_java_lang_Boolean(_disk.value(), CHECK);
   423   }
   425   jobject dump_on_exit = NULL;
   426   if (_dump_on_exit.is_set()) {
   427     dump_on_exit = JfrJavaSupport::new_java_lang_Boolean(_dump_on_exit.value(), CHECK);
   428   }
   430   jobject path_to_gc_roots = NULL;
   431   if (_path_to_gc_roots.is_set()) {
   432     path_to_gc_roots = JfrJavaSupport::new_java_lang_Boolean(_path_to_gc_roots.value(), CHECK);
   433   }
   435   jobjectArray settings = NULL;
   436   if (_settings.is_set()) {
   437     int length = _settings.value()->array()->length();
   438     if (length == 1) {
   439       const char* c_str = _settings.value()->array()->at(0);
   440       if (strcmp(c_str, "none") == 0) {
   441         length = 0;
   442       }
   443     }
   444     settings = JfrJavaSupport::new_string_array(length, CHECK);
   445     assert(settings != NULL, "invariant");
   446     for (int i = 0; i < length; ++i) {
   447       jobject element = JfrJavaSupport::new_string(_settings.value()->array()->at(i), CHECK);
   448       assert(element != NULL, "invariant");
   449       JfrJavaSupport::set_array_element(settings, element, i, CHECK);
   450     }
   451   }
   453   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStart";
   454   static const char method[] = "execute";
   455   static const char signature[] = "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/Long;"
   456     "Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/String;"
   457     "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/lang/String;";
   459   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
   460   execute_args.set_receiver(h_dcmd_instance);
   462   // arguments
   463   execute_args.push_jobject(name);
   464   execute_args.push_jobject(settings);
   465   execute_args.push_jobject(delay);
   466   execute_args.push_jobject(duration);
   467   execute_args.push_jobject(disk);
   468   execute_args.push_jobject(filename);
   469   execute_args.push_jobject(maxage);
   470   execute_args.push_jobject(maxsize);
   471   execute_args.push_jobject(dump_on_exit);
   472   execute_args.push_jobject(path_to_gc_roots);
   474   JfrJavaSupport::call_virtual(&execute_args, THREAD);
   475   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
   476 }
   478 JfrStopFlightRecordingDCmd::JfrStopFlightRecordingDCmd(outputStream* output,
   479                                                        bool heap) : DCmdWithParser(output, heap),
   480   _name("name", "Recording text,.e.g \\\"My Recording\\\"", "STRING", true, NULL),
   481   _filename("filename", "Copy recording data to file, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false, NULL) {
   482   _dcmdparser.add_dcmd_option(&_name);
   483   _dcmdparser.add_dcmd_option(&_filename);
   484 };
   486 int JfrStopFlightRecordingDCmd::num_arguments() {
   487   ResourceMark rm;
   488   JfrStopFlightRecordingDCmd* dcmd = new JfrStopFlightRecordingDCmd(NULL, false);
   489   if (dcmd != NULL) {
   490     DCmdMark mark(dcmd);
   491     return dcmd->_dcmdparser.num_arguments();
   492   }
   493   return 0;
   494 }
   496 void JfrStopFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
   497   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   499   if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
   500     return;
   501   }
   503   ResourceMark rm(THREAD);
   504   HandleMark hm(THREAD);
   505   JNIHandleBlockManager jni_handle_management(THREAD);
   507   JavaValue result(T_OBJECT);
   508   JfrJavaArguments constructor_args(&result);
   509   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdStop", CHECK);
   510   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
   511   Handle h_dcmd_instance(THREAD, dcmd);
   512   assert(h_dcmd_instance.not_null(), "invariant");
   514   jstring name = NULL;
   515   if (_name.is_set() && _name.value()  != NULL) {
   516     name = JfrJavaSupport::new_string(_name.value(), CHECK);
   517   }
   519   jstring filepath = NULL;
   520   if (_filename.is_set() && _filename.value() != NULL) {
   521     filepath = JfrJavaSupport::new_string(_filename.value(), CHECK);
   522   }
   524   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStop";
   525   static const char method[] = "execute";
   526   static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
   528   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
   529   execute_args.set_receiver(h_dcmd_instance);
   531   // arguments
   532   execute_args.push_jobject(name);
   533   execute_args.push_jobject(filepath);
   535   JfrJavaSupport::call_virtual(&execute_args, THREAD);
   536   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
   537 }
   539 JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* output,
   540                                                                bool heap) : DCmdWithParser(output, heap),
   541   _repository_path("repositorypath", "Path to repository,.e.g \\\"My Repository\\\"", "STRING", false, NULL),
   542   _dump_path("dumppath", "Path to dump,.e.g \\\"My Dump path\\\"", "STRING", false, NULL),
   543   _stack_depth("stackdepth", "Stack Depth", "JULONG", false, "64"),
   544   _global_buffer_count("globalbuffercount", "Number of global buffers,", "JULONG", false, "20"),
   545   _global_buffer_size("globalbuffersize", "Size of a global buffers,", "MEMORY SIZE", false, "512k"),
   546   _thread_buffer_size("thread_buffer_size", "Size of a thread buffer", "MEMORY SIZE", false, "8k"),
   547   _memory_size("memorysize", "Overall memory size, ", "MEMORY SIZE", false, "10m"),
   548   _max_chunk_size("maxchunksize", "Size of an individual disk chunk", "MEMORY SIZE", false, "12m"),
   549   _sample_threads("samplethreads", "Activate Thread sampling", "BOOLEAN", false, "true") {
   550   _dcmdparser.add_dcmd_option(&_repository_path);
   551   _dcmdparser.add_dcmd_option(&_dump_path);
   552   _dcmdparser.add_dcmd_option(&_stack_depth);
   553   _dcmdparser.add_dcmd_option(&_global_buffer_count);
   554   _dcmdparser.add_dcmd_option(&_global_buffer_size);
   555   _dcmdparser.add_dcmd_option(&_thread_buffer_size);
   556   _dcmdparser.add_dcmd_option(&_memory_size);
   557   _dcmdparser.add_dcmd_option(&_max_chunk_size);
   558   _dcmdparser.add_dcmd_option(&_sample_threads);
   559 };
   561 int JfrConfigureFlightRecorderDCmd::num_arguments() {
   562   ResourceMark rm;
   563   JfrConfigureFlightRecorderDCmd* dcmd = new JfrConfigureFlightRecorderDCmd(NULL, false);
   564   if (dcmd != NULL) {
   565     DCmdMark mark(dcmd);
   566     return dcmd->_dcmdparser.num_arguments();
   567   }
   568   return 0;
   569 }
   571 void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
   572   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   574   if (invalid_state(output(), THREAD)) {
   575     return;
   576   }
   578   ResourceMark rm(THREAD);
   579   HandleMark hm(THREAD);
   580   JNIHandleBlockManager jni_handle_management(THREAD);
   582   JavaValue result(T_OBJECT);
   583   JfrJavaArguments constructor_args(&result);
   584   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdConfigure", CHECK);
   585   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
   586   Handle h_dcmd_instance(THREAD, dcmd);
   587   assert(h_dcmd_instance.not_null(), "invariant");
   589   jstring repository_path = NULL;
   590   if (_repository_path.is_set() && _repository_path.value() != NULL) {
   591     repository_path = JfrJavaSupport::new_string(_repository_path.value(), CHECK);
   592   }
   594   jstring dump_path = NULL;
   595   if (_dump_path.is_set() && _dump_path.value() != NULL) {
   596     dump_path = JfrJavaSupport::new_string(_dump_path.value(), CHECK);
   597   }
   599   jobject stack_depth = NULL;
   600   if (_stack_depth.is_set()) {
   601     stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK);
   602   }
   604   jobject global_buffer_count = NULL;
   605   if (_global_buffer_count.is_set()) {
   606     global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK);
   607   }
   609   jobject global_buffer_size = NULL;
   610   if (_global_buffer_size.is_set()) {
   611     global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value()._size, CHECK);
   612   }
   614   jobject thread_buffer_size = NULL;
   615   if (_thread_buffer_size.is_set()) {
   616     thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value()._size, CHECK);
   617   }
   619   jobject max_chunk_size = NULL;
   620   if (_max_chunk_size.is_set()) {
   621     max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value()._size, CHECK);
   622   }
   624   jobject memory_size = NULL;
   625   if (_memory_size.is_set()) {
   626     memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value()._size, CHECK);
   627   }
   629   jobject sample_threads = NULL;
   630   if (_sample_threads.is_set()) {
   631     sample_threads = JfrJavaSupport::new_java_lang_Boolean(_sample_threads.value(), CHECK);
   632   }
   634   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdConfigure";
   635   static const char method[] = "execute";
   636   static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;"
   637     "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
   638     "Ljava/lang/Long;Ljava/lang/Boolean;)Ljava/lang/String;";
   640   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
   641   execute_args.set_receiver(h_dcmd_instance);
   643   // params
   644   execute_args.push_jobject(repository_path);
   645   execute_args.push_jobject(dump_path);
   646   execute_args.push_jobject(stack_depth);
   647   execute_args.push_jobject(global_buffer_count);
   648   execute_args.push_jobject(global_buffer_size);
   649   execute_args.push_jobject(thread_buffer_size);
   650   execute_args.push_jobject(memory_size);
   651   execute_args.push_jobject(max_chunk_size);
   652   execute_args.push_jobject(sample_threads);
   654   JfrJavaSupport::call_virtual(&execute_args, THREAD);
   655   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
   656 }
   658 bool register_jfr_dcmds() {
   659   uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
   660   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export, true, false));
   661   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export, true, false));
   662   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export, true, false));
   663   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export, true, false));
   664   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export, true, false));
   666   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrUnlockCommercialFeaturesDCmd>(full_export, true, false));
   667   return true;
   668 }

mercurial