Mercurial > hg > truffle
annotate src/share/vm/services/diagnosticFramework.hpp @ 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 | d2a62e0f25eb |
rev | line source |
---|---|
4133 | 1 /* |
4932
f1cb6f9cfe21
7145243: Need additional specializations for argument parsing framework
fparain
parents:
4851
diff
changeset
|
2 * Copyright (c) 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 #ifndef SHARE_VM_SERVICES_DIAGNOSTICFRAMEWORK_HPP | |
26 #define SHARE_VM_SERVICES_DIAGNOSTICFRAMEWORK_HPP | |
27 | |
28 #include "classfile/vmSymbols.hpp" | |
29 #include "memory/allocation.hpp" | |
30 #include "runtime/arguments.hpp" | |
31 #include "runtime/os.hpp" | |
32 #include "runtime/vm_version.hpp" | |
33 #include "runtime/vmThread.hpp" | |
34 #include "utilities/ostream.hpp" | |
35 | |
36 | |
37 // CmdLine is the class used to handle a command line containing a single | |
38 // diagnostic command and its arguments. It provides methods to access the | |
39 // command name and the beginning of the arguments. The class is also | |
40 // able to identify commented command lines and the "stop" keyword | |
41 class CmdLine : public StackObj { | |
42 private: | |
43 const char* _cmd; | |
44 size_t _cmd_len; | |
45 const char* _args; | |
46 size_t _args_len; | |
47 public: | |
48 CmdLine(const char* line, size_t len, bool no_command_name); | |
49 const char* args_addr() const { return _args; } | |
50 size_t args_len() const { return _args_len; } | |
51 const char* cmd_addr() const { return _cmd; } | |
52 size_t cmd_len() const { return _cmd_len; } | |
53 bool is_empty() { return _cmd_len == 0; } | |
54 bool is_executable() { return is_empty() || _cmd[0] != '#'; } | |
55 bool is_stop() { return !is_empty() && strncmp("stop", _cmd, _cmd_len) == 0; } | |
56 }; | |
57 | |
58 // Iterator class taking a character string in input and returning a CmdLine | |
59 // instance for each command line. The argument delimiter has to be specified. | |
60 class DCmdIter : public StackObj { | |
61 friend class DCmd; | |
62 private: | |
63 const char* _str; | |
64 char _delim; | |
65 size_t _len; | |
66 size_t _cursor; | |
67 public: | |
68 | |
69 DCmdIter(const char* str, char delim) { | |
70 _str = str; | |
71 _delim = delim; | |
72 _len = strlen(str); | |
73 _cursor = 0; | |
74 } | |
75 bool has_next() { return _cursor < _len; } | |
76 CmdLine next() { | |
77 assert(_cursor <= _len, "Cannot iterate more"); | |
78 size_t n = _cursor; | |
79 while (n < _len && _str[n] != _delim) n++; | |
80 CmdLine line(&(_str[_cursor]), n - _cursor, false); | |
81 _cursor = n + 1; | |
82 // The default copy constructor of CmdLine is used to return a CmdLine | |
83 // instance to the caller. | |
84 return line; | |
85 } | |
86 }; | |
87 | |
88 // Iterator class to iterate over diagnostic command arguments | |
89 class DCmdArgIter : public ResourceObj { | |
90 const char* _buffer; | |
91 size_t _len; | |
92 size_t _cursor; | |
93 const char* _key_addr; | |
94 size_t _key_len; | |
95 const char* _value_addr; | |
96 size_t _value_len; | |
97 char _delim; | |
98 public: | |
99 DCmdArgIter(const char* buf, size_t len, char delim) { | |
100 _buffer = buf; | |
101 _len = len; | |
102 _delim = delim; | |
103 _cursor = 0; | |
104 } | |
105 bool next(TRAPS); | |
106 const char* key_addr() { return _key_addr; } | |
107 size_t key_length() { return _key_len; } | |
108 const char* value_addr() { return _value_addr; } | |
109 size_t value_length() { return _value_len; } | |
110 }; | |
111 | |
112 // A DCmdInfo instance provides a description of a diagnostic command. It is | |
113 // used to export the description to the JMX interface of the framework. | |
114 class DCmdInfo : public ResourceObj { | |
115 protected: | |
116 const char* _name; | |
117 const char* _description; | |
118 const char* _impact; | |
119 int _num_arguments; | |
120 bool _is_enabled; | |
121 public: | |
122 DCmdInfo(const char* name, | |
123 const char* description, | |
124 const char* impact, | |
125 int num_arguments, | |
126 bool enabled) { | |
127 this->_name = name; | |
128 this->_description = description; | |
129 this->_impact = impact; | |
130 this->_num_arguments = num_arguments; | |
131 this->_is_enabled = enabled; | |
132 } | |
133 const char* name() const { return _name; } | |
134 const char* description() const { return _description; } | |
135 const char* impact() const { return _impact; } | |
136 int num_arguments() const { return _num_arguments; } | |
137 bool is_enabled() const { return _is_enabled; } | |
138 | |
139 static bool by_name(void* name, DCmdInfo* info); | |
140 }; | |
141 | |
142 // A DCmdArgumentInfo instance provides a description of a diagnostic command | |
143 // argument. It is used to export the description to the JMX interface of the | |
144 // framework. | |
145 class DCmdArgumentInfo : public ResourceObj { | |
146 protected: | |
147 const char* _name; | |
148 const char* _description; | |
149 const char* _type; | |
150 const char* _default_string; | |
151 bool _mandatory; | |
152 bool _option; | |
153 int _position; | |
154 public: | |
155 DCmdArgumentInfo(const char* name, const char* description, const char* type, | |
156 const char* default_string, bool mandatory, bool option) { | |
157 this->_name = name; | |
158 this->_description = description; | |
159 this->_type = type; | |
160 this->_default_string = default_string; | |
161 this->_option = option; | |
162 this->_mandatory = mandatory; | |
163 this->_option = option; | |
164 this->_position = -1; | |
165 } | |
166 DCmdArgumentInfo(const char* name, const char* description, const char* type, | |
167 const char* default_string, bool mandatory, bool option, | |
168 int position) { | |
169 this->_name = name; | |
170 this->_description = description; | |
171 this->_type = type; | |
172 this->_default_string = default_string; | |
173 this->_option = option; | |
174 this->_mandatory = mandatory; | |
175 this->_option = option; | |
176 this->_position = position; | |
177 } | |
178 const char* name() const { return _name; } | |
179 const char* description() const { return _description; } | |
180 const char* type() const { return _type; } | |
181 const char* default_string() const { return _default_string; } | |
182 bool is_mandatory() const { return _mandatory; } | |
183 bool is_option() const { return _option; } | |
184 int position() const { return _position; } | |
185 }; | |
186 | |
187 // The DCmdParser class can be used to create an argument parser for a | |
188 // diagnostic command. It is not mandatory to use it to parse arguments. | |
189 class DCmdParser { | |
190 private: | |
191 GenDCmdArgument* _options; | |
192 GenDCmdArgument* _arguments_list; | |
193 char _delim; | |
194 public: | |
195 DCmdParser() { | |
196 _options = NULL; | |
197 _arguments_list = NULL; | |
4932
f1cb6f9cfe21
7145243: Need additional specializations for argument parsing framework
fparain
parents:
4851
diff
changeset
|
198 _delim = ' '; |
4133 | 199 } |
200 void add_dcmd_option(GenDCmdArgument* arg); | |
201 void add_dcmd_argument(GenDCmdArgument* arg); | |
202 GenDCmdArgument* lookup_dcmd_option(const char* name, size_t len); | |
203 GenDCmdArgument* arguments_list() { return _arguments_list; }; | |
204 void check(TRAPS); | |
205 void parse(CmdLine* line, char delim, TRAPS); | |
206 void print_help(outputStream* out, const char* cmd_name); | |
207 void reset(TRAPS); | |
208 void cleanup(); | |
209 int num_arguments(); | |
210 GrowableArray<const char*>* argument_name_array(); | |
211 GrowableArray<DCmdArgumentInfo*>* argument_info_array(); | |
212 }; | |
213 | |
214 // The DCmd class is the parent class of all diagnostic commands | |
215 // Diagnostic command instances should not be instantiated directly but | |
216 // created using the associated factory. The factory can be retrieved with | |
217 // the DCmdFactory::getFactory() method. | |
218 // A diagnostic command instance can either be allocated in the resource Area | |
219 // or in the C-heap. Allocation in the resource area is recommended when the | |
220 // current thread is the only one which will access the diagnostic command | |
221 // instance. Allocation in the C-heap is required when the diagnostic command | |
222 // is accessed by several threads (for instance to perform asynchronous | |
223 // execution). | |
224 // To ensure a proper cleanup, it's highly recommended to use a DCmdMark for | |
225 // each diagnostic command instance. In case of a C-heap allocated diagnostic | |
226 // command instance, the DCmdMark must be created in the context of the last | |
227 // thread that will access the instance. | |
228 class DCmd : public ResourceObj { | |
229 protected: | |
230 outputStream* _output; | |
231 bool _is_heap_allocated; | |
232 public: | |
233 DCmd(outputStream* output, bool heap_allocated) { | |
234 _output = output; | |
235 _is_heap_allocated = heap_allocated; | |
236 } | |
237 | |
238 static const char* name() { return "No Name";} | |
239 static const char* description() { return "No Help";} | |
240 static const char* disabled_message() { return "Diagnostic command currently disabled"; } | |
241 static const char* impact() { return "Low: No impact"; } | |
242 static int num_arguments() { return 0; } | |
243 outputStream* output() { return _output; } | |
244 bool is_heap_allocated() { return _is_heap_allocated; } | |
4773 | 245 virtual void print_help(const char* name) { |
246 output()->print_cr("Syntax: %s", name); | |
247 } | |
248 virtual void parse(CmdLine* line, char delim, TRAPS) { | |
249 DCmdArgIter iter(line->args_addr(), line->args_len(), delim); | |
250 bool has_arg = iter.next(CHECK); | |
251 if (has_arg) { | |
252 THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), | |
253 "Unknown argument in diagnostic command"); | |
254 } | |
255 } | |
4133 | 256 virtual void execute(TRAPS) { } |
257 virtual void reset(TRAPS) { } | |
258 virtual void cleanup() { } | |
259 | |
260 // support for the JMX interface | |
261 virtual GrowableArray<const char*>* argument_name_array() { | |
262 GrowableArray<const char*>* array = new GrowableArray<const char*>(0); | |
263 return array; | |
264 } | |
265 virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array() { | |
266 GrowableArray<DCmdArgumentInfo*>* array = new GrowableArray<DCmdArgumentInfo*>(0); | |
267 return array; | |
268 } | |
269 | |
270 // main method to invoke the framework | |
271 static void parse_and_execute(outputStream* out, const char* cmdline, | |
272 char delim, TRAPS); | |
273 }; | |
274 | |
4773 | 275 class DCmdWithParser : public DCmd { |
276 protected: | |
277 DCmdParser _dcmdparser; | |
278 public: | |
279 DCmdWithParser (outputStream *output, bool heap=false) : DCmd(output, heap) { } | |
280 static const char* name() { return "No Name";} | |
281 static const char* description() { return "No Help";} | |
282 static const char* disabled_message() { return "Diagnostic command currently disabled"; } | |
283 static const char* impact() { return "Low: No impact"; } | |
284 static int num_arguments() { return 0; } | |
285 virtual void parse(CmdLine *line, char delim, TRAPS); | |
286 virtual void execute(TRAPS) { } | |
287 virtual void reset(TRAPS); | |
288 virtual void cleanup(); | |
289 virtual void print_help(const char* name); | |
290 virtual GrowableArray<const char*>* argument_name_array(); | |
291 virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array(); | |
292 }; | |
293 | |
4133 | 294 class DCmdMark : public StackObj { |
295 DCmd* _ref; | |
296 public: | |
297 DCmdMark(DCmd* cmd) { _ref = cmd; } | |
298 ~DCmdMark() { | |
299 if (_ref != NULL) { | |
300 _ref->cleanup(); | |
301 if (_ref->is_heap_allocated()) { | |
302 delete _ref; | |
303 } | |
304 } | |
305 } | |
306 }; | |
307 | |
308 // Diagnostic commands are not directly instantiated but created with a factory. | |
309 // Each diagnostic command class has its own factory. The DCmdFactory class also | |
310 // manages the status of the diagnostic command (hidden, enabled). A DCmdFactory | |
311 // has to be registered to make the diagnostic command available (see | |
312 // management.cpp) | |
313 class DCmdFactory: public CHeapObj { | |
314 private: | |
315 static Mutex* _dcmdFactory_lock; | |
316 // Pointer to the next factory in the singly-linked list of registered | |
317 // diagnostic commands | |
318 DCmdFactory* _next; | |
319 // When disabled, a diagnostic command cannot be executed. Any attempt to | |
320 // execute it will result in the printing of the disabled message without | |
321 // instantiating the command. | |
322 bool _enabled; | |
323 // When hidden, a diagnostic command doesn't appear in the list of commands | |
324 // provided by the 'help' command. | |
325 bool _hidden; | |
326 int _num_arguments; | |
327 static DCmdFactory* _DCmdFactoryList; | |
328 public: | |
329 DCmdFactory(int num_arguments, bool enabled, bool hidden) { | |
330 _next = NULL; | |
331 _enabled = enabled; | |
332 _hidden = hidden; | |
333 _num_arguments = num_arguments; | |
334 } | |
335 bool is_enabled() const { return _enabled; } | |
336 void set_enabled(bool b) { _enabled = b; } | |
337 bool is_hidden() const { return _hidden; } | |
338 void set_hidden(bool b) { _hidden = b; } | |
339 int num_arguments() { return _num_arguments; } | |
340 DCmdFactory* next() { return _next; } | |
341 virtual DCmd* create_Cheap_instance(outputStream* output) = 0; | |
342 virtual DCmd* create_resource_instance(outputStream* output) = 0; | |
343 virtual const char* name() const = 0; | |
344 virtual const char* description() const = 0; | |
345 virtual const char* impact() const = 0; | |
346 virtual const char* disabled_message() const = 0; | |
347 // Register a DCmdFactory to make a diagnostic command available. | |
348 // Once registered, a diagnostic command must not be unregistered. | |
349 // To prevent a diagnostic command from being executed, just set the | |
350 // enabled flag to false. | |
351 static int register_DCmdFactory(DCmdFactory* factory); | |
352 static DCmdFactory* factory(const char* cmd, size_t len); | |
353 // Returns a C-heap allocated diagnostic command for the given command line | |
354 static DCmd* create_global_DCmd(CmdLine &line, outputStream* out, TRAPS); | |
355 // Returns a resourceArea allocated diagnostic command for the given command line | |
356 static DCmd* create_local_DCmd(CmdLine &line, outputStream* out, TRAPS); | |
357 static GrowableArray<const char*>* DCmd_list(); | |
358 static GrowableArray<DCmdInfo*>* DCmdInfo_list(); | |
359 | |
360 friend class HelpDCmd; | |
361 }; | |
362 | |
363 // Template to easily create DCmdFactory instances. See management.cpp | |
364 // where this template is used to create and register factories. | |
365 template <class DCmdClass> class DCmdFactoryImpl : public DCmdFactory { | |
366 public: | |
367 DCmdFactoryImpl(bool enabled, bool hidden) : | |
368 DCmdFactory(DCmdClass::num_arguments(), enabled, hidden) { } | |
369 // Returns a C-heap allocated instance | |
370 virtual DCmd* create_Cheap_instance(outputStream* output) { | |
371 return new (ResourceObj::C_HEAP) DCmdClass(output, true); | |
372 } | |
373 // Returns a resourceArea allocated instance | |
374 virtual DCmd* create_resource_instance(outputStream* output) { | |
375 return new DCmdClass(output, false); | |
376 } | |
377 virtual const char* name() const { | |
378 return DCmdClass::name(); | |
379 } | |
380 virtual const char* description() const { | |
381 return DCmdClass::description(); | |
382 } | |
383 virtual const char* impact() const { | |
384 return DCmdClass::impact(); | |
385 } | |
386 virtual const char* disabled_message() const { | |
387 return DCmdClass::disabled_message(); | |
388 } | |
389 }; | |
390 | |
4851
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
391 // This class provides a convenient way to register Dcmds, without a need to change |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
392 // management.cpp every time. Body of these two methods resides in |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
393 // diagnosticCommand.cpp |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
394 |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
395 class DCmdRegistrant : public AllStatic { |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
396 |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
397 private: |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
398 static void register_dcmds(); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
399 static void register_dcmds_ext(); |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
400 |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
401 friend class Management; |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
402 }; |
a42c07c38c47
7132515: Add dcmd to manage UnlockingCommercialFeature flag
dsamersoff
parents:
4773
diff
changeset
|
403 |
4133 | 404 #endif // SHARE_VM_SERVICES_DIAGNOSTICFRAMEWORK_HPP |