Mercurial > hg > graal-compiler
annotate src/share/vm/interpreter/bytecodeInterpreter.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | f08d439fab8c |
children | 1d7922586cf6 |
rev | line source |
---|---|
0 | 1 /* |
2142 | 2 * Copyright (c) 2002, 2011, 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(); | |
493 register constantPoolCacheOop cp = istate->constants(); // method()->constants()->cache() | |
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; | |
682 xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() ^ xx; | |
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. | |
726 xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() | (intptr_t) THREAD; | |
727 if (Atomic::cmpxchg_ptr((intptr_t)THREAD | (intptr_t) rcvr->klass()->klass_part()->prototype_header(), | |
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 // | |
744 xx = (intptr_t) rcvr->klass()->klass_part()->prototype_header() | (intptr_t) THREAD; | |
745 if (Atomic::cmpxchg_ptr(rcvr->klass()->klass_part()->prototype_header(), | |
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); |
0 | 1533 if (rcvr->klass()->klass_part()->has_finalizer()) { |
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 */ | |
1628 klassOop rhsKlassOop = rhsObject->klass(); // EBX (subclass) | |
1629 assert(arrObj->klass()->klass()->klass_part()->oop_is_objArrayKlass(), "Ack not an objArrayKlass"); | |
1630 klassOop elemKlassOop = ((objArrayKlass*) arrObj->klass()->klass_part())->element_klass(); // superklass EAX | |
1631 // | |
1632 // Check for compatibilty. This check must not GC!! | |
1633 // Seems way more expensive now that we must dispatch | |
1634 // | |
1635 if (rhsKlassOop != elemKlassOop && !rhsKlassOop->klass_part()->is_subtype_of(elemKlassOop)) { // ebx->is... | |
1636 VM_JAVA_ERROR(vmSymbols::java_lang_ArrayStoreException(), ""); | |
1637 } | |
1638 } | |
1639 oop* elem_loc = (oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)); | |
1640 // *(oop*)(((address) arrObj->base(T_OBJECT)) + index * sizeof(oop)) = rhsObject; | |
1641 *elem_loc = rhsObject; | |
1642 // Mark the card | |
1643 OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)elem_loc >> CardTableModRefBS::card_shift], 0); | |
1644 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -3); | |
1645 } | |
1646 CASE(_bastore): | |
1647 ARRAY_STOREFROM32(T_BYTE, jbyte, "%d", STACK_INT, 0); | |
1648 CASE(_castore): | |
1649 ARRAY_STOREFROM32(T_CHAR, jchar, "%d", STACK_INT, 0); | |
1650 CASE(_sastore): | |
1651 ARRAY_STOREFROM32(T_SHORT, jshort, "%d", STACK_INT, 0); | |
1652 CASE(_lastore): | |
1653 ARRAY_STOREFROM64(T_LONG, jlong, STACK_LONG, 0); | |
1654 CASE(_dastore): | |
1655 ARRAY_STOREFROM64(T_DOUBLE, jdouble, STACK_DOUBLE, 0); | |
1656 | |
1657 CASE(_arraylength): | |
1658 { | |
1659 arrayOop ary = (arrayOop) STACK_OBJECT(-1); | |
1660 CHECK_NULL(ary); | |
1661 SET_STACK_INT(ary->length(), -1); | |
1662 UPDATE_PC_AND_CONTINUE(1); | |
1663 } | |
1664 | |
1665 /* monitorenter and monitorexit for locking/unlocking an object */ | |
1666 | |
1667 CASE(_monitorenter): { | |
1668 oop lockee = STACK_OBJECT(-1); | |
1669 // derefing's lockee ought to provoke implicit null check | |
1670 CHECK_NULL(lockee); | |
1671 // find a free monitor or one already allocated for this object | |
1672 // if we find a matching object then we need a new monitor | |
1673 // since this is recursive enter | |
1674 BasicObjectLock* limit = istate->monitor_base(); | |
1675 BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); | |
1676 BasicObjectLock* entry = NULL; | |
1677 while (most_recent != limit ) { | |
1678 if (most_recent->obj() == NULL) entry = most_recent; | |
1679 else if (most_recent->obj() == lockee) break; | |
1680 most_recent++; | |
1681 } | |
1682 if (entry != NULL) { | |
1683 entry->set_obj(lockee); | |
1684 markOop displaced = lockee->mark()->set_unlocked(); | |
1685 entry->lock()->set_displaced_header(displaced); | |
1686 if (Atomic::cmpxchg_ptr(entry, lockee->mark_addr(), displaced) != displaced) { | |
1687 // Is it simple recursive case? | |
1688 if (THREAD->is_lock_owned((address) displaced->clear_lock_bits())) { | |
1689 entry->lock()->set_displaced_header(NULL); | |
1690 } else { | |
1691 CALL_VM(InterpreterRuntime::monitorenter(THREAD, entry), handle_exception); | |
1692 } | |
1693 } | |
1694 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); | |
1695 } else { | |
1696 istate->set_msg(more_monitors); | |
1697 UPDATE_PC_AND_RETURN(0); // Re-execute | |
1698 } | |
1699 } | |
1700 | |
1701 CASE(_monitorexit): { | |
1702 oop lockee = STACK_OBJECT(-1); | |
1703 CHECK_NULL(lockee); | |
1704 // derefing's lockee ought to provoke implicit null check | |
1705 // find our monitor slot | |
1706 BasicObjectLock* limit = istate->monitor_base(); | |
1707 BasicObjectLock* most_recent = (BasicObjectLock*) istate->stack_base(); | |
1708 while (most_recent != limit ) { | |
1709 if ((most_recent)->obj() == lockee) { | |
1710 BasicLock* lock = most_recent->lock(); | |
1711 markOop header = lock->displaced_header(); | |
1712 most_recent->set_obj(NULL); | |
1713 // If it isn't recursive we either must swap old header or call the runtime | |
1714 if (header != NULL) { | |
1715 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { | |
1716 // restore object for the slow case | |
1717 most_recent->set_obj(lockee); | |
1718 CALL_VM(InterpreterRuntime::monitorexit(THREAD, most_recent), handle_exception); | |
1719 } | |
1720 } | |
1721 UPDATE_PC_AND_TOS_AND_CONTINUE(1, -1); | |
1722 } | |
1723 most_recent++; | |
1724 } | |
1725 // Need to throw illegal monitor state exception | |
1726 CALL_VM(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD), handle_exception); | |
2480 | 1727 ShouldNotReachHere(); |
0 | 1728 } |
1729 | |
1730 /* All of the non-quick opcodes. */ | |
1731 | |
1732 /* -Set clobbersCpIndex true if the quickened opcode clobbers the | |
1733 * constant pool index in the instruction. | |
1734 */ | |
1735 CASE(_getfield): | |
1736 CASE(_getstatic): | |
1737 { | |
1738 u2 index; | |
1739 ConstantPoolCacheEntry* cache; | |
1740 index = Bytes::get_native_u2(pc+1); | |
1741 | |
1742 // QQQ Need to make this as inlined as possible. Probably need to | |
1743 // split all the bytecode cases out so c++ compiler has a chance | |
1744 // for constant prop to fold everything possible away. | |
1745 | |
1746 cache = cp->entry_at(index); | |
1747 if (!cache->is_resolved((Bytecodes::Code)opcode)) { | |
1748 CALL_VM(InterpreterRuntime::resolve_get_put(THREAD, (Bytecodes::Code)opcode), | |
1749 handle_exception); | |
1750 cache = cp->entry_at(index); | |
1751 } | |
1752 | |
1753 #ifdef VM_JVMTI | |
1754 if (_jvmti_interp_events) { | |
1755 int *count_addr; | |
1756 oop obj; | |
1757 // Check to see if a field modification watch has been set | |
1758 // before we take the time to call into the VM. | |
1759 count_addr = (int *)JvmtiExport::get_field_access_count_addr(); | |
1760 if ( *count_addr > 0 ) { | |
1761 if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { | |
1762 obj = (oop)NULL; | |
1763 } else { | |
1764 obj = (oop) STACK_OBJECT(-1); | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1765 VERIFY_OOP(obj); |
0 | 1766 } |
1767 CALL_VM(InterpreterRuntime::post_field_access(THREAD, | |
1768 obj, | |
1769 cache), | |
1770 handle_exception); | |
1771 } | |
1772 } | |
1773 #endif /* VM_JVMTI */ | |
1774 | |
1775 oop obj; | |
1776 if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) { | |
1777 obj = (oop) cache->f1(); | |
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(); | |
1788 int field_offset = cache->f2(); | |
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) { | |
1888 obj = (oop) cache->f1(); | |
1889 } else { | |
1890 --count; | |
1891 obj = (oop) STACK_OBJECT(count); | |
1892 CHECK_NULL(obj); | |
1893 } | |
1894 | |
1895 // | |
1896 // Now store the result | |
1897 // | |
1898 int field_offset = cache->f2(); | |
1899 if (cache->is_volatile()) { | |
1900 if (tos_type == itos) { | |
1901 obj->release_int_field_put(field_offset, STACK_INT(-1)); | |
1902 } else if (tos_type == atos) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1903 VERIFY_OOP(STACK_OBJECT(-1)); |
0 | 1904 obj->release_obj_field_put(field_offset, STACK_OBJECT(-1)); |
1905 OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); | |
1906 } else if (tos_type == btos) { | |
1907 obj->release_byte_field_put(field_offset, STACK_INT(-1)); | |
1908 } else if (tos_type == ltos) { | |
1909 obj->release_long_field_put(field_offset, STACK_LONG(-1)); | |
1910 } else if (tos_type == ctos) { | |
1911 obj->release_char_field_put(field_offset, STACK_INT(-1)); | |
1912 } else if (tos_type == stos) { | |
1913 obj->release_short_field_put(field_offset, STACK_INT(-1)); | |
1914 } else if (tos_type == ftos) { | |
1915 obj->release_float_field_put(field_offset, STACK_FLOAT(-1)); | |
1916 } else { | |
1917 obj->release_double_field_put(field_offset, STACK_DOUBLE(-1)); | |
1918 } | |
1919 OrderAccess::storeload(); | |
1920 } else { | |
1921 if (tos_type == itos) { | |
1922 obj->int_field_put(field_offset, STACK_INT(-1)); | |
1923 } else if (tos_type == atos) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
1924 VERIFY_OOP(STACK_OBJECT(-1)); |
0 | 1925 obj->obj_field_put(field_offset, STACK_OBJECT(-1)); |
1926 OrderAccess::release_store(&BYTE_MAP_BASE[(uintptr_t)obj >> CardTableModRefBS::card_shift], 0); | |
1927 } else if (tos_type == btos) { | |
1928 obj->byte_field_put(field_offset, STACK_INT(-1)); | |
1929 } else if (tos_type == ltos) { | |
1930 obj->long_field_put(field_offset, STACK_LONG(-1)); | |
1931 } else if (tos_type == ctos) { | |
1932 obj->char_field_put(field_offset, STACK_INT(-1)); | |
1933 } else if (tos_type == stos) { | |
1934 obj->short_field_put(field_offset, STACK_INT(-1)); | |
1935 } else if (tos_type == ftos) { | |
1936 obj->float_field_put(field_offset, STACK_FLOAT(-1)); | |
1937 } else { | |
1938 obj->double_field_put(field_offset, STACK_DOUBLE(-1)); | |
1939 } | |
1940 } | |
1941 | |
1942 UPDATE_PC_AND_TOS_AND_CONTINUE(3, count); | |
1943 } | |
1944 | |
1945 CASE(_new): { | |
1946 u2 index = Bytes::get_Java_u2(pc+1); | |
1947 constantPoolOop constants = istate->method()->constants(); | |
1948 if (!constants->tag_at(index).is_unresolved_klass()) { | |
1949 // Make sure klass is initialized and doesn't have a finalizer | |
2256
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
2142
diff
changeset
|
1950 oop entry = constants->slot_at(index).get_oop(); |
0 | 1951 assert(entry->is_klass(), "Should be resolved klass"); |
1952 klassOop k_entry = (klassOop) entry; | |
1953 assert(k_entry->klass_part()->oop_is_instance(), "Should be instanceKlass"); | |
1954 instanceKlass* ik = (instanceKlass*) k_entry->klass_part(); | |
1955 if ( ik->is_initialized() && ik->can_be_fastpath_allocated() ) { | |
1956 size_t obj_size = ik->size_helper(); | |
1957 oop result = NULL; | |
1958 // If the TLAB isn't pre-zeroed then we'll have to do it | |
1959 bool need_zero = !ZeroTLAB; | |
1960 if (UseTLAB) { | |
1961 result = (oop) THREAD->tlab().allocate(obj_size); | |
1962 } | |
1963 if (result == NULL) { | |
1964 need_zero = true; | |
1965 // Try allocate in shared eden | |
1966 retry: | |
1967 HeapWord* compare_to = *Universe::heap()->top_addr(); | |
1968 HeapWord* new_top = compare_to + obj_size; | |
1969 if (new_top <= *Universe::heap()->end_addr()) { | |
1970 if (Atomic::cmpxchg_ptr(new_top, Universe::heap()->top_addr(), compare_to) != compare_to) { | |
1971 goto retry; | |
1972 } | |
1973 result = (oop) compare_to; | |
1974 } | |
1975 } | |
1976 if (result != NULL) { | |
1977 // Initialize object (if nonzero size and need) and then the header | |
1978 if (need_zero ) { | |
1979 HeapWord* to_zero = (HeapWord*) result + sizeof(oopDesc) / oopSize; | |
1980 obj_size -= sizeof(oopDesc) / oopSize; | |
1981 if (obj_size > 0 ) { | |
1982 memset(to_zero, 0, obj_size * HeapWordSize); | |
1983 } | |
1984 } | |
1985 if (UseBiasedLocking) { | |
1986 result->set_mark(ik->prototype_header()); | |
1987 } else { | |
1988 result->set_mark(markOopDesc::prototype()); | |
1989 } | |
167
feeb96a45707
6696264: assert("narrow oop can never be zero") for GCBasher & ParNewGC
coleenp
parents:
123
diff
changeset
|
1990 result->set_klass_gap(0); |
0 | 1991 result->set_klass(k_entry); |
1992 SET_STACK_OBJECT(result, 0); | |
1993 UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); | |
1994 } | |
1995 } | |
1996 } | |
1997 // Slow case allocation | |
1998 CALL_VM(InterpreterRuntime::_new(THREAD, METHOD->constants(), index), | |
1999 handle_exception); | |
2000 SET_STACK_OBJECT(THREAD->vm_result(), 0); | |
2001 THREAD->set_vm_result(NULL); | |
2002 UPDATE_PC_AND_TOS_AND_CONTINUE(3, 1); | |
2003 } | |
2004 CASE(_anewarray): { | |
2005 u2 index = Bytes::get_Java_u2(pc+1); | |
2006 jint size = STACK_INT(-1); | |
2007 CALL_VM(InterpreterRuntime::anewarray(THREAD, METHOD->constants(), index, size), | |
2008 handle_exception); | |
2009 SET_STACK_OBJECT(THREAD->vm_result(), -1); | |
2010 THREAD->set_vm_result(NULL); | |
2011 UPDATE_PC_AND_CONTINUE(3); | |
2012 } | |
2013 CASE(_multianewarray): { | |
2014 jint dims = *(pc+3); | |
2015 jint size = STACK_INT(-1); | |
2016 // stack grows down, dimensions are up! | |
2017 jint *dimarray = | |
1509 | 2018 (jint*)&topOfStack[dims * Interpreter::stackElementWords+ |
2019 Interpreter::stackElementWords-1]; | |
0 | 2020 //adjust pointer to start of stack element |
2021 CALL_VM(InterpreterRuntime::multianewarray(THREAD, dimarray), | |
2022 handle_exception); | |
2023 SET_STACK_OBJECT(THREAD->vm_result(), -dims); | |
2024 THREAD->set_vm_result(NULL); | |
2025 UPDATE_PC_AND_TOS_AND_CONTINUE(4, -(dims-1)); | |
2026 } | |
2027 CASE(_checkcast): | |
2028 if (STACK_OBJECT(-1) != NULL) { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2029 VERIFY_OOP(STACK_OBJECT(-1)); |
0 | 2030 u2 index = Bytes::get_Java_u2(pc+1); |
2031 if (ProfileInterpreter) { | |
2032 // needs Profile_checkcast QQQ | |
2033 ShouldNotReachHere(); | |
2034 } | |
2035 // Constant pool may have actual klass or unresolved klass. If it is | |
2036 // unresolved we must resolve it | |
2037 if (METHOD->constants()->tag_at(index).is_unresolved_klass()) { | |
2038 CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception); | |
2039 } | |
2256
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
2142
diff
changeset
|
2040 klassOop klassOf = (klassOop) METHOD->constants()->slot_at(index).get_oop(); |
0 | 2041 klassOop objKlassOop = STACK_OBJECT(-1)->klass(); //ebx |
2042 // | |
2043 // Check for compatibilty. This check must not GC!! | |
2044 // Seems way more expensive now that we must dispatch | |
2045 // | |
2046 if (objKlassOop != klassOf && | |
2047 !objKlassOop->klass_part()->is_subtype_of(klassOf)) { | |
2048 ResourceMark rm(THREAD); | |
2049 const char* objName = Klass::cast(objKlassOop)->external_name(); | |
2050 const char* klassName = Klass::cast(klassOf)->external_name(); | |
2051 char* message = SharedRuntime::generate_class_cast_message( | |
2052 objName, klassName); | |
2053 VM_JAVA_ERROR(vmSymbols::java_lang_ClassCastException(), message); | |
2054 } | |
2055 } else { | |
2056 if (UncommonNullCast) { | |
2057 // istate->method()->set_null_cast_seen(); | |
2058 // [RGV] Not sure what to do here! | |
2059 | |
2060 } | |
2061 } | |
2062 UPDATE_PC_AND_CONTINUE(3); | |
2063 | |
2064 CASE(_instanceof): | |
2065 if (STACK_OBJECT(-1) == NULL) { | |
2066 SET_STACK_INT(0, -1); | |
2067 } else { | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2068 VERIFY_OOP(STACK_OBJECT(-1)); |
0 | 2069 u2 index = Bytes::get_Java_u2(pc+1); |
2070 // Constant pool may have actual klass or unresolved klass. If it is | |
2071 // unresolved we must resolve it | |
2072 if (METHOD->constants()->tag_at(index).is_unresolved_klass()) { | |
2073 CALL_VM(InterpreterRuntime::quicken_io_cc(THREAD), handle_exception); | |
2074 } | |
2256
173926398291
7018673: Zero: 6953144, 6990754 and 7009756 made some changes which broke Zero
twisti
parents:
2142
diff
changeset
|
2075 klassOop klassOf = (klassOop) METHOD->constants()->slot_at(index).get_oop(); |
0 | 2076 klassOop objKlassOop = STACK_OBJECT(-1)->klass(); |
2077 // | |
2078 // Check for compatibilty. This check must not GC!! | |
2079 // Seems way more expensive now that we must dispatch | |
2080 // | |
2081 if ( objKlassOop == klassOf || objKlassOop->klass_part()->is_subtype_of(klassOf)) { | |
2082 SET_STACK_INT(1, -1); | |
2083 } else { | |
2084 SET_STACK_INT(0, -1); | |
2085 } | |
2086 } | |
2087 UPDATE_PC_AND_CONTINUE(3); | |
2088 | |
2089 CASE(_ldc_w): | |
2090 CASE(_ldc): | |
2091 { | |
2092 u2 index; | |
2093 bool wide = false; | |
2094 int incr = 2; // frequent case | |
2095 if (opcode == Bytecodes::_ldc) { | |
2096 index = pc[1]; | |
2097 } else { | |
2098 index = Bytes::get_Java_u2(pc+1); | |
2099 incr = 3; | |
2100 wide = true; | |
2101 } | |
2102 | |
2103 constantPoolOop constants = METHOD->constants(); | |
2104 switch (constants->tag_at(index).value()) { | |
2105 case JVM_CONSTANT_Integer: | |
2106 SET_STACK_INT(constants->int_at(index), 0); | |
2107 break; | |
2108 | |
2109 case JVM_CONSTANT_Float: | |
2110 SET_STACK_FLOAT(constants->float_at(index), 0); | |
2111 break; | |
2112 | |
2113 case JVM_CONSTANT_String: | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2114 VERIFY_OOP(constants->resolved_string_at(index)); |
0 | 2115 SET_STACK_OBJECT(constants->resolved_string_at(index), 0); |
2116 break; | |
2117 | |
2118 case JVM_CONSTANT_Class: | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2260
diff
changeset
|
2119 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
|
2120 SET_STACK_OBJECT(constants->resolved_klass_at(index)->java_mirror(), 0); |
0 | 2121 break; |
2122 | |
2123 case JVM_CONSTANT_UnresolvedString: | |
2124 case JVM_CONSTANT_UnresolvedClass: | |
2125 case JVM_CONSTANT_UnresolvedClassInError: | |
2126 CALL_VM(InterpreterRuntime::ldc(THREAD, wide), handle_exception); | |
2127 SET_STACK_OBJECT(THREAD->vm_result(), 0); | |
2128 THREAD->set_vm_result(NULL); | |
2129 break; | |
2130 | |
2131 default: ShouldNotReachHere(); | |
2132 } | |
2133 UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); | |
2134 } | |
2135 | |
2136 CASE(_ldc2_w): | |
2137 { | |
2138 u2 index = Bytes::get_Java_u2(pc+1); | |
2139 | |
2140 constantPoolOop constants = METHOD->constants(); | |
2141 switch (constants->tag_at(index).value()) { | |
2142 | |
2143 case JVM_CONSTANT_Long: | |
2144 SET_STACK_LONG(constants->long_at(index), 1); | |
2145 break; | |
2146 | |
2147 case JVM_CONSTANT_Double: | |
2148 SET_STACK_DOUBLE(constants->double_at(index), 1); | |
2149 break; | |
2150 default: ShouldNotReachHere(); | |
2151 } | |
2152 UPDATE_PC_AND_TOS_AND_CONTINUE(3, 2); | |
2153 } | |
2154 | |
2480 | 2155 CASE(_fast_aldc_w): |
2156 CASE(_fast_aldc): { | |
2157 if (!EnableInvokeDynamic) { | |
2158 // We should not encounter this bytecode if !EnableInvokeDynamic. | |
2159 // The verifier will stop it. However, if we get past the verifier, | |
2160 // this will stop the thread in a reasonable way, without crashing the JVM. | |
2161 CALL_VM(InterpreterRuntime::throw_IncompatibleClassChangeError(THREAD), | |
2162 handle_exception); | |
2163 ShouldNotReachHere(); | |
2164 } | |
2165 | |
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. | |
2179 ConstantPoolCacheEntry* cache = cp->entry_at(index); | |
2180 if (cache->is_f1_null()) { | |
2181 CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode), | |
2182 handle_exception); | |
2183 } | |
2184 | |
2185 VERIFY_OOP(cache->f1()); | |
2186 SET_STACK_OBJECT(cache->f1(), 0); | |
2187 UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1); | |
2188 } | |
2189 | |
2190 CASE(_invokedynamic): { | |
2191 if (!EnableInvokeDynamic) { | |
2192 // We should not encounter this bytecode if !EnableInvokeDynamic. | |
2193 // The verifier will stop it. However, if we get past the verifier, | |
2194 // this will stop the thread in a reasonable way, without crashing the JVM. | |
2195 CALL_VM(InterpreterRuntime::throw_IncompatibleClassChangeError(THREAD), | |
2196 handle_exception); | |
2197 ShouldNotReachHere(); | |
2198 } | |
2199 | |
2200 int index = Bytes::get_native_u4(pc+1); | |
2201 | |
2202 // We are resolved if the f1 field contains a non-null object (CallSite, etc.) | |
2203 // This kind of CP cache entry does not need to match the flags byte, because | |
2204 // there is a 1-1 relation between bytecode type and CP entry type. | |
2205 assert(constantPoolCacheOopDesc::is_secondary_index(index), "incorrect format"); | |
2206 ConstantPoolCacheEntry* cache = cp->secondary_entry_at(index); | |
2207 if (cache->is_f1_null()) { | |
2208 CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD), | |
2209 handle_exception); | |
2210 } | |
2211 | |
2212 VERIFY_OOP(cache->f1()); | |
2213 oop method_handle = java_lang_invoke_CallSite::target(cache->f1()); | |
2214 CHECK_NULL(method_handle); | |
2215 | |
2216 istate->set_msg(call_method_handle); | |
2217 istate->set_callee((methodOop) method_handle); | |
2218 istate->set_bcp_advance(5); | |
2219 | |
2220 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2221 } | |
2222 | |
0 | 2223 CASE(_invokeinterface): { |
2224 u2 index = Bytes::get_native_u2(pc+1); | |
2225 | |
2226 // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases | |
2227 // out so c++ compiler has a chance for constant prop to fold everything possible away. | |
2228 | |
2229 ConstantPoolCacheEntry* cache = cp->entry_at(index); | |
2230 if (!cache->is_resolved((Bytecodes::Code)opcode)) { | |
2231 CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), | |
2232 handle_exception); | |
2233 cache = cp->entry_at(index); | |
2234 } | |
2235 | |
2236 istate->set_msg(call_method); | |
2237 | |
2238 // Special case of invokeinterface called for virtual method of | |
2239 // java.lang.Object. See cpCacheOop.cpp for details. | |
2240 // This code isn't produced by javac, but could be produced by | |
2241 // another compliant java compiler. | |
2242 if (cache->is_methodInterface()) { | |
2243 methodOop callee; | |
2244 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); | |
2245 if (cache->is_vfinal()) { | |
2246 callee = (methodOop) cache->f2(); | |
2247 } else { | |
2248 // get receiver | |
2249 int parms = cache->parameter_size(); | |
2250 // Same comments as invokevirtual apply here | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2251 VERIFY_OOP(STACK_OBJECT(-parms)); |
0 | 2252 instanceKlass* rcvrKlass = (instanceKlass*) |
2253 STACK_OBJECT(-parms)->klass()->klass_part(); | |
2254 callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; | |
2255 } | |
2256 istate->set_callee(callee); | |
2257 istate->set_callee_entry_point(callee->from_interpreted_entry()); | |
2258 #ifdef VM_JVMTI | |
2259 if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { | |
2260 istate->set_callee_entry_point(callee->interpreter_entry()); | |
2261 } | |
2262 #endif /* VM_JVMTI */ | |
2263 istate->set_bcp_advance(5); | |
2264 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2265 } | |
2266 | |
2267 // this could definitely be cleaned up QQQ | |
2268 methodOop callee; | |
2269 klassOop iclass = (klassOop)cache->f1(); | |
2270 // instanceKlass* interface = (instanceKlass*) iclass->klass_part(); | |
2271 // get receiver | |
2272 int parms = cache->parameter_size(); | |
2273 oop rcvr = STACK_OBJECT(-parms); | |
2274 CHECK_NULL(rcvr); | |
2275 instanceKlass* int2 = (instanceKlass*) rcvr->klass()->klass_part(); | |
2276 itableOffsetEntry* ki = (itableOffsetEntry*) int2->start_of_itable(); | |
2277 int i; | |
2278 for ( i = 0 ; i < int2->itable_length() ; i++, ki++ ) { | |
2279 if (ki->interface_klass() == iclass) break; | |
2280 } | |
2281 // If the interface isn't found, this class doesn't implement this | |
2282 // interface. The link resolver checks this but only for the first | |
2283 // time this interface is called. | |
2284 if (i == int2->itable_length()) { | |
2285 VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), ""); | |
2286 } | |
2287 int mindex = cache->f2(); | |
2288 itableMethodEntry* im = ki->first_method_entry(rcvr->klass()); | |
2289 callee = im[mindex].method(); | |
2290 if (callee == NULL) { | |
2291 VM_JAVA_ERROR(vmSymbols::java_lang_AbstractMethodError(), ""); | |
2292 } | |
2293 | |
2294 istate->set_callee(callee); | |
2295 istate->set_callee_entry_point(callee->from_interpreted_entry()); | |
2296 #ifdef VM_JVMTI | |
2297 if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { | |
2298 istate->set_callee_entry_point(callee->interpreter_entry()); | |
2299 } | |
2300 #endif /* VM_JVMTI */ | |
2301 istate->set_bcp_advance(5); | |
2302 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2303 } | |
2304 | |
2305 CASE(_invokevirtual): | |
2306 CASE(_invokespecial): | |
2307 CASE(_invokestatic): { | |
2308 u2 index = Bytes::get_native_u2(pc+1); | |
2309 | |
2310 ConstantPoolCacheEntry* cache = cp->entry_at(index); | |
2311 // QQQ Need to make this as inlined as possible. Probably need to split all the bytecode cases | |
2312 // out so c++ compiler has a chance for constant prop to fold everything possible away. | |
2313 | |
2314 if (!cache->is_resolved((Bytecodes::Code)opcode)) { | |
2315 CALL_VM(InterpreterRuntime::resolve_invoke(THREAD, (Bytecodes::Code)opcode), | |
2316 handle_exception); | |
2317 cache = cp->entry_at(index); | |
2318 } | |
2319 | |
2320 istate->set_msg(call_method); | |
2321 { | |
2322 methodOop callee; | |
2323 if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) { | |
2324 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); | |
2325 if (cache->is_vfinal()) callee = (methodOop) cache->f2(); | |
2326 else { | |
2327 // get receiver | |
2328 int parms = cache->parameter_size(); | |
2329 // this works but needs a resourcemark and seems to create a vtable on every call: | |
2330 // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2()); | |
2331 // | |
2332 // this fails with an assert | |
2333 // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass()); | |
2334 // but this works | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2335 VERIFY_OOP(STACK_OBJECT(-parms)); |
0 | 2336 instanceKlass* rcvrKlass = (instanceKlass*) STACK_OBJECT(-parms)->klass()->klass_part(); |
2337 /* | |
2338 Executing this code in java.lang.String: | |
2339 public String(char value[]) { | |
2340 this.count = value.length; | |
2341 this.value = (char[])value.clone(); | |
2342 } | |
2343 | |
2344 a find on rcvr->klass()->klass_part() reports: | |
2345 {type array char}{type array class} | |
2346 - klass: {other class} | |
2347 | |
2348 but using instanceKlass::cast(STACK_OBJECT(-parms)->klass()) causes in assertion failure | |
2349 because rcvr->klass()->klass_part()->oop_is_instance() == 0 | |
2350 However it seems to have a vtable in the right location. Huh? | |
2351 | |
2352 */ | |
2353 callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()]; | |
2354 } | |
2355 } else { | |
2356 if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) { | |
2357 CHECK_NULL(STACK_OBJECT(-(cache->parameter_size()))); | |
2358 } | |
2359 callee = (methodOop) cache->f1(); | |
2360 } | |
2361 | |
2362 istate->set_callee(callee); | |
2363 istate->set_callee_entry_point(callee->from_interpreted_entry()); | |
2364 #ifdef VM_JVMTI | |
2365 if (JvmtiExport::can_post_interpreter_events() && THREAD->is_interp_only_mode()) { | |
2366 istate->set_callee_entry_point(callee->interpreter_entry()); | |
2367 } | |
2368 #endif /* VM_JVMTI */ | |
2369 istate->set_bcp_advance(3); | |
2370 UPDATE_PC_AND_RETURN(0); // I'll be back... | |
2371 } | |
2372 } | |
2373 | |
2374 /* Allocate memory for a new java object. */ | |
2375 | |
2376 CASE(_newarray): { | |
2377 BasicType atype = (BasicType) *(pc+1); | |
2378 jint size = STACK_INT(-1); | |
2379 CALL_VM(InterpreterRuntime::newarray(THREAD, atype, size), | |
2380 handle_exception); | |
2381 SET_STACK_OBJECT(THREAD->vm_result(), -1); | |
2382 THREAD->set_vm_result(NULL); | |
2383 | |
2384 UPDATE_PC_AND_CONTINUE(2); | |
2385 } | |
2386 | |
2387 /* Throw an exception. */ | |
2388 | |
2389 CASE(_athrow): { | |
2390 oop except_oop = STACK_OBJECT(-1); | |
2391 CHECK_NULL(except_oop); | |
2392 // set pending_exception so we use common code | |
2393 THREAD->set_pending_exception(except_oop, NULL, 0); | |
2394 goto handle_exception; | |
2395 } | |
2396 | |
2397 /* goto and jsr. They are exactly the same except jsr pushes | |
2398 * the address of the next instruction first. | |
2399 */ | |
2400 | |
2401 CASE(_jsr): { | |
2402 /* push bytecode index on stack */ | |
2403 SET_STACK_ADDR(((address)pc - (intptr_t)(istate->method()->code_base()) + 3), 0); | |
2404 MORE_STACK(1); | |
2405 /* FALL THROUGH */ | |
2406 } | |
2407 | |
2408 CASE(_goto): | |
2409 { | |
2410 int16_t offset = (int16_t)Bytes::get_Java_u2(pc + 1); | |
2411 address branch_pc = pc; | |
2412 UPDATE_PC(offset); | |
2413 DO_BACKEDGE_CHECKS(offset, branch_pc); | |
2414 CONTINUE; | |
2415 } | |
2416 | |
2417 CASE(_jsr_w): { | |
2418 /* push return address on the stack */ | |
2419 SET_STACK_ADDR(((address)pc - (intptr_t)(istate->method()->code_base()) + 5), 0); | |
2420 MORE_STACK(1); | |
2421 /* FALL THROUGH */ | |
2422 } | |
2423 | |
2424 CASE(_goto_w): | |
2425 { | |
2426 int32_t offset = Bytes::get_Java_u4(pc + 1); | |
2427 address branch_pc = pc; | |
2428 UPDATE_PC(offset); | |
2429 DO_BACKEDGE_CHECKS(offset, branch_pc); | |
2430 CONTINUE; | |
2431 } | |
2432 | |
2433 /* return from a jsr or jsr_w */ | |
2434 | |
2435 CASE(_ret): { | |
2436 pc = istate->method()->code_base() + (intptr_t)(LOCALS_ADDR(pc[1])); | |
2437 UPDATE_PC_AND_CONTINUE(0); | |
2438 } | |
2439 | |
2440 /* debugger breakpoint */ | |
2441 | |
2442 CASE(_breakpoint): { | |
2443 Bytecodes::Code original_bytecode; | |
2444 DECACHE_STATE(); | |
2445 SET_LAST_JAVA_FRAME(); | |
2446 original_bytecode = InterpreterRuntime::get_original_bytecode_at(THREAD, | |
2447 METHOD, pc); | |
2448 RESET_LAST_JAVA_FRAME(); | |
2449 CACHE_STATE(); | |
2450 if (THREAD->has_pending_exception()) goto handle_exception; | |
2451 CALL_VM(InterpreterRuntime::_breakpoint(THREAD, METHOD, pc), | |
2452 handle_exception); | |
2453 | |
2454 opcode = (jubyte)original_bytecode; | |
2455 goto opcode_switch; | |
2456 } | |
2457 | |
2458 DEFAULT: | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1347
diff
changeset
|
2459 fatal(err_msg("Unimplemented opcode %d = %s", opcode, |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1347
diff
changeset
|
2460 Bytecodes::name((Bytecodes::Code)opcode))); |
0 | 2461 goto finish; |
2462 | |
2463 } /* switch(opc) */ | |
2464 | |
2465 | |
2466 #ifdef USELABELS | |
2467 check_for_exception: | |
2468 #endif | |
2469 { | |
2470 if (!THREAD->has_pending_exception()) { | |
2471 CONTINUE; | |
2472 } | |
2473 /* We will be gcsafe soon, so flush our state. */ | |
2474 DECACHE_PC(); | |
2475 goto handle_exception; | |
2476 } | |
2477 do_continue: ; | |
2478 | |
2479 } /* while (1) interpreter loop */ | |
2480 | |
2481 | |
2482 // An exception exists in the thread state see whether this activation can handle it | |
2483 handle_exception: { | |
2484 | |
2485 HandleMarkCleaner __hmc(THREAD); | |
2486 Handle except_oop(THREAD, THREAD->pending_exception()); | |
2487 // Prevent any subsequent HandleMarkCleaner in the VM | |
2488 // from freeing the except_oop handle. | |
2489 HandleMark __hm(THREAD); | |
2490 | |
2491 THREAD->clear_pending_exception(); | |
2492 assert(except_oop(), "No exception to process"); | |
2493 intptr_t continuation_bci; | |
2494 // expression stack is emptied | |
1509 | 2495 topOfStack = istate->stack_base() - Interpreter::stackElementWords; |
0 | 2496 CALL_VM(continuation_bci = (intptr_t)InterpreterRuntime::exception_handler_for_exception(THREAD, except_oop()), |
2497 handle_exception); | |
2498 | |
2499 except_oop = (oop) THREAD->vm_result(); | |
2500 THREAD->set_vm_result(NULL); | |
2501 if (continuation_bci >= 0) { | |
2502 // Place exception on top of stack | |
2503 SET_STACK_OBJECT(except_oop(), 0); | |
2504 MORE_STACK(1); | |
2505 pc = METHOD->code_base() + continuation_bci; | |
2506 if (TraceExceptions) { | |
2507 ttyLocker ttyl; | |
2508 ResourceMark rm; | |
2509 tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop()); | |
2510 tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string()); | |
2511 tty->print_cr(" at bci %d, continuing at %d for thread " INTPTR_FORMAT, | |
2512 pc - (intptr_t)METHOD->code_base(), | |
2513 continuation_bci, THREAD); | |
2514 } | |
2515 // for AbortVMOnException flag | |
2516 NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); | |
2517 goto run; | |
2518 } | |
2519 if (TraceExceptions) { | |
2520 ttyLocker ttyl; | |
2521 ResourceMark rm; | |
2522 tty->print_cr("Exception <%s> (" INTPTR_FORMAT ")", except_oop->print_value_string(), except_oop()); | |
2523 tty->print_cr(" thrown in interpreter method <%s>", METHOD->print_value_string()); | |
2524 tty->print_cr(" at bci %d, unwinding for thread " INTPTR_FORMAT, | |
2525 pc - (intptr_t) METHOD->code_base(), | |
2526 THREAD); | |
2527 } | |
2528 // for AbortVMOnException flag | |
2529 NOT_PRODUCT(Exceptions::debug_check_abort(except_oop)); | |
2530 // No handler in this activation, unwind and try again | |
2531 THREAD->set_pending_exception(except_oop(), NULL, 0); | |
2532 goto handle_return; | |
2533 } /* handle_exception: */ | |
2534 | |
2535 | |
2536 | |
2537 // Return from an interpreter invocation with the result of the interpretation | |
2538 // on the top of the Java Stack (or a pending exception) | |
2539 | |
2540 handle_Pop_Frame: | |
2541 | |
2542 // We don't really do anything special here except we must be aware | |
2543 // that we can get here without ever locking the method (if sync). | |
2544 // Also we skip the notification of the exit. | |
2545 | |
2546 istate->set_msg(popping_frame); | |
2547 // Clear pending so while the pop is in process | |
2548 // we don't start another one if a call_vm is done. | |
2549 THREAD->clr_pop_frame_pending(); | |
2550 // Let interpreter (only) see the we're in the process of popping a frame | |
2551 THREAD->set_pop_frame_in_process(); | |
2552 | |
2553 handle_return: | |
2554 { | |
2555 DECACHE_STATE(); | |
2556 | |
2557 bool suppress_error = istate->msg() == popping_frame; | |
2558 bool suppress_exit_event = THREAD->has_pending_exception() || suppress_error; | |
2559 Handle original_exception(THREAD, THREAD->pending_exception()); | |
2560 Handle illegal_state_oop(THREAD, NULL); | |
2561 | |
2562 // We'd like a HandleMark here to prevent any subsequent HandleMarkCleaner | |
2563 // in any following VM entries from freeing our live handles, but illegal_state_oop | |
2564 // isn't really allocated yet and so doesn't become live until later and | |
2565 // in unpredicatable places. Instead we must protect the places where we enter the | |
2566 // VM. It would be much simpler (and safer) if we could allocate a real handle with | |
2567 // a NULL oop in it and then overwrite the oop later as needed. This isn't | |
2568 // unfortunately isn't possible. | |
2569 | |
2570 THREAD->clear_pending_exception(); | |
2571 | |
2572 // | |
2573 // As far as we are concerned we have returned. If we have a pending exception | |
2574 // that will be returned as this invocation's result. However if we get any | |
2575 // exception(s) while checking monitor state one of those IllegalMonitorStateExceptions | |
2576 // will be our final result (i.e. monitor exception trumps a pending exception). | |
2577 // | |
2578 | |
2579 // If we never locked the method (or really passed the point where we would have), | |
2580 // there is no need to unlock it (or look for other monitors), since that | |
2581 // could not have happened. | |
2582 | |
2583 if (THREAD->do_not_unlock()) { | |
2584 | |
2585 // Never locked, reset the flag now because obviously any caller must | |
2586 // have passed their point of locking for us to have gotten here. | |
2587 | |
2588 THREAD->clr_do_not_unlock(); | |
2589 } else { | |
2590 // At this point we consider that we have returned. We now check that the | |
2591 // locks were properly block structured. If we find that they were not | |
2592 // used properly we will return with an illegal monitor exception. | |
2593 // The exception is checked by the caller not the callee since this | |
2594 // checking is considered to be part of the invocation and therefore | |
2595 // in the callers scope (JVM spec 8.13). | |
2596 // | |
2597 // Another weird thing to watch for is if the method was locked | |
2598 // recursively and then not exited properly. This means we must | |
2599 // examine all the entries in reverse time(and stack) order and | |
2600 // unlock as we find them. If we find the method monitor before | |
2601 // we are at the initial entry then we should throw an exception. | |
2602 // It is not clear the template based interpreter does this | |
2603 // correctly | |
2604 | |
2605 BasicObjectLock* base = istate->monitor_base(); | |
2606 BasicObjectLock* end = (BasicObjectLock*) istate->stack_base(); | |
2607 bool method_unlock_needed = METHOD->is_synchronized(); | |
2608 // We know the initial monitor was used for the method don't check that | |
2609 // slot in the loop | |
2610 if (method_unlock_needed) base--; | |
2611 | |
2612 // Check all the monitors to see they are unlocked. Install exception if found to be locked. | |
2613 while (end < base) { | |
2614 oop lockee = end->obj(); | |
2615 if (lockee != NULL) { | |
2616 BasicLock* lock = end->lock(); | |
2617 markOop header = lock->displaced_header(); | |
2618 end->set_obj(NULL); | |
2619 // If it isn't recursive we either must swap old header or call the runtime | |
2620 if (header != NULL) { | |
2621 if (Atomic::cmpxchg_ptr(header, lockee->mark_addr(), lock) != lock) { | |
2622 // restore object for the slow case | |
2623 end->set_obj(lockee); | |
2624 { | |
2625 // Prevent any HandleMarkCleaner from freeing our live handles | |
2626 HandleMark __hm(THREAD); | |
2627 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, end)); | |
2628 } | |
2629 } | |
2630 } | |
2631 // One error is plenty | |
2632 if (illegal_state_oop() == NULL && !suppress_error) { | |
2633 { | |
2634 // Prevent any HandleMarkCleaner from freeing our live handles | |
2635 HandleMark __hm(THREAD); | |
2636 CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD)); | |
2637 } | |
2638 assert(THREAD->has_pending_exception(), "Lost our exception!"); | |
2639 illegal_state_oop = THREAD->pending_exception(); | |
2640 THREAD->clear_pending_exception(); | |
2641 } | |
2642 } | |
2643 end++; | |
2644 } | |
2645 // Unlock the method if needed | |
2646 if (method_unlock_needed) { | |
2647 if (base->obj() == NULL) { | |
2648 // The method is already unlocked this is not good. | |
2649 if (illegal_state_oop() == NULL && !suppress_error) { | |
2650 { | |
2651 // Prevent any HandleMarkCleaner from freeing our live handles | |
2652 HandleMark __hm(THREAD); | |
2653 CALL_VM_NOCHECK(InterpreterRuntime::throw_illegal_monitor_state_exception(THREAD)); | |
2654 } | |
2655 assert(THREAD->has_pending_exception(), "Lost our exception!"); | |
2656 illegal_state_oop = THREAD->pending_exception(); | |
2657 THREAD->clear_pending_exception(); | |
2658 } | |
2659 } else { | |
2660 // | |
2661 // The initial monitor is always used for the method | |
2662 // However if that slot is no longer the oop for the method it was unlocked | |
2663 // and reused by something that wasn't unlocked! | |
2664 // | |
2665 // deopt can come in with rcvr dead because c2 knows | |
2666 // its value is preserved in the monitor. So we can't use locals[0] at all | |
2667 // and must use first monitor slot. | |
2668 // | |
2669 oop rcvr = base->obj(); | |
2670 if (rcvr == NULL) { | |
2671 if (!suppress_error) { | |
2672 VM_JAVA_ERROR_NO_JUMP(vmSymbols::java_lang_NullPointerException(), ""); | |
2673 illegal_state_oop = THREAD->pending_exception(); | |
2674 THREAD->clear_pending_exception(); | |
2675 } | |
2676 } else { | |
2677 BasicLock* lock = base->lock(); | |
2678 markOop header = lock->displaced_header(); | |
2679 base->set_obj(NULL); | |
2680 // If it isn't recursive we either must swap old header or call the runtime | |
2681 if (header != NULL) { | |
2682 if (Atomic::cmpxchg_ptr(header, rcvr->mark_addr(), lock) != lock) { | |
2683 // restore object for the slow case | |
2684 base->set_obj(rcvr); | |
2685 { | |
2686 // Prevent any HandleMarkCleaner from freeing our live handles | |
2687 HandleMark __hm(THREAD); | |
2688 CALL_VM_NOCHECK(InterpreterRuntime::monitorexit(THREAD, base)); | |
2689 } | |
2690 if (THREAD->has_pending_exception()) { | |
2691 if (!suppress_error) illegal_state_oop = THREAD->pending_exception(); | |
2692 THREAD->clear_pending_exception(); | |
2693 } | |
2694 } | |
2695 } | |
2696 } | |
2697 } | |
2698 } | |
2699 } | |
2700 | |
2701 // | |
2702 // Notify jvmti/jvmdi | |
2703 // | |
2704 // NOTE: we do not notify a method_exit if we have a pending exception, | |
2705 // including an exception we generate for unlocking checks. In the former | |
2706 // case, JVMDI has already been notified by our call for the exception handler | |
2707 // and in both cases as far as JVMDI is concerned we have already returned. | |
2708 // If we notify it again JVMDI will be all confused about how many frames | |
2709 // are still on the stack (4340444). | |
2710 // | |
2711 // NOTE Further! It turns out the the JVMTI spec in fact expects to see | |
2712 // method_exit events whenever we leave an activation unless it was done | |
2713 // for popframe. This is nothing like jvmdi. However we are passing the | |
2714 // tests at the moment (apparently because they are jvmdi based) so rather | |
2715 // than change this code and possibly fail tests we will leave it alone | |
2716 // (with this note) in anticipation of changing the vm and the tests | |
2717 // simultaneously. | |
2718 | |
2719 | |
2720 // | |
2721 suppress_exit_event = suppress_exit_event || illegal_state_oop() != NULL; | |
2722 | |
2723 | |
2724 | |
2725 #ifdef VM_JVMTI | |
2726 if (_jvmti_interp_events) { | |
2727 // Whenever JVMTI puts a thread in interp_only_mode, method | |
2728 // entry/exit events are sent for that thread to track stack depth. | |
2729 if ( !suppress_exit_event && THREAD->is_interp_only_mode() ) { | |
2730 { | |
2731 // Prevent any HandleMarkCleaner from freeing our live handles | |
2732 HandleMark __hm(THREAD); | |
2733 CALL_VM_NOCHECK(InterpreterRuntime::post_method_exit(THREAD)); | |
2734 } | |
2735 } | |
2736 } | |
2737 #endif /* VM_JVMTI */ | |
2738 | |
2739 // | |
2740 // See if we are returning any exception | |
2741 // A pending exception that was pending prior to a possible popping frame | |
2742 // overrides the popping frame. | |
2743 // | |
2744 assert(!suppress_error || suppress_error && illegal_state_oop() == NULL, "Error was not suppressed"); | |
2745 if (illegal_state_oop() != NULL || original_exception() != NULL) { | |
2746 // inform the frame manager we have no result | |
2747 istate->set_msg(throwing_exception); | |
2748 if (illegal_state_oop() != NULL) | |
2749 THREAD->set_pending_exception(illegal_state_oop(), NULL, 0); | |
2750 else | |
2751 THREAD->set_pending_exception(original_exception(), NULL, 0); | |
2752 istate->set_return_kind((Bytecodes::Code)opcode); | |
2753 UPDATE_PC_AND_RETURN(0); | |
2754 } | |
2755 | |
2756 if (istate->msg() == popping_frame) { | |
2757 // Make it simpler on the assembly code and set the message for the frame pop. | |
2758 // returns | |
2759 if (istate->prev() == NULL) { | |
2760 // We must be returning to a deoptimized frame (because popframe only happens between | |
2761 // two interpreted frames). We need to save the current arguments in C heap so that | |
2762 // the deoptimized frame when it restarts can copy the arguments to its expression | |
2763 // stack and re-execute the call. We also have to notify deoptimization that this | |
605 | 2764 // has occurred and to pick the preserved args copy them to the deoptimized frame's |
0 | 2765 // java expression stack. Yuck. |
2766 // | |
2767 THREAD->popframe_preserve_args(in_ByteSize(METHOD->size_of_parameters() * wordSize), | |
2768 LOCALS_SLOT(METHOD->size_of_parameters() - 1)); | |
2769 THREAD->set_popframe_condition_bit(JavaThread::popframe_force_deopt_reexecution_bit); | |
2770 } | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2771 THREAD->clr_pop_frame_in_process(); |
0 | 2772 } |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2773 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2774 // Normal return |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2775 // Advance the pc and return to frame manager |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2776 istate->set_msg(return_from_method); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2777 istate->set_return_kind((Bytecodes::Code)opcode); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1552
diff
changeset
|
2778 UPDATE_PC_AND_RETURN(1); |
0 | 2779 } /* handle_return: */ |
2780 | |
2781 // This is really a fatal error return | |
2782 | |
2783 finish: | |
2784 DECACHE_TOS(); | |
2785 DECACHE_PC(); | |
2786 | |
2787 return; | |
2788 } | |
2789 | |
2790 /* | |
2791 * All the code following this point is only produced once and is not present | |
2792 * in the JVMTI version of the interpreter | |
2793 */ | |
2794 | |
2795 #ifndef VM_JVMTI | |
2796 | |
2797 // This constructor should only be used to contruct the object to signal | |
2798 // interpreter initialization. All other instances should be created by | |
2799 // the frame manager. | |
2800 BytecodeInterpreter::BytecodeInterpreter(messages msg) { | |
2801 if (msg != initialize) ShouldNotReachHere(); | |
2802 _msg = msg; | |
2803 _self_link = this; | |
2804 _prev_link = NULL; | |
2805 } | |
2806 | |
2807 // Inline static functions for Java Stack and Local manipulation | |
2808 | |
2809 // The implementations are platform dependent. We have to worry about alignment | |
2810 // issues on some machines which can change on the same platform depending on | |
2811 // whether it is an LP64 machine also. | |
2812 address BytecodeInterpreter::stack_slot(intptr_t *tos, int offset) { | |
2813 return (address) tos[Interpreter::expr_index_at(-offset)]; | |
2814 } | |
2815 | |
2816 jint BytecodeInterpreter::stack_int(intptr_t *tos, int offset) { | |
2817 return *((jint*) &tos[Interpreter::expr_index_at(-offset)]); | |
2818 } | |
2819 | |
2820 jfloat BytecodeInterpreter::stack_float(intptr_t *tos, int offset) { | |
2821 return *((jfloat *) &tos[Interpreter::expr_index_at(-offset)]); | |
2822 } | |
2823 | |
2824 oop BytecodeInterpreter::stack_object(intptr_t *tos, int offset) { | |
2825 return (oop)tos [Interpreter::expr_index_at(-offset)]; | |
2826 } | |
2827 | |
2828 jdouble BytecodeInterpreter::stack_double(intptr_t *tos, int offset) { | |
2829 return ((VMJavaVal64*) &tos[Interpreter::expr_index_at(-offset)])->d; | |
2830 } | |
2831 | |
2832 jlong BytecodeInterpreter::stack_long(intptr_t *tos, int offset) { | |
2833 return ((VMJavaVal64 *) &tos[Interpreter::expr_index_at(-offset)])->l; | |
2834 } | |
2835 | |
2836 // only used for value types | |
2837 void BytecodeInterpreter::set_stack_slot(intptr_t *tos, address value, | |
2838 int offset) { | |
2839 *((address *)&tos[Interpreter::expr_index_at(-offset)]) = value; | |
2840 } | |
2841 | |
2842 void BytecodeInterpreter::set_stack_int(intptr_t *tos, int value, | |
2843 int offset) { | |
2844 *((jint *)&tos[Interpreter::expr_index_at(-offset)]) = value; | |
2845 } | |
2846 | |
2847 void BytecodeInterpreter::set_stack_float(intptr_t *tos, jfloat value, | |
2848 int offset) { | |
2849 *((jfloat *)&tos[Interpreter::expr_index_at(-offset)]) = value; | |
2850 } | |
2851 | |
2852 void BytecodeInterpreter::set_stack_object(intptr_t *tos, oop value, | |
2853 int offset) { | |
2854 *((oop *)&tos[Interpreter::expr_index_at(-offset)]) = value; | |
2855 } | |
2856 | |
2857 // needs to be platform dep for the 32 bit platforms. | |
2858 void BytecodeInterpreter::set_stack_double(intptr_t *tos, jdouble value, | |
2859 int offset) { | |
2860 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = value; | |
2861 } | |
2862 | |
2863 void BytecodeInterpreter::set_stack_double_from_addr(intptr_t *tos, | |
2864 address addr, int offset) { | |
2865 (((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->d = | |
2866 ((VMJavaVal64*)addr)->d); | |
2867 } | |
2868 | |
2869 void BytecodeInterpreter::set_stack_long(intptr_t *tos, jlong value, | |
2870 int offset) { | |
2871 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb; | |
2872 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = value; | |
2873 } | |
2874 | |
2875 void BytecodeInterpreter::set_stack_long_from_addr(intptr_t *tos, | |
2876 address addr, int offset) { | |
2877 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset+1)])->l = 0xdeedbeeb; | |
2878 ((VMJavaVal64*)&tos[Interpreter::expr_index_at(-offset)])->l = | |
2879 ((VMJavaVal64*)addr)->l; | |
2880 } | |
2881 | |
2882 // Locals | |
2883 | |
2884 address BytecodeInterpreter::locals_slot(intptr_t* locals, int offset) { | |
2885 return (address)locals[Interpreter::local_index_at(-offset)]; | |
2886 } | |
2887 jint BytecodeInterpreter::locals_int(intptr_t* locals, int offset) { | |
2888 return (jint)locals[Interpreter::local_index_at(-offset)]; | |
2889 } | |
2890 jfloat BytecodeInterpreter::locals_float(intptr_t* locals, int offset) { | |
2891 return (jfloat)locals[Interpreter::local_index_at(-offset)]; | |
2892 } | |
2893 oop BytecodeInterpreter::locals_object(intptr_t* locals, int offset) { | |
2894 return (oop)locals[Interpreter::local_index_at(-offset)]; | |
2895 } | |
2896 jdouble BytecodeInterpreter::locals_double(intptr_t* locals, int offset) { | |
2897 return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d; | |
2898 } | |
2899 jlong BytecodeInterpreter::locals_long(intptr_t* locals, int offset) { | |
2900 return ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l; | |
2901 } | |
2902 | |
2903 // Returns the address of locals value. | |
2904 address BytecodeInterpreter::locals_long_at(intptr_t* locals, int offset) { | |
2905 return ((address)&locals[Interpreter::local_index_at(-(offset+1))]); | |
2906 } | |
2907 address BytecodeInterpreter::locals_double_at(intptr_t* locals, int offset) { | |
2908 return ((address)&locals[Interpreter::local_index_at(-(offset+1))]); | |
2909 } | |
2910 | |
2911 // Used for local value or returnAddress | |
2912 void BytecodeInterpreter::set_locals_slot(intptr_t *locals, | |
2913 address value, int offset) { | |
2914 *((address*)&locals[Interpreter::local_index_at(-offset)]) = value; | |
2915 } | |
2916 void BytecodeInterpreter::set_locals_int(intptr_t *locals, | |
2917 jint value, int offset) { | |
2918 *((jint *)&locals[Interpreter::local_index_at(-offset)]) = value; | |
2919 } | |
2920 void BytecodeInterpreter::set_locals_float(intptr_t *locals, | |
2921 jfloat value, int offset) { | |
2922 *((jfloat *)&locals[Interpreter::local_index_at(-offset)]) = value; | |
2923 } | |
2924 void BytecodeInterpreter::set_locals_object(intptr_t *locals, | |
2925 oop value, int offset) { | |
2926 *((oop *)&locals[Interpreter::local_index_at(-offset)]) = value; | |
2927 } | |
2928 void BytecodeInterpreter::set_locals_double(intptr_t *locals, | |
2929 jdouble value, int offset) { | |
2930 ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = value; | |
2931 } | |
2932 void BytecodeInterpreter::set_locals_long(intptr_t *locals, | |
2933 jlong value, int offset) { | |
2934 ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = value; | |
2935 } | |
2936 void BytecodeInterpreter::set_locals_double_from_addr(intptr_t *locals, | |
2937 address addr, int offset) { | |
2938 ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->d = ((VMJavaVal64*)addr)->d; | |
2939 } | |
2940 void BytecodeInterpreter::set_locals_long_from_addr(intptr_t *locals, | |
2941 address addr, int offset) { | |
2942 ((VMJavaVal64*)&locals[Interpreter::local_index_at(-(offset+1))])->l = ((VMJavaVal64*)addr)->l; | |
2943 } | |
2944 | |
2945 void BytecodeInterpreter::astore(intptr_t* tos, int stack_offset, | |
2946 intptr_t* locals, int locals_offset) { | |
2947 intptr_t value = tos[Interpreter::expr_index_at(-stack_offset)]; | |
2948 locals[Interpreter::local_index_at(-locals_offset)] = value; | |
2949 } | |
2950 | |
2951 | |
2952 void BytecodeInterpreter::copy_stack_slot(intptr_t *tos, int from_offset, | |
2953 int to_offset) { | |
2954 tos[Interpreter::expr_index_at(-to_offset)] = | |
2955 (intptr_t)tos[Interpreter::expr_index_at(-from_offset)]; | |
2956 } | |
2957 | |
2958 void BytecodeInterpreter::dup(intptr_t *tos) { | |
2959 copy_stack_slot(tos, -1, 0); | |
2960 } | |
2961 void BytecodeInterpreter::dup2(intptr_t *tos) { | |
2962 copy_stack_slot(tos, -2, 0); | |
2963 copy_stack_slot(tos, -1, 1); | |
2964 } | |
2965 | |
2966 void BytecodeInterpreter::dup_x1(intptr_t *tos) { | |
2967 /* insert top word two down */ | |
2968 copy_stack_slot(tos, -1, 0); | |
2969 copy_stack_slot(tos, -2, -1); | |
2970 copy_stack_slot(tos, 0, -2); | |
2971 } | |
2972 | |
2973 void BytecodeInterpreter::dup_x2(intptr_t *tos) { | |
2974 /* insert top word three down */ | |
2975 copy_stack_slot(tos, -1, 0); | |
2976 copy_stack_slot(tos, -2, -1); | |
2977 copy_stack_slot(tos, -3, -2); | |
2978 copy_stack_slot(tos, 0, -3); | |
2979 } | |
2980 void BytecodeInterpreter::dup2_x1(intptr_t *tos) { | |
2981 /* insert top 2 slots three down */ | |
2982 copy_stack_slot(tos, -1, 1); | |
2983 copy_stack_slot(tos, -2, 0); | |
2984 copy_stack_slot(tos, -3, -1); | |
2985 copy_stack_slot(tos, 1, -2); | |
2986 copy_stack_slot(tos, 0, -3); | |
2987 } | |
2988 void BytecodeInterpreter::dup2_x2(intptr_t *tos) { | |
2989 /* insert top 2 slots four down */ | |
2990 copy_stack_slot(tos, -1, 1); | |
2991 copy_stack_slot(tos, -2, 0); | |
2992 copy_stack_slot(tos, -3, -1); | |
2993 copy_stack_slot(tos, -4, -2); | |
2994 copy_stack_slot(tos, 1, -3); | |
2995 copy_stack_slot(tos, 0, -4); | |
2996 } | |
2997 | |
2998 | |
2999 void BytecodeInterpreter::swap(intptr_t *tos) { | |
3000 // swap top two elements | |
3001 intptr_t val = tos[Interpreter::expr_index_at(1)]; | |
3002 // Copy -2 entry to -1 | |
3003 copy_stack_slot(tos, -2, -1); | |
3004 // Store saved -1 entry into -2 | |
3005 tos[Interpreter::expr_index_at(2)] = val; | |
3006 } | |
3007 // -------------------------------------------------------------------------------- | |
3008 // Non-product code | |
3009 #ifndef PRODUCT | |
3010 | |
3011 const char* BytecodeInterpreter::C_msg(BytecodeInterpreter::messages msg) { | |
3012 switch (msg) { | |
3013 case BytecodeInterpreter::no_request: return("no_request"); | |
3014 case BytecodeInterpreter::initialize: return("initialize"); | |
3015 // status message to C++ interpreter | |
3016 case BytecodeInterpreter::method_entry: return("method_entry"); | |
3017 case BytecodeInterpreter::method_resume: return("method_resume"); | |
3018 case BytecodeInterpreter::got_monitors: return("got_monitors"); | |
3019 case BytecodeInterpreter::rethrow_exception: return("rethrow_exception"); | |
3020 // requests to frame manager from C++ interpreter | |
3021 case BytecodeInterpreter::call_method: return("call_method"); | |
3022 case BytecodeInterpreter::return_from_method: return("return_from_method"); | |
3023 case BytecodeInterpreter::more_monitors: return("more_monitors"); | |
3024 case BytecodeInterpreter::throwing_exception: return("throwing_exception"); | |
3025 case BytecodeInterpreter::popping_frame: return("popping_frame"); | |
3026 case BytecodeInterpreter::do_osr: return("do_osr"); | |
3027 // deopt | |
3028 case BytecodeInterpreter::deopt_resume: return("deopt_resume"); | |
3029 case BytecodeInterpreter::deopt_resume2: return("deopt_resume2"); | |
3030 default: return("BAD MSG"); | |
3031 } | |
3032 } | |
3033 void | |
3034 BytecodeInterpreter::print() { | |
3035 tty->print_cr("thread: " INTPTR_FORMAT, (uintptr_t) this->_thread); | |
3036 tty->print_cr("bcp: " INTPTR_FORMAT, (uintptr_t) this->_bcp); | |
3037 tty->print_cr("locals: " INTPTR_FORMAT, (uintptr_t) this->_locals); | |
3038 tty->print_cr("constants: " INTPTR_FORMAT, (uintptr_t) this->_constants); | |
3039 { | |
3040 ResourceMark rm; | |
3041 char *method_name = _method->name_and_sig_as_C_string(); | |
3042 tty->print_cr("method: " INTPTR_FORMAT "[ %s ]", (uintptr_t) this->_method, method_name); | |
3043 } | |
3044 tty->print_cr("mdx: " INTPTR_FORMAT, (uintptr_t) this->_mdx); | |
3045 tty->print_cr("stack: " INTPTR_FORMAT, (uintptr_t) this->_stack); | |
3046 tty->print_cr("msg: %s", C_msg(this->_msg)); | |
3047 tty->print_cr("result_to_call._callee: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee); | |
3048 tty->print_cr("result_to_call._callee_entry_point: " INTPTR_FORMAT, (uintptr_t) this->_result._to_call._callee_entry_point); | |
3049 tty->print_cr("result_to_call._bcp_advance: %d ", this->_result._to_call._bcp_advance); | |
3050 tty->print_cr("osr._osr_buf: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_buf); | |
3051 tty->print_cr("osr._osr_entry: " INTPTR_FORMAT, (uintptr_t) this->_result._osr._osr_entry); | |
3052 tty->print_cr("result_return_kind 0x%x ", (int) this->_result._return_kind); | |
3053 tty->print_cr("prev_link: " INTPTR_FORMAT, (uintptr_t) this->_prev_link); | |
3054 tty->print_cr("native_mirror: " INTPTR_FORMAT, (uintptr_t) this->_oop_temp); | |
3055 tty->print_cr("stack_base: " INTPTR_FORMAT, (uintptr_t) this->_stack_base); | |
3056 tty->print_cr("stack_limit: " INTPTR_FORMAT, (uintptr_t) this->_stack_limit); | |
3057 tty->print_cr("monitor_base: " INTPTR_FORMAT, (uintptr_t) this->_monitor_base); | |
3058 #ifdef SPARC | |
3059 tty->print_cr("last_Java_pc: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_pc); | |
3060 tty->print_cr("frame_bottom: " INTPTR_FORMAT, (uintptr_t) this->_frame_bottom); | |
3061 tty->print_cr("&native_fresult: " INTPTR_FORMAT, (uintptr_t) &this->_native_fresult); | |
3062 tty->print_cr("native_lresult: " INTPTR_FORMAT, (uintptr_t) this->_native_lresult); | |
3063 #endif | |
1010 | 3064 #if defined(IA64) && !defined(ZERO) |
0 | 3065 tty->print_cr("last_Java_fp: " INTPTR_FORMAT, (uintptr_t) this->_last_Java_fp); |
1010 | 3066 #endif // IA64 && !ZERO |
0 | 3067 tty->print_cr("self_link: " INTPTR_FORMAT, (uintptr_t) this->_self_link); |
3068 } | |
3069 | |
3070 extern "C" { | |
3071 void PI(uintptr_t arg) { | |
3072 ((BytecodeInterpreter*)arg)->print(); | |
3073 } | |
3074 } | |
3075 #endif // PRODUCT | |
3076 | |
3077 #endif // JVMTI | |
3078 #endif // CC_INTERP |