annotate ppc_patches/0201_C_interpreter-implement_bytecode_profiling.patch @ 4881:edf2bb42e70f

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