1 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
3 Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License as
12 published by the Free Software Foundation; either version 2, or (at
13 your option) any later version.
15 This program is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
35 #include "mm/memory.h"
37 #include "native/native.h"
39 #include "threads/lock-common.h"
41 #include "toolbox/logging.h"
43 #include "vm/builtin.h"
44 #include "vm/exceptions.h"
45 #include "vm/global.h"
46 #include "vm/stringlocal.h"
48 #include "vm/jit/asmpart.h"
49 #include "vm/jit/jit.h"
50 #include "vm/jit/parse.h"
51 #include "vm/jit/loop/loop.h"
53 #include "vmcore/linker.h"
54 #include "vmcore/loader.h"
55 #include "vmcore/options.h"
56 #include "vm/resolve.h"
58 #if defined(ENABLE_STATISTICS)
59 # include "vmcore/statistics.h"
62 #include "vmcore/suck.h"
64 #define INSTRUCTIONS_INCREMENT 5 /* number of additional instructions to */
65 /* allocate if space runs out */
68 /* local macros ***************************************************************/
70 #define BYTECODEINDEX_TO_BASICBLOCK(dst) \
73 parse_bytecodeindex_to_basicblock(jd, &pd, (dst).insindex); \
77 /* parserdata_t ***************************************************************/
79 typedef struct parsedata_t parsedata_t;
82 u1 *bytecodestart; /* start of bytecode instructions */
83 u1 *basicblockstart; /* start of bytecode basic-blocks */
85 s4 *bytecodemap; /* bytecode to IR mapping */
87 instruction *instructions; /* instruction array */
88 s4 instructionslength; /* length of the instruction array */
90 s4 *instructionmap; /* IR to basic-block mapping */
94 /* parse_setup *****************************************************************
96 Fills the passed parsedata_t structure.
98 *******************************************************************************/
100 static void parse_setup(jitdata *jd, parsedata_t *pd)
104 /* get required compiler data */
108 /* bytecode start array */
110 pd->bytecodestart = DMNEW(u1, m->jcodelength + 1);
111 MZERO(pd->bytecodestart, u1, m->jcodelength + 1);
113 /* bytecode basic-block start array */
115 pd->basicblockstart = DMNEW(u1, m->jcodelength + 1);
116 MZERO(pd->basicblockstart, u1, m->jcodelength + 1);
118 /* bytecode instruction index to IR instruction mapping */
120 pd->bytecodemap = DMNEW(s4, m->jcodelength + 1);
121 MSET(pd->bytecodemap, -1, s4, m->jcodelength + 1);
123 /* allocate the instruction array */
125 pd->instructionslength = m->jcodelength + 1;
126 pd->instructions = DMNEW(instruction, pd->instructionslength);
128 /* Zero the intermediate instructions array so we don't have any
129 invalid pointers in it if we cannot finish stack_analyse(). */
131 MZERO(pd->instructions, instruction, pd->instructionslength);
133 /* The instructionmap is allocated later when we know the count of
136 pd->instructionmap = NULL;
140 /* parse_realloc_instructions **************************************************
142 Reallocate the instructions array so there is room for at least N
143 additional instructions.
146 the new value for iptr
148 *******************************************************************************/
150 static instruction *parse_realloc_instructions(parsedata_t *pd, s4 icount, s4 n)
152 /* increase the size of the instruction array */
154 pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
156 /* reallocate the array */
158 pd->instructions = DMREALLOC(pd->instructions, instruction, icount,
159 pd->instructionslength);
160 MZERO(pd->instructions + icount, instruction,
161 (pd->instructionslength - icount));
163 /* return the iptr */
165 return pd->instructions + icount;
169 /* parse_bytecodeindex_to_basicblock *******************************************
171 Resolves a bytecode index to the corresponding basic block.
173 *******************************************************************************/
175 static basicblock *parse_bytecodeindex_to_basicblock(jitdata *jd,
182 irindex = pd->bytecodemap[bcindex];
183 bb = jd->basicblocks + pd->instructionmap[irindex];
189 /* parse_mark_exception_boundaries *********************************************
191 Mark exception handlers and the boundaries of the handled regions as
192 basic block boundaries.
195 jd...............current jitdata
198 true.............everything ok
199 false............an exception has been thrown
201 *******************************************************************************/
203 static bool parse_mark_exception_boundaries(jitdata *jd, parsedata_t *pd)
208 raw_exception_entry *rex;
213 len = m->rawexceptiontablelength;
218 rex = m->rawexceptiontable;
220 for (i = 0; i < len; ++i, ++rex) {
222 /* the start of the handled region becomes a basic block start */
224 bcindex = rex->startpc;
225 CHECK_BYTECODE_INDEX(bcindex);
226 MARK_BASICBLOCK(pd, bcindex);
228 bcindex = rex->endpc; /* see JVM Spec 4.7.3 */
229 CHECK_BYTECODE_INDEX_EXCLUSIVE(bcindex);
231 /* check that the range is valid */
233 #if defined(ENABLE_VERIFIER)
234 if (bcindex <= rex->startpc) {
235 exceptions_throw_verifyerror(m, "Invalid exception handler range");
240 /* End of handled region becomes a basic block boundary (if it
241 is the bytecode end, we'll use the special end block that
242 is created anyway). */
244 if (bcindex < m->jcodelength)
245 MARK_BASICBLOCK(pd, bcindex);
247 jd->branchtoend = true;
249 /* the start of the handler becomes a basic block start */
251 bcindex = rex->handlerpc;
252 CHECK_BYTECODE_INDEX(bcindex);
253 MARK_BASICBLOCK(pd, bcindex);
260 #if defined(ENABLE_VERIFIER)
261 throw_invalid_bytecode_index:
262 exceptions_throw_verifyerror(m,
263 "Illegal bytecode index in exception table");
269 /* parse_resolve_exception_table ***********************************************
271 Enter the exception handlers and their ranges, resolved to basicblock *s,
275 jd...............current jitdata
278 true.............everything ok
279 false............an exception has been thrown
281 *******************************************************************************/
283 static bool parse_resolve_exception_table(jitdata *jd, parsedata_t *pd)
286 raw_exception_entry *rex;
294 len = m->rawexceptiontablelength;
296 /* common case: no handler entries */
301 /* allocate the exception table */
303 jd->exceptiontablelength = len;
304 jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
306 /* copy and resolve the entries */
308 ex = jd->exceptiontable;
309 rex = m->rawexceptiontable;
311 for (i = 0; i < len; ++i, ++rex, ++ex) {
312 /* resolve instruction indices to basic blocks */
314 ex->start = parse_bytecodeindex_to_basicblock(jd, pd, rex->startpc);
315 ex->end = parse_bytecodeindex_to_basicblock(jd, pd, rex->endpc);
316 ex->handler = parse_bytecodeindex_to_basicblock(jd, pd, rex->handlerpc);
318 /* lazily resolve the catchtype */
320 if (rex->catchtype.any != NULL) {
321 if (!resolve_classref_or_classinfo(m,
323 resolveLazy, true, false,
327 /* if resolved, enter the result of resolution in the table */
330 rex->catchtype.cls = exclass;
333 ex->catchtype = rex->catchtype;
334 ex->next = NULL; /* set by loop analysis */
335 ex->down = ex + 1; /* link to next exception entry */
338 /* terminate the ->down linked list */
340 assert(ex != jd->exceptiontable);
347 /*******************************************************************************
349 function 'parse' scans the JavaVM code and generates intermediate code
351 During parsing the block index table is used to store at bit pos 0
352 a flag which marks basic block starts and at position 1 to 31 the
353 intermediate instruction index. After parsing the block index table
354 is scanned, for marked positions a block is generated and the block
355 number is stored in the block index table.
357 *******************************************************************************/
359 /*** macro for checking the length of the bytecode ***/
361 #if defined(ENABLE_VERIFIER)
362 #define CHECK_END_OF_BYTECODE(neededlength) \
364 if ((neededlength) > m->jcodelength) \
365 goto throw_unexpected_end_of_bytecode; \
367 #else /* !ENABLE_VERIFIER */
368 #define CHECK_END_OF_BYTECODE(neededlength)
369 #endif /* ENABLE_VERIFIER */
371 bool parse(jitdata *jd)
373 methodinfo *m; /* method being parsed */
375 instruction *iptr; /* current ptr into instruction array */
377 s4 bcindex; /* bytecode instruction index */
378 s4 nextbc; /* start of next bytecode instruction */
379 s4 opcode; /* bytecode instruction opcode */
381 s4 irindex; /* IR instruction index */
382 s4 ircount; /* IR instruction count */
384 s4 bbcount; /* basic block count */
386 int s_count = 0; /* stack element counter */
387 bool blockend; /* true if basic block end has been reached */
388 bool iswide; /* true if last instruction was a wide */
390 constant_classref *cr;
391 constant_classref *compr;
393 builtintable_entry *bte;
394 constant_FMIref *fmi;
396 unresolved_method *um;
397 unresolved_field *uf;
399 resolve_result_t result;
406 int *local_map; /* local pointer to renaming map */
407 /* is assigned to rd->local_map at the end */
408 branch_target_t *table;
409 lookup_target_t *lookup;
413 /* get required compiler data */
417 /* allocate buffers for local variable renaming */
419 local_map = DMNEW(int, m->maxlocals * 5);
421 for (i = 0; i < m->maxlocals; i++) {
422 local_map[i * 5 + 0] = 0;
423 local_map[i * 5 + 1] = 0;
424 local_map[i * 5 + 2] = 0;
425 local_map[i * 5 + 3] = 0;
426 local_map[i * 5 + 4] = 0;
429 /* initialize the parse data structures */
431 parse_setup(jd, &pd);
433 /* initialize local variables */
435 iptr = pd.instructions;
441 /* mark basic block boundaries for exception table */
443 if (!parse_mark_exception_boundaries(jd, &pd))
446 /* initialize stack element counter */
448 s_count = 1 + m->rawexceptiontablelength;
450 /* setup line number info */
455 if (m->linenumbercount == 0) {
459 linepcchange = m->linenumbers[0].start_pc;
462 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
464 for (bcindex = 0; bcindex < m->jcodelength; bcindex = nextbc) {
466 /* mark this position as a valid bytecode instruction start */
468 pd.bytecodestart[bcindex] = 1;
470 /* change the current line number, if necessary */
472 /* XXX rewrite this using pointer arithmetic */
474 if (linepcchange == bcindex) {
475 if (m->linenumbercount > lineindex) {
477 currentline = m->linenumbers[lineindex].line_number;
479 if (lineindex < m->linenumbercount) {
480 linepcchange = m->linenumbers[lineindex].start_pc;
481 if (linepcchange == bcindex)
482 goto next_linenumber;
488 /* fetch next opcode */
490 opcode = SUCK_BE_U1(m->jcode + bcindex);
492 /* If the previous instruction was a block-end instruction,
493 mark the current bytecode instruction as basic-block
494 starting instruction. */
496 /* NOTE: Some compilers put a JAVA_NOP after a blockend
499 if (blockend && (opcode != JAVA_NOP)) {
500 MARK_BASICBLOCK(&pd, bcindex);
504 /* If the current bytecode instruction was marked as
505 basic-block starting instruction before (e.g. blockend,
506 forward-branch target), mark the current IR instruction
509 if (pd.basicblockstart[bcindex] != 0) {
510 /* We need a NOP as last instruction in each basic block
511 for basic block reordering (may be replaced with a GOTO
514 INSTRUCTIONS_CHECK(1);
518 /* store intermediate instruction count (bit 0 mark block starts) */
520 pd.bytecodemap[bcindex] = ircount;
522 /* compute next instruction start */
524 nextbc = bcindex + jcommandsize[opcode];
526 CHECK_END_OF_BYTECODE(nextbc);
528 /* add stack elements produced by this instruction */
530 s_count += stackreq[opcode];
532 /* We check here for the space of 1 instruction in the
533 instruction array. If an opcode is converted to more than
534 1 instruction, this is checked in the corresponding
537 INSTRUCTIONS_CHECK(1);
539 /* translate this bytecode instruction */
545 /* pushing constants onto the stack ***********************************/
548 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + bcindex + 1));
552 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + bcindex + 1));
556 i = SUCK_BE_U1(m->jcode + bcindex + 1);
557 goto pushconstantitem;
561 i = SUCK_BE_U2(m->jcode + bcindex + 1);
565 #if defined(ENABLE_VERIFIER)
566 if (i >= m->class->cpcount) {
567 exceptions_throw_verifyerror(m,
568 "Attempt to access constant outside range");
573 switch (m->class->cptags[i]) {
574 case CONSTANT_Integer:
575 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
578 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
581 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
583 case CONSTANT_Double:
584 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
586 case CONSTANT_String:
587 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
590 cr = (constant_classref *) (m->class->cpinfos[i]);
592 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
595 /* if not resolved, c == NULL */
597 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
601 #if defined(ENABLE_VERIFIER)
603 exceptions_throw_verifyerror(m,
604 "Invalid constant type to push");
610 case JAVA_ACONST_NULL:
621 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
626 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
632 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
637 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
640 /* stack operations ***************************************************/
642 /* We need space for additional ICMDs so we can translate these */
643 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
646 INSTRUCTIONS_CHECK(4);
654 INSTRUCTIONS_CHECK(6);
664 INSTRUCTIONS_CHECK(2);
670 INSTRUCTIONS_CHECK(7);
681 INSTRUCTIONS_CHECK(9);
694 INSTRUCTIONS_CHECK(3);
700 /* local variable access instructions *********************************/
705 if (iswide == false) {
706 i = SUCK_BE_U1(m->jcode + bcindex + 1);
709 i = SUCK_BE_U2(m->jcode + bcindex + 1);
710 nextbc = bcindex + 3;
713 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
718 if (iswide == false) {
719 i = SUCK_BE_U1(m->jcode + bcindex + 1);
722 i = SUCK_BE_U2(m->jcode + bcindex + 1);
723 nextbc = bcindex + 3;
726 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
733 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
740 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
747 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
754 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
761 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
767 if (iswide == false) {
768 i = SUCK_BE_U1(m->jcode + bcindex + 1);
771 i = SUCK_BE_U2(m->jcode + bcindex + 1);
772 nextbc = bcindex + 3;
775 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
780 if (iswide == false) {
781 i = SUCK_BE_U1(m->jcode + bcindex + 1);
784 i = SUCK_BE_U2(m->jcode + bcindex + 1);
785 nextbc = bcindex + 3;
788 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
795 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
802 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
809 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
816 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
823 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
830 if (iswide == false) {
831 i = SUCK_BE_U1(m->jcode + bcindex + 1);
832 v = SUCK_BE_S1(m->jcode + bcindex + 2);
836 i = SUCK_BE_U2(m->jcode + bcindex + 1);
837 v = SUCK_BE_S2(m->jcode + bcindex + 3);
838 nextbc = bcindex + 5;
842 LOCALTYPE_USED(i, TYPE_INT);
843 OP_LOCALINDEX_I(opcode, i, v);
847 /* wider index for loading, storing and incrementing ******************/
854 /* managing arrays ****************************************************/
857 switch (SUCK_BE_S1(m->jcode + bcindex + 1)) {
859 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
862 bte = builtintable_get_internal(BUILTIN_newarray_char);
865 bte = builtintable_get_internal(BUILTIN_newarray_float);
868 bte = builtintable_get_internal(BUILTIN_newarray_double);
871 bte = builtintable_get_internal(BUILTIN_newarray_byte);
874 bte = builtintable_get_internal(BUILTIN_newarray_short);
877 bte = builtintable_get_internal(BUILTIN_newarray_int);
880 bte = builtintable_get_internal(BUILTIN_newarray_long);
882 #if defined(ENABLE_VERIFIER)
884 exceptions_throw_verifyerror(m, "Invalid array-type to create");
888 OP_BUILTIN_CHECK_EXCEPTION(bte);
892 i = SUCK_BE_U2(m->jcode + bcindex + 1);
893 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
897 if (!(cr = class_get_classref_multiarray_of(1, compr)))
900 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
903 INSTRUCTIONS_CHECK(2);
904 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
905 bte = builtintable_get_internal(BUILTIN_newarray);
906 OP_BUILTIN_CHECK_EXCEPTION(bte);
910 case JAVA_MULTIANEWARRAY:
911 jd->isleafmethod = false;
912 i = SUCK_BE_U2(m->jcode + bcindex + 1);
913 j = SUCK_BE_U1(m->jcode + bcindex + 3);
915 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
919 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
922 /* if unresolved, c == NULL */
924 iptr->s1.argcount = j;
925 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, INS_FLAG_CHECK);
928 /* control flow instructions ******************************************/
947 i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
948 CHECK_BYTECODE_INDEX(i);
949 MARK_BASICBLOCK(&pd, i);
951 OP_INSINDEX(opcode, i);
955 i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
956 CHECK_BYTECODE_INDEX(i);
957 MARK_BASICBLOCK(&pd, i);
959 OP_INSINDEX(ICMD_GOTO, i);
963 i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
965 CHECK_BYTECODE_INDEX(i);
966 MARK_BASICBLOCK(&pd, i);
968 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
969 iptr->sx.s23.s3.jsrtarget.insindex = i;
974 i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
978 if (iswide == false) {
979 i = SUCK_BE_U1(m->jcode + bcindex + 1);
982 i = SUCK_BE_U2(m->jcode + bcindex + 1);
983 nextbc = bcindex + 3;
988 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
998 /* XXX ARETURN will need a flag in the typechecker */
1004 /* XXX ATHROW will need a flag in the typechecker */
1009 /* table jumps ********************************************************/
1011 case JAVA_LOOKUPSWITCH:
1014 lookup_target_t *lookup;
1015 #if defined(ENABLE_VERIFIER)
1019 nextbc = MEMORY_ALIGN((bcindex + 1), 4);
1021 CHECK_END_OF_BYTECODE(nextbc + 8);
1023 OP_PREPARE_ZEROFLAGS(opcode);
1025 /* default target */
1027 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1028 iptr->sx.s23.s3.lookupdefault.insindex = j;
1030 CHECK_BYTECODE_INDEX(j);
1031 MARK_BASICBLOCK(&pd, j);
1033 /* number of pairs */
1035 num = SUCK_BE_U4(m->jcode + nextbc);
1036 iptr->sx.s23.s2.lookupcount = num;
1039 /* allocate the intermediate code table */
1041 lookup = DMNEW(lookup_target_t, num);
1042 iptr->dst.lookup = lookup;
1044 /* iterate over the lookup table */
1046 CHECK_END_OF_BYTECODE(nextbc + 8 * num);
1048 for (i = 0; i < num; i++) {
1051 j = SUCK_BE_S4(m->jcode + nextbc);
1056 #if defined(ENABLE_VERIFIER)
1057 /* check if the lookup table is sorted correctly */
1059 if (i && (j <= prevvalue)) {
1060 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
1067 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1068 lookup->target.insindex = j;
1071 CHECK_BYTECODE_INDEX(j);
1072 MARK_BASICBLOCK(&pd, j);
1080 case JAVA_TABLESWITCH:
1084 branch_target_t *table;
1087 nextbc = MEMORY_ALIGN((bcindex + 1), 4);
1089 CHECK_END_OF_BYTECODE(nextbc + 12);
1091 OP_PREPARE_ZEROFLAGS(opcode);
1093 /* default target */
1095 deftarget = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1097 CHECK_BYTECODE_INDEX(deftarget);
1098 MARK_BASICBLOCK(&pd, deftarget);
1102 j = SUCK_BE_S4(m->jcode + nextbc);
1103 iptr->sx.s23.s2.tablelow = j;
1108 num = SUCK_BE_S4(m->jcode + nextbc);
1109 iptr->sx.s23.s3.tablehigh = num;
1112 /* calculate the number of table entries */
1116 #if defined(ENABLE_VERIFIER)
1118 exceptions_throw_verifyerror(m,
1119 "invalid TABLESWITCH: upper bound < lower bound");
1123 /* create the intermediate code table */
1124 /* the first entry is the default target */
1126 table = DMNEW(branch_target_t, 1 + num);
1127 iptr->dst.table = table;
1128 (table++)->insindex = deftarget;
1130 /* iterate over the target table */
1132 CHECK_END_OF_BYTECODE(nextbc + 4 * num);
1134 for (i = 0; i < num; i++) {
1135 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1136 (table++)->insindex = j;
1138 CHECK_BYTECODE_INDEX(j);
1139 MARK_BASICBLOCK(&pd, j);
1147 /* load and store of object fields ************************************/
1151 jd->isleafmethod = false;
1154 case JAVA_GETSTATIC:
1155 case JAVA_PUTSTATIC:
1158 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1159 fmi = class_getconstant(m->class, i, CONSTANT_Fieldref);
1164 OP_PREPARE_ZEROFLAGS(opcode);
1165 iptr->sx.s23.s3.fmiref = fmi;
1167 /* only with -noverify, otherwise the typechecker does this */
1169 #if defined(ENABLE_VERIFIER)
1170 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1172 result = resolve_field_lazy(m, fmi);
1174 if (result == resolveFailed)
1177 if (result != resolveSucceeded) {
1178 uf = resolve_create_unresolved_field(m->class, m, iptr);
1183 /* store the unresolved_field pointer */
1185 iptr->sx.s23.s3.uf = uf;
1186 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1188 #if defined(ENABLE_VERIFIER)
1195 /* method invocation **************************************************/
1197 case JAVA_INVOKESTATIC:
1198 OP_PREPARE_ZEROFLAGS(opcode);
1200 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1201 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1206 md = fmi->parseddesc.md;
1208 if (md->params == NULL)
1209 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1214 case JAVA_INVOKESPECIAL:
1215 OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
1217 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1218 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1220 goto invoke_nonstatic_method;
1222 case JAVA_INVOKEINTERFACE:
1223 OP_PREPARE_ZEROFLAGS(opcode);
1225 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1226 fmi = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1228 goto invoke_nonstatic_method;
1230 case JAVA_INVOKEVIRTUAL:
1231 OP_PREPARE_ZEROFLAGS(opcode);
1233 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1234 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1236 invoke_nonstatic_method:
1240 md = fmi->parseddesc.md;
1242 if (md->params == NULL)
1243 if (!descriptor_params_from_paramtypes(md, 0))
1247 jd->isleafmethod = false;
1249 iptr->sx.s23.s3.fmiref = fmi;
1251 /* only with -noverify, otherwise the typechecker does this */
1253 #if defined(ENABLE_VERIFIER)
1254 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1256 result = resolve_method_lazy(m, fmi,
1257 (opcode == JAVA_INVOKESPECIAL));
1259 if (result == resolveFailed)
1262 if (result == resolveSucceeded) {
1263 methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1265 /* if this call is monomorphic, turn it into an
1268 assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1270 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1271 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1273 iptr->opc = ICMD_INVOKESPECIAL;
1274 iptr->flags.bits |= INS_FLAG_CHECK;
1278 um = resolve_create_unresolved_method(m->class, m, fmi,
1279 (opcode == JAVA_INVOKESTATIC),
1280 (opcode == JAVA_INVOKESPECIAL));
1285 /* store the unresolved_method pointer */
1287 iptr->sx.s23.s3.um = um;
1288 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1290 #if defined(ENABLE_VERIFIER)
1296 /* instructions taking class arguments ********************************/
1299 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1300 cr = class_getconstant(m->class, i, CONSTANT_Class);
1305 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1308 INSTRUCTIONS_CHECK(2);
1309 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1310 bte = builtintable_get_internal(BUILTIN_new);
1311 OP_BUILTIN_CHECK_EXCEPTION(bte);
1315 case JAVA_CHECKCAST:
1316 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1317 cr = class_getconstant(m->class, i, CONSTANT_Class);
1322 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1325 if (cr->name->text[0] == '[') {
1326 /* array type cast-check */
1327 flags = INS_FLAG_CHECK | INS_FLAG_ARRAY;
1328 jd->isleafmethod = false;
1331 /* object type cast-check */
1332 flags = INS_FLAG_CHECK;
1334 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1337 case JAVA_INSTANCEOF:
1338 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1339 cr = class_getconstant(m->class, i, CONSTANT_Class);
1344 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1347 if (cr->name->text[0] == '[') {
1348 /* array type cast-check */
1349 INSTRUCTIONS_CHECK(2);
1350 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1351 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1352 OP_BUILTIN_NO_EXCEPTION(bte);
1356 /* object type cast-check */
1357 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1361 /* synchronization instructions ***************************************/
1363 case JAVA_MONITORENTER:
1364 #if defined(ENABLE_THREADS)
1366 bte = builtintable_get_internal(LOCK_monitor_enter);
1367 OP_BUILTIN_CHECK_EXCEPTION(bte);
1372 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1377 case JAVA_MONITOREXIT:
1378 #if defined(ENABLE_THREADS)
1380 bte = builtintable_get_internal(LOCK_monitor_exit);
1381 OP_BUILTIN_CHECK_EXCEPTION(bte);
1386 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1391 /* arithmetic instructions that may become builtin functions **********/
1394 #if !SUPPORT_DIVISION
1395 bte = builtintable_get_internal(BUILTIN_idiv);
1396 OP_BUILTIN_ARITHMETIC(opcode, bte);
1398 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1401 OP_CHECK_EXCEPTION(opcode);
1407 #if !SUPPORT_DIVISION
1408 bte = builtintable_get_internal(BUILTIN_irem);
1409 OP_BUILTIN_ARITHMETIC(opcode, bte);
1411 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1414 OP_CHECK_EXCEPTION(opcode);
1420 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1421 bte = builtintable_get_internal(BUILTIN_ldiv);
1422 OP_BUILTIN_ARITHMETIC(opcode, bte);
1424 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1427 OP_CHECK_EXCEPTION(opcode);
1433 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1434 bte = builtintable_get_internal(BUILTIN_lrem);
1435 OP_BUILTIN_ARITHMETIC(opcode, bte);
1437 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1440 OP_CHECK_EXCEPTION(opcode);
1446 #if defined(__I386__)
1449 bte = builtintable_get_internal(BUILTIN_frem);
1450 OP_BUILTIN_NO_EXCEPTION(bte);
1455 #if defined(__I386__)
1458 bte = builtintable_get_internal(BUILTIN_drem);
1459 OP_BUILTIN_NO_EXCEPTION(bte);
1464 #if defined(__ALPHA__)
1466 bte = builtintable_get_internal(BUILTIN_f2i);
1467 OP_BUILTIN_NO_EXCEPTION(bte);
1477 #if defined(__ALPHA__)
1479 bte = builtintable_get_internal(BUILTIN_f2l);
1480 OP_BUILTIN_NO_EXCEPTION(bte);
1490 #if defined(__ALPHA__)
1492 bte = builtintable_get_internal(BUILTIN_d2i);
1493 OP_BUILTIN_NO_EXCEPTION(bte);
1503 #if defined(__ALPHA__)
1505 bte = builtintable_get_internal(BUILTIN_d2l);
1506 OP_BUILTIN_NO_EXCEPTION(bte);
1515 /* invalid opcodes ****************************************************/
1517 /* check for invalid opcodes if the verifier is enabled */
1518 #if defined(ENABLE_VERIFIER)
1519 case JAVA_BREAKPOINT:
1520 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1523 case 186: /* unused opcode */
1577 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1581 #endif /* defined(ENABLE_VERIFIER) */
1583 /* opcodes that don't require translation *****************************/
1586 /* straight-forward translation to ICMD */
1592 /* verifier checks ****************************************************/
1594 #if defined(ENABLE_VERIFIER)
1595 /* If WIDE was used correctly, iswide should have been reset by now. */
1597 exceptions_throw_verifyerror(m,
1598 "Illegal instruction: WIDE before incompatible opcode");
1601 #endif /* defined(ENABLE_VERIFIER) */
1605 if (JITDATA_HAS_FLAG_REORDER(jd)) {
1606 /* add a NOP to the last basic block */
1608 INSTRUCTIONS_CHECK(1);
1612 /*** END OF LOOP **********************************************************/
1614 /* assert that we did not write more ICMDs than allocated */
1616 assert(ircount <= pd.instructionslength);
1617 assert(ircount == (iptr - pd.instructions));
1619 /*** verifier checks ******************************************************/
1621 #if defined(ENABLE_VERIFIER)
1622 if (bcindex != m->jcodelength) {
1623 exceptions_throw_verifyerror(m,
1624 "Command-sequence crosses code-boundary");
1629 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1632 #endif /* defined(ENABLE_VERIFIER) */
1634 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1636 /* identify basic blocks */
1638 /* check if first instruction is a branch target */
1640 if (pd.basicblockstart[0] == 1) {
1641 jd->branchtoentry = true;
1644 /* first instruction always starts a basic block */
1646 iptr = pd.instructions;
1648 iptr->flags.bits |= INS_FLAG_BASICBLOCK;
1651 /* Iterate over all bytecode instructions and set missing
1652 basic-block starts in IR instructions. */
1654 for (bcindex = 0; bcindex < m->jcodelength; bcindex++) {
1655 /* Does the current bytecode instruction start a basic
1658 if (pd.basicblockstart[bcindex] == 1) {
1659 #if defined(ENABLE_VERIFIER)
1660 /* Check if this bytecode basic-block start at the
1661 beginning of a bytecode instruction. */
1663 if (pd.bytecodestart[bcindex] == 0) {
1664 exceptions_throw_verifyerror(m,
1665 "Branch into middle of instruction");
1670 /* Get the IR instruction mapped to the bytecode
1671 instruction and set the basic block flag. */
1673 irindex = pd.bytecodemap[bcindex];
1674 iptr = pd.instructions + irindex;
1676 iptr->flags.bits |= INS_FLAG_BASICBLOCK;
1680 /* IR instruction index to basic-block index mapping */
1682 pd.instructionmap = DMNEW(s4, ircount);
1683 MZERO(pd.instructionmap, s4, ircount);
1685 /* Iterate over all IR instructions and count the basic blocks. */
1687 iptr = pd.instructions;
1691 for (i = 0; i < ircount; i++, iptr++) {
1692 if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
1693 /* store the basic-block number in the IR instruction
1696 pd.instructionmap[i] = bbcount;
1698 /* post-increment the basic-block count */
1704 /* Allocate basic block array (one more for end ipc). */
1706 jd->basicblocks = DMNEW(basicblock, bbcount + 1);
1707 MZERO(jd->basicblocks, basicblock, bbcount + 1);
1709 /* Now iterate again over all IR instructions and initialize the
1710 basic block structures and, in the same loop, resolve the
1711 branch-target instruction indices to basic blocks. */
1713 iptr = pd.instructions;
1714 bptr = jd->basicblocks;
1718 for (i = 0; i < ircount; i++, iptr++) {
1719 /* check for basic block */
1721 if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
1722 /* intialize the basic block */
1724 BASICBLOCK_INIT(bptr, m);
1726 bptr->iinstr = iptr;
1729 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1732 /* bptr->icount is set when the next block is allocated */
1734 bptr->nr = bbcount++;
1736 bptr[-1].next = bptr;
1739 /* resolve instruction indices to basic blocks */
1741 switch (iptr->opc) {
1749 case JAVA_IFNONNULL:
1750 case JAVA_IF_ICMPEQ:
1751 case JAVA_IF_ICMPNE:
1752 case JAVA_IF_ICMPLT:
1753 case JAVA_IF_ICMPGT:
1754 case JAVA_IF_ICMPLE:
1755 case JAVA_IF_ICMPGE:
1756 case JAVA_IF_ACMPEQ:
1757 case JAVA_IF_ACMPNE:
1759 BYTECODEINDEX_TO_BASICBLOCK(iptr->dst);
1763 BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.jsrtarget);
1766 case ICMD_TABLESWITCH:
1767 table = iptr->dst.table;
1769 BYTECODEINDEX_TO_BASICBLOCK(*table);
1772 j = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
1775 BYTECODEINDEX_TO_BASICBLOCK(*table);
1780 case ICMD_LOOKUPSWITCH:
1781 BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.lookupdefault);
1783 lookup = iptr->dst.lookup;
1785 j = iptr->sx.s23.s2.lookupcount;
1788 BYTECODEINDEX_TO_BASICBLOCK(lookup->target);
1795 /* set instruction count of last real block */
1798 bptr[-1].icount = (pd.instructions + ircount) - bptr[-1].iinstr;
1801 /* allocate additional block at end */
1803 BASICBLOCK_INIT(bptr, m);
1806 /* set basicblock pointers in exception table */
1808 if (!parse_resolve_exception_table(jd, &pd))
1811 /* store the local map */
1813 jd->local_map = local_map;
1815 /* calculate local variable renaming */
1824 /* iterate over local_map[0..m->maxlocals*5-1] and allocate a unique */
1825 /* variable index for each _used_ (javaindex,type) pair. */
1826 /* (local_map[javaindex*5+type] = cacaoindex) */
1827 /* Unused (javaindex,type) pairs are marked with UNUSED. */
1829 for (i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
1831 *mapptr = nlocals++;
1836 jd->localcount = nlocals;
1838 /* calculate the (maximum) number of variables needed */
1841 nlocals /* local variables */
1842 + bbcount * m->maxstack /* invars */
1843 + s_count; /* variables created within blocks (non-invar) */
1845 /* reserve the first indices for local variables */
1847 jd->vartop = nlocals;
1849 /* reserve extra variables needed by stack analyse */
1851 jd->varcount += STACK_EXTRA_VARS;
1852 jd->vartop += STACK_EXTRA_VARS;
1854 /* The verifier needs space for saving invars in some cases and */
1855 /* extra variables. */
1857 #if defined(ENABLE_VERIFIER)
1858 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1859 jd->vartop += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1861 /* allocate and initialize the variable array */
1863 jd->var = DMNEW(varinfo, jd->varcount);
1864 MZERO(jd->var, varinfo, jd->varcount);
1866 /* set types of all locals in jd->var */
1868 for (mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
1869 if (*mapptr != UNUSED)
1870 VAR(*mapptr)->type = i%5;
1873 /* assign local variables to method variables */
1875 jd->instructions = pd.instructions;
1876 jd->instructioncount = ircount;
1877 jd->basicblockcount = bbcount;
1878 jd->stackcount = s_count + bbcount * m->maxstack; /* in-stacks */
1880 /* allocate stack table */
1882 jd->stack = DMNEW(stackelement, jd->stackcount);
1884 /* everything's ok */
1888 /*** goto labels for throwing verifier exceptions *************************/
1890 #if defined(ENABLE_VERIFIER)
1892 throw_unexpected_end_of_bytecode:
1893 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1896 throw_invalid_bytecode_index:
1897 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1900 throw_illegal_local_variable_number:
1901 exceptions_throw_verifyerror(m, "Illegal local variable number");
1904 #endif /* ENABLE_VERIFIER */
1909 * These are local overrides for various environment variables in Emacs.
1910 * Please do not remove this and leave it at the end of the file, where
1911 * Emacs will automagically detect them.
1912 * ---------------------------------------------------------------------
1915 * indent-tabs-mode: t
1919 * vim:noexpandtab:sw=4:ts=4: