diff -r cc624b341ab2 -r 970dc585ab63 hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp --- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Sep 02 11:40:02 2010 -0700 +++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Fri Sep 03 17:51:07 2010 -0700 @@ -294,34 +294,64 @@ // ??: invocation counter // void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { - // Update standard invocation counters - __ increment_invocation_counter(O0, G3_scratch); - if (ProfileInterpreter) { // %%% Merge this into methodDataOop - Address interpreter_invocation_counter(Lmethod, methodOopDesc::interpreter_invocation_counter_offset()); - __ ld(interpreter_invocation_counter, G3_scratch); - __ inc(G3_scratch); - __ st(G3_scratch, interpreter_invocation_counter); - } + // Note: In tiered we increment either counters in methodOop or in MDO depending if we're profiling or not. + if (TieredCompilation) { + const int increment = InvocationCounter::count_increment; + const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; + Label no_mdo, done; + if (ProfileInterpreter) { + // If no method data exists, go to profile_continue. + __ ld_ptr(Lmethod, methodOopDesc::method_data_offset(), G4_scratch); + __ br_null(G4_scratch, false, Assembler::pn, no_mdo); + __ delayed()->nop(); + // Increment counter + Address mdo_invocation_counter(G4_scratch, + in_bytes(methodDataOopDesc::invocation_counter_offset()) + + in_bytes(InvocationCounter::counter_offset())); + __ increment_mask_and_jump(mdo_invocation_counter, increment, mask, + G3_scratch, Lscratch, + Assembler::zero, overflow); + __ ba(false, done); + __ delayed()->nop(); + } - if (ProfileInterpreter && profile_method != NULL) { - // Test to see if we should create a method data oop - AddressLiteral profile_limit(&InvocationCounter::InterpreterProfileLimit); - __ sethi(profile_limit, G3_scratch); - __ ld(G3_scratch, profile_limit.low10(), G3_scratch); - __ cmp(O0, G3_scratch); - __ br(Assembler::lessUnsigned, false, Assembler::pn, *profile_method_continue); - __ delayed()->nop(); + // Increment counter in methodOop + __ bind(no_mdo); + Address invocation_counter(Lmethod, + in_bytes(methodOopDesc::invocation_counter_offset()) + + in_bytes(InvocationCounter::counter_offset())); + __ increment_mask_and_jump(invocation_counter, increment, mask, + G3_scratch, Lscratch, + Assembler::zero, overflow); + __ bind(done); + } else { + // Update standard invocation counters + __ increment_invocation_counter(O0, G3_scratch); + if (ProfileInterpreter) { // %%% Merge this into methodDataOop + Address interpreter_invocation_counter(Lmethod,in_bytes(methodOopDesc::interpreter_invocation_counter_offset())); + __ ld(interpreter_invocation_counter, G3_scratch); + __ inc(G3_scratch); + __ st(G3_scratch, interpreter_invocation_counter); + } - // if no method data exists, go to profile_method - __ test_method_data_pointer(*profile_method); - } + if (ProfileInterpreter && profile_method != NULL) { + // Test to see if we should create a method data oop + AddressLiteral profile_limit((address)&InvocationCounter::InterpreterProfileLimit); + __ load_contents(profile_limit, G3_scratch); + __ cmp(O0, G3_scratch); + __ br(Assembler::lessUnsigned, false, Assembler::pn, *profile_method_continue); + __ delayed()->nop(); - AddressLiteral invocation_limit(&InvocationCounter::InterpreterInvocationLimit); - __ sethi(invocation_limit, G3_scratch); - __ ld(G3_scratch, invocation_limit.low10(), G3_scratch); - __ cmp(O0, G3_scratch); - __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); - __ delayed()->nop(); + // if no method data exists, go to profile_method + __ test_method_data_pointer(*profile_method); + } + + AddressLiteral invocation_limit((address)&InvocationCounter::InterpreterInvocationLimit); + __ load_contents(invocation_limit, G3_scratch); + __ cmp(O0, G3_scratch); + __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); + __ delayed()->nop(); + } }