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 8159 2007-06-28 00:31:31Z michi $
37 #include "mm/memory.h"
39 #include "native/native.h"
41 #include "threads/lock-common.h"
43 #include "toolbox/logging.h"
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/stringlocal.h"
50 #include "vm/jit/asmpart.h"
51 #include "vm/jit/jit.h"
52 #include "vm/jit/parse.h"
53 #include "vm/jit/loop/loop.h"
55 #include "vmcore/linker.h"
56 #include "vmcore/loader.h"
57 #include "vmcore/options.h"
58 #include "vm/resolve.h"
60 #if defined(ENABLE_STATISTICS)
61 # include "vmcore/statistics.h"
64 #include "vmcore/suck.h"
66 #define INSTRUCTIONS_INCREMENT 5 /* number of additional instructions to */
67 /* allocate if space runs out */
70 /* local macros ***************************************************************/
72 #define BYTECODEINDEX_TO_BASICBLOCK(dst) \
75 parse_bytecodeindex_to_basicblock(jd, &pd, (dst).insindex); \
79 /* parserdata_t ***************************************************************/
81 typedef struct parsedata_t parsedata_t;
84 u1 *bytecodestart; /* start of bytecode instructions */
85 u1 *basicblockstart; /* start of bytecode basic-blocks */
87 s4 *bytecodemap; /* bytecode to IR mapping */
89 instruction *instructions; /* instruction array */
90 s4 instructionslength; /* length of the instruction array */
92 s4 *instructionmap; /* IR to basic-block mapping */
96 /* parse_setup *****************************************************************
98 Fills the passed parsedata_t structure.
100 *******************************************************************************/
102 static void parse_setup(jitdata *jd, parsedata_t *pd)
106 /* get required compiler data */
110 /* bytecode start array */
112 pd->bytecodestart = DMNEW(u1, m->jcodelength + 1);
113 MZERO(pd->bytecodestart, u1, m->jcodelength + 1);
115 /* bytecode basic-block start array */
117 pd->basicblockstart = DMNEW(u1, m->jcodelength + 1);
118 MZERO(pd->basicblockstart, u1, m->jcodelength + 1);
120 /* bytecode instruction index to IR instruction mapping */
122 pd->bytecodemap = DMNEW(s4, m->jcodelength + 1);
123 MSET(pd->bytecodemap, -1, s4, m->jcodelength + 1);
125 /* allocate the instruction array */
127 pd->instructionslength = m->jcodelength + 1;
128 pd->instructions = DMNEW(instruction, pd->instructionslength);
130 /* Zero the intermediate instructions array so we don't have any
131 invalid pointers in it if we cannot finish stack_analyse(). */
133 MZERO(pd->instructions, instruction, pd->instructionslength);
135 /* The instructionmap is allocated later when we know the count of
138 pd->instructionmap = NULL;
142 /* parse_realloc_instructions **************************************************
144 Reallocate the instructions array so there is room for at least N
145 additional instructions.
148 the new value for iptr
150 *******************************************************************************/
152 static instruction *parse_realloc_instructions(parsedata_t *pd, s4 icount, s4 n)
154 /* increase the size of the instruction array */
156 pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
158 /* reallocate the array */
160 pd->instructions = DMREALLOC(pd->instructions, instruction, icount,
161 pd->instructionslength);
162 MZERO(pd->instructions + icount, instruction,
163 (pd->instructionslength - icount));
165 /* return the iptr */
167 return pd->instructions + icount;
171 /* parse_bytecodeindex_to_basicblock *******************************************
173 Resolves a bytecode index to the corresponding basic block.
175 *******************************************************************************/
177 static basicblock *parse_bytecodeindex_to_basicblock(jitdata *jd,
184 irindex = pd->bytecodemap[bcindex];
185 bb = jd->basicblocks + pd->instructionmap[irindex];
191 /* parse_mark_exception_boundaries *********************************************
193 Mark exception handlers and the boundaries of the handled regions as
194 basic block boundaries.
197 jd...............current jitdata
200 true.............everything ok
201 false............an exception has been thrown
203 *******************************************************************************/
205 static bool parse_mark_exception_boundaries(jitdata *jd, parsedata_t *pd)
210 raw_exception_entry *rex;
215 len = m->rawexceptiontablelength;
220 rex = m->rawexceptiontable;
222 for (i = 0; i < len; ++i, ++rex) {
224 /* the start of the handled region becomes a basic block start */
226 bcindex = rex->startpc;
227 CHECK_BYTECODE_INDEX(bcindex);
228 MARK_BASICBLOCK(pd, bcindex);
230 bcindex = rex->endpc; /* see JVM Spec 4.7.3 */
231 CHECK_BYTECODE_INDEX_EXCLUSIVE(bcindex);
233 /* check that the range is valid */
235 #if defined(ENABLE_VERIFIER)
236 if (bcindex <= rex->startpc) {
237 exceptions_throw_verifyerror(m, "Invalid exception handler range");
242 /* End of handled region becomes a basic block boundary (if it
243 is the bytecode end, we'll use the special end block that
244 is created anyway). */
246 if (bcindex < m->jcodelength)
247 MARK_BASICBLOCK(pd, bcindex);
249 jd->branchtoend = true;
251 /* the start of the handler becomes a basic block start */
253 bcindex = rex->handlerpc;
254 CHECK_BYTECODE_INDEX(bcindex);
255 MARK_BASICBLOCK(pd, bcindex);
262 #if defined(ENABLE_VERIFIER)
263 throw_invalid_bytecode_index:
264 exceptions_throw_verifyerror(m,
265 "Illegal bytecode index in exception table");
271 /* parse_resolve_exception_table ***********************************************
273 Enter the exception handlers and their ranges, resolved to basicblock *s,
277 jd...............current jitdata
280 true.............everything ok
281 false............an exception has been thrown
283 *******************************************************************************/
285 static bool parse_resolve_exception_table(jitdata *jd, parsedata_t *pd)
288 raw_exception_entry *rex;
296 len = m->rawexceptiontablelength;
298 /* common case: no handler entries */
303 /* allocate the exception table */
305 jd->exceptiontablelength = len;
306 jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
308 /* copy and resolve the entries */
310 ex = jd->exceptiontable;
311 rex = m->rawexceptiontable;
313 for (i = 0; i < len; ++i, ++rex, ++ex) {
314 /* resolve instruction indices to basic blocks */
316 ex->start = parse_bytecodeindex_to_basicblock(jd, pd, rex->startpc);
317 ex->end = parse_bytecodeindex_to_basicblock(jd, pd, rex->endpc);
318 ex->handler = parse_bytecodeindex_to_basicblock(jd, pd, rex->handlerpc);
320 /* lazily resolve the catchtype */
322 if (rex->catchtype.any != NULL) {
323 if (!resolve_classref_or_classinfo(m,
325 resolveLazy, true, false,
329 /* if resolved, enter the result of resolution in the table */
332 rex->catchtype.cls = exclass;
335 ex->catchtype = rex->catchtype;
336 ex->next = NULL; /* set by loop analysis */
337 ex->down = ex + 1; /* link to next exception entry */
340 /* terminate the ->down linked list */
342 assert(ex != jd->exceptiontable);
349 /*******************************************************************************
351 function 'parse' scans the JavaVM code and generates intermediate code
353 During parsing the block index table is used to store at bit pos 0
354 a flag which marks basic block starts and at position 1 to 31 the
355 intermediate instruction index. After parsing the block index table
356 is scanned, for marked positions a block is generated and the block
357 number is stored in the block index table.
359 *******************************************************************************/
361 /*** macro for checking the length of the bytecode ***/
363 #if defined(ENABLE_VERIFIER)
364 #define CHECK_END_OF_BYTECODE(neededlength) \
366 if ((neededlength) > m->jcodelength) \
367 goto throw_unexpected_end_of_bytecode; \
369 #else /* !ENABLE_VERIFIER */
370 #define CHECK_END_OF_BYTECODE(neededlength)
371 #endif /* ENABLE_VERIFIER */
373 bool parse(jitdata *jd)
375 methodinfo *m; /* method being parsed */
377 instruction *iptr; /* current ptr into instruction array */
379 s4 bcindex; /* bytecode instruction index */
380 s4 nextbc; /* start of next bytecode instruction */
381 s4 opcode; /* bytecode instruction opcode */
383 s4 irindex; /* IR instruction index */
384 s4 ircount; /* IR instruction count */
386 s4 bbcount; /* basic block count */
388 int s_count = 0; /* stack element counter */
389 bool blockend; /* true if basic block end has been reached */
390 bool iswide; /* true if last instruction was a wide */
392 constant_classref *cr;
393 constant_classref *compr;
395 builtintable_entry *bte;
396 constant_FMIref *fmi;
398 unresolved_method *um;
399 unresolved_field *uf;
401 resolve_result_t result;
408 int *local_map; /* local pointer to renaming map */
409 /* is assigned to rd->local_map at the end */
410 branch_target_t *table;
411 lookup_target_t *lookup;
415 /* get required compiler data */
419 /* allocate buffers for local variable renaming */
421 local_map = DMNEW(int, m->maxlocals * 5);
423 for (i = 0; i < m->maxlocals; i++) {
424 local_map[i * 5 + 0] = 0;
425 local_map[i * 5 + 1] = 0;
426 local_map[i * 5 + 2] = 0;
427 local_map[i * 5 + 3] = 0;
428 local_map[i * 5 + 4] = 0;
431 /* initialize the parse data structures */
433 parse_setup(jd, &pd);
435 /* initialize local variables */
437 iptr = pd.instructions;
443 /* mark basic block boundaries for exception table */
445 if (!parse_mark_exception_boundaries(jd, &pd))
448 /* initialize stack element counter */
450 s_count = 1 + m->rawexceptiontablelength;
452 /* setup line number info */
457 if (m->linenumbercount == 0) {
461 linepcchange = m->linenumbers[0].start_pc;
464 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
466 for (bcindex = 0; bcindex < m->jcodelength; bcindex = nextbc) {
468 /* mark this position as a valid bytecode instruction start */
470 pd.bytecodestart[bcindex] = 1;
472 /* change the current line number, if necessary */
474 /* XXX rewrite this using pointer arithmetic */
476 if (linepcchange == bcindex) {
477 if (m->linenumbercount > lineindex) {
479 currentline = m->linenumbers[lineindex].line_number;
481 if (lineindex < m->linenumbercount) {
482 linepcchange = m->linenumbers[lineindex].start_pc;
483 if (linepcchange == bcindex)
484 goto next_linenumber;
490 /* fetch next opcode */
492 opcode = SUCK_BE_U1(m->jcode + bcindex);
494 /* If the previous instruction was a block-end instruction,
495 mark the current bytecode instruction as basic-block
496 starting instruction. */
498 /* NOTE: Some compilers put a JAVA_NOP after a blockend
501 if (blockend && (opcode != JAVA_NOP)) {
502 MARK_BASICBLOCK(&pd, bcindex);
506 /* If the current bytecode instruction was marked as
507 basic-block starting instruction before (e.g. blockend,
508 forward-branch target), mark the current IR instruction
511 if (pd.basicblockstart[bcindex] != 0) {
512 /* We need a NOP as last instruction in each basic block
513 for basic block reordering (may be replaced with a GOTO
516 INSTRUCTIONS_CHECK(1);
520 /* store intermediate instruction count (bit 0 mark block starts) */
522 pd.bytecodemap[bcindex] = ircount;
524 /* compute next instruction start */
526 nextbc = bcindex + jcommandsize[opcode];
528 CHECK_END_OF_BYTECODE(nextbc);
530 /* add stack elements produced by this instruction */
532 s_count += stackreq[opcode];
534 /* We check here for the space of 1 instruction in the
535 instruction array. If an opcode is converted to more than
536 1 instruction, this is checked in the corresponding
539 INSTRUCTIONS_CHECK(1);
541 /* translate this bytecode instruction */
547 /* pushing constants onto the stack ***********************************/
550 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + bcindex + 1));
554 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + bcindex + 1));
558 i = SUCK_BE_U1(m->jcode + bcindex + 1);
559 goto pushconstantitem;
563 i = SUCK_BE_U2(m->jcode + bcindex + 1);
567 #if defined(ENABLE_VERIFIER)
568 if (i >= m->class->cpcount) {
569 exceptions_throw_verifyerror(m,
570 "Attempt to access constant outside range");
575 switch (m->class->cptags[i]) {
576 case CONSTANT_Integer:
577 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
580 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
583 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
585 case CONSTANT_Double:
586 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
588 case CONSTANT_String:
589 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
592 cr = (constant_classref *) (m->class->cpinfos[i]);
594 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
597 /* if not resolved, c == NULL */
599 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
603 #if defined(ENABLE_VERIFIER)
605 exceptions_throw_verifyerror(m,
606 "Invalid constant type to push");
612 case JAVA_ACONST_NULL:
623 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
628 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
634 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
639 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
642 /* stack operations ***************************************************/
644 /* We need space for additional ICMDs so we can translate these */
645 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
648 INSTRUCTIONS_CHECK(4);
656 INSTRUCTIONS_CHECK(6);
666 INSTRUCTIONS_CHECK(2);
672 INSTRUCTIONS_CHECK(7);
683 INSTRUCTIONS_CHECK(9);
696 INSTRUCTIONS_CHECK(3);
702 /* local variable access instructions *********************************/
707 if (iswide == false) {
708 i = SUCK_BE_U1(m->jcode + bcindex + 1);
711 i = SUCK_BE_U2(m->jcode + bcindex + 1);
712 nextbc = bcindex + 3;
715 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
720 if (iswide == false) {
721 i = SUCK_BE_U1(m->jcode + bcindex + 1);
724 i = SUCK_BE_U2(m->jcode + bcindex + 1);
725 nextbc = bcindex + 3;
728 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
735 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
742 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
749 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
756 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
763 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
769 if (iswide == false) {
770 i = SUCK_BE_U1(m->jcode + bcindex + 1);
773 i = SUCK_BE_U2(m->jcode + bcindex + 1);
774 nextbc = bcindex + 3;
777 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
782 if (iswide == false) {
783 i = SUCK_BE_U1(m->jcode + bcindex + 1);
786 i = SUCK_BE_U2(m->jcode + bcindex + 1);
787 nextbc = bcindex + 3;
790 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
797 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
804 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
811 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
818 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
825 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
832 if (iswide == false) {
833 i = SUCK_BE_U1(m->jcode + bcindex + 1);
834 v = SUCK_BE_S1(m->jcode + bcindex + 2);
838 i = SUCK_BE_U2(m->jcode + bcindex + 1);
839 v = SUCK_BE_S2(m->jcode + bcindex + 3);
840 nextbc = bcindex + 5;
844 LOCALTYPE_USED(i, TYPE_INT);
845 OP_LOCALINDEX_I(opcode, i, v);
849 /* wider index for loading, storing and incrementing ******************/
856 /* managing arrays ****************************************************/
859 switch (SUCK_BE_S1(m->jcode + bcindex + 1)) {
861 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
864 bte = builtintable_get_internal(BUILTIN_newarray_char);
867 bte = builtintable_get_internal(BUILTIN_newarray_float);
870 bte = builtintable_get_internal(BUILTIN_newarray_double);
873 bte = builtintable_get_internal(BUILTIN_newarray_byte);
876 bte = builtintable_get_internal(BUILTIN_newarray_short);
879 bte = builtintable_get_internal(BUILTIN_newarray_int);
882 bte = builtintable_get_internal(BUILTIN_newarray_long);
884 #if defined(ENABLE_VERIFIER)
886 exceptions_throw_verifyerror(m, "Invalid array-type to create");
890 OP_BUILTIN_CHECK_EXCEPTION(bte);
894 i = SUCK_BE_U2(m->jcode + bcindex + 1);
895 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
899 if (!(cr = class_get_classref_multiarray_of(1, compr)))
902 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
905 INSTRUCTIONS_CHECK(2);
906 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
907 bte = builtintable_get_internal(BUILTIN_newarray);
908 OP_BUILTIN_CHECK_EXCEPTION(bte);
912 case JAVA_MULTIANEWARRAY:
913 jd->isleafmethod = false;
914 i = SUCK_BE_U2(m->jcode + bcindex + 1);
915 j = SUCK_BE_U1(m->jcode + bcindex + 3);
917 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
921 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
924 /* if unresolved, c == NULL */
926 iptr->s1.argcount = j;
927 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, INS_FLAG_CHECK);
930 /* control flow instructions ******************************************/
949 i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
950 CHECK_BYTECODE_INDEX(i);
951 MARK_BASICBLOCK(&pd, i);
953 OP_INSINDEX(opcode, i);
957 i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
958 CHECK_BYTECODE_INDEX(i);
959 MARK_BASICBLOCK(&pd, i);
961 OP_INSINDEX(ICMD_GOTO, i);
965 i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
967 CHECK_BYTECODE_INDEX(i);
968 MARK_BASICBLOCK(&pd, i);
970 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
971 iptr->sx.s23.s3.jsrtarget.insindex = i;
976 i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
980 if (iswide == false) {
981 i = SUCK_BE_U1(m->jcode + bcindex + 1);
984 i = SUCK_BE_U2(m->jcode + bcindex + 1);
985 nextbc = bcindex + 3;
990 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
1000 /* XXX ARETURN will need a flag in the typechecker */
1006 /* XXX ATHROW will need a flag in the typechecker */
1011 /* table jumps ********************************************************/
1013 case JAVA_LOOKUPSWITCH:
1016 lookup_target_t *lookup;
1017 #if defined(ENABLE_VERIFIER)
1021 nextbc = MEMORY_ALIGN((bcindex + 1), 4);
1023 CHECK_END_OF_BYTECODE(nextbc + 8);
1025 OP_PREPARE_ZEROFLAGS(opcode);
1027 /* default target */
1029 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1030 iptr->sx.s23.s3.lookupdefault.insindex = j;
1032 CHECK_BYTECODE_INDEX(j);
1033 MARK_BASICBLOCK(&pd, j);
1035 /* number of pairs */
1037 num = SUCK_BE_U4(m->jcode + nextbc);
1038 iptr->sx.s23.s2.lookupcount = num;
1041 /* allocate the intermediate code table */
1043 lookup = DMNEW(lookup_target_t, num);
1044 iptr->dst.lookup = lookup;
1046 /* iterate over the lookup table */
1048 CHECK_END_OF_BYTECODE(nextbc + 8 * num);
1050 for (i = 0; i < num; i++) {
1053 j = SUCK_BE_S4(m->jcode + nextbc);
1058 #if defined(ENABLE_VERIFIER)
1059 /* check if the lookup table is sorted correctly */
1061 if (i && (j <= prevvalue)) {
1062 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
1069 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1070 lookup->target.insindex = j;
1073 CHECK_BYTECODE_INDEX(j);
1074 MARK_BASICBLOCK(&pd, j);
1082 case JAVA_TABLESWITCH:
1086 branch_target_t *table;
1089 nextbc = MEMORY_ALIGN((bcindex + 1), 4);
1091 CHECK_END_OF_BYTECODE(nextbc + 12);
1093 OP_PREPARE_ZEROFLAGS(opcode);
1095 /* default target */
1097 deftarget = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1099 CHECK_BYTECODE_INDEX(deftarget);
1100 MARK_BASICBLOCK(&pd, deftarget);
1104 j = SUCK_BE_S4(m->jcode + nextbc);
1105 iptr->sx.s23.s2.tablelow = j;
1110 num = SUCK_BE_S4(m->jcode + nextbc);
1111 iptr->sx.s23.s3.tablehigh = num;
1114 /* calculate the number of table entries */
1118 #if defined(ENABLE_VERIFIER)
1120 exceptions_throw_verifyerror(m,
1121 "invalid TABLESWITCH: upper bound < lower bound");
1125 /* create the intermediate code table */
1126 /* the first entry is the default target */
1128 table = DMNEW(branch_target_t, 1 + num);
1129 iptr->dst.table = table;
1130 (table++)->insindex = deftarget;
1132 /* iterate over the target table */
1134 CHECK_END_OF_BYTECODE(nextbc + 4 * num);
1136 for (i = 0; i < num; i++) {
1137 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1138 (table++)->insindex = j;
1140 CHECK_BYTECODE_INDEX(j);
1141 MARK_BASICBLOCK(&pd, j);
1149 /* load and store of object fields ************************************/
1153 jd->isleafmethod = false;
1156 case JAVA_GETSTATIC:
1157 case JAVA_PUTSTATIC:
1160 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1161 fmi = class_getconstant(m->class, i, CONSTANT_Fieldref);
1166 OP_PREPARE_ZEROFLAGS(opcode);
1167 iptr->sx.s23.s3.fmiref = fmi;
1169 /* only with -noverify, otherwise the typechecker does this */
1171 #if defined(ENABLE_VERIFIER)
1172 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1174 result = resolve_field_lazy(m, fmi);
1176 if (result == resolveFailed)
1179 if (result != resolveSucceeded) {
1180 uf = resolve_create_unresolved_field(m->class, m, iptr);
1185 /* store the unresolved_field pointer */
1187 iptr->sx.s23.s3.uf = uf;
1188 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1190 #if defined(ENABLE_VERIFIER)
1197 /* method invocation **************************************************/
1199 case JAVA_INVOKESTATIC:
1200 OP_PREPARE_ZEROFLAGS(opcode);
1202 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1203 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1208 md = fmi->parseddesc.md;
1210 if (md->params == NULL)
1211 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1216 case JAVA_INVOKESPECIAL:
1217 OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
1219 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1220 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1222 goto invoke_nonstatic_method;
1224 case JAVA_INVOKEINTERFACE:
1225 OP_PREPARE_ZEROFLAGS(opcode);
1227 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1228 fmi = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1230 goto invoke_nonstatic_method;
1232 case JAVA_INVOKEVIRTUAL:
1233 OP_PREPARE_ZEROFLAGS(opcode);
1235 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1236 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1238 invoke_nonstatic_method:
1242 md = fmi->parseddesc.md;
1244 if (md->params == NULL)
1245 if (!descriptor_params_from_paramtypes(md, 0))
1249 jd->isleafmethod = false;
1251 iptr->sx.s23.s3.fmiref = fmi;
1253 /* only with -noverify, otherwise the typechecker does this */
1255 #if defined(ENABLE_VERIFIER)
1256 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1258 result = resolve_method_lazy(m, fmi,
1259 (opcode == JAVA_INVOKESPECIAL));
1261 if (result == resolveFailed)
1264 if (result == resolveSucceeded) {
1265 methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1267 /* if this call is monomorphic, turn it into an
1270 assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1272 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1273 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1275 iptr->opc = ICMD_INVOKESPECIAL;
1276 iptr->flags.bits |= INS_FLAG_CHECK;
1280 um = resolve_create_unresolved_method(m->class, m, fmi,
1281 (opcode == JAVA_INVOKESTATIC),
1282 (opcode == JAVA_INVOKESPECIAL));
1287 /* store the unresolved_method pointer */
1289 iptr->sx.s23.s3.um = um;
1290 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1292 #if defined(ENABLE_VERIFIER)
1298 /* instructions taking class arguments ********************************/
1301 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1302 cr = class_getconstant(m->class, i, CONSTANT_Class);
1307 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1310 INSTRUCTIONS_CHECK(2);
1311 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1312 bte = builtintable_get_internal(BUILTIN_new);
1313 OP_BUILTIN_CHECK_EXCEPTION(bte);
1317 case JAVA_CHECKCAST:
1318 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1319 cr = class_getconstant(m->class, i, CONSTANT_Class);
1324 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1327 if (cr->name->text[0] == '[') {
1328 /* array type cast-check */
1329 flags = INS_FLAG_CHECK | INS_FLAG_ARRAY;
1330 jd->isleafmethod = false;
1333 /* object type cast-check */
1334 flags = INS_FLAG_CHECK;
1336 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1339 case JAVA_INSTANCEOF:
1340 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1341 cr = class_getconstant(m->class, i, CONSTANT_Class);
1346 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1349 if (cr->name->text[0] == '[') {
1350 /* array type cast-check */
1351 INSTRUCTIONS_CHECK(2);
1352 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1353 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1354 OP_BUILTIN_NO_EXCEPTION(bte);
1358 /* object type cast-check */
1359 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1363 /* synchronization instructions ***************************************/
1365 case JAVA_MONITORENTER:
1366 #if defined(ENABLE_THREADS)
1368 bte = builtintable_get_internal(LOCK_monitor_enter);
1369 OP_BUILTIN_CHECK_EXCEPTION(bte);
1374 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1379 case JAVA_MONITOREXIT:
1380 #if defined(ENABLE_THREADS)
1382 bte = builtintable_get_internal(LOCK_monitor_exit);
1383 OP_BUILTIN_CHECK_EXCEPTION(bte);
1388 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1393 /* arithmetic instructions that may become builtin functions **********/
1396 #if !SUPPORT_DIVISION
1397 bte = builtintable_get_internal(BUILTIN_idiv);
1398 OP_BUILTIN_ARITHMETIC(opcode, bte);
1400 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1403 OP_CHECK_EXCEPTION(opcode);
1409 #if !SUPPORT_DIVISION
1410 bte = builtintable_get_internal(BUILTIN_irem);
1411 OP_BUILTIN_ARITHMETIC(opcode, bte);
1413 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1416 OP_CHECK_EXCEPTION(opcode);
1422 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1423 bte = builtintable_get_internal(BUILTIN_ldiv);
1424 OP_BUILTIN_ARITHMETIC(opcode, bte);
1426 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1429 OP_CHECK_EXCEPTION(opcode);
1435 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1436 bte = builtintable_get_internal(BUILTIN_lrem);
1437 OP_BUILTIN_ARITHMETIC(opcode, bte);
1439 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1442 OP_CHECK_EXCEPTION(opcode);
1448 #if defined(__I386__)
1451 bte = builtintable_get_internal(BUILTIN_frem);
1452 OP_BUILTIN_NO_EXCEPTION(bte);
1457 #if defined(__I386__)
1460 bte = builtintable_get_internal(BUILTIN_drem);
1461 OP_BUILTIN_NO_EXCEPTION(bte);
1466 #if defined(__ALPHA__)
1468 bte = builtintable_get_internal(BUILTIN_f2i);
1469 OP_BUILTIN_NO_EXCEPTION(bte);
1479 #if defined(__ALPHA__)
1481 bte = builtintable_get_internal(BUILTIN_f2l);
1482 OP_BUILTIN_NO_EXCEPTION(bte);
1492 #if defined(__ALPHA__)
1494 bte = builtintable_get_internal(BUILTIN_d2i);
1495 OP_BUILTIN_NO_EXCEPTION(bte);
1505 #if defined(__ALPHA__)
1507 bte = builtintable_get_internal(BUILTIN_d2l);
1508 OP_BUILTIN_NO_EXCEPTION(bte);
1517 /* invalid opcodes ****************************************************/
1519 /* check for invalid opcodes if the verifier is enabled */
1520 #if defined(ENABLE_VERIFIER)
1521 case JAVA_BREAKPOINT:
1522 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1525 case 186: /* unused opcode */
1579 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1583 #endif /* defined(ENABLE_VERIFIER) */
1585 /* opcodes that don't require translation *****************************/
1588 /* straight-forward translation to ICMD */
1594 /* verifier checks ****************************************************/
1596 #if defined(ENABLE_VERIFIER)
1597 /* If WIDE was used correctly, iswide should have been reset by now. */
1599 exceptions_throw_verifyerror(m,
1600 "Illegal instruction: WIDE before incompatible opcode");
1603 #endif /* defined(ENABLE_VERIFIER) */
1607 if (JITDATA_HAS_FLAG_REORDER(jd)) {
1608 /* add a NOP to the last basic block */
1610 INSTRUCTIONS_CHECK(1);
1614 /*** END OF LOOP **********************************************************/
1616 /* assert that we did not write more ICMDs than allocated */
1618 assert(ircount <= pd.instructionslength);
1619 assert(ircount == (iptr - pd.instructions));
1621 /*** verifier checks ******************************************************/
1623 #if defined(ENABLE_VERIFIER)
1624 if (bcindex != m->jcodelength) {
1625 exceptions_throw_verifyerror(m,
1626 "Command-sequence crosses code-boundary");
1631 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1634 #endif /* defined(ENABLE_VERIFIER) */
1636 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1638 /* identify basic blocks */
1640 /* check if first instruction is a branch target */
1642 if (pd.basicblockstart[0] == 1) {
1643 jd->branchtoentry = true;
1646 /* first instruction always starts a basic block */
1648 iptr = pd.instructions;
1650 iptr->flags.bits |= INS_FLAG_BASICBLOCK;
1653 /* Iterate over all bytecode instructions and set missing
1654 basic-block starts in IR instructions. */
1656 for (bcindex = 0; bcindex < m->jcodelength; bcindex++) {
1657 /* Does the current bytecode instruction start a basic
1660 if (pd.basicblockstart[bcindex] == 1) {
1661 #if defined(ENABLE_VERIFIER)
1662 /* Check if this bytecode basic-block start at the
1663 beginning of a bytecode instruction. */
1665 if (pd.bytecodestart[bcindex] == 0) {
1666 exceptions_throw_verifyerror(m,
1667 "Branch into middle of instruction");
1672 /* Get the IR instruction mapped to the bytecode
1673 instruction and set the basic block flag. */
1675 irindex = pd.bytecodemap[bcindex];
1676 iptr = pd.instructions + irindex;
1678 iptr->flags.bits |= INS_FLAG_BASICBLOCK;
1682 /* IR instruction index to basic-block index mapping */
1684 pd.instructionmap = DMNEW(s4, ircount);
1685 MZERO(pd.instructionmap, s4, ircount);
1687 /* Iterate over all IR instructions and count the basic blocks. */
1689 iptr = pd.instructions;
1693 for (i = 0; i < ircount; i++, iptr++) {
1694 if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
1695 /* store the basic-block number in the IR instruction
1698 pd.instructionmap[i] = bbcount;
1700 /* post-increment the basic-block count */
1706 /* Allocate basic block array (one more for end ipc). */
1708 jd->basicblocks = DMNEW(basicblock, bbcount + 1);
1709 MZERO(jd->basicblocks, basicblock, bbcount + 1);
1711 /* Now iterate again over all IR instructions and initialize the
1712 basic block structures and, in the same loop, resolve the
1713 branch-target instruction indices to basic blocks. */
1715 iptr = pd.instructions;
1716 bptr = jd->basicblocks;
1720 for (i = 0; i < ircount; i++, iptr++) {
1721 /* check for basic block */
1723 if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
1724 /* intialize the basic block */
1726 BASICBLOCK_INIT(bptr, m);
1728 bptr->iinstr = iptr;
1731 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1734 /* bptr->icount is set when the next block is allocated */
1736 bptr->nr = bbcount++;
1738 bptr[-1].next = bptr;
1741 /* resolve instruction indices to basic blocks */
1743 switch (iptr->opc) {
1751 case JAVA_IFNONNULL:
1752 case JAVA_IF_ICMPEQ:
1753 case JAVA_IF_ICMPNE:
1754 case JAVA_IF_ICMPLT:
1755 case JAVA_IF_ICMPGT:
1756 case JAVA_IF_ICMPLE:
1757 case JAVA_IF_ICMPGE:
1758 case JAVA_IF_ACMPEQ:
1759 case JAVA_IF_ACMPNE:
1761 BYTECODEINDEX_TO_BASICBLOCK(iptr->dst);
1765 BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.jsrtarget);
1768 case ICMD_TABLESWITCH:
1769 table = iptr->dst.table;
1771 BYTECODEINDEX_TO_BASICBLOCK(*table);
1774 j = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
1777 BYTECODEINDEX_TO_BASICBLOCK(*table);
1782 case ICMD_LOOKUPSWITCH:
1783 BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.lookupdefault);
1785 lookup = iptr->dst.lookup;
1787 j = iptr->sx.s23.s2.lookupcount;
1790 BYTECODEINDEX_TO_BASICBLOCK(lookup->target);
1797 /* set instruction count of last real block */
1800 bptr[-1].icount = (pd.instructions + ircount) - bptr[-1].iinstr;
1803 /* allocate additional block at end */
1805 BASICBLOCK_INIT(bptr, m);
1808 /* set basicblock pointers in exception table */
1810 if (!parse_resolve_exception_table(jd, &pd))
1813 /* store the local map */
1815 jd->local_map = local_map;
1817 /* calculate local variable renaming */
1826 /* iterate over local_map[0..m->maxlocals*5-1] and allocate a unique */
1827 /* variable index for each _used_ (javaindex,type) pair. */
1828 /* (local_map[javaindex*5+type] = cacaoindex) */
1829 /* Unused (javaindex,type) pairs are marked with UNUSED. */
1831 for (i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
1833 *mapptr = nlocals++;
1838 jd->localcount = nlocals;
1840 /* calculate the (maximum) number of variables needed */
1843 nlocals /* local variables */
1844 + bbcount * m->maxstack /* invars */
1845 + s_count; /* variables created within blocks (non-invar) */
1847 /* reserve the first indices for local variables */
1849 jd->vartop = nlocals;
1851 /* reserve extra variables needed by stack analyse */
1853 jd->varcount += STACK_EXTRA_VARS;
1854 jd->vartop += STACK_EXTRA_VARS;
1856 /* The verifier needs space for saving invars in some cases and */
1857 /* extra variables. */
1859 #if defined(ENABLE_VERIFIER)
1860 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1861 jd->vartop += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1863 /* allocate and initialize the variable array */
1865 jd->var = DMNEW(varinfo, jd->varcount);
1866 MZERO(jd->var, varinfo, jd->varcount);
1868 /* set types of all locals in jd->var */
1870 for (mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
1871 if (*mapptr != UNUSED)
1872 VAR(*mapptr)->type = i%5;
1875 /* assign local variables to method variables */
1877 jd->instructions = pd.instructions;
1878 jd->instructioncount = ircount;
1879 jd->basicblockcount = bbcount;
1880 jd->stackcount = s_count + bbcount * m->maxstack; /* in-stacks */
1882 /* allocate stack table */
1884 jd->stack = DMNEW(stackelement, jd->stackcount);
1886 /* everything's ok */
1890 /*** goto labels for throwing verifier exceptions *************************/
1892 #if defined(ENABLE_VERIFIER)
1894 throw_unexpected_end_of_bytecode:
1895 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1898 throw_invalid_bytecode_index:
1899 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1902 throw_illegal_local_variable_number:
1903 exceptions_throw_verifyerror(m, "Illegal local variable number");
1906 #endif /* ENABLE_VERIFIER */
1911 * These are local overrides for various environment variables in Emacs.
1912 * Please do not remove this and leave it at the end of the file, where
1913 * Emacs will automagically detect them.
1914 * ---------------------------------------------------------------------
1917 * indent-tabs-mode: t
1921 * vim:noexpandtab:sw=4:ts=4: