Wed, 14 Dec 2011 04:30:57 -0800
7104647: Adding a diagnostic command framework
Reviewed-by: phh, dcubed
fparain@3329 | 1 | /* |
fparain@3329 | 2 | * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. |
fparain@3329 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
fparain@3329 | 4 | * |
fparain@3329 | 5 | * This code is free software; you can redistribute it and/or modify it |
fparain@3329 | 6 | * under the terms of the GNU General Public License version 2 only, as |
fparain@3329 | 7 | * published by the Free Software Foundation. |
fparain@3329 | 8 | * |
fparain@3329 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
fparain@3329 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
fparain@3329 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
fparain@3329 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
fparain@3329 | 13 | * accompanied this code). |
fparain@3329 | 14 | * |
fparain@3329 | 15 | * You should have received a copy of the GNU General Public License version |
fparain@3329 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
fparain@3329 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
fparain@3329 | 18 | * |
fparain@3329 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
fparain@3329 | 20 | * or visit www.oracle.com if you need additional information or have any |
fparain@3329 | 21 | * questions. |
fparain@3329 | 22 | * |
fparain@3329 | 23 | */ |
fparain@3329 | 24 | |
fparain@3329 | 25 | #include "precompiled.hpp" |
fparain@3329 | 26 | #include "memory/oopFactory.hpp" |
fparain@3329 | 27 | #include "runtime/javaCalls.hpp" |
fparain@3329 | 28 | #include "runtime/mutexLocker.hpp" |
fparain@3329 | 29 | #include "services/diagnosticArgument.hpp" |
fparain@3329 | 30 | #include "services/diagnosticFramework.hpp" |
fparain@3329 | 31 | #include "services/management.hpp" |
fparain@3329 | 32 | |
fparain@3329 | 33 | CmdLine::CmdLine(const char* line, size_t len, bool no_command_name) { |
fparain@3329 | 34 | assert(line != NULL, "Command line string should not be NULL"); |
fparain@3329 | 35 | const char* line_end; |
fparain@3329 | 36 | const char* cmd_end; |
fparain@3329 | 37 | |
fparain@3329 | 38 | _cmd = line; |
fparain@3329 | 39 | line_end = &line[len]; |
fparain@3329 | 40 | |
fparain@3329 | 41 | // Skip whitespace in the beginning of the line. |
fparain@3329 | 42 | while (_cmd < line_end && isspace((int) _cmd[0])) { |
fparain@3329 | 43 | _cmd++; |
fparain@3329 | 44 | } |
fparain@3329 | 45 | cmd_end = _cmd; |
fparain@3329 | 46 | |
fparain@3329 | 47 | if (no_command_name) { |
fparain@3329 | 48 | _cmd = NULL; |
fparain@3329 | 49 | _cmd_len = 0; |
fparain@3329 | 50 | } else { |
fparain@3329 | 51 | // Look for end of the command name |
fparain@3329 | 52 | while (cmd_end < line_end && !isspace((int) cmd_end[0])) { |
fparain@3329 | 53 | cmd_end++; |
fparain@3329 | 54 | } |
fparain@3329 | 55 | _cmd_len = cmd_end - _cmd; |
fparain@3329 | 56 | } |
fparain@3329 | 57 | _args = cmd_end; |
fparain@3329 | 58 | _args_len = line_end - _args; |
fparain@3329 | 59 | } |
fparain@3329 | 60 | |
fparain@3329 | 61 | bool DCmdArgIter::next(TRAPS) { |
fparain@3329 | 62 | if (_len == 0) return false; |
fparain@3329 | 63 | // skipping spaces |
fparain@3329 | 64 | while (_cursor < _len - 1 && isspace(_buffer[_cursor])) { |
fparain@3329 | 65 | _cursor++; |
fparain@3329 | 66 | } |
fparain@3329 | 67 | // handling end of command line |
fparain@3329 | 68 | if (_cursor >= _len - 1) { |
fparain@3329 | 69 | _cursor = _len - 1; |
fparain@3329 | 70 | _key_addr = &_buffer[_len - 1]; |
fparain@3329 | 71 | _key_len = 0; |
fparain@3329 | 72 | _value_addr = &_buffer[_len - 1]; |
fparain@3329 | 73 | _value_len = 0; |
fparain@3329 | 74 | return false; |
fparain@3329 | 75 | } |
fparain@3329 | 76 | // extracting first item, argument or option name |
fparain@3329 | 77 | _key_addr = &_buffer[_cursor]; |
fparain@3329 | 78 | while (_cursor <= _len - 1 && _buffer[_cursor] != '=' && _buffer[_cursor] != _delim) { |
fparain@3329 | 79 | // argument can be surrounded by single or double quotes |
fparain@3329 | 80 | if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') { |
fparain@3329 | 81 | _key_addr++; |
fparain@3329 | 82 | char quote = _buffer[_cursor]; |
fparain@3329 | 83 | while (_cursor < _len - 1) { |
fparain@3329 | 84 | _cursor++; |
fparain@3329 | 85 | if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') { |
fparain@3329 | 86 | break; |
fparain@3329 | 87 | } |
fparain@3329 | 88 | } |
fparain@3329 | 89 | if (_buffer[_cursor] != quote) { |
fparain@3329 | 90 | THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 91 | "Format error in diagnostic command arguments", false); |
fparain@3329 | 92 | } |
fparain@3329 | 93 | break; |
fparain@3329 | 94 | } |
fparain@3329 | 95 | _cursor++; |
fparain@3329 | 96 | } |
fparain@3329 | 97 | _key_len = &_buffer[_cursor] - _key_addr; |
fparain@3329 | 98 | // check if the argument has the <key>=<value> format |
fparain@3329 | 99 | if (_cursor <= _len -1 && _buffer[_cursor] == '=') { |
fparain@3329 | 100 | _cursor++; |
fparain@3329 | 101 | _value_addr = &_buffer[_cursor]; |
fparain@3329 | 102 | // extract the value |
fparain@3329 | 103 | while (_cursor <= _len - 1 && _buffer[_cursor] != _delim) { |
fparain@3329 | 104 | // value can be surrounded by simple or double quotes |
fparain@3329 | 105 | if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') { |
fparain@3329 | 106 | _value_addr++; |
fparain@3329 | 107 | char quote = _buffer[_cursor]; |
fparain@3329 | 108 | while (_cursor < _len - 1) { |
fparain@3329 | 109 | _cursor++; |
fparain@3329 | 110 | if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') { |
fparain@3329 | 111 | break; |
fparain@3329 | 112 | } |
fparain@3329 | 113 | } |
fparain@3329 | 114 | if (_buffer[_cursor] != quote) { |
fparain@3329 | 115 | THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 116 | "Format error in diagnostic command arguments", false); |
fparain@3329 | 117 | } |
fparain@3329 | 118 | break; |
fparain@3329 | 119 | } |
fparain@3329 | 120 | _cursor++; |
fparain@3329 | 121 | } |
fparain@3329 | 122 | _value_len = &_buffer[_cursor] - _value_addr; |
fparain@3329 | 123 | } else { |
fparain@3329 | 124 | _value_addr = NULL; |
fparain@3329 | 125 | _value_len = 0; |
fparain@3329 | 126 | } |
fparain@3329 | 127 | return _key_len != 0; |
fparain@3329 | 128 | } |
fparain@3329 | 129 | |
fparain@3329 | 130 | bool DCmdInfo::by_name(void* cmd_name, DCmdInfo* info) { |
fparain@3329 | 131 | if (info == NULL) return false; |
fparain@3329 | 132 | return strcmp((const char*)cmd_name, info->name()) == 0; |
fparain@3329 | 133 | } |
fparain@3329 | 134 | |
fparain@3329 | 135 | void DCmdParser::add_dcmd_option(GenDCmdArgument* arg) { |
fparain@3329 | 136 | assert(arg != NULL, "Sanity"); |
fparain@3329 | 137 | if (_options == NULL) { |
fparain@3329 | 138 | _options = arg; |
fparain@3329 | 139 | } else { |
fparain@3329 | 140 | GenDCmdArgument* o = _options; |
fparain@3329 | 141 | while (o->next() != NULL) { |
fparain@3329 | 142 | o = o->next(); |
fparain@3329 | 143 | } |
fparain@3329 | 144 | o->set_next(arg); |
fparain@3329 | 145 | } |
fparain@3329 | 146 | arg->set_next(NULL); |
fparain@3329 | 147 | Thread* THREAD = Thread::current(); |
fparain@3329 | 148 | arg->init_value(THREAD); |
fparain@3329 | 149 | if (HAS_PENDING_EXCEPTION) { |
fparain@3329 | 150 | fatal("Initialization must be successful"); |
fparain@3329 | 151 | } |
fparain@3329 | 152 | } |
fparain@3329 | 153 | |
fparain@3329 | 154 | void DCmdParser::add_dcmd_argument(GenDCmdArgument* arg) { |
fparain@3329 | 155 | assert(arg != NULL, "Sanity"); |
fparain@3329 | 156 | if (_arguments_list == NULL) { |
fparain@3329 | 157 | _arguments_list = arg; |
fparain@3329 | 158 | } else { |
fparain@3329 | 159 | GenDCmdArgument* a = _arguments_list; |
fparain@3329 | 160 | while (a->next() != NULL) { |
fparain@3329 | 161 | a = a->next(); |
fparain@3329 | 162 | } |
fparain@3329 | 163 | a->set_next(arg); |
fparain@3329 | 164 | } |
fparain@3329 | 165 | arg->set_next(NULL); |
fparain@3329 | 166 | Thread* THREAD = Thread::current(); |
fparain@3329 | 167 | arg->init_value(THREAD); |
fparain@3329 | 168 | if (HAS_PENDING_EXCEPTION) { |
fparain@3329 | 169 | fatal("Initialization must be successful"); |
fparain@3329 | 170 | } |
fparain@3329 | 171 | } |
fparain@3329 | 172 | |
fparain@3329 | 173 | void DCmdParser::parse(CmdLine* line, char delim, TRAPS) { |
fparain@3329 | 174 | GenDCmdArgument* next_argument = _arguments_list; |
fparain@3329 | 175 | DCmdArgIter iter(line->args_addr(), line->args_len(), delim); |
fparain@3329 | 176 | bool cont = iter.next(CHECK); |
fparain@3329 | 177 | while (cont) { |
fparain@3329 | 178 | GenDCmdArgument* arg = lookup_dcmd_option(iter.key_addr(), |
fparain@3329 | 179 | iter.key_length()); |
fparain@3329 | 180 | if (arg != NULL) { |
fparain@3329 | 181 | arg->read_value(iter.value_addr(), iter.value_length(), CHECK); |
fparain@3329 | 182 | } else { |
fparain@3329 | 183 | if (next_argument != NULL) { |
fparain@3329 | 184 | arg = next_argument; |
fparain@3329 | 185 | arg->read_value(iter.key_addr(), iter.key_length(), CHECK); |
fparain@3329 | 186 | next_argument = next_argument->next(); |
fparain@3329 | 187 | } else { |
fparain@3329 | 188 | THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 189 | "Unknown argument in diagnostic command"); |
fparain@3329 | 190 | } |
fparain@3329 | 191 | } |
fparain@3329 | 192 | cont = iter.next(CHECK); |
fparain@3329 | 193 | } |
fparain@3329 | 194 | check(CHECK); |
fparain@3329 | 195 | } |
fparain@3329 | 196 | |
fparain@3329 | 197 | GenDCmdArgument* DCmdParser::lookup_dcmd_option(const char* name, size_t len) { |
fparain@3329 | 198 | GenDCmdArgument* arg = _options; |
fparain@3329 | 199 | while (arg != NULL) { |
fparain@3329 | 200 | if (strlen(arg->name()) == len && |
fparain@3329 | 201 | strncmp(name, arg->name(), len) == 0) { |
fparain@3329 | 202 | return arg; |
fparain@3329 | 203 | } |
fparain@3329 | 204 | arg = arg->next(); |
fparain@3329 | 205 | } |
fparain@3329 | 206 | return NULL; |
fparain@3329 | 207 | } |
fparain@3329 | 208 | |
fparain@3329 | 209 | void DCmdParser::check(TRAPS) { |
fparain@3329 | 210 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 211 | while (arg != NULL) { |
fparain@3329 | 212 | if (arg->is_mandatory() && !arg->has_value()) { |
fparain@3329 | 213 | THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 214 | "Missing argument for diagnostic command"); |
fparain@3329 | 215 | } |
fparain@3329 | 216 | arg = arg->next(); |
fparain@3329 | 217 | } |
fparain@3329 | 218 | arg = _options; |
fparain@3329 | 219 | while (arg != NULL) { |
fparain@3329 | 220 | if (arg->is_mandatory() && !arg->has_value()) { |
fparain@3329 | 221 | THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 222 | "Missing option for diagnostic command"); |
fparain@3329 | 223 | } |
fparain@3329 | 224 | arg = arg->next(); |
fparain@3329 | 225 | } |
fparain@3329 | 226 | } |
fparain@3329 | 227 | |
fparain@3329 | 228 | void DCmdParser::print_help(outputStream* out, const char* cmd_name) { |
fparain@3329 | 229 | out->print("\nSyntax : %s %s", cmd_name, _options == NULL ? "" : "[options]"); |
fparain@3329 | 230 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 231 | while (arg != NULL) { |
fparain@3329 | 232 | if (arg->is_mandatory()) { |
fparain@3329 | 233 | out->print(" <%s>", arg->name()); |
fparain@3329 | 234 | } else { |
fparain@3329 | 235 | out->print(" [<%s>]", arg->name()); |
fparain@3329 | 236 | } |
fparain@3329 | 237 | arg = arg->next(); |
fparain@3329 | 238 | } |
fparain@3329 | 239 | out->print_cr(""); |
fparain@3329 | 240 | if (_arguments_list != NULL) { |
fparain@3329 | 241 | out->print_cr("\nArguments:"); |
fparain@3329 | 242 | arg = _arguments_list; |
fparain@3329 | 243 | while (arg != NULL) { |
fparain@3329 | 244 | out->print("\t%s : %s %s (%s, ", arg->name(), |
fparain@3329 | 245 | arg->is_mandatory() ? "" : "[optional]", |
fparain@3329 | 246 | arg->description(), arg->type()); |
fparain@3329 | 247 | if (arg->has_default()) { |
fparain@3329 | 248 | out->print(arg->default_string()); |
fparain@3329 | 249 | } else { |
fparain@3329 | 250 | out->print("no default value"); |
fparain@3329 | 251 | } |
fparain@3329 | 252 | out->print_cr(")"); |
fparain@3329 | 253 | arg = arg->next(); |
fparain@3329 | 254 | } |
fparain@3329 | 255 | } |
fparain@3329 | 256 | if (_options != NULL) { |
fparain@3329 | 257 | out->print_cr("\nOptions: (options must be specified using the <key> or <key>=<value> syntax)"); |
fparain@3329 | 258 | arg = _options; |
fparain@3329 | 259 | while (arg != NULL) { |
fparain@3329 | 260 | out->print("\t%s : %s %s (%s, ", arg->name(), |
fparain@3329 | 261 | arg->is_mandatory() ? "" : "[optional]", |
fparain@3329 | 262 | arg->description(), arg->type()); |
fparain@3329 | 263 | if (arg->has_default()) { |
fparain@3329 | 264 | out->print(arg->default_string()); |
fparain@3329 | 265 | } else { |
fparain@3329 | 266 | out->print("no default value"); |
fparain@3329 | 267 | } |
fparain@3329 | 268 | out->print_cr(")"); |
fparain@3329 | 269 | arg = arg->next(); |
fparain@3329 | 270 | } |
fparain@3329 | 271 | } |
fparain@3329 | 272 | } |
fparain@3329 | 273 | |
fparain@3329 | 274 | void DCmdParser::reset(TRAPS) { |
fparain@3329 | 275 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 276 | while (arg != NULL) { |
fparain@3329 | 277 | arg->reset(CHECK); |
fparain@3329 | 278 | arg = arg->next(); |
fparain@3329 | 279 | } |
fparain@3329 | 280 | arg = _options; |
fparain@3329 | 281 | while (arg != NULL) { |
fparain@3329 | 282 | arg->reset(CHECK); |
fparain@3329 | 283 | arg = arg->next(); |
fparain@3329 | 284 | } |
fparain@3329 | 285 | } |
fparain@3329 | 286 | |
fparain@3329 | 287 | void DCmdParser::cleanup() { |
fparain@3329 | 288 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 289 | while (arg != NULL) { |
fparain@3329 | 290 | arg->cleanup(); |
fparain@3329 | 291 | arg = arg->next(); |
fparain@3329 | 292 | } |
fparain@3329 | 293 | arg = _options; |
fparain@3329 | 294 | while (arg != NULL) { |
fparain@3329 | 295 | arg->cleanup(); |
fparain@3329 | 296 | arg = arg->next(); |
fparain@3329 | 297 | } |
fparain@3329 | 298 | } |
fparain@3329 | 299 | |
fparain@3329 | 300 | int DCmdParser::num_arguments() { |
fparain@3329 | 301 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 302 | int count = 0; |
fparain@3329 | 303 | while (arg != NULL) { |
fparain@3329 | 304 | count++; |
fparain@3329 | 305 | arg = arg->next(); |
fparain@3329 | 306 | } |
fparain@3329 | 307 | arg = _options; |
fparain@3329 | 308 | while (arg != NULL) { |
fparain@3329 | 309 | count++; |
fparain@3329 | 310 | arg = arg->next(); |
fparain@3329 | 311 | } |
fparain@3329 | 312 | return count; |
fparain@3329 | 313 | } |
fparain@3329 | 314 | |
fparain@3329 | 315 | GrowableArray<const char *>* DCmdParser::argument_name_array() { |
fparain@3329 | 316 | int count = num_arguments(); |
fparain@3329 | 317 | GrowableArray<const char *>* array = new GrowableArray<const char *>(count); |
fparain@3329 | 318 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 319 | while (arg != NULL) { |
fparain@3329 | 320 | array->append(arg->name()); |
fparain@3329 | 321 | arg = arg->next(); |
fparain@3329 | 322 | } |
fparain@3329 | 323 | arg = _options; |
fparain@3329 | 324 | while (arg != NULL) { |
fparain@3329 | 325 | array->append(arg->name()); |
fparain@3329 | 326 | arg = arg->next(); |
fparain@3329 | 327 | } |
fparain@3329 | 328 | return array; |
fparain@3329 | 329 | } |
fparain@3329 | 330 | |
fparain@3329 | 331 | GrowableArray<DCmdArgumentInfo*>* DCmdParser::argument_info_array() { |
fparain@3329 | 332 | int count = num_arguments(); |
fparain@3329 | 333 | GrowableArray<DCmdArgumentInfo*>* array = new GrowableArray<DCmdArgumentInfo *>(count); |
fparain@3329 | 334 | int idx = 0; |
fparain@3329 | 335 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 336 | while (arg != NULL) { |
fparain@3329 | 337 | array->append(new DCmdArgumentInfo(arg->name(), arg->description(), |
fparain@3329 | 338 | arg->type(), arg->default_string(), arg->is_mandatory(), |
fparain@3329 | 339 | false, idx)); |
fparain@3329 | 340 | idx++; |
fparain@3329 | 341 | arg = arg->next(); |
fparain@3329 | 342 | } |
fparain@3329 | 343 | arg = _options; |
fparain@3329 | 344 | while (arg != NULL) { |
fparain@3329 | 345 | array->append(new DCmdArgumentInfo(arg->name(), arg->description(), |
fparain@3329 | 346 | arg->type(), arg->default_string(), arg->is_mandatory(), |
fparain@3329 | 347 | true)); |
fparain@3329 | 348 | arg = arg->next(); |
fparain@3329 | 349 | } |
fparain@3329 | 350 | return array; |
fparain@3329 | 351 | } |
fparain@3329 | 352 | |
fparain@3329 | 353 | DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL; |
fparain@3329 | 354 | |
fparain@3329 | 355 | void DCmd::parse_and_execute(outputStream* out, const char* cmdline, |
fparain@3329 | 356 | char delim, TRAPS) { |
fparain@3329 | 357 | |
fparain@3329 | 358 | if (cmdline == NULL) return; // Nothing to do! |
fparain@3329 | 359 | DCmdIter iter(cmdline, '\n'); |
fparain@3329 | 360 | |
fparain@3329 | 361 | while (iter.has_next()) { |
fparain@3329 | 362 | CmdLine line = iter.next(); |
fparain@3329 | 363 | if (line.is_stop()) { |
fparain@3329 | 364 | break; |
fparain@3329 | 365 | } |
fparain@3329 | 366 | if (line.is_executable()) { |
fparain@3329 | 367 | DCmd* command = DCmdFactory::create_local_DCmd(line, out, CHECK); |
fparain@3329 | 368 | assert(command != NULL, "command error must be handled before this line"); |
fparain@3329 | 369 | DCmdMark mark(command); |
fparain@3329 | 370 | command->parse(&line, delim, CHECK); |
fparain@3329 | 371 | command->execute(CHECK); |
fparain@3329 | 372 | } |
fparain@3329 | 373 | } |
fparain@3329 | 374 | } |
fparain@3329 | 375 | |
fparain@3329 | 376 | Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true); |
fparain@3329 | 377 | |
fparain@3329 | 378 | DCmdFactory* DCmdFactory::factory(const char* name, size_t len) { |
fparain@3329 | 379 | MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
fparain@3329 | 380 | DCmdFactory* factory = _DCmdFactoryList; |
fparain@3329 | 381 | while (factory != NULL) { |
fparain@3329 | 382 | if (strlen(factory->name()) == len && |
fparain@3329 | 383 | strncmp(name, factory->name(), len) == 0) { |
fparain@3329 | 384 | return factory; |
fparain@3329 | 385 | } |
fparain@3329 | 386 | factory = factory->_next; |
fparain@3329 | 387 | } |
fparain@3329 | 388 | return NULL; |
fparain@3329 | 389 | } |
fparain@3329 | 390 | |
fparain@3329 | 391 | int DCmdFactory::register_DCmdFactory(DCmdFactory* factory) { |
fparain@3329 | 392 | MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
fparain@3329 | 393 | factory->_next = _DCmdFactoryList; |
fparain@3329 | 394 | _DCmdFactoryList = factory; |
fparain@3329 | 395 | return 0; // Actually, there's no checks for duplicates |
fparain@3329 | 396 | } |
fparain@3329 | 397 | |
fparain@3329 | 398 | DCmd* DCmdFactory::create_global_DCmd(CmdLine &line, outputStream* out, TRAPS) { |
fparain@3329 | 399 | DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len()); |
fparain@3329 | 400 | if (f != NULL) { |
fparain@3329 | 401 | if (f->is_enabled()) { |
fparain@3329 | 402 | THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 403 | f->disabled_message()); |
fparain@3329 | 404 | } |
fparain@3329 | 405 | return f->create_Cheap_instance(out); |
fparain@3329 | 406 | } |
fparain@3329 | 407 | THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 408 | "Unknown diagnostic command"); |
fparain@3329 | 409 | } |
fparain@3329 | 410 | |
fparain@3329 | 411 | DCmd* DCmdFactory::create_local_DCmd(CmdLine &line, outputStream* out, TRAPS) { |
fparain@3329 | 412 | DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len()); |
fparain@3329 | 413 | if (f != NULL) { |
fparain@3329 | 414 | if (!f->is_enabled()) { |
fparain@3329 | 415 | THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 416 | f->disabled_message()); |
fparain@3329 | 417 | } |
fparain@3329 | 418 | return f->create_resource_instance(out); |
fparain@3329 | 419 | } |
fparain@3329 | 420 | THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 421 | "Unknown diagnostic command"); |
fparain@3329 | 422 | } |
fparain@3329 | 423 | |
fparain@3329 | 424 | GrowableArray<const char*>* DCmdFactory::DCmd_list() { |
fparain@3329 | 425 | MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
fparain@3329 | 426 | GrowableArray<const char*>* array = new GrowableArray<const char*>(); |
fparain@3329 | 427 | DCmdFactory* factory = _DCmdFactoryList; |
fparain@3329 | 428 | while (factory != NULL) { |
fparain@3329 | 429 | if (!factory->is_hidden()) { |
fparain@3329 | 430 | array->append(factory->name()); |
fparain@3329 | 431 | } |
fparain@3329 | 432 | factory = factory->next(); |
fparain@3329 | 433 | } |
fparain@3329 | 434 | return array; |
fparain@3329 | 435 | } |
fparain@3329 | 436 | |
fparain@3329 | 437 | GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list() { |
fparain@3329 | 438 | MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
fparain@3329 | 439 | GrowableArray<DCmdInfo*>* array = new GrowableArray<DCmdInfo*>(); |
fparain@3329 | 440 | DCmdFactory* factory = _DCmdFactoryList; |
fparain@3329 | 441 | while (factory != NULL) { |
fparain@3329 | 442 | if (!factory->is_hidden()) { |
fparain@3329 | 443 | array->append(new DCmdInfo(factory->name(), |
fparain@3329 | 444 | factory->description(), factory->impact(), |
fparain@3329 | 445 | factory->num_arguments(), factory->is_enabled())); |
fparain@3329 | 446 | } |
fparain@3329 | 447 | factory = factory->next(); |
fparain@3329 | 448 | } |
fparain@3329 | 449 | return array; |
fparain@3329 | 450 | } |