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