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