8166750: C1 profiling handles statically bindable call sites differently than the interpreter

Optimize profiling of statically binable call sites. Add monomorphic profile fixup to JVMCI MDO API.

Reviewed-by: dnsimon, kvn
This commit is contained in:
Igor Veresov 2017-10-25 16:30:31 -07:00
parent bdb82eb577
commit 548d5d4d9d
8 changed files with 21 additions and 33 deletions

View File

@ -2575,13 +2575,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
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);

View File

@ -3168,14 +3168,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
}
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);

View File

@ -2774,13 +2774,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
__ 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);

View File

@ -2713,13 +2713,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
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);

View File

@ -2763,13 +2763,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
}
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);

View File

@ -3482,13 +3482,9 @@ void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
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);

View File

@ -1913,6 +1913,12 @@ class LIR_OpProfileCall : public LIR_Op {
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

View File

@ -578,6 +578,13 @@ final class HotSpotMethodData {
}
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);
}