Mercurial > hg > truffle
annotate src/share/vm/services/diagnosticFramework.cpp @ 5763:a3d71693e0ce
removed bytecode disassembly from CodeCacheRuntime into separate BytecodeDisassembler class
removed VM call for doing bytecode disassembly
added support for explicitly excluding classes from JaCoCo (put '// JaCoCo Exclude' somewhere in the source file)
added node intrinsics to MaterializeNode
added snippets for the UnsignedMath classes
each file opened by CFGPrinter now includes a unique id in its name to avoid a race of multiple threads writing to the same file
the IdealGraphPrinter uses the new BytecodeDisassembler mechanism
teh UnsignedMath class is exclude from JaCoCo processing as it is used in snippets
author | Doug Simon <doug.simon@oracle.com> |
---|---|
date | Wed, 04 Jul 2012 21:57:49 +0200 |
parents | f1cb6f9cfe21 |
children | 5a1f452f8f90 |
rev | line source |
---|---|
4133 | 1 /* |
4932
f1cb6f9cfe21
7145243: Need additional specializations for argument parsing framework
fparain
parents:
4773
diff
changeset
|
2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. |
4133 | 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 "memory/oopFactory.hpp" | |
27 #include "runtime/javaCalls.hpp" | |
28 #include "runtime/mutexLocker.hpp" | |
29 #include "services/diagnosticArgument.hpp" | |
30 #include "services/diagnosticFramework.hpp" | |
31 #include "services/management.hpp" | |
32 | |
33 CmdLine::CmdLine(const char* line, size_t len, bool no_command_name) { | |
34 assert(line != NULL, "Command line string should not be NULL"); | |
35 const char* line_end; | |
36 const char* cmd_end; | |
37 | |
38 _cmd = line; | |
39 line_end = &line[len]; | |
40 | |
41 // Skip whitespace in the beginning of the line. | |
42 while (_cmd < line_end && isspace((int) _cmd[0])) { | |
43 _cmd++; | |
44 } | |
45 cmd_end = _cmd; | |
46 | |
47 if (no_command_name) { | |
48 _cmd = NULL; | |
49 _cmd_len = 0; | |
50 } else { | |
51 // Look for end of the command name | |
52 while (cmd_end < line_end && !isspace((int) cmd_end[0])) { | |
53 cmd_end++; | |
54 } | |
55 _cmd_len = cmd_end - _cmd; | |
56 } | |
57 _args = cmd_end; | |
58 _args_len = line_end - _args; | |
59 } | |
60 | |
61 bool DCmdArgIter::next(TRAPS) { | |
62 if (_len == 0) return false; | |
63 // skipping spaces | |
4932
f1cb6f9cfe21
7145243: Need additional specializations for argument parsing framework
fparain
parents:
4773
diff
changeset
|
64 while (_cursor < _len - 1 && _buffer[_cursor] == _delim) { |
4133 | 65 _cursor++; |
66 } | |
67 // handling end of command line | |
68 if (_cursor >= _len - 1) { | |
69 _cursor = _len - 1; | |
70 _key_addr = &_buffer[_len - 1]; | |
71 _key_len = 0; | |
72 _value_addr = &_buffer[_len - 1]; | |
73 _value_len = 0; | |
74 return false; | |
75 } | |
76 // extracting first item, argument or option name | |
77 _key_addr = &_buffer[_cursor]; | |
78 while (_cursor <= _len - 1 && _buffer[_cursor] != '=' && _buffer[_cursor] != _delim) { | |
79 // argument can be surrounded by single or double quotes | |
80 if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') { | |
81 _key_addr++; | |
82 char quote = _buffer[_cursor]; | |
83 while (_cursor < _len - 1) { | |
84 _cursor++; | |
85 if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') { | |
86 break; | |
87 } | |
88 } | |
89 if (_buffer[_cursor] != quote) { | |
90 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
91 "Format error in diagnostic command arguments", false); | |
92 } | |
93 break; | |
94 } | |
95 _cursor++; | |
96 } | |
97 _key_len = &_buffer[_cursor] - _key_addr; | |
98 // check if the argument has the <key>=<value> format | |
99 if (_cursor <= _len -1 && _buffer[_cursor] == '=') { | |
100 _cursor++; | |
101 _value_addr = &_buffer[_cursor]; | |
102 // extract the value | |
103 while (_cursor <= _len - 1 && _buffer[_cursor] != _delim) { | |
104 // value can be surrounded by simple or double quotes | |
105 if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') { | |
106 _value_addr++; | |
107 char quote = _buffer[_cursor]; | |
108 while (_cursor < _len - 1) { | |
109 _cursor++; | |
110 if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') { | |
111 break; | |
112 } | |
113 } | |
114 if (_buffer[_cursor] != quote) { | |
115 THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), | |
116 "Format error in diagnostic command arguments", false); | |
117 } | |
118 break; | |
119 } | |
120 _cursor++; | |
121 } | |
122 _value_len = &_buffer[_cursor] - _value_addr; | |
123 } else { | |
124 _value_addr = NULL; | |
125 _value_len = 0; | |
126 } | |
127 return _key_len != 0; | |
128 } | |
129 | |
130 bool DCmdInfo::by_name(void* cmd_name, DCmdInfo* info) { | |
131 if (info == NULL) return false; | |
132 return strcmp((const char*)cmd_name, info->name()) == 0; | |
133 } | |
134 | |
135 void DCmdParser::add_dcmd_option(GenDCmdArgument* arg) { | |
136 assert(arg != NULL, "Sanity"); | |
137 if (_options == NULL) { | |
138 _options = arg; | |
139 } else { | |
140 GenDCmdArgument* o = _options; | |
141 while (o->next() != NULL) { | |
142 o = o->next(); | |
143 } | |
144 o->set_next(arg); | |
145 } | |
146 arg->set_next(NULL); | |
147 Thread* THREAD = Thread::current(); | |
148 arg->init_value(THREAD); | |
149 if (HAS_PENDING_EXCEPTION) { | |
150 fatal("Initialization must be successful"); | |
151 } | |
152 } | |
153 | |
154 void DCmdParser::add_dcmd_argument(GenDCmdArgument* arg) { | |
155 assert(arg != NULL, "Sanity"); | |
156 if (_arguments_list == NULL) { | |
157 _arguments_list = arg; | |
158 } else { | |
159 GenDCmdArgument* a = _arguments_list; | |
160 while (a->next() != NULL) { | |
161 a = a->next(); | |
162 } | |
163 a->set_next(arg); | |
164 } | |
165 arg->set_next(NULL); | |
166 Thread* THREAD = Thread::current(); | |
167 arg->init_value(THREAD); | |
168 if (HAS_PENDING_EXCEPTION) { | |
169 fatal("Initialization must be successful"); | |
170 } | |
171 } | |
172 | |
173 void DCmdParser::parse(CmdLine* line, char delim, TRAPS) { | |
174 GenDCmdArgument* next_argument = _arguments_list; | |
175 DCmdArgIter iter(line->args_addr(), line->args_len(), delim); | |
176 bool cont = iter.next(CHECK); | |
177 while (cont) { | |
178 GenDCmdArgument* arg = lookup_dcmd_option(iter.key_addr(), | |
179 iter.key_length()); | |
180 if (arg != NULL) { | |
181 arg->read_value(iter.value_addr(), iter.value_length(), CHECK); | |
182 } else { | |
183 if (next_argument != NULL) { | |
184 arg = next_argument; | |
185 arg->read_value(iter.key_addr(), iter.key_length(), CHECK); | |
186 next_argument = next_argument->next(); | |
187 } else { | |
188 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
189 "Unknown argument in diagnostic command"); | |
190 } | |
191 } | |
192 cont = iter.next(CHECK); | |
193 } | |
194 check(CHECK); | |
195 } | |
196 | |
197 GenDCmdArgument* DCmdParser::lookup_dcmd_option(const char* name, size_t len) { | |
198 GenDCmdArgument* arg = _options; | |
199 while (arg != NULL) { | |
200 if (strlen(arg->name()) == len && | |
201 strncmp(name, arg->name(), len) == 0) { | |
202 return arg; | |
203 } | |
204 arg = arg->next(); | |
205 } | |
206 return NULL; | |
207 } | |
208 | |
209 void DCmdParser::check(TRAPS) { | |
210 GenDCmdArgument* arg = _arguments_list; | |
211 while (arg != NULL) { | |
212 if (arg->is_mandatory() && !arg->has_value()) { | |
213 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
214 "Missing argument for diagnostic command"); | |
215 } | |
216 arg = arg->next(); | |
217 } | |
218 arg = _options; | |
219 while (arg != NULL) { | |
220 if (arg->is_mandatory() && !arg->has_value()) { | |
221 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
222 "Missing option for diagnostic command"); | |
223 } | |
224 arg = arg->next(); | |
225 } | |
226 } | |
227 | |
228 void DCmdParser::print_help(outputStream* out, const char* cmd_name) { | |
4773 | 229 out->print("Syntax : %s %s", cmd_name, _options == NULL ? "" : "[options]"); |
4133 | 230 GenDCmdArgument* arg = _arguments_list; |
231 while (arg != NULL) { | |
232 if (arg->is_mandatory()) { | |
233 out->print(" <%s>", arg->name()); | |
234 } else { | |
235 out->print(" [<%s>]", arg->name()); | |
236 } | |
237 arg = arg->next(); | |
238 } | |
239 out->print_cr(""); | |
240 if (_arguments_list != NULL) { | |
241 out->print_cr("\nArguments:"); | |
242 arg = _arguments_list; | |
243 while (arg != NULL) { | |
244 out->print("\t%s : %s %s (%s, ", arg->name(), | |
245 arg->is_mandatory() ? "" : "[optional]", | |
246 arg->description(), arg->type()); | |
247 if (arg->has_default()) { | |
248 out->print(arg->default_string()); | |
249 } else { | |
250 out->print("no default value"); | |
251 } | |
252 out->print_cr(")"); | |
253 arg = arg->next(); | |
254 } | |
255 } | |
256 if (_options != NULL) { | |
257 out->print_cr("\nOptions: (options must be specified using the <key> or <key>=<value> syntax)"); | |
258 arg = _options; | |
259 while (arg != NULL) { | |
260 out->print("\t%s : %s %s (%s, ", arg->name(), | |
261 arg->is_mandatory() ? "" : "[optional]", | |
262 arg->description(), arg->type()); | |
263 if (arg->has_default()) { | |
264 out->print(arg->default_string()); | |
265 } else { | |
266 out->print("no default value"); | |
267 } | |
268 out->print_cr(")"); | |
269 arg = arg->next(); | |
270 } | |
271 } | |
272 } | |
273 | |
274 void DCmdParser::reset(TRAPS) { | |
275 GenDCmdArgument* arg = _arguments_list; | |
276 while (arg != NULL) { | |
277 arg->reset(CHECK); | |
278 arg = arg->next(); | |
279 } | |
280 arg = _options; | |
281 while (arg != NULL) { | |
282 arg->reset(CHECK); | |
283 arg = arg->next(); | |
284 } | |
285 } | |
286 | |
287 void DCmdParser::cleanup() { | |
288 GenDCmdArgument* arg = _arguments_list; | |
289 while (arg != NULL) { | |
290 arg->cleanup(); | |
291 arg = arg->next(); | |
292 } | |
293 arg = _options; | |
294 while (arg != NULL) { | |
295 arg->cleanup(); | |
296 arg = arg->next(); | |
297 } | |
298 } | |
299 | |
300 int DCmdParser::num_arguments() { | |
301 GenDCmdArgument* arg = _arguments_list; | |
302 int count = 0; | |
303 while (arg != NULL) { | |
304 count++; | |
305 arg = arg->next(); | |
306 } | |
307 arg = _options; | |
308 while (arg != NULL) { | |
309 count++; | |
310 arg = arg->next(); | |
311 } | |
312 return count; | |
313 } | |
314 | |
315 GrowableArray<const char *>* DCmdParser::argument_name_array() { | |
316 int count = num_arguments(); | |
317 GrowableArray<const char *>* array = new GrowableArray<const char *>(count); | |
318 GenDCmdArgument* arg = _arguments_list; | |
319 while (arg != NULL) { | |
320 array->append(arg->name()); | |
321 arg = arg->next(); | |
322 } | |
323 arg = _options; | |
324 while (arg != NULL) { | |
325 array->append(arg->name()); | |
326 arg = arg->next(); | |
327 } | |
328 return array; | |
329 } | |
330 | |
331 GrowableArray<DCmdArgumentInfo*>* DCmdParser::argument_info_array() { | |
332 int count = num_arguments(); | |
333 GrowableArray<DCmdArgumentInfo*>* array = new GrowableArray<DCmdArgumentInfo *>(count); | |
334 int idx = 0; | |
335 GenDCmdArgument* arg = _arguments_list; | |
336 while (arg != NULL) { | |
337 array->append(new DCmdArgumentInfo(arg->name(), arg->description(), | |
338 arg->type(), arg->default_string(), arg->is_mandatory(), | |
339 false, idx)); | |
340 idx++; | |
341 arg = arg->next(); | |
342 } | |
343 arg = _options; | |
344 while (arg != NULL) { | |
345 array->append(new DCmdArgumentInfo(arg->name(), arg->description(), | |
346 arg->type(), arg->default_string(), arg->is_mandatory(), | |
347 true)); | |
348 arg = arg->next(); | |
349 } | |
350 return array; | |
351 } | |
352 | |
353 DCmdFactory* DCmdFactory::_DCmdFactoryList = NULL; | |
354 | |
355 void DCmd::parse_and_execute(outputStream* out, const char* cmdline, | |
356 char delim, TRAPS) { | |
357 | |
358 if (cmdline == NULL) return; // Nothing to do! | |
359 DCmdIter iter(cmdline, '\n'); | |
360 | |
361 while (iter.has_next()) { | |
362 CmdLine line = iter.next(); | |
363 if (line.is_stop()) { | |
364 break; | |
365 } | |
366 if (line.is_executable()) { | |
367 DCmd* command = DCmdFactory::create_local_DCmd(line, out, CHECK); | |
368 assert(command != NULL, "command error must be handled before this line"); | |
369 DCmdMark mark(command); | |
370 command->parse(&line, delim, CHECK); | |
371 command->execute(CHECK); | |
372 } | |
373 } | |
374 } | |
375 | |
4773 | 376 void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) { |
377 _dcmdparser.parse(line, delim, CHECK); | |
378 } | |
379 | |
380 void DCmdWithParser::print_help(const char* name) { | |
381 _dcmdparser.print_help(output(), name); | |
382 } | |
383 | |
384 void DCmdWithParser::reset(TRAPS) { | |
385 _dcmdparser.reset(CHECK); | |
386 } | |
387 | |
388 void DCmdWithParser::cleanup() { | |
389 _dcmdparser.cleanup(); | |
390 } | |
391 | |
392 GrowableArray<const char*>* DCmdWithParser::argument_name_array() { | |
393 return _dcmdparser.argument_name_array(); | |
394 } | |
395 | |
396 GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() { | |
397 return _dcmdparser.argument_info_array(); | |
398 } | |
399 | |
4133 | 400 Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true); |
401 | |
402 DCmdFactory* DCmdFactory::factory(const char* name, size_t len) { | |
403 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); | |
404 DCmdFactory* factory = _DCmdFactoryList; | |
405 while (factory != NULL) { | |
406 if (strlen(factory->name()) == len && | |
407 strncmp(name, factory->name(), len) == 0) { | |
408 return factory; | |
409 } | |
410 factory = factory->_next; | |
411 } | |
412 return NULL; | |
413 } | |
414 | |
415 int DCmdFactory::register_DCmdFactory(DCmdFactory* factory) { | |
416 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); | |
417 factory->_next = _DCmdFactoryList; | |
418 _DCmdFactoryList = factory; | |
419 return 0; // Actually, there's no checks for duplicates | |
420 } | |
421 | |
422 DCmd* DCmdFactory::create_global_DCmd(CmdLine &line, outputStream* out, TRAPS) { | |
423 DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len()); | |
424 if (f != NULL) { | |
425 if (f->is_enabled()) { | |
426 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), | |
427 f->disabled_message()); | |
428 } | |
429 return f->create_Cheap_instance(out); | |
430 } | |
431 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), | |
432 "Unknown diagnostic command"); | |
433 } | |
434 | |
435 DCmd* DCmdFactory::create_local_DCmd(CmdLine &line, outputStream* out, TRAPS) { | |
436 DCmdFactory* f = factory(line.cmd_addr(), line.cmd_len()); | |
437 if (f != NULL) { | |
438 if (!f->is_enabled()) { | |
439 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), | |
440 f->disabled_message()); | |
441 } | |
442 return f->create_resource_instance(out); | |
443 } | |
444 THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), | |
445 "Unknown diagnostic command"); | |
446 } | |
447 | |
448 GrowableArray<const char*>* DCmdFactory::DCmd_list() { | |
449 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); | |
450 GrowableArray<const char*>* array = new GrowableArray<const char*>(); | |
451 DCmdFactory* factory = _DCmdFactoryList; | |
452 while (factory != NULL) { | |
453 if (!factory->is_hidden()) { | |
454 array->append(factory->name()); | |
455 } | |
456 factory = factory->next(); | |
457 } | |
458 return array; | |
459 } | |
460 | |
461 GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list() { | |
462 MutexLockerEx ml(_dcmdFactory_lock, Mutex::_no_safepoint_check_flag); | |
463 GrowableArray<DCmdInfo*>* array = new GrowableArray<DCmdInfo*>(); | |
464 DCmdFactory* factory = _DCmdFactoryList; | |
465 while (factory != NULL) { | |
466 if (!factory->is_hidden()) { | |
467 array->append(new DCmdInfo(factory->name(), | |
468 factory->description(), factory->impact(), | |
469 factory->num_arguments(), factory->is_enabled())); | |
470 } | |
471 factory = factory->next(); | |
472 } | |
473 return array; | |
474 } |