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

Fri, 23 Nov 2018 16:36:07 +0900

author
ysuenaga
date
Fri, 23 Nov 2018 16:36:07 +0900
changeset 9870
830105382dbd
parent 9858
b985cbb00e68
child 9883
02a4c08a8777
permissions
-rw-r--r--

8213015: Inconsistent settings between JFR.configure and -XX:FlightRecorderOptions
Reviewed-by: mgronlun, egahlin

     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     const int length = _settings.value()->array()->length();
   438     settings = JfrJavaSupport::new_string_array(length, CHECK);
   439     assert(settings != NULL, "invariant");
   440     for (int i = 0; i < length; ++i) {
   441       jobject element = JfrJavaSupport::new_string(_settings.value()->array()->at(i), CHECK);
   442       assert(element != NULL, "invariant");
   443       JfrJavaSupport::set_array_element(settings, element, i, CHECK);
   444     }
   445   }
   447   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStart";
   448   static const char method[] = "execute";
   449   static const char signature[] = "(Ljava/lang/String;[Ljava/lang/String;Ljava/lang/Long;"
   450     "Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/String;"
   451     "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Boolean;Ljava/lang/Boolean;)Ljava/lang/String;";
   453   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
   454   execute_args.set_receiver(h_dcmd_instance);
   456   // arguments
   457   execute_args.push_jobject(name);
   458   execute_args.push_jobject(settings);
   459   execute_args.push_jobject(delay);
   460   execute_args.push_jobject(duration);
   461   execute_args.push_jobject(disk);
   462   execute_args.push_jobject(filename);
   463   execute_args.push_jobject(maxage);
   464   execute_args.push_jobject(maxsize);
   465   execute_args.push_jobject(dump_on_exit);
   466   execute_args.push_jobject(path_to_gc_roots);
   468   JfrJavaSupport::call_virtual(&execute_args, THREAD);
   469   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
   470 }
   472 JfrStopFlightRecordingDCmd::JfrStopFlightRecordingDCmd(outputStream* output,
   473                                                        bool heap) : DCmdWithParser(output, heap),
   474   _name("name", "Recording text,.e.g \\\"My Recording\\\"", "STRING", true, NULL),
   475   _filename("filename", "Copy recording data to file, e.g. \\\"" JFR_FILENAME_EXAMPLE "\\\"", "STRING", false, NULL) {
   476   _dcmdparser.add_dcmd_option(&_name);
   477   _dcmdparser.add_dcmd_option(&_filename);
   478 };
   480 int JfrStopFlightRecordingDCmd::num_arguments() {
   481   ResourceMark rm;
   482   JfrStopFlightRecordingDCmd* dcmd = new JfrStopFlightRecordingDCmd(NULL, false);
   483   if (dcmd != NULL) {
   484     DCmdMark mark(dcmd);
   485     return dcmd->_dcmdparser.num_arguments();
   486   }
   487   return 0;
   488 }
   490 void JfrStopFlightRecordingDCmd::execute(DCmdSource source, TRAPS) {
   491   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   493   if (invalid_state(output(), THREAD) || !is_recorder_instance_created(output())) {
   494     return;
   495   }
   497   ResourceMark rm(THREAD);
   498   HandleMark hm(THREAD);
   499   JNIHandleBlockManager jni_handle_management(THREAD);
   501   JavaValue result(T_OBJECT);
   502   JfrJavaArguments constructor_args(&result);
   503   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdStop", CHECK);
   504   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
   505   Handle h_dcmd_instance(THREAD, dcmd);
   506   assert(h_dcmd_instance.not_null(), "invariant");
   508   jstring name = NULL;
   509   if (_name.is_set() && _name.value()  != NULL) {
   510     name = JfrJavaSupport::new_string(_name.value(), CHECK);
   511   }
   513   jstring filepath = NULL;
   514   if (_filename.is_set() && _filename.value() != NULL) {
   515     filepath = JfrJavaSupport::new_string(_filename.value(), CHECK);
   516   }
   518   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdStop";
   519   static const char method[] = "execute";
   520   static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;";
   522   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
   523   execute_args.set_receiver(h_dcmd_instance);
   525   // arguments
   526   execute_args.push_jobject(name);
   527   execute_args.push_jobject(filepath);
   529   JfrJavaSupport::call_virtual(&execute_args, THREAD);
   530   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
   531 }
   533 JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* output,
   534                                                                bool heap) : DCmdWithParser(output, heap),
   535   _repository_path("repositorypath", "Path to repository,.e.g \\\"My Repository\\\"", "STRING", false, NULL),
   536   _dump_path("dumppath", "Path to dump,.e.g \\\"My Dump path\\\"", "STRING", false, NULL),
   537   _stack_depth("stackdepth", "Stack Depth", "JULONG", false, "64"),
   538   _global_buffer_count("globalbuffercount", "Number of global buffers,", "JULONG", false, "20"),
   539   _global_buffer_size("globalbuffersize", "Size of a global buffers,", "MEMORY SIZE", false, "512k"),
   540   _thread_buffer_size("thread_buffer_size", "Size of a thread buffer", "MEMORY SIZE", false, "8k"),
   541   _memory_size("memorysize", "Overall memory size, ", "MEMORY SIZE", false, "10m"),
   542   _max_chunk_size("maxchunksize", "Size of an individual disk chunk", "MEMORY SIZE", false, "12m"),
   543   _sample_threads("samplethreads", "Activate Thread sampling", "BOOLEAN", false, "true") {
   544   _dcmdparser.add_dcmd_option(&_repository_path);
   545   _dcmdparser.add_dcmd_option(&_dump_path);
   546   _dcmdparser.add_dcmd_option(&_stack_depth);
   547   _dcmdparser.add_dcmd_option(&_global_buffer_count);
   548   _dcmdparser.add_dcmd_option(&_global_buffer_size);
   549   _dcmdparser.add_dcmd_option(&_thread_buffer_size);
   550   _dcmdparser.add_dcmd_option(&_memory_size);
   551   _dcmdparser.add_dcmd_option(&_max_chunk_size);
   552   _dcmdparser.add_dcmd_option(&_sample_threads);
   553 };
   555 int JfrConfigureFlightRecorderDCmd::num_arguments() {
   556   ResourceMark rm;
   557   JfrConfigureFlightRecorderDCmd* dcmd = new JfrConfigureFlightRecorderDCmd(NULL, false);
   558   if (dcmd != NULL) {
   559     DCmdMark mark(dcmd);
   560     return dcmd->_dcmdparser.num_arguments();
   561   }
   562   return 0;
   563 }
   565 void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
   566   DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
   568   if (invalid_state(output(), THREAD)) {
   569     return;
   570   }
   572   ResourceMark rm(THREAD);
   573   HandleMark hm(THREAD);
   574   JNIHandleBlockManager jni_handle_management(THREAD);
   576   JavaValue result(T_OBJECT);
   577   JfrJavaArguments constructor_args(&result);
   578   constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdConfigure", CHECK);
   579   const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
   580   Handle h_dcmd_instance(THREAD, dcmd);
   581   assert(h_dcmd_instance.not_null(), "invariant");
   583   jstring repository_path = NULL;
   584   if (_repository_path.is_set() && _repository_path.value() != NULL) {
   585     repository_path = JfrJavaSupport::new_string(_repository_path.value(), CHECK);
   586   }
   588   jstring dump_path = NULL;
   589   if (_dump_path.is_set() && _dump_path.value() != NULL) {
   590     dump_path = JfrJavaSupport::new_string(_dump_path.value(), CHECK);
   591   }
   593   jobject stack_depth = NULL;
   594   if (_stack_depth.is_set()) {
   595     stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK);
   596   }
   598   jobject global_buffer_count = NULL;
   599   if (_global_buffer_count.is_set()) {
   600     global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK);
   601   }
   603   jobject global_buffer_size = NULL;
   604   if (_global_buffer_size.is_set()) {
   605     global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value()._size, CHECK);
   606   }
   608   jobject thread_buffer_size = NULL;
   609   if (_thread_buffer_size.is_set()) {
   610     thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value()._size, CHECK);
   611   }
   613   jobject max_chunk_size = NULL;
   614   if (_max_chunk_size.is_set()) {
   615     max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value()._size, CHECK);
   616   }
   618   jobject memory_size = NULL;
   619   if (_memory_size.is_set()) {
   620     memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value()._size, CHECK);
   621   }
   623   jobject sample_threads = NULL;
   624   if (_sample_threads.is_set()) {
   625     sample_threads = JfrJavaSupport::new_java_lang_Boolean(_sample_threads.value(), CHECK);
   626   }
   628   static const char klass[] = "jdk/jfr/internal/dcmd/DCmdConfigure";
   629   static const char method[] = "execute";
   630   static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/Integer;"
   631     "Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
   632     "Ljava/lang/Long;Ljava/lang/Boolean;)Ljava/lang/String;";
   634   JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
   635   execute_args.set_receiver(h_dcmd_instance);
   637   // params
   638   execute_args.push_jobject(repository_path);
   639   execute_args.push_jobject(dump_path);
   640   execute_args.push_jobject(stack_depth);
   641   execute_args.push_jobject(global_buffer_count);
   642   execute_args.push_jobject(global_buffer_size);
   643   execute_args.push_jobject(thread_buffer_size);
   644   execute_args.push_jobject(memory_size);
   645   execute_args.push_jobject(max_chunk_size);
   646   execute_args.push_jobject(sample_threads);
   648   JfrJavaSupport::call_virtual(&execute_args, THREAD);
   649   handle_dcmd_result(output(), (oop)result.get_jobject(), source, THREAD);
   650 }
   652 bool register_jfr_dcmds() {
   653   uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
   654   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export, true, false));
   655   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export, true, false));
   656   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export, true, false));
   657   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export, true, false));
   658   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export, true, false));
   660   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrUnlockCommercialFeaturesDCmd>(full_export, true, false));
   661   return true;
   662 }

mercurial