Sun, 03 Feb 2013 22:28:08 +0400
8002048: Protocol to discovery of manageable Java processes on a network
Summary: Introduce a protocol to discover manageble Java instances across a network subnet, JDP
Reviewed-by: sla, dfuchs
fparain@3329 | 1 | /* |
fparain@3559 | 2 | * Copyright (c) 2011, 2012, 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@3559 | 64 | while (_cursor < _len - 1 && _buffer[_cursor] == _delim) { |
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]; |
sla@3905 | 78 | bool arg_had_quotes = false; |
fparain@3329 | 79 | while (_cursor <= _len - 1 && _buffer[_cursor] != '=' && _buffer[_cursor] != _delim) { |
fparain@3329 | 80 | // argument can be surrounded by single or double quotes |
fparain@3329 | 81 | if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') { |
fparain@3329 | 82 | _key_addr++; |
fparain@3329 | 83 | char quote = _buffer[_cursor]; |
sla@3905 | 84 | arg_had_quotes = true; |
fparain@3329 | 85 | while (_cursor < _len - 1) { |
fparain@3329 | 86 | _cursor++; |
fparain@3329 | 87 | if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') { |
fparain@3329 | 88 | break; |
fparain@3329 | 89 | } |
fparain@3329 | 90 | } |
fparain@3329 | 91 | if (_buffer[_cursor] != quote) { |
fparain@3329 | 92 | THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 93 | "Format error in diagnostic command arguments", false); |
fparain@3329 | 94 | } |
fparain@3329 | 95 | break; |
fparain@3329 | 96 | } |
fparain@3329 | 97 | _cursor++; |
fparain@3329 | 98 | } |
fparain@3329 | 99 | _key_len = &_buffer[_cursor] - _key_addr; |
sla@3905 | 100 | if (arg_had_quotes) { |
sla@3905 | 101 | // if the argument was quoted, we need to step past the last quote here |
sla@3905 | 102 | _cursor++; |
sla@3905 | 103 | } |
fparain@3329 | 104 | // check if the argument has the <key>=<value> format |
fparain@3329 | 105 | if (_cursor <= _len -1 && _buffer[_cursor] == '=') { |
fparain@3329 | 106 | _cursor++; |
fparain@3329 | 107 | _value_addr = &_buffer[_cursor]; |
sla@3905 | 108 | bool value_had_quotes = false; |
fparain@3329 | 109 | // extract the value |
fparain@3329 | 110 | while (_cursor <= _len - 1 && _buffer[_cursor] != _delim) { |
fparain@3329 | 111 | // value can be surrounded by simple or double quotes |
fparain@3329 | 112 | if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') { |
fparain@3329 | 113 | _value_addr++; |
fparain@3329 | 114 | char quote = _buffer[_cursor]; |
sla@3905 | 115 | value_had_quotes = true; |
fparain@3329 | 116 | while (_cursor < _len - 1) { |
fparain@3329 | 117 | _cursor++; |
fparain@3329 | 118 | if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') { |
fparain@3329 | 119 | break; |
fparain@3329 | 120 | } |
fparain@3329 | 121 | } |
fparain@3329 | 122 | if (_buffer[_cursor] != quote) { |
fparain@3329 | 123 | THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 124 | "Format error in diagnostic command arguments", false); |
fparain@3329 | 125 | } |
fparain@3329 | 126 | break; |
fparain@3329 | 127 | } |
fparain@3329 | 128 | _cursor++; |
fparain@3329 | 129 | } |
fparain@3329 | 130 | _value_len = &_buffer[_cursor] - _value_addr; |
sla@3905 | 131 | if (value_had_quotes) { |
sla@3905 | 132 | // if the value was quoted, we need to step past the last quote here |
sla@3905 | 133 | _cursor++; |
sla@3905 | 134 | } |
fparain@3329 | 135 | } else { |
fparain@3329 | 136 | _value_addr = NULL; |
fparain@3329 | 137 | _value_len = 0; |
fparain@3329 | 138 | } |
fparain@3329 | 139 | return _key_len != 0; |
fparain@3329 | 140 | } |
fparain@3329 | 141 | |
fparain@3329 | 142 | bool DCmdInfo::by_name(void* cmd_name, DCmdInfo* info) { |
fparain@3329 | 143 | if (info == NULL) return false; |
fparain@3329 | 144 | return strcmp((const char*)cmd_name, info->name()) == 0; |
fparain@3329 | 145 | } |
fparain@3329 | 146 | |
fparain@3329 | 147 | void DCmdParser::add_dcmd_option(GenDCmdArgument* arg) { |
fparain@3329 | 148 | assert(arg != NULL, "Sanity"); |
fparain@3329 | 149 | if (_options == NULL) { |
fparain@3329 | 150 | _options = arg; |
fparain@3329 | 151 | } else { |
fparain@3329 | 152 | GenDCmdArgument* o = _options; |
fparain@3329 | 153 | while (o->next() != NULL) { |
fparain@3329 | 154 | o = o->next(); |
fparain@3329 | 155 | } |
fparain@3329 | 156 | o->set_next(arg); |
fparain@3329 | 157 | } |
fparain@3329 | 158 | arg->set_next(NULL); |
fparain@3329 | 159 | Thread* THREAD = Thread::current(); |
fparain@3329 | 160 | arg->init_value(THREAD); |
fparain@3329 | 161 | if (HAS_PENDING_EXCEPTION) { |
fparain@3329 | 162 | fatal("Initialization must be successful"); |
fparain@3329 | 163 | } |
fparain@3329 | 164 | } |
fparain@3329 | 165 | |
fparain@3329 | 166 | void DCmdParser::add_dcmd_argument(GenDCmdArgument* arg) { |
fparain@3329 | 167 | assert(arg != NULL, "Sanity"); |
fparain@3329 | 168 | if (_arguments_list == NULL) { |
fparain@3329 | 169 | _arguments_list = arg; |
fparain@3329 | 170 | } else { |
fparain@3329 | 171 | GenDCmdArgument* a = _arguments_list; |
fparain@3329 | 172 | while (a->next() != NULL) { |
fparain@3329 | 173 | a = a->next(); |
fparain@3329 | 174 | } |
fparain@3329 | 175 | a->set_next(arg); |
fparain@3329 | 176 | } |
fparain@3329 | 177 | arg->set_next(NULL); |
fparain@3329 | 178 | Thread* THREAD = Thread::current(); |
fparain@3329 | 179 | arg->init_value(THREAD); |
fparain@3329 | 180 | if (HAS_PENDING_EXCEPTION) { |
fparain@3329 | 181 | fatal("Initialization must be successful"); |
fparain@3329 | 182 | } |
fparain@3329 | 183 | } |
fparain@3329 | 184 | |
fparain@3329 | 185 | void DCmdParser::parse(CmdLine* line, char delim, TRAPS) { |
fparain@3329 | 186 | GenDCmdArgument* next_argument = _arguments_list; |
fparain@3329 | 187 | DCmdArgIter iter(line->args_addr(), line->args_len(), delim); |
fparain@3329 | 188 | bool cont = iter.next(CHECK); |
fparain@3329 | 189 | while (cont) { |
fparain@3329 | 190 | GenDCmdArgument* arg = lookup_dcmd_option(iter.key_addr(), |
fparain@3329 | 191 | iter.key_length()); |
fparain@3329 | 192 | if (arg != NULL) { |
fparain@3329 | 193 | arg->read_value(iter.value_addr(), iter.value_length(), CHECK); |
fparain@3329 | 194 | } else { |
fparain@3329 | 195 | if (next_argument != NULL) { |
fparain@3329 | 196 | arg = next_argument; |
fparain@3329 | 197 | arg->read_value(iter.key_addr(), iter.key_length(), CHECK); |
fparain@3329 | 198 | next_argument = next_argument->next(); |
fparain@3329 | 199 | } else { |
sla@3905 | 200 | const size_t buflen = 120; |
sla@3905 | 201 | const size_t argbuflen = 30; |
sla@3905 | 202 | char buf[buflen]; |
sla@3905 | 203 | char argbuf[argbuflen]; |
sla@3905 | 204 | size_t len = MIN2<size_t>(iter.key_length(), argbuflen - 1); |
sla@3905 | 205 | |
sla@3905 | 206 | strncpy(argbuf, iter.key_addr(), len); |
sla@3905 | 207 | argbuf[len] = '\0'; |
sla@3905 | 208 | jio_snprintf(buf, buflen - 1, "Unknown argument '%s' in diagnostic command.", argbuf); |
sla@3905 | 209 | |
sla@3905 | 210 | THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf); |
fparain@3329 | 211 | } |
fparain@3329 | 212 | } |
fparain@3329 | 213 | cont = iter.next(CHECK); |
fparain@3329 | 214 | } |
fparain@3329 | 215 | check(CHECK); |
fparain@3329 | 216 | } |
fparain@3329 | 217 | |
fparain@3329 | 218 | GenDCmdArgument* DCmdParser::lookup_dcmd_option(const char* name, size_t len) { |
fparain@3329 | 219 | GenDCmdArgument* arg = _options; |
fparain@3329 | 220 | while (arg != NULL) { |
fparain@3329 | 221 | if (strlen(arg->name()) == len && |
fparain@3329 | 222 | strncmp(name, arg->name(), len) == 0) { |
fparain@3329 | 223 | return arg; |
fparain@3329 | 224 | } |
fparain@3329 | 225 | arg = arg->next(); |
fparain@3329 | 226 | } |
fparain@3329 | 227 | return NULL; |
fparain@3329 | 228 | } |
fparain@3329 | 229 | |
fparain@3329 | 230 | void DCmdParser::check(TRAPS) { |
sla@3905 | 231 | const size_t buflen = 256; |
sla@3905 | 232 | char buf[buflen]; |
fparain@3329 | 233 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 234 | while (arg != NULL) { |
fparain@3329 | 235 | if (arg->is_mandatory() && !arg->has_value()) { |
sla@3905 | 236 | jio_snprintf(buf, buflen - 1, "The argument '%s' is mandatory.", arg->name()); |
sla@3905 | 237 | THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf); |
fparain@3329 | 238 | } |
fparain@3329 | 239 | arg = arg->next(); |
fparain@3329 | 240 | } |
fparain@3329 | 241 | arg = _options; |
fparain@3329 | 242 | while (arg != NULL) { |
fparain@3329 | 243 | if (arg->is_mandatory() && !arg->has_value()) { |
sla@3905 | 244 | jio_snprintf(buf, buflen - 1, "The option '%s' is mandatory.", arg->name()); |
sla@3905 | 245 | THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf); |
fparain@3329 | 246 | } |
fparain@3329 | 247 | arg = arg->next(); |
fparain@3329 | 248 | } |
fparain@3329 | 249 | } |
fparain@3329 | 250 | |
fparain@3329 | 251 | void DCmdParser::print_help(outputStream* out, const char* cmd_name) { |
fparain@3402 | 252 | out->print("Syntax : %s %s", cmd_name, _options == NULL ? "" : "[options]"); |
fparain@3329 | 253 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 254 | while (arg != NULL) { |
fparain@3329 | 255 | if (arg->is_mandatory()) { |
fparain@3329 | 256 | out->print(" <%s>", arg->name()); |
fparain@3329 | 257 | } else { |
fparain@3329 | 258 | out->print(" [<%s>]", arg->name()); |
fparain@3329 | 259 | } |
fparain@3329 | 260 | arg = arg->next(); |
fparain@3329 | 261 | } |
fparain@3329 | 262 | out->print_cr(""); |
fparain@3329 | 263 | if (_arguments_list != NULL) { |
fparain@3329 | 264 | out->print_cr("\nArguments:"); |
fparain@3329 | 265 | arg = _arguments_list; |
fparain@3329 | 266 | while (arg != NULL) { |
fparain@3329 | 267 | out->print("\t%s : %s %s (%s, ", arg->name(), |
fparain@3329 | 268 | arg->is_mandatory() ? "" : "[optional]", |
fparain@3329 | 269 | arg->description(), arg->type()); |
fparain@3329 | 270 | if (arg->has_default()) { |
fparain@3329 | 271 | out->print(arg->default_string()); |
fparain@3329 | 272 | } else { |
fparain@3329 | 273 | out->print("no default value"); |
fparain@3329 | 274 | } |
fparain@3329 | 275 | out->print_cr(")"); |
fparain@3329 | 276 | arg = arg->next(); |
fparain@3329 | 277 | } |
fparain@3329 | 278 | } |
fparain@3329 | 279 | if (_options != NULL) { |
fparain@3329 | 280 | out->print_cr("\nOptions: (options must be specified using the <key> or <key>=<value> syntax)"); |
fparain@3329 | 281 | arg = _options; |
fparain@3329 | 282 | while (arg != NULL) { |
fparain@3329 | 283 | out->print("\t%s : %s %s (%s, ", arg->name(), |
fparain@3329 | 284 | arg->is_mandatory() ? "" : "[optional]", |
fparain@3329 | 285 | arg->description(), arg->type()); |
fparain@3329 | 286 | if (arg->has_default()) { |
fparain@3329 | 287 | out->print(arg->default_string()); |
fparain@3329 | 288 | } else { |
fparain@3329 | 289 | out->print("no default value"); |
fparain@3329 | 290 | } |
fparain@3329 | 291 | out->print_cr(")"); |
fparain@3329 | 292 | arg = arg->next(); |
fparain@3329 | 293 | } |
fparain@3329 | 294 | } |
fparain@3329 | 295 | } |
fparain@3329 | 296 | |
fparain@3329 | 297 | void DCmdParser::reset(TRAPS) { |
fparain@3329 | 298 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 299 | while (arg != NULL) { |
fparain@3329 | 300 | arg->reset(CHECK); |
fparain@3329 | 301 | arg = arg->next(); |
fparain@3329 | 302 | } |
fparain@3329 | 303 | arg = _options; |
fparain@3329 | 304 | while (arg != NULL) { |
fparain@3329 | 305 | arg->reset(CHECK); |
fparain@3329 | 306 | arg = arg->next(); |
fparain@3329 | 307 | } |
fparain@3329 | 308 | } |
fparain@3329 | 309 | |
fparain@3329 | 310 | void DCmdParser::cleanup() { |
fparain@3329 | 311 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 312 | while (arg != NULL) { |
fparain@3329 | 313 | arg->cleanup(); |
fparain@3329 | 314 | arg = arg->next(); |
fparain@3329 | 315 | } |
fparain@3329 | 316 | arg = _options; |
fparain@3329 | 317 | while (arg != NULL) { |
fparain@3329 | 318 | arg->cleanup(); |
fparain@3329 | 319 | arg = arg->next(); |
fparain@3329 | 320 | } |
fparain@3329 | 321 | } |
fparain@3329 | 322 | |
fparain@3329 | 323 | int DCmdParser::num_arguments() { |
fparain@3329 | 324 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 325 | int count = 0; |
fparain@3329 | 326 | while (arg != NULL) { |
fparain@3329 | 327 | count++; |
fparain@3329 | 328 | arg = arg->next(); |
fparain@3329 | 329 | } |
fparain@3329 | 330 | arg = _options; |
fparain@3329 | 331 | while (arg != NULL) { |
fparain@3329 | 332 | count++; |
fparain@3329 | 333 | arg = arg->next(); |
fparain@3329 | 334 | } |
fparain@3329 | 335 | return count; |
fparain@3329 | 336 | } |
fparain@3329 | 337 | |
fparain@3329 | 338 | GrowableArray<const char *>* DCmdParser::argument_name_array() { |
fparain@3329 | 339 | int count = num_arguments(); |
fparain@3329 | 340 | GrowableArray<const char *>* array = new GrowableArray<const char *>(count); |
fparain@3329 | 341 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 342 | while (arg != NULL) { |
fparain@3329 | 343 | array->append(arg->name()); |
fparain@3329 | 344 | arg = arg->next(); |
fparain@3329 | 345 | } |
fparain@3329 | 346 | arg = _options; |
fparain@3329 | 347 | while (arg != NULL) { |
fparain@3329 | 348 | array->append(arg->name()); |
fparain@3329 | 349 | arg = arg->next(); |
fparain@3329 | 350 | } |
fparain@3329 | 351 | return array; |
fparain@3329 | 352 | } |
fparain@3329 | 353 | |
fparain@3329 | 354 | GrowableArray<DCmdArgumentInfo*>* DCmdParser::argument_info_array() { |
fparain@3329 | 355 | int count = num_arguments(); |
fparain@3329 | 356 | GrowableArray<DCmdArgumentInfo*>* array = new GrowableArray<DCmdArgumentInfo *>(count); |
fparain@3329 | 357 | int idx = 0; |
fparain@3329 | 358 | GenDCmdArgument* arg = _arguments_list; |
fparain@3329 | 359 | while (arg != NULL) { |
fparain@3329 | 360 | array->append(new DCmdArgumentInfo(arg->name(), arg->description(), |
fparain@3329 | 361 | arg->type(), arg->default_string(), arg->is_mandatory(), |
fparain@3329 | 362 | false, idx)); |
fparain@3329 | 363 | idx++; |
fparain@3329 | 364 | arg = arg->next(); |
fparain@3329 | 365 | } |
fparain@3329 | 366 | arg = _options; |
fparain@3329 | 367 | while (arg != NULL) { |
fparain@3329 | 368 | array->append(new DCmdArgumentInfo(arg->name(), arg->description(), |
fparain@3329 | 369 | arg->type(), arg->default_string(), arg->is_mandatory(), |
fparain@3329 | 370 | true)); |
fparain@3329 | 371 | arg = arg->next(); |
fparain@3329 | 372 | } |
fparain@3329 | 373 | return array; |
fparain@3329 | 374 | } |
fparain@3329 | 375 | |
fparain@3329 | 376 | DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL; |
fparain@3329 | 377 | |
fparain@3329 | 378 | void DCmd::parse_and_execute(outputStream* out, const char* cmdline, |
fparain@3329 | 379 | char delim, TRAPS) { |
fparain@3329 | 380 | |
fparain@3329 | 381 | if (cmdline == NULL) return; // Nothing to do! |
fparain@3329 | 382 | DCmdIter iter(cmdline, '\n'); |
fparain@3329 | 383 | |
fparain@3329 | 384 | while (iter.has_next()) { |
fparain@3329 | 385 | CmdLine line = iter.next(); |
fparain@3329 | 386 | if (line.is_stop()) { |
fparain@3329 | 387 | break; |
fparain@3329 | 388 | } |
fparain@3329 | 389 | if (line.is_executable()) { |
fparain@3329 | 390 | DCmd* command = DCmdFactory::create_local_DCmd(line, out, CHECK); |
fparain@3329 | 391 | assert(command != NULL, "command error must be handled before this line"); |
fparain@3329 | 392 | DCmdMark mark(command); |
fparain@3329 | 393 | command->parse(&line, delim, CHECK); |
fparain@3329 | 394 | command->execute(CHECK); |
fparain@3329 | 395 | } |
fparain@3329 | 396 | } |
fparain@3329 | 397 | } |
fparain@3329 | 398 | |
fparain@3402 | 399 | void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) { |
fparain@3402 | 400 | _dcmdparser.parse(line, delim, CHECK); |
fparain@3402 | 401 | } |
fparain@3402 | 402 | |
fparain@3402 | 403 | void DCmdWithParser::print_help(const char* name) { |
fparain@3402 | 404 | _dcmdparser.print_help(output(), name); |
fparain@3402 | 405 | } |
fparain@3402 | 406 | |
fparain@3402 | 407 | void DCmdWithParser::reset(TRAPS) { |
fparain@3402 | 408 | _dcmdparser.reset(CHECK); |
fparain@3402 | 409 | } |
fparain@3402 | 410 | |
fparain@3402 | 411 | void DCmdWithParser::cleanup() { |
fparain@3402 | 412 | _dcmdparser.cleanup(); |
fparain@3402 | 413 | } |
fparain@3402 | 414 | |
fparain@3402 | 415 | GrowableArray<const char*>* DCmdWithParser::argument_name_array() { |
fparain@3402 | 416 | return _dcmdparser.argument_name_array(); |
fparain@3402 | 417 | } |
fparain@3402 | 418 | |
fparain@3402 | 419 | GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() { |
fparain@3402 | 420 | return _dcmdparser.argument_info_array(); |
fparain@3402 | 421 | } |
fparain@3402 | 422 | |
fparain@3329 | 423 | Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true); |
fparain@3329 | 424 | |
fparain@3329 | 425 | DCmdFactory* DCmdFactory::factory(const char* name, size_t len) { |
fparain@3329 | 426 | MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
fparain@3329 | 427 | DCmdFactory* factory = _DCmdFactoryList; |
fparain@3329 | 428 | while (factory != NULL) { |
fparain@3329 | 429 | if (strlen(factory->name()) == len && |
fparain@3329 | 430 | strncmp(name, factory->name(), len) == 0) { |
fparain@3329 | 431 | return factory; |
fparain@3329 | 432 | } |
fparain@3329 | 433 | factory = factory->_next; |
fparain@3329 | 434 | } |
fparain@3329 | 435 | return NULL; |
fparain@3329 | 436 | } |
fparain@3329 | 437 | |
fparain@3329 | 438 | int DCmdFactory::register_DCmdFactory(DCmdFactory* factory) { |
fparain@3329 | 439 | MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
fparain@3329 | 440 | factory->_next = _DCmdFactoryList; |
fparain@3329 | 441 | _DCmdFactoryList = factory; |
fparain@3329 | 442 | return 0; // Actually, there's no checks for duplicates |
fparain@3329 | 443 | } |
fparain@3329 | 444 | |
fparain@3329 | 445 | DCmd* DCmdFactory::create_global_DCmd(CmdLine &line, outputStream* out, TRAPS) { |
fparain@3329 | 446 | DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len()); |
fparain@3329 | 447 | if (f != NULL) { |
fparain@3329 | 448 | if (f->is_enabled()) { |
fparain@3329 | 449 | THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 450 | f->disabled_message()); |
fparain@3329 | 451 | } |
fparain@3329 | 452 | return f->create_Cheap_instance(out); |
fparain@3329 | 453 | } |
fparain@3329 | 454 | THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 455 | "Unknown diagnostic command"); |
fparain@3329 | 456 | } |
fparain@3329 | 457 | |
fparain@3329 | 458 | DCmd* DCmdFactory::create_local_DCmd(CmdLine &line, outputStream* out, TRAPS) { |
fparain@3329 | 459 | DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len()); |
fparain@3329 | 460 | if (f != NULL) { |
fparain@3329 | 461 | if (!f->is_enabled()) { |
fparain@3329 | 462 | THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 463 | f->disabled_message()); |
fparain@3329 | 464 | } |
fparain@3329 | 465 | return f->create_resource_instance(out); |
fparain@3329 | 466 | } |
fparain@3329 | 467 | THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), |
fparain@3329 | 468 | "Unknown diagnostic command"); |
fparain@3329 | 469 | } |
fparain@3329 | 470 | |
fparain@3329 | 471 | GrowableArray<const char*>* DCmdFactory::DCmd_list() { |
fparain@3329 | 472 | MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
fparain@3329 | 473 | GrowableArray<const char*>* array = new GrowableArray<const char*>(); |
fparain@3329 | 474 | DCmdFactory* factory = _DCmdFactoryList; |
fparain@3329 | 475 | while (factory != NULL) { |
fparain@3329 | 476 | if (!factory->is_hidden()) { |
fparain@3329 | 477 | array->append(factory->name()); |
fparain@3329 | 478 | } |
fparain@3329 | 479 | factory = factory->next(); |
fparain@3329 | 480 | } |
fparain@3329 | 481 | return array; |
fparain@3329 | 482 | } |
fparain@3329 | 483 | |
fparain@3329 | 484 | GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list() { |
fparain@3329 | 485 | MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); |
fparain@3329 | 486 | GrowableArray<DCmdInfo*>* array = new GrowableArray<DCmdInfo*>(); |
fparain@3329 | 487 | DCmdFactory* factory = _DCmdFactoryList; |
fparain@3329 | 488 | while (factory != NULL) { |
fparain@3329 | 489 | if (!factory->is_hidden()) { |
fparain@3329 | 490 | array->append(new DCmdInfo(factory->name(), |
fparain@3329 | 491 | factory->description(), factory->impact(), |
fparain@3329 | 492 | factory->num_arguments(), factory->is_enabled())); |
fparain@3329 | 493 | } |
fparain@3329 | 494 | factory = factory->next(); |
fparain@3329 | 495 | } |
fparain@3329 | 496 | return array; |
fparain@3329 | 497 | } |