Thu, 18 Apr 2013 17:00:16 -0400
Merge
src/cpu/sparc/vm/templateTable_sparc.cpp | file | annotate | diff | comparison | revisions | |
src/cpu/x86/vm/templateTable_x86_64.cpp | file | annotate | diff | comparison | revisions |
1.1 --- a/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Thu Apr 18 14:38:31 2013 +0200 1.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java Thu Apr 18 17:00:16 2013 -0400 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 1.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 * 1.9 * This code is free software; you can redistribute it and/or modify it 1.10 @@ -49,19 +49,13 @@ 1.11 Type type = db.lookupType("Method"); 1.12 constMethod = type.getAddressField("_constMethod"); 1.13 methodData = type.getAddressField("_method_data"); 1.14 + methodCounters = type.getAddressField("_method_counters"); 1.15 methodSize = new CIntField(type.getCIntegerField("_method_size"), 0); 1.16 accessFlags = new CIntField(type.getCIntegerField("_access_flags"), 0); 1.17 code = type.getAddressField("_code"); 1.18 vtableIndex = new CIntField(type.getCIntegerField("_vtable_index"), 0); 1.19 - if (!VM.getVM().isCore()) { 1.20 - invocationCounter = new CIntField(type.getCIntegerField("_invocation_counter"), 0); 1.21 - backedgeCounter = new CIntField(type.getCIntegerField("_backedge_counter"), 0); 1.22 - } 1.23 bytecodeOffset = type.getSize(); 1.24 1.25 - interpreterThrowoutCountField = new CIntField(type.getCIntegerField("_interpreter_throwout_count"), 0); 1.26 - interpreterInvocationCountField = new CIntField(type.getCIntegerField("_interpreter_invocation_count"), 0); 1.27 - 1.28 /* 1.29 interpreterEntry = type.getAddressField("_interpreter_entry"); 1.30 fromCompiledCodeEntryPoint = type.getAddressField("_from_compiled_code_entry_point"); 1.31 @@ -80,18 +74,14 @@ 1.32 // Fields 1.33 private static AddressField constMethod; 1.34 private static AddressField methodData; 1.35 + private static AddressField methodCounters; 1.36 private static CIntField methodSize; 1.37 private static CIntField accessFlags; 1.38 private static CIntField vtableIndex; 1.39 - private static CIntField invocationCounter; 1.40 - private static CIntField backedgeCounter; 1.41 private static long bytecodeOffset; 1.42 1.43 private static AddressField code; 1.44 1.45 - private static CIntField interpreterThrowoutCountField; 1.46 - private static CIntField interpreterInvocationCountField; 1.47 - 1.48 // constant method names - <init>, <clinit> 1.49 // Initialized lazily to avoid initialization ordering dependencies between Method and SymbolTable 1.50 private static Symbol objectInitializerName; 1.51 @@ -127,6 +117,10 @@ 1.52 Address addr = methodData.getValue(getAddress()); 1.53 return (MethodData) VMObjectFactory.newObject(MethodData.class, addr); 1.54 } 1.55 + public MethodCounters getMethodCounters() { 1.56 + Address addr = methodCounters.getValue(getAddress()); 1.57 + return (MethodCounters) VMObjectFactory.newObject(MethodCounters.class, addr); 1.58 + } 1.59 /** WARNING: this is in words, not useful in this system; use getObjectSize() instead */ 1.60 public long getMethodSize() { return methodSize.getValue(this); } 1.61 public long getMaxStack() { return getConstMethod().getMaxStack(); } 1.62 @@ -139,16 +133,10 @@ 1.63 public long getCodeSize() { return getConstMethod().getCodeSize(); } 1.64 public long getVtableIndex() { return vtableIndex.getValue(this); } 1.65 public long getInvocationCounter() { 1.66 - if (Assert.ASSERTS_ENABLED) { 1.67 - Assert.that(!VM.getVM().isCore(), "must not be used in core build"); 1.68 - } 1.69 - return invocationCounter.getValue(this); 1.70 + return getMethodCounters().getInvocationCounter(); 1.71 } 1.72 public long getBackedgeCounter() { 1.73 - if (Assert.ASSERTS_ENABLED) { 1.74 - Assert.that(!VM.getVM().isCore(), "must not be used in core build"); 1.75 - } 1.76 - return backedgeCounter.getValue(this); 1.77 + return getMethodCounters().getBackedgeCounter(); 1.78 } 1.79 1.80 // get associated compiled native method, if available, else return null. 1.81 @@ -369,10 +357,10 @@ 1.82 } 1.83 1.84 public int interpreterThrowoutCount() { 1.85 - return (int) interpreterThrowoutCountField.getValue(this); 1.86 + return getMethodCounters().interpreterThrowoutCount(); 1.87 } 1.88 1.89 public int interpreterInvocationCount() { 1.90 - return (int) interpreterInvocationCountField.getValue(this); 1.91 + return getMethodCounters().interpreterInvocationCount(); 1.92 } 1.93 }
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/agent/src/share/classes/sun/jvm/hotspot/oops/MethodCounters.java Thu Apr 18 17:00:16 2013 -0400 2.3 @@ -0,0 +1,86 @@ 2.4 +/* 2.5 + * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. 2.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 + * 2.8 + * This code is free software; you can redistribute it and/or modify it 2.9 + * under the terms of the GNU General Public License version 2 only, as 2.10 + * published by the Free Software Foundation. 2.11 + * 2.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 2.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.15 + * version 2 for more details (a copy is included in the LICENSE file that 2.16 + * accompanied this code). 2.17 + * 2.18 + * You should have received a copy of the GNU General Public License version 2.19 + * 2 along with this work; if not, write to the Free Software Foundation, 2.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.21 + * 2.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.23 + * or visit www.oracle.com if you need additional information or have any 2.24 + * questions. 2.25 + * 2.26 + */ 2.27 + 2.28 +package sun.jvm.hotspot.oops; 2.29 + 2.30 +import java.io.*; 2.31 +import java.util.*; 2.32 +import sun.jvm.hotspot.debugger.*; 2.33 +import sun.jvm.hotspot.runtime.*; 2.34 +import sun.jvm.hotspot.types.*; 2.35 +import sun.jvm.hotspot.utilities.*; 2.36 + 2.37 +public class MethodCounters extends Metadata { 2.38 + public MethodCounters(Address addr) { 2.39 + super(addr); 2.40 + } 2.41 + 2.42 + static { 2.43 + VM.registerVMInitializedObserver(new Observer() { 2.44 + public void update(Observable o, Object data) { 2.45 + initialize(VM.getVM().getTypeDataBase()); 2.46 + } 2.47 + }); 2.48 + } 2.49 + 2.50 + private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { 2.51 + Type type = db.lookupType("MethodCounters"); 2.52 + 2.53 + interpreterInvocationCountField = new CIntField(type.getCIntegerField("_interpreter_invocation_count"), 0); 2.54 + interpreterThrowoutCountField = new CIntField(type.getCIntegerField("_interpreter_throwout_count"), 0); 2.55 + if (!VM.getVM().isCore()) { 2.56 + invocationCounter = new CIntField(type.getCIntegerField("_invocation_counter"), 0); 2.57 + backedgeCounter = new CIntField(type.getCIntegerField("_backedge_counter"), 0); 2.58 + } 2.59 + } 2.60 + 2.61 + private static CIntField interpreterInvocationCountField; 2.62 + private static CIntField interpreterThrowoutCountField; 2.63 + private static CIntField invocationCounter; 2.64 + private static CIntField backedgeCounter; 2.65 + 2.66 + public int interpreterInvocationCount() { 2.67 + return (int) interpreterInvocationCountField.getValue(this); 2.68 + } 2.69 + 2.70 + public int interpreterThrowoutCount() { 2.71 + return (int) interpreterThrowoutCountField.getValue(this); 2.72 + } 2.73 + public long getInvocationCounter() { 2.74 + if (Assert.ASSERTS_ENABLED) { 2.75 + Assert.that(!VM.getVM().isCore(), "must not be used in core build"); 2.76 + } 2.77 + return invocationCounter.getValue(this); 2.78 + } 2.79 + public long getBackedgeCounter() { 2.80 + if (Assert.ASSERTS_ENABLED) { 2.81 + Assert.that(!VM.getVM().isCore(), "must not be used in core build"); 2.82 + } 2.83 + return backedgeCounter.getValue(this); 2.84 + } 2.85 + 2.86 + public void printValueOn(PrintStream tty) { 2.87 + } 2.88 +} 2.89 +
3.1 --- a/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Thu Apr 18 14:38:31 2013 +0200 3.2 +++ b/src/cpu/sparc/vm/cppInterpreter_sparc.cpp Thu Apr 18 17:00:16 2013 -0400 3.3 @@ -1,5 +1,5 @@ 3.4 /* 3.5 - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. 3.6 + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 3.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.8 * 3.9 * This code is free software; you can redistribute it and/or modify it 3.10 @@ -404,14 +404,20 @@ 3.11 // ??: invocation counter 3.12 // 3.13 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { 3.14 + Label done; 3.15 + const Register Rcounters = G3_scratch; 3.16 + 3.17 + __ ld_ptr(STATE(_method), G5_method); 3.18 + __ get_method_counters(G5_method, Rcounters, done); 3.19 + 3.20 // Update standard invocation counters 3.21 - __ increment_invocation_counter(O0, G3_scratch); 3.22 - if (ProfileInterpreter) { // %%% Merge this into MethodData* 3.23 - __ ld_ptr(STATE(_method), G3_scratch); 3.24 - Address interpreter_invocation_counter(G3_scratch, 0, in_bytes(Method::interpreter_invocation_counter_offset())); 3.25 - __ ld(interpreter_invocation_counter, G3_scratch); 3.26 - __ inc(G3_scratch); 3.27 - __ st(G3_scratch, interpreter_invocation_counter); 3.28 + __ increment_invocation_counter(Rcounters, O0, G4_scratch); 3.29 + if (ProfileInterpreter) { 3.30 + Address interpreter_invocation_counter(Rcounters, 0, 3.31 + in_bytes(MethodCounters::interpreter_invocation_counter_offset())); 3.32 + __ ld(interpreter_invocation_counter, G4_scratch); 3.33 + __ inc(G4_scratch); 3.34 + __ st(G4_scratch, interpreter_invocation_counter); 3.35 } 3.36 3.37 Address invocation_limit(G3_scratch, (address)&InvocationCounter::InterpreterInvocationLimit); 3.38 @@ -420,7 +426,7 @@ 3.39 __ cmp(O0, G3_scratch); 3.40 __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); 3.41 __ delayed()->nop(); 3.42 - 3.43 + __ bind(done); 3.44 } 3.45 3.46 address InterpreterGenerator::generate_empty_entry(void) {
4.1 --- a/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Apr 18 14:38:31 2013 +0200 4.2 +++ b/src/cpu/sparc/vm/interp_masm_sparc.cpp Thu Apr 18 17:00:16 2013 -0400 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -30,6 +30,7 @@ 4.11 #include "oops/markOop.hpp" 4.12 #include "oops/methodData.hpp" 4.13 #include "oops/method.hpp" 4.14 +#include "oops/methodCounters.hpp" 4.15 #include "prims/jvmtiExport.hpp" 4.16 #include "prims/jvmtiRedefineClassesTrace.hpp" 4.17 #include "prims/jvmtiThreadState.hpp" 4.18 @@ -2086,19 +2087,28 @@ 4.19 4.20 #endif /* CC_INTERP */ 4.21 4.22 -void InterpreterMacroAssembler::increment_invocation_counter( Register Rtmp, Register Rtmp2 ) { 4.23 +void InterpreterMacroAssembler::get_method_counters(Register method, 4.24 + Register Rcounters, 4.25 + Label& skip) { 4.26 + Label has_counters; 4.27 + Address method_counters(method, in_bytes(Method::method_counters_offset())); 4.28 + ld_ptr(method_counters, Rcounters); 4.29 + br_notnull_short(Rcounters, Assembler::pt, has_counters); 4.30 + call_VM(noreg, CAST_FROM_FN_PTR(address, 4.31 + InterpreterRuntime::build_method_counters), method); 4.32 + ld_ptr(method_counters, Rcounters); 4.33 + br_null_short(Rcounters, Assembler::pn, skip); // No MethodCounters, OutOfMemory 4.34 + bind(has_counters); 4.35 +} 4.36 + 4.37 +void InterpreterMacroAssembler::increment_invocation_counter( Register Rcounters, Register Rtmp, Register Rtmp2 ) { 4.38 assert(UseCompiler, "incrementing must be useful"); 4.39 -#ifdef CC_INTERP 4.40 - Address inv_counter(G5_method, Method::invocation_counter_offset() + 4.41 + assert_different_registers(Rcounters, Rtmp, Rtmp2); 4.42 + 4.43 + Address inv_counter(Rcounters, MethodCounters::invocation_counter_offset() + 4.44 InvocationCounter::counter_offset()); 4.45 - Address be_counter (G5_method, Method::backedge_counter_offset() + 4.46 + Address be_counter (Rcounters, MethodCounters::backedge_counter_offset() + 4.47 InvocationCounter::counter_offset()); 4.48 -#else 4.49 - Address inv_counter(Lmethod, Method::invocation_counter_offset() + 4.50 - InvocationCounter::counter_offset()); 4.51 - Address be_counter (Lmethod, Method::backedge_counter_offset() + 4.52 - InvocationCounter::counter_offset()); 4.53 -#endif /* CC_INTERP */ 4.54 int delta = InvocationCounter::count_increment; 4.55 4.56 // Load each counter in a register 4.57 @@ -2122,19 +2132,15 @@ 4.58 // Note that this macro must leave the backedge_count + invocation_count in Rtmp! 4.59 } 4.60 4.61 -void InterpreterMacroAssembler::increment_backedge_counter( Register Rtmp, Register Rtmp2 ) { 4.62 +void InterpreterMacroAssembler::increment_backedge_counter( Register Rcounters, Register Rtmp, Register Rtmp2 ) { 4.63 assert(UseCompiler, "incrementing must be useful"); 4.64 -#ifdef CC_INTERP 4.65 - Address be_counter (G5_method, Method::backedge_counter_offset() + 4.66 + assert_different_registers(Rcounters, Rtmp, Rtmp2); 4.67 + 4.68 + Address be_counter (Rcounters, MethodCounters::backedge_counter_offset() + 4.69 InvocationCounter::counter_offset()); 4.70 - Address inv_counter(G5_method, Method::invocation_counter_offset() + 4.71 + Address inv_counter(Rcounters, MethodCounters::invocation_counter_offset() + 4.72 InvocationCounter::counter_offset()); 4.73 -#else 4.74 - Address be_counter (Lmethod, Method::backedge_counter_offset() + 4.75 - InvocationCounter::counter_offset()); 4.76 - Address inv_counter(Lmethod, Method::invocation_counter_offset() + 4.77 - InvocationCounter::counter_offset()); 4.78 -#endif /* CC_INTERP */ 4.79 + 4.80 int delta = InvocationCounter::count_increment; 4.81 // Load each counter in a register 4.82 ld( be_counter, Rtmp );
5.1 --- a/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Apr 18 14:38:31 2013 +0200 5.2 +++ b/src/cpu/sparc/vm/interp_masm_sparc.hpp Thu Apr 18 17:00:16 2013 -0400 5.3 @@ -1,5 +1,5 @@ 5.4 /* 5.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 5.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 5.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.8 * 5.9 * This code is free software; you can redistribute it and/or modify it 5.10 @@ -263,8 +263,9 @@ 5.11 void compute_stack_base( Register Rdest ); 5.12 5.13 #endif /* CC_INTERP */ 5.14 - void increment_invocation_counter( Register Rtmp, Register Rtmp2 ); 5.15 - void increment_backedge_counter( Register Rtmp, Register Rtmp2 ); 5.16 + void get_method_counters(Register method, Register Rcounters, Label& skip); 5.17 + void increment_invocation_counter( Register Rcounters, Register Rtmp, Register Rtmp2 ); 5.18 + void increment_backedge_counter( Register Rcounters, Register Rtmp, Register Rtmp2 ); 5.19 #ifndef CC_INTERP 5.20 void test_backedge_count_for_osr( Register backedge_count, Register branch_bcp, Register Rtmp ); 5.21
6.1 --- a/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Apr 18 14:38:31 2013 +0200 6.2 +++ b/src/cpu/sparc/vm/templateInterpreter_sparc.cpp Thu Apr 18 17:00:16 2013 -0400 6.3 @@ -1,5 +1,5 @@ 6.4 /* 6.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 6.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 6.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.8 * 6.9 * This code is free software; you can redistribute it and/or modify it 6.10 @@ -292,11 +292,15 @@ 6.11 // ??: invocation counter 6.12 // 6.13 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { 6.14 - // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. 6.15 + // Note: In tiered we increment either counters in MethodCounters* or in 6.16 + // MDO depending if we're profiling or not. 6.17 + const Register Rcounters = G3_scratch; 6.18 + Label done; 6.19 + 6.20 if (TieredCompilation) { 6.21 const int increment = InvocationCounter::count_increment; 6.22 const int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; 6.23 - Label no_mdo, done; 6.24 + Label no_mdo; 6.25 if (ProfileInterpreter) { 6.26 // If no method data exists, go to profile_continue. 6.27 __ ld_ptr(Lmethod, Method::method_data_offset(), G4_scratch); 6.28 @@ -311,23 +315,26 @@ 6.29 __ ba_short(done); 6.30 } 6.31 6.32 - // Increment counter in Method* 6.33 + // Increment counter in MethodCounters* 6.34 __ bind(no_mdo); 6.35 - Address invocation_counter(Lmethod, 6.36 - in_bytes(Method::invocation_counter_offset()) + 6.37 - in_bytes(InvocationCounter::counter_offset())); 6.38 + Address invocation_counter(Rcounters, 6.39 + in_bytes(MethodCounters::invocation_counter_offset()) + 6.40 + in_bytes(InvocationCounter::counter_offset())); 6.41 + __ get_method_counters(Lmethod, Rcounters, done); 6.42 __ increment_mask_and_jump(invocation_counter, increment, mask, 6.43 - G3_scratch, Lscratch, 6.44 + G4_scratch, Lscratch, 6.45 Assembler::zero, overflow); 6.46 __ bind(done); 6.47 } else { 6.48 // Update standard invocation counters 6.49 - __ increment_invocation_counter(O0, G3_scratch); 6.50 - if (ProfileInterpreter) { // %%% Merge this into MethodData* 6.51 - Address interpreter_invocation_counter(Lmethod,in_bytes(Method::interpreter_invocation_counter_offset())); 6.52 - __ ld(interpreter_invocation_counter, G3_scratch); 6.53 - __ inc(G3_scratch); 6.54 - __ st(G3_scratch, interpreter_invocation_counter); 6.55 + __ get_method_counters(Lmethod, Rcounters, done); 6.56 + __ increment_invocation_counter(Rcounters, O0, G4_scratch); 6.57 + if (ProfileInterpreter) { 6.58 + Address interpreter_invocation_counter(Rcounters, 6.59 + in_bytes(MethodCounters::interpreter_invocation_counter_offset())); 6.60 + __ ld(interpreter_invocation_counter, G4_scratch); 6.61 + __ inc(G4_scratch); 6.62 + __ st(G4_scratch, interpreter_invocation_counter); 6.63 } 6.64 6.65 if (ProfileInterpreter && profile_method != NULL) { 6.66 @@ -345,6 +352,7 @@ 6.67 __ cmp(O0, G3_scratch); 6.68 __ br(Assembler::greaterEqualUnsigned, false, Assembler::pn, *overflow); // Far distance 6.69 __ delayed()->nop(); 6.70 + __ bind(done); 6.71 } 6.72 6.73 }
7.1 --- a/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Apr 18 14:38:31 2013 +0200 7.2 +++ b/src/cpu/sparc/vm/templateTable_sparc.cpp Thu Apr 18 17:00:16 2013 -0400 7.3 @@ -1611,9 +1611,8 @@ 7.4 // Normal (non-jsr) branch handling 7.5 7.6 // Save the current Lbcp 7.7 - const Register O0_cur_bcp = O0; 7.8 - __ mov( Lbcp, O0_cur_bcp ); 7.9 - 7.10 + const Register l_cur_bcp = Lscratch; 7.11 + __ mov( Lbcp, l_cur_bcp ); 7.12 7.13 bool increment_invocation_counter_for_backward_branches = UseCompiler && UseLoopCounter; 7.14 if ( increment_invocation_counter_for_backward_branches ) { 7.15 @@ -1623,6 +1622,9 @@ 7.16 // Bump bytecode pointer by displacement (take the branch) 7.17 __ delayed()->add( O1_disp, Lbcp, Lbcp ); // add to bc addr 7.18 7.19 + const Register Rcounters = G3_scratch; 7.20 + __ get_method_counters(Lmethod, Rcounters, Lforward); 7.21 + 7.22 if (TieredCompilation) { 7.23 Label Lno_mdo, Loverflow; 7.24 int increment = InvocationCounter::count_increment; 7.25 @@ -1635,21 +1637,22 @@ 7.26 // Increment backedge counter in the MDO 7.27 Address mdo_backedge_counter(G4_scratch, in_bytes(MethodData::backedge_counter_offset()) + 7.28 in_bytes(InvocationCounter::counter_offset())); 7.29 - __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, Lscratch, 7.30 + __ increment_mask_and_jump(mdo_backedge_counter, increment, mask, G3_scratch, O0, 7.31 Assembler::notZero, &Lforward); 7.32 __ ba_short(Loverflow); 7.33 } 7.34 7.35 - // If there's no MDO, increment counter in Method* 7.36 + // If there's no MDO, increment counter in MethodCounters* 7.37 __ bind(Lno_mdo); 7.38 - Address backedge_counter(Lmethod, in_bytes(Method::backedge_counter_offset()) + 7.39 - in_bytes(InvocationCounter::counter_offset())); 7.40 - __ increment_mask_and_jump(backedge_counter, increment, mask, G3_scratch, Lscratch, 7.41 + Address backedge_counter(Rcounters, 7.42 + in_bytes(MethodCounters::backedge_counter_offset()) + 7.43 + in_bytes(InvocationCounter::counter_offset())); 7.44 + __ increment_mask_and_jump(backedge_counter, increment, mask, G4_scratch, O0, 7.45 Assembler::notZero, &Lforward); 7.46 __ bind(Loverflow); 7.47 7.48 // notify point for loop, pass branch bytecode 7.49 - __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), O0_cur_bcp); 7.50 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::frequency_counter_overflow), l_cur_bcp); 7.51 7.52 // Was an OSR adapter generated? 7.53 // O0 = osr nmethod 7.54 @@ -1686,15 +1689,15 @@ 7.55 } else { 7.56 // Update Backedge branch separately from invocations 7.57 const Register G4_invoke_ctr = G4; 7.58 - __ increment_backedge_counter(G4_invoke_ctr, G1_scratch); 7.59 + __ increment_backedge_counter(Rcounters, G4_invoke_ctr, G1_scratch); 7.60 if (ProfileInterpreter) { 7.61 __ test_invocation_counter_for_mdp(G4_invoke_ctr, G3_scratch, Lforward); 7.62 if (UseOnStackReplacement) { 7.63 - __ test_backedge_count_for_osr(O2_bumped_count, O0_cur_bcp, G3_scratch); 7.64 + __ test_backedge_count_for_osr(O2_bumped_count, l_cur_bcp, G3_scratch); 7.65 } 7.66 } else { 7.67 if (UseOnStackReplacement) { 7.68 - __ test_backedge_count_for_osr(G4_invoke_ctr, O0_cur_bcp, G3_scratch); 7.69 + __ test_backedge_count_for_osr(G4_invoke_ctr, l_cur_bcp, G3_scratch); 7.70 } 7.71 } 7.72 }
8.1 --- a/src/cpu/x86/vm/cppInterpreter_x86.cpp Thu Apr 18 14:38:31 2013 +0200 8.2 +++ b/src/cpu/x86/vm/cppInterpreter_x86.cpp Thu Apr 18 17:00:16 2013 -0400 8.3 @@ -1,5 +1,5 @@ 8.4 /* 8.5 - * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. 8.6 + * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved. 8.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.8 * 8.9 * This code is free software; you can redistribute it and/or modify it 8.10 @@ -570,20 +570,28 @@ 8.11 // rcx: invocation counter 8.12 // 8.13 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { 8.14 - 8.15 - const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); 8.16 - const Address backedge_counter (rbx, Method::backedge_counter_offset() + InvocationCounter::counter_offset()); 8.17 - 8.18 - if (ProfileInterpreter) { // %%% Merge this into MethodData* 8.19 - __ incrementl(Address(rbx,Method::interpreter_invocation_counter_offset())); 8.20 + Label done; 8.21 + const Address invocation_counter(rax, 8.22 + MethodCounters::invocation_counter_offset() + 8.23 + InvocationCounter::counter_offset()); 8.24 + const Address backedge_counter (rax, 8.25 + MethodCounter::backedge_counter_offset() + 8.26 + InvocationCounter::counter_offset()); 8.27 + 8.28 + __ get_method_counters(rbx, rax, done); 8.29 + 8.30 + if (ProfileInterpreter) { 8.31 + __ incrementl(Address(rax, 8.32 + MethodCounters::interpreter_invocation_counter_offset())); 8.33 } 8.34 // Update standard invocation counters 8.35 + __ movl(rcx, invocation_counter); 8.36 + __ increment(rcx, InvocationCounter::count_increment); 8.37 + __ movl(invocation_counter, rcx); // save invocation count 8.38 + 8.39 __ movl(rax, backedge_counter); // load backedge counter 8.40 - 8.41 - __ increment(rcx, InvocationCounter::count_increment); 8.42 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits 8.43 8.44 - __ movl(invocation_counter, rcx); // save invocation count 8.45 __ addl(rcx, rax); // add both counters 8.46 8.47 // profile_method is non-null only for interpreted method so 8.48 @@ -593,7 +601,7 @@ 8.49 __ cmp32(rcx, 8.50 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); 8.51 __ jcc(Assembler::aboveEqual, *overflow); 8.52 - 8.53 + __ bind(done); 8.54 } 8.55 8.56 void InterpreterGenerator::generate_counter_overflow(Label* do_continue) { 8.57 @@ -977,7 +985,6 @@ 8.58 address entry_point = __ pc(); 8.59 8.60 const Address constMethod (rbx, Method::const_offset()); 8.61 - const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); 8.62 const Address access_flags (rbx, Method::access_flags_offset()); 8.63 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset()); 8.64 8.65 @@ -1029,8 +1036,6 @@ 8.66 } 8.67 #endif 8.68 8.69 - if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count 8.70 - 8.71 const Register unlock_thread = LP64_ONLY(r15_thread) NOT_LP64(rax); 8.72 NOT_LP64(__ movptr(unlock_thread, STATE(_thread));) // get thread 8.73 // Since at this point in the method invocation the exception handler
9.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Apr 18 14:38:31 2013 +0200 9.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.cpp Thu Apr 18 17:00:16 2013 -0400 9.3 @@ -1,5 +1,5 @@ 9.4 /* 9.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 9.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 9.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.8 * 9.9 * This code is free software; you can redistribute it and/or modify it 9.10 @@ -266,6 +266,20 @@ 9.11 addptr(cache, tmp); // construct pointer to cache entry 9.12 } 9.13 9.14 +void InterpreterMacroAssembler::get_method_counters(Register method, 9.15 + Register mcs, Label& skip) { 9.16 + Label has_counters; 9.17 + movptr(mcs, Address(method, Method::method_counters_offset())); 9.18 + testptr(mcs, mcs); 9.19 + jcc(Assembler::notZero, has_counters); 9.20 + call_VM(noreg, CAST_FROM_FN_PTR(address, 9.21 + InterpreterRuntime::build_method_counters), method); 9.22 + movptr(mcs, Address(method,Method::method_counters_offset())); 9.23 + testptr(mcs, mcs); 9.24 + jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory 9.25 + bind(has_counters); 9.26 +} 9.27 + 9.28 // Load object from cpool->resolved_references(index) 9.29 void InterpreterMacroAssembler::load_resolved_reference_at_index( 9.30 Register result, Register index) {
10.1 --- a/src/cpu/x86/vm/interp_masm_x86_32.hpp Thu Apr 18 14:38:31 2013 +0200 10.2 +++ b/src/cpu/x86/vm/interp_masm_x86_32.hpp Thu Apr 18 17:00:16 2013 -0400 10.3 @@ -1,5 +1,5 @@ 10.4 /* 10.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 10.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 10.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 10.8 * 10.9 * This code is free software; you can redistribute it and/or modify it 10.10 @@ -89,6 +89,7 @@ 10.11 void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2)); 10.12 void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2)); 10.13 void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2)); 10.14 + void get_method_counters(Register method, Register mcs, Label& skip); 10.15 10.16 // load cpool->resolved_references(index); 10.17 void load_resolved_reference_at_index(Register result, Register index);
11.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Apr 18 14:38:31 2013 +0200 11.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.cpp Thu Apr 18 17:00:16 2013 -0400 11.3 @@ -1,5 +1,5 @@ 11.4 /* 11.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 11.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 11.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 11.8 * 11.9 * This code is free software; you can redistribute it and/or modify it 11.10 @@ -271,6 +271,20 @@ 11.11 addptr(cache, tmp); // construct pointer to cache entry 11.12 } 11.13 11.14 +void InterpreterMacroAssembler::get_method_counters(Register method, 11.15 + Register mcs, Label& skip) { 11.16 + Label has_counters; 11.17 + movptr(mcs, Address(method, Method::method_counters_offset())); 11.18 + testptr(mcs, mcs); 11.19 + jcc(Assembler::notZero, has_counters); 11.20 + call_VM(noreg, CAST_FROM_FN_PTR(address, 11.21 + InterpreterRuntime::build_method_counters), method); 11.22 + movptr(mcs, Address(method,Method::method_counters_offset())); 11.23 + testptr(mcs, mcs); 11.24 + jcc(Assembler::zero, skip); // No MethodCounters allocated, OutOfMemory 11.25 + bind(has_counters); 11.26 +} 11.27 + 11.28 // Load object from cpool->resolved_references(index) 11.29 void InterpreterMacroAssembler::load_resolved_reference_at_index( 11.30 Register result, Register index) {
12.1 --- a/src/cpu/x86/vm/interp_masm_x86_64.hpp Thu Apr 18 14:38:31 2013 +0200 12.2 +++ b/src/cpu/x86/vm/interp_masm_x86_64.hpp Thu Apr 18 17:00:16 2013 -0400 12.3 @@ -1,5 +1,5 @@ 12.4 /* 12.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 12.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 12.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.8 * 12.9 * This code is free software; you can redistribute it and/or modify it 12.10 @@ -111,6 +111,7 @@ 12.11 void get_cache_and_index_and_bytecode_at_bcp(Register cache, Register index, Register bytecode, int byte_no, int bcp_offset, size_t index_size = sizeof(u2)); 12.12 void get_cache_entry_pointer_at_bcp(Register cache, Register tmp, int bcp_offset, size_t index_size = sizeof(u2)); 12.13 void get_cache_index_at_bcp(Register index, int bcp_offset, size_t index_size = sizeof(u2)); 12.14 + void get_method_counters(Register method, Register mcs, Label& skip); 12.15 12.16 // load cpool->resolved_references(index); 12.17 void load_resolved_reference_at_index(Register result, Register index);
13.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Apr 18 14:38:31 2013 +0200 13.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_32.cpp Thu Apr 18 17:00:16 2013 -0400 13.3 @@ -1,5 +1,5 @@ 13.4 /* 13.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 13.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 13.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.8 * 13.9 * This code is free software; you can redistribute it and/or modify it 13.10 @@ -344,13 +344,13 @@ 13.11 // rcx: invocation counter 13.12 // 13.13 void InterpreterGenerator::generate_counter_incr(Label* overflow, Label* profile_method, Label* profile_method_continue) { 13.14 - const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) + 13.15 - in_bytes(InvocationCounter::counter_offset())); 13.16 - // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. 13.17 + Label done; 13.18 + // Note: In tiered we increment either counters in MethodCounters* or in MDO 13.19 + // depending if we're profiling or not. 13.20 if (TieredCompilation) { 13.21 int increment = InvocationCounter::count_increment; 13.22 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; 13.23 - Label no_mdo, done; 13.24 + Label no_mdo; 13.25 if (ProfileInterpreter) { 13.26 // Are we profiling? 13.27 __ movptr(rax, Address(rbx, Method::method_data_offset())); 13.28 @@ -363,23 +363,38 @@ 13.29 __ jmpb(done); 13.30 } 13.31 __ bind(no_mdo); 13.32 - // Increment counter in Method* (we don't need to load it, it's in rcx). 13.33 - __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow); 13.34 + // Increment counter in MethodCounters 13.35 + const Address invocation_counter(rax, 13.36 + MethodCounters::invocation_counter_offset() + 13.37 + InvocationCounter::counter_offset()); 13.38 + 13.39 + __ get_method_counters(rbx, rax, done); 13.40 + __ increment_mask_and_jump(invocation_counter, increment, mask, 13.41 + rcx, false, Assembler::zero, overflow); 13.42 __ bind(done); 13.43 } else { 13.44 - const Address backedge_counter (rbx, Method::backedge_counter_offset() + 13.45 - InvocationCounter::counter_offset()); 13.46 + const Address backedge_counter (rax, 13.47 + MethodCounters::backedge_counter_offset() + 13.48 + InvocationCounter::counter_offset()); 13.49 + const Address invocation_counter(rax, 13.50 + MethodCounters::invocation_counter_offset() + 13.51 + InvocationCounter::counter_offset()); 13.52 13.53 - if (ProfileInterpreter) { // %%% Merge this into MethodData* 13.54 - __ incrementl(Address(rbx,Method::interpreter_invocation_counter_offset())); 13.55 + __ get_method_counters(rbx, rax, done); 13.56 + 13.57 + if (ProfileInterpreter) { 13.58 + __ incrementl(Address(rax, 13.59 + MethodCounters::interpreter_invocation_counter_offset())); 13.60 } 13.61 + 13.62 // Update standard invocation counters 13.63 + __ movl(rcx, invocation_counter); 13.64 + __ incrementl(rcx, InvocationCounter::count_increment); 13.65 + __ movl(invocation_counter, rcx); // save invocation count 13.66 + 13.67 __ movl(rax, backedge_counter); // load backedge counter 13.68 - 13.69 - __ incrementl(rcx, InvocationCounter::count_increment); 13.70 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits 13.71 13.72 - __ movl(invocation_counter, rcx); // save invocation count 13.73 __ addl(rcx, rax); // add both counters 13.74 13.75 // profile_method is non-null only for interpreted method so 13.76 @@ -399,6 +414,7 @@ 13.77 __ cmp32(rcx, 13.78 ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); 13.79 __ jcc(Assembler::aboveEqual, *overflow); 13.80 + __ bind(done); 13.81 } 13.82 } 13.83 13.84 @@ -868,7 +884,6 @@ 13.85 address entry_point = __ pc(); 13.86 13.87 const Address constMethod (rbx, Method::const_offset()); 13.88 - const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); 13.89 const Address access_flags (rbx, Method::access_flags_offset()); 13.90 const Address size_of_parameters(rcx, ConstMethod::size_of_parameters_offset()); 13.91 13.92 @@ -897,9 +912,7 @@ 13.93 // NULL oop temp (mirror or jni oop result) 13.94 __ push((int32_t)NULL_WORD); 13.95 13.96 - if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count 13.97 // initialize fixed part of activation frame 13.98 - 13.99 generate_fixed_frame(true); 13.100 13.101 // make sure method is native & not abstract 13.102 @@ -1286,7 +1299,6 @@ 13.103 address entry_point = __ pc(); 13.104 13.105 const Address constMethod (rbx, Method::const_offset()); 13.106 - const Address invocation_counter(rbx, Method::invocation_counter_offset() + InvocationCounter::counter_offset()); 13.107 const Address access_flags (rbx, Method::access_flags_offset()); 13.108 const Address size_of_parameters(rdx, ConstMethod::size_of_parameters_offset()); 13.109 const Address size_of_locals (rdx, ConstMethod::size_of_locals_offset()); 13.110 @@ -1326,7 +1338,6 @@ 13.111 __ bind(exit); 13.112 } 13.113 13.114 - if (inc_counter) __ movl(rcx, invocation_counter); // (pre-)fetch invocation count 13.115 // initialize fixed part of activation frame 13.116 generate_fixed_frame(false); 13.117
14.1 --- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Apr 18 14:38:31 2013 +0200 14.2 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Thu Apr 18 17:00:16 2013 -0400 14.3 @@ -1,5 +1,5 @@ 14.4 /* 14.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 14.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 14.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.8 * 14.9 * This code is free software; you can redistribute it and/or modify it 14.10 @@ -300,13 +300,12 @@ 14.11 Label* overflow, 14.12 Label* profile_method, 14.13 Label* profile_method_continue) { 14.14 - const Address invocation_counter(rbx, in_bytes(Method::invocation_counter_offset()) + 14.15 - in_bytes(InvocationCounter::counter_offset())); 14.16 + Label done; 14.17 // Note: In tiered we increment either counters in Method* or in MDO depending if we're profiling or not. 14.18 if (TieredCompilation) { 14.19 int increment = InvocationCounter::count_increment; 14.20 int mask = ((1 << Tier0InvokeNotifyFreqLog) - 1) << InvocationCounter::count_shift; 14.21 - Label no_mdo, done; 14.22 + Label no_mdo; 14.23 if (ProfileInterpreter) { 14.24 // Are we profiling? 14.25 __ movptr(rax, Address(rbx, Method::method_data_offset())); 14.26 @@ -319,25 +318,36 @@ 14.27 __ jmpb(done); 14.28 } 14.29 __ bind(no_mdo); 14.30 - // Increment counter in Method* (we don't need to load it, it's in ecx). 14.31 - __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, true, Assembler::zero, overflow); 14.32 + // Increment counter in MethodCounters 14.33 + const Address invocation_counter(rax, 14.34 + MethodCounters::invocation_counter_offset() + 14.35 + InvocationCounter::counter_offset()); 14.36 + __ get_method_counters(rbx, rax, done); 14.37 + __ increment_mask_and_jump(invocation_counter, increment, mask, rcx, 14.38 + false, Assembler::zero, overflow); 14.39 __ bind(done); 14.40 } else { 14.41 - const Address backedge_counter(rbx, 14.42 - Method::backedge_counter_offset() + 14.43 - InvocationCounter::counter_offset()); 14.44 + const Address backedge_counter(rax, 14.45 + MethodCounters::backedge_counter_offset() + 14.46 + InvocationCounter::counter_offset()); 14.47 + const Address invocation_counter(rax, 14.48 + MethodCounters::invocation_counter_offset() + 14.49 + InvocationCounter::counter_offset()); 14.50 14.51 - if (ProfileInterpreter) { // %%% Merge this into MethodData* 14.52 - __ incrementl(Address(rbx, 14.53 - Method::interpreter_invocation_counter_offset())); 14.54 + __ get_method_counters(rbx, rax, done); 14.55 + 14.56 + if (ProfileInterpreter) { 14.57 + __ incrementl(Address(rax, 14.58 + MethodCounters::interpreter_invocation_counter_offset())); 14.59 } 14.60 // Update standard invocation counters 14.61 + __ movl(rcx, invocation_counter); 14.62 + __ incrementl(rcx, InvocationCounter::count_increment); 14.63 + __ movl(invocation_counter, rcx); // save invocation count 14.64 + 14.65 __ movl(rax, backedge_counter); // load backedge counter 14.66 - 14.67 - __ incrementl(rcx, InvocationCounter::count_increment); 14.68 __ andl(rax, InvocationCounter::count_mask_value); // mask out the status bits 14.69 14.70 - __ movl(invocation_counter, rcx); // save invocation count 14.71 __ addl(rcx, rax); // add both counters 14.72 14.73 // profile_method is non-null only for interpreted method so 14.74 @@ -354,6 +364,7 @@ 14.75 14.76 __ cmp32(rcx, ExternalAddress((address)&InvocationCounter::InterpreterInvocationLimit)); 14.77 __ jcc(Assembler::aboveEqual, *overflow); 14.78 + __ bind(done); 14.79 } 14.80 } 14.81 14.82 @@ -843,9 +854,6 @@ 14.83 address entry_point = __ pc(); 14.84 14.85 const Address constMethod (rbx, Method::const_offset()); 14.86 - const Address invocation_counter(rbx, Method:: 14.87 - invocation_counter_offset() + 14.88 - InvocationCounter::counter_offset()); 14.89 const Address access_flags (rbx, Method::access_flags_offset()); 14.90 const Address size_of_parameters(rcx, ConstMethod:: 14.91 size_of_parameters_offset()); 14.92 @@ -876,10 +884,6 @@ 14.93 // (static native method holder mirror/jni oop result) 14.94 __ push((int) NULL_WORD); 14.95 14.96 - if (inc_counter) { 14.97 - __ movl(rcx, invocation_counter); // (pre-)fetch invocation count 14.98 - } 14.99 - 14.100 // initialize fixed part of activation frame 14.101 generate_fixed_frame(true); 14.102 14.103 @@ -1296,9 +1300,6 @@ 14.104 address entry_point = __ pc(); 14.105 14.106 const Address constMethod(rbx, Method::const_offset()); 14.107 - const Address invocation_counter(rbx, 14.108 - Method::invocation_counter_offset() + 14.109 - InvocationCounter::counter_offset()); 14.110 const Address access_flags(rbx, Method::access_flags_offset()); 14.111 const Address size_of_parameters(rdx, 14.112 ConstMethod::size_of_parameters_offset()); 14.113 @@ -1343,10 +1344,6 @@ 14.114 __ bind(exit); 14.115 } 14.116 14.117 - // (pre-)fetch invocation count 14.118 - if (inc_counter) { 14.119 - __ movl(rcx, invocation_counter); 14.120 - } 14.121 // initialize fixed part of activation frame 14.122 generate_fixed_frame(false); 14.123
15.1 --- a/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Apr 18 14:38:31 2013 +0200 15.2 +++ b/src/cpu/x86/vm/templateTable_x86_32.cpp Thu Apr 18 17:00:16 2013 -0400 15.3 @@ -1,5 +1,5 @@ 15.4 /* 15.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 15.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 15.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 15.8 * 15.9 * This code is free software; you can redistribute it and/or modify it 15.10 @@ -1546,9 +1546,10 @@ 15.11 __ get_method(rcx); // ECX holds method 15.12 __ profile_taken_branch(rax,rbx); // EAX holds updated MDP, EBX holds bumped taken count 15.13 15.14 - const ByteSize be_offset = Method::backedge_counter_offset() + InvocationCounter::counter_offset(); 15.15 - const ByteSize inv_offset = Method::invocation_counter_offset() + InvocationCounter::counter_offset(); 15.16 - const int method_offset = frame::interpreter_frame_method_offset * wordSize; 15.17 + const ByteSize be_offset = MethodCounters::backedge_counter_offset() + 15.18 + InvocationCounter::counter_offset(); 15.19 + const ByteSize inv_offset = MethodCounters::invocation_counter_offset() + 15.20 + InvocationCounter::counter_offset(); 15.21 15.22 // Load up EDX with the branch displacement 15.23 __ movl(rdx, at_bcp(1)); 15.24 @@ -1596,6 +1597,22 @@ 15.25 __ testl(rdx, rdx); // check if forward or backward branch 15.26 __ jcc(Assembler::positive, dispatch); // count only if backward branch 15.27 15.28 + // check if MethodCounters exists 15.29 + Label has_counters; 15.30 + __ movptr(rax, Address(rcx, Method::method_counters_offset())); 15.31 + __ testptr(rax, rax); 15.32 + __ jcc(Assembler::notZero, has_counters); 15.33 + __ push(rdx); 15.34 + __ push(rcx); 15.35 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), 15.36 + rcx); 15.37 + __ pop(rcx); 15.38 + __ pop(rdx); 15.39 + __ movptr(rax, Address(rcx, Method::method_counters_offset())); 15.40 + __ testptr(rax, rax); 15.41 + __ jcc(Assembler::zero, dispatch); 15.42 + __ bind(has_counters); 15.43 + 15.44 if (TieredCompilation) { 15.45 Label no_mdo; 15.46 int increment = InvocationCounter::count_increment; 15.47 @@ -1613,16 +1630,19 @@ 15.48 __ jmp(dispatch); 15.49 } 15.50 __ bind(no_mdo); 15.51 - // Increment backedge counter in Method* 15.52 + // Increment backedge counter in MethodCounters* 15.53 + __ movptr(rcx, Address(rcx, Method::method_counters_offset())); 15.54 __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask, 15.55 rax, false, Assembler::zero, &backedge_counter_overflow); 15.56 } else { 15.57 // increment counter 15.58 + __ movptr(rcx, Address(rcx, Method::method_counters_offset())); 15.59 __ movl(rax, Address(rcx, be_offset)); // load backedge counter 15.60 __ incrementl(rax, InvocationCounter::count_increment); // increment counter 15.61 __ movl(Address(rcx, be_offset), rax); // store counter 15.62 15.63 __ movl(rax, Address(rcx, inv_offset)); // load invocation counter 15.64 + 15.65 __ andl(rax, InvocationCounter::count_mask_value); // and the status bits 15.66 __ addl(rax, Address(rcx, be_offset)); // add both counters 15.67
16.1 --- a/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Apr 18 14:38:31 2013 +0200 16.2 +++ b/src/cpu/x86/vm/templateTable_x86_64.cpp Thu Apr 18 17:00:16 2013 -0400 16.3 @@ -1,5 +1,5 @@ 16.4 /* 16.5 - * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 16.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. 16.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 16.8 * 16.9 * This code is free software; you can redistribute it and/or modify it 16.10 @@ -1569,11 +1569,10 @@ 16.11 __ profile_taken_branch(rax, rbx); // rax holds updated MDP, rbx 16.12 // holds bumped taken count 16.13 16.14 - const ByteSize be_offset = Method::backedge_counter_offset() + 16.15 + const ByteSize be_offset = MethodCounters::backedge_counter_offset() + 16.16 InvocationCounter::counter_offset(); 16.17 - const ByteSize inv_offset = Method::invocation_counter_offset() + 16.18 + const ByteSize inv_offset = MethodCounters::invocation_counter_offset() + 16.19 InvocationCounter::counter_offset(); 16.20 - const int method_offset = frame::interpreter_frame_method_offset * wordSize; 16.21 16.22 // Load up edx with the branch displacement 16.23 __ movl(rdx, at_bcp(1)); 16.24 @@ -1623,6 +1622,22 @@ 16.25 // r14: locals pointer 16.26 __ testl(rdx, rdx); // check if forward or backward branch 16.27 __ jcc(Assembler::positive, dispatch); // count only if backward branch 16.28 + 16.29 + // check if MethodCounters exists 16.30 + Label has_counters; 16.31 + __ movptr(rax, Address(rcx, Method::method_counters_offset())); 16.32 + __ testptr(rax, rax); 16.33 + __ jcc(Assembler::notZero, has_counters); 16.34 + __ push(rdx); 16.35 + __ push(rcx); 16.36 + __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters), 16.37 + rcx); 16.38 + __ pop(rcx); 16.39 + __ pop(rdx); 16.40 + __ movptr(rax, Address(rcx, Method::method_counters_offset())); 16.41 + __ jcc(Assembler::zero, dispatch); 16.42 + __ bind(has_counters); 16.43 + 16.44 if (TieredCompilation) { 16.45 Label no_mdo; 16.46 int increment = InvocationCounter::count_increment; 16.47 @@ -1640,16 +1655,19 @@ 16.48 __ jmp(dispatch); 16.49 } 16.50 __ bind(no_mdo); 16.51 - // Increment backedge counter in Method* 16.52 + // Increment backedge counter in MethodCounters* 16.53 + __ movptr(rcx, Address(rcx, Method::method_counters_offset())); 16.54 __ increment_mask_and_jump(Address(rcx, be_offset), increment, mask, 16.55 rax, false, Assembler::zero, &backedge_counter_overflow); 16.56 } else { 16.57 // increment counter 16.58 + __ movptr(rcx, Address(rcx, Method::method_counters_offset())); 16.59 __ movl(rax, Address(rcx, be_offset)); // load backedge counter 16.60 __ incrementl(rax, InvocationCounter::count_increment); // increment counter 16.61 __ movl(Address(rcx, be_offset), rax); // store counter 16.62 16.63 __ movl(rax, Address(rcx, inv_offset)); // load invocation counter 16.64 + 16.65 __ andl(rax, InvocationCounter::count_mask_value); // and the status bits 16.66 __ addl(rax, Address(rcx, be_offset)); // add both counters 16.67
17.1 --- a/src/share/vm/c1/c1_LIRGenerator.cpp Thu Apr 18 14:38:31 2013 +0200 17.2 +++ b/src/share/vm/c1/c1_LIRGenerator.cpp Thu Apr 18 17:00:16 2013 -0400 17.3 @@ -1,5 +1,5 @@ 17.4 /* 17.5 - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. 17.6 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 17.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 17.8 * 17.9 * This code is free software; you can redistribute it and/or modify it 17.10 @@ -3044,21 +3044,20 @@ 17.11 assert(level > CompLevel_simple, "Shouldn't be here"); 17.12 17.13 int offset = -1; 17.14 - LIR_Opr counter_holder = new_register(T_METADATA); 17.15 - LIR_Opr meth; 17.16 + LIR_Opr counter_holder; 17.17 if (level == CompLevel_limited_profile) { 17.18 - offset = in_bytes(backedge ? Method::backedge_counter_offset() : 17.19 - Method::invocation_counter_offset()); 17.20 - __ metadata2reg(method->constant_encoding(), counter_holder); 17.21 - meth = counter_holder; 17.22 + address counters_adr = method->ensure_method_counters(); 17.23 + counter_holder = new_pointer_register(); 17.24 + __ move(LIR_OprFact::intptrConst(counters_adr), counter_holder); 17.25 + offset = in_bytes(backedge ? MethodCounters::backedge_counter_offset() : 17.26 + MethodCounters::invocation_counter_offset()); 17.27 } else if (level == CompLevel_full_profile) { 17.28 + counter_holder = new_register(T_METADATA); 17.29 offset = in_bytes(backedge ? MethodData::backedge_counter_offset() : 17.30 MethodData::invocation_counter_offset()); 17.31 ciMethodData* md = method->method_data_or_null(); 17.32 assert(md != NULL, "Sanity"); 17.33 __ metadata2reg(md->constant_encoding(), counter_holder); 17.34 - meth = new_register(T_METADATA); 17.35 - __ metadata2reg(method->constant_encoding(), meth); 17.36 } else { 17.37 ShouldNotReachHere(); 17.38 } 17.39 @@ -3069,6 +3068,8 @@ 17.40 __ store(result, counter); 17.41 if (notify) { 17.42 LIR_Opr mask = load_immediate(frequency << InvocationCounter::count_shift, T_INT); 17.43 + LIR_Opr meth = new_register(T_METADATA); 17.44 + __ metadata2reg(method->constant_encoding(), meth); 17.45 __ logical_and(result, mask, result); 17.46 __ cmp(lir_cond_equal, result, LIR_OprFact::intConst(0)); 17.47 // The bci for info can point to cmp for if's we want the if bci
18.1 --- a/src/share/vm/ci/ciMethod.cpp Thu Apr 18 14:38:31 2013 +0200 18.2 +++ b/src/share/vm/ci/ciMethod.cpp Thu Apr 18 17:00:16 2013 -0400 18.3 @@ -1,5 +1,5 @@ 18.4 /* 18.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 18.6 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 18.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.8 * 18.9 * This code is free software; you can redistribute it and/or modify it 18.10 @@ -905,6 +905,20 @@ 18.11 } 18.12 18.13 // ------------------------------------------------------------------ 18.14 +// ciMethod::ensure_method_counters 18.15 +// 18.16 +address ciMethod::ensure_method_counters() { 18.17 + check_is_loaded(); 18.18 + VM_ENTRY_MARK; 18.19 + methodHandle mh(THREAD, get_Method()); 18.20 + MethodCounters *counter = mh->method_counters(); 18.21 + if (counter == NULL) { 18.22 + counter = Method::build_method_counters(mh(), CHECK_AND_CLEAR_NULL); 18.23 + } 18.24 + return (address)counter; 18.25 +} 18.26 + 18.27 +// ------------------------------------------------------------------ 18.28 // ciMethod::should_exclude 18.29 // 18.30 // Should this method be excluded from compilation? 18.31 @@ -1191,13 +1205,14 @@ 18.32 ASSERT_IN_VM; 18.33 ResourceMark rm; 18.34 Method* method = get_Method(); 18.35 + MethodCounters* mcs = method->method_counters(); 18.36 Klass* holder = method->method_holder(); 18.37 st->print_cr("ciMethod %s %s %s %d %d %d %d %d", 18.38 holder->name()->as_quoted_ascii(), 18.39 method->name()->as_quoted_ascii(), 18.40 method->signature()->as_quoted_ascii(), 18.41 - method->invocation_counter()->raw_counter(), 18.42 - method->backedge_counter()->raw_counter(), 18.43 + mcs == NULL ? 0 : mcs->invocation_counter()->raw_counter(), 18.44 + mcs == NULL ? 0 : mcs->backedge_counter()->raw_counter(), 18.45 interpreter_invocation_count(), 18.46 interpreter_throwout_count(), 18.47 _instructions_size);
19.1 --- a/src/share/vm/ci/ciMethod.hpp Thu Apr 18 14:38:31 2013 +0200 19.2 +++ b/src/share/vm/ci/ciMethod.hpp Thu Apr 18 17:00:16 2013 -0400 19.3 @@ -1,5 +1,5 @@ 19.4 /* 19.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 19.6 + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved. 19.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.8 * 19.9 * This code is free software; you can redistribute it and/or modify it 19.10 @@ -262,6 +262,7 @@ 19.11 bool is_klass_loaded(int refinfo_index, bool must_be_resolved) const; 19.12 bool check_call(int refinfo_index, bool is_static) const; 19.13 bool ensure_method_data(); // make sure it exists in the VM also 19.14 + address ensure_method_counters(); 19.15 int instructions_size(); 19.16 int scale_count(int count, float prof_factor = 1.); // make MDO count commensurate with IIC 19.17
20.1 --- a/src/share/vm/ci/ciReplay.cpp Thu Apr 18 14:38:31 2013 +0200 20.2 +++ b/src/share/vm/ci/ciReplay.cpp Thu Apr 18 17:00:16 2013 -0400 20.3 @@ -920,12 +920,17 @@ 20.4 method->print_name(tty); 20.5 tty->cr(); 20.6 } else { 20.7 + EXCEPTION_CONTEXT; 20.8 + MethodCounters* mcs = method->method_counters(); 20.9 // m->_instructions_size = rec->instructions_size; 20.10 m->_instructions_size = -1; 20.11 m->_interpreter_invocation_count = rec->interpreter_invocation_count; 20.12 m->_interpreter_throwout_count = rec->interpreter_throwout_count; 20.13 - method->invocation_counter()->_counter = rec->invocation_counter; 20.14 - method->backedge_counter()->_counter = rec->backedge_counter; 20.15 + if (mcs == NULL) { 20.16 + mcs = Method::build_method_counters(method, CHECK_AND_CLEAR); 20.17 + } 20.18 + mcs->invocation_counter()->_counter = rec->invocation_counter; 20.19 + mcs->backedge_counter()->_counter = rec->backedge_counter; 20.20 } 20.21 } 20.22
21.1 --- a/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 18 14:38:31 2013 +0200 21.2 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Thu Apr 18 17:00:16 2013 -0400 21.3 @@ -1,5 +1,5 @@ 21.4 /* 21.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 21.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 21.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 21.8 * 21.9 * This code is free software; you can redistribute it and/or modify it 21.10 @@ -454,7 +454,7 @@ 21.11 continuation = Interpreter::remove_activation_entry(); 21.12 #endif 21.13 // Count this for compilation purposes 21.14 - h_method->interpreter_throwout_increment(); 21.15 + h_method->interpreter_throwout_increment(THREAD); 21.16 } else { 21.17 // handler in this method => change bci/bcp to handler bci/bcp and continue there 21.18 handler_pc = h_method->code_base() + handler_bci; 21.19 @@ -903,6 +903,15 @@ 21.20 fr.interpreter_frame_set_mdp(new_mdp); 21.21 IRT_END 21.22 21.23 +IRT_ENTRY(MethodCounters*, InterpreterRuntime::build_method_counters(JavaThread* thread, Method* m)) 21.24 + MethodCounters* mcs = Method::build_method_counters(m, thread); 21.25 + if (HAS_PENDING_EXCEPTION) { 21.26 + assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here"); 21.27 + CLEAR_PENDING_EXCEPTION; 21.28 + } 21.29 + return mcs; 21.30 +IRT_END 21.31 + 21.32 21.33 IRT_ENTRY(void, InterpreterRuntime::at_safepoint(JavaThread* thread)) 21.34 // We used to need an explict preserve_arguments here for invoke bytecodes. However,
22.1 --- a/src/share/vm/interpreter/interpreterRuntime.hpp Thu Apr 18 14:38:31 2013 +0200 22.2 +++ b/src/share/vm/interpreter/interpreterRuntime.hpp Thu Apr 18 17:00:16 2013 -0400 22.3 @@ -1,5 +1,5 @@ 22.4 /* 22.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 22.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 22.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.8 * 22.9 * This code is free software; you can redistribute it and/or modify it 22.10 @@ -169,6 +169,7 @@ 22.11 #ifdef ASSERT 22.12 static void verify_mdp(Method* method, address bcp, address mdp); 22.13 #endif // ASSERT 22.14 + static MethodCounters* build_method_counters(JavaThread* thread, Method* m); 22.15 }; 22.16 22.17
23.1 --- a/src/share/vm/interpreter/invocationCounter.cpp Thu Apr 18 14:38:31 2013 +0200 23.2 +++ b/src/share/vm/interpreter/invocationCounter.cpp Thu Apr 18 17:00:16 2013 -0400 23.3 @@ -1,5 +1,5 @@ 23.4 /* 23.5 - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. 23.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 23.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.8 * 23.9 * This code is free software; you can redistribute it and/or modify it 23.10 @@ -104,15 +104,19 @@ 23.11 23.12 static address do_nothing(methodHandle method, TRAPS) { 23.13 // dummy action for inactive invocation counters 23.14 - method->invocation_counter()->set_carry(); 23.15 - method->invocation_counter()->set_state(InvocationCounter::wait_for_nothing); 23.16 + MethodCounters* mcs = method->method_counters(); 23.17 + assert(mcs != NULL, ""); 23.18 + mcs->invocation_counter()->set_carry(); 23.19 + mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing); 23.20 return NULL; 23.21 } 23.22 23.23 23.24 static address do_decay(methodHandle method, TRAPS) { 23.25 // decay invocation counters so compilation gets delayed 23.26 - method->invocation_counter()->decay(); 23.27 + MethodCounters* mcs = method->method_counters(); 23.28 + assert(mcs != NULL, ""); 23.29 + mcs->invocation_counter()->decay(); 23.30 return NULL; 23.31 } 23.32
24.1 --- a/src/share/vm/oops/method.cpp Thu Apr 18 14:38:31 2013 +0200 24.2 +++ b/src/share/vm/oops/method.cpp Thu Apr 18 17:00:16 2013 -0400 24.3 @@ -91,7 +91,7 @@ 24.4 set_hidden(false); 24.5 set_dont_inline(false); 24.6 set_method_data(NULL); 24.7 - set_interpreter_throwout_count(0); 24.8 + set_method_counters(NULL); 24.9 set_vtable_index(Method::garbage_vtable_index); 24.10 24.11 // Fix and bury in Method* 24.12 @@ -105,16 +105,6 @@ 24.13 } 24.14 24.15 NOT_PRODUCT(set_compiled_invocation_count(0);) 24.16 - set_interpreter_invocation_count(0); 24.17 - invocation_counter()->init(); 24.18 - backedge_counter()->init(); 24.19 - clear_number_of_breakpoints(); 24.20 - 24.21 -#ifdef TIERED 24.22 - set_rate(0); 24.23 - set_prev_event_count(0); 24.24 - set_prev_time(0); 24.25 -#endif 24.26 } 24.27 24.28 // Release Method*. The nmethod will be gone when we get here because 24.29 @@ -124,6 +114,8 @@ 24.30 set_constMethod(NULL); 24.31 MetadataFactory::free_metadata(loader_data, method_data()); 24.32 set_method_data(NULL); 24.33 + MetadataFactory::free_metadata(loader_data, method_counters()); 24.34 + set_method_counters(NULL); 24.35 // The nmethod will be gone when we get here. 24.36 if (code() != NULL) _code = NULL; 24.37 } 24.38 @@ -323,7 +315,10 @@ 24.39 // compiler does not bump invocation counter of compiled methods 24.40 return true; 24.41 } 24.42 - else if (_invocation_counter.carry() || (method_data() != NULL && method_data()->invocation_counter()->carry())) { 24.43 + else if ((method_counters() != NULL && 24.44 + method_counters()->invocation_counter()->carry()) || 24.45 + (method_data() != NULL && 24.46 + method_data()->invocation_counter()->carry())) { 24.47 // The carry bit is set when the counter overflows and causes 24.48 // a compilation to occur. We don't know how many times 24.49 // the counter has been reset, so we simply assume it has 24.50 @@ -387,6 +382,18 @@ 24.51 } 24.52 } 24.53 24.54 +MethodCounters* Method::build_method_counters(Method* m, TRAPS) { 24.55 + methodHandle mh(m); 24.56 + ClassLoaderData* loader_data = mh->method_holder()->class_loader_data(); 24.57 + MethodCounters* counters = MethodCounters::allocate(loader_data, CHECK_NULL); 24.58 + if (mh->method_counters() == NULL) { 24.59 + mh->set_method_counters(counters); 24.60 + } else { 24.61 + MetadataFactory::free_metadata(loader_data, counters); 24.62 + } 24.63 + return mh->method_counters(); 24.64 +} 24.65 + 24.66 void Method::cleanup_inline_caches() { 24.67 // The current system doesn't use inline caches in the interpreter 24.68 // => nothing to do (keep this method around for future use) 24.69 @@ -794,8 +801,6 @@ 24.70 set_signature_handler(NULL); 24.71 } 24.72 NOT_PRODUCT(set_compiled_invocation_count(0);) 24.73 - invocation_counter()->reset(); 24.74 - backedge_counter()->reset(); 24.75 _adapter = NULL; 24.76 _from_compiled_entry = NULL; 24.77 24.78 @@ -808,8 +813,7 @@ 24.79 assert(!DumpSharedSpaces || _method_data == NULL, "unexpected method data?"); 24.80 24.81 set_method_data(NULL); 24.82 - set_interpreter_throwout_count(0); 24.83 - set_interpreter_invocation_count(0); 24.84 + set_method_counters(NULL); 24.85 } 24.86 24.87 // Called when the method_holder is getting linked. Setup entrypoints so the method 24.88 @@ -1545,28 +1549,34 @@ 24.89 24.90 24.91 int Method::invocation_count() { 24.92 + MethodCounters *mcs = method_counters(); 24.93 if (TieredCompilation) { 24.94 MethodData* const mdo = method_data(); 24.95 - if (invocation_counter()->carry() || ((mdo != NULL) ? mdo->invocation_counter()->carry() : false)) { 24.96 + if (((mcs != NULL) ? mcs->invocation_counter()->carry() : false) || 24.97 + ((mdo != NULL) ? mdo->invocation_counter()->carry() : false)) { 24.98 return InvocationCounter::count_limit; 24.99 } else { 24.100 - return invocation_counter()->count() + ((mdo != NULL) ? mdo->invocation_counter()->count() : 0); 24.101 + return ((mcs != NULL) ? mcs->invocation_counter()->count() : 0) + 24.102 + ((mdo != NULL) ? mdo->invocation_counter()->count() : 0); 24.103 } 24.104 } else { 24.105 - return invocation_counter()->count(); 24.106 + return (mcs == NULL) ? 0 : mcs->invocation_counter()->count(); 24.107 } 24.108 } 24.109 24.110 int Method::backedge_count() { 24.111 + MethodCounters *mcs = method_counters(); 24.112 if (TieredCompilation) { 24.113 MethodData* const mdo = method_data(); 24.114 - if (backedge_counter()->carry() || ((mdo != NULL) ? mdo->backedge_counter()->carry() : false)) { 24.115 + if (((mcs != NULL) ? mcs->backedge_counter()->carry() : false) || 24.116 + ((mdo != NULL) ? mdo->backedge_counter()->carry() : false)) { 24.117 return InvocationCounter::count_limit; 24.118 } else { 24.119 - return backedge_counter()->count() + ((mdo != NULL) ? mdo->backedge_counter()->count() : 0); 24.120 + return ((mcs != NULL) ? mcs->backedge_counter()->count() : 0) + 24.121 + ((mdo != NULL) ? mdo->backedge_counter()->count() : 0); 24.122 } 24.123 } else { 24.124 - return backedge_counter()->count(); 24.125 + return (mcs == NULL) ? 0 : mcs->backedge_counter()->count(); 24.126 } 24.127 } 24.128 24.129 @@ -1621,12 +1631,12 @@ 24.130 assert(orig_bytecode() == code, "original bytecode must be the same"); 24.131 } 24.132 #endif 24.133 + Thread *thread = Thread::current(); 24.134 *method->bcp_from(_bci) = Bytecodes::_breakpoint; 24.135 - method->incr_number_of_breakpoints(); 24.136 + method->incr_number_of_breakpoints(thread); 24.137 SystemDictionary::notice_modification(); 24.138 { 24.139 // Deoptimize all dependents on this method 24.140 - Thread *thread = Thread::current(); 24.141 HandleMark hm(thread); 24.142 methodHandle mh(thread, method); 24.143 Universe::flush_dependents_on_method(mh); 24.144 @@ -1636,7 +1646,7 @@ 24.145 void BreakpointInfo::clear(Method* method) { 24.146 *method->bcp_from(_bci) = orig_bytecode(); 24.147 assert(method->number_of_breakpoints() > 0, "must not go negative"); 24.148 - method->decr_number_of_breakpoints(); 24.149 + method->decr_number_of_breakpoints(Thread::current()); 24.150 } 24.151 24.152 // jmethodID handling
25.1 --- a/src/share/vm/oops/method.hpp Thu Apr 18 14:38:31 2013 +0200 25.2 +++ b/src/share/vm/oops/method.hpp Thu Apr 18 17:00:16 2013 -0400 25.3 @@ -31,6 +31,7 @@ 25.4 #include "interpreter/invocationCounter.hpp" 25.5 #include "oops/annotations.hpp" 25.6 #include "oops/constantPool.hpp" 25.7 +#include "oops/methodCounters.hpp" 25.8 #include "oops/instanceKlass.hpp" 25.9 #include "oops/oop.hpp" 25.10 #include "oops/typeArrayOop.hpp" 25.11 @@ -100,6 +101,7 @@ 25.12 class LocalVariableTableElement; 25.13 class AdapterHandlerEntry; 25.14 class MethodData; 25.15 +class MethodCounters; 25.16 class ConstMethod; 25.17 class InlineTableSizes; 25.18 class KlassSizeStats; 25.19 @@ -109,7 +111,7 @@ 25.20 private: 25.21 ConstMethod* _constMethod; // Method read-only data. 25.22 MethodData* _method_data; 25.23 - int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered) 25.24 + MethodCounters* _method_counters; 25.25 AccessFlags _access_flags; // Access flags 25.26 int _vtable_index; // vtable index of this method (see VtableIndexFlag) 25.27 // note: can have vtables with >2**16 elements (because of inheritance) 25.28 @@ -124,15 +126,6 @@ 25.29 _hidden : 1, 25.30 _dont_inline : 1, 25.31 : 3; 25.32 - u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting 25.33 - u2 _number_of_breakpoints; // fullspeed debugging support 25.34 - InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations 25.35 - InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations 25.36 - 25.37 -#ifdef TIERED 25.38 - float _rate; // Events (invocation and backedge counter increments) per millisecond 25.39 - jlong _prev_time; // Previous time the rate was acquired 25.40 -#endif 25.41 25.42 #ifndef PRODUCT 25.43 int _compiled_invocation_count; // Number of nmethod invocations so far (for perf. debugging) 25.44 @@ -247,11 +240,31 @@ 25.45 void clear_all_breakpoints(); 25.46 // Tracking number of breakpoints, for fullspeed debugging. 25.47 // Only mutated by VM thread. 25.48 - u2 number_of_breakpoints() const { return _number_of_breakpoints; } 25.49 - void incr_number_of_breakpoints() { ++_number_of_breakpoints; } 25.50 - void decr_number_of_breakpoints() { --_number_of_breakpoints; } 25.51 + u2 number_of_breakpoints() const { 25.52 + if (method_counters() == NULL) { 25.53 + return 0; 25.54 + } else { 25.55 + return method_counters()->number_of_breakpoints(); 25.56 + } 25.57 + } 25.58 + void incr_number_of_breakpoints(TRAPS) { 25.59 + MethodCounters* mcs = get_method_counters(CHECK); 25.60 + if (mcs != NULL) { 25.61 + mcs->incr_number_of_breakpoints(); 25.62 + } 25.63 + } 25.64 + void decr_number_of_breakpoints(TRAPS) { 25.65 + MethodCounters* mcs = get_method_counters(CHECK); 25.66 + if (mcs != NULL) { 25.67 + mcs->decr_number_of_breakpoints(); 25.68 + } 25.69 + } 25.70 // Initialization only 25.71 - void clear_number_of_breakpoints() { _number_of_breakpoints = 0; } 25.72 + void clear_number_of_breakpoints() { 25.73 + if (method_counters() != NULL) { 25.74 + method_counters()->clear_number_of_breakpoints(); 25.75 + } 25.76 + } 25.77 25.78 // index into InstanceKlass methods() array 25.79 // note: also used by jfr 25.80 @@ -288,14 +301,20 @@ 25.81 void set_highest_osr_comp_level(int level); 25.82 25.83 // Count of times method was exited via exception while interpreting 25.84 - void interpreter_throwout_increment() { 25.85 - if (_interpreter_throwout_count < 65534) { 25.86 - _interpreter_throwout_count++; 25.87 + void interpreter_throwout_increment(TRAPS) { 25.88 + MethodCounters* mcs = get_method_counters(CHECK); 25.89 + if (mcs != NULL) { 25.90 + mcs->interpreter_throwout_increment(); 25.91 } 25.92 } 25.93 25.94 - int interpreter_throwout_count() const { return _interpreter_throwout_count; } 25.95 - void set_interpreter_throwout_count(int count) { _interpreter_throwout_count = count; } 25.96 + int interpreter_throwout_count() const { 25.97 + if (method_counters() == NULL) { 25.98 + return 0; 25.99 + } else { 25.100 + return method_counters()->interpreter_throwout_count(); 25.101 + } 25.102 + } 25.103 25.104 // size of parameters 25.105 int size_of_parameters() const { return constMethod()->size_of_parameters(); } 25.106 @@ -339,23 +358,54 @@ 25.107 MethodData* method_data() const { 25.108 return _method_data; 25.109 } 25.110 + 25.111 void set_method_data(MethodData* data) { 25.112 _method_data = data; 25.113 } 25.114 25.115 - // invocation counter 25.116 - InvocationCounter* invocation_counter() { return &_invocation_counter; } 25.117 - InvocationCounter* backedge_counter() { return &_backedge_counter; } 25.118 + MethodCounters* method_counters() const { 25.119 + return _method_counters; 25.120 + } 25.121 + 25.122 + 25.123 + void set_method_counters(MethodCounters* counters) { 25.124 + _method_counters = counters; 25.125 + } 25.126 25.127 #ifdef TIERED 25.128 // We are reusing interpreter_invocation_count as a holder for the previous event count! 25.129 // We can do that since interpreter_invocation_count is not used in tiered. 25.130 - int prev_event_count() const { return _interpreter_invocation_count; } 25.131 - void set_prev_event_count(int count) { _interpreter_invocation_count = count; } 25.132 - jlong prev_time() const { return _prev_time; } 25.133 - void set_prev_time(jlong time) { _prev_time = time; } 25.134 - float rate() const { return _rate; } 25.135 - void set_rate(float rate) { _rate = rate; } 25.136 + int prev_event_count() const { 25.137 + if (method_counters() == NULL) { 25.138 + return 0; 25.139 + } else { 25.140 + return method_counters()->interpreter_invocation_count(); 25.141 + } 25.142 + } 25.143 + void set_prev_event_count(int count, TRAPS) { 25.144 + MethodCounters* mcs = get_method_counters(CHECK); 25.145 + if (mcs != NULL) { 25.146 + mcs->set_interpreter_invocation_count(count); 25.147 + } 25.148 + } 25.149 + jlong prev_time() const { 25.150 + return method_counters() == NULL ? 0 : method_counters()->prev_time(); 25.151 + } 25.152 + void set_prev_time(jlong time, TRAPS) { 25.153 + MethodCounters* mcs = get_method_counters(CHECK); 25.154 + if (mcs != NULL) { 25.155 + mcs->set_prev_time(time); 25.156 + } 25.157 + } 25.158 + float rate() const { 25.159 + return method_counters() == NULL ? 0 : method_counters()->rate(); 25.160 + } 25.161 + void set_rate(float rate, TRAPS) { 25.162 + MethodCounters* mcs = get_method_counters(CHECK); 25.163 + if (mcs != NULL) { 25.164 + mcs->set_rate(rate); 25.165 + } 25.166 + } 25.167 #endif 25.168 25.169 int invocation_count(); 25.170 @@ -366,14 +416,17 @@ 25.171 25.172 static void build_interpreter_method_data(methodHandle method, TRAPS); 25.173 25.174 + static MethodCounters* build_method_counters(Method* m, TRAPS); 25.175 + 25.176 int interpreter_invocation_count() { 25.177 if (TieredCompilation) return invocation_count(); 25.178 - else return _interpreter_invocation_count; 25.179 + else return (method_counters() == NULL) ? 0 : 25.180 + method_counters()->interpreter_invocation_count(); 25.181 } 25.182 - void set_interpreter_invocation_count(int count) { _interpreter_invocation_count = count; } 25.183 - int increment_interpreter_invocation_count() { 25.184 + int increment_interpreter_invocation_count(TRAPS) { 25.185 if (TieredCompilation) ShouldNotReachHere(); 25.186 - return ++_interpreter_invocation_count; 25.187 + MethodCounters* mcs = get_method_counters(CHECK_0); 25.188 + return (mcs == NULL) ? 0 : mcs->increment_interpreter_invocation_count(); 25.189 } 25.190 25.191 #ifndef PRODUCT 25.192 @@ -582,12 +635,12 @@ 25.193 #endif /* CC_INTERP */ 25.194 static ByteSize from_compiled_offset() { return byte_offset_of(Method, _from_compiled_entry); } 25.195 static ByteSize code_offset() { return byte_offset_of(Method, _code); } 25.196 - static ByteSize invocation_counter_offset() { return byte_offset_of(Method, _invocation_counter); } 25.197 - static ByteSize backedge_counter_offset() { return byte_offset_of(Method, _backedge_counter); } 25.198 static ByteSize method_data_offset() { 25.199 return byte_offset_of(Method, _method_data); 25.200 } 25.201 - static ByteSize interpreter_invocation_counter_offset() { return byte_offset_of(Method, _interpreter_invocation_count); } 25.202 + static ByteSize method_counters_offset() { 25.203 + return byte_offset_of(Method, _method_counters); 25.204 + } 25.205 #ifndef PRODUCT 25.206 static ByteSize compiled_invocation_counter_offset() { return byte_offset_of(Method, _compiled_invocation_count); } 25.207 #endif // not PRODUCT 25.208 @@ -598,8 +651,6 @@ 25.209 25.210 // for code generation 25.211 static int method_data_offset_in_bytes() { return offset_of(Method, _method_data); } 25.212 - static int interpreter_invocation_counter_offset_in_bytes() 25.213 - { return offset_of(Method, _interpreter_invocation_count); } 25.214 static int intrinsic_id_offset_in_bytes() { return offset_of(Method, _intrinsic_id); } 25.215 static int intrinsic_id_size_in_bytes() { return sizeof(u1); } 25.216 25.217 @@ -757,6 +808,13 @@ 25.218 private: 25.219 void print_made_not_compilable(int comp_level, bool is_osr, bool report, const char* reason); 25.220 25.221 + MethodCounters* get_method_counters(TRAPS) { 25.222 + if (_method_counters == NULL) { 25.223 + build_method_counters(this, CHECK_AND_CLEAR_NULL); 25.224 + } 25.225 + return _method_counters; 25.226 + } 25.227 + 25.228 public: 25.229 bool is_not_c1_compilable() const { return access_flags().is_not_c1_compilable(); } 25.230 void set_not_c1_compilable() { _access_flags.set_not_c1_compilable(); }
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/src/share/vm/oops/methodCounters.cpp Thu Apr 18 17:00:16 2013 -0400 26.3 @@ -0,0 +1,37 @@ 26.4 +/* 26.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 26.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 26.7 + * 26.8 + * This code is free software; you can redistribute it and/or modify it 26.9 + * under the terms of the GNU General Public License version 2 only, as 26.10 + * published by the Free Software Foundation. 26.11 + * 26.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 26.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 26.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26.15 + * version 2 for more details (a copy is included in the LICENSE file that 26.16 + * accompanied this code). 26.17 + * 26.18 + * You should have received a copy of the GNU General Public License version 26.19 + * 2 along with this work; if not, write to the Free Software Foundation, 26.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 26.21 + * 26.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 26.23 + * or visit www.oracle.com if you need additional information or have any 26.24 + * questions. 26.25 + * 26.26 + */ 26.27 +#include "precompiled.hpp" 26.28 +#include "oops/methodCounters.hpp" 26.29 +#include "runtime/thread.inline.hpp" 26.30 + 26.31 +MethodCounters* MethodCounters::allocate(ClassLoaderData* loader_data, TRAPS) { 26.32 + return new(loader_data, size(), false, THREAD) MethodCounters(); 26.33 +} 26.34 + 26.35 +void MethodCounters::clear_counters() { 26.36 + invocation_counter()->reset(); 26.37 + backedge_counter()->reset(); 26.38 + set_interpreter_throwout_count(0); 26.39 + set_interpreter_invocation_count(0); 26.40 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 27.2 +++ b/src/share/vm/oops/methodCounters.hpp Thu Apr 18 17:00:16 2013 -0400 27.3 @@ -0,0 +1,124 @@ 27.4 +/* 27.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 27.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 27.7 + * 27.8 + * This code is free software; you can redistribute it and/or modify it 27.9 + * under the terms of the GNU General Public License version 2 only, as 27.10 + * published by the Free Software Foundation. 27.11 + * 27.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 27.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 27.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 27.15 + * version 2 for more details (a copy is included in the LICENSE file that 27.16 + * accompanied this code). 27.17 + * 27.18 + * You should have received a copy of the GNU General Public License version 27.19 + * 2 along with this work; if not, write to the Free Software Foundation, 27.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 27.21 + * 27.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 27.23 + * or visit www.oracle.com if you need additional information or have any 27.24 + * questions. 27.25 + * 27.26 + */ 27.27 + 27.28 +#ifndef SHARE_VM_OOPS_METHODCOUNTERS_HPP 27.29 +#define SHARE_VM_OOPS_METHODCOUNTERS_HPP 27.30 + 27.31 +#include "oops/metadata.hpp" 27.32 +#include "interpreter/invocationCounter.hpp" 27.33 + 27.34 +class MethodCounters: public MetaspaceObj { 27.35 + friend class VMStructs; 27.36 + private: 27.37 + int _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered) 27.38 + u2 _interpreter_throwout_count; // Count of times method was exited via exception while interpreting 27.39 + u2 _number_of_breakpoints; // fullspeed debugging support 27.40 + InvocationCounter _invocation_counter; // Incremented before each activation of the method - used to trigger frequency-based optimizations 27.41 + InvocationCounter _backedge_counter; // Incremented before each backedge taken - used to trigger frequencey-based optimizations 27.42 + 27.43 +#ifdef TIERED 27.44 + float _rate; // Events (invocation and backedge counter increments) per millisecond 27.45 + jlong _prev_time; // Previous time the rate was acquired 27.46 +#endif 27.47 + 27.48 + MethodCounters() : _interpreter_invocation_count(0), 27.49 + _interpreter_throwout_count(0), 27.50 + _number_of_breakpoints(0) 27.51 +#ifdef TIERED 27.52 + , _rate(0), 27.53 + _prev_time(0) 27.54 +#endif 27.55 + { 27.56 + invocation_counter()->init(); 27.57 + backedge_counter()->init(); 27.58 + } 27.59 + 27.60 + public: 27.61 + static MethodCounters* allocate(ClassLoaderData* loader_data, TRAPS); 27.62 + 27.63 + void deallocate_contents(ClassLoaderData* loader_data) {} 27.64 + DEBUG_ONLY(bool on_stack() { return false; }) // for template 27.65 + 27.66 + static int size() { return sizeof(MethodCounters) / wordSize; } 27.67 + 27.68 + bool is_klass() const { return false; } 27.69 + 27.70 + void clear_counters(); 27.71 + 27.72 + int interpreter_invocation_count() { 27.73 + return _interpreter_invocation_count; 27.74 + } 27.75 + void set_interpreter_invocation_count(int count) { 27.76 + _interpreter_invocation_count = count; 27.77 + } 27.78 + int increment_interpreter_invocation_count() { 27.79 + return ++_interpreter_invocation_count; 27.80 + } 27.81 + 27.82 + void interpreter_throwout_increment() { 27.83 + if (_interpreter_throwout_count < 65534) { 27.84 + _interpreter_throwout_count++; 27.85 + } 27.86 + } 27.87 + int interpreter_throwout_count() const { 27.88 + return _interpreter_throwout_count; 27.89 + } 27.90 + void set_interpreter_throwout_count(int count) { 27.91 + _interpreter_throwout_count = count; 27.92 + } 27.93 + 27.94 + u2 number_of_breakpoints() const { return _number_of_breakpoints; } 27.95 + void incr_number_of_breakpoints() { ++_number_of_breakpoints; } 27.96 + void decr_number_of_breakpoints() { --_number_of_breakpoints; } 27.97 + void clear_number_of_breakpoints() { _number_of_breakpoints = 0; } 27.98 + 27.99 +#ifdef TIERED 27.100 + jlong prev_time() const { return _prev_time; } 27.101 + void set_prev_time(jlong time) { _prev_time = time; } 27.102 + float rate() const { return _rate; } 27.103 + void set_rate(float rate) { _rate = rate; } 27.104 +#endif 27.105 + 27.106 + // invocation counter 27.107 + InvocationCounter* invocation_counter() { return &_invocation_counter; } 27.108 + InvocationCounter* backedge_counter() { return &_backedge_counter; } 27.109 + 27.110 + static ByteSize interpreter_invocation_counter_offset() { 27.111 + return byte_offset_of(MethodCounters, _interpreter_invocation_count); 27.112 + } 27.113 + 27.114 + static ByteSize invocation_counter_offset() { 27.115 + return byte_offset_of(MethodCounters, _invocation_counter); 27.116 + } 27.117 + 27.118 + static ByteSize backedge_counter_offset() { 27.119 + return byte_offset_of(MethodCounters, _backedge_counter); 27.120 + } 27.121 + 27.122 + static int interpreter_invocation_counter_offset_in_bytes() { 27.123 + return offset_of(MethodCounters, _interpreter_invocation_count); 27.124 + } 27.125 + 27.126 +}; 27.127 +#endif //SHARE_VM_OOPS_METHODCOUNTERS_HPP
28.1 --- a/src/share/vm/oops/methodData.cpp Thu Apr 18 14:38:31 2013 +0200 28.2 +++ b/src/share/vm/oops/methodData.cpp Thu Apr 18 17:00:16 2013 -0400 28.3 @@ -732,14 +732,17 @@ 28.4 } else { 28.5 int iic = method->interpreter_invocation_count(); 28.6 if (mileage < iic) mileage = iic; 28.7 - InvocationCounter* ic = method->invocation_counter(); 28.8 - InvocationCounter* bc = method->backedge_counter(); 28.9 - int icval = ic->count(); 28.10 - if (ic->carry()) icval += CompileThreshold; 28.11 - if (mileage < icval) mileage = icval; 28.12 - int bcval = bc->count(); 28.13 - if (bc->carry()) bcval += CompileThreshold; 28.14 - if (mileage < bcval) mileage = bcval; 28.15 + MethodCounters* mcs = method->method_counters(); 28.16 + if (mcs != NULL) { 28.17 + InvocationCounter* ic = mcs->invocation_counter(); 28.18 + InvocationCounter* bc = mcs->backedge_counter(); 28.19 + int icval = ic->count(); 28.20 + if (ic->carry()) icval += CompileThreshold; 28.21 + if (mileage < icval) mileage = icval; 28.22 + int bcval = bc->count(); 28.23 + if (bc->carry()) bcval += CompileThreshold; 28.24 + if (mileage < bcval) mileage = bcval; 28.25 + } 28.26 } 28.27 return mileage; 28.28 }
29.1 --- a/src/share/vm/opto/parseHelper.cpp Thu Apr 18 14:38:31 2013 +0200 29.2 +++ b/src/share/vm/opto/parseHelper.cpp Thu Apr 18 17:00:16 2013 -0400 29.3 @@ -1,5 +1,5 @@ 29.4 /* 29.5 - * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved. 29.6 + * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved. 29.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 29.8 * 29.9 * This code is free software; you can redistribute it and/or modify it 29.10 @@ -337,19 +337,21 @@ 29.11 if (!count_invocations()) return; 29.12 29.13 // Get the Method* node. 29.14 - const TypePtr* adr_type = TypeMetadataPtr::make(method()); 29.15 - Node *method_node = makecon(adr_type); 29.16 + ciMethod* m = method(); 29.17 + address counters_adr = m->ensure_method_counters(); 29.18 29.19 - // Load the interpreter_invocation_counter from the Method*. 29.20 - int offset = Method::interpreter_invocation_counter_offset_in_bytes(); 29.21 - Node* adr_node = basic_plus_adr(method_node, method_node, offset); 29.22 - Node* cnt = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type); 29.23 + Node* ctrl = control(); 29.24 + const TypePtr* adr_type = TypeRawPtr::make(counters_adr); 29.25 + Node *counters_node = makecon(adr_type); 29.26 + Node* adr_iic_node = basic_plus_adr(counters_node, counters_node, 29.27 + MethodCounters::interpreter_invocation_counter_offset_in_bytes()); 29.28 + Node* cnt = make_load(ctrl, adr_iic_node, TypeInt::INT, T_INT, adr_type); 29.29 29.30 test_counter_against_threshold(cnt, limit); 29.31 29.32 // Add one to the counter and store 29.33 Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1))); 29.34 - store_to_memory( NULL, adr_node, incr, T_INT, adr_type ); 29.35 + store_to_memory( ctrl, adr_iic_node, incr, T_INT, adr_type ); 29.36 } 29.37 29.38 //----------------------------method_data_addressing---------------------------
30.1 --- a/src/share/vm/prims/whitebox.cpp Thu Apr 18 14:38:31 2013 +0200 30.2 +++ b/src/share/vm/prims/whitebox.cpp Thu Apr 18 17:00:16 2013 -0400 30.3 @@ -278,6 +278,7 @@ 30.4 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 30.5 MutexLockerEx mu(Compile_lock); 30.6 MethodData* mdo = mh->method_data(); 30.7 + MethodCounters* mcs = mh->method_counters(); 30.8 30.9 if (mdo != NULL) { 30.10 mdo->init(); 30.11 @@ -288,20 +289,22 @@ 30.12 } 30.13 } 30.14 30.15 - mh->backedge_counter()->init(); 30.16 - mh->invocation_counter()->init(); 30.17 - mh->set_interpreter_invocation_count(0); 30.18 - mh->set_interpreter_throwout_count(0); 30.19 mh->clear_not_c1_compilable(); 30.20 mh->clear_not_c2_compilable(); 30.21 mh->clear_not_c2_osr_compilable(); 30.22 NOT_PRODUCT(mh->set_compiled_invocation_count(0)); 30.23 + if (mcs != NULL) { 30.24 + mcs->backedge_counter()->init(); 30.25 + mcs->invocation_counter()->init(); 30.26 + mcs->set_interpreter_invocation_count(0); 30.27 + mcs->set_interpreter_throwout_count(0); 30.28 30.29 #ifdef TIERED 30.30 - mh->set_rate(0.0F); 30.31 - mh->set_prev_event_count(0); 30.32 - mh->set_prev_time(0); 30.33 + mcs->set_rate(0.0F); 30.34 + mh->set_prev_event_count(0, THREAD); 30.35 + mh->set_prev_time(0, THREAD); 30.36 #endif 30.37 + } 30.38 WB_END 30.39 30.40 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
31.1 --- a/src/share/vm/runtime/advancedThresholdPolicy.cpp Thu Apr 18 14:38:31 2013 +0200 31.2 +++ b/src/share/vm/runtime/advancedThresholdPolicy.cpp Thu Apr 18 17:00:16 2013 -0400 31.3 @@ -1,5 +1,5 @@ 31.4 /* 31.5 - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. 31.6 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 31.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.8 * 31.9 * This code is free software; you can redistribute it and/or modify it 31.10 @@ -74,10 +74,11 @@ 31.11 31.12 // update_rate() is called from select_task() while holding a compile queue lock. 31.13 void AdvancedThresholdPolicy::update_rate(jlong t, Method* m) { 31.14 + JavaThread* THREAD = JavaThread::current(); 31.15 if (is_old(m)) { 31.16 // We don't remove old methods from the queue, 31.17 // so we can just zero the rate. 31.18 - m->set_rate(0); 31.19 + m->set_rate(0, THREAD); 31.20 return; 31.21 } 31.22 31.23 @@ -93,13 +94,13 @@ 31.24 if (delta_s >= TieredRateUpdateMinTime) { 31.25 // And we must've taken the previous point at least 1ms before. 31.26 if (delta_t >= TieredRateUpdateMinTime && delta_e > 0) { 31.27 - m->set_prev_time(t); 31.28 - m->set_prev_event_count(event_count); 31.29 - m->set_rate((float)delta_e / (float)delta_t); // Rate is events per millisecond 31.30 + m->set_prev_time(t, THREAD); 31.31 + m->set_prev_event_count(event_count, THREAD); 31.32 + m->set_rate((float)delta_e / (float)delta_t, THREAD); // Rate is events per millisecond 31.33 } else 31.34 if (delta_t > TieredRateUpdateMaxTime && delta_e == 0) { 31.35 // If nothing happened for 25ms, zero the rate. Don't modify prev values. 31.36 - m->set_rate(0); 31.37 + m->set_rate(0, THREAD); 31.38 } 31.39 } 31.40 }
32.1 --- a/src/share/vm/runtime/compilationPolicy.cpp Thu Apr 18 14:38:31 2013 +0200 32.2 +++ b/src/share/vm/runtime/compilationPolicy.cpp Thu Apr 18 17:00:16 2013 -0400 32.3 @@ -1,5 +1,5 @@ 32.4 /* 32.5 - * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved. 32.6 + * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. 32.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 32.8 * 32.9 * This code is free software; you can redistribute it and/or modify it 32.10 @@ -198,8 +198,10 @@ 32.11 32.12 // BUT also make sure the method doesn't look like it was never executed. 32.13 // Set carry bit and reduce counter's value to min(count, CompileThreshold/2). 32.14 - m->invocation_counter()->set_carry(); 32.15 - m->backedge_counter()->set_carry(); 32.16 + MethodCounters* mcs = m->method_counters(); 32.17 + assert(mcs != NULL, "MethodCounters cannot be NULL for profiling"); 32.18 + mcs->invocation_counter()->set_carry(); 32.19 + mcs->backedge_counter()->set_carry(); 32.20 32.21 assert(!m->was_never_executed(), "don't reset to 0 -- could be mistaken for never-executed"); 32.22 } 32.23 @@ -207,8 +209,10 @@ 32.24 void NonTieredCompPolicy::reset_counter_for_back_branch_event(methodHandle m) { 32.25 // Delay next back-branch event but pump up invocation counter to triger 32.26 // whole method compilation. 32.27 - InvocationCounter* i = m->invocation_counter(); 32.28 - InvocationCounter* b = m->backedge_counter(); 32.29 + MethodCounters* mcs = m->method_counters(); 32.30 + assert(mcs != NULL, "MethodCounters cannot be NULL for profiling"); 32.31 + InvocationCounter* i = mcs->invocation_counter(); 32.32 + InvocationCounter* b = mcs->backedge_counter(); 32.33 32.34 // Don't set invocation_counter's value too low otherwise the method will 32.35 // look like immature (ic < ~5300) which prevents the inlining based on 32.36 @@ -227,7 +231,10 @@ 32.37 class CounterDecay : public AllStatic { 32.38 static jlong _last_timestamp; 32.39 static void do_method(Method* m) { 32.40 - m->invocation_counter()->decay(); 32.41 + MethodCounters* mcs = m->method_counters(); 32.42 + if (mcs != NULL) { 32.43 + mcs->invocation_counter()->decay(); 32.44 + } 32.45 } 32.46 public: 32.47 static void decay(); 32.48 @@ -265,30 +272,44 @@ 32.49 32.50 void NonTieredCompPolicy::reprofile(ScopeDesc* trap_scope, bool is_osr) { 32.51 ScopeDesc* sd = trap_scope; 32.52 + MethodCounters* mcs; 32.53 + InvocationCounter* c; 32.54 for (; !sd->is_top(); sd = sd->sender()) { 32.55 - // Reset ICs of inlined methods, since they can trigger compilations also. 32.56 - sd->method()->invocation_counter()->reset(); 32.57 + mcs = sd->method()->method_counters(); 32.58 + if (mcs != NULL) { 32.59 + // Reset ICs of inlined methods, since they can trigger compilations also. 32.60 + mcs->invocation_counter()->reset(); 32.61 + } 32.62 } 32.63 - InvocationCounter* c = sd->method()->invocation_counter(); 32.64 - if (is_osr) { 32.65 - // It was an OSR method, so bump the count higher. 32.66 - c->set(c->state(), CompileThreshold); 32.67 - } else { 32.68 - c->reset(); 32.69 + mcs = sd->method()->method_counters(); 32.70 + if (mcs != NULL) { 32.71 + c = mcs->invocation_counter(); 32.72 + if (is_osr) { 32.73 + // It was an OSR method, so bump the count higher. 32.74 + c->set(c->state(), CompileThreshold); 32.75 + } else { 32.76 + c->reset(); 32.77 + } 32.78 + mcs->backedge_counter()->reset(); 32.79 } 32.80 - sd->method()->backedge_counter()->reset(); 32.81 } 32.82 32.83 // This method can be called by any component of the runtime to notify the policy 32.84 // that it's recommended to delay the complation of this method. 32.85 void NonTieredCompPolicy::delay_compilation(Method* method) { 32.86 - method->invocation_counter()->decay(); 32.87 - method->backedge_counter()->decay(); 32.88 + MethodCounters* mcs = method->method_counters(); 32.89 + if (mcs != NULL) { 32.90 + mcs->invocation_counter()->decay(); 32.91 + mcs->backedge_counter()->decay(); 32.92 + } 32.93 } 32.94 32.95 void NonTieredCompPolicy::disable_compilation(Method* method) { 32.96 - method->invocation_counter()->set_state(InvocationCounter::wait_for_nothing); 32.97 - method->backedge_counter()->set_state(InvocationCounter::wait_for_nothing); 32.98 + MethodCounters* mcs = method->method_counters(); 32.99 + if (mcs != NULL) { 32.100 + mcs->invocation_counter()->set_state(InvocationCounter::wait_for_nothing); 32.101 + mcs->backedge_counter()->set_state(InvocationCounter::wait_for_nothing); 32.102 + } 32.103 } 32.104 32.105 CompileTask* NonTieredCompPolicy::select_task(CompileQueue* compile_queue) { 32.106 @@ -371,8 +392,10 @@ 32.107 #ifndef PRODUCT 32.108 void NonTieredCompPolicy::trace_frequency_counter_overflow(methodHandle m, int branch_bci, int bci) { 32.109 if (TraceInvocationCounterOverflow) { 32.110 - InvocationCounter* ic = m->invocation_counter(); 32.111 - InvocationCounter* bc = m->backedge_counter(); 32.112 + MethodCounters* mcs = m->method_counters(); 32.113 + assert(mcs != NULL, "MethodCounters cannot be NULL for profiling"); 32.114 + InvocationCounter* ic = mcs->invocation_counter(); 32.115 + InvocationCounter* bc = mcs->backedge_counter(); 32.116 ResourceMark rm; 32.117 const char* msg = 32.118 bci == InvocationEntryBci
33.1 --- a/src/share/vm/runtime/fprofiler.cpp Thu Apr 18 14:38:31 2013 +0200 33.2 +++ b/src/share/vm/runtime/fprofiler.cpp Thu Apr 18 17:00:16 2013 -0400 33.3 @@ -1,5 +1,5 @@ 33.4 /* 33.5 - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. 33.6 + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 33.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 33.8 * 33.9 * This code is free software; you can redistribute it and/or modify it 33.10 @@ -421,7 +421,8 @@ 33.11 33.12 void print_method_on(outputStream* st) { 33.13 ProfilerNode::print_method_on(st); 33.14 - if (Verbose) method()->invocation_counter()->print_short(); 33.15 + MethodCounters* mcs = method()->method_counters(); 33.16 + if (Verbose && mcs != NULL) mcs->invocation_counter()->print_short(); 33.17 } 33.18 }; 33.19
34.1 --- a/src/share/vm/runtime/simpleThresholdPolicy.cpp Thu Apr 18 14:38:31 2013 +0200 34.2 +++ b/src/share/vm/runtime/simpleThresholdPolicy.cpp Thu Apr 18 17:00:16 2013 -0400 34.3 @@ -1,5 +1,5 @@ 34.4 /* 34.5 - * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved. 34.6 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 34.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 34.8 * 34.9 * This code is free software; you can redistribute it and/or modify it 34.10 @@ -153,8 +153,10 @@ 34.11 34.12 // Set carry flags on the counters if necessary 34.13 void SimpleThresholdPolicy::handle_counter_overflow(Method* method) { 34.14 - set_carry_if_necessary(method->invocation_counter()); 34.15 - set_carry_if_necessary(method->backedge_counter()); 34.16 + MethodCounters *mcs = method->method_counters(); 34.17 + assert(mcs != NULL, ""); 34.18 + set_carry_if_necessary(mcs->invocation_counter()); 34.19 + set_carry_if_necessary(mcs->backedge_counter()); 34.20 MethodData* mdo = method->method_data(); 34.21 if (mdo != NULL) { 34.22 set_carry_if_necessary(mdo->invocation_counter());
35.1 --- a/src/share/vm/runtime/vmStructs.cpp Thu Apr 18 14:38:31 2013 +0200 35.2 +++ b/src/share/vm/runtime/vmStructs.cpp Thu Apr 18 17:00:16 2013 -0400 35.3 @@ -77,6 +77,7 @@ 35.4 #include "oops/klass.hpp" 35.5 #include "oops/markOop.hpp" 35.6 #include "oops/methodData.hpp" 35.7 +#include "oops/methodCounters.hpp" 35.8 #include "oops/method.hpp" 35.9 #include "oops/objArrayKlass.hpp" 35.10 #include "oops/objArrayOop.hpp" 35.11 @@ -348,16 +349,17 @@ 35.12 nonstatic_field(MethodData, _arg_local, intx) \ 35.13 nonstatic_field(MethodData, _arg_stack, intx) \ 35.14 nonstatic_field(MethodData, _arg_returned, intx) \ 35.15 - nonstatic_field(Method, _constMethod, ConstMethod*) \ 35.16 - nonstatic_field(Method, _method_data, MethodData*) \ 35.17 - nonstatic_field(Method, _interpreter_invocation_count, int) \ 35.18 + nonstatic_field(MethodCounters, _interpreter_invocation_count, int) \ 35.19 + nonstatic_field(MethodCounters, _interpreter_throwout_count, u2) \ 35.20 + nonstatic_field(MethodCounters, _number_of_breakpoints, u2) \ 35.21 + nonstatic_field(MethodCounters, _invocation_counter, InvocationCounter) \ 35.22 + nonstatic_field(MethodCounters, _backedge_counter, InvocationCounter) \ 35.23 + nonstatic_field(Method, _constMethod, ConstMethod*) \ 35.24 + nonstatic_field(Method, _method_data, MethodData*) \ 35.25 + nonstatic_field(Method, _method_counters, MethodCounters*) \ 35.26 nonstatic_field(Method, _access_flags, AccessFlags) \ 35.27 nonstatic_field(Method, _vtable_index, int) \ 35.28 nonstatic_field(Method, _method_size, u2) \ 35.29 - nonstatic_field(Method, _interpreter_throwout_count, u2) \ 35.30 - nonstatic_field(Method, _number_of_breakpoints, u2) \ 35.31 - nonstatic_field(Method, _invocation_counter, InvocationCounter) \ 35.32 - nonstatic_field(Method, _backedge_counter, InvocationCounter) \ 35.33 nonproduct_nonstatic_field(Method, _compiled_invocation_count, int) \ 35.34 volatile_nonstatic_field(Method, _code, nmethod*) \ 35.35 nonstatic_field(Method, _i2i_entry, address) \ 35.36 @@ -1382,6 +1384,7 @@ 35.37 declare_type(ConstantPoolCache, MetaspaceObj) \ 35.38 declare_type(MethodData, Metadata) \ 35.39 declare_type(Method, Metadata) \ 35.40 + declare_type(MethodCounters, MetaspaceObj) \ 35.41 declare_type(ConstMethod, MetaspaceObj) \ 35.42 \ 35.43 declare_toplevel_type(Symbol) \