OpenJDK / bsd-port / bsd-port / hotspot
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") \