diff -r 000000000000 -r f90c822e73f8 src/share/vm/services/diagnosticFramework.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/share/vm/services/diagnosticFramework.hpp Wed Apr 27 01:25:04 2016 +0800 @@ -0,0 +1,491 @@ +/* + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_VM_SERVICES_DIAGNOSTICFRAMEWORK_HPP +#define SHARE_VM_SERVICES_DIAGNOSTICFRAMEWORK_HPP + +#include "classfile/vmSymbols.hpp" +#include "memory/allocation.hpp" +#include "runtime/arguments.hpp" +#include "runtime/os.hpp" +#include "runtime/vm_version.hpp" +#include "runtime/vmThread.hpp" +#include "utilities/ostream.hpp" + + +enum DCmdSource { + DCmd_Source_Internal = 0x01U, // invocation from the JVM + DCmd_Source_AttachAPI = 0x02U, // invocation via the attachAPI + DCmd_Source_MBean = 0x04U // invocation via a MBean +}; + +// Warning: strings referenced by the JavaPermission struct are passed to +// the native part of the JDK. Avoid use of dynamically allocated strings +// that could be de-allocated before the JDK native code had time to +// convert them into Java Strings. +struct JavaPermission { + const char* _class; + const char* _name; + const char* _action; +}; + +// CmdLine is the class used to handle a command line containing a single +// diagnostic command and its arguments. It provides methods to access the +// command name and the beginning of the arguments. The class is also +// able to identify commented command lines and the "stop" keyword +class CmdLine : public StackObj { +private: + const char* _cmd; + size_t _cmd_len; + const char* _args; + size_t _args_len; +public: + CmdLine(const char* line, size_t len, bool no_command_name); + const char* args_addr() const { return _args; } + size_t args_len() const { return _args_len; } + const char* cmd_addr() const { return _cmd; } + size_t cmd_len() const { return _cmd_len; } + bool is_empty() { return _cmd_len == 0; } + bool is_executable() { return is_empty() || _cmd[0] != '#'; } + bool is_stop() { return !is_empty() && strncmp("stop", _cmd, _cmd_len) == 0; } +}; + +// Iterator class taking a character string in input and returning a CmdLine +// instance for each command line. The argument delimiter has to be specified. +class DCmdIter : public StackObj { + friend class DCmd; +private: + const char* _str; + char _delim; + size_t _len; + size_t _cursor; +public: + + DCmdIter(const char* str, char delim) { + _str = str; + _delim = delim; + _len = strlen(str); + _cursor = 0; + } + bool has_next() { return _cursor < _len; } + CmdLine next() { + assert(_cursor <= _len, "Cannot iterate more"); + size_t n = _cursor; + while (n < _len && _str[n] != _delim) n++; + CmdLine line(&(_str[_cursor]), n - _cursor, false); + _cursor = n + 1; + // The default copy constructor of CmdLine is used to return a CmdLine + // instance to the caller. + return line; + } +}; + +// Iterator class to iterate over diagnostic command arguments +class DCmdArgIter : public ResourceObj { + const char* _buffer; + size_t _len; + size_t _cursor; + const char* _key_addr; + size_t _key_len; + const char* _value_addr; + size_t _value_len; + char _delim; +public: + DCmdArgIter(const char* buf, size_t len, char delim) { + _buffer = buf; + _len = len; + _delim = delim; + _cursor = 0; + } + bool next(TRAPS); + const char* key_addr() { return _key_addr; } + size_t key_length() { return _key_len; } + const char* value_addr() { return _value_addr; } + size_t value_length() { return _value_len; } +}; + +// A DCmdInfo instance provides a description of a diagnostic command. It is +// used to export the description to the JMX interface of the framework. +class DCmdInfo : public ResourceObj { +protected: + const char* _name; /* Name of the diagnostic command */ + const char* _description; /* Short description */ + const char* _impact; /* Impact on the JVM */ + JavaPermission _permission; /* Java Permission required to execute this command if any */ + int _num_arguments; /* Number of supported options or arguments */ + bool _is_enabled; /* True if the diagnostic command can be invoked, false otherwise */ +public: + DCmdInfo(const char* name, + const char* description, + const char* impact, + JavaPermission permission, + int num_arguments, + bool enabled) { + this->_name = name; + this->_description = description; + this->_impact = impact; + this->_permission = permission; + this->_num_arguments = num_arguments; + this->_is_enabled = enabled; + } + const char* name() const { return _name; } + const char* description() const { return _description; } + const char* impact() const { return _impact; } + JavaPermission permission() const { return _permission; } + int num_arguments() const { return _num_arguments; } + bool is_enabled() const { return _is_enabled; } + + static bool by_name(void* name, DCmdInfo* info); +}; + +// A DCmdArgumentInfo instance provides a description of a diagnostic command +// argument. It is used to export the description to the JMX interface of the +// framework. +class DCmdArgumentInfo : public ResourceObj { +protected: + const char* _name; /* Option/Argument name*/ + const char* _description; /* Short description */ + const char* _type; /* Type: STRING, BOOLEAN, etc. */ + const char* _default_string; /* Default value in a parsable string */ + bool _mandatory; /* True if the option/argument is mandatory */ + bool _option; /* True if it is an option, false if it is an argument */ + /* (see diagnosticFramework.hpp for option/argument definitions) */ + bool _multiple; /* True is the option can be specified several time */ + int _position; /* Expected position for this argument (this field is */ + /* meaningless for options) */ +public: + DCmdArgumentInfo(const char* name, const char* description, const char* type, + const char* default_string, bool mandatory, bool option, + bool multiple) { + this->_name = name; + this->_description = description; + this->_type = type; + this->_default_string = default_string; + this->_option = option; + this->_mandatory = mandatory; + this->_option = option; + this->_multiple = multiple; + this->_position = -1; + } + DCmdArgumentInfo(const char* name, const char* description, const char* type, + const char* default_string, bool mandatory, bool option, + bool multiple, int position) { + this->_name = name; + this->_description = description; + this->_type = type; + this->_default_string = default_string; + this->_option = option; + this->_mandatory = mandatory; + this->_option = option; + this->_multiple = multiple; + this->_position = position; + } + const char* name() const { return _name; } + const char* description() const { return _description; } + const char* type() const { return _type; } + const char* default_string() const { return _default_string; } + bool is_mandatory() const { return _mandatory; } + bool is_option() const { return _option; } + bool is_multiple() const { return _multiple; } + int position() const { return _position; } +}; + +// The DCmdParser class can be used to create an argument parser for a +// diagnostic command. It is not mandatory to use it to parse arguments. +// The DCmdParser parses a CmdLine instance according to the parameters that +// have been declared by its associated diagnostic command. A parameter can +// either be an option or an argument. Options are identified by the option name +// while arguments are identified by their position in the command line. The +// position of an argument is defined relative to all arguments passed on the +// command line, options are not considered when defining an argument position. +// The generic syntax of a diagnostic command is: +// +// [