Mercurial > hg > truffle
annotate src/share/vm/interpreter/bytecodeInterpreter.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | 9fae07c31641 |
children | e60b3fce2b02 |
rev | line source |
---|---|
0 | 1 /* |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2 * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1513
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 // no precompiled headers |
26 #include "classfile/vmSymbols.hpp" | |
27 #include "gc_interface/collectedHeap.hpp" | |
28 #include "interpreter/bytecodeHistogram.hpp" | |
29 #include "interpreter/bytecodeInterpreter.hpp" | |
30 #include "interpreter/bytecodeInterpreter.inline.hpp" | |
31 #include "interpreter/interpreter.hpp" | |
32 #include "interpreter/interpreterRuntime.hpp" | |
33 #include "memory/cardTableModRefBS.hpp" | |
34 #include "memory/resourceArea.hpp" | |
35 #include "oops/objArrayKlass.hpp" | |
36 #include "oops/oop.inline.hpp" | |
37 #include "prims/jvmtiExport.hpp" | |
38 #include "runtime/frame.inline.hpp" | |
39 #include "runtime/handles.inline.hpp" | |
40 #include "runtime/interfaceSupport.hpp" | |
41 #include "runtime/sharedRuntime.hpp" | |
42 #include "runtime/threadCritical.hpp" | |
43 #include "utilities/exceptions.hpp" | |
44 #ifdef TARGET_OS_ARCH_linux_x86 | |
45 # include "orderAccess_linux_x86.inline.hpp" | |
46 #endif | |
47 #ifdef TARGET_OS_ARCH_linux_sparc | |
48 # include "orderAccess_linux_sparc.inline.hpp" | |
49 #endif | |
50 #ifdef TARGET_OS_ARCH_linux_zero | |
51 # include "orderAccess_linux_zero.inline.hpp" | |
52 #endif | |
53 #ifdef TARGET_OS_ARCH_solaris_x86 | |
54 # include "orderAccess_solaris_x86.inline.hpp" | |
55 #endif | |
56 #ifdef TARGET_OS_ARCH_solaris_sparc | |
57 # include "orderAccess_solaris_sparc.inline.hpp" | |
58 #endif | |
59 #ifdef TARGET_OS_ARCH_windows_x86 | |
60 # include "orderAccess_windows_x86.inline.hpp" | |
61 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
62 #ifdef TARGET_OS_ARCH_linux_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
63 # include "orderAccess_linux_arm.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
64 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
65 #ifdef TARGET_OS_ARCH_linux_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
66 # include "orderAccess_linux_ppc.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2142
diff
changeset
|
67 #endif |
3960 | 68 #ifdef TARGET_OS_ARCH_bsd_x86 |
69 # include "orderAccess_bsd_x86.inline.hpp" | |
70 #endif | |
71 #ifdef TARGET_OS_ARCH_bsd_zero | |
72 # include "orderAccess_bsd_zero.inline.hpp" | |
73 #endif | |
1972 | 74 |
0 | 75 |
76 // no precompiled headers | |
77 #ifdef CC_INTERP | |
78 | |
79 /* | |
80 * USELABELS - If using GCC, then use labels for the opcode dispatching | |
81 * rather -then a switch statement. This improves performance because it | |
82 * gives us the oportunity to have the instructions that calculate the | |
83 * next opcode to jump to be intermixed with the rest of the instructions | |
84 * that implement the opcode (see UPDATE_PC_AND_TOS_AND_CONTINUE macro). | |
85 */ | |
86 #undef USELABELS | |
87 #ifdef __GNUC__ | |
88 /* | |
89 ASSERT signifies debugging. It is much easier to step thru bytecodes if we | |
90 don't use the computed goto approach. | |
91 */ | |
92 #ifndef ASSERT | |
93 #define USELABELS | |
94 #endif | |
95 #endif | |
96 | |
97 #undef CASE | |
98 #ifdef USELABELS | |
99 #define CASE(opcode) opc ## opcode | |
100 #define DEFAULT opc_default | |
101 #else | |
102 #define CASE(opcode) case Bytecodes:: opcode | |
103 #define DEFAULT default | |
104 #endif | |
105 | |
106 /* | |
107 * PREFETCH_OPCCODE - Some compilers do better if you prefetch the next | |
108 * opcode before going back to the top of the while loop, rather then having | |
109 * the top of the while loop handle it. This provides a better opportunity | |
110 * for instruction scheduling. Some compilers just do this prefetch | |
111 * automatically. Some actually end up with worse performance if you | |
112 * force the prefetch. Solaris gcc seems to do better, but cc does worse. | |
113 */ | |
114 #undef PREFETCH_OPCCODE | |
115 #define PREFETCH_OPCCODE | |
116 | |
117 /* | |
118 Interpreter safepoint: it is expected that the interpreter will have no live | |
119 handles of its own creation live at an interpreter safepoint. Therefore we | |
120 run a HandleMarkCleaner and trash all handles allocated in the call chain | |
121 since the JavaCalls::call_helper invocation that initiated the chain. | |
122 There really shouldn't be any handles remaining to trash but this is cheap | |
123 in relation to a safepoint. | |
124 */ | |
125 #define SAFEPOINT \ | |
126 if ( SafepointSynchronize::is_synchronizing()) { \ | |
127 { \ | |
128 /* zap freed handles rather than GC'ing them */ \ | |
129 HandleMarkCleaner __hmc(THREAD); \ | |
130 } \ | |
131 CALL_VM(SafepointSynchronize::block(THREAD), handle_exception); \ | |
132 } | |
133 | |
134 /* | |
135 * VM_JAVA_ERROR - Macro for throwing a java exception from | |
136 * the interpreter loop. Should really be a CALL_VM but there | |
137 * is no entry point to do the transition to vm so we just | |
138 * do it by hand here. | |
139 */ | |
140 #define VM_JAVA_ERROR_NO_JUMP(name, msg) \ | |
141 DECACHE_STATE(); \ | |
142 SET_LAST_JAVA_FRAME(); \ | |
143 { \ | |
144 ThreadInVMfromJava trans(THREAD); \ | |
145 Exceptions::_throw_msg(THREAD, __FILE__, __LINE__, name, msg); \ | |
146 } \ | |
147 RESET_LAST_JAVA_FRAME(); \ | |
148 CACHE_STATE(); | |
149 | |
150 // Normal throw of a java error | |
151 #define VM_JAVA_ERROR(name, msg) \ | |
152 VM_JAVA_ERROR_NO_JUMP(name, msg) \ | |
153 goto handle_exception; | |
154 | |
155 #ifdef PRODUCT | |
156 #define DO_UPDATE_INSTRUCTION_COUNT(opcode) | |
157 #else | |
158 #define DO_UPDATE_INSTRUCTION_COUNT(opcode) \ | |
159 { \ | |
160 BytecodeCounter::_counter_value++; \ | |
161 BytecodeHistogram::_counters[(Bytecodes::Code)opcode]++; \ | |
162 if (StopInterpreterAt && StopInterpreterAt == BytecodeCounter::_counter_value) os::breakpoint(); \ | |
163 if (TraceBytecodes) { \ | |
164 CALL_VM((void)SharedRuntime::trace_bytecode(THREAD, 0, \ | |
165 topOfStack[Interpreter::expr_index_at(1)], \ | |
166 topOfStack[Interpreter::expr_index_at(2)]), \ | |
167 handle_exception); \ | |
168 } \ | |
169 } | |
170 #endif | |
171 | |
172 #undef DEBUGGER_SINGLE_STEP_NOTIFY | |
173 #ifdef VM_JVMTI | |
174 /* NOTE: (kbr) This macro must be called AFTER the PC has been | |
175 incremented. JvmtiExport::at_single_stepping_point() may cause a | |
176 breakpoint opcode to get inserted at the current PC to allow the | |
177 debugger to coalesce single-step events. | |
178 | |
179 As a result if we call at_single_stepping_point() we refetch opcode | |
180 to get the current opcode. This will override any other prefetching | |
181 that might have occurred. | |
182 */ | |
183 #define DEBUGGER_SINGLE_STEP_NOTIFY() \ | |
184 { \ | |
185 if (_jvmti_interp_events) { \ | |
186 if (JvmtiExport::should_post_single_step()) { \ | |
187 DECACHE_STATE(); \ | |
188 SET_LAST_JAVA_FRAME(); \ | |
189 ThreadInVMfromJava trans(THREAD); \ | |
190 JvmtiExport::at_single_stepping_point(THREAD, \ | |
191 istate->method(), \ | |
192 pc); \ | |
193 RESET_LAST_JAVA_FRAME(); \ | |
194 CACHE_STATE(); \ | |
195 if (THREAD->pop_frame_pending() && \ | |
196 !THREAD->pop_frame_in_process()) { \ | |
197 goto handle_Pop_Frame; \ | |
198 } \ | |
199 opcode = *pc; \ | |
200 } \ | |
201 } \ | |
202 } | |
203 #else | |
204 #define DEBUGGER_SINGLE_STEP_NOTIFY() | |
205 #endif | |
206 | |
207 /* | |
208 * CONTINUE - Macro for executing the next opcode. | |
209 */ | |
210 #undef CONTINUE | |
211 #ifdef USELABELS | |
212 // Have to do this dispatch this way in C++ because otherwise gcc complains about crossing an | |
213 // initialization (which is is the initialization of the table pointer...) | |
520
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
196
diff
changeset
|
214 #define DISPATCH(opcode) goto *(void*)dispatch_table[opcode] |
0 | 215 #define CONTINUE { \ |
216 opcode = *pc; \ | |
217 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
218 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
219 DISPATCH(opcode); \ | |
220 } | |
221 #else | |
222 #ifdef PREFETCH_OPCCODE | |
223 #define CONTINUE { \ | |
224 opcode = *pc; \ | |
225 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
226 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
227 continue; \ | |
228 } | |
229 #else | |
230 #define CONTINUE { \ | |
231 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
232 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
233 continue; \ | |
234 } | |
235 #endif | |
236 #endif | |
237 | |
238 | |
239 #define UPDATE_PC(opsize) {pc += opsize; } | |
240 /* | |
241 * UPDATE_PC_AND_TOS - Macro for updating the pc and topOfStack. | |
242 */ | |
243 #undef UPDATE_PC_AND_TOS | |
244 #define UPDATE_PC_AND_TOS(opsize, stack) \ | |
245 {pc += opsize; MORE_STACK(stack); } | |
246 | |
247 /* | |
248 * UPDATE_PC_AND_TOS_AND_CONTINUE - Macro for updating the pc and topOfStack, | |
249 * and executing the next opcode. It's somewhat similar to the combination | |
250 * of UPDATE_PC_AND_TOS and CONTINUE, but with some minor optimizations. | |
251 */ | |
252 #undef UPDATE_PC_AND_TOS_AND_CONTINUE | |
253 #ifdef USELABELS | |
254 #define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ | |
255 pc += opsize; opcode = *pc; MORE_STACK(stack); \ | |
256 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
257 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
258 DISPATCH(opcode); \ | |
259 } | |
260 | |
261 #define UPDATE_PC_AND_CONTINUE(opsize) { \ | |
262 pc += opsize; opcode = *pc; \ | |
263 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
264 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
265 DISPATCH(opcode); \ | |
266 } | |
267 #else | |
268 #ifdef PREFETCH_OPCCODE | |
269 #define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ | |
270 pc += opsize; opcode = *pc; MORE_STACK(stack); \ | |
271 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
272 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
273 goto do_continue; \ | |
274 } | |
275 | |
276 #define UPDATE_PC_AND_CONTINUE(opsize) { \ | |
277 pc += opsize; opcode = *pc; \ | |
278 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
279 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
280 goto do_continue; \ | |
281 } | |
282 #else | |
283 #define UPDATE_PC_AND_TOS_AND_CONTINUE(opsize, stack) { \ | |
284 pc += opsize; MORE_STACK(stack); \ | |
285 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
286 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
287 goto do_continue; \ | |
288 } | |
289 | |
290 #define UPDATE_PC_AND_CONTINUE(opsize) { \ | |
291 pc += opsize; \ | |
292 DO_UPDATE_INSTRUCTION_COUNT(opcode); \ | |
293 DEBUGGER_SINGLE_STEP_NOTIFY(); \ | |
294 goto do_continue; \ | |
295 } | |
296 #endif /* PREFETCH_OPCCODE */ | |
297 #endif /* USELABELS */ | |
298 | |
299 // About to call a new method, update the save the adjusted pc and return to frame manager | |
300 #define UPDATE_PC_AND_RETURN(opsize) \ | |
301 DECACHE_TOS(); \ | |
302 istate->set_bcp(pc+opsize); \ | |
303 return; | |
304 | |
305 | |
306 #define METHOD istate->method() | |
307 #define INVOCATION_COUNT METHOD->invocation_counter() | |
308 #define BACKEDGE_COUNT METHOD->backedge_counter() | |
309 | |
310 | |
311 #define INCR_INVOCATION_COUNT INVOCATION_COUNT->increment() | |
312 #define OSR_REQUEST(res, branch_pc) \ | |
313 CALL_VM(res=InterpreterRuntime::frequency_counter_overflow(THREAD, branch_pc), handle_exception); | |
314 /* | |
315 * For those opcodes that need to have a GC point on a backwards branch | |
316 */ | |
317 | |
318 // Backedge counting is kind of strange. The asm interpreter will increment | |
319 // the backedge counter as a separate counter but it does it's comparisons | |
320 // to the sum (scaled) of invocation counter and backedge count to make | |
321 // a decision. Seems kind of odd to sum them together like that | |
322 | |
323 // skip is delta from current bcp/bci for target, branch_pc is pre-branch bcp | |
324 | |
325 | |
326 #define DO_BACKEDGE_CHECKS(skip, branch_pc) \ | |
327 if ((skip) <= 0) { \ | |
1078 | 328 if (UseLoopCounter) { \ |
0 | 329 bool do_OSR = UseOnStackReplacement; \ |
330 BACKEDGE_COUNT->increment(); \ | |
331 if (do_OSR) do_OSR = BACKEDGE_COUNT->reached_InvocationLimit(); \ | |
332 if (do_OSR) { \ | |
333 nmethod* osr_nmethod; \ | |
334 OSR_REQUEST(osr_nmethod, branch_pc); \ | |
335 if (osr_nmethod != NULL && osr_nmethod->osr_entry_bci() != InvalidOSREntryBci) { \ | |
1078 | 336 intptr_t* buf = SharedRuntime::OSR_migration_begin(THREAD); \ |
0 | 337 istate->set_msg(do_osr); \ |
338 istate->set_osr_buf((address)buf); \ | |
339 istate->set_osr_entry(osr_nmethod->osr_entry()); \ | |
340 return; \ | |
341 } \ | |
342 } \ | |
343 } /* UseCompiler ... */ \ | |
344 INCR_INVOCATION_COUNT; \ | |
345 SAFEPOINT; \ | |
346 } | |
347 | |
348 /* | |
349 * For those opcodes that need to have a GC point on a backwards branch | |
350 */ | |
351 | |
352 /* | |
353 * Macros for caching and flushing the interpreter state. Some local | |
354 * variables need to be flushed out to the frame before we do certain | |
355 * things (like pushing frames or becomming gc safe) and some need to | |
356 * be recached later (like after popping a frame). We could use one | |
357 * macro to cache or decache everything, but this would be less then | |
358 * optimal because we don't always need to cache or decache everything | |
359 * because some things we know are already cached or decached. | |
360 */ | |
361 #undef DECACHE_TOS | |
362 #undef CACHE_TOS | |
363 #undef CACHE_PREV_TOS | |
364 #define DECACHE_TOS() istate->set_stack(topOfStack); | |
365 | |
366 #define CACHE_TOS() topOfStack = (intptr_t *)istate->stack(); | |
367 | |
368 #undef DECACHE_PC | |
369 #undef CACHE_PC | |
370 #define DECACHE_PC() istate->set_bcp(pc); | |
371 #define CACHE_PC() pc = istate->bcp(); | |
372 #define CACHE_CP() cp = istate->constants(); | |
373 #define CACHE_LOCALS() locals = istate->locals(); | |
374 #undef CACHE_FRAME | |
375 #define CACHE_FRAME() | |
376 | |
377 /* | |
378 * CHECK_NULL - Macro for throwing a NullPointerException if the object | |
379 * passed is a null ref. | |
380 * On some architectures/platforms it should be possible to do this implicitly | |
381 */ | |
382 #undef CHECK_NULL | |
383 #define CHECK_NULL(obj_) \ | |
520
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
196
diff
changeset
|
384 if ((obj_) == NULL) { \ |
0 | 385 VM_JAVA_ERROR(vmSymbols::java_lang_NullPointerException(), ""); \ |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
386 } \ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
387 VERIFY_OOP(obj_) |
0 | 388 |
389 #define VMdoubleConstZero() 0.0 | |
390 #define VMdoubleConstOne() 1.0 | |
391 #define VMlongConstZero() (max_jlong-max_jlong) | |
392 #define VMlongConstOne() ((max_jlong-max_jlong)+1) | |
393 | |
394 /* | |
395 * Alignment | |
396 */ | |
397 #define VMalignWordUp(val) (((uintptr_t)(val) + 3) & ~3) | |
398 | |
399 // Decache the interpreter state that interpreter modifies directly (i.e. GC is indirect mod) | |
400 #define DECACHE_STATE() DECACHE_PC(); DECACHE_TOS(); | |
401 | |
402 // Reload interpreter state after calling the VM or a possible GC | |
403 #define CACHE_STATE() \ | |
404 CACHE_TOS(); \ | |
405 CACHE_PC(); \ | |
406 CACHE_CP(); \ | |
407 CACHE_LOCALS(); | |
408 | |
409 // Call the VM don't check for pending exceptions | |
410 #define CALL_VM_NOCHECK(func) \ | |
411 DECACHE_STATE(); \ | |
412 SET_LAST_JAVA_FRAME(); \ | |
413 func; \ | |
414 RESET_LAST_JAVA_FRAME(); \ | |
415 CACHE_STATE(); \ | |
416 if (THREAD->pop_frame_pending() && \ | |
417 !THREAD->pop_frame_in_process()) { \ | |
418 goto handle_Pop_Frame; \ | |
419 } | |
420 | |
421 // Call the VM and check for pending exceptions | |
422 #define CALL_VM(func, label) { \ | |
423 CALL_VM_NOCHECK(func); \ | |
424 if (THREAD->has_pending_exception()) goto label; \ | |
425 } | |
426 | |
427 /* | |
428 * BytecodeInterpreter::run(interpreterState istate) | |
429 * BytecodeInterpreter::runWithChecks(interpreterState istate) | |
430 * | |
431 * The real deal. This is where byte codes actually get interpreted. | |
432 * Basically it's a big while loop that iterates until we return from | |
433 * the method passed in. | |
434 * | |
435 * The runWithChecks is used if JVMTI is enabled. | |
436 * | |
437 */ | |
438 #if defined(VM_JVMTI) | |
439 void | |
440 BytecodeInterpreter::runWithChecks(interpreterState istate) { | |
441 #else | |
442 void | |
443 BytecodeInterpreter::run(interpreterState istate) { | |
444 #endif | |
445 | |
446 // In order to simplify some tests based on switches set at runtime | |
447 // we invoke the interpreter a single time after switches are enabled | |
448 // and set simpler to to test variables rather than method calls or complex | |
449 // boolean expressions. | |
450 | |
451 static int initialized = 0; | |
452 static int checkit = 0; | |
453 static intptr_t* c_addr = NULL; | |
454 static intptr_t c_value; | |
455 | |
456 if (checkit && *c_addr != c_value) { | |
457 os::breakpoint(); | |
458 } | |
459 #ifdef VM_JVMTI | |
460 static bool _jvmti_interp_events = 0; | |
461 #endif | |
462 | |
463 static int _compiling; // (UseCompiler || CountCompiledCalls) | |
464 | |
465 #ifdef ASSERT | |
466 if (istate->_msg != initialize) { | |
467 assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit"); | |
1729 | 468 #ifndef SHARK |
469 IA32_ONLY(assert(istate->_stack_limit == istate->_thread->last_Java_sp() + 1, "wrong")); | |
470 #endif // !SHARK | |
0 | 471 } |
472 // Verify linkages. | |
473 interpreterState l = istate; | |
474 do { | |
475 assert(l == l->_self_link, "bad link"); | |
476 l = l->_prev_link; | |
477 } while (l != NULL); | |
478 // Screwups with stack management usually cause us to overwrite istate | |
479 // save a copy so we can verify it. | |
480 interpreterState orig = istate; | |
481 #endif | |
482 | |
483 static volatile jbyte* _byte_map_base; // adjusted card table base for oop store barrier | |
484 | |
485 register intptr_t* topOfStack = (intptr_t *)istate->stack(); /* access with STACK macros */ | |
486 register address pc = istate->bcp(); | |
487 register jubyte opcode; | |
488 register intptr_t* locals = istate->locals(); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
489 register ConstantPoolCache* cp = istate->constants(); // method()->constants()->cache() |
0 | 490 #ifdef LOTS_OF_REGS |
491 register JavaThread* THREAD = istate->thread(); | |
492 register volatile jbyte* BYTE_MAP_BASE = _byte_map_base; | |
493 #else | |
494 #undef THREAD | |
495 #define THREAD istate->thread() | |
496 #undef BYTE_MAP_BASE | |
497 #define BYTE_MAP_BASE _byte_map_base | |
498 #endif | |
499 | |
500 #ifdef USELABELS | |
501 const static void* const opclabels_data[256] = { | |
502 /* 0x00 */ &&opc_nop, &&opc_aconst_null,&&opc_iconst_m1,&&opc_iconst_0, | |
503 /* 0x04 */ &&opc_iconst_1,&&opc_iconst_2, &&opc_iconst_3, &&opc_iconst_4, | |
504 /* 0x08 */ &&opc_iconst_5,&&opc_lconst_0, &&opc_lconst_1, &&opc_fconst_0, | |
505 /* 0x0C */ &&opc_fconst_1,&&opc_fconst_2, &&opc_dconst_0, &&opc_dconst_1, | |
506 | |
507 /* 0x10 */ &&opc_bipush, &&opc_sipush, &&opc_ldc, &&opc_ldc_w, | |
508 /* 0x14 */ &&opc_ldc2_w, &&opc_iload, &&opc_lload, &&opc_fload, | |
509 /* 0x18 */ &&opc_dload, &&opc_aload, &&opc_iload_0,&&opc_iload_1, | |
510 /* 0x1C */ &&opc_iload_2,&&opc_iload_3,&&opc_lload_0,&&opc_lload_1, | |
511 | |
512 /* 0x20 */ &&opc_lload_2,&&opc_lload_3,&&opc_fload_0,&&opc_fload_1, | |
513 /* 0x24 */ &&opc_fload_2,&&opc_fload_3,&&opc_dload_0,&&opc_dload_1, | |
514 /* 0x28 */ &&opc_dload_2,&&opc_dload_3,&&opc_aload_0,&&opc_aload_1, | |
515 /* 0x2C */ &&opc_aload_2,&&opc_aload_3,&&opc_iaload, &&opc_laload, | |
516 | |
517 /* 0x30 */ &&opc_faload, &&opc_daload, &&opc_aaload, &&opc_baload, | |
518 /* 0x34 */ &&opc_caload, &&opc_saload, &&opc_istore, &&opc_lstore, | |
519 /* 0x38 */ &&opc_fstore, &&opc_dstore, &&opc_astore, &&opc_istore_0, | |
520 /* 0x3C */ &&opc_istore_1,&&opc_istore_2,&&opc_istore_3,&&opc_lstore_0, | |
521 | |
522 /* 0x40 */ &&opc_lstore_1,&&opc_lstore_2,&&opc_lstore_3,&&opc_fstore_0, | |
523 /* 0x44 */ &&opc_fstore_1,&&opc_fstore_2,&&opc_fstore_3,&&opc_dstore_0, | |
524 /* 0x48 */ &&opc_dstore_1,&&opc_dstore_2,&&opc_dstore_3,&&opc_astore_0, | |
525 /* 0x4C */ &&opc_astore_1,&&opc_astore_2,&&opc_astore_3,&&opc_iastore, | |
526 | |
527 /* 0x50 */ &&opc_lastore,&&opc_fastore,&&opc_dastore,&&opc_aastore, | |
528 /* 0x54 */ &&opc_bastore,&&opc_castore,&&opc_sastore,&&opc_pop, | |
529 /* 0x58 */ &&opc_pop2, &&opc_dup, &&opc_dup_x1, &&opc_dup_x2, | |
530 /* 0x5C */ &&opc_dup2, &&opc_dup2_x1,&&opc_dup2_x2,&&opc_swap, | |
531 | |
532 /* 0x60 */ &&opc_iadd,&&opc_ladd,&&opc_fadd,&&opc_dadd, | |
533 /* 0x64 */ &&opc_isub,&&opc_lsub,&&opc_fsub,&&opc_dsub, | |
534 /* 0x68 */ &&opc_imul,&&opc_lmul,&&opc_fmul,&&opc_dmul, | |
535 /* 0x6C */ &&opc_idiv,&&opc_ldiv,&&opc_fdiv,&&opc_ddiv, | |
536 | |
537 /* 0x70 */ &&opc_irem, &&opc_lrem, &&opc_frem,&&opc_drem, | |
538 /* 0x74 */ &&opc_ineg, &&opc_lneg, &&opc_fneg,&&opc_dneg, | |
539 /* 0x78 */ &&opc_ishl, &&opc_lshl, &&opc_ishr,&&opc_lshr, | |
540 /* 0x7C */ &&opc_iushr,&&opc_lushr,&&opc_iand,&&opc_land, | |
541 | |
542 /* 0x80 */ &&opc_ior, &&opc_lor,&&opc_ixor,&&opc_lxor, | |
543 /* 0x84 */ &&opc_iinc,&&opc_i2l,&&opc_i2f, &&opc_i2d, | |
544 /* 0x88 */ &&opc_l2i, &&opc_l2f,&&opc_l2d, &&opc_f2i, | |
545 /* 0x8C */ &&opc_f2l, &&opc_f2d,&&opc_d2i, &&opc_d2l, | |
546 | |
547 /* 0x90 */ &&opc_d2f, &&opc_i2b, &&opc_i2c, &&opc_i2s, | |
548 /* 0x94 */ &&opc_lcmp, &&opc_fcmpl,&&opc_fcmpg,&&opc_dcmpl, | |
549 /* 0x98 */ &&opc_dcmpg,&&opc_ifeq, &&opc_ifne, &&opc_iflt, | |
550 /* 0x9C */ &&opc_ifge, &&opc_ifgt, &&opc_ifle, &&opc_if_icmpeq, | |
551 | |
552 /* 0xA0 */ &&opc_if_icmpne,&&opc_if_icmplt,&&opc_if_icmpge, &&opc_if_icmpgt, | |
553 /* 0xA4 */ &&opc_if_icmple,&&opc_if_acmpeq,&&opc_if_acmpne, &&opc_goto, | |
554 /* 0xA8 */ &&opc_jsr, &&opc_ret, &&opc_tableswitch,&&opc_lookupswitch, | |
555 /* 0xAC */ &&opc_ireturn, &&opc_lreturn, &&opc_freturn, &&opc_dreturn, | |
556 | |
557 /* 0xB0 */ &&opc_areturn, &&opc_return, &&opc_getstatic, &&opc_putstatic, | |
558 /* 0xB4 */ &&opc_getfield, &&opc_putfield, &&opc_invokevirtual,&&opc_invokespecial, | |
2480 | 559 /* 0xB8 */ &&opc_invokestatic,&&opc_invokeinterface,&&opc_invokedynamic,&&opc_new, |
0 | 560 /* 0xBC */ &&opc_newarray, &&opc_anewarray, &&opc_arraylength, &&opc_athrow, |
561 | |
562 /* 0xC0 */ &&opc_checkcast, &&opc_instanceof, &&opc_monitorenter, &&opc_monitorexit, | |
563 /* 0xC4 */ &&opc_wide, &&opc_multianewarray, &&opc_ifnull, &&opc_ifnonnull, | |
123 | 564 /* 0xC8 */ &&opc_goto_w, &&opc_jsr_w, &&opc_breakpoint, &&opc_default, |
565 /* 0xCC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, | |
566 | |
567 /* 0xD0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, | |
0 | 568 /* 0xD4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, |
569 /* 0xD8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, | |
570 /* 0xDC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, | |
571 | |
572 /* 0xE0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, | |
2480 | 573 /* 0xE4 */ &&opc_default, &&opc_fast_aldc, &&opc_fast_aldc_w, &&opc_return_register_finalizer, |
6926 | 574 /* 0xE8 */ &&opc_invokehandle,&&opc_default, &&opc_default, &&opc_default, |
0 | 575 /* 0xEC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, |
576 | |
577 /* 0xF0 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, | |
578 /* 0xF4 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, | |
579 /* 0xF8 */ &&opc_default, &&opc_default, &&opc_default, &&opc_default, | |
580 /* 0xFC */ &&opc_default, &&opc_default, &&opc_default, &&opc_default | |
581 }; | |
582 register uintptr_t *dispatch_table = (uintptr_t*)&opclabels_data[0]; | |
583 #endif /* USELABELS */ | |
584 | |
585 #ifdef ASSERT | |
586 // this will trigger a VERIFY_OOP on entry | |
587 if (istate->msg() != initialize && ! METHOD->is_static()) { | |
588 oop rcvr = LOCALS_OBJECT(0); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
589 VERIFY_OOP(rcvr); |
0 | 590 } |
591 #endif | |
592 // #define HACK | |
593 #ifdef HACK | |
594 bool interesting = false; | |
595 #endif // HACK | |
596 | |
597 /* QQQ this should be a stack method so we don't know actual direction */ | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
598 guarantee(istate->msg() == initialize || |
0 | 599 topOfStack >= istate->stack_limit() && |
600 topOfStack < istate->stack_base(), | |
601 "Stack top out of range"); | |
602 | |
603 switch (istate->msg()) { | |
604 case initialize: { | |
605 if (initialized++) ShouldNotReachHere(); // Only one initialize call | |
606 _compiling = (UseCompiler || CountCompiledCalls); | |
607 #ifdef VM_JVMTI | |
608 _jvmti_interp_events = JvmtiExport::can_post_interpreter_events(); | |
609 #endif | |
610 BarrierSet* bs = Universe::heap()->barrier_set(); | |
611 assert(bs->kind() == BarrierSet::CardTableModRef, "Wrong barrier set kind"); | |
612 _byte_map_base = (volatile jbyte*)(((CardTableModRefBS*)bs)->byte_map_base); | |
613 return; | |
614 } | |
615 break; | |
616 case method_entry: { | |
617 THREAD->set_do_not_unlock(); | |
618 // count invocations | |
619 assert(initialized, "Interpreter not initialized"); | |
620 if (_compiling) { | |
621 if (ProfileInterpreter) { | |
622 METHOD->increment_interpreter_invocation_count(); | |
623 } | |
624 INCR_INVOCATION_COUNT; | |
625 if (INVOCATION_COUNT->reached_InvocationLimit()) { | |
626 CALL_VM((void)InterpreterRuntime::frequency_counter_overflow(THREAD, NULL), handle_exception); | |
627 | |
628 // We no longer retry on a counter overflow | |
629 | |
630 // istate->set_msg(retry_method); | |
631 // THREAD->clr_do_not_unlock(); | |
632 // return; | |
633 } | |
634 SAFEPOINT; | |
635 } | |
636 | |
637 if ((istate->_stack_base - istate->_stack_limit) != istate->method()->max_stack() + 1) { | |
638 // initialize | |
639 os::breakpoint(); | |
640 } | |
641 | |
642 #ifdef HACK | |
643 { | |
644 ResourceMark rm; | |
645 char *method_name = istate->method()->name_and_sig_as_C_string(); | |
646 if (strstr(method_name, "runThese$TestRunner.run()V") != NULL) { | |
647 tty->print_cr("entering: depth %d bci: %d", | |
648 (istate->_stack_base - istate->_stack), | |
649 istate->_bcp - istate->_method->code_base()); | |
650 interesting = true; | |
651 } | |
652 } | |
653 #endif // HACK | |
654 | |
655 | |
656 // lock method if synchronized | |
657 if (METHOD->is_synchronized()) { | |
658 // oop rcvr = locals[0].j.r; | |
659 oop rcvr; | |
660 if (METHOD->is_static()) { | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2260
diff
changeset
|
661 rcvr = METHOD->constants()->pool_holder()->java_mirror(); |
0 | 662 } else { |
663 rcvr = LOCALS_OBJECT(0); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
664 VERIFY_OOP(rcvr); |
0 | 665 } |
666 // The initial monitor is ours for the taking | |
667 BasicObjectLock* mon = &istate->monitor_base()[-1]; | |
668 oop monobj = mon->obj(); | |
669 assert(mon->obj() == rcvr, "method monitor mis-initialized"); | |
670 | |
671 bool success = UseBiasedLocking; | |
672 if (UseBiasedLocking) { | |
673 markOop mark = rcvr->mark(); | |
674 if (mark->has_bias_pattern()) { | |
675 // The bias pattern is present in the object's header. Need to check | |
676 // whether the bias owner and the epoch are both still current. | |
677 intptr_t xx = ((intptr_t) THREAD) ^ (intptr_t) mark; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
678 xx = (intptr_t) rcvr->klass()->prototype_header() ^ xx; |
0 | 679 intptr_t yy = (xx & ~((int) markOopDesc::age_mask_in_place)); |
680 if (yy != 0 ) { | |
681 // At this point we know that the header has the bias pattern and | |
682 // that we are not the bias owner in the current epoch. We need to | |
683 // figure out more details about the state of the header in order to | |
684 // know what operations can be legally performed on the object's | |
685 // header. | |
686 | |
687 // If the low three bits in the xor result aren't clear, that means | |
688 // the prototype header is no longer biased and we have to revoke | |
689 // the bias on this object. | |
690 | |
691 if (yy & markOopDesc::biased_lock_mask_in_place == 0 ) { | |
692 // Biasing is still enabled for this data type. See whether the | |
693 // epoch of the current bias is still valid, meaning that the epoch | |
694 // bits of the mark word are equal to the epoch bits of the | |
695 // prototype header. (Note that the prototype header's epoch bits | |
696 // only change at a safepoint.) If not, attempt to rebias the object | |
697 // toward the current thread. Note that we must be absolutely sure | |
698 // that the current epoch is invalid in order to do this because | |
699 // otherwise the manipulations it performs on the mark word are | |
700 // illegal. | |
701 if (yy & markOopDesc::epoch_mask_in_place == 0) { | |
702 // The epoch of the current bias is still valid but we know nothing | |
703 // about the owner; it might be set or it might be clear. Try to | |
704 // acquire the bias of the object using an atomic operation. If this | |
705 // fails we will go in to the runtime to revoke the object's bias. | |
706 // Note that we first construct the presumed unbiased header so we | |
707 // don't accidentally blow away another thread's valid bias. | |
708 intptr_t unbiased = (intptr_t) mark & (markOopDesc::biased_lock_mask_in_place | | |
709 markOopDesc::age_mask_in_place | | |
710 markOopDesc::epoch_mask_in_place); | |
711 if (Atomic::cmpxchg_ptr((intptr_t)THREAD | unbiased, (intptr_t*) rcvr->mark_addr(), unbiased) != unbiased) { | |
712 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); | |
713 } | |
714 } else { | |
715 try_rebias: | |
716 // At this point we know the epoch has expired, meaning that the | |
717 // current "bias owner", if any, is actually invalid. Under these | |
718 // circumstances _only_, we are allowed to use the current header's | |
719 // value as the comparison value when doing the cas to acquire the | |
720 // bias in the current epoch. In other words, we allow transfer of | |
721 // the bias from one thread to another directly in this situation. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
722 xx = (intptr_t) rcvr->klass()->prototype_header() | (intptr_t) THREAD; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
723 if (Atomic::cmpxchg_ptr((intptr_t)THREAD | (intptr_t) rcvr->klass()->prototype_header(), |
0 | 724 (intptr_t*) rcvr->mark_addr(), |
725 (intptr_t) mark) != (intptr_t) mark) { | |
726 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); | |
727 } | |
728 } | |
729 } else { | |
730 try_revoke_bias: | |
731 // The prototype mark in the klass doesn't have the bias bit set any | |
732 // more, indicating that objects of this data type are not supposed | |
733 // to be biased any more. We are going to try to reset the mark of | |
734 // this object to the prototype value and fall through to the | |
735 // CAS-based locking scheme. Note that if our CAS fails, it means | |
736 // that another thread raced us for the privilege of revoking the | |
737 // bias of this particular object, so it's okay to continue in the | |
738 // normal locking code. | |
739 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
740 xx = (intptr_t) rcvr->klass()->prototype_header() | (intptr_t) THREAD; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
741 if (Atomic::cmpxchg_ptr(rcvr->klass()->prototype_header(), |
0 | 742 (intptr_t*) rcvr->mark_addr(), |
743 mark) == mark) { | |
744 // (*counters->revoked_lock_entry_count_addr())++; | |
745 success = false; | |
746 } | |
747 } | |
748 } | |
749 } else { | |
750 cas_label: | |
751 success = false; | |
752 } | |
753 } | |
754 if (!success) { | |
755 markOop displaced = rcvr->mark()->set_unlocked(); | |
756 mon->lock()->set_displaced_header(displaced); | |
757 if (Atomic::cmpxchg_ptr(mon, rcvr->mark_addr(), displaced) != displaced) { | |
758 // Is it simple recursive case? | |
759 if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { | |
760 mon->lock()->set_displaced_header(NULL); | |
761 } else { | |
762 CALL_VM(InterpreterRuntime::monitorenter(THREAD, mon), handle_exception); | |
763 } | |
764 } | |
765 } | |
766 } | |
767 THREAD->clr_do_not_unlock(); | |
768 | |
769 // Notify jvmti | |
770 #ifdef VM_JVMTI | |
771 if (_jvmti_interp_events) { | |
772 // Whenever JVMTI puts a thread in interp_only_mode, method | |
773 // entry/exit events are sent for that thread to track stack depth. | |
774 if (THREAD->is_interp_only_mode()) { | |
775 CALL_VM(InterpreterRuntime::post_method_entry(THREAD), | |
776 handle_exception); | |
777 } | |
778 } | |
779 #endif /* VM_JVMTI */ | |
780 | |
781 goto run; | |
782 } | |
783 | |
784 case popping_frame: { | |
785 // returned from a java call to pop the frame, restart the call | |
786 // clear the message so we don't confuse ourselves later | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
787 ShouldNotReachHere(); // we don't return this. |
0 | 788 assert(THREAD->pop_frame_in_process(), "wrong frame pop state"); |
789 istate->set_msg(no_request); | |
790 THREAD->clr_pop_frame_in_process(); | |
791 goto run; | |
792 } | |
793 | |
794 case method_resume: { | |
795 if ((istate->_stack_base - istate->_stack_limit) != istate->method()->max_stack() + 1) { | |
796 // resume | |
797 os::breakpoint(); | |
798 } | |
799 #ifdef HACK | |
800 { | |
801 ResourceMark rm; | |
802 char *method_name = istate->method()->name_and_sig_as_C_string(); | |
803 if (strstr(method_name, "runThese$TestRunner.run()V") != NULL) { | |
804 tty->print_cr("resume: depth %d bci: %d", | |
805 (istate->_stack_base - istate->_stack) , | |
806 istate->_bcp - istate->_method->code_base()); | |
807 interesting = true; | |
808 } | |
809 } | |
810 #endif // HACK | |
811 // returned from a java call, continue executing. | |
812 if (THREAD->pop_frame_pending() && !THREAD->pop_frame_in_process()) { | |
813 goto handle_Pop_Frame; | |
814 } | |
815 | |
816 if (THREAD->has_pending_exception()) goto handle_exception; | |
817 // Update the pc by the saved amount of the invoke bytecode size | |
818 UPDATE_PC(istate->bcp_advance()); | |
819 goto run; | |
820 } | |
821 | |
822 case deopt_resume2: { | |
823 // Returned from an opcode that will reexecute. Deopt was | |
824 // a result of a PopFrame request. | |
825 // | |
826 goto run; | |
827 } | |
828 | |
829 case deopt_resume: { | |
830 // Returned from an opcode that has completed. The stack has | |
831 // the result all we need to do is skip across the bytecode | |
832 // and continue (assuming there is no exception pending) | |
833 // | |
834 // compute continuation length | |
835 // | |
836 // Note: it is possible to deopt at a return_register_finalizer opcode | |
837 // because this requires entering the vm to do the registering. While the | |
838 // opcode is complete we can't advance because there are no more opcodes | |
839 // much like trying to deopt at a poll return. In that has we simply | |
840 // get out of here | |
841 // | |
2142 | 842 if ( Bytecodes::code_at(METHOD, pc) == Bytecodes::_return_register_finalizer) { |
0 | 843 // this will do the right thing even if an exception is pending. |
844 goto handle_return; | |
845 } | |
2142 | 846 UPDATE_PC(Bytecodes::length_at(METHOD, pc)); |
0 | 847 if (THREAD->has_pending_exception()) goto handle_exception; |
848 goto run; | |
849 } | |
850 case got_monitors: { | |
851 // continue locking now that we have a monitor to use | |
852 // we expect to find newly allocated monitor at the "top" of the monitor stack. | |
853 oop lockee = STACK_OBJECT(-1); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
854 VERIFY_OOP(lockee); |
0 | 855 // derefing's lockee ought to provoke implicit null check |
856 // find a free monitor | |
857 BasicObjectLock* entry = (BasicObjectLock*) istate->stack_base(); | |
858 assert(entry->obj() == NULL, "Frame manager didn't allocate the monitor"); | |
859 entry->set_obj(lockee); | |
860 | |
861 markOop displaced = lockee->mark()->set_unlocked(); | |
862 entry->lock()->set_displaced_header(displaced); | |
863 if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { | |
864 // Is it simple recursive case? | |
865 if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { | |
866 entry->lock()->set_displaced_header(NULL); | |
867 } else { | |
868 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); | |
869 } | |
870 } | |
871 UPDATE_PC_AND_TOS(1, -1); | |
872 goto run; | |
873 } | |
874 default: { | |
875 fatal("Unexpected message from frame manager"); | |
876 } | |
877 } | |
878 | |
879 run: | |
880 | |
881 DO_UPDATE_INSTRUCTION_COUNT(*pc) | |
882 DEBUGGER_SINGLE_STEP_NOTIFY(); | |
883 #ifdef PREFETCH_OPCCODE | |
884 opcode = *pc; /* prefetch first opcode */ | |
885 #endif | |
886 | |
887 #ifndef USELABELS | |
888 while (1) | |
889 #endif | |
890 { | |
891 #ifndef PREFETCH_OPCCODE | |
892 opcode = *pc; | |
893 #endif | |
894 // Seems like this happens twice per opcode. At worst this is only | |
895 // need at entry to the loop. | |
896 // DEBUGGER_SINGLE_STEP_NOTIFY(); | |
897 /* Using this labels avoids double breakpoints when quickening and | |
898 * when returing from transition frames. | |
899 */ | |
900 opcode_switch: | |
901 assert(istate == orig, "Corrupted istate"); | |
902 /* QQQ Hmm this has knowledge of direction, ought to be a stack method */ | |
903 assert(topOfStack >= istate->stack_limit(), "Stack overrun"); | |
904 assert(topOfStack < istate->stack_base(), "Stack underrun"); | |
905 | |
906 #ifdef USELABELS | |
907 DISPATCH(opcode); | |
908 #else | |
909 switch (opcode) | |
910 #endif | |
911 { | |
912 CASE(_nop): | |
913 UPDATE_PC_AND_CONTINUE(1); | |
914 | |
915 /* Push miscellaneous constants onto the stack. */ | |
916 | |
917 CASE(_aconst_null): | |
918 SET_STACK_OBJECT(NULL, 0); | |
919 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
920 | |
921 #undef OPC_CONST_n | |
922 #define OPC_CONST_n(opcode, const_type, value) \ | |
923 CASE(opcode): \ | |
924 SET_STACK_ ## const_type(value, 0); \ | |
925 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
926 | |
927 OPC_CONST_n(_iconst_m1, INT, -1); | |
928 OPC_CONST_n(_iconst_0, INT, 0); | |
929 OPC_CONST_n(_iconst_1, INT, 1); | |
930 OPC_CONST_n(_iconst_2, INT, 2); | |
931 OPC_CONST_n(_iconst_3, INT, 3); | |
932 OPC_CONST_n(_iconst_4, INT, 4); | |
933 OPC_CONST_n(_iconst_5, INT, 5); | |
934 OPC_CONST_n(_fconst_0, FLOAT, 0.0); | |
935 OPC_CONST_n(_fconst_1, FLOAT, 1.0); | |
936 OPC_CONST_n(_fconst_2, FLOAT, 2.0); | |
937 | |
938 #undef OPC_CONST2_n | |
939 #define OPC_CONST2_n(opcname, value, key, kind) \ | |
940 CASE(_##opcname): \ | |
941 { \ | |
942 SET_STACK_ ## kind(VM##key##Const##value(), 1); \ | |
943 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); \ | |
944 } | |
945 OPC_CONST2_n(dconst_0, Zero, double, DOUBLE); | |
946 OPC_CONST2_n(dconst_1, One, double, DOUBLE); | |
947 OPC_CONST2_n(lconst_0, Zero, long, LONG); | |
948 OPC_CONST2_n(lconst_1, One, long, LONG); | |
949 | |
950 /* Load constant from constant pool: */ | |
951 | |
952 /* Push a 1-byte signed integer value onto the stack. */ | |
953 CASE(_bipush): | |
954 SET_STACK_INT((jbyte)(pc[1]), 0); | |
955 UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); | |
956 | |
957 /* Push a 2-byte signed integer constant onto the stack. */ | |
958 CASE(_sipush): | |
959 SET_STACK_INT((int16_t)Bytes::get_Java_u2(pc + 1), 0); | |
960 UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); | |
961 | |
962 /* load from local variable */ | |
963 | |
964 CASE(_aload): | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
965 VERIFY_OOP(LOCALS_OBJECT(pc[1])); |
0 | 966 SET_STACK_OBJECT(LOCALS_OBJECT(pc[1]), 0); |
967 UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); | |
968 | |
969 CASE(_iload): | |
970 CASE(_fload): | |
971 SET_STACK_SLOT(LOCALS_SLOT(pc[1]), 0); | |
972 UPDATE_PC_AND_TOS_AND_CONTINUE(2, 1); | |
973 | |
974 CASE(_lload): | |
975 SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(pc[1]), 1); | |
976 UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2); | |
977 | |
978 CASE(_dload): | |
979 SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(pc[1]), 1); | |
980 UPDATE_PC_AND_TOS_AND_CONTINUE(2, 2); | |
981 | |
982 #undef OPC_LOAD_n | |
983 #define OPC_LOAD_n(num) \ | |
984 CASE(_aload_##num): \ | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
985 VERIFY_OOP(LOCALS_OBJECT(num)); \ |
0 | 986 SET_STACK_OBJECT(LOCALS_OBJECT(num), 0); \ |
987 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); \ | |
988 \ | |
989 CASE(_iload_##num): \ | |
990 CASE(_fload_##num): \ | |
991 SET_STACK_SLOT(LOCALS_SLOT(num), 0); \ | |
992 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); \ | |
993 \ | |
994 CASE(_lload_##num): \ | |
995 SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(num), 1); \ | |
996 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); \ | |
997 CASE(_dload_##num): \ | |
998 SET_STACK_DOUBLE_FROM_ADDR(LOCALS_DOUBLE_AT(num), 1); \ | |
999 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1000 | |
1001 OPC_LOAD_n(0); | |
1002 OPC_LOAD_n(1); | |
1003 OPC_LOAD_n(2); | |
1004 OPC_LOAD_n(3); | |
1005 | |
1006 /* store to a local variable */ | |
1007 | |
1008 CASE(_astore): | |
1009 astore(topOfStack, -1, locals, pc[1]); | |
1010 UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1); | |
1011 | |
1012 CASE(_istore): | |
1013 CASE(_fstore): | |
1014 SET_LOCALS_SLOT(STACK_SLOT(-1), pc[1]); | |
1015 UPDATE_PC_AND_TOS_AND_CONTINUE(2, -1); | |
1016 | |
1017 CASE(_lstore): | |
1018 SET_LOCALS_LONG(STACK_LONG(-1), pc[1]); | |
1019 UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2); | |
1020 | |
1021 CASE(_dstore): | |
1022 SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), pc[1]); | |
1023 UPDATE_PC_AND_TOS_AND_CONTINUE(2, -2); | |
1024 | |
1025 CASE(_wide): { | |
1026 uint16_t reg = Bytes::get_Java_u2(pc + 2); | |
1027 | |
1028 opcode = pc[1]; | |
1029 switch(opcode) { | |
1030 case Bytecodes::_aload: | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1031 VERIFY_OOP(LOCALS_OBJECT(reg)); |
0 | 1032 SET_STACK_OBJECT(LOCALS_OBJECT(reg), 0); |
1033 UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1); | |
1034 | |
1035 case Bytecodes::_iload: | |
1036 case Bytecodes::_fload: | |
1037 SET_STACK_SLOT(LOCALS_SLOT(reg), 0); | |
1038 UPDATE_PC_AND_TOS_AND_CONTINUE(4, 1); | |
1039 | |
1040 case Bytecodes::_lload: | |
1041 SET_STACK_LONG_FROM_ADDR(LOCALS_LONG_AT(reg), 1); | |
1042 UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2); | |
1043 | |
1044 case Bytecodes::_dload: | |
1045 SET_STACK_DOUBLE_FROM_ADDR(LOCALS_LONG_AT(reg), 1); | |
1046 UPDATE_PC_AND_TOS_AND_CONTINUE(4, 2); | |
1047 | |
1048 case Bytecodes::_astore: | |
1049 astore(topOfStack, -1, locals, reg); | |
1050 UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1); | |
1051 | |
1052 case Bytecodes::_istore: | |
1053 case Bytecodes::_fstore: | |
1054 SET_LOCALS_SLOT(STACK_SLOT(-1), reg); | |
1055 UPDATE_PC_AND_TOS_AND_CONTINUE(4, -1); | |
1056 | |
1057 case Bytecodes::_lstore: | |
1058 SET_LOCALS_LONG(STACK_LONG(-1), reg); | |
1059 UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2); | |
1060 | |
1061 case Bytecodes::_dstore: | |
1062 SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), reg); | |
1063 UPDATE_PC_AND_TOS_AND_CONTINUE(4, -2); | |
1064 | |
1065 case Bytecodes::_iinc: { | |
1066 int16_t offset = (int16_t)Bytes::get_Java_u2(pc+4); | |
1067 // Be nice to see what this generates.... QQQ | |
1068 SET_LOCALS_INT(LOCALS_INT(reg) + offset, reg); | |
1069 UPDATE_PC_AND_CONTINUE(6); | |
1070 } | |
1071 case Bytecodes::_ret: | |
1072 pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(reg)); | |
1073 UPDATE_PC_AND_CONTINUE(0); | |
1074 default: | |
1075 VM_JAVA_ERROR(vmSymbols::java_lang_InternalError(), "undefined opcode"); | |
1076 } | |
1077 } | |
1078 | |
1079 | |
1080 #undef OPC_STORE_n | |
1081 #define OPC_STORE_n(num) \ | |
1082 CASE(_astore_##num): \ | |
1083 astore(topOfStack, -1, locals, num); \ | |
1084 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ | |
1085 CASE(_istore_##num): \ | |
1086 CASE(_fstore_##num): \ | |
1087 SET_LOCALS_SLOT(STACK_SLOT(-1), num); \ | |
1088 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); | |
1089 | |
1090 OPC_STORE_n(0); | |
1091 OPC_STORE_n(1); | |
1092 OPC_STORE_n(2); | |
1093 OPC_STORE_n(3); | |
1094 | |
1095 #undef OPC_DSTORE_n | |
1096 #define OPC_DSTORE_n(num) \ | |
1097 CASE(_dstore_##num): \ | |
1098 SET_LOCALS_DOUBLE(STACK_DOUBLE(-1), num); \ | |
1099 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ | |
1100 CASE(_lstore_##num): \ | |
1101 SET_LOCALS_LONG(STACK_LONG(-1), num); \ | |
1102 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); | |
1103 | |
1104 OPC_DSTORE_n(0); | |
1105 OPC_DSTORE_n(1); | |
1106 OPC_DSTORE_n(2); | |
1107 OPC_DSTORE_n(3); | |
1108 | |
1109 /* stack pop, dup, and insert opcodes */ | |
1110 | |
1111 | |
1112 CASE(_pop): /* Discard the top item on the stack */ | |
1113 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); | |
1114 | |
1115 | |
1116 CASE(_pop2): /* Discard the top 2 items on the stack */ | |
1117 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); | |
1118 | |
1119 | |
1120 CASE(_dup): /* Duplicate the top item on the stack */ | |
1121 dup(topOfStack); | |
1122 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1123 | |
1124 CASE(_dup2): /* Duplicate the top 2 items on the stack */ | |
1125 dup2(topOfStack); | |
1126 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1127 | |
1128 CASE(_dup_x1): /* insert top word two down */ | |
1129 dup_x1(topOfStack); | |
1130 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1131 | |
1132 CASE(_dup_x2): /* insert top word three down */ | |
1133 dup_x2(topOfStack); | |
1134 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1135 | |
1136 CASE(_dup2_x1): /* insert top 2 slots three down */ | |
1137 dup2_x1(topOfStack); | |
1138 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1139 | |
1140 CASE(_dup2_x2): /* insert top 2 slots four down */ | |
1141 dup2_x2(topOfStack); | |
1142 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1143 | |
1144 CASE(_swap): { /* swap top two elements on the stack */ | |
1145 swap(topOfStack); | |
1146 UPDATE_PC_AND_CONTINUE(1); | |
1147 } | |
1148 | |
1149 /* Perform various binary integer operations */ | |
1150 | |
1151 #undef OPC_INT_BINARY | |
1152 #define OPC_INT_BINARY(opcname, opname, test) \ | |
1153 CASE(_i##opcname): \ | |
1154 if (test && (STACK_INT(-1) == 0)) { \ | |
1155 VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \ | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1156 "/ by zero"); \ |
0 | 1157 } \ |
1158 SET_STACK_INT(VMint##opname(STACK_INT(-2), \ | |
1159 STACK_INT(-1)), \ | |
1160 -2); \ | |
1161 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ | |
1162 CASE(_l##opcname): \ | |
1163 { \ | |
1164 if (test) { \ | |
1165 jlong l1 = STACK_LONG(-1); \ | |
1166 if (VMlongEqz(l1)) { \ | |
1167 VM_JAVA_ERROR(vmSymbols::java_lang_ArithmeticException(), \ | |
1168 "/ by long zero"); \ | |
1169 } \ | |
1170 } \ | |
1171 /* First long at (-1,-2) next long at (-3,-4) */ \ | |
1172 SET_STACK_LONG(VMlong##opname(STACK_LONG(-3), \ | |
1173 STACK_LONG(-1)), \ | |
1174 -3); \ | |
1175 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ | |
1176 } | |
1177 | |
1178 OPC_INT_BINARY(add, Add, 0); | |
1179 OPC_INT_BINARY(sub, Sub, 0); | |
1180 OPC_INT_BINARY(mul, Mul, 0); | |
1181 OPC_INT_BINARY(and, And, 0); | |
1182 OPC_INT_BINARY(or, Or, 0); | |
1183 OPC_INT_BINARY(xor, Xor, 0); | |
1184 OPC_INT_BINARY(div, Div, 1); | |
1185 OPC_INT_BINARY(rem, Rem, 1); | |
1186 | |
1187 | |
1188 /* Perform various binary floating number operations */ | |
1189 /* On some machine/platforms/compilers div zero check can be implicit */ | |
1190 | |
1191 #undef OPC_FLOAT_BINARY | |
1192 #define OPC_FLOAT_BINARY(opcname, opname) \ | |
1193 CASE(_d##opcname): { \ | |
1194 SET_STACK_DOUBLE(VMdouble##opname(STACK_DOUBLE(-3), \ | |
1195 STACK_DOUBLE(-1)), \ | |
1196 -3); \ | |
1197 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -2); \ | |
1198 } \ | |
1199 CASE(_f##opcname): \ | |
1200 SET_STACK_FLOAT(VMfloat##opname(STACK_FLOAT(-2), \ | |
1201 STACK_FLOAT(-1)), \ | |
1202 -2); \ | |
1203 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); | |
1204 | |
1205 | |
1206 OPC_FLOAT_BINARY(add, Add); | |
1207 OPC_FLOAT_BINARY(sub, Sub); | |
1208 OPC_FLOAT_BINARY(mul, Mul); | |
1209 OPC_FLOAT_BINARY(div, Div); | |
1210 OPC_FLOAT_BINARY(rem, Rem); | |
1211 | |
1212 /* Shift operations | |
1213 * Shift left int and long: ishl, lshl | |
1214 * Logical shift right int and long w/zero extension: iushr, lushr | |
1215 * Arithmetic shift right int and long w/sign extension: ishr, lshr | |
1216 */ | |
1217 | |
1218 #undef OPC_SHIFT_BINARY | |
1219 #define OPC_SHIFT_BINARY(opcname, opname) \ | |
1220 CASE(_i##opcname): \ | |
1221 SET_STACK_INT(VMint##opname(STACK_INT(-2), \ | |
1222 STACK_INT(-1)), \ | |
1223 -2); \ | |
1224 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ | |
1225 CASE(_l##opcname): \ | |
1226 { \ | |
1227 SET_STACK_LONG(VMlong##opname(STACK_LONG(-2), \ | |
1228 STACK_INT(-1)), \ | |
1229 -2); \ | |
1230 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ | |
1231 } | |
1232 | |
1233 OPC_SHIFT_BINARY(shl, Shl); | |
1234 OPC_SHIFT_BINARY(shr, Shr); | |
1235 OPC_SHIFT_BINARY(ushr, Ushr); | |
1236 | |
1237 /* Increment local variable by constant */ | |
1238 CASE(_iinc): | |
1239 { | |
1240 // locals[pc[1]].j.i += (jbyte)(pc[2]); | |
1241 SET_LOCALS_INT(LOCALS_INT(pc[1]) + (jbyte)(pc[2]), pc[1]); | |
1242 UPDATE_PC_AND_CONTINUE(3); | |
1243 } | |
1244 | |
1245 /* negate the value on the top of the stack */ | |
1246 | |
1247 CASE(_ineg): | |
1248 SET_STACK_INT(VMintNeg(STACK_INT(-1)), -1); | |
1249 UPDATE_PC_AND_CONTINUE(1); | |
1250 | |
1251 CASE(_fneg): | |
1252 SET_STACK_FLOAT(VMfloatNeg(STACK_FLOAT(-1)), -1); | |
1253 UPDATE_PC_AND_CONTINUE(1); | |
1254 | |
1255 CASE(_lneg): | |
1256 { | |
1257 SET_STACK_LONG(VMlongNeg(STACK_LONG(-1)), -1); | |
1258 UPDATE_PC_AND_CONTINUE(1); | |
1259 } | |
1260 | |
1261 CASE(_dneg): | |
1262 { | |
1263 SET_STACK_DOUBLE(VMdoubleNeg(STACK_DOUBLE(-1)), -1); | |
1264 UPDATE_PC_AND_CONTINUE(1); | |
1265 } | |
1266 | |
1267 /* Conversion operations */ | |
1268 | |
1269 CASE(_i2f): /* convert top of stack int to float */ | |
1270 SET_STACK_FLOAT(VMint2Float(STACK_INT(-1)), -1); | |
1271 UPDATE_PC_AND_CONTINUE(1); | |
1272 | |
1273 CASE(_i2l): /* convert top of stack int to long */ | |
1274 { | |
1275 // this is ugly QQQ | |
1276 jlong r = VMint2Long(STACK_INT(-1)); | |
1277 MORE_STACK(-1); // Pop | |
1278 SET_STACK_LONG(r, 1); | |
1279 | |
1280 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1281 } | |
1282 | |
1283 CASE(_i2d): /* convert top of stack int to double */ | |
1284 { | |
1285 // this is ugly QQQ (why cast to jlong?? ) | |
1286 jdouble r = (jlong)STACK_INT(-1); | |
1287 MORE_STACK(-1); // Pop | |
1288 SET_STACK_DOUBLE(r, 1); | |
1289 | |
1290 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1291 } | |
1292 | |
1293 CASE(_l2i): /* convert top of stack long to int */ | |
1294 { | |
1295 jint r = VMlong2Int(STACK_LONG(-1)); | |
1296 MORE_STACK(-2); // Pop | |
1297 SET_STACK_INT(r, 0); | |
1298 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1299 } | |
1300 | |
1301 CASE(_l2f): /* convert top of stack long to float */ | |
1302 { | |
1303 jlong r = STACK_LONG(-1); | |
1304 MORE_STACK(-2); // Pop | |
1305 SET_STACK_FLOAT(VMlong2Float(r), 0); | |
1306 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1307 } | |
1308 | |
1309 CASE(_l2d): /* convert top of stack long to double */ | |
1310 { | |
1311 jlong r = STACK_LONG(-1); | |
1312 MORE_STACK(-2); // Pop | |
1313 SET_STACK_DOUBLE(VMlong2Double(r), 1); | |
1314 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1315 } | |
1316 | |
1317 CASE(_f2i): /* Convert top of stack float to int */ | |
1318 SET_STACK_INT(SharedRuntime::f2i(STACK_FLOAT(-1)), -1); | |
1319 UPDATE_PC_AND_CONTINUE(1); | |
1320 | |
1321 CASE(_f2l): /* convert top of stack float to long */ | |
1322 { | |
1323 jlong r = SharedRuntime::f2l(STACK_FLOAT(-1)); | |
1324 MORE_STACK(-1); // POP | |
1325 SET_STACK_LONG(r, 1); | |
1326 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1327 } | |
1328 | |
1329 CASE(_f2d): /* convert top of stack float to double */ | |
1330 { | |
1331 jfloat f; | |
1332 jdouble r; | |
1333 f = STACK_FLOAT(-1); | |
1334 r = (jdouble) f; | |
1335 MORE_STACK(-1); // POP | |
1336 SET_STACK_DOUBLE(r, 1); | |
1337 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1338 } | |
1339 | |
1340 CASE(_d2i): /* convert top of stack double to int */ | |
1341 { | |
1342 jint r1 = SharedRuntime::d2i(STACK_DOUBLE(-1)); | |
1343 MORE_STACK(-2); | |
1344 SET_STACK_INT(r1, 0); | |
1345 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1346 } | |
1347 | |
1348 CASE(_d2f): /* convert top of stack double to float */ | |
1349 { | |
1350 jfloat r1 = VMdouble2Float(STACK_DOUBLE(-1)); | |
1351 MORE_STACK(-2); | |
1352 SET_STACK_FLOAT(r1, 0); | |
1353 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1354 } | |
1355 | |
1356 CASE(_d2l): /* convert top of stack double to long */ | |
1357 { | |
1358 jlong r1 = SharedRuntime::d2l(STACK_DOUBLE(-1)); | |
1359 MORE_STACK(-2); | |
1360 SET_STACK_LONG(r1, 1); | |
1361 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 2); | |
1362 } | |
1363 | |
1364 CASE(_i2b): | |
1365 SET_STACK_INT(VMint2Byte(STACK_INT(-1)), -1); | |
1366 UPDATE_PC_AND_CONTINUE(1); | |
1367 | |
1368 CASE(_i2c): | |
1369 SET_STACK_INT(VMint2Char(STACK_INT(-1)), -1); | |
1370 UPDATE_PC_AND_CONTINUE(1); | |
1371 | |
1372 CASE(_i2s): | |
1373 SET_STACK_INT(VMint2Short(STACK_INT(-1)), -1); | |
1374 UPDATE_PC_AND_CONTINUE(1); | |
1375 | |
1376 /* comparison operators */ | |
1377 | |
1378 | |
1379 #define COMPARISON_OP(name, comparison) \ | |
1380 CASE(_if_icmp##name): { \ | |
1381 int skip = (STACK_INT(-2) comparison STACK_INT(-1)) \ | |
1382 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ | |
1383 address branch_pc = pc; \ | |
1384 UPDATE_PC_AND_TOS(skip, -2); \ | |
1385 DO_BACKEDGE_CHECKS(skip, branch_pc); \ | |
1386 CONTINUE; \ | |
1387 } \ | |
1388 CASE(_if##name): { \ | |
1389 int skip = (STACK_INT(-1) comparison 0) \ | |
1390 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ | |
1391 address branch_pc = pc; \ | |
1392 UPDATE_PC_AND_TOS(skip, -1); \ | |
1393 DO_BACKEDGE_CHECKS(skip, branch_pc); \ | |
1394 CONTINUE; \ | |
1395 } | |
1396 | |
1397 #define COMPARISON_OP2(name, comparison) \ | |
1398 COMPARISON_OP(name, comparison) \ | |
1399 CASE(_if_acmp##name): { \ | |
1400 int skip = (STACK_OBJECT(-2) comparison STACK_OBJECT(-1)) \ | |
1401 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ | |
1402 address branch_pc = pc; \ | |
1403 UPDATE_PC_AND_TOS(skip, -2); \ | |
1404 DO_BACKEDGE_CHECKS(skip, branch_pc); \ | |
1405 CONTINUE; \ | |
1406 } | |
1407 | |
1408 #define NULL_COMPARISON_NOT_OP(name) \ | |
1409 CASE(_if##name): { \ | |
520
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
196
diff
changeset
|
1410 int skip = (!(STACK_OBJECT(-1) == NULL)) \ |
0 | 1411 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ |
1412 address branch_pc = pc; \ | |
1413 UPDATE_PC_AND_TOS(skip, -1); \ | |
1414 DO_BACKEDGE_CHECKS(skip, branch_pc); \ | |
1415 CONTINUE; \ | |
1416 } | |
1417 | |
1418 #define NULL_COMPARISON_OP(name) \ | |
1419 CASE(_if##name): { \ | |
520
52a431267315
6791168: Fix invalid code in bytecodeInterpreter that can cause gcc ICE
coleenp
parents:
196
diff
changeset
|
1420 int skip = ((STACK_OBJECT(-1) == NULL)) \ |
0 | 1421 ? (int16_t)Bytes::get_Java_u2(pc + 1) : 3; \ |
1422 address branch_pc = pc; \ | |
1423 UPDATE_PC_AND_TOS(skip, -1); \ | |
1424 DO_BACKEDGE_CHECKS(skip, branch_pc); \ | |
1425 CONTINUE; \ | |
1426 } | |
1427 COMPARISON_OP(lt, <); | |
1428 COMPARISON_OP(gt, >); | |
1429 COMPARISON_OP(le, <=); | |
1430 COMPARISON_OP(ge, >=); | |
1431 COMPARISON_OP2(eq, ==); /* include ref comparison */ | |
1432 COMPARISON_OP2(ne, !=); /* include ref comparison */ | |
1433 NULL_COMPARISON_OP(null); | |
1434 NULL_COMPARISON_NOT_OP(nonnull); | |
1435 | |
1436 /* Goto pc at specified offset in switch table. */ | |
1437 | |
1438 CASE(_tableswitch): { | |
1439 jint* lpc = (jint*)VMalignWordUp(pc+1); | |
1440 int32_t key = STACK_INT(-1); | |
1441 int32_t low = Bytes::get_Java_u4((address)&lpc[1]); | |
1442 int32_t high = Bytes::get_Java_u4((address)&lpc[2]); | |
1443 int32_t skip; | |
1444 key -= low; | |
1445 skip = ((uint32_t) key > (uint32_t)(high - low)) | |
1446 ? Bytes::get_Java_u4((address)&lpc[0]) | |
1447 : Bytes::get_Java_u4((address)&lpc[key + 3]); | |
1448 // Does this really need a full backedge check (osr?) | |
1449 address branch_pc = pc; | |
1450 UPDATE_PC_AND_TOS(skip, -1); | |
1451 DO_BACKEDGE_CHECKS(skip, branch_pc); | |
1452 CONTINUE; | |
1453 } | |
1454 | |
1455 /* Goto pc whose table entry matches specified key */ | |
1456 | |
1457 CASE(_lookupswitch): { | |
1458 jint* lpc = (jint*)VMalignWordUp(pc+1); | |
1459 int32_t key = STACK_INT(-1); | |
1460 int32_t skip = Bytes::get_Java_u4((address) lpc); /* default amount */ | |
1461 int32_t npairs = Bytes::get_Java_u4((address) &lpc[1]); | |
1462 while (--npairs >= 0) { | |
1463 lpc += 2; | |
1464 if (key == (int32_t)Bytes::get_Java_u4((address)lpc)) { | |
1465 skip = Bytes::get_Java_u4((address)&lpc[1]); | |
1466 break; | |
1467 } | |
1468 } | |
1469 address branch_pc = pc; | |
1470 UPDATE_PC_AND_TOS(skip, -1); | |
1471 DO_BACKEDGE_CHECKS(skip, branch_pc); | |
1472 CONTINUE; | |
1473 } | |
1474 | |
1475 CASE(_fcmpl): | |
1476 CASE(_fcmpg): | |
1477 { | |
1478 SET_STACK_INT(VMfloatCompare(STACK_FLOAT(-2), | |
1479 STACK_FLOAT(-1), | |
1480 (opcode == Bytecodes::_fcmpl ? -1 : 1)), | |
1481 -2); | |
1482 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); | |
1483 } | |
1484 | |
1485 CASE(_dcmpl): | |
1486 CASE(_dcmpg): | |
1487 { | |
1488 int r = VMdoubleCompare(STACK_DOUBLE(-3), | |
1489 STACK_DOUBLE(-1), | |
1490 (opcode == Bytecodes::_dcmpl ? -1 : 1)); | |
1491 MORE_STACK(-4); // Pop | |
1492 SET_STACK_INT(r, 0); | |
1493 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1494 } | |
1495 | |
1496 CASE(_lcmp): | |
1497 { | |
1498 int r = VMlongCompare(STACK_LONG(-3), STACK_LONG(-1)); | |
1499 MORE_STACK(-4); | |
1500 SET_STACK_INT(r, 0); | |
1501 UPDATE_PC_AND_TOS_AND_CONTINUE(1, 1); | |
1502 } | |
1503 | |
1504 | |
1505 /* Return from a method */ | |
1506 | |
1507 CASE(_areturn): | |
1508 CASE(_ireturn): | |
1509 CASE(_freturn): | |
1510 { | |
1511 // Allow a safepoint before returning to frame manager. | |
1512 SAFEPOINT; | |
1513 | |
1514 goto handle_return; | |
1515 } | |
1516 | |
1517 CASE(_lreturn): | |
1518 CASE(_dreturn): | |
1519 { | |
1520 // Allow a safepoint before returning to frame manager. | |
1521 SAFEPOINT; | |
1522 goto handle_return; | |
1523 } | |
1524 | |
1525 CASE(_return_register_finalizer): { | |
1526 | |
1527 oop rcvr = LOCALS_OBJECT(0); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1528 VERIFY_OOP(rcvr); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1529 if (rcvr->klass()->has_finalizer()) { |
0 | 1530 CALL_VM(InterpreterRuntime::register_finalizer(THREAD, rcvr), handle_exception); |
1531 } | |
1532 goto handle_return; | |
1533 } | |
1534 CASE(_return): { | |
1535 | |
1536 // Allow a safepoint before returning to frame manager. | |
1537 SAFEPOINT; | |
1538 goto handle_return; | |
1539 } | |
1540 | |
1541 /* Array access byte-codes */ | |
1542 | |
1543 /* Every array access byte-code starts out like this */ | |
1544 // arrayOopDesc* arrObj = (arrayOopDesc*)STACK_OBJECT(arrayOff); | |
1545 #define ARRAY_INTRO(arrayOff) \ | |
1546 arrayOop arrObj = (arrayOop)STACK_OBJECT(arrayOff); \ | |
1547 jint index = STACK_INT(arrayOff + 1); \ | |
1548 char message[jintAsStringSize]; \ | |
1549 CHECK_NULL(arrObj); \ | |
1550 if ((uint32_t)index >= (uint32_t)arrObj->length()) { \ | |
1551 sprintf(message, "%d", index); \ | |
1552 VM_JAVA_ERROR(vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), \ | |
1553 message); \ | |
1554 } | |
1555 | |
1556 /* 32-bit loads. These handle conversion from < 32-bit types */ | |
1557 #define ARRAY_LOADTO32(T, T2, format, stackRes, extra) \ | |
1558 { \ | |
1559 ARRAY_INTRO(-2); \ | |
1560 extra; \ | |
1561 SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), \ | |
1562 -2); \ | |
1563 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); \ | |
1564 } | |
1565 | |
1566 /* 64-bit loads */ | |
1567 #define ARRAY_LOADTO64(T,T2, stackRes, extra) \ | |
1568 { \ | |
1569 ARRAY_INTRO(-2); \ | |
1570 SET_ ## stackRes(*(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)), -1); \ | |
1571 extra; \ | |
1572 UPDATE_PC_AND_CONTINUE(1); \ | |
1573 } | |
1574 | |
1575 CASE(_iaload): | |
1576 ARRAY_LOADTO32(T_INT, jint, "%d", STACK_INT, 0); | |
1577 CASE(_faload): | |
1578 ARRAY_LOADTO32(T_FLOAT, jfloat, "%f", STACK_FLOAT, 0); | |
1579 CASE(_aaload): | |
1580 ARRAY_LOADTO32(T_OBJECT, oop, INTPTR_FORMAT, STACK_OBJECT, 0); | |
1581 CASE(_baload): | |
1582 ARRAY_LOADTO32(T_BYTE, jbyte, "%d", STACK_INT, 0); | |
1583 CASE(_caload): | |
1584 ARRAY_LOADTO32(T_CHAR, jchar, "%d", STACK_INT, 0); | |
1585 CASE(_saload): | |
1586 ARRAY_LOADTO32(T_SHORT, jshort, "%d", STACK_INT, 0); | |
1587 CASE(_laload): | |
1588 ARRAY_LOADTO64(T_LONG, jlong, STACK_LONG, 0); | |
1589 CASE(_daload): | |
1590 ARRAY_LOADTO64(T_DOUBLE, jdouble, STACK_DOUBLE, 0); | |
1591 | |
1592 /* 32-bit stores. These handle conversion to < 32-bit types */ | |
1593 #define ARRAY_STOREFROM32(T, T2, format, stackSrc, extra) \ | |
1594 { \ | |
1595 ARRAY_INTRO(-3); \ | |
1596 extra; \ | |
1597 *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \ | |
1598 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); \ | |
1599 } | |
1600 | |
1601 /* 64-bit stores */ | |
1602 #define ARRAY_STOREFROM64(T, T2, stackSrc, extra) \ | |
1603 { \ | |
1604 ARRAY_INTRO(-4); \ | |
1605 extra; \ | |
1606 *(T2 *)(((address) arrObj->base(T)) + index * sizeof(T2)) = stackSrc( -1); \ | |
1607 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -4); \ | |
1608 } | |
1609 | |
1610 CASE(_iastore): | |
1611 ARRAY_STOREFROM32(T_INT, jint, "%d", STACK_INT, 0); | |
1612 CASE(_fastore): | |
1613 ARRAY_STOREFROM32(T_FLOAT, jfloat, "%f", STACK_FLOAT, 0); | |
1614 /* | |
1615 * This one looks different because of the assignability check | |
1616 */ | |
1617 CASE(_aastore): { | |
1618 oop rhsObject = STACK_OBJECT(-1); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1619 VERIFY_OOP(rhsObject); |
0 | 1620 ARRAY_INTRO( -3); |
1621 // arrObj, index are set | |
1622 if (rhsObject != NULL) { | |
1623 /* Check assignability of rhsObject into arrObj */ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1624 Klass* rhsKlassOop = rhsObject->klass(); // EBX (subclass) |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
1625 Klass* elemKlassOop = ObjArrayKlass::cast(arrObj->klass())->element_klass(); // superklass EAX |
0 | 1626 // |
1627 // Check for compatibilty. This check must not GC!! | |
1628 // Seems way more expensive now that we must dispatch | |
1629 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1630 if (rhsKlassOop != elemKlassOop && !rhsKlassOop->is_subtype_of(elemKlassOop)) { // ebx->is... |
0 | 1631 VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), ""); |
1632 } | |
1633 } | |
1634 oop* elem_loc = (oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)); | |
1635 // *(oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)) = rhsObject; | |
1636 *elem_loc = rhsObject; | |
1637 // Mark the card | |
1638 OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)elem_loc >> CardTableModRefBS::card_shift], 0); | |
1639 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); | |
1640 } | |
1641 CASE(_bastore): | |
1642 ARRAY_STOREFROM32(T_BYTE, jbyte, "%d", STACK_INT, 0); | |
1643 CASE(_castore): | |
1644 ARRAY_STOREFROM32(T_CHAR, jchar, "%d", STACK_INT, 0); | |
1645 CASE(_sastore): | |
1646 ARRAY_STOREFROM32(T_SHORT, jshort, "%d", STACK_INT, 0); | |
1647 CASE(_lastore): | |
1648 ARRAY_STOREFROM64(T_LONG, jlong, STACK_LONG, 0); | |
1649 CASE(_dastore): | |
1650 ARRAY_STOREFROM64(T_DOUBLE, jdouble, STACK_DOUBLE, 0); | |
1651 | |
1652 CASE(_arraylength): | |
1653 { | |
1654 arrayOop ary = (arrayOop) STACK_OBJECT(-1); | |
1655 CHECK_NULL(ary); | |
1656 SET_STACK_INT(ary->length(), -1); | |
1657 UPDATE_PC_AND_CONTINUE(1); | |
1658 } | |
1659 | |
1660 /* monitorenter and monitorexit for locking/unlocking an object */ | |
1661 | |
1662 CASE(_monitorenter): { | |
1663 oop lockee = STACK_OBJECT(-1); | |
1664 // derefing's lockee ought to provoke implicit null check | |
1665 CHECK_NULL(lockee); | |
1666 // find a free monitor or one already allocated for this object | |
1667 // if we find a matching object then we need a new monitor | |
1668 // since this is recursive enter | |
1669 BasicObjectLock* limit = istate->monitor_base(); | |
1670 BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); | |
1671 BasicObjectLock* entry = NULL; | |
1672 while (most_recent != limit ) { | |
1673 if (most_recent->obj() == NULL) entry = most_recent; | |
1674 else if (most_recent->obj() == lockee) break; | |
1675 most_recent++; | |
1676 } | |
1677 if (entry != NULL) { | |
1678 entry->set_obj(lockee); | |
1679 markOop displaced = lockee->mark()->set_unlocked(); | |
1680 entry->lock()->set_displaced_header(displaced); | |
1681 if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { | |
1682 // Is it simple recursive case? | |
1683 if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { | |
1684 entry->lock()->set_displaced_header(NULL); | |
1685 } else { | |
1686 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); | |
1687 } | |
1688 } | |
1689 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); | |
1690 } else { | |
1691 istate->set_msg(more_monitors); | |
1692 UPDATE_PC_AND_RETURN(0); // Re-execute | |
1693 } | |
1694 } | |
1695 | |
1696 CASE(_monitorexit): { | |
1697 oop lockee = STACK_OBJECT(-1); | |
1698 CHECK_NULL(lockee); | |
1699 // derefing's lockee ought to provoke implicit null check | |
1700 // find our monitor slot | |
1701 BasicObjectLock* limit = istate->monitor_base(); | |
1702 BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); | |
1703 while (most_recent != limit ) { | |
1704 if ((most_recent)->obj() == lockee) { | |
1705 BasicLock* lock = most_recent->lock(); | |
1706 markOop header = lock->displaced_header(); | |
1707 most_recent->set_obj(NULL); | |
1708 // If it isn't recursive we either must swap old header or call the runtime | |
1709 if (header != NULL) { | |
1710 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { | |
1711 // restore object for the slow case | |
1712 most_recent->set_obj(lockee); | |
1713 CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception); | |
1714 } | |
1715 } | |
1716 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); | |
1717 } | |
1718 most_recent++; | |
1719 } | |
1720 // Need to throw illegal monitor state exception | |
1721 CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception); | |
2480 | 1722 ShouldNotReachHere(); |
0 | 1723 } |
1724 | |
1725 /* All of the non-quick opcodes. */ | |
1726 | |
1727 /* -Set clobbersCpIndex true if the quickened opcode clobbers the | |
1728 * constant pool index in the instruction. | |
1729 */ | |
1730 CASE(_getfield): | |
1731 CASE(_getstatic): | |
1732 { | |
1733 u2 index; | |
1734 ConstantPoolCacheEntry* cache; | |
1735 index = Bytes::get_native_u2(pc+1); | |
1736 | |
1737 // QQQ Need to make this as inlined as possible. Probably need to | |
1738 // split all the bytecode cases out so c++ compiler has a chance | |
1739 // for constant prop to fold everything possible away. | |
1740 | |
1741 cache = cp->entry_at(index); | |
1742 if (!cache->is_resolved((Bytecodes::Code)opcode)) { | |
1743 CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), | |
1744 handle_exception); | |
1745 cache = cp->entry_at(index); | |
1746 } | |
1747 | |
1748 #ifdef VM_JVMTI | |
1749 if (_jvmti_interp_events) { | |
1750 int *count_addr; | |
1751 oop obj; | |
1752 // Check to see if a field modification watch has been set | |
1753 // before we take the time to call into the VM. | |
1754 count_addr = (int *)JvmtiExport::get_field_access_count_addr(); | |
1755 if ( *count_addr > 0 ) { | |
1756 if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { | |
1757 obj = (oop)NULL; | |
1758 } else { | |
1759 obj = (oop) STACK_OBJECT(-1); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1760 VERIFY_OOP(obj); |
0 | 1761 } |
1762 CALL_VM(InterpreterRuntime::post_field_access(THREAD, | |
1763 obj, | |
1764 cache), | |
1765 handle_exception); | |
1766 } | |
1767 } | |
1768 #endif /* VM_JVMTI */ | |
1769 | |
1770 oop obj; | |
1771 if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { | |
6926 | 1772 Klass* k = cache->f1_as_klass(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1773 obj = k->java_mirror(); |
0 | 1774 MORE_STACK(1); // Assume single slot push |
1775 } else { | |
1776 obj = (oop) STACK_OBJECT(-1); | |
1777 CHECK_NULL(obj); | |
1778 } | |
1779 | |
1780 // | |
1781 // Now store the result on the stack | |
1782 // | |
1783 TosState tos_type = cache->flag_state(); | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
1784 int field_offset = cache->f2_as_index(); |
0 | 1785 if (cache->is_volatile()) { |
1786 if (tos_type == atos) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1787 VERIFY_OOP(obj->obj_field_acquire(field_offset)); |
0 | 1788 SET_STACK_OBJECT(obj->obj_field_acquire(field_offset), -1); |
1789 } else if (tos_type == itos) { | |
1790 SET_STACK_INT(obj->int_field_acquire(field_offset), -1); | |
1791 } else if (tos_type == ltos) { | |
1792 SET_STACK_LONG(obj->long_field_acquire(field_offset), 0); | |
1793 MORE_STACK(1); | |
1794 } else if (tos_type == btos) { | |
1795 SET_STACK_INT(obj->byte_field_acquire(field_offset), -1); | |
1796 } else if (tos_type == ctos) { | |
1797 SET_STACK_INT(obj->char_field_acquire(field_offset), -1); | |
1798 } else if (tos_type == stos) { | |
1799 SET_STACK_INT(obj->short_field_acquire(field_offset), -1); | |
1800 } else if (tos_type == ftos) { | |
1801 SET_STACK_FLOAT(obj->float_field_acquire(field_offset), -1); | |
1802 } else { | |
1803 SET_STACK_DOUBLE(obj->double_field_acquire(field_offset), 0); | |
1804 MORE_STACK(1); | |
1805 } | |
1806 } else { | |
1807 if (tos_type == atos) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1808 VERIFY_OOP(obj->obj_field(field_offset)); |
0 | 1809 SET_STACK_OBJECT(obj->obj_field(field_offset), -1); |
1810 } else if (tos_type == itos) { | |
1811 SET_STACK_INT(obj->int_field(field_offset), -1); | |
1812 } else if (tos_type == ltos) { | |
1813 SET_STACK_LONG(obj->long_field(field_offset), 0); | |
1814 MORE_STACK(1); | |
1815 } else if (tos_type == btos) { | |
1816 SET_STACK_INT(obj->byte_field(field_offset), -1); | |
1817 } else if (tos_type == ctos) { | |
1818 SET_STACK_INT(obj->char_field(field_offset), -1); | |
1819 } else if (tos_type == stos) { | |
1820 SET_STACK_INT(obj->short_field(field_offset), -1); | |
1821 } else if (tos_type == ftos) { | |
1822 SET_STACK_FLOAT(obj->float_field(field_offset), -1); | |
1823 } else { | |
1824 SET_STACK_DOUBLE(obj->double_field(field_offset), 0); | |
1825 MORE_STACK(1); | |
1826 } | |
1827 } | |
1828 | |
1829 UPDATE_PC_AND_CONTINUE(3); | |
1830 } | |
1831 | |
1832 CASE(_putfield): | |
1833 CASE(_putstatic): | |
1834 { | |
1835 u2 index = Bytes::get_native_u2(pc+1); | |
1836 ConstantPoolCacheEntry* cache = cp->entry_at(index); | |
1837 if (!cache->is_resolved((Bytecodes::Code)opcode)) { | |
1838 CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), | |
1839 handle_exception); | |
1840 cache = cp->entry_at(index); | |
1841 } | |
1842 | |
1843 #ifdef VM_JVMTI | |
1844 if (_jvmti_interp_events) { | |
1845 int *count_addr; | |
1846 oop obj; | |
1847 // Check to see if a field modification watch has been set | |
1848 // before we take the time to call into the VM. | |
1849 count_addr = (int *)JvmtiExport::get_field_modification_count_addr(); | |
1850 if ( *count_addr > 0 ) { | |
1851 if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { | |
1852 obj = (oop)NULL; | |
1853 } | |
1854 else { | |
1855 if (cache->is_long() || cache->is_double()) { | |
1856 obj = (oop) STACK_OBJECT(-3); | |
1857 } else { | |
1858 obj = (oop) STACK_OBJECT(-2); | |
1859 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1860 VERIFY_OOP(obj); |
0 | 1861 } |
1862 | |
1863 CALL_VM(InterpreterRuntime::post_field_modification(THREAD, | |
1864 obj, | |
1865 cache, | |
1866 (jvalue *)STACK_SLOT(-1)), | |
1867 handle_exception); | |
1868 } | |
1869 } | |
1870 #endif /* VM_JVMTI */ | |
1871 | |
1872 // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases | |
1873 // out so c++ compiler has a chance for constant prop to fold everything possible away. | |
1874 | |
1875 oop obj; | |
1876 int count; | |
1877 TosState tos_type = cache->flag_state(); | |
1878 | |
1879 count = -1; | |
1880 if (tos_type == ltos || tos_type == dtos) { | |
1881 --count; | |
1882 } | |
1883 if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) { | |
6926 | 1884 Klass* k = cache->f1_as_klass(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1885 obj = k->java_mirror(); |
0 | 1886 } else { |
1887 --count; | |
1888 obj = (oop) STACK_OBJECT(count); | |
1889 CHECK_NULL(obj); | |
1890 } | |
1891 | |
1892 // | |
1893 // Now store the result | |
1894 // | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
1895 int field_offset = cache->f2_as_index(); |
0 | 1896 if (cache->is_volatile()) { |
1897 if (tos_type == itos) { | |
1898 obj->release_int_field_put(field_offset, STACK_INT(-1)); | |
1899 } else if (tos_type == atos) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1900 VERIFY_OOP(STACK_OBJECT(-1)); |
0 | 1901 obj->release_obj_field_put(field_offset, STACK_OBJECT(-1)); |
1902 OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); | |
1903 } else if (tos_type == btos) { | |
1904 obj->release_byte_field_put(field_offset, STACK_INT(-1)); | |
1905 } else if (tos_type == ltos) { | |
1906 obj->release_long_field_put(field_offset, STACK_LONG(-1)); | |
1907 } else if (tos_type == ctos) { | |
1908 obj->release_char_field_put(field_offset, STACK_INT(-1)); | |
1909 } else if (tos_type == stos) { | |
1910 obj->release_short_field_put(field_offset, STACK_INT(-1)); | |
1911 } else if (tos_type == ftos) { | |
1912 obj->release_float_field_put(field_offset, STACK_FLOAT(-1)); | |
1913 } else { | |
1914 obj->release_double_field_put(field_offset, STACK_DOUBLE(-1)); | |
1915 } | |
1916 OrderAccess::storeload(); | |
1917 } else { | |
1918 if (tos_type == itos) { | |
1919 obj->int_field_put(field_offset, STACK_INT(-1)); | |
1920 } else if (tos_type == atos) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1921 VERIFY_OOP(STACK_OBJECT(-1)); |
0 | 1922 obj->obj_field_put(field_offset, STACK_OBJECT(-1)); |
1923 OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); | |
1924 } else if (tos_type == btos) { | |
1925 obj->byte_field_put(field_offset, STACK_INT(-1)); | |
1926 } else if (tos_type == ltos) { | |
1927 obj->long_field_put(field_offset, STACK_LONG(-1)); | |
1928 } else if (tos_type == ctos) { | |
1929 obj->char_field_put(field_offset, STACK_INT(-1)); | |
1930 } else if (tos_type == stos) { | |
1931 obj->short_field_put(field_offset, STACK_INT(-1)); | |
1932 } else if (tos_type == ftos) { | |
1933 obj->float_field_put(field_offset, STACK_FLOAT(-1)); | |
1934 } else { | |
1935 obj->double_field_put(field_offset, STACK_DOUBLE(-1)); | |
1936 } | |
1937 } | |
1938 | |
1939 UPDATE_PC_AND_TOS_AND_CONTINUE(3, count); | |
1940 } | |
1941 | |
1942 CASE(_new): { | |
1943 u2 index = Bytes::get_Java_u2(pc+1); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1944 ConstantPool* constants = istate->method()->constants(); |
0 | 1945 if (!constants->tag_at(index).is_unresolved_klass()) { |
1946 // Make sure klass is initialized and doesn't have a finalizer | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1947 Klass* entry = constants->slot_at(index).get_klass(); |
0 | 1948 assert(entry->is_klass(), "Should be resolved klass"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1949 Klass* k_entry = (Klass*) entry; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1950 assert(k_entry->oop_is_instance(), "Should be InstanceKlass"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
1951 InstanceKlass* ik = (InstanceKlass*) k_entry; |
0 | 1952 if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) { |
1953 size_t obj_size = ik->size_helper(); | |
1954 oop result = NULL; | |
1955 // If the TLAB isn't pre-zeroed then we'll have to do it | |
1956 bool need_zero = !ZeroTLAB; | |
1957 if (UseTLAB) { | |
1958 result = (oop) THREAD->tlab().allocate(obj_size); | |
1959 } | |
1960 if (result == NULL) { | |
1961 need_zero = true; | |
1962 // Try allocate in shared eden | |
1963 retry: | |
1964 HeapWord* compare_to = *Universe::heap()->top_addr(); | |
1965 HeapWord* new_top = compare_to + obj_size; | |
1966 if (new_top <= *Universe::heap()->end_addr()) { | |
1967 if (Atomic::cmpxchg_ptr(new_top, Universe::heap()->top_addr(), compare_to) != compare_to) { | |
1968 goto retry; | |
1969 } | |
1970 result = (oop) compare_to; | |
1971 } | |
1972 } | |
1973 if (result != NULL) { | |
1974 // Initialize object (if nonzero size and need) and then the header | |
1975 if (need_zero ) { | |
1976 HeapWord* to_zero = (HeapWord*) result + sizeof(oopDesc) / oopSize; | |
1977 obj_size -= sizeof(oopDesc) / oopSize; | |
1978 if (obj_size > 0 ) { | |
1979 memset(to_zero, 0, obj_size * HeapWordSize); | |
1980 } | |
1981 } | |
1982 if (UseBiasedLocking) { | |
1983 result->set_mark(ik->prototype_header()); | |
1984 } else { | |
1985 result->set_mark(markOopDesc::prototype()); | |
1986 } | |
167
feeb96a45707
6696264: assert("narrow oop can never be zero") for GCBasher & ParNewGC
coleenp
parents:
123
diff
changeset
|
1987 result->set_klass_gap(0); |
0 | 1988 result->set_klass(k_entry); |
1989 SET_STACK_OBJECT(result, 0); | |
1990 UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); | |
1991 } | |
1992 } | |
1993 } | |
1994 // Slow case allocation | |
1995 CALL_VM(InterpreterRuntime::_new(THREAD, METHOD->constants(), index), | |
1996 handle_exception); | |
1997 SET_STACK_OBJECT(THREAD->vm_result(), 0); | |
1998 THREAD->set_vm_result(NULL); | |
1999 UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); | |
2000 } | |
2001 CASE(_anewarray): { | |
2002 u2 index = Bytes::get_Java_u2(pc+1); | |
2003 jint size = STACK_INT(-1); | |
2004 CALL_VM(InterpreterRuntime::anewarray(THREAD, METHOD->constants(), index, size), | |
2005 handle_exception); | |
2006 SET_STACK_OBJECT(THREAD->vm_result(), -1); | |
2007 THREAD->set_vm_result(NULL); | |
2008 UPDATE_PC_AND_CONTINUE(3); | |
2009 } | |
2010 CASE(_multianewarray): { | |
2011 jint dims = *(pc+3); | |
2012 jint size = STACK_INT(-1); | |
2013 // stack grows down, dimensions are up! | |
2014 jint *dimarray = | |
1509 | 2015 (jint*)&topOfStack[dims * Interpreter::stackElementWords+ |
2016 Interpreter::stackElementWords-1]; | |
0 | 2017 //adjust pointer to start of stack element |
2018 CALL_VM(InterpreterRuntime::multianewarray(THREAD, dimarray), | |
2019 handle_exception); | |
2020 SET_STACK_OBJECT(THREAD->vm_result(), -dims); | |
2021 THREAD->set_vm_result(NULL); | |
2022 UPDATE_PC_AND_TOS_AND_CONTINUE(4, -(dims-1)); | |
2023 } | |
2024 CASE(_checkcast): | |
2025 if (STACK_OBJECT(-1) != NULL) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2026 VERIFY_OOP(STACK_OBJECT(-1)); |
0 | 2027 u2 index = Bytes::get_Java_u2(pc+1); |
2028 if (ProfileInterpreter) { | |
2029 // needs Profile_checkcast QQQ | |
2030 ShouldNotReachHere(); | |
2031 } | |
2032 // Constant pool may have actual klass or unresolved klass. If it is | |
2033 // unresolved we must resolve it | |
2034 if (METHOD->constants()->tag_at(index).is_unresolved_klass()) { | |
2035 CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception); | |
2036 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2037 Klass* klassOf = (Klass*) METHOD->constants()->slot_at(index).get_klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2038 Klass* objKlassOop = STACK_OBJECT(-1)->klass(); //ebx |
0 | 2039 // |
2040 // Check for compatibilty. This check must not GC!! | |
2041 // Seems way more expensive now that we must dispatch | |
2042 // | |
2043 if (objKlassOop != klassOf && | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2044 !objKlassOop->is_subtype_of(klassOf)) { |
0 | 2045 ResourceMark rm(THREAD); |
6983 | 2046 const char* objName = objKlassOop->external_name(); |
2047 const char* klassName = klassOf->external_name(); | |
0 | 2048 char* message = SharedRuntime::generate_class_cast_message( |
2049 objName, klassName); | |
2050 VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message); | |
2051 } | |
2052 } else { | |
2053 if (UncommonNullCast) { | |
2054 // istate->method()->set_null_cast_seen(); | |
2055 // [RGV] Not sure what to do here! | |
2056 | |
2057 } | |
2058 } | |
2059 UPDATE_PC_AND_CONTINUE(3); | |
2060 | |
2061 CASE(_instanceof): | |
2062 if (STACK_OBJECT(-1) == NULL) { | |
2063 SET_STACK_INT(0, -1); | |
2064 } else { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2065 VERIFY_OOP(STACK_OBJECT(-1)); |
0 | 2066 u2 index = Bytes::get_Java_u2(pc+1); |
2067 // Constant pool may have actual klass or unresolved klass. If it is | |
2068 // unresolved we must resolve it | |
2069 if (METHOD->constants()->tag_at(index).is_unresolved_klass()) { | |
2070 CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception); | |
2071 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2072 Klass* klassOf = (Klass*) METHOD->constants()->slot_at(index).get_klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2073 Klass* objKlassOop = STACK_OBJECT(-1)->klass(); |
0 | 2074 // |
2075 // Check for compatibilty. This check must not GC!! | |
2076 // Seems way more expensive now that we must dispatch | |
2077 // | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2078 if ( objKlassOop == klassOf || objKlassOop->is_subtype_of(klassOf)) { |
0 | 2079 SET_STACK_INT(1, -1); |
2080 } else { | |
2081 SET_STACK_INT(0, -1); | |
2082 } | |
2083 } | |
2084 UPDATE_PC_AND_CONTINUE(3); | |
2085 | |
2086 CASE(_ldc_w): | |
2087 CASE(_ldc): | |
2088 { | |
2089 u2 index; | |
2090 bool wide = false; | |
2091 int incr = 2; // frequent case | |
2092 if (opcode == Bytecodes::_ldc) { | |
2093 index = pc[1]; | |
2094 } else { | |
2095 index = Bytes::get_Java_u2(pc+1); | |
2096 incr = 3; | |
2097 wide = true; | |
2098 } | |
2099 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2100 ConstantPool* constants = METHOD->constants(); |
0 | 2101 switch (constants->tag_at(index).value()) { |
2102 case JVM_CONSTANT_Integer: | |
2103 SET_STACK_INT(constants->int_at(index), 0); | |
2104 break; | |
2105 | |
2106 case JVM_CONSTANT_Float: | |
2107 SET_STACK_FLOAT(constants->float_at(index), 0); | |
2108 break; | |
2109 | |
2110 case JVM_CONSTANT_String: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2111 { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2112 oop result = constants->resolved_references()->obj_at(index); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2113 if (result == NULL) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2114 CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), handle_exception); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2115 SET_STACK_OBJECT(THREAD->vm_result(), 0); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2116 THREAD->set_vm_result(NULL); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2117 } else { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2118 VERIFY_OOP(result); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2119 SET_STACK_OBJECT(result, 0); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2120 } |
0 | 2121 break; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2122 } |
0 | 2123 |
2124 case JVM_CONSTANT_Class: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2260
diff
changeset
|
2125 VERIFY_OOP(constants->resolved_klass_at(index)->java_mirror()); |
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2260
diff
changeset
|
2126 SET_STACK_OBJECT(constants->resolved_klass_at(index)->java_mirror(), 0); |
0 | 2127 break; |
2128 | |
2129 case JVM_CONSTANT_UnresolvedClass: | |
2130 case JVM_CONSTANT_UnresolvedClassInError: | |
2131 CALL_VM(InterpreterRuntime::ldc(THREAD, wide), handle_exception); | |
2132 SET_STACK_OBJECT(THREAD->vm_result(), 0); | |
2133 THREAD->set_vm_result(NULL); | |
2134 break; | |
2135 | |
2136 default: ShouldNotReachHere(); | |
2137 } | |
2138 UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); | |
2139 } | |
2140 | |
2141 CASE(_ldc2_w): | |
2142 { | |
2143 u2 index = Bytes::get_Java_u2(pc+1); | |
2144 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2145 ConstantPool* constants = METHOD->constants(); |
0 | 2146 switch (constants->tag_at(index).value()) { |
2147 | |
2148 case JVM_CONSTANT_Long: | |
2149 SET_STACK_LONG(constants->long_at(index), 1); | |
2150 break; | |
2151 | |
2152 case JVM_CONSTANT_Double: | |
2153 SET_STACK_DOUBLE(constants->double_at(index), 1); | |
2154 break; | |
2155 default: ShouldNotReachHere(); | |
2156 } | |
2157 UPDATE_PC_AND_TOS_AND_CONTINUE(3, 2); | |
2158 } | |
2159 | |
2480 | 2160 CASE(_fast_aldc_w): |
2161 CASE(_fast_aldc): { | |
2162 u2 index; | |
2163 int incr; | |
2164 if (opcode == Bytecodes::_fast_aldc) { | |
2165 index = pc[1]; | |
2166 incr = 2; | |
2167 } else { | |
2168 index = Bytes::get_native_u2(pc+1); | |
2169 incr = 3; | |
2170 } | |
2171 | |
2172 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) | |
2173 // This kind of CP cache entry does not need to match the flags byte, because | |
2174 // there is a 1-1 relation between bytecode type and CP entry type. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2175 ConstantPool* constants = METHOD->constants(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2176 oop result = constants->resolved_references()->obj_at(index); |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
2177 if (result == NULL) { |
2480 | 2178 CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), |
2179 handle_exception); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2180 result = THREAD->vm_result(); |
2480 | 2181 } |
2182 | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
2183 VERIFY_OOP(result); |
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
2184 SET_STACK_OBJECT(result, 0); |
2480 | 2185 UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); |
2186 } | |
2187 | |
2188 CASE(_invokedynamic): { | |
6926 | 2189 |
2480 | 2190 if (!EnableInvokeDynamic) { |
2191 // We should not encounter this bytecode if !EnableInvokeDynamic. | |
2192 // The verifier will stop it. However, if we get past the verifier, | |
2193 // this will stop the thread in a reasonable way, without crashing the JVM. | |
2194 CALL_VM(InterpreterRuntime::throw_IncompatibleClassChangeError(THREAD), | |
2195 handle_exception); | |
2196 ShouldNotReachHere(); | |
2197 } | |
2198 | |
6926 | 2199 u4 index = Bytes::get_native_u4(pc+1); |
2200 ConstantPoolCacheEntry* cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index); | |
2480 | 2201 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2202 // We are resolved if the resolved_references field contains a non-null object (CallSite, etc.) |
2480 | 2203 // This kind of CP cache entry does not need to match the flags byte, because |
2204 // there is a 1-1 relation between bytecode type and CP entry type. | |
6926 | 2205 if (! cache->is_resolved((Bytecodes::Code) opcode)) { |
2480 | 2206 CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD), |
2207 handle_exception); | |
6926 | 2208 cache = cp->constant_pool()->invokedynamic_cp_cache_entry_at(index); |
2209 } | |
2210 | |
2211 Method* method = cache->f1_as_method(); | |
2212 VERIFY_OOP(method); | |
2213 | |
2214 if (cache->has_appendix()) { | |
2215 ConstantPool* constants = METHOD->constants(); | |
2216 SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0); | |
2217 MORE_STACK(1); | |
2218 } | |
2219 | |
2220 istate->set_msg(call_method); | |
2221 istate->set_callee(method); | |
2222 istate->set_callee_entry_point(method->from_interpreted_entry()); | |
2223 istate->set_bcp_advance(5); | |
2224 | |
2225 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2226 } | |
2227 | |
2228 CASE(_invokehandle): { | |
2229 | |
2230 if (!EnableInvokeDynamic) { | |
2231 ShouldNotReachHere(); | |
2480 | 2232 } |
2233 | |
6926 | 2234 u2 index = Bytes::get_native_u2(pc+1); |
2235 ConstantPoolCacheEntry* cache = cp->entry_at(index); | |
2236 | |
2237 if (! cache->is_resolved((Bytecodes::Code) opcode)) { | |
2238 CALL_VM(InterpreterRuntime::resolve_invokehandle(THREAD), | |
2239 handle_exception); | |
2240 cache = cp->entry_at(index); | |
2241 } | |
2242 | |
2243 Method* method = cache->f1_as_method(); | |
2244 | |
2245 VERIFY_OOP(method); | |
2246 | |
2247 if (cache->has_appendix()) { | |
2248 ConstantPool* constants = METHOD->constants(); | |
2249 SET_STACK_OBJECT(cache->appendix_if_resolved(constants), 0); | |
2250 MORE_STACK(1); | |
2251 } | |
2252 | |
2253 istate->set_msg(call_method); | |
2254 istate->set_callee(method); | |
2255 istate->set_callee_entry_point(method->from_interpreted_entry()); | |
2256 istate->set_bcp_advance(3); | |
2480 | 2257 |
2258 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2259 } | |
2260 | |
0 | 2261 CASE(_invokeinterface): { |
2262 u2 index = Bytes::get_native_u2(pc+1); | |
2263 | |
2264 // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases | |
2265 // out so c++ compiler has a chance for constant prop to fold everything possible away. | |
2266 | |
2267 ConstantPoolCacheEntry* cache = cp->entry_at(index); | |
2268 if (!cache->is_resolved((Bytecodes::Code)opcode)) { | |
2269 CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), | |
2270 handle_exception); | |
2271 cache = cp->entry_at(index); | |
2272 } | |
2273 | |
2274 istate->set_msg(call_method); | |
2275 | |
2276 // Special case of invokeinterface called for virtual method of | |
2277 // java.lang.Object. See cpCacheOop.cpp for details. | |
2278 // This code isn't produced by javac, but could be produced by | |
2279 // another compliant java compiler. | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
2280 if (cache->is_forced_virtual()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2281 Method* callee; |
0 | 2282 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); |
2283 if (cache->is_vfinal()) { | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
2284 callee = cache->f2_as_vfinal_method(); |
0 | 2285 } else { |
2286 // get receiver | |
2287 int parms = cache->parameter_size(); | |
2288 // Same comments as invokevirtual apply here | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2289 VERIFY_OOP(STACK_OBJECT(-parms)); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2290 InstanceKlass* rcvrKlass = (InstanceKlass*) |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2291 STACK_OBJECT(-parms)->klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2292 callee = (Method*) rcvrKlass->start_of_vtable()[ cache->f2_as_index()]; |
0 | 2293 } |
2294 istate->set_callee(callee); | |
2295 istate->set_callee_entry_point(callee->from_interpreted_entry()); | |
2296 #ifdef VM_JVMTI | |
2297 if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { | |
2298 istate->set_callee_entry_point(callee->interpreter_entry()); | |
2299 } | |
2300 #endif /* VM_JVMTI */ | |
2301 istate->set_bcp_advance(5); | |
2302 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2303 } | |
2304 | |
2305 // this could definitely be cleaned up QQQ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2306 Method* callee; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2307 Klass* iclass = cache->f1_as_klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2308 // InstanceKlass* interface = (InstanceKlass*) iclass; |
0 | 2309 // get receiver |
2310 int parms = cache->parameter_size(); | |
2311 oop rcvr = STACK_OBJECT(-parms); | |
2312 CHECK_NULL(rcvr); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2313 InstanceKlass* int2 = (InstanceKlass*) rcvr->klass(); |
0 | 2314 itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable(); |
2315 int i; | |
2316 for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) { | |
2317 if (ki->interface_klass() == iclass) break; | |
2318 } | |
2319 // If the interface isn't found, this class doesn't implement this | |
2320 // interface. The link resolver checks this but only for the first | |
2321 // time this interface is called. | |
2322 if (i == int2->itable_length()) { | |
2323 VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), ""); | |
2324 } | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
2325 int mindex = cache->f2_as_index(); |
0 | 2326 itableMethodEntry* im = ki->first_method_entry(rcvr->klass()); |
2327 callee = im[mindex].method(); | |
2328 if (callee == NULL) { | |
2329 VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), ""); | |
2330 } | |
2331 | |
2332 istate->set_callee(callee); | |
2333 istate->set_callee_entry_point(callee->from_interpreted_entry()); | |
2334 #ifdef VM_JVMTI | |
2335 if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { | |
2336 istate->set_callee_entry_point(callee->interpreter_entry()); | |
2337 } | |
2338 #endif /* VM_JVMTI */ | |
2339 istate->set_bcp_advance(5); | |
2340 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2341 } | |
2342 | |
2343 CASE(_invokevirtual): | |
2344 CASE(_invokespecial): | |
2345 CASE(_invokestatic): { | |
2346 u2 index = Bytes::get_native_u2(pc+1); | |
2347 | |
2348 ConstantPoolCacheEntry* cache = cp->entry_at(index); | |
2349 // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases | |
2350 // out so c++ compiler has a chance for constant prop to fold everything possible away. | |
2351 | |
2352 if (!cache->is_resolved((Bytecodes::Code)opcode)) { | |
2353 CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), | |
2354 handle_exception); | |
2355 cache = cp->entry_at(index); | |
2356 } | |
2357 | |
2358 istate->set_msg(call_method); | |
2359 { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2360 Method* callee; |
0 | 2361 if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) { |
2362 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
2363 if (cache->is_vfinal()) callee = cache->f2_as_vfinal_method(); |
0 | 2364 else { |
2365 // get receiver | |
2366 int parms = cache->parameter_size(); | |
2367 // this works but needs a resourcemark and seems to create a vtable on every call: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2368 // Method* callee = rcvr->klass()->vtable()->method_at(cache->f2_as_index()); |
0 | 2369 // |
2370 // this fails with an assert | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2371 // InstanceKlass* rcvrKlass = InstanceKlass::cast(STACK_OBJECT(-parms)->klass()); |
0 | 2372 // but this works |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2373 VERIFY_OOP(STACK_OBJECT(-parms)); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2374 InstanceKlass* rcvrKlass = (InstanceKlass*) STACK_OBJECT(-parms)->klass(); |
0 | 2375 /* |
2376 Executing this code in java.lang.String: | |
2377 public String(char value[]) { | |
2378 this.count = value.length; | |
2379 this.value = (char[])value.clone(); | |
2380 } | |
2381 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2382 a find on rcvr->klass() reports: |
0 | 2383 {type array char}{type array class} |
2384 - klass: {other class} | |
2385 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2386 but using InstanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2387 because rcvr->klass()->oop_is_instance() == 0 |
0 | 2388 However it seems to have a vtable in the right location. Huh? |
2389 | |
2390 */ | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2391 callee = (Method*) rcvrKlass->start_of_vtable()[ cache->f2_as_index()]; |
0 | 2392 } |
2393 } else { | |
2394 if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) { | |
2395 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); | |
2396 } | |
6266
1d7922586cf6
7023639: JSR 292 method handle invocation needs a fast path for compiled code
twisti
parents:
3960
diff
changeset
|
2397 callee = cache->f1_as_method(); |
0 | 2398 } |
2399 | |
2400 istate->set_callee(callee); | |
2401 istate->set_callee_entry_point(callee->from_interpreted_entry()); | |
2402 #ifdef VM_JVMTI | |
2403 if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { | |
2404 istate->set_callee_entry_point(callee->interpreter_entry()); | |
2405 } | |
2406 #endif /* VM_JVMTI */ | |
2407 istate->set_bcp_advance(3); | |
2408 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2409 } | |
2410 } | |
2411 | |
2412 /* Allocate memory for a new java object. */ | |
2413 | |
2414 CASE(_newarray): { | |
2415 BasicType atype = (BasicType) *(pc+1); | |
2416 jint size = STACK_INT(-1); | |
2417 CALL_VM(InterpreterRuntime::newarray(THREAD, atype, size), | |
2418 handle_exception); | |
2419 SET_STACK_OBJECT(THREAD->vm_result(), -1); | |
2420 THREAD->set_vm_result(NULL); | |
2421 | |
2422 UPDATE_PC_AND_CONTINUE(2); | |
2423 } | |
2424 | |
2425 /* Throw an exception. */ | |
2426 | |
2427 CASE(_athrow): { | |
2428 oop except_oop = STACK_OBJECT(-1); | |
2429 CHECK_NULL(except_oop); | |
2430 // set pending_exception so we use common code | |
2431 THREAD->set_pending_exception(except_oop, NULL, 0); | |
2432 goto handle_exception; | |
2433 } | |
2434 | |
2435 /* goto and jsr. They are exactly the same except jsr pushes | |
2436 * the address of the next instruction first. | |
2437 */ | |
2438 | |
2439 CASE(_jsr): { | |
2440 /* push bytecode index on stack */ | |
2441 SET_STACK_ADDR(((address)pc - (intptr_t)(istate->method()->code_base()) + 3), 0); | |
2442 MORE_STACK(1); | |
2443 /* FALL THROUGH */ | |
2444 } | |
2445 | |
2446 CASE(_goto): | |
2447 { | |
2448 int16_t offset = (int16_t)Bytes::get_Java_u2(pc + 1); | |
2449 address branch_pc = pc; | |
2450 UPDATE_PC(offset); | |
2451 DO_BACKEDGE_CHECKS(offset, branch_pc); | |
2452 CONTINUE; | |
2453 } | |
2454 | |
2455 CASE(_jsr_w): { | |
2456 /* push return address on the stack */ | |
2457 SET_STACK_ADDR(((address)pc - (intptr_t)(istate->method()->code_base()) + 5), 0); | |
2458 MORE_STACK(1); | |
2459 /* FALL THROUGH */ | |
2460 } | |
2461 | |
2462 CASE(_goto_w): | |
2463 { | |
2464 int32_t offset = Bytes::get_Java_u4(pc + 1); | |
2465 address branch_pc = pc; | |
2466 UPDATE_PC(offset); | |
2467 DO_BACKEDGE_CHECKS(offset, branch_pc); | |
2468 CONTINUE; | |
2469 } | |
2470 | |
2471 /* return from a jsr or jsr_w */ | |
2472 | |
2473 CASE(_ret): { | |
2474 pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(pc[1])); | |
2475 UPDATE_PC_AND_CONTINUE(0); | |
2476 } | |
2477 | |
2478 /* debugger breakpoint */ | |
2479 | |
2480 CASE(_breakpoint): { | |
2481 Bytecodes::Code original_bytecode; | |
2482 DECACHE_STATE(); | |
2483 SET_LAST_JAVA_FRAME(); | |
2484 original_bytecode = InterpreterRuntime::get_original_bytecode_at(THREAD, | |
2485 METHOD, pc); | |
2486 RESET_LAST_JAVA_FRAME(); | |
2487 CACHE_STATE(); | |
2488 if (THREAD->has_pending_exception()) goto handle_exception; | |
2489 CALL_VM(InterpreterRuntime::_breakpoint(THREAD, METHOD, pc), | |
2490 handle_exception); | |
2491 | |
2492 opcode = (jubyte)original_bytecode; | |
2493 goto opcode_switch; | |
2494 } | |
2495 | |
2496 DEFAULT: | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1347
diff
changeset
|
2497 fatal(err_msg("Unimplemented opcode %d = %s", opcode, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1347
diff
changeset
|
2498 Bytecodes::name((Bytecodes::Code)opcode))); |
0 | 2499 goto finish; |
2500 | |
2501 } /* switch(opc) */ | |
2502 | |
2503 | |
2504 #ifdef USELABELS | |
2505 check_for_exception: | |
2506 #endif | |
2507 { | |
2508 if (!THREAD->has_pending_exception()) { | |
2509 CONTINUE; | |
2510 } | |
2511 /* We will be gcsafe soon, so flush our state. */ | |
2512 DECACHE_PC(); | |
2513 goto handle_exception; | |
2514 } | |
2515 do_continue: ; | |
2516 | |
2517 } /* while (1) interpreter loop */ | |
2518 | |
2519 | |
2520 // An exception exists in the thread state see whether this activation can handle it | |
2521 handle_exception: { | |
2522 | |
2523 HandleMarkCleaner __hmc(THREAD); | |
2524 Handle except_oop(THREAD, THREAD->pending_exception()); | |
2525 // Prevent any subsequent HandleMarkCleaner in the VM | |
2526 // from freeing the except_oop handle. | |
2527 HandleMark __hm(THREAD); | |
2528 | |
2529 THREAD->clear_pending_exception(); | |
2530 assert(except_oop(), "No exception to process"); | |
2531 intptr_t continuation_bci; | |
2532 // expression stack is emptied | |
1509 | 2533 topOfStack = istate->stack_base() - Interpreter::stackElementWords; |
0 | 2534 CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()), |
2535 handle_exception); | |
2536 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
6266
diff
changeset
|
2537 except_oop = THREAD->vm_result(); |
0 | 2538 THREAD->set_vm_result(NULL); |
2539 if (continuation_bci >= 0) { | |
2540 // Place exception on top of stack | |
2541 SET_STACK_OBJECT(except_oop(), 0); | |
2542 MORE_STACK(1); | |
2543 pc = METHOD->code_base() + continuation_bci; | |
2544 if (TraceExceptions) { | |
2545 ttyLocker ttyl; | |
2546 ResourceMark rm; | |
2547 tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop()); | |
2548 tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string()); | |
2549 tty->print_cr(" at bci %d, continuing at %d for thread " INTPTR_FORMAT, | |
2550 pc - (intptr_t)METHOD->code_base(), | |
2551 continuation_bci, THREAD); | |
2552 } | |
2553 // for AbortVMOnException flag | |
2554 NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); | |
2555 goto run; | |
2556 } | |
2557 if (TraceExceptions) { | |
2558 ttyLocker ttyl; | |
2559 ResourceMark rm; | |
2560 tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop()); | |
2561 tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string()); | |
2562 tty->print_cr(" at bci %d, unwinding for thread " INTPTR_FORMAT, | |
2563 pc - (intptr_t) METHOD->code_base(), | |
2564 THREAD); | |
2565 } | |
2566 // for AbortVMOnException flag | |
2567 NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); | |
2568 // No handler in this activation, unwind and try again | |
2569 THREAD->set_pending_exception(except_oop(), NULL, 0); | |
2570 goto handle_return; | |
2571 } /* handle_exception: */ | |
2572 | |
2573 | |
2574 | |
2575 // Return from an interpreter invocation with the result of the interpretation | |
2576 // on the top of the Java Stack (or a pending exception) | |
2577 | |
2578 handle_Pop_Frame: | |
2579 | |
2580 // We don't really do anything special here except we must be aware | |
2581 // that we can get here without ever locking the method (if sync). | |
2582 // Also we skip the notification of the exit. | |
2583 | |
2584 istate->set_msg(popping_frame); | |
2585 // Clear pending so while the pop is in process | |
2586 // we don't start another one if a call_vm is done. | |
2587 THREAD->clr_pop_frame_pending(); | |
2588 // Let interpreter (only) see the we're in the process of popping a frame | |
2589 THREAD->set_pop_frame_in_process(); | |
2590 | |
2591 handle_return: | |
2592 { | |
2593 DECACHE_STATE(); | |
2594 | |
2595 bool suppress_error = istate->msg() == popping_frame; | |
2596 bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error; | |
2597 Handle original_exception(THREAD, THREAD->pending_exception()); | |
2598 Handle illegal_state_oop(THREAD, NULL); | |
2599 | |
2600 // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner | |
2601 // in any following VM entries from freeing our live handles, but illegal_state_oop | |
2602 // isn't really allocated yet and so doesn't become live until later and | |
2603 // in unpredicatable places. Instead we must protect the places where we enter the | |
2604 // VM. It would be much simpler (and safer) if we could allocate a real handle with | |
2605 // a NULL oop in it and then overwrite the oop later as needed. This isn't | |
2606 // unfortunately isn't possible. | |
2607 | |
2608 THREAD->clear_pending_exception(); | |
2609 | |
2610 // | |
2611 // As far as we are concerned we have returned. If we have a pending exception | |
2612 // that will be returned as this invocation's result. However if we get any | |
2613 // exception(s) while checking monitor state one of those IllegalMonitorStateExceptions | |
2614 // will be our final result (i.e. monitor exception trumps a pending exception). | |
2615 // | |
2616 | |
2617 // If we never locked the method (or really passed the point where we would have), | |
2618 // there is no need to unlock it (or look for other monitors), since that | |
2619 // could not have happened. | |
2620 | |
2621 if (THREAD->do_not_unlock()) { | |
2622 | |
2623 // Never locked, reset the flag now because obviously any caller must | |
2624 // have passed their point of locking for us to have gotten here. | |
2625 | |
2626 THREAD->clr_do_not_unlock(); | |
2627 } else { | |
2628 // At this point we consider that we have returned. We now check that the | |
2629 // locks were properly block structured. If we find that they were not | |
2630 // used properly we will return with an illegal monitor exception. | |
2631 // The exception is checked by the caller not the callee since this | |
2632 // checking is considered to be part of the invocation and therefore | |
2633 // in the callers scope (JVM spec 8.13). | |
2634 // | |
2635 // Another weird thing to watch for is if the method was locked | |
2636 // recursively and then not exited properly. This means we must | |
2637 // examine all the entries in reverse time(and stack) order and | |
2638 // unlock as we find them. If we find the method monitor before | |
2639 // we are at the initial entry then we should throw an exception. | |
2640 // It is not clear the template based interpreter does this | |
2641 // correctly | |
2642 | |
2643 BasicObjectLock* base = istate->monitor_base(); | |
2644 BasicObjectLock* end = (BasicObjectLock*) istate->stack_base(); | |
2645 bool method_unlock_needed = METHOD->is_synchronized(); | |
2646 // We know the initial monitor was used for the method don't check that | |
2647 // slot in the loop | |
2648 if (method_unlock_needed) base--; | |
2649 | |
2650 // Check all the monitors to see they are unlocked. Install exception if found to be locked. | |
2651 while (end < base) { | |
2652 oop lockee = end->obj(); | |
2653 if (lockee != NULL) { | |
2654 BasicLock* lock = end->lock(); | |
2655 markOop header = lock->displaced_header(); | |
2656 end->set_obj(NULL); | |
2657 // If it isn't recursive we either must swap old header or call the runtime | |
2658 if (header != NULL) { | |
2659 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { | |
2660 // restore object for the slow case | |
2661 end->set_obj(lockee); | |
2662 { | |
2663 // Prevent any HandleMarkCleaner from freeing our live handles | |
2664 HandleMark __hm(THREAD); | |
2665 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end)); | |
2666 } | |
2667 } | |
2668 } | |
2669 // One error is plenty | |
2670 if (illegal_state_oop() == NULL && !suppress_error) { | |
2671 { | |
2672 // Prevent any HandleMarkCleaner from freeing our live handles | |
2673 HandleMark __hm(THREAD); | |
2674 CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD)); | |
2675 } | |
2676 assert(THREAD->has_pending_exception(), "Lost our exception!"); | |
2677 illegal_state_oop = THREAD->pending_exception(); | |
2678 THREAD->clear_pending_exception(); | |
2679 } | |
2680 } | |
2681 end++; | |
2682 } | |
2683 // Unlock the method if needed | |
2684 if (method_unlock_needed) { | |
2685 if (base->obj() == NULL) { | |
2686 // The method is already unlocked this is not good. | |
2687 if (illegal_state_oop() == NULL && !suppress_error) { | |
2688 { | |
2689 // Prevent any HandleMarkCleaner from freeing our live handles | |
2690 HandleMark __hm(THREAD); | |
2691 CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD)); | |
2692 } | |
2693 assert(THREAD->has_pending_exception(), "Lost our exception!"); | |
2694 illegal_state_oop = THREAD->pending_exception(); | |
2695 THREAD->clear_pending_exception(); | |
2696 } | |
2697 } else { | |
2698 // | |
2699 // The initial monitor is always used for the method | |
2700 // However if that slot is no longer the oop for the method it was unlocked | |
2701 // and reused by something that wasn't unlocked! | |
2702 // | |
2703 // deopt can come in with rcvr dead because c2 knows | |
2704 // its value is preserved in the monitor. So we can't use locals[0] at all | |
2705 // and must use first monitor slot. | |
2706 // | |
2707 oop rcvr = base->obj(); | |
2708 if (rcvr == NULL) { | |
2709 if (!suppress_error) { | |
2710 VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), ""); | |
2711 illegal_state_oop = THREAD->pending_exception(); | |
2712 THREAD->clear_pending_exception(); | |
2713 } | |
2714 } else { | |
2715 BasicLock* lock = base->lock(); | |
2716 markOop header = lock->displaced_header(); | |
2717 base->set_obj(NULL); | |
2718 // If it isn't recursive we either must swap old header or call the runtime | |
2719 if (header != NULL) { | |
2720 if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) { | |
2721 // restore object for the slow case | |
2722 base->set_obj(rcvr); | |
2723 { | |
2724 // Prevent any HandleMarkCleaner from freeing our live handles | |
2725 HandleMark __hm(THREAD); | |
2726 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base)); | |
2727 } | |
2728 if (THREAD->has_pending_exception()) { | |
2729 if (!suppress_error) illegal_state_oop = THREAD->pending_exception(); | |
2730 THREAD->clear_pending_exception(); | |
2731 } | |
2732 } | |
2733 } | |
2734 } | |
2735 } | |
2736 } | |
2737 } | |
2738 | |
2739 // | |
2740 // Notify jvmti/jvmdi | |
2741 // | |
2742 // NOTE: we do not notify a method_exit if we have a pending exception, | |
2743 // including an exception we generate for unlocking checks. In the former | |
2744 // case, JVMDI has already been notified by our call for the exception handler | |
2745 // and in both cases as far as JVMDI is concerned we have already returned. | |
2746 // If we notify it again JVMDI will be all confused about how many frames | |
2747 // are still on the stack (4340444). | |
2748 // | |
2749 // NOTE Further! It turns out the the JVMTI spec in fact expects to see | |
2750 // method_exit events whenever we leave an activation unless it was done | |
2751 // for popframe. This is nothing like jvmdi. However we are passing the | |
2752 // tests at the moment (apparently because they are jvmdi based) so rather | |
2753 // than change this code and possibly fail tests we will leave it alone | |
2754 // (with this note) in anticipation of changing the vm and the tests | |
2755 // simultaneously. | |
2756 | |
2757 | |
2758 // | |
2759 suppress_exit_event = suppress_exit_event || illegal_state_oop() != NULL; | |
2760 | |
2761 | |
2762 | |
2763 #ifdef VM_JVMTI | |
2764 if (_jvmti_interp_events) { | |
2765 // Whenever JVMTI puts a thread in interp_only_mode, method | |
2766 // entry/exit events are sent for that thread to track stack depth. | |
2767 if ( !suppress_exit_event && THREAD->is_interp_only_mode() ) { | |
2768 { | |
2769 // Prevent any HandleMarkCleaner from freeing our live handles | |
2770 HandleMark __hm(THREAD); | |
2771 CALL_VM_NOCHECK(InterpreterRuntime::post_method_exit(THREAD)); | |
2772 } | |
2773 } | |
2774 } | |
2775 #endif /* VM_JVMTI */ | |
2776 | |
2777 // | |
2778 // See if we are returning any exception | |
2779 // A pending exception that was pending prior to a possible popping frame | |
2780 // overrides the popping frame. | |
2781 // | |
2782 assert(!suppress_error || suppress_error && illegal_state_oop() == NULL, "Error was not suppressed"); | |
2783 if (illegal_state_oop() != NULL || original_exception() != NULL) { | |
2784 // inform the frame manager we have no result | |
2785 istate->set_msg(throwing_exception); | |
2786 if (illegal_state_oop() != NULL) | |
2787 THREAD->set_pending_exception(illegal_state_oop(), NULL, 0); | |
2788 else | |
2789 THREAD->set_pending_exception(original_exception(), NULL, 0); | |
2790 istate->set_return_kind((Bytecodes::Code)opcode); | |
2791 UPDATE_PC_AND_RETURN(0); | |
2792 } | |
2793 | |
2794 if (istate->msg() == popping_frame) { | |
2795 // Make it simpler on the assembly code and set the message for the frame pop. | |
2796 // returns | |
2797 if (istate->prev() == NULL) { | |
2798 // We must be returning to a deoptimized frame (because popframe only happens between | |
2799 // two interpreted frames). We need to save the current arguments in C heap so that | |
2800 // the deoptimized frame when it restarts can copy the arguments to its expression | |
2801 // stack and re-execute the call. We also have to notify deoptimization that this | |
605 | 2802 // has occurred and to pick the preserved args copy them to the deoptimized frame's |
0 | 2803 // java expression stack. Yuck. |
2804 // | |
2805 THREAD->popframe_preserve_args(in_ByteSize(METHOD->size_of_parameters() * wordSize), | |
2806 LOCALS_SLOT(METHOD->size_of_parameters() - 1)); | |
2807 THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); | |
2808 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2809 THREAD->clr_pop_frame_in_process(); |
0 | 2810 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2811 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2812 // Normal return |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2813 // Advance the pc and return to frame manager |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2814 istate->set_msg(return_from_method); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2815 istate->set_return_kind((Bytecodes::Code)opcode); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2816 UPDATE_PC_AND_RETURN(1); |
0 | 2817 } /* handle_return: */ |
2818 | |
2819 // This is really a fatal error return | |
2820 | |
2821 finish: | |
2822 DECACHE_TOS(); | |
2823 DECACHE_PC(); | |
2824 | |
2825 return; | |
2826 } | |
2827 | |
2828 /* | |
2829 * All the code following this point is only produced once and is not present | |
2830 * in the JVMTI version of the interpreter | |
2831 */ | |
2832 | |
2833 #ifndef VM_JVMTI | |
2834 | |
2835 // This constructor should only be used to contruct the object to signal | |
2836 // interpreter initialization. All other instances should be created by | |
2837 // the frame manager. | |
2838 BytecodeInterpreter::BytecodeInterpreter(messages msg) { | |
2839 if (msg != initialize) ShouldNotReachHere(); | |
2840 _msg = msg; | |
2841 _self_link = this; | |
2842 _prev_link = NULL; | |
2843 } | |
2844 | |
2845 // Inline static functions for Java Stack and Local manipulation | |
2846 | |
2847 // The implementations are platform dependent. We have to worry about alignment | |
2848 // issues on some machines which can change on the same platform depending on | |
2849 // whether it is an LP64 machine also. | |
2850 address BytecodeInterpreter::stack_slot(intptr_t *tos, int offset) { | |
2851 return (address) tos[Interpreter::expr_index_at(-offset)]; | |
2852 } | |
2853 | |
2854 jint BytecodeInterpreter::stack_int(intptr_t *tos, int offset) { | |
2855 return *((jint*) &tos[Interpreter::expr_index_at(-offset)]); | |
2856 } | |
2857 | |
2858 jfloat BytecodeInterpreter::stack_float(intptr_t *tos, int offset) { | |
2859 return *((jfloat *) &tos[Interpreter::expr_index_at(-offset)]); | |
2860 } | |
2861 | |
2862 oop BytecodeInterpreter::stack_object(intptr_t *tos, int offset) { | |
2863 return (oop)tos [Interpreter::expr_index_at(-offset)]; | |
2864 } | |
2865 | |
2866 jdouble BytecodeInterpreter::stack_double(intptr_t *tos, int offset) { | |
2867 return ((VMJavaVal64*) &tos[Interpreter::expr_index_at(-offset)])->d; | |
2868 } | |
2869 | |
2870 jlong BytecodeInterpreter::stack_long(intptr_t *tos, int offset) { | |
2871 return ((VMJavaVal64 *) &tos[Interpreter::expr_index_at(-offset)])->l; | |
2872 } | |
2873 | |
2874 // only used for value types | |
2875 void BytecodeInterpreter::set_stack_slot(intptr_t *tos, address value, | |
2876 int offset) { | |
2877 *((address *)&tos[Interpreter::expr_index_at(-offset)]) = value; | |
2878 } | |
2879 | |
2880 void BytecodeInterpreter::set_stack_int(intptr_t *tos, int value, | |
2881 int offset) { | |
2882 *((jint *)&tos[Interpreter::expr_index_at(-offset)]) = value; | |
2883 } | |
2884 | |
2885 void BytecodeInterpreter::set_stack_float(intptr_t *tos, jfloat value, | |
2886 int offset) { | |
2887 *((jfloat *)&tos[Interpreter::expr_index_at(-offset)]) = value; | |
2888 } | |
2889 | |
2890 void BytecodeInterpreter::set_stack_object(intptr_t *tos, oop value, | |
2891 int offset) { | |
2892 *((oop *)&tos[Interpreter::expr_index_at(-offset)]) = value; | |
2893 } | |
2894 | |
2895 // needs to be platform dep for the 32 bit platforms. | |
2896 void BytecodeInterpreter::set_stack_double(intptr_t *tos, jdouble value, | |
2897 int offset) { | |
2898 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = value; | |
2899 } | |
2900 | |
2901 void BytecodeInterpreter::set_stack_double_from_addr(intptr_t *tos, | |
2902 address addr, int offset) { | |
2903 (((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = | |
2904 ((VMJavaVal64*)addr)->d); | |
2905 } | |
2906 | |
2907 void BytecodeInterpreter::set_stack_long(intptr_t *tos, jlong value, | |
2908 int offset) { | |
2909 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb; | |
2910 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = value; | |
2911 } | |
2912 | |
2913 void BytecodeInterpreter::set_stack_long_from_addr(intptr_t *tos, | |
2914 address addr, int offset) { | |
2915 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb; | |
2916 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = | |
2917 ((VMJavaVal64*)addr)->l; | |
2918 } | |
2919 | |
2920 // Locals | |
2921 | |
2922 address BytecodeInterpreter::locals_slot(intptr_t* locals, int offset) { | |
2923 return (address)locals[Interpreter::local_index_at(-offset)]; | |
2924 } | |
2925 jint BytecodeInterpreter::locals_int(intptr_t* locals, int offset) { | |
2926 return (jint)locals[Interpreter::local_index_at(-offset)]; | |
2927 } | |
2928 jfloat BytecodeInterpreter::locals_float(intptr_t* locals, int offset) { | |
2929 return (jfloat)locals[Interpreter::local_index_at(-offset)]; | |
2930 } | |
2931 oop BytecodeInterpreter::locals_object(intptr_t* locals, int offset) { | |
2932 return (oop)locals[Interpreter::local_index_at(-offset)]; | |
2933 } | |
2934 jdouble BytecodeInterpreter::locals_double(intptr_t* locals, int offset) { | |
2935 return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d; | |
2936 } | |
2937 jlong BytecodeInterpreter::locals_long(intptr_t* locals, int offset) { | |
2938 return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l; | |
2939 } | |
2940 | |
2941 // Returns the address of locals value. | |
2942 address BytecodeInterpreter::locals_long_at(intptr_t* locals, int offset) { | |
2943 return ((address)&locals[Interpreter::local_index_at(-(offset+1))]); | |
2944 } | |
2945 address BytecodeInterpreter::locals_double_at(intptr_t* locals, int offset) { | |
2946 return ((address)&locals[Interpreter::local_index_at(-(offset+1))]); | |
2947 } | |
2948 | |
2949 // Used for local value or returnAddress | |
2950 void BytecodeInterpreter::set_locals_slot(intptr_t *locals, | |
2951 address value, int offset) { | |
2952 *((address*)&locals[Interpreter::local_index_at(-offset)]) = value; | |
2953 } | |
2954 void BytecodeInterpreter::set_locals_int(intptr_t *locals, | |
2955 jint value, int offset) { | |
2956 *((jint *)&locals[Interpreter::local_index_at(-offset)]) = value; | |
2957 } | |
2958 void BytecodeInterpreter::set_locals_float(intptr_t *locals, | |
2959 jfloat value, int offset) { | |
2960 *((jfloat *)&locals[Interpreter::local_index_at(-offset)]) = value; | |
2961 } | |
2962 void BytecodeInterpreter::set_locals_object(intptr_t *locals, | |
2963 oop value, int offset) { | |
2964 *((oop *)&locals[Interpreter::local_index_at(-offset)]) = value; | |
2965 } | |
2966 void BytecodeInterpreter::set_locals_double(intptr_t *locals, | |
2967 jdouble value, int offset) { | |
2968 ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = value; | |
2969 } | |
2970 void BytecodeInterpreter::set_locals_long(intptr_t *locals, | |
2971 jlong value, int offset) { | |
2972 ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = value; | |
2973 } | |
2974 void BytecodeInterpreter::set_locals_double_from_addr(intptr_t *locals, | |
2975 address addr, int offset) { | |
2976 ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = ((VMJavaVal64*)addr)->d; | |
2977 } | |
2978 void BytecodeInterpreter::set_locals_long_from_addr(intptr_t *locals, | |
2979 address addr, int offset) { | |
2980 ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = ((VMJavaVal64*)addr)->l; | |
2981 } | |
2982 | |
2983 void BytecodeInterpreter::astore(intptr_t* tos, int stack_offset, | |
2984 intptr_t* locals, int locals_offset) { | |
2985 intptr_t value = tos[Interpreter::expr_index_at(-stack_offset)]; | |
2986 locals[Interpreter::local_index_at(-locals_offset)] = value; | |
2987 } | |
2988 | |
2989 | |
2990 void BytecodeInterpreter::copy_stack_slot(intptr_t *tos, int from_offset, | |
2991 int to_offset) { | |
2992 tos[Interpreter::expr_index_at(-to_offset)] = | |
2993 (intptr_t)tos[Interpreter::expr_index_at(-from_offset)]; | |
2994 } | |
2995 | |
2996 void BytecodeInterpreter::dup(intptr_t *tos) { | |
2997 copy_stack_slot(tos, -1, 0); | |
2998 } | |
2999 void BytecodeInterpreter::dup2(intptr_t *tos) { | |
3000 copy_stack_slot(tos, -2, 0); | |
3001 copy_stack_slot(tos, -1, 1); | |
3002 } | |
3003 | |
3004 void BytecodeInterpreter::dup_x1(intptr_t *tos) { | |
3005 /* insert top word two down */ | |
3006 copy_stack_slot(tos, -1, 0); | |
3007 copy_stack_slot(tos, -2, -1); | |
3008 copy_stack_slot(tos, 0, -2); | |
3009 } | |
3010 | |
3011 void BytecodeInterpreter::dup_x2(intptr_t *tos) { | |
3012 /* insert top word three down */ | |
3013 copy_stack_slot(tos, -1, 0); | |
3014 copy_stack_slot(tos, -2, -1); | |
3015 copy_stack_slot(tos, -3, -2); | |
3016 copy_stack_slot(tos, 0, -3); | |
3017 } | |
3018 void BytecodeInterpreter::dup2_x1(intptr_t *tos) { | |
3019 /* insert top 2 slots three down */ | |
3020 copy_stack_slot(tos, -1, 1); | |
3021 copy_stack_slot(tos, -2, 0); | |
3022 copy_stack_slot(tos, -3, -1); | |
3023 copy_stack_slot(tos, 1, -2); | |
3024 copy_stack_slot(tos, 0, -3); | |
3025 } | |
3026 void BytecodeInterpreter::dup2_x2(intptr_t *tos) { | |
3027 /* insert top 2 slots four down */ | |
3028 copy_stack_slot(tos, -1, 1); | |
3029 copy_stack_slot(tos, -2, 0); | |
3030 copy_stack_slot(tos, -3, -1); | |
3031 copy_stack_slot(tos, -4, -2); | |
3032 copy_stack_slot(tos, 1, -3); | |
3033 copy_stack_slot(tos, 0, -4); | |
3034 } | |
3035 | |
3036 | |
3037 void BytecodeInterpreter::swap(intptr_t *tos) { | |
3038 // swap top two elements | |
3039 intptr_t val = tos[Interpreter::expr_index_at(1)]; | |
3040 // Copy -2 entry to -1 | |
3041 copy_stack_slot(tos, -2, -1); | |
3042 // Store saved -1 entry into -2 | |
3043 tos[Interpreter::expr_index_at(2)] = val; | |
3044 } | |
3045 // -------------------------------------------------------------------------------- | |
3046 // Non-product code | |
3047 #ifndef PRODUCT | |
3048 | |
3049 const char* BytecodeInterpreter::C_msg(BytecodeInterpreter::messages msg) { | |
3050 switch (msg) { | |
3051 case BytecodeInterpreter::no_request: return("no_request"); | |
3052 case BytecodeInterpreter::initialize: return("initialize"); | |
3053 // status message to C++ interpreter | |
3054 case BytecodeInterpreter::method_entry: return("method_entry"); | |
3055 case BytecodeInterpreter::method_resume: return("method_resume"); | |
3056 case BytecodeInterpreter::got_monitors: return("got_monitors"); | |
3057 case BytecodeInterpreter::rethrow_exception: return("rethrow_exception"); | |
3058 // requests to frame manager from C++ interpreter | |
3059 case BytecodeInterpreter::call_method: return("call_method"); | |
3060 case BytecodeInterpreter::return_from_method: return("return_from_method"); | |
3061 case BytecodeInterpreter::more_monitors: return("more_monitors"); | |
3062 case BytecodeInterpreter::throwing_exception: return("throwing_exception"); | |
3063 case BytecodeInterpreter::popping_frame: return("popping_frame"); | |
3064 case BytecodeInterpreter::do_osr: return("do_osr"); | |
3065 // deopt | |
3066 case BytecodeInterpreter::deopt_resume: return("deopt_resume"); | |
3067 case BytecodeInterpreter::deopt_resume2: return("deopt_resume2"); | |
3068 default: return("BAD MSG"); | |
3069 } | |
3070 } | |
3071 void | |
3072 BytecodeInterpreter::print() { | |
3073 tty->print_cr("thread: " INTPTR_FORMAT, (uintptr_t) this->_thread); | |
3074 tty->print_cr("bcp: " INTPTR_FORMAT, (uintptr_t) this->_bcp); | |
3075 tty->print_cr("locals: " INTPTR_FORMAT, (uintptr_t) this->_locals); | |
3076 tty->print_cr("constants: " INTPTR_FORMAT, (uintptr_t) this->_constants); | |
3077 { | |
3078 ResourceMark rm; | |
3079 char *method_name = _method->name_and_sig_as_C_string(); | |
3080 tty->print_cr("method: " INTPTR_FORMAT "[ %s ]", (uintptr_t) this->_method, method_name); | |
3081 } | |
3082 tty->print_cr("mdx: " INTPTR_FORMAT, (uintptr_t) this->_mdx); | |
3083 tty->print_cr("stack: " INTPTR_FORMAT, (uintptr_t) this->_stack); | |
3084 tty->print_cr("msg: %s", C_msg(this->_msg)); | |
3085 tty->print_cr("result_to_call._callee: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee); | |
3086 tty->print_cr("result_to_call._callee_entry_point: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee_entry_point); | |
3087 tty->print_cr("result_to_call._bcp_advance: %d ", this->_result._to_call._bcp_advance); | |
3088 tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf); | |
3089 tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry); | |
3090 tty->print_cr("result_return_kind 0x%x ", (int) this->_result._return_kind); | |
3091 tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link); | |
3092 tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp); | |
3093 tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base); | |
3094 tty->print_cr("stack_limit: " INTPTR_FORMAT, (uintptr_t) this->_stack_limit); | |
3095 tty->print_cr("monitor_base: " INTPTR_FORMAT, (uintptr_t) this->_monitor_base); | |
3096 #ifdef SPARC | |
3097 tty->print_cr("last_Java_pc: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_pc); | |
3098 tty->print_cr("frame_bottom: " INTPTR_FORMAT, (uintptr_t) this->_frame_bottom); | |
3099 tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult); | |
3100 tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult); | |
3101 #endif | |
7994 | 3102 #if !defined(ZERO) |
0 | 3103 tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp); |
7994 | 3104 #endif // !ZERO |
0 | 3105 tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link); |
3106 } | |
3107 | |
3108 extern "C" { | |
3109 void PI(uintptr_t arg) { | |
3110 ((BytecodeInterpreter*)arg)->print(); | |
3111 } | |
3112 } | |
3113 #endif // PRODUCT | |
3114 | |
3115 #endif // JVMTI | |
3116 #endif // CC_INTERP |