8166750: C1 profiling handles statically bindable call sites differently than the interpreter
authoriveresov
Wed, 25 Oct 2017 16:30:31 -0700
changeset 47698 d4bfafe600d0
parent 47697 2e54e9324e1c
child 47699 068d316e905e
child 47754 00e1afbd0a76
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
src/hotspot/cpu/aarch64/c1_LIRAssembler_aarch64.cpp
src/hotspot/cpu/arm/c1_LIRAssembler_arm.cpp
src/hotspot/cpu/ppc/c1_LIRAssembler_ppc.cpp
src/hotspot/cpu/s390/c1_LIRAssembler_s390.cpp
src/hotspot/cpu/sparc/c1_LIRAssembler_sparc.cpp
src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp
src/hotspot/share/c1/c1_LIR.hpp
src/jdk.internal.vm.ci/share/classes/jdk.vm.ci.hotspot/src/jdk/vm/ci/hotspot/HotSpotMethodData.java
--- 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);
         }