提交 ab2b4385 编写于 作者: R roland

8037970: make PrintMethodData a diagnostic options

Summary: make PrintMethodData a diagnostic options for performance investigation
Reviewed-by: kvn, iveresov
上级 c27343de
......@@ -135,6 +135,14 @@ void ClassLoaderData::classes_do(void f(Klass * const)) {
}
}
void ClassLoaderData::methods_do(void f(Method*)) {
for (Klass* k = _klasses; k != NULL; k = k->next_link()) {
if (k->oop_is_instance()) {
InstanceKlass::cast(k)->methods_do(f);
}
}
}
void ClassLoaderData::loaded_classes_do(KlassClosure* klass_closure) {
// Lock to avoid classes being modified/added/removed during iteration
MutexLockerEx ml(metaspace_lock(), Mutex::_no_safepoint_check_flag);
......@@ -624,6 +632,12 @@ void ClassLoaderDataGraph::classes_do(void f(Klass* const)) {
}
}
void ClassLoaderDataGraph::methods_do(void f(Method*)) {
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
cld->methods_do(f);
}
}
void ClassLoaderDataGraph::loaded_classes_do(KlassClosure* klass_closure) {
for (ClassLoaderData* cld = _head; cld != NULL; cld = cld->next()) {
cld->loaded_classes_do(klass_closure);
......
......@@ -78,6 +78,7 @@ class ClassLoaderDataGraph : public AllStatic {
static void keep_alive_oops_do(OopClosure* blk, KlassClosure* klass_closure, bool must_claim);
static void classes_do(KlassClosure* klass_closure);
static void classes_do(void f(Klass* const));
static void methods_do(void f(Method*));
static void loaded_classes_do(KlassClosure* klass_closure);
static void classes_unloading_do(void f(Klass* const));
static bool do_unloading(BoolObjectClosure* is_alive);
......@@ -189,6 +190,7 @@ class ClassLoaderData : public CHeapObj<mtClass> {
void classes_do(void f(Klass*));
void loaded_classes_do(KlassClosure* klass_closure);
void classes_do(void f(InstanceKlass*));
void methods_do(void f(Method*));
// Deallocate free list during class unloading.
void free_deallocate_list();
......
......@@ -35,8 +35,6 @@
#include "runtime/timer.hpp"
#ifndef PRODUCT
// Standard closure for BytecodeTracer: prints the current bytecode
// and its attributes using bytecode-specific information.
......@@ -600,4 +598,3 @@ void BytecodePrinter::bytecode_epilog(int bci, outputStream* st) {
}
}
}
#endif // PRODUCT
......@@ -34,8 +34,7 @@
// By specialising the BytecodeClosure, all kinds of bytecode traces can
// be done.
#ifndef PRODUCT
// class BytecodeTracer is only used by TraceBytecodes option
// class BytecodeTracer is used by TraceBytecodes option and PrintMethodData
class BytecodeClosure;
class BytecodeTracer: AllStatic {
......@@ -60,6 +59,4 @@ class BytecodeClosure {
virtual void trace(methodHandle method, address bcp, outputStream* st) = 0;
};
#endif // !PRODUCT
#endif // SHARE_VM_INTERPRETER_BYTECODETRACER_HPP
......@@ -329,14 +329,12 @@ bool Method::was_executed_more_than(int n) {
}
}
#ifndef PRODUCT
void Method::print_invocation_count() {
if (is_static()) tty->print("static ");
if (is_final()) tty->print("final ");
if (is_synchronized()) tty->print("synchronized ");
if (is_native()) tty->print("native ");
method_holder()->name()->print_symbol_on(tty);
tty->print(".");
tty->print("%s::", method_holder()->external_name());
name()->print_symbol_on(tty);
signature()->print_symbol_on(tty);
......@@ -349,12 +347,12 @@ void Method::print_invocation_count() {
tty->print_cr (" interpreter_invocation_count: %8d ", interpreter_invocation_count());
tty->print_cr (" invocation_counter: %8d ", invocation_count());
tty->print_cr (" backedge_counter: %8d ", backedge_count());
#ifndef PRODUCT
if (CountCompiledCalls) {
tty->print_cr (" compiled_invocation_count: %8d ", compiled_invocation_count());
}
}
#endif
}
// Build a MethodData* object to hold information about this method
// collected in the interpreter.
......@@ -1443,10 +1441,6 @@ void Method::print_name(outputStream* st) {
#endif // !PRODUCT || INCLUDE_JVMTI
//-----------------------------------------------------------------------------------
// Non-product code
#ifndef PRODUCT
void Method::print_codes_on(outputStream* st) const {
print_codes_on(0, code_size(), st);
}
......@@ -1460,7 +1454,6 @@ void Method::print_codes_on(int from, int to, outputStream* st) const {
BytecodeTracer::set_closure(BytecodeTracer::std_closure());
while (s.next() >= 0) BytecodeTracer::trace(mh, s.bcp(), st);
}
#endif // not PRODUCT
// Simple compression of line number tables. We use a regular compressed stream, except that we compress deltas
......
......@@ -429,6 +429,9 @@ class Method : public Metadata {
#ifndef PRODUCT
int compiled_invocation_count() const { return _compiled_invocation_count; }
void set_compiled_invocation_count(int count) { _compiled_invocation_count = count; }
#else
// for PrintMethodData in a product build
int compiled_invocation_count() const { return 0; }
#endif // not PRODUCT
// Clear (non-shared space) pointers which could not be relevant
......@@ -497,10 +500,8 @@ class Method : public Metadata {
// Interpreter oopmap support
void mask_for(int bci, InterpreterOopMap* mask);
#ifndef PRODUCT
// operations on invocation counter
void print_invocation_count();
#endif
// byte codes
void set_code(address code) { return constMethod()->set_code(code); }
......@@ -509,8 +510,8 @@ class Method : public Metadata {
// prints byte codes
void print_codes() const { print_codes_on(tty); }
void print_codes_on(outputStream* st) const PRODUCT_RETURN;
void print_codes_on(int from, int to, outputStream* st) const PRODUCT_RETURN;
void print_codes_on(outputStream* st) const;
void print_codes_on(int from, int to, outputStream* st) const;
// method parameters
bool has_method_parameters() const
......
......@@ -115,7 +115,6 @@ void ProfileData::print_data_on(outputStream* st, const MethodData* md) const {
print_data_on(st, print_data_on_helper(md));
}
#ifndef PRODUCT
void ProfileData::print_shared(outputStream* st, const char* name, const char* extra) const {
st->print("bci: %d", bci());
st->fill_to(tab_width_one);
......@@ -138,7 +137,6 @@ void ProfileData::print_shared(outputStream* st, const char* name, const char* e
void ProfileData::tab(outputStream* st, bool first) const {
st->fill_to(first ? tab_width_one : tab_width_two);
}
#endif // !PRODUCT
// ==================================================================
// BitData
......@@ -147,23 +145,19 @@ void ProfileData::tab(outputStream* st, bool first) const {
// whether a checkcast bytecode has seen a null value.
#ifndef PRODUCT
void BitData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "BitData", extra);
}
#endif // !PRODUCT
// ==================================================================
// CounterData
//
// A CounterData corresponds to a simple counter.
#ifndef PRODUCT
void CounterData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "CounterData", extra);
st->print_cr("count(%u)", count());
}
#endif // !PRODUCT
// ==================================================================
// JumpData
......@@ -188,12 +182,10 @@ void JumpData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
set_displacement(offset);
}
#ifndef PRODUCT
void JumpData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "JumpData", extra);
st->print_cr("taken(%u) displacement(%d)", taken(), displacement());
}
#endif // !PRODUCT
int TypeStackSlotEntries::compute_cell_count(Symbol* signature, bool include_receiver, int max) {
// Parameter profiling include the receiver
......@@ -342,7 +334,6 @@ bool TypeEntriesAtCall::arguments_profiling_enabled() {
return MethodData::profile_arguments();
}
#ifndef PRODUCT
void TypeEntries::print_klass(outputStream* st, intptr_t k) {
if (is_type_none(k)) {
st->print("none");
......@@ -398,7 +389,6 @@ void VirtualCallTypeData::print_data_on(outputStream* st, const char* extra) con
_ret.print_data_on(st);
}
}
#endif
// ==================================================================
// ReceiverTypeData
......@@ -417,7 +407,6 @@ void ReceiverTypeData::clean_weak_klass_links(BoolObjectClosure* is_alive_cl) {
}
}
#ifndef PRODUCT
void ReceiverTypeData::print_receiver_data_on(outputStream* st) const {
uint row;
int entries = 0;
......@@ -447,7 +436,6 @@ void VirtualCallData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "VirtualCallData", extra);
print_receiver_data_on(st);
}
#endif // !PRODUCT
// ==================================================================
// RetData
......@@ -499,7 +487,6 @@ DataLayout* RetData::advance(MethodData *md, int bci) {
}
#endif // CC_INTERP
#ifndef PRODUCT
void RetData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "RetData", extra);
uint row;
......@@ -516,7 +503,6 @@ void RetData::print_data_on(outputStream* st, const char* extra) const {
}
}
}
#endif // !PRODUCT
// ==================================================================
// BranchData
......@@ -534,7 +520,6 @@ void BranchData::post_initialize(BytecodeStream* stream, MethodData* mdo) {
set_displacement(offset);
}
#ifndef PRODUCT
void BranchData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "BranchData", extra);
st->print_cr("taken(%u) displacement(%d)",
......@@ -542,7 +527,6 @@ void BranchData::print_data_on(outputStream* st, const char* extra) const {
tab(st);
st->print_cr("not taken(%u)", not_taken());
}
#endif
// ==================================================================
// MultiBranchData
......@@ -608,7 +592,6 @@ void MultiBranchData::post_initialize(BytecodeStream* stream,
}
}
#ifndef PRODUCT
void MultiBranchData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "MultiBranchData", extra);
st->print_cr("default_count(%u) displacement(%d)",
......@@ -620,9 +603,7 @@ void MultiBranchData::print_data_on(outputStream* st, const char* extra) const {
count_at(i), displacement_at(i));
}
}
#endif
#ifndef PRODUCT
void ArgInfoData::print_data_on(outputStream* st, const char* extra) const {
print_shared(st, "ArgInfoData", extra);
int nargs = number_of_args();
......@@ -632,8 +613,6 @@ void ArgInfoData::print_data_on(outputStream* st, const char* extra) const {
st->cr();
}
#endif
int ParametersTypeData::compute_cell_count(Method* m) {
if (!MethodData::profile_parameters_for_method(m)) {
return 0;
......@@ -654,7 +633,6 @@ bool ParametersTypeData::profiling_enabled() {
return MethodData::profile_parameters();
}
#ifndef PRODUCT
void ParametersTypeData::print_data_on(outputStream* st, const char* extra) const {
st->print("parameter types", extra);
_parameters.print_data_on(st);
......@@ -666,7 +644,6 @@ void SpeculativeTrapData::print_data_on(outputStream* st, const char* extra) con
method()->print_short_name(st);
st->cr();
}
#endif
// ==================================================================
// MethodData*
......@@ -1359,8 +1336,6 @@ ArgInfoData *MethodData::arg_info() {
// Printing
#ifndef PRODUCT
void MethodData::print_on(outputStream* st) const {
assert(is_methodData(), "should be method data");
st->print("method data for ");
......@@ -1369,15 +1344,12 @@ void MethodData::print_on(outputStream* st) const {
print_data_on(st);
}
#endif //PRODUCT
void MethodData::print_value_on(outputStream* st) const {
assert(is_methodData(), "should be method data");
st->print("method data for ");
method()->print_value_on(st);
}
#ifndef PRODUCT
void MethodData::print_data_on(outputStream* st) const {
ResourceMark rm;
ProfileData* data = first_data();
......@@ -1418,7 +1390,6 @@ void MethodData::print_data_on(outputStream* st) const {
if (dp >= end) return;
}
}
#endif
#if INCLUDE_SERVICES
// Size Statistics
......
......@@ -280,12 +280,10 @@ class ProfileData : public ResourceObj {
friend class ReturnTypeEntry;
friend class TypeStackSlotEntries;
private:
#ifndef PRODUCT
enum {
tab_width_one = 16,
tab_width_two = 36
};
#endif // !PRODUCT
// This is a pointer to a section of profiling data.
DataLayout* _data;
......@@ -521,10 +519,8 @@ public:
void print_data_on(outputStream* st, const MethodData* md) const;
#ifndef PRODUCT
void print_shared(outputStream* st, const char* name, const char* extra) const;
void tab(outputStream* st, bool first = false) const;
#endif
};
// BitData
......@@ -583,9 +579,7 @@ public:
}
#endif // CC_INTERP
#ifndef PRODUCT
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// CounterData
......@@ -646,9 +640,7 @@ public:
}
#endif // CC_INTERP
#ifndef PRODUCT
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// JumpData
......@@ -733,9 +725,7 @@ public:
// Specific initialization.
void post_initialize(BytecodeStream* stream, MethodData* mdo);
#ifndef PRODUCT
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// Entries in a ProfileData object to record types: it can either be
......@@ -808,9 +798,7 @@ public:
return with_status((intptr_t)k, in);
}
#ifndef PRODUCT
static void print_klass(outputStream* st, intptr_t k);
#endif
// GC support
static bool is_loader_alive(BoolObjectClosure* is_alive_cl, intptr_t p);
......@@ -919,9 +907,7 @@ public:
// GC support
void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
#ifndef PRODUCT
void print_data_on(outputStream* st) const;
#endif
};
// Type entry used for return from a call. A single cell to record the
......@@ -964,9 +950,7 @@ public:
// GC support
void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
#ifndef PRODUCT
void print_data_on(outputStream* st) const;
#endif
};
// Entries to collect type information at a call: contains arguments
......@@ -1144,9 +1128,7 @@ public:
}
}
#ifndef PRODUCT
virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// ReceiverTypeData
......@@ -1288,10 +1270,8 @@ public:
}
#endif // CC_INTERP
#ifndef PRODUCT
void print_receiver_data_on(outputStream* st) const;
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// VirtualCallData
......@@ -1332,9 +1312,7 @@ public:
}
#endif // CC_INTERP
#ifndef PRODUCT
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// VirtualCallTypeData
......@@ -1458,9 +1436,7 @@ public:
}
}
#ifndef PRODUCT
virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// RetData
......@@ -1561,9 +1537,7 @@ public:
// Specific initialization.
void post_initialize(BytecodeStream* stream, MethodData* mdo);
#ifndef PRODUCT
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// BranchData
......@@ -1639,9 +1613,7 @@ public:
// Specific initialization.
void post_initialize(BytecodeStream* stream, MethodData* mdo);
#ifndef PRODUCT
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// ArrayData
......@@ -1832,9 +1804,7 @@ public:
// Specific initialization.
void post_initialize(BytecodeStream* stream, MethodData* mdo);
#ifndef PRODUCT
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
class ArgInfoData : public ArrayData {
......@@ -1859,9 +1829,7 @@ public:
array_set_int_at(arg, val);
}
#ifndef PRODUCT
void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// ParametersTypeData
......@@ -1920,9 +1888,7 @@ public:
_parameters.clean_weak_klass_links(is_alive_closure);
}
#ifndef PRODUCT
virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
static ByteSize stack_slot_offset(int i) {
return cell_offset(stack_slot_local_offset(i));
......@@ -1976,9 +1942,7 @@ public:
set_intptr_at(method_offset, (intptr_t)m);
}
#ifndef PRODUCT
virtual void print_data_on(outputStream* st, const char* extra = NULL) const;
#endif
};
// MethodData*
......@@ -2457,15 +2421,11 @@ public:
void set_size(int object_size_in_bytes) { _size = object_size_in_bytes; }
// Printing
#ifndef PRODUCT
void print_on (outputStream* st) const;
#endif
void print_value_on(outputStream* st) const;
#ifndef PRODUCT
// printing support for method data
void print_data_on(outputStream* st) const;
#endif
const char* internal_name() const { return "{method data}"; }
......
......@@ -2832,7 +2832,7 @@ class CommandLineFlags {
"number of method invocations/branches (expressed as % of " \
"CompileThreshold) before using the method's profile") \
\
develop(bool, PrintMethodData, false, \
diagnostic(bool, PrintMethodData, false, \
"Print the results of +ProfileInterpreter at end of run") \
\
develop(bool, VerifyDataPointer, trueInDebug, \
......
......@@ -98,21 +98,14 @@
#endif
#ifndef PRODUCT
// Statistics printing (method invocation histogram)
GrowableArray<Method*>* collected_invoked_methods;
GrowableArray<Method*>* collected_profiled_methods;
void collect_invoked_methods(Method* m) {
if (m->invocation_count() + m->compiled_invocation_count() >= 1 ) {
collected_invoked_methods->push(m);
}
int compare_methods(Method** a, Method** b) {
// %%% there can be 32-bit overflow here
return ((*b)->invocation_count() + (*b)->compiled_invocation_count())
- ((*a)->invocation_count() + (*a)->compiled_invocation_count());
}
GrowableArray<Method*>* collected_profiled_methods;
void collect_profiled_methods(Method* m) {
Thread* thread = Thread::current();
// This HandleMark prevents a huge amount of handles from being added
......@@ -125,14 +118,54 @@ void collect_profiled_methods(Method* m) {
}
}
void print_method_profiling_data() {
if (ProfileInterpreter COMPILER1_PRESENT(|| C1UpdateMethodData)) {
ResourceMark rm;
HandleMark hm;
collected_profiled_methods = new GrowableArray<Method*>(1024);
ClassLoaderDataGraph::methods_do(collect_profiled_methods);
collected_profiled_methods->sort(&compare_methods);
int count = collected_profiled_methods->length();
int total_size = 0;
if (count > 0) {
for (int index = 0; index < count; index++) {
Method* m = collected_profiled_methods->at(index);
ttyLocker ttyl;
tty->print_cr("------------------------------------------------------------------------");
m->print_invocation_count();
tty->print_cr(" mdo size: %d bytes", m->method_data()->size_in_bytes());
tty->cr();
// Dump data on parameters if any
if (m->method_data() != NULL && m->method_data()->parameters_type_data() != NULL) {
tty->fill_to(2);
m->method_data()->parameters_type_data()->print_data_on(tty);
}
m->print_codes();
total_size += m->method_data()->size_in_bytes();
}
tty->print_cr("------------------------------------------------------------------------");
tty->print_cr("Total MDO size: %d bytes", total_size);
}
}
}
int compare_methods(Method** a, Method** b) {
// %%% there can be 32-bit overflow here
return ((*b)->invocation_count() + (*b)->compiled_invocation_count())
- ((*a)->invocation_count() + (*a)->compiled_invocation_count());
#ifndef PRODUCT
// Statistics printing (method invocation histogram)
GrowableArray<Method*>* collected_invoked_methods;
void collect_invoked_methods(Method* m) {
if (m->invocation_count() + m->compiled_invocation_count() >= 1 ) {
collected_invoked_methods->push(m);
}
}
void print_method_invocation_histogram() {
ResourceMark rm;
HandleMark hm;
......@@ -173,37 +206,6 @@ void print_method_invocation_histogram() {
SharedRuntime::print_call_statistics(comp_total);
}
void print_method_profiling_data() {
ResourceMark rm;
HandleMark hm;
collected_profiled_methods = new GrowableArray<Method*>(1024);
SystemDictionary::methods_do(collect_profiled_methods);
collected_profiled_methods->sort(&compare_methods);
int count = collected_profiled_methods->length();
int total_size = 0;
if (count > 0) {
for (int index = 0; index < count; index++) {
Method* m = collected_profiled_methods->at(index);
ttyLocker ttyl;
tty->print_cr("------------------------------------------------------------------------");
//m->print_name(tty);
m->print_invocation_count();
tty->print_cr(" mdo size: %d bytes", m->method_data()->size_in_bytes());
tty->cr();
// Dump data on parameters if any
if (m->method_data() != NULL && m->method_data()->parameters_type_data() != NULL) {
tty->fill_to(2);
m->method_data()->parameters_type_data()->print_data_on(tty);
}
m->print_codes();
total_size += m->method_data()->size_in_bytes();
}
tty->print_cr("------------------------------------------------------------------------");
tty->print_cr("Total MDO size: %d bytes", total_size);
}
}
void print_bytecode_count() {
if (CountBytecodes || TraceBytecodes || StopInterpreterAt) {
tty->print_cr("[BytecodeCounter::counter_value = %d]", BytecodeCounter::counter_value());
......@@ -281,9 +283,9 @@ void print_statistics() {
if (CountCompiledCalls) {
print_method_invocation_histogram();
}
if (ProfileInterpreter COMPILER1_PRESENT(|| C1UpdateMethodData)) {
print_method_profiling_data();
}
print_method_profiling_data();
if (TimeCompiler) {
COMPILER2_PRESENT(Compile::print_timers();)
}
......@@ -373,6 +375,10 @@ void print_statistics() {
void print_statistics() {
if (PrintMethodData) {
print_method_profiling_data();
}
if (CITime) {
CompileBroker::print_times();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册