提交 020220a6 编写于 作者: J jrose

Merge

......@@ -63,8 +63,6 @@ public class InstanceKlass extends Klass {
private static int CLASS_STATE_FULLY_INITIALIZED;
private static int CLASS_STATE_INITIALIZATION_ERROR;
private static int IS_MARKED_DEPENDENT_MASK;
private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
Type type = db.lookupType("instanceKlass");
arrayKlasses = new OopField(type.getOopField("_array_klasses"), Oop.getHeaderSize());
......@@ -92,7 +90,7 @@ public class InstanceKlass extends Klass {
staticFieldSize = new CIntField(type.getCIntegerField("_static_field_size"), Oop.getHeaderSize());
staticOopFieldCount = new CIntField(type.getCIntegerField("_static_oop_field_count"), Oop.getHeaderSize());
nonstaticOopMapSize = new CIntField(type.getCIntegerField("_nonstatic_oop_map_size"), Oop.getHeaderSize());
miscFlags = new CIntField(type.getCIntegerField("_misc_flags"), Oop.getHeaderSize());
isMarkedDependent = new CIntField(type.getCIntegerField("_is_marked_dependent"), Oop.getHeaderSize());
initState = new CIntField(type.getCIntegerField("_init_state"), Oop.getHeaderSize());
vtableLen = new CIntField(type.getCIntegerField("_vtable_len"), Oop.getHeaderSize());
itableLen = new CIntField(type.getCIntegerField("_itable_len"), Oop.getHeaderSize());
......@@ -120,8 +118,6 @@ public class InstanceKlass extends Klass {
CLASS_STATE_FULLY_INITIALIZED = db.lookupIntConstant("instanceKlass::fully_initialized").intValue();
CLASS_STATE_INITIALIZATION_ERROR = db.lookupIntConstant("instanceKlass::initialization_error").intValue();
IS_MARKED_DEPENDENT_MASK = db.lookupIntConstant("instanceKlass::IS_MARKED_DEPENDENT").intValue();
}
InstanceKlass(OopHandle handle, ObjectHeap heap) {
......@@ -155,7 +151,7 @@ public class InstanceKlass extends Klass {
private static CIntField staticFieldSize;
private static CIntField staticOopFieldCount;
private static CIntField nonstaticOopMapSize;
private static CIntField miscFlags;
private static CIntField isMarkedDependent;
private static CIntField initState;
private static CIntField vtableLen;
private static CIntField itableLen;
......@@ -337,7 +333,7 @@ public class InstanceKlass extends Klass {
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
public long getStaticOopFieldCount() { return staticOopFieldCount.getValue(this); }
public long getNonstaticOopMapSize() { return nonstaticOopMapSize.getValue(this); }
public boolean getIsMarkedDependent() { return (miscFlags.getValue(this) & IS_MARKED_DEPENDENT_MASK) != 0; }
public boolean getIsMarkedDependent() { return isMarkedDependent.getValue(this) != 0; }
public long getVtableLen() { return vtableLen.getValue(this); }
public long getItableLen() { return itableLen.getValue(this); }
public Symbol getGenericSignature() { return getSymbol(genericSignature); }
......@@ -528,7 +524,7 @@ public class InstanceKlass extends Klass {
visitor.doCInt(staticFieldSize, true);
visitor.doCInt(staticOopFieldCount, true);
visitor.doCInt(nonstaticOopMapSize, true);
visitor.doCInt(miscFlags, true);
visitor.doCInt(isMarkedDependent, true);
visitor.doCInt(initState, true);
visitor.doCInt(vtableLen, true);
visitor.doCInt(itableLen, true);
......
......@@ -296,6 +296,7 @@
template(finalize_method_name, "finalize") \
template(reference_lock_name, "lock") \
template(reference_discovered_name, "discovered") \
template(run_finalization_name, "runFinalization") \
template(run_finalizers_on_exit_name, "runFinalizersOnExit") \
template(uncaughtException_name, "uncaughtException") \
template(dispatchUncaughtException_name, "dispatchUncaughtException") \
......
......@@ -1631,7 +1631,7 @@ void KlassDepChange::initialize() {
for (ContextStream str(*this); str.next(); ) {
klassOop d = str.klass();
assert(!instanceKlass::cast(d)->is_marked_dependent(), "checking");
instanceKlass::cast(d)->set_is_marked_dependent();
instanceKlass::cast(d)->set_is_marked_dependent(true);
}
}
......@@ -1640,7 +1640,7 @@ KlassDepChange::~KlassDepChange() {
// Unmark transitive interfaces
for (ContextStream str(*this); str.next(); ) {
klassOop d = str.klass();
instanceKlass::cast(d)->clear_is_marked_dependent();
instanceKlass::cast(d)->set_is_marked_dependent(false);
}
}
......
......@@ -231,6 +231,10 @@ class instanceKlass: public Klass {
u2 _java_fields_count; // The number of declared Java fields
int _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
bool _is_marked_dependent; // used for marking during flushing and deoptimization
bool _rewritten; // methods rewritten.
bool _has_nonstatic_fields; // for sizing with UseCompressedOops
bool _should_verify_class; // allow caching of preverification
u2 _minor_version; // minor version number of class file
u2 _major_version; // major version number of class file
Thread* _init_thread; // Pointer to current thread doing initialization (to handle recusive initialization)
......@@ -261,19 +265,6 @@ class instanceKlass: public Klass {
// _idnum_allocated_count.
u1 _init_state; // state of class
// Compact the following four boolean flags into 1-bit each. These four flags
// were defined as separate boolean fields and each was 1-byte before. Since
// there are 2 bytes unused after the _idnum_allocated_count field, place the
// _misc_flags field after _idnum_allocated_count to utilize the unused bits
// and save total 4-bytes.
enum {
IS_MARKED_DEPENDENT = 0x1, // used for marking during flushing and deoptimization
REWRITTEN = 0x2, // methods rewritten.
HAS_NONSTATIC_FIELDS = 0x4, // for sizing with UseCompressedOops
SHOULD_VERIFY_CLASS = 0x8 // allow caching of preverification
};
u1 _misc_flags;
// embedded Java vtable follows here
// embedded Java itables follows here
// embedded static fields follows here
......@@ -283,14 +274,8 @@ class instanceKlass: public Klass {
friend class SystemDictionary;
public:
bool has_nonstatic_fields() const { return (_misc_flags & HAS_NONSTATIC_FIELDS) != 0; }
void set_has_nonstatic_fields(bool b) {
if (b) {
_misc_flags |= HAS_NONSTATIC_FIELDS;
} else {
_misc_flags &= ~HAS_NONSTATIC_FIELDS;
}
}
bool has_nonstatic_fields() const { return _has_nonstatic_fields; }
void set_has_nonstatic_fields(bool b) { _has_nonstatic_fields = b; }
// field sizes
int nonstatic_field_size() const { return _nonstatic_field_size; }
......@@ -398,23 +383,15 @@ class instanceKlass: public Klass {
bool is_in_error_state() const { return _init_state == initialization_error; }
bool is_reentrant_initialization(Thread *thread) { return thread == _init_thread; }
ClassState init_state() { return (ClassState)_init_state; }
bool is_rewritten() const { return (_misc_flags & REWRITTEN) != 0; }
bool is_rewritten() const { return _rewritten; }
// defineClass specified verification
bool should_verify_class() const { return (_misc_flags & SHOULD_VERIFY_CLASS) != 0; }
void set_should_verify_class(bool value) {
if (value) {
_misc_flags |= SHOULD_VERIFY_CLASS;
} else {
_misc_flags &= ~SHOULD_VERIFY_CLASS;
}
}
bool should_verify_class() const { return _should_verify_class; }
void set_should_verify_class(bool value) { _should_verify_class = value; }
// marking
bool is_marked_dependent() const { return (_misc_flags & IS_MARKED_DEPENDENT) != 0; }
void set_is_marked_dependent() { _misc_flags |= IS_MARKED_DEPENDENT; }
void clear_is_marked_dependent() { _misc_flags &= ~IS_MARKED_DEPENDENT; }
bool is_marked_dependent() const { return _is_marked_dependent; }
void set_is_marked_dependent(bool value) { _is_marked_dependent = value; }
// initialization (virtuals from Klass)
bool should_be_initialized() const; // means that initialize should be called
......@@ -784,7 +761,7 @@ private:
#else
void set_init_state(ClassState state) { _init_state = (u1)state; }
#endif
void set_rewritten() { _misc_flags |= REWRITTEN; }
void set_rewritten() { _rewritten = true; }
void set_init_thread(Thread *thread) { _init_thread = thread; }
u2 idnum_allocated_count() const { return _idnum_allocated_count; }
......
......@@ -399,7 +399,7 @@ instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int it
ik->set_inner_classes(NULL);
ik->set_static_oop_field_count(0);
ik->set_nonstatic_field_size(0);
ik->clear_is_marked_dependent();
ik->set_is_marked_dependent(false);
ik->set_init_state(instanceKlass::allocated);
ik->set_init_thread(NULL);
ik->set_reference_type(rt);
......
......@@ -2330,7 +2330,7 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
#ifndef PRODUCT
// -Xprintflags
} else if (match_option(option, "-Xprintflags", &tail)) {
CommandLineFlags::printFlags();
CommandLineFlags::printFlags(tty, false);
vm_exit(0);
#endif
// -D
......@@ -2978,13 +2978,13 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
IgnoreUnrecognizedVMOptions = false;
}
if (match_option(option, "-XX:+PrintFlagsInitial", &tail)) {
CommandLineFlags::printFlags();
CommandLineFlags::printFlags(tty, false);
vm_exit(0);
}
#ifndef PRODUCT
if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) {
CommandLineFlags::printFlags(true);
CommandLineFlags::printFlags(tty, true);
vm_exit(0);
}
#endif
......@@ -3180,7 +3180,7 @@ jint Arguments::parse(const JavaVMInitArgs* args) {
#endif
if (PrintCommandLineFlags) {
CommandLineFlags::printSetFlags();
CommandLineFlags::printSetFlags(tty);
}
// Apply CPU specific policy for the BiasedLocking
......
......@@ -488,7 +488,7 @@ extern "C" {
}
}
void CommandLineFlags::printSetFlags() {
void CommandLineFlags::printSetFlags(outputStream* out) {
// Print which flags were set on the command line
// note: this method is called before the thread structure is in place
// which means resource allocation cannot be used.
......@@ -507,11 +507,11 @@ void CommandLineFlags::printSetFlags() {
// Print
for (int i = 0; i < length; i++) {
if (array[i]->origin /* naked field! */) {
array[i]->print_as_flag(tty);
tty->print(" ");
array[i]->print_as_flag(out);
out->print(" ");
}
}
tty->cr();
out->cr();
FREE_C_HEAP_ARRAY(Flag*, array);
}
......@@ -524,7 +524,7 @@ void CommandLineFlags::verify() {
#endif // PRODUCT
void CommandLineFlags::printFlags(bool withComments) {
void CommandLineFlags::printFlags(outputStream* out, bool withComments) {
// Print the flags sorted by name
// note: this method is called before the thread structure is in place
// which means resource allocation cannot be used.
......@@ -541,10 +541,10 @@ void CommandLineFlags::printFlags(bool withComments) {
qsort(array, length, sizeof(Flag*), compare_flags);
// Print
tty->print_cr("[Global flags]");
out->print_cr("[Global flags]");
for (int i = 0; i < length; i++) {
if (array[i]->is_unlocked()) {
array[i]->print_on(tty, withComments);
array[i]->print_on(out, withComments);
}
}
FREE_C_HEAP_ARRAY(Flag*, array);
......
......@@ -326,9 +326,9 @@ class CommandLineFlags {
// Returns false if name is not a command line flag.
static bool wasSetOnCmdline(const char* name, bool* value);
static void printSetFlags();
static void printSetFlags(outputStream* out);
static void printFlags(bool withComments = false );
static void printFlags(outputStream* out, bool withComments);
static void verify() PRODUCT_RETURN;
};
......
......@@ -140,7 +140,7 @@ jint init_globals() {
// All the flags that get adjusted by VM_Version_init and os::init_2
// have been set so dump the flags now.
if (PrintFlagsFinal) {
CommandLineFlags::printFlags();
CommandLineFlags::printFlags(tty, false);
}
return JNI_OK;
......
......@@ -307,7 +307,7 @@ static inline uint64_t cast_uint64_t(size_t x)
nonstatic_field(instanceKlass, _static_field_size, int) \
nonstatic_field(instanceKlass, _static_oop_field_count, u2) \
nonstatic_field(instanceKlass, _nonstatic_oop_map_size, int) \
nonstatic_field(instanceKlass, _misc_flags, u1) \
nonstatic_field(instanceKlass, _is_marked_dependent, bool) \
nonstatic_field(instanceKlass, _minor_version, u2) \
nonstatic_field(instanceKlass, _major_version, u2) \
nonstatic_field(instanceKlass, _init_state, u1) \
......@@ -2386,7 +2386,6 @@ static inline uint64_t cast_uint64_t(size_t x)
declare_constant(instanceKlass::being_initialized) \
declare_constant(instanceKlass::fully_initialized) \
declare_constant(instanceKlass::initialization_error) \
declare_constant(instanceKlass::IS_MARKED_DEPENDENT) \
\
/*********************************/ \
/* Symbol* - symbol max length */ \
......
......@@ -99,6 +99,7 @@ static jint get_properties(AttachOperation* op, outputStream* out, Symbol* seria
}
// Implementation of "properties" command.
// See also: PrintSystemPropertiesDCmd class
static jint get_system_properties(AttachOperation* op, outputStream* out) {
return get_properties(op, out, vmSymbols::serializePropertiesToByteArray_name());
}
......@@ -127,6 +128,7 @@ static jint data_dump(AttachOperation* op, outputStream* out) {
}
// Implementation of "threaddump" command - essentially a remote ctrl-break
// See also: ThreadDumpDCmd class
//
static jint thread_dump(AttachOperation* op, outputStream* out) {
bool print_concurrent_locks = false;
......@@ -158,6 +160,7 @@ static jint jcmd(AttachOperation* op, outputStream* out) {
DCmd::parse_and_execute(out, op->arg(0), ' ', THREAD);
if (HAS_PENDING_EXCEPTION) {
java_lang_Throwable::print(PENDING_EXCEPTION, out);
out->cr();
CLEAR_PENDING_EXCEPTION;
// The exception has been printed on the output stream
// If the JVM returns JNI_ERR, the attachAPI throws a generic I/O
......@@ -169,6 +172,7 @@ static jint jcmd(AttachOperation* op, outputStream* out) {
#ifndef SERVICES_KERNEL // Heap dumping not supported
// Implementation of "dumpheap" command.
// See also: HeapDumpDCmd class
//
// Input arguments :-
// arg0: Name of the dump file
......@@ -211,6 +215,7 @@ jint dump_heap(AttachOperation* op, outputStream* out) {
#endif // SERVICES_KERNEL
// Implementation of "inspectheap" command
// See also: ClassHistogramDCmd class
//
// Input arguments :-
// arg0: "-live" or "-all"
......@@ -354,6 +359,7 @@ static jint set_flag(AttachOperation* op, outputStream* out) {
}
// Implementation of "printflag" command
// See also: PrintVMFlagsDCmd class
static jint print_flag(AttachOperation* op, outputStream* out) {
const char* name = NULL;
if ((name = op->arg(0)) == NULL) {
......
......@@ -23,11 +23,15 @@
*/
#include "precompiled.hpp"
#include "gc_implementation/shared/vmGCOperations.hpp"
#include "runtime/javaCalls.hpp"
#include "services/diagnosticArgument.hpp"
#include "services/diagnosticCommand.hpp"
#include "services/diagnosticFramework.hpp"
#include "services/heapDumper.hpp"
#include "services/management.hpp"
HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmd(output, heap),
HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap),
_all("-all", "Show help for all commands", "BOOLEAN", false, "false"),
_cmd("command name", "The name of the command for which we want help",
"STRING", false) {
......@@ -35,14 +39,6 @@ HelpDCmd::HelpDCmd(outputStream* output, bool heap) : DCmd(output, heap),
_dcmdparser.add_dcmd_argument(&_cmd);
};
void HelpDCmd::parse(CmdLine* line, char delim, TRAPS) {
_dcmdparser.parse(line, delim, CHECK);
}
void HelpDCmd::print_help(outputStream* out) {
_dcmdparser.print_help(out, name());
}
void HelpDCmd::execute(TRAPS) {
if (_all.value()) {
GrowableArray<const char*>* cmd_list = DCmdFactory::DCmd_list();
......@@ -66,10 +62,11 @@ void HelpDCmd::execute(TRAPS) {
factory->is_enabled() ? "" : " [disabled]");
output()->print_cr(factory->description());
output()->print_cr("\nImpact: %s", factory->impact());
output()->cr();
cmd = factory->create_resource_instance(output());
if (cmd != NULL) {
DCmdMark mark(cmd);
cmd->print_help(output());
cmd->print_help(factory->name());
}
} else {
output()->print_cr("Help unavailable : '%s' : No such command", _cmd.value());
......@@ -90,14 +87,6 @@ void HelpDCmd::execute(TRAPS) {
}
}
void HelpDCmd::reset(TRAPS) {
_dcmdparser.reset(CHECK);
}
void HelpDCmd::cleanup() {
_dcmdparser.cleanup();
}
int HelpDCmd::num_arguments() {
ResourceMark rm;
HelpDCmd* dcmd = new HelpDCmd(NULL, false);
......@@ -109,14 +98,6 @@ int HelpDCmd::num_arguments() {
}
}
GrowableArray<const char*>* HelpDCmd::argument_name_array() {
return _dcmdparser.argument_name_array();
}
GrowableArray<DCmdArgumentInfo*>* HelpDCmd::argument_info_array() {
return _dcmdparser.argument_info_array();
}
void VersionDCmd::execute(TRAPS) {
output()->print_cr("%s version %s", Abstract_VM_Version::vm_name(),
Abstract_VM_Version::vm_release());
......@@ -129,3 +110,210 @@ void VersionDCmd::execute(TRAPS) {
jdk_version.minor_version());
}
}
PrintVMFlagsDCmd::PrintVMFlagsDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_all("-all", "Print all flags supported by the VM", "BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_all);
}
void PrintVMFlagsDCmd::execute(TRAPS) {
if (_all.value()) {
CommandLineFlags::printFlags(output(), true);
} else {
CommandLineFlags::printSetFlags(output());
}
}
int PrintVMFlagsDCmd::num_arguments() {
ResourceMark rm;
PrintVMFlagsDCmd* dcmd = new PrintVMFlagsDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
void PrintSystemPropertiesDCmd::execute(TRAPS) {
// load sun.misc.VMSupport
Symbol* klass = vmSymbols::sun_misc_VMSupport();
klassOop k = SystemDictionary::resolve_or_fail(klass, true, CHECK);
instanceKlassHandle ik (THREAD, k);
if (ik->should_be_initialized()) {
ik->initialize(THREAD);
}
if (HAS_PENDING_EXCEPTION) {
java_lang_Throwable::print(PENDING_EXCEPTION, output());
output()->cr();
CLEAR_PENDING_EXCEPTION;
return;
}
// invoke the serializePropertiesToByteArray method
JavaValue result(T_OBJECT);
JavaCallArguments args;
Symbol* signature = vmSymbols::serializePropertiesToByteArray_signature();
JavaCalls::call_static(&result,
ik,
vmSymbols::serializePropertiesToByteArray_name(),
signature,
&args,
THREAD);
if (HAS_PENDING_EXCEPTION) {
java_lang_Throwable::print(PENDING_EXCEPTION, output());
output()->cr();
CLEAR_PENDING_EXCEPTION;
return;
}
// The result should be a [B
oop res = (oop)result.get_jobject();
assert(res->is_typeArray(), "just checking");
assert(typeArrayKlass::cast(res->klass())->element_type() == T_BYTE, "just checking");
// copy the bytes to the output stream
typeArrayOop ba = typeArrayOop(res);
jbyte* addr = typeArrayOop(res)->byte_at_addr(0);
output()->print_raw((const char*)addr, ba->length());
}
VMUptimeDCmd::VMUptimeDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_date("-date", "Add a prefix with current date", "BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_date);
}
void VMUptimeDCmd::execute(TRAPS) {
if (_date.value()) {
output()->date_stamp(true, "", ": ");
}
output()->time_stamp().update_to(tty->time_stamp().ticks());
output()->stamp();
output()->print_cr(" s");
}
int VMUptimeDCmd::num_arguments() {
ResourceMark rm;
VMUptimeDCmd* dcmd = new VMUptimeDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
void SystemGCDCmd::execute(TRAPS) {
Universe::heap()->collect(GCCause::_java_lang_system_gc);
}
void RunFinalizationDCmd::execute(TRAPS) {
klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_System(),
true, CHECK);
instanceKlassHandle klass(THREAD, k);
JavaValue result(T_VOID);
JavaCalls::call_static(&result, klass,
vmSymbols::run_finalization_name(),
vmSymbols::void_method_signature(), CHECK);
}
#ifndef SERVICES_KERNEL // Heap dumping not supported
HeapDumpDCmd::HeapDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_filename("filename","Name of the dump file", "STRING",true),
_all("-all", "Dump all objects, including unreachable objects",
"BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_all);
_dcmdparser.add_dcmd_argument(&_filename);
}
void HeapDumpDCmd::execute(TRAPS) {
// Request a full GC before heap dump if _all is false
// This helps reduces the amount of unreachable objects in the dump
// and makes it easier to browse.
HeapDumper dumper(!_all.value() /* request GC if _all is false*/);
int res = dumper.dump(_filename.value());
if (res == 0) {
output()->print_cr("Heap dump file created");
} else {
// heap dump failed
ResourceMark rm;
char* error = dumper.error_as_C_string();
if (error == NULL) {
output()->print_cr("Dump failed - reason unknown");
} else {
output()->print_cr("%s", error);
}
}
}
int HeapDumpDCmd::num_arguments() {
ResourceMark rm;
HeapDumpDCmd* dcmd = new HeapDumpDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
#endif // SERVICES_KERNEL
ClassHistogramDCmd::ClassHistogramDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_all("-all", "Inspect all objects, including unreachable objects",
"BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_all);
}
void ClassHistogramDCmd::execute(TRAPS) {
VM_GC_HeapInspection heapop(output(),
!_all.value() /* request full gc if false */,
true /* need_prologue */);
VMThread::execute(&heapop);
}
int ClassHistogramDCmd::num_arguments() {
ResourceMark rm;
ClassHistogramDCmd* dcmd = new ClassHistogramDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
ThreadDumpDCmd::ThreadDumpDCmd(outputStream* output, bool heap) :
DCmdWithParser(output, heap),
_locks("-l", "print java.util.concurrent locks", "BOOLEAN", false, "false") {
_dcmdparser.add_dcmd_option(&_locks);
}
void ThreadDumpDCmd::execute(TRAPS) {
// thread stacks
VM_PrintThreads op1(output(), _locks.value());
VMThread::execute(&op1);
// JNI global handles
VM_PrintJNI op2(output());
VMThread::execute(&op2);
// Deadlock detection
VM_FindDeadlocks op3(output());
VMThread::execute(&op3);
}
int ThreadDumpDCmd::num_arguments() {
ResourceMark rm;
ThreadDumpDCmd* dcmd = new ThreadDumpDCmd(NULL, false);
if (dcmd != NULL) {
DCmdMark mark(dcmd);
return dcmd->_dcmdparser.num_arguments();
} else {
return 0;
}
}
......@@ -35,9 +35,8 @@
#include "services/diagnosticCommand.hpp"
#include "services/diagnosticFramework.hpp"
class HelpDCmd : public DCmd {
class HelpDCmd : public DCmdWithParser {
protected:
DCmdParser _dcmdparser;
DCmdArgument<bool> _all;
DCmdArgument<char*> _cmd;
public:
......@@ -50,13 +49,7 @@ public:
}
static const char* impact() { return "Low: "; }
static int num_arguments();
virtual void parse(CmdLine* line, char delim, TRAPS);
virtual void execute(TRAPS);
virtual void reset(TRAPS);
virtual void cleanup();
virtual void print_help(outputStream* out);
virtual GrowableArray<const char*>* argument_name_array();
virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array();
};
class VersionDCmd : public DCmd {
......@@ -68,9 +61,156 @@ public:
}
static const char* impact() { return "Low: "; }
static int num_arguments() { return 0; }
virtual void parse(CmdLine* line, char delim, TRAPS) { }
virtual void execute(TRAPS);
virtual void print_help(outputStream* out) { }
};
class CommandLineDCmd : public DCmd {
public:
CommandLineDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "VM.command_line"; }
static const char* description() {
return "Print the command line used to start this VM instance.";
}
static const char* impact() { return "Low: "; }
static int num_arguments() { return 0; }
virtual void execute(TRAPS) {
Arguments::print_on(_output);
}
};
// See also: get_system_properties in attachListener.cpp
class PrintSystemPropertiesDCmd : public DCmd {
public:
PrintSystemPropertiesDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "VM.system_properties"; }
static const char* description() {
return "Print system properties.";
}
static const char* impact() {
return "Low: ";
}
static int num_arguments() { return 0; }
virtual void execute(TRAPS);
};
// See also: print_flag in attachListener.cpp
class PrintVMFlagsDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _all;
public:
PrintVMFlagsDCmd(outputStream* output, bool heap);
static const char* name() { return "VM.flags"; }
static const char* description() {
return "Print VM flag options and their current values.";
}
static const char* impact() {
return "Low: ";
}
static int num_arguments();
virtual void execute(TRAPS);
};
class VMUptimeDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _date;
public:
VMUptimeDCmd(outputStream* output, bool heap);
static const char* name() { return "VM.uptime"; }
static const char* description() {
return "Print VM uptime.";
}
static const char* impact() {
return "Low: ";
}
static int num_arguments();
virtual void execute(TRAPS);
};
class SystemGCDCmd : public DCmd {
public:
SystemGCDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "GC.run"; }
static const char* description() {
return "Call java.lang.System.gc().";
}
static const char* impact() {
return "Medium: Depends on Java heap size and content.";
}
static int num_arguments() { return 0; }
virtual void execute(TRAPS);
};
class RunFinalizationDCmd : public DCmd {
public:
RunFinalizationDCmd(outputStream* output, bool heap) : DCmd(output, heap) { }
static const char* name() { return "GC.run_finalization"; }
static const char* description() {
return "Call java.lang.System.runFinalization().";
}
static const char* impact() {
return "Medium: Depends on Java content.";
}
static int num_arguments() { return 0; }
virtual void execute(TRAPS);
};
#ifndef SERVICES_KERNEL // Heap dumping not supported
// See also: dump_heap in attachListener.cpp
class HeapDumpDCmd : public DCmdWithParser {
protected:
DCmdArgument<char*> _filename;
DCmdArgument<bool> _all;
public:
HeapDumpDCmd(outputStream* output, bool heap);
static const char* name() {
return "GC.heap_dump";
}
static const char* description() {
return "Generate a HPROF format dump of the Java heap.";
}
static const char* impact() {
return "High: Depends on Java heap size and content. "
"Request a full GC unless the '-all' option is specified.";
}
static int num_arguments();
virtual void execute(TRAPS);
};
#endif // SERVICES_KERNEL
// See also: inspeactheap in attachListener.cpp
class ClassHistogramDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _all;
public:
ClassHistogramDCmd(outputStream* output, bool heap);
static const char* name() {
return "GC.class_histogram";
}
static const char* description() {
return "Provide statistics about the Java heap usage.";
}
static const char* impact() {
return "High: Depends on Java heap size and content.";
}
static int num_arguments();
virtual void execute(TRAPS);
};
// See also: thread_dump in attachListener.cpp
class ThreadDumpDCmd : public DCmdWithParser {
protected:
DCmdArgument<bool> _locks;
public:
ThreadDumpDCmd(outputStream* output, bool heap);
static const char* name() { return "Thread.print"; }
static const char* description() {
return "Print all threads with stacktraces.";
}
static const char* impact() {
return "Medium: Depends on the number of threads.";
}
static int num_arguments();
virtual void execute(TRAPS);
};
#endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
......@@ -226,7 +226,7 @@ void DCmdParser::check(TRAPS) {
}
void DCmdParser::print_help(outputStream* out, const char* cmd_name) {
out->print("\nSyntax : %s %s", cmd_name, _options == NULL ? "" : "[options]");
out->print("Syntax : %s %s", cmd_name, _options == NULL ? "" : "[options]");
GenDCmdArgument* arg = _arguments_list;
while (arg != NULL) {
if (arg->is_mandatory()) {
......@@ -373,6 +373,30 @@ void DCmd::parse_and_execute(outputStream* out, const char* cmdline,
}
}
void DCmdWithParser::parse(CmdLine* line, char delim, TRAPS) {
_dcmdparser.parse(line, delim, CHECK);
}
void DCmdWithParser::print_help(const char* name) {
_dcmdparser.print_help(output(), name);
}
void DCmdWithParser::reset(TRAPS) {
_dcmdparser.reset(CHECK);
}
void DCmdWithParser::cleanup() {
_dcmdparser.cleanup();
}
GrowableArray<const char*>* DCmdWithParser::argument_name_array() {
return _dcmdparser.argument_name_array();
}
GrowableArray<DCmdArgumentInfo*>* DCmdWithParser::argument_info_array() {
return _dcmdparser.argument_info_array();
}
Mutex* DCmdFactory::_dcmdFactory_lock = new Mutex(Mutex::leaf, "DCmdFactory", true);
DCmdFactory* DCmdFactory::factory(const char* name, size_t len) {
......
......@@ -241,8 +241,17 @@ public:
static int num_arguments() { return 0; }
outputStream* output() { return _output; }
bool is_heap_allocated() { return _is_heap_allocated; }
virtual void print_help(outputStream* out) { };
virtual void parse(CmdLine* line, char delim, TRAPS) { }
virtual void print_help(const char* name) {
output()->print_cr("Syntax: %s", name);
}
virtual void parse(CmdLine* line, char delim, TRAPS) {
DCmdArgIter iter(line->args_addr(), line->args_len(), delim);
bool has_arg = iter.next(CHECK);
if (has_arg) {
THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
"Unknown argument in diagnostic command");
}
}
virtual void execute(TRAPS) { }
virtual void reset(TRAPS) { }
virtual void cleanup() { }
......@@ -262,6 +271,25 @@ public:
char delim, TRAPS);
};
class DCmdWithParser : public DCmd {
protected:
DCmdParser _dcmdparser;
public:
DCmdWithParser (outputStream *output, bool heap=false) : DCmd(output, heap) { }
static const char* name() { return "No Name";}
static const char* description() { return "No Help";}
static const char* disabled_message() { return "Diagnostic command currently disabled"; }
static const char* impact() { return "Low: No impact"; }
static int num_arguments() { return 0; }
virtual void parse(CmdLine *line, char delim, TRAPS);
virtual void execute(TRAPS) { }
virtual void reset(TRAPS);
virtual void cleanup();
virtual void print_help(const char* name);
virtual GrowableArray<const char*>* argument_name_array();
virtual GrowableArray<DCmdArgumentInfo*>* argument_info_array();
};
class DCmdMark : public StackObj {
DCmd* _ref;
public:
......
......@@ -118,8 +118,22 @@ void Management::init() {
#endif // SERVICES_KERNEL
_optional_support.isThreadAllocatedMemorySupported = 1;
// Registration of the diagnostic commands
// First boolean argument specifies if the command is enabled
// Second boolean argument specifies if the command is hidden
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HelpDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VersionDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CommandLineDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintSystemPropertiesDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<PrintVMFlagsDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<VMUptimeDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<SystemGCDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RunFinalizationDCmd>(true, false));
#ifndef SERVICES_KERNEL // Heap dumping not supported
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<HeapDumpDCmd>(true, false));
#endif // SERVICES_KERNEL
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassHistogramDCmd>(true, false));
DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(true, false));
}
void Management::initialize(TRAPS) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册