8261447: MethodInvocationCounters frequently run into overflow

Reviewed-by: thartmann, mdoerr, kvn, iveresov
This commit is contained in:
Lutz Schmidt 2021-03-03 20:04:31 +00:00
parent 75aa15467e
commit 268d9b7982
11 changed files with 160 additions and 113 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, Red Hat Inc. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
@ -70,7 +70,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
#if (!defined(PRODUCT) && defined(COMPILER2))
if (CountCompiledCalls) {
__ lea(r16, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
__ incrementw(Address(r16));
__ increment(Address(r16));
}
#endif
@ -145,6 +145,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
if (s == NULL) {
return NULL;
}
// Count unused bytes in instruction sequences of variable size.
// We add them to the computed buffer size in order to avoid
// overflow in subsequently generated stubs.
@ -159,7 +160,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
#if (!defined(PRODUCT) && defined(COMPILER2))
if (CountCompiledCalls) {
__ lea(r10, ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
__ incrementw(Address(r10));
__ increment(Address(r10));
}
#endif

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2018 SAP SE. All rights reserved.
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2021 SAP SE. 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
@ -73,9 +73,9 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
slop_delta = load_const_maxLen - (__ pc() - start_pc);
slop_bytes += slop_delta;
assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta);
__ lwz(R12_scratch2, offs, R11_scratch1);
__ ld(R12_scratch2, offs, R11_scratch1);
__ addi(R12_scratch2, R12_scratch2, 1);
__ stw(R12_scratch2, offs, R11_scratch1);
__ std(R12_scratch2, offs, R11_scratch1);
}
#endif
@ -141,6 +141,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
if (s == NULL) {
return NULL;
}
// Count unused bytes in instruction sequences of variable size.
// We add them to the computed buffer size in order to avoid
// overflow in subsequently generated stubs.
@ -160,9 +161,9 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
slop_delta = load_const_maxLen - (__ pc() - start_pc);
slop_bytes += slop_delta;
assert(slop_delta >= 0, "negative slop(%d) encountered, adjust code size estimate!", slop_delta);
__ lwz(R12_scratch2, offs, R11_scratch1);
__ ld(R12_scratch2, offs, R11_scratch1);
__ addi(R12_scratch2, R12_scratch2, 1);
__ stw(R12_scratch2, offs, R11_scratch1);
__ std(R12_scratch2, offs, R11_scratch1);
}
#endif

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2018 SAP SE. All rights reserved.
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2021 SAP SE. 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
@ -75,7 +75,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
// Abuse Z_method as scratch register for generic emitter.
// It is loaded further down anyway before it is first used.
// No dynamic code size variance here, increment is 1, always.
__ add2mem_32(Address(Z_R1_scratch), 1, Z_method);
__ add2mem_64(Address(Z_R1_scratch), 1, Z_method);
}
#endif
@ -158,6 +158,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
if (s == NULL) {
return NULL;
}
// Count unused bytes in instruction sequences of variable size.
// We add them to the computed buffer size in order to avoid
// overflow in subsequently generated stubs.
@ -179,7 +180,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
// Abuse Z_method as scratch register for generic emitter.
// It is loaded further down anyway before it is first used.
// No dynamic code size variance here, increment is 1, always.
__ add2mem_32(Address(Z_R1_scratch), 1, Z_method);
__ add2mem_64(Address(Z_R1_scratch), 1, Z_method);
}
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2021, 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
@ -70,7 +70,7 @@ VtableStub* VtableStubs::create_vtable_stub(int vtable_index) {
#if (!defined(PRODUCT) && defined(COMPILER2))
if (CountCompiledCalls) {
__ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
__ incrementq(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
}
#endif
@ -148,6 +148,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
if (s == NULL) {
return NULL;
}
// Count unused bytes in instruction sequences of variable size.
// We add them to the computed buffer size in order to avoid
// overflow in subsequently generated stubs.
@ -163,7 +164,7 @@ VtableStub* VtableStubs::create_itable_stub(int itable_index) {
#if (!defined(PRODUCT) && defined(COMPILER2))
if (CountCompiledCalls) {
__ incrementl(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
__ incrementq(ExternalAddress((address) SharedRuntime::nof_megamorphic_calls_addr()));
}
#endif // PRODUCT

View File

@ -493,6 +493,7 @@ bool Method::was_executed_more_than(int n) {
}
void Method::print_invocation_count() {
//---< compose+print method return type, klass, name, and signature >---
if (is_static()) tty->print("static ");
if (is_final()) tty->print("final ");
if (is_synchronized()) tty->print("synchronized ");
@ -507,12 +508,22 @@ void Method::print_invocation_count() {
}
tty->cr();
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());
// Counting based on signed int counters tends to overflow with
// longer-running workloads on fast machines. The counters under
// consideration here, however, are limited in range by counting
// logic. See InvocationCounter:count_limit for example.
// No "overflow precautions" need to be implemented here.
tty->print_cr (" interpreter_invocation_count: " INT32_FORMAT_W(11), interpreter_invocation_count());
tty->print_cr (" invocation_counter: " INT32_FORMAT_W(11), invocation_count());
tty->print_cr (" backedge_counter: " INT32_FORMAT_W(11), backedge_count());
if (method_data() != NULL) {
tty->print_cr (" decompile_count: " UINT32_FORMAT_W(11), method_data()->decompile_count());
}
#ifndef PRODUCT
if (CountCompiledCalls) {
tty->print_cr (" compiled_invocation_count: %8d ", compiled_invocation_count());
tty->print_cr (" compiled_invocation_count: " INT64_FORMAT_W(11), compiled_invocation_count());
}
#endif
}

View File

@ -98,7 +98,7 @@ class Method : public Metadata {
JFR_ONLY(DEFINE_TRACE_FLAG;)
#ifndef PRODUCT
int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging)
int64_t _compiled_invocation_count;
#endif
// Entry point for calling both from and to the interpreter.
address _i2i_entry; // All-args-on-stack calling convention
@ -436,11 +436,11 @@ class Method : public Metadata {
int interpreter_invocation_count() { return invocation_count(); }
#ifndef PRODUCT
int compiled_invocation_count() const { return _compiled_invocation_count; }
void set_compiled_invocation_count(int count) { _compiled_invocation_count = count; }
int64_t compiled_invocation_count() const { return _compiled_invocation_count;}
void set_compiled_invocation_count(int count) { _compiled_invocation_count = (int64_t)count; }
#else
// for PrintMethodData in a product build
int compiled_invocation_count() const { return 0; }
int64_t compiled_invocation_count() const { return 0; }
#endif // not PRODUCT
// Clear (non-shared space) pointers which could not be relevant

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@ -2000,9 +2000,9 @@ void GraphKit::increment_counter(address counter_addr) {
void GraphKit::increment_counter(Node* counter_addr) {
int adr_type = Compile::AliasIdxRaw;
Node* ctrl = control();
Node* cnt = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type, MemNode::unordered);
Node* incr = _gvn.transform(new AddINode(cnt, _gvn.intcon(1)));
store_to_memory(ctrl, counter_addr, incr, T_INT, adr_type, MemNode::unordered);
Node* cnt = make_load(ctrl, counter_addr, TypeLong::LONG, T_LONG, adr_type, MemNode::unordered);
Node* incr = _gvn.transform(new AddLNode(cnt, _gvn.longcon(1)));
store_to_memory(ctrl, counter_addr, incr, T_LONG, adr_type, MemNode::unordered);
}

View File

@ -97,9 +97,11 @@
GrowableArray<Method*>* collected_profiled_methods;
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());
// compiled_invocation_count() returns int64_t, forcing the entire expression
// to be evaluated as int64_t. Overflow is not an issue.
int64_t diff = (((*b)->invocation_count() + (*b)->compiled_invocation_count())
- ((*a)->invocation_count() + (*a)->compiled_invocation_count()));
return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
}
void collect_profiled_methods(Method* m) {
@ -151,14 +153,15 @@ void print_method_profiling_data() {
GrowableArray<Method*>* collected_invoked_methods;
void collect_invoked_methods(Method* m) {
if (m->invocation_count() + m->compiled_invocation_count() >= 1 ) {
if (m->invocation_count() + m->compiled_invocation_count() >= 1) {
collected_invoked_methods->push(m);
}
}
// Invocation count accumulators should be unsigned long to shift the
// overflow border. Longer-running workloads tend to create invocation
// counts which already overflow 32-bit counters for individual methods.
void print_method_invocation_histogram() {
ResourceMark rm;
collected_invoked_methods = new GrowableArray<Method*>(1024);
@ -169,31 +172,45 @@ void print_method_invocation_histogram() {
tty->print_cr("Histogram Over Method Invocation Counters (cutoff = " INTX_FORMAT "):", MethodHistogramCutoff);
tty->cr();
tty->print_cr("____Count_(I+C)____Method________________________Module_________________");
unsigned total = 0, int_total = 0, comp_total = 0, static_total = 0, final_total = 0,
synch_total = 0, nativ_total = 0, acces_total = 0;
uint64_t total = 0,
int_total = 0,
comp_total = 0,
special_total= 0,
static_total = 0,
final_total = 0,
synch_total = 0,
native_total = 0,
access_total = 0;
for (int index = 0; index < collected_invoked_methods->length(); index++) {
// Counter values returned from getter methods are signed int.
// To shift the overflow border by a factor of two, we interpret
// them here as unsigned long. A counter can't be negative anyway.
Method* m = collected_invoked_methods->at(index);
int c = m->invocation_count() + m->compiled_invocation_count();
if (c >= MethodHistogramCutoff) m->print_invocation_count();
int_total += m->invocation_count();
comp_total += m->compiled_invocation_count();
if (m->is_final()) final_total += c;
if (m->is_static()) static_total += c;
if (m->is_synchronized()) synch_total += c;
if (m->is_native()) nativ_total += c;
if (m->is_accessor()) acces_total += c;
uint64_t iic = (uint64_t)m->invocation_count();
uint64_t cic = (uint64_t)m->compiled_invocation_count();
if ((iic + cic) >= (uint64_t)MethodHistogramCutoff) m->print_invocation_count();
int_total += iic;
comp_total += cic;
if (m->is_final()) final_total += iic + cic;
if (m->is_static()) static_total += iic + cic;
if (m->is_synchronized()) synch_total += iic + cic;
if (m->is_native()) native_total += iic + cic;
if (m->is_accessor()) access_total += iic + cic;
}
tty->cr();
total = int_total + comp_total;
tty->print_cr("Invocations summary:");
tty->print_cr("\t%9d (%4.1f%%) interpreted", int_total, 100.0 * int_total / total);
tty->print_cr("\t%9d (%4.1f%%) compiled", comp_total, 100.0 * comp_total / total);
tty->print_cr("\t%9d (100%%) total", total);
tty->print_cr("\t%9d (%4.1f%%) synchronized", synch_total, 100.0 * synch_total / total);
tty->print_cr("\t%9d (%4.1f%%) final", final_total, 100.0 * final_total / total);
tty->print_cr("\t%9d (%4.1f%%) static", static_total, 100.0 * static_total / total);
tty->print_cr("\t%9d (%4.1f%%) native", nativ_total, 100.0 * nativ_total / total);
tty->print_cr("\t%9d (%4.1f%%) accessor", acces_total, 100.0 * acces_total / total);
special_total = final_total + static_total +synch_total + native_total + access_total;
tty->print_cr("Invocations summary for %d methods:", collected_invoked_methods->length());
tty->print_cr("\t" UINT64_FORMAT_W(12) " (100%%) total", total);
tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- interpreted", int_total, 100.0 * int_total / total);
tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- compiled", comp_total, 100.0 * comp_total / total);
tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- special methods (interpreted and compiled)",
special_total, 100.0 * special_total/ total);
tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- synchronized",synch_total, 100.0 * synch_total / total);
tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- final", final_total, 100.0 * final_total / total);
tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- static", static_total, 100.0 * static_total / total);
tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- native", native_total, 100.0 * native_total / total);
tty->print_cr("\t" UINT64_FORMAT_W(12) " (%4.1f%%) |- accessor", access_total, 100.0 * access_total / total);
tty->cr();
SharedRuntime::print_call_statistics(comp_total);
}

View File

@ -143,16 +143,16 @@ int SharedRuntime::_implicit_null_throws = 0;
int SharedRuntime::_implicit_div0_throws = 0;
int SharedRuntime::_throw_null_ctr = 0;
int SharedRuntime::_nof_normal_calls = 0;
int SharedRuntime::_nof_optimized_calls = 0;
int SharedRuntime::_nof_inlined_calls = 0;
int SharedRuntime::_nof_megamorphic_calls = 0;
int SharedRuntime::_nof_static_calls = 0;
int SharedRuntime::_nof_inlined_static_calls = 0;
int SharedRuntime::_nof_interface_calls = 0;
int SharedRuntime::_nof_optimized_interface_calls = 0;
int SharedRuntime::_nof_inlined_interface_calls = 0;
int SharedRuntime::_nof_megamorphic_interface_calls = 0;
int64_t SharedRuntime::_nof_normal_calls = 0;
int64_t SharedRuntime::_nof_optimized_calls = 0;
int64_t SharedRuntime::_nof_inlined_calls = 0;
int64_t SharedRuntime::_nof_megamorphic_calls = 0;
int64_t SharedRuntime::_nof_static_calls = 0;
int64_t SharedRuntime::_nof_inlined_static_calls = 0;
int64_t SharedRuntime::_nof_interface_calls = 0;
int64_t SharedRuntime::_nof_optimized_interface_calls = 0;
int64_t SharedRuntime::_nof_inlined_interface_calls = 0;
int64_t SharedRuntime::_nof_megamorphic_interface_calls = 0;
int SharedRuntime::_new_instance_ctr=0;
int SharedRuntime::_new_array_ctr=0;
@ -2203,14 +2203,20 @@ inline double percent(int x, int y) {
return 100.0 * x / MAX2(y, 1);
}
inline double percent(int64_t x, int64_t y) {
return 100.0 * x / MAX2(y, (int64_t)1);
}
class MethodArityHistogram {
public:
enum { MAX_ARITY = 256 };
private:
static int _arity_histogram[MAX_ARITY]; // histogram of #args
static int _size_histogram[MAX_ARITY]; // histogram of arg size in words
static int _max_arity; // max. arity seen
static int _max_size; // max. arg size seen
static uint64_t _arity_histogram[MAX_ARITY]; // histogram of #args
static uint64_t _size_histogram[MAX_ARITY]; // histogram of arg size in words
static uint64_t _total_compiled_calls;
static uint64_t _max_compiled_calls_per_method;
static int _max_arity; // max. arity seen
static int _max_size; // max. arg size seen
static void add_method_to_histogram(nmethod* nm) {
Method* method = (nm == NULL) ? NULL : nm->method();
@ -2220,7 +2226,9 @@ class MethodArityHistogram {
int argsize = method->size_of_parameters();
arity = MIN2(arity, MAX_ARITY-1);
argsize = MIN2(argsize, MAX_ARITY-1);
int count = method->compiled_invocation_count();
uint64_t count = (uint64_t)method->compiled_invocation_count();
_max_compiled_calls_per_method = count > _max_compiled_calls_per_method ? count : _max_compiled_calls_per_method;
_total_compiled_calls += count;
_arity_histogram[arity] += count;
_size_histogram[argsize] += count;
_max_arity = MAX2(_max_arity, arity);
@ -2228,27 +2236,31 @@ class MethodArityHistogram {
}
}
void print_histogram_helper(int n, int* histo, const char* name) {
const int N = MIN2(5, n);
tty->print_cr("\nHistogram of call arity (incl. rcvr, calls to compiled methods only):");
void print_histogram_helper(int n, uint64_t* histo, const char* name) {
const int N = MIN2(9, n);
double sum = 0;
double weighted_sum = 0;
int i;
for (i = 0; i <= n; i++) { sum += histo[i]; weighted_sum += i*histo[i]; }
double rest = sum;
double percent = sum / 100;
for (i = 0; i <= N; i++) {
rest -= histo[i];
tty->print_cr("%4d: %7d (%5.1f%%)", i, histo[i], histo[i] / percent);
for (int i = 0; i <= n; i++) { sum += histo[i]; weighted_sum += i*histo[i]; }
if (sum >= 1.0) { // prevent divide by zero or divide overflow
double rest = sum;
double percent = sum / 100;
for (int i = 0; i <= N; i++) {
rest -= histo[i];
tty->print_cr("%4d: " UINT64_FORMAT_W(12) " (%5.1f%%)", i, histo[i], histo[i] / percent);
}
tty->print_cr("rest: " INT64_FORMAT_W(12) " (%5.1f%%)", (int64_t)rest, rest / percent);
tty->print_cr("(avg. %s = %3.1f, max = %d)", name, weighted_sum / sum, n);
tty->print_cr("(total # of compiled calls = " INT64_FORMAT_W(14) ")", _total_compiled_calls);
tty->print_cr("(max # of compiled calls = " INT64_FORMAT_W(14) ")", _max_compiled_calls_per_method);
} else {
tty->print_cr("Histogram generation failed for %s. n = %d, sum = %7.5f", name, n, sum);
}
tty->print_cr("rest: %7d (%5.1f%%))", (int)rest, rest / percent);
tty->print_cr("(avg. %s = %3.1f, max = %d)", name, weighted_sum / sum, n);
}
void print_histogram() {
tty->print_cr("\nHistogram of call arity (incl. rcvr, calls to compiled methods only):");
print_histogram_helper(_max_arity, _arity_histogram, "arity");
tty->print_cr("\nSame for parameter size (in words):");
tty->print_cr("\nHistogram of parameter block size (in words, incl. rcvr):");
print_histogram_helper(_max_size, _size_histogram, "size");
tty->cr();
}
@ -2260,35 +2272,39 @@ class MethodArityHistogram {
// Take the CodeCache_lock to protect against changes in the CodeHeap structure
MutexLocker mu2(CodeCache_lock, Mutex::_no_safepoint_check_flag);
_max_arity = _max_size = 0;
_total_compiled_calls = 0;
_max_compiled_calls_per_method = 0;
for (int i = 0; i < MAX_ARITY; i++) _arity_histogram[i] = _size_histogram[i] = 0;
CodeCache::nmethods_do(add_method_to_histogram);
print_histogram();
}
};
int MethodArityHistogram::_arity_histogram[MethodArityHistogram::MAX_ARITY];
int MethodArityHistogram::_size_histogram[MethodArityHistogram::MAX_ARITY];
uint64_t MethodArityHistogram::_arity_histogram[MethodArityHistogram::MAX_ARITY];
uint64_t MethodArityHistogram::_size_histogram[MethodArityHistogram::MAX_ARITY];
uint64_t MethodArityHistogram::_total_compiled_calls;
uint64_t MethodArityHistogram::_max_compiled_calls_per_method;
int MethodArityHistogram::_max_arity;
int MethodArityHistogram::_max_size;
void SharedRuntime::print_call_statistics(int comp_total) {
void SharedRuntime::print_call_statistics(uint64_t comp_total) {
tty->print_cr("Calls from compiled code:");
int total = _nof_normal_calls + _nof_interface_calls + _nof_static_calls;
int mono_c = _nof_normal_calls - _nof_optimized_calls - _nof_megamorphic_calls;
int mono_i = _nof_interface_calls - _nof_optimized_interface_calls - _nof_megamorphic_interface_calls;
tty->print_cr("\t%9d (%4.1f%%) total non-inlined ", total, percent(total, total));
tty->print_cr("\t%9d (%4.1f%%) virtual calls ", _nof_normal_calls, percent(_nof_normal_calls, total));
tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_calls, percent(_nof_inlined_calls, _nof_normal_calls));
tty->print_cr("\t %9d (%3.0f%%) optimized ", _nof_optimized_calls, percent(_nof_optimized_calls, _nof_normal_calls));
tty->print_cr("\t %9d (%3.0f%%) monomorphic ", mono_c, percent(mono_c, _nof_normal_calls));
tty->print_cr("\t %9d (%3.0f%%) megamorphic ", _nof_megamorphic_calls, percent(_nof_megamorphic_calls, _nof_normal_calls));
tty->print_cr("\t%9d (%4.1f%%) interface calls ", _nof_interface_calls, percent(_nof_interface_calls, total));
tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_interface_calls, percent(_nof_inlined_interface_calls, _nof_interface_calls));
tty->print_cr("\t %9d (%3.0f%%) optimized ", _nof_optimized_interface_calls, percent(_nof_optimized_interface_calls, _nof_interface_calls));
tty->print_cr("\t %9d (%3.0f%%) monomorphic ", mono_i, percent(mono_i, _nof_interface_calls));
tty->print_cr("\t %9d (%3.0f%%) megamorphic ", _nof_megamorphic_interface_calls, percent(_nof_megamorphic_interface_calls, _nof_interface_calls));
tty->print_cr("\t%9d (%4.1f%%) static/special calls", _nof_static_calls, percent(_nof_static_calls, total));
tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_static_calls, percent(_nof_inlined_static_calls, _nof_static_calls));
int64_t total = _nof_normal_calls + _nof_interface_calls + _nof_static_calls;
int64_t mono_c = _nof_normal_calls - _nof_optimized_calls - _nof_megamorphic_calls;
int64_t mono_i = _nof_interface_calls - _nof_optimized_interface_calls - _nof_megamorphic_interface_calls;
tty->print_cr("\t" INT64_FORMAT_W(12) " (100%%) total non-inlined ", total);
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.1f%%) |- virtual calls ", _nof_normal_calls, percent(_nof_normal_calls, total));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- inlined ", _nof_inlined_calls, percent(_nof_inlined_calls, _nof_normal_calls));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- optimized ", _nof_optimized_calls, percent(_nof_optimized_calls, _nof_normal_calls));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- monomorphic ", mono_c, percent(mono_c, _nof_normal_calls));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- megamorphic ", _nof_megamorphic_calls, percent(_nof_megamorphic_calls, _nof_normal_calls));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.1f%%) |- interface calls ", _nof_interface_calls, percent(_nof_interface_calls, total));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- inlined ", _nof_inlined_interface_calls, percent(_nof_inlined_interface_calls, _nof_interface_calls));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- optimized ", _nof_optimized_interface_calls, percent(_nof_optimized_interface_calls, _nof_interface_calls));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- monomorphic ", mono_i, percent(mono_i, _nof_interface_calls));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- megamorphic ", _nof_megamorphic_interface_calls, percent(_nof_megamorphic_interface_calls, _nof_interface_calls));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.1f%%) |- static/special calls", _nof_static_calls, percent(_nof_static_calls, total));
tty->print_cr("\t" INT64_FORMAT_W(12) " (%4.0f%%) | |- inlined ", _nof_inlined_static_calls, percent(_nof_inlined_static_calls, _nof_static_calls));
tty->cr();
tty->print_cr("Note 1: counter updates are not MT-safe.");
tty->print_cr("Note 2: %% in major categories are relative to total non-inlined calls;");

View File

@ -78,7 +78,7 @@ class SharedRuntime: AllStatic {
#ifndef PRODUCT
// Counters
static int _nof_megamorphic_calls; // total # of megamorphic calls (through vtable)
static int64_t _nof_megamorphic_calls; // total # of megamorphic calls (through vtable)
#endif // !PRODUCT
private:
@ -567,16 +567,16 @@ class SharedRuntime: AllStatic {
// Statistics code
// stats for "normal" compiled calls (non-interface)
static int _nof_normal_calls; // total # of calls
static int _nof_optimized_calls; // total # of statically-bound calls
static int _nof_inlined_calls; // total # of inlined normal calls
static int _nof_static_calls; // total # of calls to static methods or super methods (invokespecial)
static int _nof_inlined_static_calls; // total # of inlined static calls
static int64_t _nof_normal_calls; // total # of calls
static int64_t _nof_optimized_calls; // total # of statically-bound calls
static int64_t _nof_inlined_calls; // total # of inlined normal calls
static int64_t _nof_static_calls; // total # of calls to static methods or super methods (invokespecial)
static int64_t _nof_inlined_static_calls; // total # of inlined static calls
// stats for compiled interface calls
static int _nof_interface_calls; // total # of compiled calls
static int _nof_optimized_interface_calls; // total # of statically-bound interface calls
static int _nof_inlined_interface_calls; // total # of inlined interface calls
static int _nof_megamorphic_interface_calls;// total # of megamorphic interface calls
static int64_t _nof_interface_calls; // total # of compiled calls
static int64_t _nof_optimized_interface_calls; // total # of statically-bound interface calls
static int64_t _nof_inlined_interface_calls; // total # of inlined interface calls
static int64_t _nof_megamorphic_interface_calls;// total # of megamorphic interface calls
public: // for compiler
static address nof_normal_calls_addr() { return (address)&_nof_normal_calls; }
@ -588,7 +588,7 @@ class SharedRuntime: AllStatic {
static address nof_optimized_interface_calls_addr() { return (address)&_nof_optimized_interface_calls; }
static address nof_inlined_interface_calls_addr() { return (address)&_nof_inlined_interface_calls; }
static address nof_megamorphic_interface_calls_addr() { return (address)&_nof_megamorphic_interface_calls; }
static void print_call_statistics(int comp_total);
static void print_call_statistics(uint64_t comp_total);
static void print_statistics();
static void print_ic_miss_histogram();

View File

@ -307,7 +307,6 @@ typedef HashtableEntry<InstanceKlass*, mtClass> KlassHashtableEntry;
nonstatic_field(Method, _vtable_index, int) \
nonstatic_field(Method, _intrinsic_id, u2) \
nonstatic_field(Method, _flags, u2) \
nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \
volatile_nonstatic_field(Method, _code, CompiledMethod*) \
nonstatic_field(Method, _i2i_entry, address) \
volatile_nonstatic_field(Method, _from_compiled_entry, address) \