@@ -154,19 +154,19 @@ static void print_message(outputStream* output, oop content, TRAPS) {
154154}
155155
156156static 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);
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 ;
169167 }
168+ msg.info (" %s" , text);
169+ }
170170}
171171
172172static void handle_dcmd_result (outputStream* output,
@@ -215,6 +215,8 @@ static oop construct_dcmd_instance(JfrJavaArguments* args, TRAPS) {
215215 return args->result ()->get_oop ();
216216}
217217
218+ JfrDCmd::JfrDCmd (outputStream* output, bool heap, int num_arguments) : DCmd(output, heap), _args(NULL ), _num_arguments(num_arguments), _delimiter(' \0 ' ) {}
219+
218220void JfrDCmd::invoke (JfrJavaArguments& method, TRAPS) const {
219221 JavaValue constructor_result (T_OBJECT);
220222 JfrJavaArguments constructor_args (&constructor_result);
@@ -274,6 +276,20 @@ void JfrDCmd::print_help(const char* name) const {
274276 handle_dcmd_result (output (), result.get_oop (), DCmd_Source_MBean, thread);
275277}
276278
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+
277293// Since the DcmdFramework does not support dynamically allocated strings,
278294// we keep them in a thread local arena. The arena is reset between invocations.
279295static THREAD_LOCAL Arena* dcmd_arena = NULL ;
@@ -340,16 +356,29 @@ static DCmdArgumentInfo* create_info(oop argument, TRAPS) {
340356GrowableArray<DCmdArgumentInfo*>* JfrDCmd::argument_info_array () const {
341357 static const char signature[] = " ()[Ljdk/jfr/internal/dcmd/Argument;" ;
342358 JavaThread* thread = JavaThread::current ();
359+ GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*>(_num_arguments);
343360 JavaValue result (T_OBJECT);
344361 JfrJavaArguments getArgumentInfos (&result, javaClass (), " getArgumentInfos" , signature, thread);
345362 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+ }
346375 objArrayOop arguments = objArrayOop (result.get_oop ());
347376 assert (arguments != NULL , " invariant" );
348377 assert (arguments->is_array (), " must be array" );
349- GrowableArray<DCmdArgumentInfo*>* const array = new GrowableArray<DCmdArgumentInfo*> ();
350- const int length = arguments-> length ( );
378+ const int num_arguments = arguments-> length ();
379+ assert (num_arguments == _num_arguments, " invariant " );
351380 prepare_dcmd_string_arena ();
352- for (int i = 0 ; i < length ; ++i) {
381+ for (int i = 0 ; i < num_arguments ; ++i) {
353382 DCmdArgumentInfo* const dai = create_info (arguments->obj_at (i), thread);
354383 assert (dai != NULL , " invariant" );
355384 array->append (dai);
0 commit comments