Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/jdk17u
Path: blob/master/src/hotspot/share/jfr/dcmd/jfrDcmds.cpp
66644 views
1
/*
2
* Copyright (c) 2012, 2021, 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.inline.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 "logging/log.hpp"
34
#include "logging/logConfiguration.hpp"
35
#include "logging/logMessage.hpp"
36
#include "memory/arena.hpp"
37
#include "memory/resourceArea.hpp"
38
#include "oops/objArrayOop.inline.hpp"
39
#include "oops/oop.inline.hpp"
40
#include "oops/symbol.hpp"
41
#include "runtime/handles.inline.hpp"
42
#include "runtime/jniHandles.hpp"
43
#include "services/diagnosticArgument.hpp"
44
#include "services/diagnosticFramework.hpp"
45
#include "utilities/globalDefinitions.hpp"
46
47
48
bool register_jfr_dcmds() {
49
uint32_t full_export = DCmd_Source_Internal | DCmd_Source_AttachAPI | DCmd_Source_MBean;
50
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrCheckFlightRecordingDCmd>(full_export, true, false));
51
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrDumpFlightRecordingDCmd>(full_export, true, false));
52
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStartFlightRecordingDCmd>(full_export, true, false));
53
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrStopFlightRecordingDCmd>(full_export, true, false));
54
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JfrConfigureFlightRecorderDCmd>(full_export, true, false));
55
return true;
56
}
57
58
// JNIHandle management
59
60
// ------------------------------------------------------------------
61
// push_jni_handle_block
62
//
63
// Push on a new block of JNI handles.
64
static void push_jni_handle_block(JavaThread* const thread) {
65
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread));
66
67
// Allocate a new block for JNI handles.
68
// Inlined code from jni_PushLocalFrame()
69
JNIHandleBlock* prev_handles = thread->active_handles();
70
JNIHandleBlock* entry_handles = JNIHandleBlock::allocate_block(thread);
71
assert(entry_handles != NULL && prev_handles != NULL, "should not be NULL");
72
entry_handles->set_pop_frame_link(prev_handles); // make sure prev handles get gc'd.
73
thread->set_active_handles(entry_handles);
74
}
75
76
// ------------------------------------------------------------------
77
// pop_jni_handle_block
78
//
79
// Pop off the current block of JNI handles.
80
static void pop_jni_handle_block(JavaThread* const thread) {
81
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread));
82
83
// Release our JNI handle block
84
JNIHandleBlock* entry_handles = thread->active_handles();
85
JNIHandleBlock* prev_handles = entry_handles->pop_frame_link();
86
// restore
87
thread->set_active_handles(prev_handles);
88
entry_handles->set_pop_frame_link(NULL);
89
JNIHandleBlock::release_block(entry_handles, thread); // may block
90
}
91
92
class JNIHandleBlockManager : public StackObj {
93
private:
94
JavaThread* const _thread;
95
public:
96
JNIHandleBlockManager(JavaThread* thread) : _thread(thread) {
97
push_jni_handle_block(_thread);
98
}
99
100
~JNIHandleBlockManager() {
101
pop_jni_handle_block(_thread);
102
}
103
};
104
105
static bool is_module_available(outputStream* output, TRAPS) {
106
return JfrJavaSupport::is_jdk_jfr_module_available(output, THREAD);
107
}
108
109
static bool is_disabled(outputStream* output) {
110
if (Jfr::is_disabled()) {
111
if (output != NULL) {
112
output->print_cr("Flight Recorder is disabled.\n");
113
}
114
return true;
115
}
116
return false;
117
}
118
119
static bool invalid_state(outputStream* out, TRAPS) {
120
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
121
return is_disabled(out) || !is_module_available(out, THREAD);
122
}
123
124
static void handle_pending_exception(outputStream* output, bool startup, oop throwable) {
125
assert(throwable != NULL, "invariant");
126
127
oop msg = java_lang_Throwable::message(throwable);
128
if (msg == NULL) {
129
return;
130
}
131
char* text = java_lang_String::as_utf8_string(msg);
132
if (text != NULL) {
133
if (startup) {
134
log_error(jfr,startup)("%s", text);
135
} else {
136
output->print_cr("%s", text);
137
}
138
}
139
}
140
141
static void print_message(outputStream* output, oop content, TRAPS) {
142
objArrayOop lines = objArrayOop(content);
143
assert(lines != NULL, "invariant");
144
assert(lines->is_array(), "must be array");
145
const int length = lines->length();
146
for (int i = 0; i < length; ++i) {
147
const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
148
if (text == NULL) {
149
// An oome has been thrown and is pending.
150
break;
151
}
152
output->print_cr("%s", text);
153
}
154
}
155
156
static void log(oop content, TRAPS) {
157
LogMessage(jfr,startup) msg;
158
objArrayOop lines = objArrayOop(content);
159
assert(lines != NULL, "invariant");
160
assert(lines->is_array(), "must be array");
161
const int length = lines->length();
162
for (int i = 0; i < length; ++i) {
163
const char* text = JfrJavaSupport::c_str(lines->obj_at(i), THREAD);
164
if (text == NULL) {
165
// An oome has been thrown and is pending.
166
break;
167
}
168
msg.info("%s", text);
169
}
170
}
171
172
static void handle_dcmd_result(outputStream* output,
173
const oop result,
174
const DCmdSource source,
175
TRAPS) {
176
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
177
assert(output != NULL, "invariant");
178
ResourceMark rm(THREAD);
179
const bool startup = DCmd_Source_Internal == source;
180
if (HAS_PENDING_EXCEPTION) {
181
handle_pending_exception(output, startup, PENDING_EXCEPTION);
182
// Don't clear excption on startup, JVM should fail initialization.
183
if (!startup) {
184
CLEAR_PENDING_EXCEPTION;
185
}
186
return;
187
}
188
189
assert(!HAS_PENDING_EXCEPTION, "invariant");
190
191
if (startup) {
192
if (log_is_enabled(Warning, jfr, startup)) {
193
// if warning is set, assume user hasn't configured log level
194
// Log to Info and reset to Warning. This way user can disable
195
// default output by setting -Xlog:jfr+startup=error/off
196
LogConfiguration::configure_stdout(LogLevel::Info, true, LOG_TAGS(jfr, startup));
197
log(result, THREAD);
198
LogConfiguration::configure_stdout(LogLevel::Warning, true, LOG_TAGS(jfr, startup));
199
} else {
200
log(result, THREAD);
201
}
202
} else {
203
// Print output for jcmd or MXBean
204
print_message(output, result, THREAD);
205
}
206
}
207
208
static oop construct_dcmd_instance(JfrJavaArguments* args, TRAPS) {
209
assert(args != NULL, "invariant");
210
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
211
assert(args->klass() != NULL, "invariant");
212
args->set_name("<init>");
213
args->set_signature("()V");
214
JfrJavaSupport::new_object(args, CHECK_NULL);
215
return args->result()->get_oop();
216
}
217
218
JfrDCmd::JfrDCmd(outputStream* output, bool heap, int num_arguments) : DCmd(output, heap), _args(NULL), _num_arguments(num_arguments), _delimiter('\0') {}
219
220
void JfrDCmd::invoke(JfrJavaArguments& method, TRAPS) const {
221
JavaValue constructor_result(T_OBJECT);
222
JfrJavaArguments constructor_args(&constructor_result);
223
constructor_args.set_klass(javaClass(), CHECK);
224
225
HandleMark hm(THREAD);
226
JNIHandleBlockManager jni_handle_management(THREAD);
227
228
const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
229
230
Handle h_dcmd_instance(THREAD, dcmd);
231
assert(h_dcmd_instance.not_null(), "invariant");
232
233
method.set_receiver(h_dcmd_instance);
234
JfrJavaSupport::call_virtual(&method, THREAD);
235
}
236
237
void JfrDCmd::parse(CmdLine* line, char delim, TRAPS) {
238
_args = line->args_addr();
239
_delimiter = delim;
240
// Error checking done in execute.
241
// Will not matter from DCmdFactory perspective
242
// where parse and execute are called consecutively.
243
}
244
245
void JfrDCmd::execute(DCmdSource source, TRAPS) {
246
if (invalid_state(output(), THREAD)) {
247
return;
248
}
249
static const char signature[] = "(Ljava/lang/String;Ljava/lang/String;C)[Ljava/lang/String;";
250
JavaValue result(T_OBJECT);
251
JfrJavaArguments execute(&result, javaClass(), "execute", signature, CHECK);
252
jstring argument = JfrJavaSupport::new_string(_args, CHECK);
253
jstring s = NULL;
254
if (source == DCmd_Source_Internal) {
255
s = JfrJavaSupport::new_string("internal", CHECK);
256
}
257
if (source == DCmd_Source_MBean) {
258
s = JfrJavaSupport::new_string("mbean", CHECK);
259
}
260
if (source == DCmd_Source_AttachAPI) {
261
s = JfrJavaSupport::new_string("attach", CHECK);
262
}
263
execute.push_jobject(s);
264
execute.push_jobject(argument);
265
execute.push_int(_delimiter);
266
invoke(execute, THREAD);
267
handle_dcmd_result(output(), result.get_oop(), source, THREAD);
268
}
269
270
void JfrDCmd::print_help(const char* name) const {
271
static const char signature[] = "()[Ljava/lang/String;";
272
JavaThread* thread = JavaThread::current();
273
JavaValue result(T_OBJECT);
274
JfrJavaArguments printHelp(&result, javaClass(), "printHelp", signature, thread);
275
invoke(printHelp, thread);
276
handle_dcmd_result(output(), result.get_oop(), DCmd_Source_MBean, thread);
277
}
278
279
static void initialize_dummy_descriptors(GrowableArray<DCmdArgumentInfo*>* array) {
280
assert(array != NULL, "invariant");
281
DCmdArgumentInfo * const dummy = new DCmdArgumentInfo(NULL,
282
NULL,
283
NULL,
284
NULL,
285
false,
286
true, // a DcmdFramework "option"
287
false);
288
for (int i = 0; i < array->max_length(); ++i) {
289
array->append(dummy);
290
}
291
}
292
293
// Since the DcmdFramework does not support dynamically allocated strings,
294
// we keep them in a thread local arena. The arena is reset between invocations.
295
static THREAD_LOCAL Arena* dcmd_arena = NULL;
296
297
static void prepare_dcmd_string_arena() {
298
if (dcmd_arena == NULL) {
299
dcmd_arena = new (mtTracing) Arena(mtTracing);
300
} else {
301
dcmd_arena->destruct_contents(); // will grow on next allocation
302
}
303
}
304
305
static char* dcmd_arena_allocate(size_t size) {
306
assert(dcmd_arena != NULL, "invariant");
307
return (char*)dcmd_arena->Amalloc(size);
308
}
309
310
static const char* get_as_dcmd_arena_string(oop string, JavaThread* t) {
311
char* str = NULL;
312
const typeArrayOop value = java_lang_String::value(string);
313
if (value != NULL) {
314
const size_t length = static_cast<size_t>(java_lang_String::utf8_length(string, value)) + 1;
315
str = dcmd_arena_allocate(length);
316
assert(str != NULL, "invariant");
317
java_lang_String::as_utf8_string(string, value, str, static_cast<int>(length));
318
}
319
return str;
320
}
321
322
static const char* read_string_field(oop argument, const char* field_name, TRAPS) {
323
JavaValue result(T_OBJECT);
324
JfrJavaArguments args(&result);
325
args.set_klass(argument->klass());
326
args.set_name(field_name);
327
args.set_signature("Ljava/lang/String;");
328
args.set_receiver(argument);
329
JfrJavaSupport::get_field(&args, THREAD);
330
const oop string_oop = result.get_oop();
331
return string_oop != NULL ? get_as_dcmd_arena_string(string_oop, (JavaThread*)THREAD) : NULL;
332
}
333
334
static bool read_boolean_field(oop argument, const char* field_name, TRAPS) {
335
JavaValue result(T_BOOLEAN);
336
JfrJavaArguments args(&result);
337
args.set_klass(argument->klass());
338
args.set_name(field_name);
339
args.set_signature("Z");
340
args.set_receiver(argument);
341
JfrJavaSupport::get_field(&args, THREAD);
342
return (result.get_jint() & 1) == 1;
343
}
344
345
static DCmdArgumentInfo* create_info(oop argument, TRAPS) {
346
return new DCmdArgumentInfo(
347
read_string_field(argument, "name", THREAD),
348
read_string_field(argument, "description", THREAD),
349
read_string_field(argument, "type", THREAD),
350
read_string_field(argument, "defaultValue", THREAD),
351
read_boolean_field(argument, "mandatory", THREAD),
352
true, // a DcmdFramework "option"
353
read_boolean_field(argument, "allowMultiple", THREAD));
354
}
355
356
GrowableArray<DCmdArgumentInfo*>* JfrDCmd::argument_info_array() const {
357
static const char signature[] = "()[Ljdk/jfr/internal/dcmd/Argument;";
358
JavaThread* thread = JavaThread::current();
359
GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>(_num_arguments);
360
JavaValue result(T_OBJECT);
361
JfrJavaArguments getArgumentInfos(&result, javaClass(), "getArgumentInfos", signature, thread);
362
invoke(getArgumentInfos, thread);
363
if (thread->has_pending_exception()) {
364
// Most likely an OOME, but the DCmdFramework is not the best place to handle it.
365
// We handle it locally by clearing the exception and returning an array with dummy descriptors.
366
// This lets the MBean server initialization routine complete successfully,
367
// but this particular command will have no argument descriptors exposed.
368
// Hence we postpone, or delegate, handling of OOME's to code that is better suited.
369
log_debug(jfr, system)("Exception in DCmd getArgumentInfos");
370
thread->clear_pending_exception();
371
initialize_dummy_descriptors(array);
372
assert(array->length() == _num_arguments, "invariant");
373
return array;
374
}
375
objArrayOop arguments = objArrayOop(result.get_oop());
376
assert(arguments != NULL, "invariant");
377
assert(arguments->is_array(), "must be array");
378
const int num_arguments = arguments->length();
379
assert(num_arguments == _num_arguments, "invariant");
380
prepare_dcmd_string_arena();
381
for (int i = 0; i < num_arguments; ++i) {
382
DCmdArgumentInfo* const dai = create_info(arguments->obj_at(i), thread);
383
assert(dai != NULL, "invariant");
384
array->append(dai);
385
}
386
return array;
387
}
388
389
GrowableArray<const char*>* JfrDCmd::argument_name_array() const {
390
GrowableArray<DCmdArgumentInfo*>* argument_infos = argument_info_array();
391
GrowableArray<const char*>* array = new GrowableArray<const char*>(argument_infos->length());
392
for (int i = 0; i < argument_infos->length(); i++) {
393
array->append(argument_infos->at(i)->name());
394
}
395
return array;
396
}
397
398
JfrConfigureFlightRecorderDCmd::JfrConfigureFlightRecorderDCmd(outputStream* output,
399
bool heap) : DCmdWithParser(output, heap),
400
_repository_path("repositorypath", "Path to repository,.e.g \\\"My Repository\\\"", "STRING", false, NULL),
401
_dump_path("dumppath", "Path to dump,.e.g \\\"My Dump path\\\"", "STRING", false, NULL),
402
_stack_depth("stackdepth", "Stack Depth", "JULONG", false, "64"),
403
_global_buffer_count("globalbuffercount", "Number of global buffers,", "JULONG", false, "20"),
404
_global_buffer_size("globalbuffersize", "Size of a global buffers,", "MEMORY SIZE", false, "512k"),
405
_thread_buffer_size("thread_buffer_size", "Size of a thread buffer", "MEMORY SIZE", false, "8k"),
406
_memory_size("memorysize", "Overall memory size, ", "MEMORY SIZE", false, "10m"),
407
_max_chunk_size("maxchunksize", "Size of an individual disk chunk", "MEMORY SIZE", false, "12m"),
408
_sample_threads("samplethreads", "Activate Thread sampling", "BOOLEAN", false, "true"),
409
_verbose(true) {
410
_dcmdparser.add_dcmd_option(&_repository_path);
411
_dcmdparser.add_dcmd_option(&_dump_path);
412
_dcmdparser.add_dcmd_option(&_stack_depth);
413
_dcmdparser.add_dcmd_option(&_global_buffer_count);
414
_dcmdparser.add_dcmd_option(&_global_buffer_size);
415
_dcmdparser.add_dcmd_option(&_thread_buffer_size);
416
_dcmdparser.add_dcmd_option(&_memory_size);
417
_dcmdparser.add_dcmd_option(&_max_chunk_size);
418
_dcmdparser.add_dcmd_option(&_sample_threads);
419
};
420
421
void JfrConfigureFlightRecorderDCmd::print_help(const char* name) const {
422
outputStream* out = output();
423
// 0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890
424
out->print_cr("Options:");
425
out->print_cr("");
426
out->print_cr(" globalbuffercount (Optional) Number of global buffers. This option is a legacy");
427
out->print_cr(" option: change the memorysize parameter to alter the number of");
428
out->print_cr(" global buffers. This value cannot be changed once JFR has been");
429
out->print_cr(" initalized. (STRING, default determined by the value for");
430
out->print_cr(" memorysize)");
431
out->print_cr("");
432
out->print_cr(" globalbuffersize (Optional) Size of the global buffers, in bytes. This option is a");
433
out->print_cr(" legacy option: change the memorysize parameter to alter the size");
434
out->print_cr(" of the global buffers. This value cannot be changed once JFR has");
435
out->print_cr(" been initalized. (STRING, default determined by the value for");
436
out->print_cr(" memorysize)");
437
out->print_cr("");
438
out->print_cr(" maxchunksize (Optional) Maximum size of an individual data chunk in bytes if");
439
out->print_cr(" one of the following suffixes is not used: 'm' or 'M' for");
440
out->print_cr(" megabytes OR 'g' or 'G' for gigabytes. This value cannot be");
441
out->print_cr(" changed once JFR has been initialized. (STRING, 12M)");
442
out->print_cr("");
443
out->print_cr(" memorysize (Optional) Overall memory size, in bytes if one of the following");
444
out->print_cr(" suffixes is not used: 'm' or 'M' for megabytes OR 'g' or 'G' for");
445
out->print_cr(" gigabytes. This value cannot be changed once JFR has been");
446
out->print_cr(" initialized. (STRING, 10M)");
447
out->print_cr("");
448
out->print_cr(" repositorypath (Optional) Path to the location where recordings are stored until");
449
out->print_cr(" they are written to a permanent file. (STRING, The default");
450
out->print_cr(" location is the temporary directory for the operating system. On");
451
out->print_cr(" Linux operating systems, the temporary directory is /tmp. On");
452
out->print_cr(" Windows, the temporary directory is specified by the TMP");
453
out->print_cr(" environment variable.)");
454
out->print_cr("");
455
out->print_cr(" stackdepth (Optional) Stack depth for stack traces. Setting this value");
456
out->print_cr(" greater than the default of 64 may cause a performance");
457
out->print_cr(" degradation. This value cannot be changed once JFR has been");
458
out->print_cr(" initialized. (LONG, 64)");
459
out->print_cr("");
460
out->print_cr(" thread_buffer_size (Optional) Local buffer size for each thread in bytes if one of");
461
out->print_cr(" the following suffixes is not used: 'k' or 'K' for kilobytes or");
462
out->print_cr(" 'm' or 'M' for megabytes. Overriding this parameter could reduce");
463
out->print_cr(" performance and is not recommended. This value cannot be changed");
464
out->print_cr(" once JFR has been initialized. (STRING, 8k)");
465
out->print_cr("");
466
out->print_cr(" samplethreads (Optional) Flag for activating thread sampling. (BOOLEAN, true)");
467
out->print_cr("");
468
out->print_cr("Options must be specified using the <key> or <key>=<value> syntax.");
469
out->print_cr("");
470
out->print_cr("Example usage:");
471
out->print_cr("");
472
out->print_cr(" $ jcmd <pid> JFR.configure");
473
out->print_cr(" $ jcmd <pid> JFR.configure repositorypath=/temporary");
474
out->print_cr(" $ jcmd <pid> JFR.configure stackdepth=256");
475
out->print_cr(" $ jcmd <pid> JFR.configure memorysize=100M");
476
out->print_cr("");
477
}
478
479
int JfrConfigureFlightRecorderDCmd::num_arguments() {
480
ResourceMark rm;
481
JfrConfigureFlightRecorderDCmd* dcmd = new JfrConfigureFlightRecorderDCmd(NULL, false);
482
if (dcmd != NULL) {
483
DCmdMark mark(dcmd);
484
return dcmd->_dcmdparser.num_arguments();
485
}
486
return 0;
487
}
488
489
void JfrConfigureFlightRecorderDCmd::execute(DCmdSource source, TRAPS) {
490
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(THREAD));
491
492
if (invalid_state(output(), THREAD)) {
493
return;
494
}
495
496
HandleMark hm(THREAD);
497
JNIHandleBlockManager jni_handle_management(THREAD);
498
499
JavaValue result(T_OBJECT);
500
JfrJavaArguments constructor_args(&result);
501
constructor_args.set_klass("jdk/jfr/internal/dcmd/DCmdConfigure", CHECK);
502
const oop dcmd = construct_dcmd_instance(&constructor_args, CHECK);
503
Handle h_dcmd_instance(THREAD, dcmd);
504
assert(h_dcmd_instance.not_null(), "invariant");
505
506
jstring repository_path = NULL;
507
if (_repository_path.is_set() && _repository_path.value() != NULL) {
508
repository_path = JfrJavaSupport::new_string(_repository_path.value(), CHECK);
509
}
510
511
jstring dump_path = NULL;
512
if (_dump_path.is_set() && _dump_path.value() != NULL) {
513
dump_path = JfrJavaSupport::new_string(_dump_path.value(), CHECK);
514
}
515
516
jobject stack_depth = NULL;
517
if (_stack_depth.is_set()) {
518
stack_depth = JfrJavaSupport::new_java_lang_Integer((jint)_stack_depth.value(), CHECK);
519
}
520
521
jobject global_buffer_count = NULL;
522
if (_global_buffer_count.is_set()) {
523
global_buffer_count = JfrJavaSupport::new_java_lang_Long(_global_buffer_count.value(), CHECK);
524
}
525
526
jobject global_buffer_size = NULL;
527
if (_global_buffer_size.is_set()) {
528
global_buffer_size = JfrJavaSupport::new_java_lang_Long(_global_buffer_size.value()._size, CHECK);
529
}
530
531
jobject thread_buffer_size = NULL;
532
if (_thread_buffer_size.is_set()) {
533
thread_buffer_size = JfrJavaSupport::new_java_lang_Long(_thread_buffer_size.value()._size, CHECK);
534
}
535
536
jobject max_chunk_size = NULL;
537
if (_max_chunk_size.is_set()) {
538
max_chunk_size = JfrJavaSupport::new_java_lang_Long(_max_chunk_size.value()._size, CHECK);
539
}
540
541
jobject memory_size = NULL;
542
if (_memory_size.is_set()) {
543
memory_size = JfrJavaSupport::new_java_lang_Long(_memory_size.value()._size, CHECK);
544
}
545
546
jobject sample_threads = NULL;
547
if (_sample_threads.is_set()) {
548
sample_threads = JfrJavaSupport::new_java_lang_Boolean(_sample_threads.value(), CHECK);
549
}
550
551
static const char klass[] = "jdk/jfr/internal/dcmd/DCmdConfigure";
552
static const char method[] = "execute";
553
static const char signature[] = "(ZLjava/lang/String;Ljava/lang/String;Ljava/lang/Integer;"
554
"Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;Ljava/lang/Long;"
555
"Ljava/lang/Long;Ljava/lang/Boolean;)[Ljava/lang/String;";
556
557
JfrJavaArguments execute_args(&result, klass, method, signature, CHECK);
558
execute_args.set_receiver(h_dcmd_instance);
559
560
// params
561
execute_args.push_int(_verbose ? 1 : 0);
562
execute_args.push_jobject(repository_path);
563
execute_args.push_jobject(dump_path);
564
execute_args.push_jobject(stack_depth);
565
execute_args.push_jobject(global_buffer_count);
566
execute_args.push_jobject(global_buffer_size);
567
execute_args.push_jobject(thread_buffer_size);
568
execute_args.push_jobject(memory_size);
569
execute_args.push_jobject(max_chunk_size);
570
execute_args.push_jobject(sample_threads);
571
572
JfrJavaSupport::call_virtual(&execute_args, THREAD);
573
handle_dcmd_result(output(), result.get_oop(), source, THREAD);
574
}
575
576