8166750: C1 profiling handles statically bindable call sites differently than the interpreter
Summary: Optimize profiling of statically binable call sites. Add monomorphic profile fixup to JVMCI MDO API.
Reviewed-by: dnsimon, kvn
--- a/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Wed Oct 25 16:15:10 2017 +0200
+++ b/src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp Wed Oct 25 16:30:31 2017 -0700
@@ -2575,13 +2575,9 @@
Register mdo = op->mdo()->as_register();
__ mov_metadata(mdo, md->constant_encoding());
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
- Bytecodes::Code bc = method->java_code_at_bci(bci);
- const bool callee_is_static = callee->is_loaded() && callee->is_static();
// Perform additional virtual call profiling for invokevirtual and
// invokeinterface bytecodes
- if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
- !callee_is_static && // required for optimized MH invokes
- C1ProfileVirtualCalls) {
+ if (op->should_profile_receiver_type()) {
assert(op->recv()->is_single_cpu(), "recv must be allocated");
Register recv = op->recv()->as_register();
assert_different_registers(mdo, recv);
--- a/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Wed Oct 25 16:15:10 2017 +0200
+++ b/src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp Wed Oct 25 16:30:31 2017 -0700
@@ -3168,14 +3168,9 @@
}
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
- Bytecodes::Code bc = method->java_code_at_bci(bci);
- const bool callee_is_static = callee->is_loaded() && callee->is_static();
// Perform additional virtual call profiling for invokevirtual and
// invokeinterface bytecodes
- if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
- !callee_is_static && // required for optimized MH invokes
- C1ProfileVirtualCalls) {
-
+ if (op->should_profile_receiver_type()) {
assert(op->recv()->is_single_cpu(), "recv must be allocated");
Register recv = op->recv()->as_register();
assert_different_registers(mdo, tmp1, recv);
--- a/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Wed Oct 25 16:15:10 2017 +0200
+++ b/src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp Wed Oct 25 16:30:31 2017 -0700
@@ -2774,13 +2774,9 @@
__ add_const_optimized(mdo, mdo, mdo_offset_bias, R0);
}
- Bytecodes::Code bc = method->java_code_at_bci(bci);
- const bool callee_is_static = callee->is_loaded() && callee->is_static();
// Perform additional virtual call profiling for invokevirtual and
- // invokeinterface bytecodes.
- if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
- !callee_is_static && // Required for optimized MH invokes.
- C1ProfileVirtualCalls) {
+ // invokeinterface bytecodes
+ if (op->should_profile_receiver_type()) {
assert(op->recv()->is_single_cpu(), "recv must be allocated");
Register recv = op->recv()->as_register();
assert_different_registers(mdo, tmp1, recv);
--- a/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Wed Oct 25 16:15:10 2017 +0200
+++ b/src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp Wed Oct 25 16:30:31 2017 -0700
@@ -2713,13 +2713,9 @@
metadata2reg(md->constant_encoding(), mdo);
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
- Bytecodes::Code bc = method->java_code_at_bci(bci);
- const bool callee_is_static = callee->is_loaded() && callee->is_static();
// Perform additional virtual call profiling for invokevirtual and
- // invokeinterface bytecodes.
- if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
- !callee_is_static && // Required for optimized MH invokes.
- C1ProfileVirtualCalls) {
+ // invokeinterface bytecodes
+ if (op->should_profile_receiver_type()) {
assert(op->recv()->is_single_cpu(), "recv must be allocated");
Register recv = op->recv()->as_register();
assert_different_registers(mdo, tmp1, recv);
--- a/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Wed Oct 25 16:15:10 2017 +0200
+++ b/src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp Wed Oct 25 16:30:31 2017 -0700
@@ -2763,13 +2763,9 @@
}
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
- Bytecodes::Code bc = method->java_code_at_bci(bci);
- const bool callee_is_static = callee->is_loaded() && callee->is_static();
// Perform additional virtual call profiling for invokevirtual and
// invokeinterface bytecodes
- if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
- !callee_is_static && // required for optimized MH invokes
- C1ProfileVirtualCalls) {
+ if (op->should_profile_receiver_type()) {
assert(op->recv()->is_single_cpu(), "recv must be allocated");
Register recv = op->recv()->as_register();
assert_different_registers(mdo, tmp1, recv);
--- a/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Wed Oct 25 16:15:10 2017 +0200
+++ b/src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp Wed Oct 25 16:30:31 2017 -0700
@@ -3482,13 +3482,9 @@
Register mdo = op->mdo()->as_register();
__ mov_metadata(mdo, md->constant_encoding());
Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
- Bytecodes::Code bc = method->java_code_at_bci(bci);
- const bool callee_is_static = callee->is_loaded() && callee->is_static();
// Perform additional virtual call profiling for invokevirtual and
// invokeinterface bytecodes
- if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
- !callee_is_static && // required for optimized MH invokes
- C1ProfileVirtualCalls) {
+ if (op->should_profile_receiver_type()) {
assert(op->recv()->is_single_cpu(), "recv must be allocated");
Register recv = op->recv()->as_register();
assert_different_registers(mdo, recv);
--- a/src/hotspot/share/c1/c1_LIR.hpp Wed Oct 25 16:15:10 2017 +0200
+++ b/src/hotspot/share/c1/c1_LIR.hpp Wed Oct 25 16:30:31 2017 -0700
@@ -1913,6 +1913,12 @@
virtual void emit_code(LIR_Assembler* masm);
virtual LIR_OpProfileCall* as_OpProfileCall() { return this; }
virtual void print_instr(outputStream* out) const PRODUCT_RETURN;
+ bool should_profile_receiver_type() const {
+ bool callee_is_static = _profiled_callee->is_loaded() && _profiled_callee->is_static();
+ Bytecodes::Code bc = _profiled_method->java_code_at_bci(_profiled_bci);
+ bool call_is_virtual = (bc == Bytecodes::_invokevirtual && !_profiled_callee->can_be_statically_bound()) || bc == Bytecodes::_invokeinterface;
+ return C1ProfileVirtualCalls && call_is_virtual && !callee_is_static;
+ }
};
// LIR_OpProfileType
--- a/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java Wed Oct 25 16:15:10 2017 +0200
+++ b/src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java Wed Oct 25 16:30:31 2017 -0700
@@ -578,6 +578,13 @@
}
totalCount += getMethodsNotRecordedExecutionCount(data, position);
+
+ // Fixup the case of C1's inability to optimize profiling of a statically bindable call site.
+ // If it's a monomorphic call site, attribute all the counts to the first type (if any is recorded).
+ if (entries == 1) {
+ counts[0] = totalCount;
+ }
+
return new RawItemProfile<>(entries, methods, counts, totalCount);
}