annotate ppc_patches/0201_C_interpreter-implement_bytecode_profiling.patch @ 4798:df79d76c17ab

Patch queue containing the ppc port. Applying this to the staging repository at tag hs25-b34 leads to the code contained in this repository. We will update the patches so that with the staging repo and the patches always a working hotspot for ppc can be built.
author Goetz
date Wed, 12 Jun 2013 15:55:20 +0200
parents
children edf2bb42e70f
rev   line source
Goetz@4798 1 # HG changeset patch
Goetz@4798 2 # Parent 84fd980e69ee155f80ae36002f29703ea7d16205
Goetz@4798 3 C-interpreter: implement bytecode profiling.
Goetz@4798 4
Goetz@4798 5 diff -r 84fd980e69ee src/share/vm/interpreter/bytecodeInterpreter.cpp
Goetz@4798 6 --- a/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Jun 07 12:50:21 2013 +0200
Goetz@4798 7 +++ b/src/share/vm/interpreter/bytecodeInterpreter.cpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 8 @@ -28,6 +28,7 @@
Goetz@4798 9 #include "interpreter/bytecodeHistogram.hpp"
Goetz@4798 10 #include "interpreter/bytecodeInterpreter.hpp"
Goetz@4798 11 #include "interpreter/bytecodeInterpreter.inline.hpp"
Goetz@4798 12 +#include "interpreter/bytecodeInterpreterProfiling.hpp"
Goetz@4798 13 #include "interpreter/interpreter.hpp"
Goetz@4798 14 #include "interpreter/interpreterRuntime.hpp"
Goetz@4798 15 #include "memory/cardTableModRefBS.hpp"
Goetz@4798 16 @@ -143,10 +144,11 @@
Goetz@4798 17 * is no entry point to do the transition to vm so we just
Goetz@4798 18 * do it by hand here.
Goetz@4798 19 */
Goetz@4798 20 -#define VM_JAVA_ERROR_NO_JUMP(name, msg) \
Goetz@4798 21 +#define VM_JAVA_ERROR_NO_JUMP(name, msg, note_a_trap) \
Goetz@4798 22 DECACHE_STATE(); \
Goetz@4798 23 SET_LAST_JAVA_FRAME(); \
Goetz@4798 24 { \
Goetz@4798 25 + InterpreterRuntime::note_a_trap(THREAD, istate->method(), BCI()); \
Goetz@4798 26 ThreadInVMfromJava trans(THREAD); \
Goetz@4798 27 Exceptions::_throw_msg(THREAD, __FILE__, __LINE__, name, msg); \
Goetz@4798 28 } \
Goetz@4798 29 @@ -154,8 +156,8 @@
Goetz@4798 30 CACHE_STATE();
Goetz@4798 31
Goetz@4798 32 // Normal throw of a java error
Goetz@4798 33 -#define VM_JAVA_ERROR(name, msg) \
Goetz@4798 34 - VM_JAVA_ERROR_NO_JUMP(name, msg) \
Goetz@4798 35 +#define VM_JAVA_ERROR(name, msg, note_a_trap) \
Goetz@4798 36 + VM_JAVA_ERROR_NO_JUMP(name, msg, note_a_trap) \
Goetz@4798 37 goto handle_exception;
Goetz@4798 38
Goetz@4798 39 #ifdef PRODUCT
Goetz@4798 40 @@ -346,7 +348,22 @@
Goetz@4798 41 if (UseLoopCounter) { \
Goetz@4798 42 bool do_OSR = UseOnStackReplacement; \
Goetz@4798 43 INCR_BACKEDGE_COUNT(mcs); \
Goetz@4798 44 - if (do_OSR) do_OSR = BACKEDGE_COUNT(mcs)->reached_InvocationLimit(); \
Goetz@4798 45 + if (ProfileInterpreter) { \
Goetz@4798 46 + BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception); \
Goetz@4798 47 + /* Check for overflow against MDO count. */ \
Goetz@4798 48 + do_OSR = do_OSR \
Goetz@4798 49 + && (mdo_last_branch_taken_count >= (uint)InvocationCounter::InterpreterBackwardBranchLimit)\
Goetz@4798 50 + /* When ProfileInterpreter is on, the backedge_count comes */ \
Goetz@4798 51 + /* from the methodDataOop, which value does not get reset on */ \
Goetz@4798 52 + /* the call to frequency_counter_overflow(). To avoid */ \
Goetz@4798 53 + /* excessive calls to the overflow routine while the method is */ \
Goetz@4798 54 + /* being compiled, add a second test to make sure the overflow */ \
Goetz@4798 55 + /* function is called only once every overflow_frequency. */ \
Goetz@4798 56 + && (!(mdo_last_branch_taken_count & 1023)); \
Goetz@4798 57 + } else { \
Goetz@4798 58 + /* check for overflow of backedge counter */ \
Goetz@4798 59 + do_OSR = do_OSR && INVOCATION_COUNT(mcs)->reached_InvocationLimit(BACKEDGE_COUNT(mcs)); \
Goetz@4798 60 + } \
Goetz@4798 61 if (do_OSR) { \
Goetz@4798 62 nmethod* osr_nmethod; \
Goetz@4798 63 OSR_REQUEST(osr_nmethod, branch_pc); \
Goetz@4798 64 @@ -359,7 +376,6 @@
Goetz@4798 65 } \
Goetz@4798 66 } \
Goetz@4798 67 } /* UseCompiler ... */ \
Goetz@4798 68 - mcs->invocation_counter()->increment(); \
Goetz@4798 69 SAFEPOINT; \
Goetz@4798 70 }
Goetz@4798 71
Goetz@4798 72 @@ -392,16 +408,20 @@
Goetz@4798 73 #undef CACHE_FRAME
Goetz@4798 74 #define CACHE_FRAME()
Goetz@4798 75
Goetz@4798 76 +// BCI() returns the current bytecode-index.
Goetz@4798 77 +#undef BCI
Goetz@4798 78 +#define BCI() ((int)(intptr_t)(pc - (intptr_t)istate->method()->code_base()))
Goetz@4798 79 +
Goetz@4798 80 /*
Goetz@4798 81 * CHECK_NULL - Macro for throwing a NullPointerException if the object
Goetz@4798 82 * passed is a null ref.
Goetz@4798 83 * On some architectures/platforms it should be possible to do this implicitly
Goetz@4798 84 */
Goetz@4798 85 #undef CHECK_NULL
Goetz@4798 86 -#define CHECK_NULL(obj_) \
Goetz@4798 87 - if ((obj_) == NULL) { \
Goetz@4798 88 - VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), ""); \
Goetz@4798 89 - } \
Goetz@4798 90 +#define CHECK_NULL(obj_) \
Goetz@4798 91 + if ((obj_) == NULL) { \
Goetz@4798 92 + VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), "", note_nullCheck_trap); \
Goetz@4798 93 + } \
Goetz@4798 94 VERIFY_OOP(obj_)
Goetz@4798 95
Goetz@4798 96 #define VMdoubleConstZero() 0.0
Goetz@4798 97 @@ -636,6 +656,13 @@
Goetz@4798 98 topOfStack < istate->stack_base(),
Goetz@4798 99 "Stack top out of range");
Goetz@4798 100
Goetz@4798 101 +#ifdef CC_INTERP_PROFILE
Goetz@4798 102 + // MethodData's last branch taken count.
Goetz@4798 103 + uint mdo_last_branch_taken_count = 0;
Goetz@4798 104 +#else
Goetz@4798 105 + const uint mdo_last_branch_taken_count = 0;
Goetz@4798 106 +#endif
Goetz@4798 107 +
Goetz@4798 108 switch (istate->msg()) {
Goetz@4798 109 case initialize: {
Goetz@4798 110 if (initialized++) ShouldNotReachHere(); // Only one initialize call
Goetz@4798 111 @@ -657,15 +684,12 @@
Goetz@4798 112 METHOD->increment_interpreter_invocation_count(THREAD);
Goetz@4798 113 }
Goetz@4798 114 INCR_INVOCATION_COUNT(mcs);
Goetz@4798 115 - if (INVOCATION_COUNT(mcs)->reached_InvocationLimit()) {
Goetz@4798 116 - CALL_VM((void)InterpreterRuntime::frequency_counter_overflow(THREAD, NULL), handle_exception);
Goetz@4798 117 -
Goetz@4798 118 - // We no longer retry on a counter overflow
Goetz@4798 119 -
Goetz@4798 120 - // istate->set_msg(retry_method);
Goetz@4798 121 - // THREAD->clr_do_not_unlock();
Goetz@4798 122 - // return;
Goetz@4798 123 + if (INVOCATION_COUNT(mcs)->reached_InvocationLimit(BACKEDGE_COUNT(mcs))) {
Goetz@4798 124 + CALL_VM((void)InterpreterRuntime::frequency_counter_overflow(THREAD, NULL), handle_exception);
Goetz@4798 125 + // We no longer retry on a counter overflow
Goetz@4798 126 }
Goetz@4798 127 + // Get or create profile data. Check for pending (async) exceptions.
Goetz@4798 128 + BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception);
Goetz@4798 129 SAFEPOINT;
Goetz@4798 130 }
Goetz@4798 131
Goetz@4798 132 @@ -806,9 +830,18 @@
Goetz@4798 133 case popping_frame: {
Goetz@4798 134 // returned from a java call to pop the frame, restart the call
Goetz@4798 135 // clear the message so we don't confuse ourselves later
Goetz@4798 136 - ShouldNotReachHere(); // we don't return this.
Goetz@4798 137 + // Commented out ShouldNotReachHere() below, because we do reach
Goetz@4798 138 + // here when the frame manager calls the interpreter loop after
Goetz@4798 139 + // popping the top frame.
Goetz@4798 140 + // ShouldNotReachHere(); // we don't return this.
Goetz@4798 141 assert(THREAD->pop_frame_in_process(), "wrong frame pop state");
Goetz@4798 142 istate->set_msg(no_request);
Goetz@4798 143 + if (_compiling) {
Goetz@4798 144 + // Set MDX back to the ProfileData of the invoke bytecode that will be
Goetz@4798 145 + // restarted.
Goetz@4798 146 + SET_MDX(NULL);
Goetz@4798 147 + BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception);
Goetz@4798 148 + }
Goetz@4798 149 THREAD->clr_pop_frame_in_process();
Goetz@4798 150 goto run;
Goetz@4798 151 }
Goetz@4798 152 @@ -842,6 +875,11 @@
Goetz@4798 153 if (THREAD->has_pending_exception()) goto handle_exception;
Goetz@4798 154 // Update the pc by the saved amount of the invoke bytecode size
Goetz@4798 155 UPDATE_PC(istate->bcp_advance());
Goetz@4798 156 +
Goetz@4798 157 + if (_compiling) {
Goetz@4798 158 + // Get or create profile data. Check for pending (async) exceptions.
Goetz@4798 159 + BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception);
Goetz@4798 160 + }
Goetz@4798 161 goto run;
Goetz@4798 162 }
Goetz@4798 163
Goetz@4798 164 @@ -849,6 +887,11 @@
Goetz@4798 165 // Returned from an opcode that will reexecute. Deopt was
Goetz@4798 166 // a result of a PopFrame request.
Goetz@4798 167 //
Goetz@4798 168 +
Goetz@4798 169 + if (_compiling) {
Goetz@4798 170 + // Get or create profile data. Check for pending (async) exceptions.
Goetz@4798 171 + BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception);
Goetz@4798 172 + }
Goetz@4798 173 goto run;
Goetz@4798 174 }
Goetz@4798 175
Goetz@4798 176 @@ -871,6 +914,11 @@
Goetz@4798 177 }
Goetz@4798 178 UPDATE_PC(Bytecodes::length_at(METHOD, pc));
Goetz@4798 179 if (THREAD->has_pending_exception()) goto handle_exception;
Goetz@4798 180 +
Goetz@4798 181 + if (_compiling) {
Goetz@4798 182 + // Get or create profile data. Check for pending (async) exceptions.
Goetz@4798 183 + BI_PROFILE_GET_OR_CREATE_METHOD_DATA(handle_exception);
Goetz@4798 184 + }
Goetz@4798 185 goto run;
Goetz@4798 186 }
Goetz@4798 187 case got_monitors: {
Goetz@4798 188 @@ -1124,6 +1172,11 @@
Goetz@4798 189 uint16_t reg = Bytes::get_Java_u2(pc + 2);
Goetz@4798 190
Goetz@4798 191 opcode = pc[1];
Goetz@4798 192 +
Goetz@4798 193 + // Wide and it's sub-bytecode are counted as separate instructions. If we
Goetz@4798 194 + // don't account for this here, the bytecode trace skips the next bytecode.
Goetz@4798 195 + DO_UPDATE_INSTRUCTION_COUNT(opcode);
Goetz@4798 196 +
Goetz@4798 197 switch(opcode) {
Goetz@4798 198 case Bytecodes::_aload:
Goetz@4798 199 VERIFY_OOP(LOCALS_OBJECT(reg));
Goetz@4798 200 @@ -1167,10 +1220,13 @@
Goetz@4798 201 UPDATE_PC_AND_CONTINUE(6);
Goetz@4798 202 }
Goetz@4798 203 case Bytecodes::_ret:
Goetz@4798 204 + // Profile ret.
Goetz@4798 205 + BI_PROFILE_UPDATE_RET(/*bci=*/((int)(intptr_t)(LOCALS_ADDR(reg))));
Goetz@4798 206 + // Now, update the pc.
Goetz@4798 207 pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(reg));
Goetz@4798 208 UPDATE_PC_AND_CONTINUE(0);
Goetz@4798 209 default:
Goetz@4798 210 - VM_JAVA_ERROR(vmSymbols::java_lang_InternalError(), "undefined opcode");
Goetz@4798 211 + VM_JAVA_ERROR(vmSymbols::java_lang_InternalError(), "undefined opcode", note_no_trap);
Goetz@4798 212 }
Goetz@4798 213 }
Goetz@4798 214
Goetz@4798 215 @@ -1251,7 +1307,7 @@
Goetz@4798 216 CASE(_i##opcname): \
Goetz@4798 217 if (test && (STACK_INT(-1) == 0)) { \
Goetz@4798 218 VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \
Goetz@4798 219 - "/ by zero"); \
Goetz@4798 220 + "/ by zero", note_div0Check_trap); \
Goetz@4798 221 } \
Goetz@4798 222 SET_STACK_INT(VMint##opname(STACK_INT(-2), \
Goetz@4798 223 STACK_INT(-1)), \
Goetz@4798 224 @@ -1263,7 +1319,7 @@
Goetz@4798 225 jlong l1 = STACK_LONG(-1); \
Goetz@4798 226 if (VMlongEqz(l1)) { \
Goetz@4798 227 VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \
Goetz@4798 228 - "/ by long zero"); \
Goetz@4798 229 + "/ by long zero", note_div0Check_trap); \
Goetz@4798 230 } \
Goetz@4798 231 } \
Goetz@4798 232 /* First long at (-1,-2) next long at (-3,-4) */ \
Goetz@4798 233 @@ -1476,17 +1532,23 @@
Goetz@4798 234
Goetz@4798 235 #define COMPARISON_OP(name, comparison) \
Goetz@4798 236 CASE(_if_icmp##name): { \
Goetz@4798 237 - int skip = (STACK_INT(-2) comparison STACK_INT(-1)) \
Goetz@4798 238 + const bool cmp = (STACK_INT(-2) comparison STACK_INT(-1)); \
Goetz@4798 239 + int skip = cmp \
Goetz@4798 240 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \
Goetz@4798 241 address branch_pc = pc; \
Goetz@4798 242 + /* Profile branch. */ \
Goetz@4798 243 + BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \
Goetz@4798 244 UPDATE_PC_AND_TOS(skip, -2); \
Goetz@4798 245 DO_BACKEDGE_CHECKS(skip, branch_pc); \
Goetz@4798 246 CONTINUE; \
Goetz@4798 247 } \
Goetz@4798 248 CASE(_if##name): { \
Goetz@4798 249 - int skip = (STACK_INT(-1) comparison 0) \
Goetz@4798 250 + const bool cmp = (STACK_INT(-1) comparison 0); \
Goetz@4798 251 + int skip = cmp \
Goetz@4798 252 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \
Goetz@4798 253 address branch_pc = pc; \
Goetz@4798 254 + /* Profile branch. */ \
Goetz@4798 255 + BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \
Goetz@4798 256 UPDATE_PC_AND_TOS(skip, -1); \
Goetz@4798 257 DO_BACKEDGE_CHECKS(skip, branch_pc); \
Goetz@4798 258 CONTINUE; \
Goetz@4798 259 @@ -1495,9 +1557,12 @@
Goetz@4798 260 #define COMPARISON_OP2(name, comparison) \
Goetz@4798 261 COMPARISON_OP(name, comparison) \
Goetz@4798 262 CASE(_if_acmp##name): { \
Goetz@4798 263 - int skip = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)) \
Goetz@4798 264 + const bool cmp = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)); \
Goetz@4798 265 + int skip = cmp \
Goetz@4798 266 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \
Goetz@4798 267 address branch_pc = pc; \
Goetz@4798 268 + /* Profile branch. */ \
Goetz@4798 269 + BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \
Goetz@4798 270 UPDATE_PC_AND_TOS(skip, -2); \
Goetz@4798 271 DO_BACKEDGE_CHECKS(skip, branch_pc); \
Goetz@4798 272 CONTINUE; \
Goetz@4798 273 @@ -1505,9 +1570,12 @@
Goetz@4798 274
Goetz@4798 275 #define NULL_COMPARISON_NOT_OP(name) \
Goetz@4798 276 CASE(_if##name): { \
Goetz@4798 277 - int skip = (!(STACK_OBJECT(-1) == NULL)) \
Goetz@4798 278 + const bool cmp = (!(STACK_OBJECT(-1) == NULL)); \
Goetz@4798 279 + int skip = cmp \
Goetz@4798 280 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \
Goetz@4798 281 address branch_pc = pc; \
Goetz@4798 282 + /* Profile branch. */ \
Goetz@4798 283 + BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \
Goetz@4798 284 UPDATE_PC_AND_TOS(skip, -1); \
Goetz@4798 285 DO_BACKEDGE_CHECKS(skip, branch_pc); \
Goetz@4798 286 CONTINUE; \
Goetz@4798 287 @@ -1515,9 +1583,12 @@
Goetz@4798 288
Goetz@4798 289 #define NULL_COMPARISON_OP(name) \
Goetz@4798 290 CASE(_if##name): { \
Goetz@4798 291 - int skip = ((STACK_OBJECT(-1) == NULL)) \
Goetz@4798 292 + const bool cmp = ((STACK_OBJECT(-1) == NULL)); \
Goetz@4798 293 + int skip = cmp \
Goetz@4798 294 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \
Goetz@4798 295 address branch_pc = pc; \
Goetz@4798 296 + /* Profile branch. */ \
Goetz@4798 297 + BI_PROFILE_UPDATE_BRANCH(/*is_taken=*/cmp); \
Goetz@4798 298 UPDATE_PC_AND_TOS(skip, -1); \
Goetz@4798 299 DO_BACKEDGE_CHECKS(skip, branch_pc); \
Goetz@4798 300 CONTINUE; \
Goetz@4798 301 @@ -1540,9 +1611,14 @@
Goetz@4798 302 int32_t high = Bytes::get_Java_u4((address)&lpc[2]);
Goetz@4798 303 int32_t skip;
Goetz@4798 304 key -= low;
Goetz@4798 305 - skip = ((uint32_t) key > (uint32_t)(high - low))
Goetz@4798 306 - ? Bytes::get_Java_u4((address)&lpc[0])
Goetz@4798 307 - : Bytes::get_Java_u4((address)&lpc[key + 3]);
Goetz@4798 308 + if (((uint32_t) key > (uint32_t)(high - low))) {
Goetz@4798 309 + key = -1;
Goetz@4798 310 + skip = Bytes::get_Java_u4((address)&lpc[0]);
Goetz@4798 311 + } else {
Goetz@4798 312 + skip = Bytes::get_Java_u4((address)&lpc[key + 3]);
Goetz@4798 313 + }
Goetz@4798 314 + // Profile switch.
Goetz@4798 315 + BI_PROFILE_UPDATE_SWITCH(/*switch_index=*/key);
Goetz@4798 316 // Does this really need a full backedge check (osr?)
Goetz@4798 317 address branch_pc = pc;
Goetz@4798 318 UPDATE_PC_AND_TOS(skip, -1);
Goetz@4798 319 @@ -1556,14 +1632,21 @@
Goetz@4798 320 jint* lpc = (jint*)VMalignWordUp(pc+1);
Goetz@4798 321 int32_t key = STACK_INT(-1);
Goetz@4798 322 int32_t skip = Bytes::get_Java_u4((address) lpc); /* default amount */
Goetz@4798 323 + // Remember index.
Goetz@4798 324 + int index = -1;
Goetz@4798 325 + int newindex = 0;
Goetz@4798 326 int32_t npairs = Bytes::get_Java_u4((address) &lpc[1]);
Goetz@4798 327 while (--npairs >= 0) {
Goetz@4798 328 - lpc += 2;
Goetz@4798 329 - if (key == (int32_t)Bytes::get_Java_u4((address)lpc)) {
Goetz@4798 330 - skip = Bytes::get_Java_u4((address)&lpc[1]);
Goetz@4798 331 - break;
Goetz@4798 332 - }
Goetz@4798 333 + lpc += 2;
Goetz@4798 334 + if (key == (int32_t)Bytes::get_Java_u4((address)lpc)) {
Goetz@4798 335 + skip = Bytes::get_Java_u4((address)&lpc[1]);
Goetz@4798 336 + index = newindex;
Goetz@4798 337 + break;
Goetz@4798 338 + }
Goetz@4798 339 + newindex += 1;
Goetz@4798 340 }
Goetz@4798 341 + // Profile switch.
Goetz@4798 342 + BI_PROFILE_UPDATE_SWITCH(/*switch_index=*/index);
Goetz@4798 343 address branch_pc = pc;
Goetz@4798 344 UPDATE_PC_AND_TOS(skip, -1);
Goetz@4798 345 DO_BACKEDGE_CHECKS(skip, branch_pc);
Goetz@4798 346 @@ -1648,7 +1731,7 @@
Goetz@4798 347 if ((uint32_t)index >= (uint32_t)arrObj->length()) { \
Goetz@4798 348 sprintf(message, "%d", index); \
Goetz@4798 349 VM_JAVA_ERROR(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), \
Goetz@4798 350 - message); \
Goetz@4798 351 + message, note_rangeCheck_trap); \
Goetz@4798 352 }
Goetz@4798 353
Goetz@4798 354 /* 32-bit loads. These handle conversion from < 32-bit types */
Goetz@4798 355 @@ -1729,15 +1812,22 @@
Goetz@4798 356 // arrObj, index are set
Goetz@4798 357 if (rhsObject != NULL) {
Goetz@4798 358 /* Check assignability of rhsObject into arrObj */
Goetz@4798 359 - Klass* rhsKlassOop = rhsObject->klass(); // EBX (subclass)
Goetz@4798 360 - Klass* elemKlassOop = ObjArrayKlass::cast(arrObj->klass())->element_klass(); // superklass EAX
Goetz@4798 361 + Klass* rhsKlass = rhsObject->klass(); // EBX (subclass)
Goetz@4798 362 + Klass* elemKlass = ObjArrayKlass::cast(arrObj->klass())->element_klass(); // superklass EAX
Goetz@4798 363 //
Goetz@4798 364 // Check for compatibilty. This check must not GC!!
Goetz@4798 365 // Seems way more expensive now that we must dispatch
Goetz@4798 366 //
Goetz@4798 367 - if (rhsKlassOop != elemKlassOop && !rhsKlassOop->is_subtype_of(elemKlassOop)) { // ebx->is...
Goetz@4798 368 - VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), "");
Goetz@4798 369 + if (rhsKlass != elemKlass && !rhsKlass->is_subtype_of(elemKlass)) { // ebx->is...
Goetz@4798 370 + // Decrement counter if subtype check failed.
Goetz@4798 371 + BI_PROFILE_SUBTYPECHECK_FAILED(rhsKlass);
Goetz@4798 372 + VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), "", note_arrayCheck_trap);
Goetz@4798 373 }
Goetz@4798 374 + // Profile checkcast with null_seen and receiver.
Goetz@4798 375 + BI_PROFILE_UPDATE_CHECKCAST(/*null_seen=*/false, rhsKlass);
Goetz@4798 376 + } else {
Goetz@4798 377 + // Profile checkcast with null_seen and receiver.
Goetz@4798 378 + BI_PROFILE_UPDATE_CHECKCAST(/*null_seen=*/true, NULL);
Goetz@4798 379 }
Goetz@4798 380 // G1GC port. Use accessor instead of storing manually.
Goetz@4798 381 // Takes care of write barriers internally and replaces the code above.
Goetz@4798 382 @@ -2139,10 +2229,14 @@
Goetz@4798 383 if (UseTLAB) {
Goetz@4798 384 result = (oop) THREAD->tlab().allocate(obj_size);
Goetz@4798 385 }
Goetz@4798 386 + // Disable non-TLAB-based fast-path, because profiling requires that all
Goetz@4798 387 + // allocations go through InterpreterRuntime::_new() if THREAD->tlab().allocate
Goetz@4798 388 + // returns NULL.
Goetz@4798 389 +#ifndef CC_INTERP_PROFILE
Goetz@4798 390 if (result == NULL) {
Goetz@4798 391 need_zero = true;
Goetz@4798 392 // Try allocate in shared eden
Goetz@4798 393 - retry:
Goetz@4798 394 + retry:
Goetz@4798 395 HeapWord* compare_to = *Universe::heap()->top_addr();
Goetz@4798 396 HeapWord* new_top = compare_to + obj_size;
Goetz@4798 397 if (new_top <= *Universe::heap()->end_addr()) {
Goetz@4798 398 @@ -2152,6 +2246,7 @@
Goetz@4798 399 result = (oop) compare_to;
Goetz@4798 400 }
Goetz@4798 401 }
Goetz@4798 402 +#endif
Goetz@4798 403 if (result != NULL) {
Goetz@4798 404 // Initialize object (if nonzero size and need) and then the header
Goetz@4798 405 if (need_zero ) {
Goetz@4798 406 @@ -2207,42 +2302,40 @@
Goetz@4798 407 if (STACK_OBJECT(-1) != NULL) {
Goetz@4798 408 VERIFY_OOP(STACK_OBJECT(-1));
Goetz@4798 409 u2 index = Bytes::get_Java_u2(pc+1);
Goetz@4798 410 - if (ProfileInterpreter) {
Goetz@4798 411 - // needs Profile_checkcast QQQ
Goetz@4798 412 - ShouldNotReachHere();
Goetz@4798 413 - }
Goetz@4798 414 // Constant pool may have actual klass or unresolved klass. If it is
Goetz@4798 415 // unresolved we must resolve it
Goetz@4798 416 if (METHOD->constants()->tag_at(index).is_unresolved_klass()) {
Goetz@4798 417 CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception);
Goetz@4798 418 }
Goetz@4798 419 Klass* klassOf = (Klass*) METHOD->constants()->slot_at(index).get_klass();
Goetz@4798 420 - Klass* objKlassOop = STACK_OBJECT(-1)->klass(); //ebx
Goetz@4798 421 + Klass* objKlass = STACK_OBJECT(-1)->klass(); //ebx
Goetz@4798 422 //
Goetz@4798 423 // Check for compatibilty. This check must not GC!!
Goetz@4798 424 // Seems way more expensive now that we must dispatch
Goetz@4798 425 //
Goetz@4798 426 - if (objKlassOop != klassOf &&
Goetz@4798 427 - !objKlassOop->is_subtype_of(klassOf)) {
Goetz@4798 428 + if (objKlass != klassOf && !objKlass->is_subtype_of(klassOf)) {
Goetz@4798 429 + // Decrement counter at checkcast.
Goetz@4798 430 + BI_PROFILE_SUBTYPECHECK_FAILED(objKlass);
Goetz@4798 431 ResourceMark rm(THREAD);
Goetz@4798 432 - const char* objName = objKlassOop->external_name();
Goetz@4798 433 + const char* objName = objKlass->external_name();
Goetz@4798 434 const char* klassName = klassOf->external_name();
Goetz@4798 435 char* message = SharedRuntime::generate_class_cast_message(
Goetz@4798 436 objName, klassName);
Goetz@4798 437 - VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message);
Goetz@4798 438 + VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message, note_classCheck_trap);
Goetz@4798 439 }
Goetz@4798 440 + // Profile checkcast with null_seen and receiver.
Goetz@4798 441 + BI_PROFILE_UPDATE_CHECKCAST(/*null_seen=*/false, objKlass);
Goetz@4798 442 } else {
Goetz@4798 443 - if (UncommonNullCast) {
Goetz@4798 444 -// istate->method()->set_null_cast_seen();
Goetz@4798 445 -// [RGV] Not sure what to do here!
Goetz@4798 446 -
Goetz@4798 447 - }
Goetz@4798 448 + // Profile checkcast with null_seen and receiver.
Goetz@4798 449 + BI_PROFILE_UPDATE_CHECKCAST(/*null_seen=*/true, NULL);
Goetz@4798 450 }
Goetz@4798 451 UPDATE_PC_AND_CONTINUE(3);
Goetz@4798 452
Goetz@4798 453 CASE(_instanceof):
Goetz@4798 454 if (STACK_OBJECT(-1) == NULL) {
Goetz@4798 455 SET_STACK_INT(0, -1);
Goetz@4798 456 + // Profile instanceof with null_seen and receiver.
Goetz@4798 457 + BI_PROFILE_UPDATE_INSTANCEOF(/*null_seen=*/true, NULL);
Goetz@4798 458 } else {
Goetz@4798 459 VERIFY_OOP(STACK_OBJECT(-1));
Goetz@4798 460 u2 index = Bytes::get_Java_u2(pc+1);
Goetz@4798 461 @@ -2252,16 +2345,20 @@
Goetz@4798 462 CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception);
Goetz@4798 463 }
Goetz@4798 464 Klass* klassOf = (Klass*) METHOD->constants()->slot_at(index).get_klass();
Goetz@4798 465 - Klass* objKlassOop = STACK_OBJECT(-1)->klass();
Goetz@4798 466 + Klass* objKlass = STACK_OBJECT(-1)->klass();
Goetz@4798 467 //
Goetz@4798 468 // Check for compatibilty. This check must not GC!!
Goetz@4798 469 // Seems way more expensive now that we must dispatch
Goetz@4798 470 //
Goetz@4798 471 - if ( objKlassOop == klassOf || objKlassOop->is_subtype_of(klassOf)) {
Goetz@4798 472 + if ( objKlass == klassOf || objKlass->is_subtype_of(klassOf)) {
Goetz@4798 473 SET_STACK_INT(1, -1);
Goetz@4798 474 } else {
Goetz@4798 475 SET_STACK_INT(0, -1);
Goetz@4798 476 + // Decrement counter at checkcast.
Goetz@4798 477 + BI_PROFILE_SUBTYPECHECK_FAILED(objKlass);
Goetz@4798 478 }
Goetz@4798 479 + // Profile instanceof with null_seen and receiver.
Goetz@4798 480 + BI_PROFILE_UPDATE_INSTANCEOF(/*null_seen=*/false, objKlass);
Goetz@4798 481 }
Goetz@4798 482 UPDATE_PC_AND_CONTINUE(3);
Goetz@4798 483
Goetz@4798 484 @@ -2404,6 +2501,9 @@
Goetz@4798 485 istate->set_callee_entry_point(method->from_interpreted_entry());
Goetz@4798 486 istate->set_bcp_advance(5);
Goetz@4798 487
Goetz@4798 488 + // Invokedynamic has got a call counter, just like an invokestatic -> increment!
Goetz@4798 489 + BI_PROFILE_UPDATE_CALL();
Goetz@4798 490 +
Goetz@4798 491 UPDATE_PC_AND_RETURN(0); // I'll be back...
Goetz@4798 492 }
Goetz@4798 493
Goetz@4798 494 @@ -2437,6 +2537,9 @@
Goetz@4798 495 istate->set_callee_entry_point(method->from_interpreted_entry());
Goetz@4798 496 istate->set_bcp_advance(3);
Goetz@4798 497
Goetz@4798 498 + // Invokehandle has got a call counter, just like a final call -> increment!
Goetz@4798 499 + BI_PROFILE_UPDATE_FINALCALL();
Goetz@4798 500 +
Goetz@4798 501 UPDATE_PC_AND_RETURN(0); // I'll be back...
Goetz@4798 502 }
Goetz@4798 503
Goetz@4798 504 @@ -2464,14 +2567,18 @@
Goetz@4798 505 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
Goetz@4798 506 if (cache->is_vfinal()) {
Goetz@4798 507 callee = cache->f2_as_vfinal_method();
Goetz@4798 508 + // Profile 'special case of invokeinterface' final call.
Goetz@4798 509 + BI_PROFILE_UPDATE_FINALCALL();
Goetz@4798 510 } else {
Goetz@4798 511 // get receiver
Goetz@4798 512 int parms = cache->parameter_size();
Goetz@4798 513 // Same comments as invokevirtual apply here
Goetz@4798 514 - VERIFY_OOP(STACK_OBJECT(-parms));
Goetz@4798 515 - InstanceKlass* rcvrKlass = (InstanceKlass*)
Goetz@4798 516 - STACK_OBJECT(-parms)->klass();
Goetz@4798 517 + oop rcvr = STACK_OBJECT(-parms);
Goetz@4798 518 + VERIFY_OOP(rcvr);
Goetz@4798 519 + InstanceKlass* rcvrKlass = (InstanceKlass*)rcvr->klass();
Goetz@4798 520 callee = (Method*) rcvrKlass->start_of_vtable()[ cache->f2_as_index()];
Goetz@4798 521 + // Profile 'special case of invokeinterface' virtual call.
Goetz@4798 522 + BI_PROFILE_UPDATE_VIRTUALCALL(rcvr->klass());
Goetz@4798 523 }
Goetz@4798 524 istate->set_callee(callee);
Goetz@4798 525 istate->set_callee_entry_point(callee->from_interpreted_entry());
Goetz@4798 526 @@ -2502,15 +2609,18 @@
Goetz@4798 527 // interface. The link resolver checks this but only for the first
Goetz@4798 528 // time this interface is called.
Goetz@4798 529 if (i == int2->itable_length()) {
Goetz@4798 530 - VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "");
Goetz@4798 531 + VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "", note_no_trap);
Goetz@4798 532 }
Goetz@4798 533 int mindex = cache->f2_as_index();
Goetz@4798 534 itableMethodEntry* im = ki->first_method_entry(rcvr->klass());
Goetz@4798 535 callee = im[mindex].method();
Goetz@4798 536 if (callee == NULL) {
Goetz@4798 537 - VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), "");
Goetz@4798 538 + VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), "", note_no_trap);
Goetz@4798 539 }
Goetz@4798 540
Goetz@4798 541 + // Profile virtual call.
Goetz@4798 542 + BI_PROFILE_UPDATE_VIRTUALCALL(rcvr->klass());
Goetz@4798 543 +
Goetz@4798 544 istate->set_callee(callee);
Goetz@4798 545 istate->set_callee_entry_point(callee->from_interpreted_entry());
Goetz@4798 546 #ifdef VM_JVMTI
Goetz@4798 547 @@ -2542,8 +2652,11 @@
Goetz@4798 548 Method* callee;
Goetz@4798 549 if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) {
Goetz@4798 550 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
Goetz@4798 551 - if (cache->is_vfinal()) callee = cache->f2_as_vfinal_method();
Goetz@4798 552 - else {
Goetz@4798 553 + if (cache->is_vfinal()) {
Goetz@4798 554 + callee = cache->f2_as_vfinal_method();
Goetz@4798 555 + // Profile final call.
Goetz@4798 556 + BI_PROFILE_UPDATE_FINALCALL();
Goetz@4798 557 + } else {
Goetz@4798 558 // get receiver
Goetz@4798 559 int parms = cache->parameter_size();
Goetz@4798 560 // this works but needs a resourcemark and seems to create a vtable on every call:
Goetz@4798 561 @@ -2552,8 +2665,9 @@
Goetz@4798 562 // this fails with an assert
Goetz@4798 563 // InstanceKlass* rcvrKlass = InstanceKlass::cast(STACK_OBJECT(-parms)->klass());
Goetz@4798 564 // but this works
Goetz@4798 565 - VERIFY_OOP(STACK_OBJECT(-parms));
Goetz@4798 566 - InstanceKlass* rcvrKlass = (InstanceKlass*) STACK_OBJECT(-parms)->klass();
Goetz@4798 567 + oop rcvr = STACK_OBJECT(-parms);
Goetz@4798 568 + VERIFY_OOP(rcvr);
Goetz@4798 569 + InstanceKlass* rcvrKlass = (InstanceKlass*)rcvr->klass();
Goetz@4798 570 /*
Goetz@4798 571 Executing this code in java.lang.String:
Goetz@4798 572 public String(char value[]) {
Goetz@4798 573 @@ -2571,12 +2685,17 @@
Goetz@4798 574
Goetz@4798 575 */
Goetz@4798 576 callee = (Method*) rcvrKlass->start_of_vtable()[ cache->f2_as_index()];
Goetz@4798 577 + // Profile virtual call.
Goetz@4798 578 + BI_PROFILE_UPDATE_VIRTUALCALL(rcvr->klass());
Goetz@4798 579 }
Goetz@4798 580 } else {
Goetz@4798 581 if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) {
Goetz@4798 582 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
Goetz@4798 583 }
Goetz@4798 584 callee = cache->f1_as_method();
Goetz@4798 585 +
Goetz@4798 586 + // Profile call.
Goetz@4798 587 + BI_PROFILE_UPDATE_CALL();
Goetz@4798 588 }
Goetz@4798 589
Goetz@4798 590 istate->set_callee(callee);
Goetz@4798 591 @@ -2628,6 +2747,8 @@
Goetz@4798 592 CASE(_goto):
Goetz@4798 593 {
Goetz@4798 594 int16_t offset = (int16_t)Bytes::get_Java_u2(pc + 1);
Goetz@4798 595 + // Profile jump.
Goetz@4798 596 + BI_PROFILE_UPDATE_JUMP();
Goetz@4798 597 address branch_pc = pc;
Goetz@4798 598 UPDATE_PC(offset);
Goetz@4798 599 DO_BACKEDGE_CHECKS(offset, branch_pc);
Goetz@4798 600 @@ -2644,6 +2765,8 @@
Goetz@4798 601 CASE(_goto_w):
Goetz@4798 602 {
Goetz@4798 603 int32_t offset = Bytes::get_Java_u4(pc + 1);
Goetz@4798 604 + // Profile jump.
Goetz@4798 605 + BI_PROFILE_UPDATE_JUMP();
Goetz@4798 606 address branch_pc = pc;
Goetz@4798 607 UPDATE_PC(offset);
Goetz@4798 608 DO_BACKEDGE_CHECKS(offset, branch_pc);
Goetz@4798 609 @@ -2653,6 +2776,9 @@
Goetz@4798 610 /* return from a jsr or jsr_w */
Goetz@4798 611
Goetz@4798 612 CASE(_ret): {
Goetz@4798 613 + // Profile ret.
Goetz@4798 614 + BI_PROFILE_UPDATE_RET(/*bci=*/((int)(intptr_t)(LOCALS_ADDR(pc[1]))));
Goetz@4798 615 + // now, update the pc
Goetz@4798 616 pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(pc[1]));
Goetz@4798 617 UPDATE_PC_AND_CONTINUE(0);
Goetz@4798 618 }
Goetz@4798 619 @@ -2734,6 +2860,9 @@
Goetz@4798 620 }
Goetz@4798 621 // for AbortVMOnException flag
Goetz@4798 622 NOT_PRODUCT(Exceptions::debug_check_abort(except_oop));
Goetz@4798 623 +
Goetz@4798 624 + // Update profiling data.
Goetz@4798 625 + BI_PROFILE_ALIGN_TO_CURRENT_BCI();
Goetz@4798 626 goto run;
Goetz@4798 627 }
Goetz@4798 628 if (TraceExceptions) {
Goetz@4798 629 @@ -2936,7 +3065,7 @@
Goetz@4798 630 oop rcvr = base->obj();
Goetz@4798 631 if (rcvr == NULL) {
Goetz@4798 632 if (!suppress_error) {
Goetz@4798 633 - VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), "");
Goetz@4798 634 + VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), "", note_nullCheck_trap);
Goetz@4798 635 illegal_state_oop = THREAD->pending_exception();
Goetz@4798 636 THREAD->clear_pending_exception();
Goetz@4798 637 }
Goetz@4798 638 @@ -3014,7 +3143,7 @@
Goetz@4798 639 // A pending exception that was pending prior to a possible popping frame
Goetz@4798 640 // overrides the popping frame.
Goetz@4798 641 //
Goetz@4798 642 - assert(!suppress_error || suppress_error && illegal_state_oop() == NULL, "Error was not suppressed");
Goetz@4798 643 + assert(!suppress_error || (suppress_error && illegal_state_oop() == NULL), "Error was not suppressed");
Goetz@4798 644 if (illegal_state_oop() != NULL || original_exception() != NULL) {
Goetz@4798 645 // inform the frame manager we have no result
Goetz@4798 646 istate->set_msg(throwing_exception);
Goetz@4798 647 diff -r 84fd980e69ee src/share/vm/interpreter/bytecodeInterpreterProfiling.hpp
Goetz@4798 648 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
Goetz@4798 649 +++ b/src/share/vm/interpreter/bytecodeInterpreterProfiling.hpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 650 @@ -0,0 +1,307 @@
Goetz@4798 651 +/*
Goetz@4798 652 + * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
Goetz@4798 653 + * Copyright 2012 SAP AG. All rights reserved.
Goetz@4798 654 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
Goetz@4798 655 + *
Goetz@4798 656 + * This code is free software; you can redistribute it and/or modify it
Goetz@4798 657 + * under the terms of the GNU General Public License version 2 only, as
Goetz@4798 658 + * published by the Free Software Foundation.
Goetz@4798 659 + *
Goetz@4798 660 + * This code is distributed in the hope that it will be useful, but WITHOUT
Goetz@4798 661 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Goetz@4798 662 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
Goetz@4798 663 + * version 2 for more details (a copy is included in the LICENSE file that
Goetz@4798 664 + * accompanied this code).
Goetz@4798 665 + *
Goetz@4798 666 + * You should have received a copy of the GNU General Public License version
Goetz@4798 667 + * 2 along with this work; if not, write to the Free Software Foundation,
Goetz@4798 668 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
Goetz@4798 669 + *
Goetz@4798 670 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
Goetz@4798 671 + * or visit www.oracle.com if you need additional information or have any
Goetz@4798 672 + * questions.
Goetz@4798 673 + *
Goetz@4798 674 + */
Goetz@4798 675 +
Goetz@4798 676 +// This file defines a set of macros which are used by the c++-interpreter
Goetz@4798 677 +// for updating a method's methodData object.
Goetz@4798 678 +
Goetz@4798 679 +
Goetz@4798 680 +#ifndef SHARE_VM_INTERPRETER_BYTECODEINTERPRETERPROFILING_HPP
Goetz@4798 681 +#define SHARE_VM_INTERPRETER_BYTECODEINTERPRETERPROFILING_HPP
Goetz@4798 682 +
Goetz@4798 683 +
Goetz@4798 684 +// Global settings /////////////////////////////////////////////////////////////
Goetz@4798 685 +
Goetz@4798 686 +
Goetz@4798 687 +// Enables profiling support
Goetz@4798 688 +#if defined(COMPILER2) && defined(PPC64)
Goetz@4798 689 +#define CC_INTERP_PROFILE
Goetz@4798 690 +#endif
Goetz@4798 691 +
Goetz@4798 692 +// Enables assertions for profiling code (also works in product-builds).
Goetz@4798 693 +// #define CC_INTERP_PROFILE_WITH_ASSERTIONS
Goetz@4798 694 +
Goetz@4798 695 +
Goetz@4798 696 +#ifdef CC_INTERP
Goetz@4798 697 +
Goetz@4798 698 +// Empty dummy implementations if profiling code is switched off. //////////////
Goetz@4798 699 +
Goetz@4798 700 +#ifndef CC_INTERP_PROFILE
Goetz@4798 701 +
Goetz@4798 702 +#define SET_MDX(mdx)
Goetz@4798 703 +
Goetz@4798 704 +#define BI_PROFILE_GET_OR_CREATE_METHOD_DATA(exception_handler) \
Goetz@4798 705 + if (ProfileInterpreter) { \
Goetz@4798 706 + ShouldNotReachHere(); \
Goetz@4798 707 + }
Goetz@4798 708 +
Goetz@4798 709 +#define BI_PROFILE_ALIGN_TO_CURRENT_BCI()
Goetz@4798 710 +
Goetz@4798 711 +#define BI_PROFILE_UPDATE_JUMP()
Goetz@4798 712 +#define BI_PROFILE_UPDATE_BRANCH(is_taken)
Goetz@4798 713 +#define BI_PROFILE_UPDATE_RET(bci)
Goetz@4798 714 +#define BI_PROFILE_SUBTYPECHECK_FAILED(receiver)
Goetz@4798 715 +#define BI_PROFILE_UPDATE_CHECKCAST(null_seen, receiver)
Goetz@4798 716 +#define BI_PROFILE_UPDATE_INSTANCEOF(null_seen, receiver)
Goetz@4798 717 +#define BI_PROFILE_UPDATE_CALL()
Goetz@4798 718 +#define BI_PROFILE_UPDATE_FINALCALL()
Goetz@4798 719 +#define BI_PROFILE_UPDATE_VIRTUALCALL(receiver)
Goetz@4798 720 +#define BI_PROFILE_UPDATE_SWITCH(switch_index)
Goetz@4798 721 +
Goetz@4798 722 +
Goetz@4798 723 +#else
Goetz@4798 724 +
Goetz@4798 725 +
Goetz@4798 726 +// Non-dummy implementations ///////////////////////////////////////////////////
Goetz@4798 727 +
Goetz@4798 728 +// Accessors for the current method data pointer 'mdx'.
Goetz@4798 729 +#define MDX() (istate->mdx())
Goetz@4798 730 +#define SET_MDX(mdx) \
Goetz@4798 731 + if (TraceProfileInterpreter) { \
Goetz@4798 732 + /* Let it look like TraceBytecodes' format. */ \
Goetz@4798 733 + tty->print_cr("[%d] %4d " \
Goetz@4798 734 + "mdx " PTR_FORMAT "(%d)" \
Goetz@4798 735 + " " \
Goetz@4798 736 + " \t-> " PTR_FORMAT "(%d)", \
Goetz@4798 737 + (int) THREAD->osthread()->thread_id(), \
Goetz@4798 738 + BCI(), \
Goetz@4798 739 + MDX(), \
Goetz@4798 740 + (MDX() == NULL \
Goetz@4798 741 + ? 0 \
Goetz@4798 742 + : istate->method()->method_data()->dp_to_di((address)MDX())), \
Goetz@4798 743 + mdx, \
Goetz@4798 744 + istate->method()->method_data()->dp_to_di((address)mdx) \
Goetz@4798 745 + ); \
Goetz@4798 746 + }; \
Goetz@4798 747 + istate->set_mdx(mdx);
Goetz@4798 748 +
Goetz@4798 749 +
Goetz@4798 750 +// Dumps the profiling method data for the current method.
Goetz@4798 751 +#ifdef PRODUCT
Goetz@4798 752 +#define BI_PROFILE_PRINT_METHOD_DATA()
Goetz@4798 753 +#else // PRODUCT
Goetz@4798 754 +#define BI_PROFILE_PRINT_METHOD_DATA() \
Goetz@4798 755 + { \
Goetz@4798 756 + ttyLocker ttyl; \
Goetz@4798 757 + MethodData *md = istate->method()->method_data(); \
Goetz@4798 758 + tty->cr(); \
Goetz@4798 759 + tty->print("method data at mdx " PTR_FORMAT "(0) for", \
Goetz@4798 760 + md->data_layout_at(md->bci_to_di(0))); \
Goetz@4798 761 + istate->method()->print_short_name(tty); \
Goetz@4798 762 + tty->cr(); \
Goetz@4798 763 + if (md != NULL) { \
Goetz@4798 764 + md->print_data_on(tty); \
Goetz@4798 765 + address mdx = (address) MDX(); \
Goetz@4798 766 + if (mdx != NULL) { \
Goetz@4798 767 + tty->print_cr("current mdx " PTR_FORMAT "(%d)", \
Goetz@4798 768 + mdx, \
Goetz@4798 769 + istate->method()->method_data()->dp_to_di(mdx)); \
Goetz@4798 770 + } \
Goetz@4798 771 + } else { \
Goetz@4798 772 + tty->print_cr("no method data"); \
Goetz@4798 773 + } \
Goetz@4798 774 + }
Goetz@4798 775 +#endif // PRODUCT
Goetz@4798 776 +
Goetz@4798 777 +
Goetz@4798 778 +// Gets or creates the profiling method data and initializes mdx.
Goetz@4798 779 +#define BI_PROFILE_GET_OR_CREATE_METHOD_DATA(exception_handler) \
Goetz@4798 780 + if (ProfileInterpreter && MDX() == NULL) { \
Goetz@4798 781 + /* Mdx is not yet initialized for this activation. */ \
Goetz@4798 782 + MethodData *md = istate->method()->method_data(); \
Goetz@4798 783 + if (md == NULL) { \
Goetz@4798 784 + MethodCounters* mcs; \
Goetz@4798 785 + GET_METHOD_COUNTERS(mcs); \
Goetz@4798 786 + /* The profiling method data doesn't exist for this method, */ \
Goetz@4798 787 + /* create it if the counters have overflowed. */ \
Goetz@4798 788 + if (INVOCATION_COUNT(mcs)->reached_ProfileLimit(BACKEDGE_COUNT(mcs))) { \
Goetz@4798 789 + /* Must use CALL_VM, because an async exception may be pending. */ \
Goetz@4798 790 + CALL_VM((InterpreterRuntime::profile_method(THREAD)), \
Goetz@4798 791 + exception_handler); \
Goetz@4798 792 + md = istate->method()->method_data(); \
Goetz@4798 793 + if (md != NULL) { \
Goetz@4798 794 + if (TraceProfileInterpreter) { \
Goetz@4798 795 + BI_PROFILE_PRINT_METHOD_DATA(); \
Goetz@4798 796 + } \
Goetz@4798 797 + Method *m = istate->method(); \
Goetz@4798 798 + int bci = m->bci_from(pc); \
Goetz@4798 799 + jint di = md->bci_to_di(bci); \
Goetz@4798 800 + SET_MDX(md->data_layout_at(di)); \
Goetz@4798 801 + } \
Goetz@4798 802 + } \
Goetz@4798 803 + } else { \
Goetz@4798 804 + /* The profiling method data exists, align the method data pointer */ \
Goetz@4798 805 + /* mdx to the current bytecode index. */ \
Goetz@4798 806 + if (TraceProfileInterpreter) { \
Goetz@4798 807 + BI_PROFILE_PRINT_METHOD_DATA(); \
Goetz@4798 808 + } \
Goetz@4798 809 + SET_MDX(md->data_layout_at(md->bci_to_di(BCI()))); \
Goetz@4798 810 + } \
Goetz@4798 811 + }
Goetz@4798 812 +
Goetz@4798 813 +
Goetz@4798 814 +// Asserts that the current method data pointer mdx corresponds
Goetz@4798 815 +// to the current bytecode.
Goetz@4798 816 +#if defined(CC_INTERP_PROFILE_WITH_ASSERTIONS)
Goetz@4798 817 +#define BI_PROFILE_CHECK_MDX() \
Goetz@4798 818 + { \
Goetz@4798 819 + MethodData *md = istate->method()->method_data(); \
Goetz@4798 820 + address mdx = (address) MDX(); \
Goetz@4798 821 + address mdx2 = (address) md->data_layout_at(md->bci_to_di(BCI())); \
Goetz@4798 822 + guarantee(md != NULL, "1"); \
Goetz@4798 823 + guarantee(mdx != NULL, "2"); \
Goetz@4798 824 + guarantee(mdx2 != NULL, "3"); \
Goetz@4798 825 + if (mdx != mdx2) { \
Goetz@4798 826 + BI_PROFILE_PRINT_METHOD_DATA(); \
Goetz@4798 827 + fatal3("invalid mdx at bci %d:" \
Goetz@4798 828 + " was " PTR_FORMAT \
Goetz@4798 829 + " but expected " PTR_FORMAT, \
Goetz@4798 830 + BCI(), \
Goetz@4798 831 + mdx, \
Goetz@4798 832 + mdx2); \
Goetz@4798 833 + } \
Goetz@4798 834 + }
Goetz@4798 835 +#else
Goetz@4798 836 +#define BI_PROFILE_CHECK_MDX()
Goetz@4798 837 +#endif
Goetz@4798 838 +
Goetz@4798 839 +
Goetz@4798 840 +// Aligns the method data pointer mdx to the current bytecode index.
Goetz@4798 841 +#define BI_PROFILE_ALIGN_TO_CURRENT_BCI() \
Goetz@4798 842 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 843 + MethodData *md = istate->method()->method_data(); \
Goetz@4798 844 + SET_MDX(md->data_layout_at(md->bci_to_di(BCI()))); \
Goetz@4798 845 + }
Goetz@4798 846 +
Goetz@4798 847 +
Goetz@4798 848 +// Updates profiling data for a jump.
Goetz@4798 849 +#define BI_PROFILE_UPDATE_JUMP() \
Goetz@4798 850 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 851 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 852 + JumpData::increment_taken_count_no_overflow(MDX()); \
Goetz@4798 853 + /* Remember last branch taken count. */ \
Goetz@4798 854 + mdo_last_branch_taken_count = JumpData::taken_count(MDX()); \
Goetz@4798 855 + SET_MDX(JumpData::advance_taken(MDX())); \
Goetz@4798 856 + }
Goetz@4798 857 +
Goetz@4798 858 +
Goetz@4798 859 +// Updates profiling data for a taken/not taken branch.
Goetz@4798 860 +#define BI_PROFILE_UPDATE_BRANCH(is_taken) \
Goetz@4798 861 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 862 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 863 + if (is_taken) { \
Goetz@4798 864 + BranchData::increment_taken_count_no_overflow(MDX()); \
Goetz@4798 865 + /* Remember last branch taken count. */ \
Goetz@4798 866 + mdo_last_branch_taken_count = BranchData::taken_count(MDX()); \
Goetz@4798 867 + SET_MDX(BranchData::advance_taken(MDX())); \
Goetz@4798 868 + } else { \
Goetz@4798 869 + BranchData::increment_not_taken_count_no_overflow(MDX()); \
Goetz@4798 870 + SET_MDX(BranchData::advance_not_taken(MDX())); \
Goetz@4798 871 + } \
Goetz@4798 872 + }
Goetz@4798 873 +
Goetz@4798 874 +
Goetz@4798 875 +// Updates profiling data for a ret with given bci.
Goetz@4798 876 +#define BI_PROFILE_UPDATE_RET(bci) \
Goetz@4798 877 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 878 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 879 + MethodData *md = istate->method()->method_data(); \
Goetz@4798 880 +/* FIXME: there is more to do here than increment and advance(mdx)! */ \
Goetz@4798 881 + CounterData::increment_count_no_overflow(MDX()); \
Goetz@4798 882 + SET_MDX(RetData::advance(md, bci)); \
Goetz@4798 883 + }
Goetz@4798 884 +
Goetz@4798 885 +// Decrement counter at checkcast if the subtype check fails (as template
Goetz@4798 886 +// interpreter does!).
Goetz@4798 887 +#define BI_PROFILE_SUBTYPECHECK_FAILED(receiver) \
Goetz@4798 888 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 889 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 890 + ReceiverTypeData::increment_receiver_count_no_overflow(MDX(), receiver); \
Goetz@4798 891 + ReceiverTypeData::decrement_count(MDX()); \
Goetz@4798 892 + }
Goetz@4798 893 +
Goetz@4798 894 +// Updates profiling data for a checkcast (was a null seen? which receiver?).
Goetz@4798 895 +#define BI_PROFILE_UPDATE_CHECKCAST(null_seen, receiver) \
Goetz@4798 896 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 897 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 898 + if (null_seen) { \
Goetz@4798 899 + ReceiverTypeData::set_null_seen(MDX()); \
Goetz@4798 900 + } else { \
Goetz@4798 901 + /* Template interpreter doesn't increment count. */ \
Goetz@4798 902 + /* ReceiverTypeData::increment_count_no_overflow(MDX());*/ \
Goetz@4798 903 + ReceiverTypeData::increment_receiver_count_no_overflow(MDX(), receiver); \
Goetz@4798 904 + } \
Goetz@4798 905 + SET_MDX(ReceiverTypeData::advance(MDX())); \
Goetz@4798 906 + }
Goetz@4798 907 +
Goetz@4798 908 +
Goetz@4798 909 +// Updates profiling data for an instanceof (was a null seen? which receiver?).
Goetz@4798 910 +#define BI_PROFILE_UPDATE_INSTANCEOF(null_seen, receiver) \
Goetz@4798 911 + BI_PROFILE_UPDATE_CHECKCAST(null_seen, receiver)
Goetz@4798 912 +
Goetz@4798 913 +
Goetz@4798 914 +// Updates profiling data for a call.
Goetz@4798 915 +#define BI_PROFILE_UPDATE_CALL() \
Goetz@4798 916 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 917 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 918 + CounterData::increment_count_no_overflow(MDX()); \
Goetz@4798 919 + SET_MDX(CounterData::advance(MDX())); \
Goetz@4798 920 + }
Goetz@4798 921 +
Goetz@4798 922 +
Goetz@4798 923 +// Updates profiling data for a final call.
Goetz@4798 924 +#define BI_PROFILE_UPDATE_FINALCALL() \
Goetz@4798 925 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 926 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 927 + VirtualCallData::increment_count_no_overflow(MDX()); \
Goetz@4798 928 + SET_MDX(VirtualCallData::advance(MDX())); \
Goetz@4798 929 + }
Goetz@4798 930 +
Goetz@4798 931 +
Goetz@4798 932 +// Updates profiling data for a virtual call with given receiver Klass.
Goetz@4798 933 +#define BI_PROFILE_UPDATE_VIRTUALCALL(receiver) \
Goetz@4798 934 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 935 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 936 + VirtualCallData::increment_receiver_count_no_overflow(MDX(), receiver); \
Goetz@4798 937 + SET_MDX(VirtualCallData::advance(MDX())); \
Goetz@4798 938 + }
Goetz@4798 939 +
Goetz@4798 940 +
Goetz@4798 941 +// Updates profiling data for a switch (tabelswitch or lookupswitch) with
Goetz@4798 942 +// given taken index (-1 means default case was taken).
Goetz@4798 943 +#define BI_PROFILE_UPDATE_SWITCH(switch_index) \
Goetz@4798 944 + if (ProfileInterpreter && MDX() != NULL) { \
Goetz@4798 945 + BI_PROFILE_CHECK_MDX(); \
Goetz@4798 946 + MultiBranchData::increment_count_no_overflow(MDX(), switch_index); \
Goetz@4798 947 + SET_MDX(MultiBranchData::advance(MDX(), switch_index)); \
Goetz@4798 948 + }
Goetz@4798 949 +
Goetz@4798 950 +
Goetz@4798 951 +// The end /////////////////////////////////////////////////////////////////////
Goetz@4798 952 +
Goetz@4798 953 +#endif // CC_INTERP_PROFILE
Goetz@4798 954 +
Goetz@4798 955 +#endif // CC_INTERP
Goetz@4798 956 +
Goetz@4798 957 +#endif // SHARE_VM_INTERPRETER_BYTECODECINTERPRETERPROFILING_HPP
Goetz@4798 958 diff -r 84fd980e69ee src/share/vm/interpreter/interpreterRuntime.cpp
Goetz@4798 959 --- a/src/share/vm/interpreter/interpreterRuntime.cpp Fri Jun 07 12:50:21 2013 +0200
Goetz@4798 960 +++ b/src/share/vm/interpreter/interpreterRuntime.cpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 961 @@ -267,6 +267,49 @@
Goetz@4798 962 }
Goetz@4798 963 }
Goetz@4798 964
Goetz@4798 965 +#ifdef CC_INTERP
Goetz@4798 966 +// As legacy note_trap, but we have more arguments.
Goetz@4798 967 +IRT_ENTRY(void, InterpreterRuntime::note_trap(JavaThread* thread, int reason, Method *method, int trap_bci))
Goetz@4798 968 + methodHandle trap_method(method);
Goetz@4798 969 +
Goetz@4798 970 + // START derived from note_trap
Goetz@4798 971 + // passed as arg: methodHandle trap_method(thread, method(thread));
Goetz@4798 972 + if (trap_method.not_null()) {
Goetz@4798 973 + MethodData *trap_md = trap_method->method_data();
Goetz@4798 974 + if (trap_md == NULL) {
Goetz@4798 975 + Method::build_interpreter_method_data(trap_method, THREAD);
Goetz@4798 976 + if (HAS_PENDING_EXCEPTION) {
Goetz@4798 977 + assert((PENDING_EXCEPTION->is_a(SystemDictionary::OutOfMemoryError_klass())), "we expect only an OOM error here");
Goetz@4798 978 + CLEAR_PENDING_EXCEPTION;
Goetz@4798 979 + }
Goetz@4798 980 + trap_md = trap_method->method_data();
Goetz@4798 981 + // and fall through...
Goetz@4798 982 + }
Goetz@4798 983 + if (trap_md != NULL) {
Goetz@4798 984 + // Update per-method count of trap events. The interpreter
Goetz@4798 985 + // is updating the MDO to simulate the effect of compiler traps.
Goetz@4798 986 + // Passed as arg int trap_bci = trap_method->bci_from(bcp(thread));
Goetz@4798 987 + Deoptimization::update_method_data_from_interpreter(trap_md, trap_bci, reason);
Goetz@4798 988 + }
Goetz@4798 989 + }
Goetz@4798 990 + // END derived from note_trap
Goetz@4798 991 +IRT_END
Goetz@4798 992 +
Goetz@4798 993 +// Class Deoptimization is not visible in BytecodeInterpreter, so we need a wrapper
Goetz@4798 994 +// for each exception.
Goetz@4798 995 +void InterpreterRuntime::note_nullCheck_trap(JavaThread* thread, Method *method, int trap_bci)
Goetz@4798 996 + { if (ProfileTraps) note_trap(thread, Deoptimization::Reason_null_check, method, trap_bci); }
Goetz@4798 997 +void InterpreterRuntime::note_div0Check_trap(JavaThread* thread, Method *method, int trap_bci)
Goetz@4798 998 + { if (ProfileTraps) note_trap(thread, Deoptimization::Reason_div0_check, method, trap_bci); }
Goetz@4798 999 +void InterpreterRuntime::note_rangeCheck_trap(JavaThread* thread, Method *method, int trap_bci)
Goetz@4798 1000 + { if (ProfileTraps) note_trap(thread, Deoptimization::Reason_range_check, method, trap_bci); }
Goetz@4798 1001 +void InterpreterRuntime::note_classCheck_trap(JavaThread* thread, Method *method, int trap_bci)
Goetz@4798 1002 + { if (ProfileTraps) note_trap(thread, Deoptimization::Reason_class_check, method, trap_bci); }
Goetz@4798 1003 +void InterpreterRuntime::note_arrayCheck_trap(JavaThread* thread, Method *method, int trap_bci)
Goetz@4798 1004 + { if (ProfileTraps) note_trap(thread, Deoptimization::Reason_array_check, method, trap_bci); }
Goetz@4798 1005 +#endif // CC_INTERP
Goetz@4798 1006 +
Goetz@4798 1007 +
Goetz@4798 1008 static Handle get_preinitialized_exception(Klass* k, TRAPS) {
Goetz@4798 1009 // get klass
Goetz@4798 1010 InstanceKlass* klass = InstanceKlass::cast(k);
Goetz@4798 1011 diff -r 84fd980e69ee src/share/vm/interpreter/interpreterRuntime.hpp
Goetz@4798 1012 --- a/src/share/vm/interpreter/interpreterRuntime.hpp Fri Jun 07 12:50:21 2013 +0200
Goetz@4798 1013 +++ b/src/share/vm/interpreter/interpreterRuntime.hpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 1014 @@ -67,6 +67,10 @@
Goetz@4798 1015 static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i) { return method(thread)->constants()->cache()->entry_at(i); }
Goetz@4798 1016 static ConstantPoolCacheEntry* cache_entry(JavaThread *thread) { return cache_entry_at(thread, Bytes::get_native_u2(bcp(thread) + 1)); }
Goetz@4798 1017 static void note_trap(JavaThread *thread, int reason, TRAPS);
Goetz@4798 1018 +#ifdef CC_INTERP
Goetz@4798 1019 + // Profile traps in C++ interpreter.
Goetz@4798 1020 + static void note_trap(JavaThread* thread, int reason, Method *method, int trap_bci);
Goetz@4798 1021 +#endif // CC_INTERP
Goetz@4798 1022
Goetz@4798 1023 // Inner work method for Interpreter's frequency counter overflow
Goetz@4798 1024 static nmethod* frequency_counter_overflow_inner(JavaThread* thread, address branch_bcp);
Goetz@4798 1025 @@ -97,6 +101,17 @@
Goetz@4798 1026 static address exception_handler_for_exception(JavaThread* thread, oopDesc* exception);
Goetz@4798 1027 static void throw_pending_exception(JavaThread* thread);
Goetz@4798 1028
Goetz@4798 1029 +#ifdef CC_INTERP
Goetz@4798 1030 + // Profile traps in C++ interpreter
Goetz@4798 1031 + static void note_nullCheck_trap (JavaThread* thread, Method *method, int trap_bci);
Goetz@4798 1032 + static void note_div0Check_trap (JavaThread* thread, Method *method, int trap_bci);
Goetz@4798 1033 + static void note_rangeCheck_trap(JavaThread* thread, Method *method, int trap_bci);
Goetz@4798 1034 + static void note_classCheck_trap(JavaThread* thread, Method *method, int trap_bci);
Goetz@4798 1035 + static void note_arrayCheck_trap(JavaThread* thread, Method *method, int trap_bci);
Goetz@4798 1036 + // A dummy for makros that shall not profile traps
Goetz@4798 1037 + static void note_no_trap(JavaThread* thread, Method *method, int trap_bci) {}
Goetz@4798 1038 +#endif // CC_INTERP
Goetz@4798 1039 +
Goetz@4798 1040 // Statics & fields
Goetz@4798 1041 static void resolve_get_put(JavaThread* thread, Bytecodes::Code bytecode);
Goetz@4798 1042
Goetz@4798 1043 diff -r 84fd980e69ee src/share/vm/interpreter/invocationCounter.hpp
Goetz@4798 1044 --- a/src/share/vm/interpreter/invocationCounter.hpp Fri Jun 07 12:50:21 2013 +0200
Goetz@4798 1045 +++ b/src/share/vm/interpreter/invocationCounter.hpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 1046 @@ -101,13 +101,17 @@
Goetz@4798 1047
Goetz@4798 1048 // Test counter using scaled limits like the asm interpreter would do rather than doing
Goetz@4798 1049 // the shifts to normalize the counter.
Goetz@4798 1050 -
Goetz@4798 1051 - bool reached_InvocationLimit() const { return _counter >= (unsigned int) InterpreterInvocationLimit; }
Goetz@4798 1052 - bool reached_BackwardBranchLimit() const { return _counter >= (unsigned int) InterpreterBackwardBranchLimit; }
Goetz@4798 1053 + // Checks sum of invocation_counter and backedge_counter as the template interpreter does.
Goetz@4798 1054 + bool reached_InvocationLimit(InvocationCounter *back_edge_count) const {
Goetz@4798 1055 + return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >= (unsigned int) InterpreterInvocationLimit;
Goetz@4798 1056 + }
Goetz@4798 1057 + bool reached_BackwardBranchLimit(InvocationCounter *back_edge_count) const {
Goetz@4798 1058 + return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >= (unsigned int) InterpreterBackwardBranchLimit;
Goetz@4798 1059 + }
Goetz@4798 1060
Goetz@4798 1061 // Do this just like asm interpreter does for max speed
Goetz@4798 1062 - bool reached_ProfileLimit(InvocationCounter *back_edge_count) const {
Goetz@4798 1063 - return (_counter && count_mask) + back_edge_count->_counter >= (unsigned int) InterpreterProfileLimit;
Goetz@4798 1064 + bool reached_ProfileLimit(InvocationCounter *back_edge_count) const {
Goetz@4798 1065 + return (_counter & count_mask) + (back_edge_count->_counter & count_mask) >= (unsigned int) InterpreterProfileLimit;
Goetz@4798 1066 }
Goetz@4798 1067
Goetz@4798 1068 void increment() { _counter += count_increment; }
Goetz@4798 1069 diff -r 84fd980e69ee src/share/vm/oops/methodData.cpp
Goetz@4798 1070 --- a/src/share/vm/oops/methodData.cpp Fri Jun 07 12:50:21 2013 +0200
Goetz@4798 1071 +++ b/src/share/vm/oops/methodData.cpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 1072 @@ -244,6 +244,11 @@
Goetz@4798 1073 return mdp;
Goetz@4798 1074 }
Goetz@4798 1075
Goetz@4798 1076 +#ifdef CC_INTERP
Goetz@4798 1077 +DataLayout* RetData::advance(MethodData *md, int bci) {
Goetz@4798 1078 + return (DataLayout*) md->bci_to_dp(bci);
Goetz@4798 1079 +}
Goetz@4798 1080 +#endif // CC_INTERP
Goetz@4798 1081
Goetz@4798 1082 #ifndef PRODUCT
Goetz@4798 1083 void RetData::print_data_on(outputStream* st) {
Goetz@4798 1084 diff -r 84fd980e69ee src/share/vm/oops/methodData.hpp
Goetz@4798 1085 --- a/src/share/vm/oops/methodData.hpp Fri Jun 07 12:50:21 2013 +0200
Goetz@4798 1086 +++ b/src/share/vm/oops/methodData.hpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 1087 @@ -225,6 +225,11 @@
Goetz@4798 1088 static ByteSize cell_offset(int index) {
Goetz@4798 1089 return byte_offset_of(DataLayout, _cells) + in_ByteSize(index * cell_size);
Goetz@4798 1090 }
Goetz@4798 1091 +#ifdef CC_INTERP
Goetz@4798 1092 + static int cell_offset_in_bytes(int index) {
Goetz@4798 1093 + return (int)offset_of(DataLayout, _cells[index]);
Goetz@4798 1094 + }
Goetz@4798 1095 +#endif // CC_INTERP
Goetz@4798 1096 // Return a value which, when or-ed as a byte into _flags, sets the flag.
Goetz@4798 1097 static int flag_number_to_byte_constant(int flag_number) {
Goetz@4798 1098 assert(0 <= flag_number && flag_number < flag_limit, "oob");
Goetz@4798 1099 @@ -356,6 +361,41 @@
Goetz@4798 1100 _data = data;
Goetz@4798 1101 }
Goetz@4798 1102
Goetz@4798 1103 +#ifdef CC_INTERP
Goetz@4798 1104 + // Static low level accessors for DataLayout with ProfileData's semantics.
Goetz@4798 1105 +
Goetz@4798 1106 + static int cell_offset_in_bytes(int index) {
Goetz@4798 1107 + return DataLayout::cell_offset_in_bytes(index);
Goetz@4798 1108 + }
Goetz@4798 1109 +
Goetz@4798 1110 + static void increment_uint_at_no_overflow(DataLayout* layout, int index,
Goetz@4798 1111 + int inc = DataLayout::counter_increment) {
Goetz@4798 1112 + uint count = ((uint)layout->cell_at(index)) + inc;
Goetz@4798 1113 + if (count == 0) return;
Goetz@4798 1114 + layout->set_cell_at(index, (intptr_t) count);
Goetz@4798 1115 + }
Goetz@4798 1116 +
Goetz@4798 1117 + static int int_at(DataLayout* layout, int index) {
Goetz@4798 1118 + return (int)layout->cell_at(index);
Goetz@4798 1119 + }
Goetz@4798 1120 +
Goetz@4798 1121 + static int uint_at(DataLayout* layout, int index) {
Goetz@4798 1122 + return (uint)layout->cell_at(index);
Goetz@4798 1123 + }
Goetz@4798 1124 +
Goetz@4798 1125 + static oop oop_at(DataLayout* layout, int index) {
Goetz@4798 1126 + return (oop)layout->cell_at(index);
Goetz@4798 1127 + }
Goetz@4798 1128 +
Goetz@4798 1129 + static void set_intptr_at(DataLayout* layout, int index, intptr_t value) {
Goetz@4798 1130 + layout->set_cell_at(index, (intptr_t) value);
Goetz@4798 1131 + }
Goetz@4798 1132 +
Goetz@4798 1133 + static void set_flag_at(DataLayout* layout, int flag_number) {
Goetz@4798 1134 + layout->set_flag_at(flag_number);
Goetz@4798 1135 + }
Goetz@4798 1136 +#endif // CC_INTERP
Goetz@4798 1137 +
Goetz@4798 1138 public:
Goetz@4798 1139 // Constructor for invalid ProfileData.
Goetz@4798 1140 ProfileData();
Goetz@4798 1141 @@ -495,6 +535,20 @@
Goetz@4798 1142 return cell_offset(bit_cell_count);
Goetz@4798 1143 }
Goetz@4798 1144
Goetz@4798 1145 +#ifdef CC_INTERP
Goetz@4798 1146 + static int bit_data_size_in_bytes() {
Goetz@4798 1147 + return cell_offset_in_bytes(bit_cell_count);
Goetz@4798 1148 + }
Goetz@4798 1149 +
Goetz@4798 1150 + static void set_null_seen(DataLayout* layout) {
Goetz@4798 1151 + set_flag_at(layout, null_seen_flag);
Goetz@4798 1152 + }
Goetz@4798 1153 +
Goetz@4798 1154 + static DataLayout* advance(DataLayout* layout) {
Goetz@4798 1155 + return (DataLayout*) (((address)layout) + (ssize_t)BitData::bit_data_size_in_bytes());
Goetz@4798 1156 + }
Goetz@4798 1157 +#endif // CC_INTERP
Goetz@4798 1158 +
Goetz@4798 1159 #ifndef PRODUCT
Goetz@4798 1160 void print_data_on(outputStream* st);
Goetz@4798 1161 #endif
Goetz@4798 1162 @@ -539,6 +593,25 @@
Goetz@4798 1163 set_uint_at(count_off, count);
Goetz@4798 1164 }
Goetz@4798 1165
Goetz@4798 1166 +#ifdef CC_INTERP
Goetz@4798 1167 + static int counter_data_size_in_bytes() {
Goetz@4798 1168 + return cell_offset_in_bytes(counter_cell_count);
Goetz@4798 1169 + }
Goetz@4798 1170 +
Goetz@4798 1171 + static void increment_count_no_overflow(DataLayout* layout) {
Goetz@4798 1172 + increment_uint_at_no_overflow(layout, count_off);
Goetz@4798 1173 + }
Goetz@4798 1174 +
Goetz@4798 1175 + // Support counter decrementation at checkcast / subtype check failed
Goetz@4798 1176 + static void decrement_count(DataLayout* layout) {
Goetz@4798 1177 + increment_uint_at_no_overflow(layout, count_off, -1);
Goetz@4798 1178 + }
Goetz@4798 1179 +
Goetz@4798 1180 + static DataLayout* advance(DataLayout* layout) {
Goetz@4798 1181 + return (DataLayout*) (((address)layout) + (ssize_t)CounterData::counter_data_size_in_bytes());
Goetz@4798 1182 + }
Goetz@4798 1183 +#endif // CC_INTERP
Goetz@4798 1184 +
Goetz@4798 1185 #ifndef PRODUCT
Goetz@4798 1186 void print_data_on(outputStream* st);
Goetz@4798 1187 #endif
Goetz@4798 1188 @@ -609,6 +682,20 @@
Goetz@4798 1189 return cell_offset(displacement_off_set);
Goetz@4798 1190 }
Goetz@4798 1191
Goetz@4798 1192 +#ifdef CC_INTERP
Goetz@4798 1193 + static void increment_taken_count_no_overflow(DataLayout* layout) {
Goetz@4798 1194 + increment_uint_at_no_overflow(layout, taken_off_set);
Goetz@4798 1195 + }
Goetz@4798 1196 +
Goetz@4798 1197 + static DataLayout* advance_taken(DataLayout* layout) {
Goetz@4798 1198 + return (DataLayout*) (((address)layout) + (ssize_t)int_at(layout, displacement_off_set));
Goetz@4798 1199 + }
Goetz@4798 1200 +
Goetz@4798 1201 + static uint taken_count(DataLayout* layout) {
Goetz@4798 1202 + return (uint) uint_at(layout, taken_off_set);
Goetz@4798 1203 + }
Goetz@4798 1204 +#endif // CC_INTERP
Goetz@4798 1205 +
Goetz@4798 1206 // Specific initialization.
Goetz@4798 1207 void post_initialize(BytecodeStream* stream, MethodData* mdo);
Goetz@4798 1208
Goetz@4798 1209 @@ -718,6 +805,43 @@
Goetz@4798 1210 // GC support
Goetz@4798 1211 virtual void clean_weak_klass_links(BoolObjectClosure* is_alive_closure);
Goetz@4798 1212
Goetz@4798 1213 +#ifdef CC_INTERP
Goetz@4798 1214 + static int receiver_type_data_size_in_bytes() {
Goetz@4798 1215 + return cell_offset_in_bytes(static_cell_count());
Goetz@4798 1216 + }
Goetz@4798 1217 +
Goetz@4798 1218 + static Klass *receiver_unchecked(DataLayout* layout, uint row) {
Goetz@4798 1219 + oop recv = oop_at(layout, receiver_cell_index(row));
Goetz@4798 1220 + return (Klass *)recv;
Goetz@4798 1221 + }
Goetz@4798 1222 +
Goetz@4798 1223 + static void increment_receiver_count_no_overflow(DataLayout* layout, Klass *rcvr) {
Goetz@4798 1224 + const int num_rows = row_limit();
Goetz@4798 1225 + // Receiver already exists?
Goetz@4798 1226 + for (int row = 0; row < num_rows; row++) {
Goetz@4798 1227 + if (receiver_unchecked(layout, row) == rcvr) {
Goetz@4798 1228 + increment_uint_at_no_overflow(layout, receiver_count_cell_index(row));
Goetz@4798 1229 + return;
Goetz@4798 1230 + }
Goetz@4798 1231 + }
Goetz@4798 1232 + // New receiver, find a free slot.
Goetz@4798 1233 + for (int row = 0; row < num_rows; row++) {
Goetz@4798 1234 + if (receiver_unchecked(layout, row) == NULL) {
Goetz@4798 1235 + set_intptr_at(layout, receiver_cell_index(row), (intptr_t)rcvr);
Goetz@4798 1236 + increment_uint_at_no_overflow(layout, receiver_count_cell_index(row));
Goetz@4798 1237 + return;
Goetz@4798 1238 + }
Goetz@4798 1239 + }
Goetz@4798 1240 + // Receiver did not match any saved receiver and there is no empty row for it.
Goetz@4798 1241 + // Increment total counter to indicate polymorphic case.
Goetz@4798 1242 + increment_count_no_overflow(layout);
Goetz@4798 1243 + }
Goetz@4798 1244 +
Goetz@4798 1245 + static DataLayout* advance(DataLayout* layout) {
Goetz@4798 1246 + return (DataLayout*) (((address)layout) + (ssize_t)ReceiverTypeData::receiver_type_data_size_in_bytes());
Goetz@4798 1247 + }
Goetz@4798 1248 +#endif // CC_INTERP
Goetz@4798 1249 +
Goetz@4798 1250 #ifndef PRODUCT
Goetz@4798 1251 void print_receiver_data_on(outputStream* st);
Goetz@4798 1252 void print_data_on(outputStream* st);
Goetz@4798 1253 @@ -751,6 +875,16 @@
Goetz@4798 1254 return cell_offset(static_cell_count());
Goetz@4798 1255 }
Goetz@4798 1256
Goetz@4798 1257 +#ifdef CC_INTERP
Goetz@4798 1258 + static int virtual_call_data_size_in_bytes() {
Goetz@4798 1259 + return cell_offset_in_bytes(static_cell_count());
Goetz@4798 1260 + }
Goetz@4798 1261 +
Goetz@4798 1262 + static DataLayout* advance(DataLayout* layout) {
Goetz@4798 1263 + return (DataLayout*) (((address)layout) + (ssize_t)VirtualCallData::virtual_call_data_size_in_bytes());
Goetz@4798 1264 + }
Goetz@4798 1265 +#endif // CC_INTERP
Goetz@4798 1266 +
Goetz@4798 1267 #ifndef PRODUCT
Goetz@4798 1268 void print_data_on(outputStream* st);
Goetz@4798 1269 #endif
Goetz@4798 1270 @@ -847,6 +981,10 @@
Goetz@4798 1271 return cell_offset(bci_displacement_cell_index(row));
Goetz@4798 1272 }
Goetz@4798 1273
Goetz@4798 1274 +#ifdef CC_INTERP
Goetz@4798 1275 + static DataLayout* advance(MethodData *md, int bci);
Goetz@4798 1276 +#endif // CC_INTERP
Goetz@4798 1277 +
Goetz@4798 1278 // Specific initialization.
Goetz@4798 1279 void post_initialize(BytecodeStream* stream, MethodData* mdo);
Goetz@4798 1280
Goetz@4798 1281 @@ -911,6 +1049,20 @@
Goetz@4798 1282 return cell_offset(branch_cell_count);
Goetz@4798 1283 }
Goetz@4798 1284
Goetz@4798 1285 +#ifdef CC_INTERP
Goetz@4798 1286 + static int branch_data_size_in_bytes() {
Goetz@4798 1287 + return cell_offset_in_bytes(branch_cell_count);
Goetz@4798 1288 + }
Goetz@4798 1289 +
Goetz@4798 1290 + static void increment_not_taken_count_no_overflow(DataLayout* layout) {
Goetz@4798 1291 + increment_uint_at_no_overflow(layout, not_taken_off_set);
Goetz@4798 1292 + }
Goetz@4798 1293 +
Goetz@4798 1294 + static DataLayout* advance_not_taken(DataLayout* layout) {
Goetz@4798 1295 + return (DataLayout*) (((address)layout) + (ssize_t)BranchData::branch_data_size_in_bytes());
Goetz@4798 1296 + }
Goetz@4798 1297 +#endif // CC_INTERP
Goetz@4798 1298 +
Goetz@4798 1299 // Specific initialization.
Goetz@4798 1300 void post_initialize(BytecodeStream* stream, MethodData* mdo);
Goetz@4798 1301
Goetz@4798 1302 @@ -950,6 +1102,20 @@
Goetz@4798 1303 set_int_at(aindex, value);
Goetz@4798 1304 }
Goetz@4798 1305
Goetz@4798 1306 +#ifdef CC_INTERP
Goetz@4798 1307 + // Static low level accessors for DataLayout with ArrayData's semantics.
Goetz@4798 1308 +
Goetz@4798 1309 + static void increment_array_uint_at_no_overflow(DataLayout* layout, int index) {
Goetz@4798 1310 + int aindex = index + array_start_off_set;
Goetz@4798 1311 + increment_uint_at_no_overflow(layout, aindex);
Goetz@4798 1312 + }
Goetz@4798 1313 +
Goetz@4798 1314 + static int array_int_at(DataLayout* layout, int index) {
Goetz@4798 1315 + int aindex = index + array_start_off_set;
Goetz@4798 1316 + return int_at(layout, aindex);
Goetz@4798 1317 + }
Goetz@4798 1318 +#endif // CC_INTERP
Goetz@4798 1319 +
Goetz@4798 1320 // Code generation support for subclasses.
Goetz@4798 1321 static ByteSize array_element_offset(int index) {
Goetz@4798 1322 return cell_offset(array_start_off_set + index);
Goetz@4798 1323 @@ -1068,6 +1234,28 @@
Goetz@4798 1324 return in_ByteSize(relative_displacement_off_set) * cell_size;
Goetz@4798 1325 }
Goetz@4798 1326
Goetz@4798 1327 +#ifdef CC_INTERP
Goetz@4798 1328 + static void increment_count_no_overflow(DataLayout* layout, int index) {
Goetz@4798 1329 + if (index == -1) {
Goetz@4798 1330 + increment_array_uint_at_no_overflow(layout, default_count_off_set);
Goetz@4798 1331 + } else {
Goetz@4798 1332 + increment_array_uint_at_no_overflow(layout, case_array_start +
Goetz@4798 1333 + index * per_case_cell_count +
Goetz@4798 1334 + relative_count_off_set);
Goetz@4798 1335 + }
Goetz@4798 1336 + }
Goetz@4798 1337 +
Goetz@4798 1338 + static DataLayout* advance(DataLayout* layout, int index) {
Goetz@4798 1339 + if (index == -1) {
Goetz@4798 1340 + return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, default_disaplacement_off_set));
Goetz@4798 1341 + } else {
Goetz@4798 1342 + return (DataLayout*) (((address)layout) + (ssize_t)array_int_at(layout, case_array_start +
Goetz@4798 1343 + index * per_case_cell_count +
Goetz@4798 1344 + relative_displacement_off_set));
Goetz@4798 1345 + }
Goetz@4798 1346 + }
Goetz@4798 1347 +#endif // CC_INTERP
Goetz@4798 1348 +
Goetz@4798 1349 // Specific initialization.
Goetz@4798 1350 void post_initialize(BytecodeStream* stream, MethodData* mdo);
Goetz@4798 1351
Goetz@4798 1352 @@ -1146,8 +1334,11 @@
Goetz@4798 1353 // adjusted in the event of a change in control flow.
Goetz@4798 1354 //
Goetz@4798 1355
Goetz@4798 1356 +CC_INTERP_ONLY(class BytecodeInterpreter;)
Goetz@4798 1357 +
Goetz@4798 1358 class MethodData : public Metadata {
Goetz@4798 1359 friend class VMStructs;
Goetz@4798 1360 + CC_INTERP_ONLY(friend class BytecodeInterpreter;)
Goetz@4798 1361 private:
Goetz@4798 1362 friend class ProfileData;
Goetz@4798 1363
Goetz@4798 1364 diff -r 84fd980e69ee src/share/vm/runtime/arguments.cpp
Goetz@4798 1365 --- a/src/share/vm/runtime/arguments.cpp Fri Jun 07 12:50:21 2013 +0200
Goetz@4798 1366 +++ b/src/share/vm/runtime/arguments.cpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 1367 @@ -3578,10 +3578,10 @@
Goetz@4798 1368 // Clear flags not supported by the C++ interpreter
Goetz@4798 1369 #if !defined(PPC64)
Goetz@4798 1370 FLAG_SET_DEFAULT(UseBiasedLocking, false);
Goetz@4798 1371 + FLAG_SET_DEFAULT(ProfileInterpreter, false);
Goetz@4798 1372 LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedOops, false));
Goetz@4798 1373 LP64_ONLY(FLAG_SET_DEFAULT(UseCompressedKlassPointers, false));
Goetz@4798 1374 #endif // !PPC64
Goetz@4798 1375 - FLAG_SET_DEFAULT(ProfileInterpreter, false);
Goetz@4798 1376 #endif // CC_INTERP
Goetz@4798 1377
Goetz@4798 1378 #ifdef COMPILER2
Goetz@4798 1379 diff -r 84fd980e69ee src/share/vm/runtime/globals.hpp
Goetz@4798 1380 --- a/src/share/vm/runtime/globals.hpp Fri Jun 07 12:50:21 2013 +0200
Goetz@4798 1381 +++ b/src/share/vm/runtime/globals.hpp Fri Jun 07 12:51:22 2013 +0200
Goetz@4798 1382 @@ -2708,6 +2708,9 @@
Goetz@4798 1383 product_pd(bool, ProfileInterpreter, \
Goetz@4798 1384 "Profile at the bytecode level during interpretation") \
Goetz@4798 1385 \
Goetz@4798 1386 + develop(bool, TraceProfileInterpreter, false, \
Goetz@4798 1387 + "Trace profiling at the bytecode level during interpretation") \
Goetz@4798 1388 + \
Goetz@4798 1389 develop_pd(bool, ProfileTraps, \
Goetz@4798 1390 "Profile deoptimization traps at the bytecode level") \
Goetz@4798 1391 \