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
25 $Id: parse.c 7766 2007-04-19 13:24:48Z michi $
37 #include "mm/memory.h"
38 #include "native/native.h"
40 #if defined(ENABLE_THREADS)
41 # include "threads/native/lock.h"
44 #include "toolbox/logging.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49 #include "vm/stringlocal.h"
51 #include "vm/jit/asmpart.h"
52 #include "vm/jit/jit.h"
53 #include "vm/jit/parse.h"
54 #include "vm/jit/patcher.h"
55 #include "vm/jit/loop/loop.h"
57 #include "vmcore/linker.h"
58 #include "vmcore/loader.h"
59 #include "vmcore/options.h"
60 #include "vm/resolve.h"
62 #if defined(ENABLE_STATISTICS)
63 # include "vmcore/statistics.h"
66 #include "vmcore/suck.h"
68 #define INSTRUCTIONS_INCREMENT 5 /* number of additional instructions to */
69 /* allocate if space runs out */
72 /* local macros ***************************************************************/
74 #define BYTECODEINDEX_TO_BASICBLOCK(dst) \
77 parse_bytecodeindex_to_basicblock(jd, &pd, (dst).insindex); \
81 /* parserdata_t ***************************************************************/
83 typedef struct parsedata_t parsedata_t;
86 u1 *bytecodestart; /* start of bytecode instructions */
87 u1 *basicblockstart; /* start of bytecode basic-blocks */
89 s4 *bytecodemap; /* bytecode to IR mapping */
91 instruction *instructions; /* instruction array */
92 s4 instructionslength; /* length of the instruction array */
94 s4 *instructionmap; /* IR to basic-block mapping */
98 /* parse_setup *****************************************************************
100 Fills the passed parsedata_t structure.
102 *******************************************************************************/
104 static void parse_setup(jitdata *jd, parsedata_t *pd)
108 /* get required compiler data */
112 /* bytecode start array */
114 pd->bytecodestart = DMNEW(u1, m->jcodelength + 1);
115 MZERO(pd->bytecodestart, u1, m->jcodelength + 1);
117 /* bytecode basic-block start array */
119 pd->basicblockstart = DMNEW(u1, m->jcodelength + 1);
120 MZERO(pd->basicblockstart, u1, m->jcodelength + 1);
122 /* bytecode instruction index to IR instruction mapping */
124 pd->bytecodemap = DMNEW(s4, m->jcodelength + 1);
125 MSET(pd->bytecodemap, -1, s4, m->jcodelength + 1);
127 /* allocate the instruction array */
129 pd->instructionslength = m->jcodelength + 1;
130 pd->instructions = DMNEW(instruction, pd->instructionslength);
132 /* Zero the intermediate instructions array so we don't have any
133 invalid pointers in it if we cannot finish stack_analyse(). */
135 MZERO(pd->instructions, instruction, pd->instructionslength);
137 /* The instructionmap is allocated later when we know the count of
140 pd->instructionmap = NULL;
144 /* parse_realloc_instructions **************************************************
146 Reallocate the instructions array so there is room for at least N
147 additional instructions.
150 the new value for iptr
152 *******************************************************************************/
154 static instruction *parse_realloc_instructions(parsedata_t *pd, s4 icount, s4 n)
156 /* increase the size of the instruction array */
158 pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
160 /* reallocate the array */
162 pd->instructions = DMREALLOC(pd->instructions, instruction, icount,
163 pd->instructionslength);
164 MZERO(pd->instructions + icount, instruction,
165 (pd->instructionslength - icount));
167 /* return the iptr */
169 return pd->instructions + icount;
173 /* parse_bytecodeindex_to_basicblock *******************************************
175 Resolves a bytecode index to the corresponding basic block.
177 *******************************************************************************/
179 static basicblock *parse_bytecodeindex_to_basicblock(jitdata *jd,
186 irindex = pd->bytecodemap[bcindex];
187 bb = jd->basicblocks + pd->instructionmap[irindex];
193 /* parse_mark_exception_boundaries *********************************************
195 Mark exception handlers and the boundaries of the handled regions as
196 basic block boundaries.
199 jd...............current jitdata
202 true.............everything ok
203 false............an exception has been thrown
205 *******************************************************************************/
207 static bool parse_mark_exception_boundaries(jitdata *jd, parsedata_t *pd)
212 raw_exception_entry *rex;
217 len = m->rawexceptiontablelength;
222 rex = m->rawexceptiontable;
224 for (i = 0; i < len; ++i, ++rex) {
226 /* the start of the handled region becomes a basic block start */
228 bcindex = rex->startpc;
229 CHECK_BYTECODE_INDEX(bcindex);
230 MARK_BASICBLOCK(pd, bcindex);
232 bcindex = rex->endpc; /* see JVM Spec 4.7.3 */
233 CHECK_BYTECODE_INDEX_EXCLUSIVE(bcindex);
235 /* check that the range is valid */
237 #if defined(ENABLE_VERIFIER)
238 if (bcindex <= rex->startpc) {
239 exceptions_throw_verifyerror(m, "Invalid exception handler range");
244 /* End of handled region becomes a basic block boundary (if it
245 is the bytecode end, we'll use the special end block that
246 is created anyway). */
248 if (bcindex < m->jcodelength)
249 MARK_BASICBLOCK(pd, bcindex);
251 jd->branchtoend = true;
253 /* the start of the handler becomes a basic block start */
255 bcindex = rex->handlerpc;
256 CHECK_BYTECODE_INDEX(bcindex);
257 MARK_BASICBLOCK(pd, bcindex);
264 #if defined(ENABLE_VERIFIER)
265 throw_invalid_bytecode_index:
266 exceptions_throw_verifyerror(m,
267 "Illegal bytecode index in exception table");
273 /* parse_resolve_exception_table ***********************************************
275 Enter the exception handlers and their ranges, resolved to basicblock *s,
279 jd...............current jitdata
282 true.............everything ok
283 false............an exception has been thrown
285 *******************************************************************************/
287 static bool parse_resolve_exception_table(jitdata *jd, parsedata_t *pd)
290 raw_exception_entry *rex;
298 len = m->rawexceptiontablelength;
300 /* common case: no handler entries */
305 /* allocate the exception table */
307 jd->exceptiontablelength = len;
308 jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
310 /* copy and resolve the entries */
312 ex = jd->exceptiontable;
313 rex = m->rawexceptiontable;
315 for (i = 0; i < len; ++i, ++rex, ++ex) {
316 /* resolve instruction indices to basic blocks */
318 ex->start = parse_bytecodeindex_to_basicblock(jd, pd, rex->startpc);
319 ex->end = parse_bytecodeindex_to_basicblock(jd, pd, rex->endpc);
320 ex->handler = parse_bytecodeindex_to_basicblock(jd, pd, rex->handlerpc);
322 /* lazily resolve the catchtype */
324 if (rex->catchtype.any != NULL) {
325 if (!resolve_classref_or_classinfo(m,
327 resolveLazy, true, false,
331 /* if resolved, enter the result of resolution in the table */
334 rex->catchtype.cls = exclass;
337 ex->catchtype = rex->catchtype;
338 ex->next = NULL; /* set by loop analysis */
339 ex->down = ex + 1; /* link to next exception entry */
342 /* terminate the ->down linked list */
344 assert(ex != jd->exceptiontable);
351 /*******************************************************************************
353 function 'parse' scans the JavaVM code and generates intermediate code
355 During parsing the block index table is used to store at bit pos 0
356 a flag which marks basic block starts and at position 1 to 31 the
357 intermediate instruction index. After parsing the block index table
358 is scanned, for marked positions a block is generated and the block
359 number is stored in the block index table.
361 *******************************************************************************/
363 /*** macro for checking the length of the bytecode ***/
365 #if defined(ENABLE_VERIFIER)
366 #define CHECK_END_OF_BYTECODE(neededlength) \
368 if ((neededlength) > m->jcodelength) \
369 goto throw_unexpected_end_of_bytecode; \
371 #else /* !ENABLE_VERIFIER */
372 #define CHECK_END_OF_BYTECODE(neededlength)
373 #endif /* ENABLE_VERIFIER */
375 bool parse(jitdata *jd)
377 methodinfo *m; /* method being parsed */
379 instruction *iptr; /* current ptr into instruction array */
381 s4 bcindex; /* bytecode instruction index */
382 s4 nextbc; /* start of next bytecode instruction */
383 s4 opcode; /* bytecode instruction opcode */
385 s4 irindex; /* IR instruction index */
386 s4 ircount; /* IR instruction count */
388 s4 bbcount; /* basic block count */
390 int s_count = 0; /* stack element counter */
391 bool blockend; /* true if basic block end has been reached */
392 bool iswide; /* true if last instruction was a wide */
394 constant_classref *cr;
395 constant_classref *compr;
397 builtintable_entry *bte;
398 constant_FMIref *fmi;
400 unresolved_method *um;
401 unresolved_field *uf;
403 resolve_result_t result;
410 int *local_map; /* local pointer to renaming map */
411 /* is assigned to rd->local_map at the end */
412 branch_target_t *table;
413 lookup_target_t *lookup;
417 /* get required compiler data */
421 /* allocate buffers for local variable renaming */
423 local_map = DMNEW(int, m->maxlocals * 5);
425 for (i = 0; i < m->maxlocals; i++) {
426 local_map[i * 5 + 0] = 0;
427 local_map[i * 5 + 1] = 0;
428 local_map[i * 5 + 2] = 0;
429 local_map[i * 5 + 3] = 0;
430 local_map[i * 5 + 4] = 0;
433 /* initialize the parse data structures */
435 parse_setup(jd, &pd);
437 /* initialize local variables */
439 iptr = pd.instructions;
445 /* mark basic block boundaries for exception table */
447 if (!parse_mark_exception_boundaries(jd, &pd))
450 /* initialize stack element counter */
452 s_count = 1 + m->rawexceptiontablelength;
454 /* setup line number info */
459 if (m->linenumbercount == 0) {
463 linepcchange = m->linenumbers[0].start_pc;
466 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
468 for (bcindex = 0; bcindex < m->jcodelength; bcindex = nextbc) {
470 /* mark this position as a valid bytecode instruction start */
472 pd.bytecodestart[bcindex] = 1;
474 /* change the current line number, if necessary */
476 /* XXX rewrite this using pointer arithmetic */
478 if (linepcchange == bcindex) {
479 if (m->linenumbercount > lineindex) {
481 currentline = m->linenumbers[lineindex].line_number;
483 if (lineindex < m->linenumbercount) {
484 linepcchange = m->linenumbers[lineindex].start_pc;
485 if (linepcchange == bcindex)
486 goto next_linenumber;
492 /* fetch next opcode */
494 opcode = SUCK_BE_U1(m->jcode + bcindex);
496 /* If the previous instruction was a block-end instruction,
497 mark the current bytecode instruction as basic-block
498 starting instruction. */
500 /* NOTE: Some compilers put a JAVA_NOP after a blockend
503 if (blockend && (opcode != JAVA_NOP)) {
504 MARK_BASICBLOCK(&pd, bcindex);
508 /* If the current bytecode instruction was marked as
509 basic-block starting instruction before (e.g. blockend,
510 forward-branch target), mark the current IR instruction
513 if (pd.basicblockstart[bcindex] != 0) {
514 /* We need a NOP as last instruction in each basic block
515 for basic block reordering (may be replaced with a GOTO
518 INSTRUCTIONS_CHECK(1);
522 /* store intermediate instruction count (bit 0 mark block starts) */
524 pd.bytecodemap[bcindex] = ircount;
526 /* compute next instruction start */
528 nextbc = bcindex + jcommandsize[opcode];
530 CHECK_END_OF_BYTECODE(nextbc);
532 /* add stack elements produced by this instruction */
534 s_count += stackreq[opcode];
536 /* We check here for the space of 1 instruction in the
537 instruction array. If an opcode is converted to more than
538 1 instruction, this is checked in the corresponding
541 INSTRUCTIONS_CHECK(1);
543 /* translate this bytecode instruction */
549 /* pushing constants onto the stack ***********************************/
552 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + bcindex + 1));
556 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + bcindex + 1));
560 i = SUCK_BE_U1(m->jcode + bcindex + 1);
561 goto pushconstantitem;
565 i = SUCK_BE_U2(m->jcode + bcindex + 1);
569 #if defined(ENABLE_VERIFIER)
570 if (i >= m->class->cpcount) {
571 exceptions_throw_verifyerror(m,
572 "Attempt to access constant outside range");
577 switch (m->class->cptags[i]) {
578 case CONSTANT_Integer:
579 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
582 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
585 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
587 case CONSTANT_Double:
588 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
590 case CONSTANT_String:
591 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
594 cr = (constant_classref *) (m->class->cpinfos[i]);
596 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
599 /* if not resolved, c == NULL */
601 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
605 #if defined(ENABLE_VERIFIER)
607 exceptions_throw_verifyerror(m,
608 "Invalid constant type to push");
614 case JAVA_ACONST_NULL:
625 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
630 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
636 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
641 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
644 /* stack operations ***************************************************/
646 /* We need space for additional ICMDs so we can translate these */
647 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
650 INSTRUCTIONS_CHECK(4);
658 INSTRUCTIONS_CHECK(6);
668 INSTRUCTIONS_CHECK(2);
674 INSTRUCTIONS_CHECK(7);
685 INSTRUCTIONS_CHECK(9);
698 INSTRUCTIONS_CHECK(3);
704 /* local variable access instructions *********************************/
709 if (iswide == false) {
710 i = SUCK_BE_U1(m->jcode + bcindex + 1);
713 i = SUCK_BE_U2(m->jcode + bcindex + 1);
714 nextbc = bcindex + 3;
717 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
722 if (iswide == false) {
723 i = SUCK_BE_U1(m->jcode + bcindex + 1);
726 i = SUCK_BE_U2(m->jcode + bcindex + 1);
727 nextbc = bcindex + 3;
730 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
737 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
744 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
751 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
758 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
765 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
771 if (iswide == false) {
772 i = SUCK_BE_U1(m->jcode + bcindex + 1);
775 i = SUCK_BE_U2(m->jcode + bcindex + 1);
776 nextbc = bcindex + 3;
779 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
784 if (iswide == false) {
785 i = SUCK_BE_U1(m->jcode + bcindex + 1);
788 i = SUCK_BE_U2(m->jcode + bcindex + 1);
789 nextbc = bcindex + 3;
792 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
799 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
806 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
813 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
820 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
827 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
834 if (iswide == false) {
835 i = SUCK_BE_U1(m->jcode + bcindex + 1);
836 v = SUCK_BE_S1(m->jcode + bcindex + 2);
840 i = SUCK_BE_U2(m->jcode + bcindex + 1);
841 v = SUCK_BE_S2(m->jcode + bcindex + 3);
842 nextbc = bcindex + 5;
846 LOCALTYPE_USED(i, TYPE_INT);
847 OP_LOCALINDEX_I(opcode, i, v);
851 /* wider index for loading, storing and incrementing ******************/
858 /* managing arrays ****************************************************/
861 switch (SUCK_BE_S1(m->jcode + bcindex + 1)) {
863 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
866 bte = builtintable_get_internal(BUILTIN_newarray_char);
869 bte = builtintable_get_internal(BUILTIN_newarray_float);
872 bte = builtintable_get_internal(BUILTIN_newarray_double);
875 bte = builtintable_get_internal(BUILTIN_newarray_byte);
878 bte = builtintable_get_internal(BUILTIN_newarray_short);
881 bte = builtintable_get_internal(BUILTIN_newarray_int);
884 bte = builtintable_get_internal(BUILTIN_newarray_long);
886 #if defined(ENABLE_VERIFIER)
888 exceptions_throw_verifyerror(m, "Invalid array-type to create");
892 OP_BUILTIN_CHECK_EXCEPTION(bte);
896 i = SUCK_BE_U2(m->jcode + bcindex + 1);
897 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
901 if (!(cr = class_get_classref_multiarray_of(1, compr)))
904 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
907 INSTRUCTIONS_CHECK(2);
908 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
909 bte = builtintable_get_internal(BUILTIN_newarray);
910 OP_BUILTIN_CHECK_EXCEPTION(bte);
914 case JAVA_MULTIANEWARRAY:
915 jd->isleafmethod = false;
916 i = SUCK_BE_U2(m->jcode + bcindex + 1);
917 j = SUCK_BE_U1(m->jcode + bcindex + 3);
919 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
923 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
926 /* if unresolved, c == NULL */
928 iptr->s1.argcount = j;
929 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, INS_FLAG_CHECK);
932 /* control flow instructions ******************************************/
951 i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
952 CHECK_BYTECODE_INDEX(i);
953 MARK_BASICBLOCK(&pd, i);
955 OP_INSINDEX(opcode, i);
959 i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
960 CHECK_BYTECODE_INDEX(i);
961 MARK_BASICBLOCK(&pd, i);
963 OP_INSINDEX(ICMD_GOTO, i);
967 i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
969 CHECK_BYTECODE_INDEX(i);
970 MARK_BASICBLOCK(&pd, i);
972 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
973 iptr->sx.s23.s3.jsrtarget.insindex = i;
978 i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
982 if (iswide == false) {
983 i = SUCK_BE_U1(m->jcode + bcindex + 1);
986 i = SUCK_BE_U2(m->jcode + bcindex + 1);
987 nextbc = bcindex + 3;
992 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
1002 /* XXX ARETURN will need a flag in the typechecker */
1008 /* XXX ATHROW will need a flag in the typechecker */
1013 /* table jumps ********************************************************/
1015 case JAVA_LOOKUPSWITCH:
1018 lookup_target_t *lookup;
1019 #if defined(ENABLE_VERIFIER)
1023 nextbc = MEMORY_ALIGN((bcindex + 1), 4);
1025 CHECK_END_OF_BYTECODE(nextbc + 8);
1027 OP_PREPARE_ZEROFLAGS(opcode);
1029 /* default target */
1031 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1032 iptr->sx.s23.s3.lookupdefault.insindex = j;
1034 CHECK_BYTECODE_INDEX(j);
1035 MARK_BASICBLOCK(&pd, j);
1037 /* number of pairs */
1039 num = SUCK_BE_U4(m->jcode + nextbc);
1040 iptr->sx.s23.s2.lookupcount = num;
1043 /* allocate the intermediate code table */
1045 lookup = DMNEW(lookup_target_t, num);
1046 iptr->dst.lookup = lookup;
1048 /* iterate over the lookup table */
1050 CHECK_END_OF_BYTECODE(nextbc + 8 * num);
1052 for (i = 0; i < num; i++) {
1055 j = SUCK_BE_S4(m->jcode + nextbc);
1060 #if defined(ENABLE_VERIFIER)
1061 /* check if the lookup table is sorted correctly */
1063 if (i && (j <= prevvalue)) {
1064 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
1071 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1072 lookup->target.insindex = j;
1075 CHECK_BYTECODE_INDEX(j);
1076 MARK_BASICBLOCK(&pd, j);
1084 case JAVA_TABLESWITCH:
1088 branch_target_t *table;
1091 nextbc = MEMORY_ALIGN((bcindex + 1), 4);
1093 CHECK_END_OF_BYTECODE(nextbc + 12);
1095 OP_PREPARE_ZEROFLAGS(opcode);
1097 /* default target */
1099 deftarget = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1101 CHECK_BYTECODE_INDEX(deftarget);
1102 MARK_BASICBLOCK(&pd, deftarget);
1106 j = SUCK_BE_S4(m->jcode + nextbc);
1107 iptr->sx.s23.s2.tablelow = j;
1112 num = SUCK_BE_S4(m->jcode + nextbc);
1113 iptr->sx.s23.s3.tablehigh = num;
1116 /* calculate the number of table entries */
1120 #if defined(ENABLE_VERIFIER)
1122 exceptions_throw_verifyerror(m,
1123 "invalid TABLESWITCH: upper bound < lower bound");
1127 /* create the intermediate code table */
1128 /* the first entry is the default target */
1130 table = DMNEW(branch_target_t, 1 + num);
1131 iptr->dst.table = table;
1132 (table++)->insindex = deftarget;
1134 /* iterate over the target table */
1136 CHECK_END_OF_BYTECODE(nextbc + 4 * num);
1138 for (i = 0; i < num; i++) {
1139 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1140 (table++)->insindex = j;
1142 CHECK_BYTECODE_INDEX(j);
1143 MARK_BASICBLOCK(&pd, j);
1151 /* load and store of object fields ************************************/
1155 jd->isleafmethod = false;
1158 case JAVA_GETSTATIC:
1159 case JAVA_PUTSTATIC:
1162 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1163 fmi = class_getconstant(m->class, i, CONSTANT_Fieldref);
1168 OP_PREPARE_ZEROFLAGS(opcode);
1169 iptr->sx.s23.s3.fmiref = fmi;
1171 /* only with -noverify, otherwise the typechecker does this */
1173 #if defined(ENABLE_VERIFIER)
1174 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1176 result = resolve_field_lazy(m, fmi);
1178 if (result == resolveFailed)
1181 if (result != resolveSucceeded) {
1182 uf = resolve_create_unresolved_field(m->class, m, iptr);
1187 /* store the unresolved_field pointer */
1189 iptr->sx.s23.s3.uf = uf;
1190 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1192 #if defined(ENABLE_VERIFIER)
1199 /* method invocation **************************************************/
1201 case JAVA_INVOKESTATIC:
1202 OP_PREPARE_ZEROFLAGS(opcode);
1204 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1205 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1210 md = fmi->parseddesc.md;
1212 if (md->params == NULL)
1213 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1218 case JAVA_INVOKESPECIAL:
1219 OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
1221 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1222 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1224 goto invoke_nonstatic_method;
1226 case JAVA_INVOKEINTERFACE:
1227 OP_PREPARE_ZEROFLAGS(opcode);
1229 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1230 fmi = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1232 goto invoke_nonstatic_method;
1234 case JAVA_INVOKEVIRTUAL:
1235 OP_PREPARE_ZEROFLAGS(opcode);
1237 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1238 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1240 invoke_nonstatic_method:
1244 md = fmi->parseddesc.md;
1246 if (md->params == NULL)
1247 if (!descriptor_params_from_paramtypes(md, 0))
1251 jd->isleafmethod = false;
1253 iptr->sx.s23.s3.fmiref = fmi;
1255 /* only with -noverify, otherwise the typechecker does this */
1257 #if defined(ENABLE_VERIFIER)
1258 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1260 result = resolve_method_lazy(m, fmi,
1261 (opcode == JAVA_INVOKESPECIAL));
1263 if (result == resolveFailed)
1266 if (result == resolveSucceeded) {
1267 methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1269 /* if this call is monomorphic, turn it into an
1272 assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1274 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1275 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1277 iptr->opc = ICMD_INVOKESPECIAL;
1278 iptr->flags.bits |= INS_FLAG_CHECK;
1282 um = resolve_create_unresolved_method(m->class, m, fmi,
1283 (opcode == JAVA_INVOKESTATIC),
1284 (opcode == JAVA_INVOKESPECIAL));
1289 /* store the unresolved_method pointer */
1291 iptr->sx.s23.s3.um = um;
1292 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1294 #if defined(ENABLE_VERIFIER)
1300 /* instructions taking class arguments ********************************/
1303 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1304 cr = class_getconstant(m->class, i, CONSTANT_Class);
1309 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1312 INSTRUCTIONS_CHECK(2);
1313 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1314 bte = builtintable_get_internal(BUILTIN_new);
1315 OP_BUILTIN_CHECK_EXCEPTION(bte);
1319 case JAVA_CHECKCAST:
1320 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1321 cr = class_getconstant(m->class, i, CONSTANT_Class);
1326 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1329 if (cr->name->text[0] == '[') {
1330 /* array type cast-check */
1331 flags = INS_FLAG_CHECK | INS_FLAG_ARRAY;
1332 jd->isleafmethod = false;
1335 /* object type cast-check */
1336 flags = INS_FLAG_CHECK;
1338 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1341 case JAVA_INSTANCEOF:
1342 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1343 cr = class_getconstant(m->class, i, CONSTANT_Class);
1348 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1351 if (cr->name->text[0] == '[') {
1352 /* array type cast-check */
1353 INSTRUCTIONS_CHECK(2);
1354 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1355 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1356 OP_BUILTIN_NO_EXCEPTION(bte);
1360 /* object type cast-check */
1361 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1365 /* synchronization instructions ***************************************/
1367 case JAVA_MONITORENTER:
1368 #if defined(ENABLE_THREADS)
1370 bte = builtintable_get_internal(LOCK_monitor_enter);
1371 OP_BUILTIN_CHECK_EXCEPTION(bte);
1376 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1381 case JAVA_MONITOREXIT:
1382 #if defined(ENABLE_THREADS)
1384 bte = builtintable_get_internal(LOCK_monitor_exit);
1385 OP_BUILTIN_CHECK_EXCEPTION(bte);
1390 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1395 /* arithmetic instructions that may become builtin functions **********/
1398 #if !SUPPORT_DIVISION
1399 bte = builtintable_get_internal(BUILTIN_idiv);
1400 OP_BUILTIN_ARITHMETIC(opcode, bte);
1402 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1405 OP_CHECK_EXCEPTION(opcode);
1411 #if !SUPPORT_DIVISION
1412 bte = builtintable_get_internal(BUILTIN_irem);
1413 OP_BUILTIN_ARITHMETIC(opcode, bte);
1415 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1418 OP_CHECK_EXCEPTION(opcode);
1424 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1425 bte = builtintable_get_internal(BUILTIN_ldiv);
1426 OP_BUILTIN_ARITHMETIC(opcode, bte);
1428 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1431 OP_CHECK_EXCEPTION(opcode);
1437 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1438 bte = builtintable_get_internal(BUILTIN_lrem);
1439 OP_BUILTIN_ARITHMETIC(opcode, bte);
1441 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1444 OP_CHECK_EXCEPTION(opcode);
1450 #if defined(__I386__)
1453 bte = builtintable_get_internal(BUILTIN_frem);
1454 OP_BUILTIN_NO_EXCEPTION(bte);
1459 #if defined(__I386__)
1462 bte = builtintable_get_internal(BUILTIN_drem);
1463 OP_BUILTIN_NO_EXCEPTION(bte);
1468 #if defined(__ALPHA__)
1470 bte = builtintable_get_internal(BUILTIN_f2i);
1471 OP_BUILTIN_NO_EXCEPTION(bte);
1481 #if defined(__ALPHA__)
1483 bte = builtintable_get_internal(BUILTIN_f2l);
1484 OP_BUILTIN_NO_EXCEPTION(bte);
1494 #if defined(__ALPHA__)
1496 bte = builtintable_get_internal(BUILTIN_d2i);
1497 OP_BUILTIN_NO_EXCEPTION(bte);
1507 #if defined(__ALPHA__)
1509 bte = builtintable_get_internal(BUILTIN_d2l);
1510 OP_BUILTIN_NO_EXCEPTION(bte);
1519 /* invalid opcodes ****************************************************/
1521 /* check for invalid opcodes if the verifier is enabled */
1522 #if defined(ENABLE_VERIFIER)
1523 case JAVA_BREAKPOINT:
1524 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1527 case 186: /* unused opcode */
1581 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1585 #endif /* defined(ENABLE_VERIFIER) */
1587 /* opcodes that don't require translation *****************************/
1590 /* straight-forward translation to ICMD */
1596 /* verifier checks ****************************************************/
1598 #if defined(ENABLE_VERIFIER)
1599 /* If WIDE was used correctly, iswide should have been reset by now. */
1601 exceptions_throw_verifyerror(m,
1602 "Illegal instruction: WIDE before incompatible opcode");
1605 #endif /* defined(ENABLE_VERIFIER) */
1609 if (JITDATA_HAS_FLAG_REORDER(jd)) {
1610 /* add a NOP to the last basic block */
1612 INSTRUCTIONS_CHECK(1);
1616 /*** END OF LOOP **********************************************************/
1618 /* assert that we did not write more ICMDs than allocated */
1620 assert(ircount <= pd.instructionslength);
1621 assert(ircount == (iptr - pd.instructions));
1623 /*** verifier checks ******************************************************/
1625 #if defined(ENABLE_VERIFIER)
1626 if (bcindex != m->jcodelength) {
1627 exceptions_throw_verifyerror(m,
1628 "Command-sequence crosses code-boundary");
1633 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1636 #endif /* defined(ENABLE_VERIFIER) */
1638 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1640 /* identify basic blocks */
1642 /* check if first instruction is a branch target */
1644 if (pd.basicblockstart[0] == 1) {
1645 jd->branchtoentry = true;
1648 /* first instruction always starts a basic block */
1650 iptr = pd.instructions;
1652 iptr->flags.bits |= INS_FLAG_BASICBLOCK;
1655 /* Iterate over all bytecode instructions and set missing
1656 basic-block starts in IR instructions. */
1658 for (bcindex = 0; bcindex < m->jcodelength; bcindex++) {
1659 /* Does the current bytecode instruction start a basic
1662 if (pd.basicblockstart[bcindex] == 1) {
1663 #if defined(ENABLE_VERIFIER)
1664 /* Check if this bytecode basic-block start at the
1665 beginning of a bytecode instruction. */
1667 if (pd.bytecodestart[bcindex] == 0) {
1668 exceptions_throw_verifyerror(m,
1669 "Branch into middle of instruction");
1674 /* Get the IR instruction mapped to the bytecode
1675 instruction and set the basic block flag. */
1677 irindex = pd.bytecodemap[bcindex];
1678 iptr = pd.instructions + irindex;
1680 iptr->flags.bits |= INS_FLAG_BASICBLOCK;
1684 /* IR instruction index to basic-block index mapping */
1686 pd.instructionmap = DMNEW(s4, ircount);
1687 MZERO(pd.instructionmap, s4, ircount);
1689 /* Iterate over all IR instructions and count the basic blocks. */
1691 iptr = pd.instructions;
1695 for (i = 0; i < ircount; i++, iptr++) {
1696 if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
1697 /* store the basic-block number in the IR instruction
1700 pd.instructionmap[i] = bbcount;
1702 /* post-increment the basic-block count */
1708 /* Allocate basic block array (one more for end ipc). */
1710 jd->basicblocks = DMNEW(basicblock, bbcount + 1);
1711 MZERO(jd->basicblocks, basicblock, bbcount + 1);
1713 /* Now iterate again over all IR instructions and initialize the
1714 basic block structures and, in the same loop, resolve the
1715 branch-target instruction indices to basic blocks. */
1717 iptr = pd.instructions;
1718 bptr = jd->basicblocks;
1722 for (i = 0; i < ircount; i++, iptr++) {
1723 /* check for basic block */
1725 if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
1726 /* intialize the basic block */
1728 BASICBLOCK_INIT(bptr, m);
1730 bptr->iinstr = iptr;
1733 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1736 /* bptr->icount is set when the next block is allocated */
1738 bptr->nr = bbcount++;
1740 bptr[-1].next = bptr;
1743 /* resolve instruction indices to basic blocks */
1745 switch (iptr->opc) {
1753 case JAVA_IFNONNULL:
1754 case JAVA_IF_ICMPEQ:
1755 case JAVA_IF_ICMPNE:
1756 case JAVA_IF_ICMPLT:
1757 case JAVA_IF_ICMPGT:
1758 case JAVA_IF_ICMPLE:
1759 case JAVA_IF_ICMPGE:
1760 case JAVA_IF_ACMPEQ:
1761 case JAVA_IF_ACMPNE:
1763 BYTECODEINDEX_TO_BASICBLOCK(iptr->dst);
1767 BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.jsrtarget);
1770 case ICMD_TABLESWITCH:
1771 table = iptr->dst.table;
1773 BYTECODEINDEX_TO_BASICBLOCK(*table);
1776 j = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
1779 BYTECODEINDEX_TO_BASICBLOCK(*table);
1784 case ICMD_LOOKUPSWITCH:
1785 BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.lookupdefault);
1787 lookup = iptr->dst.lookup;
1789 j = iptr->sx.s23.s2.lookupcount;
1792 BYTECODEINDEX_TO_BASICBLOCK(lookup->target);
1799 /* set instruction count of last real block */
1802 bptr[-1].icount = (pd.instructions + ircount) - bptr[-1].iinstr;
1805 /* allocate additional block at end */
1807 BASICBLOCK_INIT(bptr, m);
1810 /* set basicblock pointers in exception table */
1812 if (!parse_resolve_exception_table(jd, &pd))
1815 /* store the local map */
1817 jd->local_map = local_map;
1819 /* calculate local variable renaming */
1828 /* iterate over local_map[0..m->maxlocals*5-1] and allocate a unique */
1829 /* variable index for each _used_ (javaindex,type) pair. */
1830 /* (local_map[javaindex*5+type] = cacaoindex) */
1831 /* Unused (javaindex,type) pairs are marked with UNUSED. */
1833 for (i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
1835 *mapptr = nlocals++;
1840 jd->localcount = nlocals;
1842 /* calculate the (maximum) number of variables needed */
1845 nlocals /* local variables */
1846 + bbcount * m->maxstack /* invars */
1847 + s_count; /* variables created within blocks (non-invar) */
1849 /* reserve the first indices for local variables */
1851 jd->vartop = nlocals;
1853 /* reserve extra variables needed by stack analyse */
1855 jd->varcount += STACK_EXTRA_VARS;
1856 jd->vartop += STACK_EXTRA_VARS;
1858 /* The verifier needs space for saving invars in some cases and */
1859 /* extra variables. */
1861 #if defined(ENABLE_VERIFIER)
1862 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1863 jd->vartop += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1865 /* allocate and initialize the variable array */
1867 jd->var = DMNEW(varinfo, jd->varcount);
1868 MZERO(jd->var, varinfo, jd->varcount);
1870 /* set types of all locals in jd->var */
1872 for (mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
1873 if (*mapptr != UNUSED)
1874 VAR(*mapptr)->type = i%5;
1877 /* assign local variables to method variables */
1879 jd->instructions = pd.instructions;
1880 jd->instructioncount = ircount;
1881 jd->basicblockcount = bbcount;
1882 jd->stackcount = s_count + bbcount * m->maxstack; /* in-stacks */
1884 /* allocate stack table */
1886 jd->stack = DMNEW(stackelement, jd->stackcount);
1888 /* everything's ok */
1892 /*** goto labels for throwing verifier exceptions *************************/
1894 #if defined(ENABLE_VERIFIER)
1896 throw_unexpected_end_of_bytecode:
1897 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1900 throw_invalid_bytecode_index:
1901 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1904 throw_illegal_local_variable_number:
1905 exceptions_throw_verifyerror(m, "Illegal local variable number");
1908 #endif /* ENABLE_VERIFIER */
1913 * These are local overrides for various environment variables in Emacs.
1914 * Please do not remove this and leave it at the end of the file, where
1915 * Emacs will automagically detect them.
1916 * ---------------------------------------------------------------------
1919 * indent-tabs-mode: t
1923 * vim:noexpandtab:sw=4:ts=4: