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 7813 2007-04-25 19:20:13Z twisti $
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/patcher.h"
54 #include "vm/jit/loop/loop.h"
56 #include "vmcore/linker.h"
57 #include "vmcore/loader.h"
58 #include "vmcore/options.h"
59 #include "vm/resolve.h"
61 #if defined(ENABLE_STATISTICS)
62 # include "vmcore/statistics.h"
65 #include "vmcore/suck.h"
67 #define INSTRUCTIONS_INCREMENT 5 /* number of additional instructions to */
68 /* allocate if space runs out */
71 /* local macros ***************************************************************/
73 #define BYTECODEINDEX_TO_BASICBLOCK(dst) \
76 parse_bytecodeindex_to_basicblock(jd, &pd, (dst).insindex); \
80 /* parserdata_t ***************************************************************/
82 typedef struct parsedata_t parsedata_t;
85 u1 *bytecodestart; /* start of bytecode instructions */
86 u1 *basicblockstart; /* start of bytecode basic-blocks */
88 s4 *bytecodemap; /* bytecode to IR mapping */
90 instruction *instructions; /* instruction array */
91 s4 instructionslength; /* length of the instruction array */
93 s4 *instructionmap; /* IR to basic-block mapping */
97 /* parse_setup *****************************************************************
99 Fills the passed parsedata_t structure.
101 *******************************************************************************/
103 static void parse_setup(jitdata *jd, parsedata_t *pd)
107 /* get required compiler data */
111 /* bytecode start array */
113 pd->bytecodestart = DMNEW(u1, m->jcodelength + 1);
114 MZERO(pd->bytecodestart, u1, m->jcodelength + 1);
116 /* bytecode basic-block start array */
118 pd->basicblockstart = DMNEW(u1, m->jcodelength + 1);
119 MZERO(pd->basicblockstart, u1, m->jcodelength + 1);
121 /* bytecode instruction index to IR instruction mapping */
123 pd->bytecodemap = DMNEW(s4, m->jcodelength + 1);
124 MSET(pd->bytecodemap, -1, s4, m->jcodelength + 1);
126 /* allocate the instruction array */
128 pd->instructionslength = m->jcodelength + 1;
129 pd->instructions = DMNEW(instruction, pd->instructionslength);
131 /* Zero the intermediate instructions array so we don't have any
132 invalid pointers in it if we cannot finish stack_analyse(). */
134 MZERO(pd->instructions, instruction, pd->instructionslength);
136 /* The instructionmap is allocated later when we know the count of
139 pd->instructionmap = NULL;
143 /* parse_realloc_instructions **************************************************
145 Reallocate the instructions array so there is room for at least N
146 additional instructions.
149 the new value for iptr
151 *******************************************************************************/
153 static instruction *parse_realloc_instructions(parsedata_t *pd, s4 icount, s4 n)
155 /* increase the size of the instruction array */
157 pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
159 /* reallocate the array */
161 pd->instructions = DMREALLOC(pd->instructions, instruction, icount,
162 pd->instructionslength);
163 MZERO(pd->instructions + icount, instruction,
164 (pd->instructionslength - icount));
166 /* return the iptr */
168 return pd->instructions + icount;
172 /* parse_bytecodeindex_to_basicblock *******************************************
174 Resolves a bytecode index to the corresponding basic block.
176 *******************************************************************************/
178 static basicblock *parse_bytecodeindex_to_basicblock(jitdata *jd,
185 irindex = pd->bytecodemap[bcindex];
186 bb = jd->basicblocks + pd->instructionmap[irindex];
192 /* parse_mark_exception_boundaries *********************************************
194 Mark exception handlers and the boundaries of the handled regions as
195 basic block boundaries.
198 jd...............current jitdata
201 true.............everything ok
202 false............an exception has been thrown
204 *******************************************************************************/
206 static bool parse_mark_exception_boundaries(jitdata *jd, parsedata_t *pd)
211 raw_exception_entry *rex;
216 len = m->rawexceptiontablelength;
221 rex = m->rawexceptiontable;
223 for (i = 0; i < len; ++i, ++rex) {
225 /* the start of the handled region becomes a basic block start */
227 bcindex = rex->startpc;
228 CHECK_BYTECODE_INDEX(bcindex);
229 MARK_BASICBLOCK(pd, bcindex);
231 bcindex = rex->endpc; /* see JVM Spec 4.7.3 */
232 CHECK_BYTECODE_INDEX_EXCLUSIVE(bcindex);
234 /* check that the range is valid */
236 #if defined(ENABLE_VERIFIER)
237 if (bcindex <= rex->startpc) {
238 exceptions_throw_verifyerror(m, "Invalid exception handler range");
243 /* End of handled region becomes a basic block boundary (if it
244 is the bytecode end, we'll use the special end block that
245 is created anyway). */
247 if (bcindex < m->jcodelength)
248 MARK_BASICBLOCK(pd, bcindex);
250 jd->branchtoend = true;
252 /* the start of the handler becomes a basic block start */
254 bcindex = rex->handlerpc;
255 CHECK_BYTECODE_INDEX(bcindex);
256 MARK_BASICBLOCK(pd, bcindex);
263 #if defined(ENABLE_VERIFIER)
264 throw_invalid_bytecode_index:
265 exceptions_throw_verifyerror(m,
266 "Illegal bytecode index in exception table");
272 /* parse_resolve_exception_table ***********************************************
274 Enter the exception handlers and their ranges, resolved to basicblock *s,
278 jd...............current jitdata
281 true.............everything ok
282 false............an exception has been thrown
284 *******************************************************************************/
286 static bool parse_resolve_exception_table(jitdata *jd, parsedata_t *pd)
289 raw_exception_entry *rex;
297 len = m->rawexceptiontablelength;
299 /* common case: no handler entries */
304 /* allocate the exception table */
306 jd->exceptiontablelength = len;
307 jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
309 /* copy and resolve the entries */
311 ex = jd->exceptiontable;
312 rex = m->rawexceptiontable;
314 for (i = 0; i < len; ++i, ++rex, ++ex) {
315 /* resolve instruction indices to basic blocks */
317 ex->start = parse_bytecodeindex_to_basicblock(jd, pd, rex->startpc);
318 ex->end = parse_bytecodeindex_to_basicblock(jd, pd, rex->endpc);
319 ex->handler = parse_bytecodeindex_to_basicblock(jd, pd, rex->handlerpc);
321 /* lazily resolve the catchtype */
323 if (rex->catchtype.any != NULL) {
324 if (!resolve_classref_or_classinfo(m,
326 resolveLazy, true, false,
330 /* if resolved, enter the result of resolution in the table */
333 rex->catchtype.cls = exclass;
336 ex->catchtype = rex->catchtype;
337 ex->next = NULL; /* set by loop analysis */
338 ex->down = ex + 1; /* link to next exception entry */
341 /* terminate the ->down linked list */
343 assert(ex != jd->exceptiontable);
350 /*******************************************************************************
352 function 'parse' scans the JavaVM code and generates intermediate code
354 During parsing the block index table is used to store at bit pos 0
355 a flag which marks basic block starts and at position 1 to 31 the
356 intermediate instruction index. After parsing the block index table
357 is scanned, for marked positions a block is generated and the block
358 number is stored in the block index table.
360 *******************************************************************************/
362 /*** macro for checking the length of the bytecode ***/
364 #if defined(ENABLE_VERIFIER)
365 #define CHECK_END_OF_BYTECODE(neededlength) \
367 if ((neededlength) > m->jcodelength) \
368 goto throw_unexpected_end_of_bytecode; \
370 #else /* !ENABLE_VERIFIER */
371 #define CHECK_END_OF_BYTECODE(neededlength)
372 #endif /* ENABLE_VERIFIER */
374 bool parse(jitdata *jd)
376 methodinfo *m; /* method being parsed */
378 instruction *iptr; /* current ptr into instruction array */
380 s4 bcindex; /* bytecode instruction index */
381 s4 nextbc; /* start of next bytecode instruction */
382 s4 opcode; /* bytecode instruction opcode */
384 s4 irindex; /* IR instruction index */
385 s4 ircount; /* IR instruction count */
387 s4 bbcount; /* basic block count */
389 int s_count = 0; /* stack element counter */
390 bool blockend; /* true if basic block end has been reached */
391 bool iswide; /* true if last instruction was a wide */
393 constant_classref *cr;
394 constant_classref *compr;
396 builtintable_entry *bte;
397 constant_FMIref *fmi;
399 unresolved_method *um;
400 unresolved_field *uf;
402 resolve_result_t result;
409 int *local_map; /* local pointer to renaming map */
410 /* is assigned to rd->local_map at the end */
411 branch_target_t *table;
412 lookup_target_t *lookup;
416 /* get required compiler data */
420 /* allocate buffers for local variable renaming */
422 local_map = DMNEW(int, m->maxlocals * 5);
424 for (i = 0; i < m->maxlocals; i++) {
425 local_map[i * 5 + 0] = 0;
426 local_map[i * 5 + 1] = 0;
427 local_map[i * 5 + 2] = 0;
428 local_map[i * 5 + 3] = 0;
429 local_map[i * 5 + 4] = 0;
432 /* initialize the parse data structures */
434 parse_setup(jd, &pd);
436 /* initialize local variables */
438 iptr = pd.instructions;
444 /* mark basic block boundaries for exception table */
446 if (!parse_mark_exception_boundaries(jd, &pd))
449 /* initialize stack element counter */
451 s_count = 1 + m->rawexceptiontablelength;
453 /* setup line number info */
458 if (m->linenumbercount == 0) {
462 linepcchange = m->linenumbers[0].start_pc;
465 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
467 for (bcindex = 0; bcindex < m->jcodelength; bcindex = nextbc) {
469 /* mark this position as a valid bytecode instruction start */
471 pd.bytecodestart[bcindex] = 1;
473 /* change the current line number, if necessary */
475 /* XXX rewrite this using pointer arithmetic */
477 if (linepcchange == bcindex) {
478 if (m->linenumbercount > lineindex) {
480 currentline = m->linenumbers[lineindex].line_number;
482 if (lineindex < m->linenumbercount) {
483 linepcchange = m->linenumbers[lineindex].start_pc;
484 if (linepcchange == bcindex)
485 goto next_linenumber;
491 /* fetch next opcode */
493 opcode = SUCK_BE_U1(m->jcode + bcindex);
495 /* If the previous instruction was a block-end instruction,
496 mark the current bytecode instruction as basic-block
497 starting instruction. */
499 /* NOTE: Some compilers put a JAVA_NOP after a blockend
502 if (blockend && (opcode != JAVA_NOP)) {
503 MARK_BASICBLOCK(&pd, bcindex);
507 /* If the current bytecode instruction was marked as
508 basic-block starting instruction before (e.g. blockend,
509 forward-branch target), mark the current IR instruction
512 if (pd.basicblockstart[bcindex] != 0) {
513 /* We need a NOP as last instruction in each basic block
514 for basic block reordering (may be replaced with a GOTO
517 INSTRUCTIONS_CHECK(1);
521 /* store intermediate instruction count (bit 0 mark block starts) */
523 pd.bytecodemap[bcindex] = ircount;
525 /* compute next instruction start */
527 nextbc = bcindex + jcommandsize[opcode];
529 CHECK_END_OF_BYTECODE(nextbc);
531 /* add stack elements produced by this instruction */
533 s_count += stackreq[opcode];
535 /* We check here for the space of 1 instruction in the
536 instruction array. If an opcode is converted to more than
537 1 instruction, this is checked in the corresponding
540 INSTRUCTIONS_CHECK(1);
542 /* translate this bytecode instruction */
548 /* pushing constants onto the stack ***********************************/
551 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + bcindex + 1));
555 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + bcindex + 1));
559 i = SUCK_BE_U1(m->jcode + bcindex + 1);
560 goto pushconstantitem;
564 i = SUCK_BE_U2(m->jcode + bcindex + 1);
568 #if defined(ENABLE_VERIFIER)
569 if (i >= m->class->cpcount) {
570 exceptions_throw_verifyerror(m,
571 "Attempt to access constant outside range");
576 switch (m->class->cptags[i]) {
577 case CONSTANT_Integer:
578 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
581 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
584 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
586 case CONSTANT_Double:
587 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
589 case CONSTANT_String:
590 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
593 cr = (constant_classref *) (m->class->cpinfos[i]);
595 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
598 /* if not resolved, c == NULL */
600 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
604 #if defined(ENABLE_VERIFIER)
606 exceptions_throw_verifyerror(m,
607 "Invalid constant type to push");
613 case JAVA_ACONST_NULL:
624 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
629 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
635 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
640 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
643 /* stack operations ***************************************************/
645 /* We need space for additional ICMDs so we can translate these */
646 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
649 INSTRUCTIONS_CHECK(4);
657 INSTRUCTIONS_CHECK(6);
667 INSTRUCTIONS_CHECK(2);
673 INSTRUCTIONS_CHECK(7);
684 INSTRUCTIONS_CHECK(9);
697 INSTRUCTIONS_CHECK(3);
703 /* local variable access instructions *********************************/
708 if (iswide == false) {
709 i = SUCK_BE_U1(m->jcode + bcindex + 1);
712 i = SUCK_BE_U2(m->jcode + bcindex + 1);
713 nextbc = bcindex + 3;
716 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
721 if (iswide == false) {
722 i = SUCK_BE_U1(m->jcode + bcindex + 1);
725 i = SUCK_BE_U2(m->jcode + bcindex + 1);
726 nextbc = bcindex + 3;
729 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
736 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
743 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
750 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
757 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
764 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
770 if (iswide == false) {
771 i = SUCK_BE_U1(m->jcode + bcindex + 1);
774 i = SUCK_BE_U2(m->jcode + bcindex + 1);
775 nextbc = bcindex + 3;
778 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
783 if (iswide == false) {
784 i = SUCK_BE_U1(m->jcode + bcindex + 1);
787 i = SUCK_BE_U2(m->jcode + bcindex + 1);
788 nextbc = bcindex + 3;
791 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
798 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
805 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
812 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
819 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
826 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
833 if (iswide == false) {
834 i = SUCK_BE_U1(m->jcode + bcindex + 1);
835 v = SUCK_BE_S1(m->jcode + bcindex + 2);
839 i = SUCK_BE_U2(m->jcode + bcindex + 1);
840 v = SUCK_BE_S2(m->jcode + bcindex + 3);
841 nextbc = bcindex + 5;
845 LOCALTYPE_USED(i, TYPE_INT);
846 OP_LOCALINDEX_I(opcode, i, v);
850 /* wider index for loading, storing and incrementing ******************/
857 /* managing arrays ****************************************************/
860 switch (SUCK_BE_S1(m->jcode + bcindex + 1)) {
862 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
865 bte = builtintable_get_internal(BUILTIN_newarray_char);
868 bte = builtintable_get_internal(BUILTIN_newarray_float);
871 bte = builtintable_get_internal(BUILTIN_newarray_double);
874 bte = builtintable_get_internal(BUILTIN_newarray_byte);
877 bte = builtintable_get_internal(BUILTIN_newarray_short);
880 bte = builtintable_get_internal(BUILTIN_newarray_int);
883 bte = builtintable_get_internal(BUILTIN_newarray_long);
885 #if defined(ENABLE_VERIFIER)
887 exceptions_throw_verifyerror(m, "Invalid array-type to create");
891 OP_BUILTIN_CHECK_EXCEPTION(bte);
895 i = SUCK_BE_U2(m->jcode + bcindex + 1);
896 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
900 if (!(cr = class_get_classref_multiarray_of(1, compr)))
903 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
906 INSTRUCTIONS_CHECK(2);
907 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
908 bte = builtintable_get_internal(BUILTIN_newarray);
909 OP_BUILTIN_CHECK_EXCEPTION(bte);
913 case JAVA_MULTIANEWARRAY:
914 jd->isleafmethod = false;
915 i = SUCK_BE_U2(m->jcode + bcindex + 1);
916 j = SUCK_BE_U1(m->jcode + bcindex + 3);
918 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
922 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
925 /* if unresolved, c == NULL */
927 iptr->s1.argcount = j;
928 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, INS_FLAG_CHECK);
931 /* control flow instructions ******************************************/
950 i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
951 CHECK_BYTECODE_INDEX(i);
952 MARK_BASICBLOCK(&pd, i);
954 OP_INSINDEX(opcode, i);
958 i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
959 CHECK_BYTECODE_INDEX(i);
960 MARK_BASICBLOCK(&pd, i);
962 OP_INSINDEX(ICMD_GOTO, i);
966 i = bcindex + SUCK_BE_S2(m->jcode + bcindex + 1);
968 CHECK_BYTECODE_INDEX(i);
969 MARK_BASICBLOCK(&pd, i);
971 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
972 iptr->sx.s23.s3.jsrtarget.insindex = i;
977 i = bcindex + SUCK_BE_S4(m->jcode + bcindex + 1);
981 if (iswide == false) {
982 i = SUCK_BE_U1(m->jcode + bcindex + 1);
985 i = SUCK_BE_U2(m->jcode + bcindex + 1);
986 nextbc = bcindex + 3;
991 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
1001 /* XXX ARETURN will need a flag in the typechecker */
1007 /* XXX ATHROW will need a flag in the typechecker */
1012 /* table jumps ********************************************************/
1014 case JAVA_LOOKUPSWITCH:
1017 lookup_target_t *lookup;
1018 #if defined(ENABLE_VERIFIER)
1022 nextbc = MEMORY_ALIGN((bcindex + 1), 4);
1024 CHECK_END_OF_BYTECODE(nextbc + 8);
1026 OP_PREPARE_ZEROFLAGS(opcode);
1028 /* default target */
1030 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1031 iptr->sx.s23.s3.lookupdefault.insindex = j;
1033 CHECK_BYTECODE_INDEX(j);
1034 MARK_BASICBLOCK(&pd, j);
1036 /* number of pairs */
1038 num = SUCK_BE_U4(m->jcode + nextbc);
1039 iptr->sx.s23.s2.lookupcount = num;
1042 /* allocate the intermediate code table */
1044 lookup = DMNEW(lookup_target_t, num);
1045 iptr->dst.lookup = lookup;
1047 /* iterate over the lookup table */
1049 CHECK_END_OF_BYTECODE(nextbc + 8 * num);
1051 for (i = 0; i < num; i++) {
1054 j = SUCK_BE_S4(m->jcode + nextbc);
1059 #if defined(ENABLE_VERIFIER)
1060 /* check if the lookup table is sorted correctly */
1062 if (i && (j <= prevvalue)) {
1063 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
1070 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1071 lookup->target.insindex = j;
1074 CHECK_BYTECODE_INDEX(j);
1075 MARK_BASICBLOCK(&pd, j);
1083 case JAVA_TABLESWITCH:
1087 branch_target_t *table;
1090 nextbc = MEMORY_ALIGN((bcindex + 1), 4);
1092 CHECK_END_OF_BYTECODE(nextbc + 12);
1094 OP_PREPARE_ZEROFLAGS(opcode);
1096 /* default target */
1098 deftarget = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1100 CHECK_BYTECODE_INDEX(deftarget);
1101 MARK_BASICBLOCK(&pd, deftarget);
1105 j = SUCK_BE_S4(m->jcode + nextbc);
1106 iptr->sx.s23.s2.tablelow = j;
1111 num = SUCK_BE_S4(m->jcode + nextbc);
1112 iptr->sx.s23.s3.tablehigh = num;
1115 /* calculate the number of table entries */
1119 #if defined(ENABLE_VERIFIER)
1121 exceptions_throw_verifyerror(m,
1122 "invalid TABLESWITCH: upper bound < lower bound");
1126 /* create the intermediate code table */
1127 /* the first entry is the default target */
1129 table = DMNEW(branch_target_t, 1 + num);
1130 iptr->dst.table = table;
1131 (table++)->insindex = deftarget;
1133 /* iterate over the target table */
1135 CHECK_END_OF_BYTECODE(nextbc + 4 * num);
1137 for (i = 0; i < num; i++) {
1138 j = bcindex + SUCK_BE_S4(m->jcode + nextbc);
1139 (table++)->insindex = j;
1141 CHECK_BYTECODE_INDEX(j);
1142 MARK_BASICBLOCK(&pd, j);
1150 /* load and store of object fields ************************************/
1154 jd->isleafmethod = false;
1157 case JAVA_GETSTATIC:
1158 case JAVA_PUTSTATIC:
1161 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1162 fmi = class_getconstant(m->class, i, CONSTANT_Fieldref);
1167 OP_PREPARE_ZEROFLAGS(opcode);
1168 iptr->sx.s23.s3.fmiref = fmi;
1170 /* only with -noverify, otherwise the typechecker does this */
1172 #if defined(ENABLE_VERIFIER)
1173 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1175 result = resolve_field_lazy(m, fmi);
1177 if (result == resolveFailed)
1180 if (result != resolveSucceeded) {
1181 uf = resolve_create_unresolved_field(m->class, m, iptr);
1186 /* store the unresolved_field pointer */
1188 iptr->sx.s23.s3.uf = uf;
1189 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1191 #if defined(ENABLE_VERIFIER)
1198 /* method invocation **************************************************/
1200 case JAVA_INVOKESTATIC:
1201 OP_PREPARE_ZEROFLAGS(opcode);
1203 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1204 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1209 md = fmi->parseddesc.md;
1211 if (md->params == NULL)
1212 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1217 case JAVA_INVOKESPECIAL:
1218 OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
1220 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1221 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1223 goto invoke_nonstatic_method;
1225 case JAVA_INVOKEINTERFACE:
1226 OP_PREPARE_ZEROFLAGS(opcode);
1228 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1229 fmi = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1231 goto invoke_nonstatic_method;
1233 case JAVA_INVOKEVIRTUAL:
1234 OP_PREPARE_ZEROFLAGS(opcode);
1236 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1237 fmi = class_getconstant(m->class, i, CONSTANT_Methodref);
1239 invoke_nonstatic_method:
1243 md = fmi->parseddesc.md;
1245 if (md->params == NULL)
1246 if (!descriptor_params_from_paramtypes(md, 0))
1250 jd->isleafmethod = false;
1252 iptr->sx.s23.s3.fmiref = fmi;
1254 /* only with -noverify, otherwise the typechecker does this */
1256 #if defined(ENABLE_VERIFIER)
1257 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1259 result = resolve_method_lazy(m, fmi,
1260 (opcode == JAVA_INVOKESPECIAL));
1262 if (result == resolveFailed)
1265 if (result == resolveSucceeded) {
1266 methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1268 /* if this call is monomorphic, turn it into an
1271 assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1273 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1274 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1276 iptr->opc = ICMD_INVOKESPECIAL;
1277 iptr->flags.bits |= INS_FLAG_CHECK;
1281 um = resolve_create_unresolved_method(m->class, m, fmi,
1282 (opcode == JAVA_INVOKESTATIC),
1283 (opcode == JAVA_INVOKESPECIAL));
1288 /* store the unresolved_method pointer */
1290 iptr->sx.s23.s3.um = um;
1291 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1293 #if defined(ENABLE_VERIFIER)
1299 /* instructions taking class arguments ********************************/
1302 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1303 cr = class_getconstant(m->class, i, CONSTANT_Class);
1308 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1311 INSTRUCTIONS_CHECK(2);
1312 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1313 bte = builtintable_get_internal(BUILTIN_new);
1314 OP_BUILTIN_CHECK_EXCEPTION(bte);
1318 case JAVA_CHECKCAST:
1319 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1320 cr = class_getconstant(m->class, i, CONSTANT_Class);
1325 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1328 if (cr->name->text[0] == '[') {
1329 /* array type cast-check */
1330 flags = INS_FLAG_CHECK | INS_FLAG_ARRAY;
1331 jd->isleafmethod = false;
1334 /* object type cast-check */
1335 flags = INS_FLAG_CHECK;
1337 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1340 case JAVA_INSTANCEOF:
1341 i = SUCK_BE_U2(m->jcode + bcindex + 1);
1342 cr = class_getconstant(m->class, i, CONSTANT_Class);
1347 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1350 if (cr->name->text[0] == '[') {
1351 /* array type cast-check */
1352 INSTRUCTIONS_CHECK(2);
1353 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1354 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1355 OP_BUILTIN_NO_EXCEPTION(bte);
1359 /* object type cast-check */
1360 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1364 /* synchronization instructions ***************************************/
1366 case JAVA_MONITORENTER:
1367 #if defined(ENABLE_THREADS)
1369 bte = builtintable_get_internal(LOCK_monitor_enter);
1370 OP_BUILTIN_CHECK_EXCEPTION(bte);
1375 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1380 case JAVA_MONITOREXIT:
1381 #if defined(ENABLE_THREADS)
1383 bte = builtintable_get_internal(LOCK_monitor_exit);
1384 OP_BUILTIN_CHECK_EXCEPTION(bte);
1389 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1394 /* arithmetic instructions that may become builtin functions **********/
1397 #if !SUPPORT_DIVISION
1398 bte = builtintable_get_internal(BUILTIN_idiv);
1399 OP_BUILTIN_ARITHMETIC(opcode, bte);
1401 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1404 OP_CHECK_EXCEPTION(opcode);
1410 #if !SUPPORT_DIVISION
1411 bte = builtintable_get_internal(BUILTIN_irem);
1412 OP_BUILTIN_ARITHMETIC(opcode, bte);
1414 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1417 OP_CHECK_EXCEPTION(opcode);
1423 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1424 bte = builtintable_get_internal(BUILTIN_ldiv);
1425 OP_BUILTIN_ARITHMETIC(opcode, bte);
1427 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1430 OP_CHECK_EXCEPTION(opcode);
1436 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1437 bte = builtintable_get_internal(BUILTIN_lrem);
1438 OP_BUILTIN_ARITHMETIC(opcode, bte);
1440 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1443 OP_CHECK_EXCEPTION(opcode);
1449 #if defined(__I386__)
1452 bte = builtintable_get_internal(BUILTIN_frem);
1453 OP_BUILTIN_NO_EXCEPTION(bte);
1458 #if defined(__I386__)
1461 bte = builtintable_get_internal(BUILTIN_drem);
1462 OP_BUILTIN_NO_EXCEPTION(bte);
1467 #if defined(__ALPHA__)
1469 bte = builtintable_get_internal(BUILTIN_f2i);
1470 OP_BUILTIN_NO_EXCEPTION(bte);
1480 #if defined(__ALPHA__)
1482 bte = builtintable_get_internal(BUILTIN_f2l);
1483 OP_BUILTIN_NO_EXCEPTION(bte);
1493 #if defined(__ALPHA__)
1495 bte = builtintable_get_internal(BUILTIN_d2i);
1496 OP_BUILTIN_NO_EXCEPTION(bte);
1506 #if defined(__ALPHA__)
1508 bte = builtintable_get_internal(BUILTIN_d2l);
1509 OP_BUILTIN_NO_EXCEPTION(bte);
1518 /* invalid opcodes ****************************************************/
1520 /* check for invalid opcodes if the verifier is enabled */
1521 #if defined(ENABLE_VERIFIER)
1522 case JAVA_BREAKPOINT:
1523 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1526 case 186: /* unused opcode */
1580 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1584 #endif /* defined(ENABLE_VERIFIER) */
1586 /* opcodes that don't require translation *****************************/
1589 /* straight-forward translation to ICMD */
1595 /* verifier checks ****************************************************/
1597 #if defined(ENABLE_VERIFIER)
1598 /* If WIDE was used correctly, iswide should have been reset by now. */
1600 exceptions_throw_verifyerror(m,
1601 "Illegal instruction: WIDE before incompatible opcode");
1604 #endif /* defined(ENABLE_VERIFIER) */
1608 if (JITDATA_HAS_FLAG_REORDER(jd)) {
1609 /* add a NOP to the last basic block */
1611 INSTRUCTIONS_CHECK(1);
1615 /*** END OF LOOP **********************************************************/
1617 /* assert that we did not write more ICMDs than allocated */
1619 assert(ircount <= pd.instructionslength);
1620 assert(ircount == (iptr - pd.instructions));
1622 /*** verifier checks ******************************************************/
1624 #if defined(ENABLE_VERIFIER)
1625 if (bcindex != m->jcodelength) {
1626 exceptions_throw_verifyerror(m,
1627 "Command-sequence crosses code-boundary");
1632 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1635 #endif /* defined(ENABLE_VERIFIER) */
1637 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1639 /* identify basic blocks */
1641 /* check if first instruction is a branch target */
1643 if (pd.basicblockstart[0] == 1) {
1644 jd->branchtoentry = true;
1647 /* first instruction always starts a basic block */
1649 iptr = pd.instructions;
1651 iptr->flags.bits |= INS_FLAG_BASICBLOCK;
1654 /* Iterate over all bytecode instructions and set missing
1655 basic-block starts in IR instructions. */
1657 for (bcindex = 0; bcindex < m->jcodelength; bcindex++) {
1658 /* Does the current bytecode instruction start a basic
1661 if (pd.basicblockstart[bcindex] == 1) {
1662 #if defined(ENABLE_VERIFIER)
1663 /* Check if this bytecode basic-block start at the
1664 beginning of a bytecode instruction. */
1666 if (pd.bytecodestart[bcindex] == 0) {
1667 exceptions_throw_verifyerror(m,
1668 "Branch into middle of instruction");
1673 /* Get the IR instruction mapped to the bytecode
1674 instruction and set the basic block flag. */
1676 irindex = pd.bytecodemap[bcindex];
1677 iptr = pd.instructions + irindex;
1679 iptr->flags.bits |= INS_FLAG_BASICBLOCK;
1683 /* IR instruction index to basic-block index mapping */
1685 pd.instructionmap = DMNEW(s4, ircount);
1686 MZERO(pd.instructionmap, s4, ircount);
1688 /* Iterate over all IR instructions and count the basic blocks. */
1690 iptr = pd.instructions;
1694 for (i = 0; i < ircount; i++, iptr++) {
1695 if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
1696 /* store the basic-block number in the IR instruction
1699 pd.instructionmap[i] = bbcount;
1701 /* post-increment the basic-block count */
1707 /* Allocate basic block array (one more for end ipc). */
1709 jd->basicblocks = DMNEW(basicblock, bbcount + 1);
1710 MZERO(jd->basicblocks, basicblock, bbcount + 1);
1712 /* Now iterate again over all IR instructions and initialize the
1713 basic block structures and, in the same loop, resolve the
1714 branch-target instruction indices to basic blocks. */
1716 iptr = pd.instructions;
1717 bptr = jd->basicblocks;
1721 for (i = 0; i < ircount; i++, iptr++) {
1722 /* check for basic block */
1724 if (INSTRUCTION_STARTS_BASICBLOCK(iptr)) {
1725 /* intialize the basic block */
1727 BASICBLOCK_INIT(bptr, m);
1729 bptr->iinstr = iptr;
1732 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1735 /* bptr->icount is set when the next block is allocated */
1737 bptr->nr = bbcount++;
1739 bptr[-1].next = bptr;
1742 /* resolve instruction indices to basic blocks */
1744 switch (iptr->opc) {
1752 case JAVA_IFNONNULL:
1753 case JAVA_IF_ICMPEQ:
1754 case JAVA_IF_ICMPNE:
1755 case JAVA_IF_ICMPLT:
1756 case JAVA_IF_ICMPGT:
1757 case JAVA_IF_ICMPLE:
1758 case JAVA_IF_ICMPGE:
1759 case JAVA_IF_ACMPEQ:
1760 case JAVA_IF_ACMPNE:
1762 BYTECODEINDEX_TO_BASICBLOCK(iptr->dst);
1766 BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.jsrtarget);
1769 case ICMD_TABLESWITCH:
1770 table = iptr->dst.table;
1772 BYTECODEINDEX_TO_BASICBLOCK(*table);
1775 j = iptr->sx.s23.s3.tablehigh - iptr->sx.s23.s2.tablelow + 1;
1778 BYTECODEINDEX_TO_BASICBLOCK(*table);
1783 case ICMD_LOOKUPSWITCH:
1784 BYTECODEINDEX_TO_BASICBLOCK(iptr->sx.s23.s3.lookupdefault);
1786 lookup = iptr->dst.lookup;
1788 j = iptr->sx.s23.s2.lookupcount;
1791 BYTECODEINDEX_TO_BASICBLOCK(lookup->target);
1798 /* set instruction count of last real block */
1801 bptr[-1].icount = (pd.instructions + ircount) - bptr[-1].iinstr;
1804 /* allocate additional block at end */
1806 BASICBLOCK_INIT(bptr, m);
1809 /* set basicblock pointers in exception table */
1811 if (!parse_resolve_exception_table(jd, &pd))
1814 /* store the local map */
1816 jd->local_map = local_map;
1818 /* calculate local variable renaming */
1827 /* iterate over local_map[0..m->maxlocals*5-1] and allocate a unique */
1828 /* variable index for each _used_ (javaindex,type) pair. */
1829 /* (local_map[javaindex*5+type] = cacaoindex) */
1830 /* Unused (javaindex,type) pairs are marked with UNUSED. */
1832 for (i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
1834 *mapptr = nlocals++;
1839 jd->localcount = nlocals;
1841 /* calculate the (maximum) number of variables needed */
1844 nlocals /* local variables */
1845 + bbcount * m->maxstack /* invars */
1846 + s_count; /* variables created within blocks (non-invar) */
1848 /* reserve the first indices for local variables */
1850 jd->vartop = nlocals;
1852 /* reserve extra variables needed by stack analyse */
1854 jd->varcount += STACK_EXTRA_VARS;
1855 jd->vartop += STACK_EXTRA_VARS;
1857 /* The verifier needs space for saving invars in some cases and */
1858 /* extra variables. */
1860 #if defined(ENABLE_VERIFIER)
1861 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1862 jd->vartop += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1864 /* allocate and initialize the variable array */
1866 jd->var = DMNEW(varinfo, jd->varcount);
1867 MZERO(jd->var, varinfo, jd->varcount);
1869 /* set types of all locals in jd->var */
1871 for (mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
1872 if (*mapptr != UNUSED)
1873 VAR(*mapptr)->type = i%5;
1876 /* assign local variables to method variables */
1878 jd->instructions = pd.instructions;
1879 jd->instructioncount = ircount;
1880 jd->basicblockcount = bbcount;
1881 jd->stackcount = s_count + bbcount * m->maxstack; /* in-stacks */
1883 /* allocate stack table */
1885 jd->stack = DMNEW(stackelement, jd->stackcount);
1887 /* everything's ok */
1891 /*** goto labels for throwing verifier exceptions *************************/
1893 #if defined(ENABLE_VERIFIER)
1895 throw_unexpected_end_of_bytecode:
1896 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1899 throw_invalid_bytecode_index:
1900 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1903 throw_illegal_local_variable_number:
1904 exceptions_throw_verifyerror(m, "Illegal local variable number");
1907 #endif /* ENABLE_VERIFIER */
1912 * These are local overrides for various environment variables in Emacs.
1913 * Please do not remove this and leave it at the end of the file, where
1914 * Emacs will automagically detect them.
1915 * ---------------------------------------------------------------------
1918 * indent-tabs-mode: t
1922 * vim:noexpandtab:sw=4:ts=4: