/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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.
*
*/
#include "classfile/vmSymbols.hpp"
#include "memory/allocation.hpp"
#include "runtime/arguments.hpp"
#include "runtime/vm_version.hpp"
#include "runtime/vmThread.hpp"
#include "utilities/ostream.hpp"
// 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
private:
const char* _cmd;
const char* _args;
public:
};
// Iterator class taking a character string in input and returning a CmdLine
// instance for each command line. The argument delimiter has to be specified.
friend class DCmd;
private:
const char* _str;
char _delim;
public:
_cursor = 0;
}
_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
const char* _buffer;
const char* _key_addr;
const char* _value_addr;
char _delim;
public:
_cursor = 0;
}
};
// A DCmdInfo instance provides a description of a diagnostic command. It is
// used to export the description to the JMX interface of the framework.
protected:
const char* _name;
const char* _description;
const char* _impact;
int _num_arguments;
bool _is_enabled;
public:
const char* description,
const char* impact,
int num_arguments,
bool enabled) {
this->_description = description;
this->_num_arguments = num_arguments;
this->_is_enabled = enabled;
}
};
// 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.
protected:
const char* _name;
const char* _description;
const char* _type;
const char* _default_string;
bool _mandatory;
bool _option;
int _position;
public:
this->_description = description;
this->_default_string = default_string;
this->_mandatory = mandatory;
this->_position = -1;
}
int position) {
this->_description = description;
this->_default_string = default_string;
this->_mandatory = mandatory;
}
};
// 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.
class DCmdParser {
private:
char _delim;
public:
DCmdParser() {
_delim = ' ';
}
void cleanup();
int num_arguments();
GrowableArray<const char*>* argument_name_array();
};
// The DCmd class is the parent class of all diagnostic commands
// Diagnostic command instances should not be instantiated directly but
// created using the associated factory. The factory can be retrieved with
// the DCmdFactory::getFactory() method.
// A diagnostic command instance can either be allocated in the resource Area
// or in the C-heap. Allocation in the resource area is recommended when the
// current thread is the only one which will access the diagnostic command
// instance. Allocation in the C-heap is required when the diagnostic command
// is accessed by several threads (for instance to perform asynchronous
// execution).
// To ensure a proper cleanup, it's highly recommended to use a DCmdMark for
// each diagnostic command instance. In case of a C-heap allocated diagnostic
// command instance, the DCmdMark must be created in the context of the last
// thread that will access the instance.
protected:
bool _is_heap_allocated;
public:
}
// The impact() method returns a description of the intrusiveness of the diagnostic
// command on the Java Virtual Machine behavior. The rational for this method is that some
// diagnostic commands can seriously disrupt the behavior of the Java Virtual Machine
// (for instance a Thread Dump for an application with several tens of thousands of threads,
// or a Head Dump with a 40GB+ heap size) and other diagnostic commands have no serious
// impact on the JVM (for instance, getting the command line arguments or the JVM version).
// The recommended format for the description is <impact level>: [longer description],
// where the impact level is selected among this list: {Low, Medium, High}. The optional
// longer description can provide more specific details like the fact that Thread Dump
// impact depends on the heap size.
static int num_arguments() { return 0; }
}
if (has_arg) {
"The argument list of this diagnostic command should be empty.");
}
}
virtual void cleanup() { }
// support for the JMX interface
return array;
}
return array;
}
// main method to invoke the framework
};
protected:
public:
static int num_arguments() { return 0; }
virtual void cleanup();
virtual void print_help(const char* name);
virtual GrowableArray<const char*>* argument_name_array();
};
public:
~DCmdMark() {
if (_ref->is_heap_allocated()) {
delete _ref;
}
}
}
};
// Diagnostic commands are not directly instantiated but created with a factory.
// Each diagnostic command class has its own factory. The DCmdFactory class also
// manages the status of the diagnostic command (hidden, enabled). A DCmdFactory
// has to be registered to make the diagnostic command available (see
// management.cpp)
private:
// Pointer to the next factory in the singly-linked list of registered
// diagnostic commands
// When disabled, a diagnostic command cannot be executed. Any attempt to
// execute it will result in the printing of the disabled message without
// instantiating the command.
bool _enabled;
// When hidden, a diagnostic command doesn't appear in the list of commands
// provided by the 'help' command.
bool _hidden;
int _num_arguments;
public:
}
virtual const char* name() const = 0;
virtual const char* description() const = 0;
virtual const char* impact() const = 0;
virtual const char* disabled_message() const = 0;
// Register a DCmdFactory to make a diagnostic command available.
// Once registered, a diagnostic command must not be unregistered.
// To prevent a diagnostic command from being executed, just set the
// enabled flag to false.
// Returns a C-heap allocated diagnostic command for the given command line
// Returns a resourceArea allocated diagnostic command for the given command line
static GrowableArray<const char*>* DCmd_list();
friend class HelpDCmd;
};
// Template to easily create DCmdFactory instances. See management.cpp
// where this template is used to create and register factories.
public:
// Returns a C-heap allocated instance
}
// Returns a resourceArea allocated instance
}
virtual const char* name() const {
}
virtual const char* description() const {
return DCmdClass::description();
}
virtual const char* impact() const {
}
virtual const char* disabled_message() const {
return DCmdClass::disabled_message();
}
};
// This class provides a convenient way to register Dcmds, without a need to change
// management.cpp every time. Body of these two methods resides in
private:
static void register_dcmds();
static void register_dcmds_ext();
friend class Management;
};
#endif // SHARE_VM_SERVICES_DIAGNOSTICFRAMEWORK_HPP