changeset 5944:f6f8694a17b9

8024468: PPC64 (part 201): cppInterpreter: implement bytecode profiling Summary: Implement profiling for c2 jit compilation. Reviewed-by: kvn
author goetz
date Mon, 10 Feb 2014 12:33:17 +0100
parents dfc4a5d5995b
children 3e9fd1cbb698
files src/cpu/zero/vm/cppInterpreter_zero.cpp src/share/vm/interpreter/bytecodeInterpreter.cpp src/share/vm/interpreter/bytecodeInterpreterProfiling.hpp src/share/vm/interpreter/interpreterRuntime.cpp src/share/vm/interpreter/interpreterRuntime.hpp src/share/vm/interpreter/invocationCounter.hpp src/share/vm/oops/methodDataOop.hpp src/share/vm/runtime/arguments.cpp src/share/vm/runtime/globals.hpp
diffstat 9 files changed, 55 insertions(+), 70 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/zero/vm/cppInterpreter_zero.cpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Mon Feb 10 12:33:17 2014 +0100
@@ -250,7 +250,7 @@
   if ((UseCompiler || CountCompiledCalls) && !method->is_synchronized()) {
     InvocationCounter *counter = method->invocation_counter();
     counter->increment();
-    if (counter->reached_InvocationLimit()) {
+    if (counter->reached_InvocationLimit(mcs->backedge_counter())) {
       CALL_VM_NOCHECK(
         InterpreterRuntime::frequency_counter_overflow(thread, NULL));
       if (HAS_PENDING_EXCEPTION)
--- a/src/share/vm/interpreter/bytecodeInterpreter.cpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp	Mon Feb 10 12:33:17 2014 +0100
@@ -345,7 +345,7 @@
             && (mdo_last_branch_taken_count >= (uint)InvocationCounter::InterpreterBackwardBranchLimit)\
             /* When ProfileInterpreter is on, the backedge_count comes     */                       \
             /* from the methodDataOop, which value does not get reset on   */                       \
-            /* the call to frequency_counter_overflow().  To avoid         */                       \
+            /* the call to frequency_counter_overflow(). To avoid          */                       \
             /* excessive calls to the overflow routine while the method is */                       \
             /* being compiled, add a second test to make sure the overflow */                       \
             /* function is called only once every overflow_frequency.      */                       \
@@ -411,11 +411,11 @@
  * On some architectures/platforms it should be possible to do this implicitly
  */
 #undef CHECK_NULL
-#define CHECK_NULL(obj_)                                                                      \
-    if ((obj_) == NULL) {                                                                     \
-      VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), NULL, note_nullCheck_trap);  \
-    }                                                                                         \
-    VERIFY_OOP(obj_)
+#define CHECK_NULL(obj_)                                                                         \
+        if ((obj_) == NULL) {                                                                    \
+          VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), NULL, note_nullCheck_trap); \
+        }                                                                                        \
+        VERIFY_OOP(obj_)
 
 #define VMdoubleConstZero() 0.0
 #define VMdoubleConstOne() 1.0
@@ -663,7 +663,7 @@
 
   switch (istate->msg()) {
     case initialize: {
-      if (initialized++) ShouldNotReachHere(); // Only one initialize call
+      if (initialized++) ShouldNotReachHere(); // Only one initialize call.
       _compiling = (UseCompiler || CountCompiledCalls);
 #ifdef VM_JVMTI
       _jvmti_interp_events = JvmtiExport::can_post_interpreter_events();
@@ -682,7 +682,7 @@
         INCR_INVOCATION_COUNT;
         if (INVOCATION_COUNT->reached_InvocationLimit(BACKEDGE_COUNT)) {
           CALL_VM((void)InterpreterRuntime::frequency_counter_overflow(THREAD, NULL), handle_exception);
-          // We no longer retry on a counter overflow
+          // We no longer retry on a counter overflow.
         }
         // Get or create profile data. Check for pending (async) exceptions.
         BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception);
@@ -2323,9 +2323,7 @@
             // Check for compatibilty. This check must not GC!!
             // Seems way more expensive now that we must dispatch.
             //
-            if (objKlassOop != klassOf &&
-                !objKlassOop->klass_part()->is_subtype_of(klassOf)) {
-
+            if (objKlassOop != klassOf && !objKlassOop->klass_part()->is_subtype_of(klassOf)) {
               // Decrement counter at checkcast.
               BI_PROFILE_SUBTYPECHECK_FAILED(objKlassOop);
               ResourceMark rm(THREAD);
@@ -2521,6 +2519,7 @@
 
         UPDATE_PC_AND_RETURN(0); // I'll be back...
       }
+
       CASE(_invokehandle): {
 
         if (!EnableInvokeDynamic) {
@@ -2533,12 +2532,10 @@
         if (! cache->is_resolved((Bytecodes::Code) opcode)) {
           CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD),
                   handle_exception);
-          // GC might move cache while returning from VM call.
-          cache = cp->entry_at(index); // reload
+          cache = cp->entry_at(index);
         }
 
         methodOop method = cache->f2_as_vfinal_method();
-
         VERIFY_OOP(method);
 
         if (cache->has_appendix()) {
@@ -2585,9 +2582,9 @@
             // Profile 'special case of invokeinterface' final call.
             BI_PROFILE_UPDATE_FINALCALL();
           } else {
-            // get receiver
+            // Get receiver.
             int parms = cache->parameter_size();
-            // Same comments as invokevirtual apply here
+            // Same comments as invokevirtual apply here.
             oop rcvr = STACK_OBJECT(-parms);
             VERIFY_OOP(rcvr);
             instanceKlass* rcvrKlass = (instanceKlass*)rcvr->klass()->klass_part();
@@ -2796,7 +2793,7 @@
       CASE(_ret): {
           // Profile ret.
           BI_PROFILE_UPDATE_RET(/*bci=*/((int)(intptr_t)(LOCALS_ADDR(pc[1]))));
-          // now, update the pc
+          // Now, update the pc.
           pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(pc[1]));
           UPDATE_PC_AND_CONTINUE(0);
       }
--- a/src/share/vm/interpreter/bytecodeInterpreterProfiling.hpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/share/vm/interpreter/bytecodeInterpreterProfiling.hpp	Mon Feb 10 12:33:17 2014 +0100
@@ -1,6 +1,6 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2012 SAP AG. All rights reserved.
+ * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2012, 2013 SAP AG. 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
@@ -34,8 +34,8 @@
 // Global settings /////////////////////////////////////////////////////////////
 
 
-// Enables profiling support
-#if defined(COMPILER2) && defined(PPC64)
+// Enables profiling support.
+#if defined(COMPILER2)
 #define CC_INTERP_PROFILE
 #endif
 
@@ -75,7 +75,6 @@
 
 // Non-dummy implementations ///////////////////////////////////////////////////
 
-
 // Accessors for the current method data pointer 'mdx'.
 #define MDX()        (istate->mdx())
 #define SET_MDX(mdx)                                                           \
@@ -248,7 +247,7 @@
       ReceiverTypeData::set_null_seen(MDX());                                  \
     } else {                                                                   \
       /* Template interpreter doesn't increment count. */                      \
-      /* ReceiverTypeData::increment_count_no_overflow(MDX());*/               \
+      /* ReceiverTypeData::increment_count_no_overflow(MDX()); */              \
       ReceiverTypeData::increment_receiver_count_no_overflow(MDX(), receiver); \
     }                                                                          \
     SET_MDX(ReceiverTypeData::advance(MDX()));                                 \
--- a/src/share/vm/interpreter/interpreterRuntime.cpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/share/vm/interpreter/interpreterRuntime.cpp	Mon Feb 10 12:33:17 2014 +0100
@@ -251,18 +251,15 @@
 //------------------------------------------------------------------------------------------------------------------------
 // Exceptions
 
-// Assume the compiler is (or will be) interested in this event.
-// If necessary, create an MDO to hold the information, and record it.
-void InterpreterRuntime::note_trap(JavaThread* thread, int reason, TRAPS) {
-  assert(ProfileTraps, "call me only if profiling");
-  methodHandle trap_method(thread, method(thread));
-
+void InterpreterRuntime::note_trap_inner(JavaThread* thread, int reason,
+                                         methodHandle trap_method, int trap_bci, TRAPS) {
   if (trap_method.not_null()) {
     methodDataHandle trap_mdo(thread, trap_method->method_data());
     if (trap_mdo.is_null()) {
       methodOopDesc::build_interpreter_method_data(trap_method, THREAD);
       if (HAS_PENDING_EXCEPTION) {
-        assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
+        assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())),
+               "we expect only an OOM error here");
         CLEAR_PENDING_EXCEPTION;
       }
       trap_mdo = methodDataHandle(thread, trap_method->method_data());
@@ -271,38 +268,25 @@
     if (trap_mdo.not_null()) {
       // Update per-method count of trap events.  The interpreter
       // is updating the MDO to simulate the effect of compiler traps.
-      int trap_bci = trap_method->bci_from(bcp(thread));
       Deoptimization::update_method_data_from_interpreter(trap_mdo, trap_bci, reason);
     }
   }
 }
 
+// Assume the compiler is (or will be) interested in this event.
+// If necessary, create an MDO to hold the information, and record it.
+void InterpreterRuntime::note_trap(JavaThread* thread, int reason, TRAPS) {
+  assert(ProfileTraps, "call me only if profiling");
+  methodHandle trap_method(thread, method(thread));
+  int trap_bci = trap_method->bci_from(bcp(thread));
+  note_trap_inner(thread, reason, trap_method, trap_bci, THREAD);
+}
+
 #ifdef CC_INTERP
 // As legacy note_trap, but we have more arguments.
 IRT_ENTRY(void, InterpreterRuntime::note_trap(JavaThread* thread, int reason, methodOop method, int trap_bci))
   methodHandle trap_method(method);
-
-  // START derived from note_trap
-  // passed as arg: methodHandle trap_method(thread, method(thread));
-  if (trap_method.not_null()) {
-    methodDataHandle trap_mdo(thread, trap_method->method_data());
-    if (trap_mdo.is_null()) {
-      methodOopDesc::build_interpreter_method_data(trap_method, THREAD);
-      if (HAS_PENDING_EXCEPTION) {
-        assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
-        CLEAR_PENDING_EXCEPTION;
-      }
-      trap_mdo = trap_method->method_data();
-      // and fall through...
-    }
-    if (trap_mdo.not_null()) {
-      // Update per-method count of trap events. The interpreter
-      // is updating the MDO to simulate the effect of compiler traps.
-      // Passed as arg int trap_bci = trap_method->bci_from(bcp(thread));
-      Deoptimization::update_method_data_from_interpreter(trap_mdo, trap_bci, reason);
-    }
-  }
-  // END derived from note_trap
+  note_trap_inner(thread, reason, trap_method, trap_bci, THREAD);
 IRT_END
 
 // Class Deoptimization is not visible in BytecodeInterpreter, so we need a wrapper
--- a/src/share/vm/interpreter/interpreterRuntime.hpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/share/vm/interpreter/interpreterRuntime.hpp	Mon Feb 10 12:33:17 2014 +0100
@@ -80,13 +80,15 @@
 
   static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i)  { return method(thread)->constants()->cache()->entry_at(i); }
   static ConstantPoolCacheEntry* cache_entry(JavaThread *thread)            { return cache_entry_at(thread, Bytes::get_native_u2(bcp(thread) + 1)); }
+  static void      note_trap_inner(JavaThread* thread, int reason,
+                                   methodHandle trap_method, int trap_bci, TRAPS);
   static void      note_trap(JavaThread *thread, int reason, TRAPS);
 #ifdef CC_INTERP
   // Profile traps in C++ interpreter.
   static void      note_trap(JavaThread* thread, int reason, methodOop method, int trap_bci);
 #endif // CC_INTERP
 
-  // Inner work method for Interpreter's frequency counter overflow
+  // Inner work method for Interpreter's frequency counter overflow.
   static nmethod* frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp);
 
  public:
@@ -117,13 +119,13 @@
   static void    throw_pending_exception(JavaThread* thread);
 
 #ifdef CC_INTERP
-  // Profile traps in C++ interpreter
+  // Profile traps in C++ interpreter.
   static void    note_nullCheck_trap (JavaThread* thread, methodOop method, int trap_bci);
   static void    note_div0Check_trap (JavaThread* thread, methodOop method, int trap_bci);
   static void    note_rangeCheck_trap(JavaThread* thread, methodOop method, int trap_bci);
   static void    note_classCheck_trap(JavaThread* thread, methodOop method, int trap_bci);
   static void    note_arrayCheck_trap(JavaThread* thread, methodOop method, int trap_bci);
-  // A dummy for makros that shall not profile traps
+  // A dummy for makros that shall not profile traps.
   static void    note_no_trap(JavaThread* thread, methodOop method, int trap_bci) {}
 #endif // CC_INTERP
 
--- a/src/share/vm/interpreter/invocationCounter.hpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/share/vm/interpreter/invocationCounter.hpp	Mon Feb 10 12:33:17 2014 +0100
@@ -96,20 +96,24 @@
   int   get_BackwardBranchLimit() const          { return InterpreterBackwardBranchLimit >> number_of_noncount_bits; }
   int   get_ProfileLimit() const                 { return InterpreterProfileLimit >> number_of_noncount_bits; }
 
+#ifdef CC_INTERP
   // Test counter using scaled limits like the asm interpreter would do rather than doing
   // the shifts to normalize the counter.
   // Checks sum of invocation_counter and backedge_counter as the template interpreter does.
   bool reached_InvocationLimit(InvocationCounter *back_edge_count) const {
-    return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >= (unsigned int) InterpreterInvocationLimit;
+    return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >=
+           (unsigned int) InterpreterInvocationLimit;
   }
   bool reached_BackwardBranchLimit(InvocationCounter *back_edge_count) const {
-    return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >= (unsigned int) InterpreterBackwardBranchLimit;
+    return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >=
+           (unsigned int) InterpreterBackwardBranchLimit;
   }
-
-  // Do this just like asm interpreter does for max speed
+  // Do this just like asm interpreter does for max speed.
   bool reached_ProfileLimit(InvocationCounter *back_edge_count) const {
-    return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >= (unsigned int) InterpreterProfileLimit;
+    return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >=
+           (unsigned int) InterpreterProfileLimit;
   }
+#endif // CC_INTERP
 
   void increment()                               { _counter += count_increment; }
 
--- a/src/share/vm/oops/methodDataOop.hpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/share/vm/oops/methodDataOop.hpp	Mon Feb 10 12:33:17 2014 +0100
@@ -620,7 +620,7 @@
     increment_uint_at_no_overflow(layout, count_off);
   }
 
-  // Support counter decrementation at checkcast / subtype check failed
+  // Support counter decrementation at checkcast / subtype check failed.
   static void decrement_count(DataLayout* layout) {
     increment_uint_at_no_overflow(layout, count_off, -1);
   }
--- a/src/share/vm/runtime/arguments.cpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/share/vm/runtime/arguments.cpp	Mon Feb 10 12:33:17 2014 +0100
@@ -3485,14 +3485,11 @@
     UseBiasedLocking = false;
   }
 
-#ifdef CC_INTERP
-  // Clear flags not supported by the C++ interpreter
-#if !defined(PPC64)
-  // Now supported by CC_INTERP, but not tested with other ports than PPC.
-  LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false));
+#ifdef ZERO
+  // Clear flags not supported on zero.
   FLAG_SET_DEFAULT(ProfileInterpreter, false);
   FLAG_SET_DEFAULT(UseBiasedLocking, false);
-#endif
+  LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false));
 #endif // CC_INTERP
 
 #ifdef COMPILER2
--- a/src/share/vm/runtime/globals.hpp	Mon Feb 10 11:52:36 2014 +0100
+++ b/src/share/vm/runtime/globals.hpp	Mon Feb 10 12:33:17 2014 +0100
@@ -2729,7 +2729,9 @@
            "Profile at the bytecode level during interpretation")           \
                                                                             \
   develop(bool, TraceProfileInterpreter, false,                             \
-           "Trace profiling at the bytecode level during interpretation")   \
+          "Trace profiling at the bytecode level during interpretation. "   \
+          "This outputs the profiling information collected to improve "    \
+          "jit compilation.")                                               \
                                                                             \
   develop_pd(bool, ProfileTraps,                                            \
           "Profile deoptimization traps at the bytecode level")             \