1 /* src/vm/jit/parse.c - parser for JavaVM to intermediate code translation
3 Copyright (C) 1996-2005, 2006 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 Contact: cacao@cacaojvm.org
29 Changes: Carolyn Oates
34 $Id: parse.c 5785 2006-10-15 22:25:54Z edwin $
46 #include "mm/memory.h"
47 #include "native/native.h"
49 #if defined(ENABLE_THREADS)
50 # include "threads/native/lock.h"
53 #include "toolbox/logging.h"
54 #include "vm/builtin.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/linker.h"
58 #include "vm/loader.h"
59 #include "vm/resolve.h"
60 #include "vm/options.h"
61 #include "vm/statistics.h"
62 #include "vm/stringlocal.h"
64 #include "vm/jit/asmpart.h"
65 #include "vm/jit/jit.h"
66 #include "vm/jit/parse.h"
67 #include "vm/jit/patcher.h"
68 #include "vm/jit/loop/loop.h"
70 #define INSTRUCTIONS_INCREMENT 5 /* number of additional instructions to */
71 /* allocate if space runs out */
74 /* parserdata_t ***************************************************************/
76 typedef struct parsedata_t parsedata_t;
79 instruction *instructions; /* instruction array */
80 s4 instructionslength; /* length of the instruction array */
85 /* parse_setup *****************************************************************
87 Fills the passed parsedata_t structure.
89 *******************************************************************************/
91 static void parse_setup(jitdata *jd, parsedata_t *pd)
95 /* get required compiler data */
99 /* Allocate instruction array and block index table (1 additional
102 jd->basicblockindex = DMNEW(s4, m->jcodelength + 1);
103 pd->instructionstart = DMNEW(u1, m->jcodelength + 1);
105 MZERO(jd->basicblockindex, s4, m->jcodelength + 1);
106 MZERO(pd->instructionstart, u1, m->jcodelength + 1);
108 /* Set the length of the instruction array. We simply add 5 more
109 instruction, as this seems to be a reasonable value. */
111 pd->instructionslength = m->jcodelength + 1;
113 /* allocate the instruction array */
115 pd->instructions = DMNEW(instruction, pd->instructionslength);
117 /* Zero the intermediate instructions array so we don't have any
118 invalid pointers in it if we cannot finish stack_analyse(). */
120 MZERO(pd->instructions, instruction, pd->instructionslength);
124 /* parse_realloc_instructions **************************************************
126 Reallocate the instructions array so there is room for at least N
127 additional instructions.
130 the new value for iptr
132 *******************************************************************************/
134 static instruction *parse_realloc_instructions(parsedata_t *pd, s4 ipc, s4 n)
136 /* increase the size of the instruction array */
138 pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
140 /* reallocate the array */
142 pd->instructions = DMREALLOC(pd->instructions, instruction, ipc,
143 pd->instructionslength);
145 /* return the iptr */
147 return pd->instructions + ipc;
151 /* parse_mark_exception_boundaries *********************************************
153 Mark exception handlers and the boundaries of the handled regions as
154 basic block boundaries.
157 jd...............current jitdata
160 >= 0.............the number of new basic blocks marked
161 -1...............an exception has been thrown
163 *******************************************************************************/
165 static int parse_mark_exception_boundaries(jitdata *jd)
171 raw_exception_entry *rex;
176 len = m->rawexceptiontablelength;
182 rex = m->rawexceptiontable;
184 for (i = 0; i < len; ++i, ++rex) {
186 /* the start of the handled region becomes a basic block start */
189 CHECK_BYTECODE_INDEX(pc);
192 pc = rex->endpc; /* see JVM Spec 4.7.3 */
193 CHECK_BYTECODE_INDEX_EXCLUSIVE(pc);
195 /* check that the range is valid */
197 #if defined(ENABLE_VERIFIER)
198 if (pc <= rex->startpc) {
199 exceptions_throw_verifyerror(m,
200 "Invalid exception handler range");
205 /* end of handled region becomes a basic block boundary */
206 /* (If it is the bytecode end, we'll use the special */
207 /* end block that is created anyway.) */
209 if (pc < m->jcodelength)
212 /* the start of the handler becomes a basic block start */
215 CHECK_BYTECODE_INDEX(pc);
223 #if defined(ENABLE_VERIFIER)
224 throw_invalid_bytecode_index:
225 exceptions_throw_verifyerror(m,
226 "Illegal bytecode index in exception table");
232 /* parse_resolve_exception_table ***********************************************
234 Enter the exception handlers and their ranges, resolved to basicblock *s,
238 jd...............current jitdata
241 true.............everything ok
242 false............an exception has been thrown
244 *******************************************************************************/
246 static bool parse_resolve_exception_table(jitdata *jd)
250 raw_exception_entry *rex;
259 len = m->rawexceptiontablelength;
261 /* common case: no handler entries */
266 /* allocate the exception table */
268 jd->exceptiontablelength = len;
269 jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
271 /* copy and resolve the entries */
273 ex = jd->exceptiontable;
274 rex = m->rawexceptiontable;
276 for (i = 0; i < len; ++i, ++rex, ++ex) {
277 /* resolve instruction indices to basic blocks */
279 ex->start = BLOCK_OF(rex->startpc);
280 ex->end = BLOCK_OF(rex->endpc);
281 ex->handler = BLOCK_OF(rex->handlerpc);
283 /* lazily resolve the catchtype */
285 if (rex->catchtype.any != NULL) {
286 if (!resolve_classref_or_classinfo(m,
288 resolveLazy, true, false,
292 /* if resolved, enter the result of resolution in the table */
295 rex->catchtype.cls = exclass;
298 ex->catchtype = rex->catchtype;
299 ex->next = NULL; /* set by loop analysis */
300 ex->down = ex + 1; /* link to next exception entry */
303 /* terminate the ->down linked list */
305 assert(ex != jd->exceptiontable);
312 /*******************************************************************************
314 function 'parse' scans the JavaVM code and generates intermediate code
316 During parsing the block index table is used to store at bit pos 0
317 a flag which marks basic block starts and at position 1 to 31 the
318 intermediate instruction index. After parsing the block index table
319 is scanned, for marked positions a block is generated and the block
320 number is stored in the block index table.
322 *******************************************************************************/
324 /*** macro for checking the length of the bytecode ***/
326 #if defined(ENABLE_VERIFIER)
327 #define CHECK_END_OF_BYTECODE(neededlength) \
329 if ((neededlength) > m->jcodelength) \
330 goto throw_unexpected_end_of_bytecode; \
332 #else /* !ENABLE_VERIFIER */
333 #define CHECK_END_OF_BYTECODE(neededlength)
334 #endif /* ENABLE_VERIFIER */
336 bool parse(jitdata *jd)
338 methodinfo *m; /* method being parsed */
342 instruction *iptr; /* current ptr into instruction array */
343 s4 ipc; /* intermediate instruction counter */
344 s4 p; /* java instruction counter */
345 s4 nextp; /* start of next java instruction */
346 s4 opcode; /* java opcode */
349 int b_count; /* basic block counter */
350 int s_count = 0; /* stack element counter */
351 bool blockend = false; /* true if basic block end has been reached */
352 bool iswide = false; /* true if last instruction was a wide */
353 constant_classref *cr;
354 constant_classref *compr;
356 builtintable_entry *bte;
359 unresolved_method *um;
360 resolve_result_t result;
367 int *local_map; /* local pointer to renaming structore */
368 /* is assigned to rd->local_map at the end */
369 /* get required compiler data */
375 /* allocate buffers for local variable renaming */
376 local_map = DMNEW(int, cd->maxlocals * 5);
377 for (i = 0; i < cd->maxlocals; i++) {
378 local_map[i * 5 + 0] = 0;
379 local_map[i * 5 + 1] = 0;
380 local_map[i * 5 + 2] = 0;
381 local_map[i * 5 + 3] = 0;
382 local_map[i * 5 + 4] = 0;
385 /* initialize the parse data structures */
387 parse_setup(jd, &pd);
389 /* initialize local variables */
391 iptr = pd.instructions;
394 /* mark basic block boundaries for exception table */
396 b_count = parse_mark_exception_boundaries(jd);
400 /* initialize stack element counter */
402 s_count = 1 + m->rawexceptiontablelength;
404 #if defined(ENABLE_THREADS)
405 if (checksync && (m->flags & ACC_SYNCHRONIZED))
406 jd->isleafmethod = false;
409 /* setup line number info */
414 if (m->linenumbercount == 0) {
418 linepcchange = m->linenumbers[0].start_pc;
421 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
423 for (p = 0; p < m->jcodelength; p = nextp) {
425 /* mark this position as a valid instruction start */
427 pd.instructionstart[p] = 1;
429 /* change the current line number, if necessary */
431 /* XXX rewrite this using pointer arithmetic */
433 if (linepcchange == p) {
434 if (m->linenumbercount > lineindex) {
436 currentline = m->linenumbers[lineindex].line_number;
438 if (lineindex < m->linenumbercount) {
439 linepcchange = m->linenumbers[lineindex].start_pc;
440 if (linepcchange == p)
441 goto next_linenumber;
447 /* fetch next opcode */
449 opcode = SUCK_BE_U1(m->jcode + p);
451 /* some compilers put a JAVA_NOP after a blockend instruction */
453 if (blockend && (opcode != JAVA_NOP)) {
454 /* start new block */
460 /* We need a NOP as last instruction in each basic block
461 for basic block reordering (may be replaced with a GOTO
464 if (jd->basicblockindex[p] & 1) {
465 INSTRUCTIONS_CHECK(1);
469 /* store intermediate instruction count (bit 0 mark block starts) */
471 jd->basicblockindex[p] |= (ipc << 1);
473 /* compute next instruction start */
475 nextp = p + jcommandsize[opcode];
477 CHECK_END_OF_BYTECODE(nextp);
479 /* add stack elements produced by this instruction */
481 s_count += stackreq[opcode];
483 /* We check here for the space of 1 instruction in the
484 instruction array. If an opcode is converted to more than
485 1 instruction, this is checked in the corresponding
488 INSTRUCTIONS_CHECK(1);
490 /* translate this bytecode instruction */
496 /* pushing constants onto the stack ***********************************/
499 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
503 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
507 i = SUCK_BE_U1(m->jcode + p + 1);
508 goto pushconstantitem;
512 i = SUCK_BE_U2(m->jcode + p + 1);
516 #if defined(ENABLE_VERIFIER)
517 if (i >= m->class->cpcount) {
518 exceptions_throw_verifyerror(m,
519 "Attempt to access constant outside range");
524 switch (m->class->cptags[i]) {
525 case CONSTANT_Integer:
526 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
529 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
532 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
534 case CONSTANT_Double:
535 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
537 case CONSTANT_String:
538 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
541 cr = (constant_classref *) (m->class->cpinfos[i]);
543 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
546 /* if not resolved, c == NULL */
548 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
552 #if defined(ENABLE_VERIFIER)
554 exceptions_throw_verifyerror(m,
555 "Invalid constant type to push");
561 case JAVA_ACONST_NULL:
572 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
577 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
583 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
588 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
591 /* stack operations ***************************************************/
593 /* We need space for additional ICMDs so we can translate these */
594 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
597 INSTRUCTIONS_CHECK(4);
605 INSTRUCTIONS_CHECK(6);
615 INSTRUCTIONS_CHECK(2);
621 INSTRUCTIONS_CHECK(7);
632 INSTRUCTIONS_CHECK(9);
645 INSTRUCTIONS_CHECK(3);
651 /* local variable access instructions *********************************/
656 if (iswide == false) {
657 i = SUCK_BE_U1(m->jcode + p + 1);
660 i = SUCK_BE_U2(m->jcode + p + 1);
664 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
669 if (iswide == false) {
670 i = SUCK_BE_U1(m->jcode + p + 1);
673 i = SUCK_BE_U2(m->jcode + p + 1);
677 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
684 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
691 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
698 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
705 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
712 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
718 if (iswide == false) {
719 i = SUCK_BE_U1(m->jcode + p + 1);
722 i = SUCK_BE_U2(m->jcode + p + 1);
726 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
731 if (iswide == false) {
732 i = SUCK_BE_U1(m->jcode + p + 1);
735 i = SUCK_BE_U2(m->jcode + p + 1);
739 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
746 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
753 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
760 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
767 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
774 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
781 if (iswide == false) {
782 i = SUCK_BE_U1(m->jcode + p + 1);
783 v = SUCK_BE_S1(m->jcode + p + 2);
787 i = SUCK_BE_U2(m->jcode + p + 1);
788 v = SUCK_BE_S2(m->jcode + p + 3);
793 LOCALTYPE_USED(i, TYPE_INT);
794 OP_LOCALINDEX_I(opcode, i, v);
798 /* wider index for loading, storing and incrementing ******************/
805 /* managing arrays ****************************************************/
808 switch (SUCK_BE_S1(m->jcode + p + 1)) {
810 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
813 bte = builtintable_get_internal(BUILTIN_newarray_char);
816 bte = builtintable_get_internal(BUILTIN_newarray_float);
819 bte = builtintable_get_internal(BUILTIN_newarray_double);
822 bte = builtintable_get_internal(BUILTIN_newarray_byte);
825 bte = builtintable_get_internal(BUILTIN_newarray_short);
828 bte = builtintable_get_internal(BUILTIN_newarray_int);
831 bte = builtintable_get_internal(BUILTIN_newarray_long);
833 #if defined(ENABLE_VERIFIER)
835 exceptions_throw_verifyerror(m, "Invalid array-type to create");
839 OP_BUILTIN_CHECK_EXCEPTION(bte);
843 i = SUCK_BE_U2(m->jcode + p + 1);
844 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
848 if (!(cr = class_get_classref_multiarray_of(1, compr)))
851 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
854 INSTRUCTIONS_CHECK(2);
855 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
856 bte = builtintable_get_internal(BUILTIN_newarray);
857 OP_BUILTIN_CHECK_EXCEPTION(bte);
861 case JAVA_MULTIANEWARRAY:
862 jd->isleafmethod = false;
863 i = SUCK_BE_U2(m->jcode + p + 1);
864 j = SUCK_BE_U1(m->jcode + p + 3);
866 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
870 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
873 /* if unresolved, c == NULL */
875 iptr->s1.argcount = j;
876 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
879 /* control flow instructions ******************************************/
898 i = p + SUCK_BE_S2(m->jcode + p + 1);
899 CHECK_BYTECODE_INDEX(i);
902 OP_INSINDEX(opcode, i);
906 i = p + SUCK_BE_S4(m->jcode + p + 1);
907 CHECK_BYTECODE_INDEX(i);
910 OP_INSINDEX(opcode, i);
914 i = p + SUCK_BE_S2(m->jcode + p + 1);
916 CHECK_BYTECODE_INDEX(i);
919 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
920 iptr->sx.s23.s3.jsrtarget.insindex = i;
925 i = p + SUCK_BE_S4(m->jcode + p + 1);
929 if (iswide == false) {
930 i = SUCK_BE_U1(m->jcode + p + 1);
933 i = SUCK_BE_U2(m->jcode + p + 1);
939 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
949 /* XXX ARETURN will need a flag in the typechecker */
955 /* XXX ATHROW will need a flag in the typechecker */
960 /* table jumps ********************************************************/
962 case JAVA_LOOKUPSWITCH:
965 lookup_target_t *lookup;
966 #if defined(ENABLE_VERIFIER)
970 nextp = ALIGN((p + 1), 4);
972 CHECK_END_OF_BYTECODE(nextp + 8);
974 OP_PREPARE_ZEROFLAGS(opcode);
978 j = p + SUCK_BE_S4(m->jcode + nextp);
979 iptr->sx.s23.s3.lookupdefault.insindex = j;
981 CHECK_BYTECODE_INDEX(j);
984 /* number of pairs */
986 num = SUCK_BE_U4(m->jcode + nextp);
987 iptr->sx.s23.s2.lookupcount = num;
990 /* allocate the intermediate code table */
992 lookup = DMNEW(lookup_target_t, num);
993 iptr->dst.lookup = lookup;
995 /* iterate over the lookup table */
997 CHECK_END_OF_BYTECODE(nextp + 8 * num);
999 for (i = 0; i < num; i++) {
1002 j = SUCK_BE_S4(m->jcode + nextp);
1007 #if defined(ENABLE_VERIFIER)
1008 /* check if the lookup table is sorted correctly */
1010 if (i && (j <= prevvalue)) {
1011 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
1018 j = p + SUCK_BE_S4(m->jcode + nextp);
1019 lookup->target.insindex = j;
1022 CHECK_BYTECODE_INDEX(j);
1031 case JAVA_TABLESWITCH:
1035 branch_target_t *table;
1038 nextp = ALIGN((p + 1), 4);
1040 CHECK_END_OF_BYTECODE(nextp + 12);
1042 OP_PREPARE_ZEROFLAGS(opcode);
1044 /* default target */
1046 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
1048 CHECK_BYTECODE_INDEX(deftarget);
1049 MARK_BASICBLOCK(deftarget);
1053 j = SUCK_BE_S4(m->jcode + nextp);
1054 iptr->sx.s23.s2.tablelow = j;
1059 num = SUCK_BE_S4(m->jcode + nextp);
1060 iptr->sx.s23.s3.tablehigh = num;
1063 /* calculate the number of table entries */
1067 #if defined(ENABLE_VERIFIER)
1069 exceptions_throw_verifyerror(m,
1070 "invalid TABLESWITCH: upper bound < lower bound");
1074 /* create the intermediate code table */
1075 /* the first entry is the default target */
1077 table = MNEW(branch_target_t, 1 + num);
1078 iptr->dst.table = table;
1079 (table++)->insindex = deftarget;
1081 /* iterate over the target table */
1083 CHECK_END_OF_BYTECODE(nextp + 4 * num);
1085 for (i = 0; i < num; i++) {
1086 j = p + SUCK_BE_S4(m->jcode + nextp);
1087 (table++)->insindex = j;
1089 CHECK_BYTECODE_INDEX(j);
1098 /* load and store of object fields ************************************/
1102 jd->isleafmethod = false;
1105 case JAVA_GETSTATIC:
1106 case JAVA_PUTSTATIC:
1110 constant_FMIref *fr;
1111 unresolved_field *uf;
1113 i = SUCK_BE_U2(m->jcode + p + 1);
1114 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1118 OP_PREPARE_ZEROFLAGS(opcode);
1119 iptr->sx.s23.s3.fmiref = fr;
1121 /* only with -noverify, otherwise the typechecker does this */
1123 #if defined(ENABLE_VERIFIER)
1124 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1126 result = resolve_field_lazy(m, fr);
1127 if (result == resolveFailed)
1130 if (result != resolveSucceeded) {
1131 uf = resolve_create_unresolved_field(m->class, m, iptr);
1136 /* store the unresolved_field pointer */
1138 iptr->sx.s23.s3.uf = uf;
1139 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1141 #if defined(ENABLE_VERIFIER)
1149 /* method invocation **************************************************/
1151 case JAVA_INVOKESTATIC:
1152 i = SUCK_BE_U2(m->jcode + p + 1);
1153 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1158 md = mr->parseddesc.md;
1160 if (md->params == NULL)
1161 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1166 case JAVA_INVOKEINTERFACE:
1167 i = SUCK_BE_U2(m->jcode + p + 1);
1169 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1171 goto invoke_nonstatic_method;
1173 case JAVA_INVOKESPECIAL:
1174 case JAVA_INVOKEVIRTUAL:
1175 i = SUCK_BE_U2(m->jcode + p + 1);
1176 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1178 invoke_nonstatic_method:
1182 md = mr->parseddesc.md;
1184 if (md->params == NULL)
1185 if (!descriptor_params_from_paramtypes(md, 0))
1189 jd->isleafmethod = false;
1191 OP_PREPARE_ZEROFLAGS(opcode);
1192 iptr->sx.s23.s3.fmiref = mr;
1194 /* only with -noverify, otherwise the typechecker does this */
1196 #if defined(ENABLE_VERIFIER)
1197 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1199 result = resolve_method_lazy(m, mr,
1200 (opcode == JAVA_INVOKESPECIAL));
1201 if (result == resolveFailed)
1204 if (result == resolveSucceeded) {
1205 methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1207 /* if this call is monomorphic, turn it into an INVOKESPECIAL */
1209 assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1211 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1212 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1214 iptr->opc = ICMD_INVOKESPECIAL;
1218 um = resolve_create_unresolved_method(m->class, m, mr,
1219 (opcode == JAVA_INVOKESTATIC),
1220 (opcode == JAVA_INVOKESPECIAL));
1225 /* store the unresolved_method pointer */
1227 iptr->sx.s23.s3.um = um;
1228 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1230 #if defined(ENABLE_VERIFIER)
1236 /* instructions taking class arguments ********************************/
1239 i = SUCK_BE_U2(m->jcode + p + 1);
1240 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1244 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1247 INSTRUCTIONS_CHECK(2);
1248 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1249 bte = builtintable_get_internal(BUILTIN_new);
1250 OP_BUILTIN_CHECK_EXCEPTION(bte);
1254 case JAVA_CHECKCAST:
1255 i = SUCK_BE_U2(m->jcode + p + 1);
1256 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1260 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1263 if (cr->name->text[0] == '[') {
1264 /* array type cast-check */
1265 flags = INS_FLAG_ARRAY;
1266 jd->isleafmethod = false;
1269 /* object type cast-check */
1272 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1275 case JAVA_INSTANCEOF:
1276 i = SUCK_BE_U2(m->jcode + p + 1);
1277 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1281 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1284 if (cr->name->text[0] == '[') {
1285 /* array type cast-check */
1286 INSTRUCTIONS_CHECK(2);
1287 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1288 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1289 OP_BUILTIN_NO_EXCEPTION(bte);
1293 /* object type cast-check */
1294 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1298 /* synchronization instructions ***************************************/
1300 case JAVA_MONITORENTER:
1301 #if defined(ENABLE_THREADS)
1303 bte = builtintable_get_internal(LOCK_monitor_enter);
1304 OP_BUILTIN_CHECK_EXCEPTION(bte);
1309 OP(ICMD_CHECKNULL_POP);
1313 case JAVA_MONITOREXIT:
1314 #if defined(ENABLE_THREADS)
1316 bte = builtintable_get_internal(LOCK_monitor_exit);
1317 OP_BUILTIN_CHECK_EXCEPTION(bte);
1322 OP(ICMD_CHECKNULL_POP);
1326 /* arithmetic instructions that may become builtin functions **********/
1329 #if !SUPPORT_DIVISION
1330 bte = builtintable_get_internal(BUILTIN_idiv);
1331 OP_BUILTIN_ARITHMETIC(opcode, bte);
1338 #if !SUPPORT_DIVISION
1339 bte = builtintable_get_internal(BUILTIN_irem);
1340 OP_BUILTIN_ARITHMETIC(opcode, bte);
1347 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1348 bte = builtintable_get_internal(BUILTIN_ldiv);
1349 OP_BUILTIN_ARITHMETIC(opcode, bte);
1356 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1357 bte = builtintable_get_internal(BUILTIN_lrem);
1358 OP_BUILTIN_ARITHMETIC(opcode, bte);
1365 #if defined(__I386__)
1368 bte = builtintable_get_internal(BUILTIN_frem);
1369 OP_BUILTIN_NO_EXCEPTION(bte);
1374 #if defined(__I386__)
1377 bte = builtintable_get_internal(BUILTIN_drem);
1378 OP_BUILTIN_NO_EXCEPTION(bte);
1383 #if defined(__ALPHA__)
1385 bte = builtintable_get_internal(BUILTIN_f2i);
1386 OP_BUILTIN_NO_EXCEPTION(bte);
1396 #if defined(__ALPHA__)
1398 bte = builtintable_get_internal(BUILTIN_f2l);
1399 OP_BUILTIN_NO_EXCEPTION(bte);
1409 #if defined(__ALPHA__)
1411 bte = builtintable_get_internal(BUILTIN_d2i);
1412 OP_BUILTIN_NO_EXCEPTION(bte);
1422 #if defined(__ALPHA__)
1424 bte = builtintable_get_internal(BUILTIN_d2l);
1425 OP_BUILTIN_NO_EXCEPTION(bte);
1434 /* invalid opcodes ****************************************************/
1436 /* check for invalid opcodes if the verifier is enabled */
1437 #if defined(ENABLE_VERIFIER)
1438 case JAVA_BREAKPOINT:
1439 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1442 case 186: /* unused opcode */
1496 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1500 #endif /* defined(ENABLE_VERIFIER) */
1502 /* opcodes that don't require translation *****************************/
1505 /* straight-forward translation to ICMD */
1511 /* verifier checks ****************************************************/
1513 #if defined(ENABLE_VERIFIER)
1514 /* If WIDE was used correctly, iswide should have been reset by now. */
1516 exceptions_throw_verifyerror(m,
1517 "Illegal instruction: WIDE before incompatible opcode");
1520 #endif /* defined(ENABLE_VERIFIER) */
1524 if (JITDATA_HAS_FLAG_REORDER(jd)) {
1525 /* add a NOP to the last basic block */
1527 INSTRUCTIONS_CHECK(1);
1531 /*** END OF LOOP **********************************************************/
1533 /* assert that we did not write more ICMDs than allocated */
1535 assert(ipc <= pd.instructionslength);
1536 assert(ipc == (iptr - pd.instructions));
1538 /*** verifier checks ******************************************************/
1540 #if defined(ENABLE_VERIFIER)
1541 if (p != m->jcodelength) {
1542 exceptions_throw_verifyerror(m,
1543 "Command-sequence crosses code-boundary");
1548 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1551 #endif /* defined(ENABLE_VERIFIER) */
1553 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1555 /* adjust block count if target 0 is not first intermediate instruction */
1557 if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1))
1560 /* copy local to method variables */
1562 jd->instructions = pd.instructions;
1563 jd->instructioncount = ipc;
1564 jd->basicblockcount = b_count;
1565 jd->stackcount = s_count + jd->basicblockcount * m->maxstack; /* in-stacks */
1567 /* allocate stack table */
1569 jd->stack = DMNEW(stackelement, jd->stackcount);
1571 /* build basic block list */
1573 bptr = jd->basicblocks = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1575 /* zero out all basic block structures */
1577 MZERO(bptr, basicblock, b_count + 1);
1581 /* additional block if target 0 is not first intermediate instruction */
1583 if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1)) {
1584 BASICBLOCK_INIT(bptr, m);
1586 bptr->iinstr = jd->instructions;
1587 /* bptr->icount is set when the next block is allocated */
1589 bptr->nr = b_count++;
1591 bptr[-1].next = bptr;
1594 /* allocate blocks */
1596 for (p = 0; p < m->jcodelength; p++) {
1597 if (jd->basicblockindex[p] & 1) {
1598 #if defined(ENABLE_VERIFIER)
1599 /* Check if this block starts at the beginning of an
1602 if (!pd.instructionstart[p]) {
1603 exceptions_throw_verifyerror(m,
1604 "Branch into middle of instruction");
1609 /* allocate the block */
1611 BASICBLOCK_INIT(bptr, m);
1613 bptr->iinstr = jd->instructions + (jd->basicblockindex[p] >> 1);
1615 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1617 /* bptr->icount is set when the next block is allocated */
1619 jd->basicblockindex[p] = b_count;
1621 bptr->nr = b_count++;
1623 bptr[-1].next = bptr;
1627 /* set instruction count of last real block */
1630 bptr[-1].icount = (jd->instructions + jd->instructioncount) - bptr[-1].iinstr;
1633 /* allocate additional block at end */
1635 BASICBLOCK_INIT(bptr,m);
1637 jd->basicblockindex[m->jcodelength] = b_count;
1639 /* set basicblock pointers in exception table */
1641 if (!parse_resolve_exception_table(jd))
1644 /* store the local map */
1646 jd->local_map = local_map;
1648 /* calculate local variable renaming */
1658 /* iterate over local_map[0..m->maxlocals*5] and set all existing */
1659 /* index,type pairs (local_map[index*5+type]==1) to an unique value */
1660 /* -> == new local var index */
1661 for(i = 0; i < (cd->maxlocals * 5); i++, mapptr++) {
1663 *mapptr = nlocals++;
1668 jd->localcount = nlocals;
1670 /* calculate the (maximum) number of variables needed */
1673 nlocals /* local variables */
1674 + jd->basicblockcount * m->maxstack /* invars */
1675 + s_count; /* variables created within blocks (non-invar) */
1677 /* reserve the first indices for local variables */
1679 jd->vartop = nlocals;
1681 /* reserve extra variables needed by stack analyse */
1683 jd->varcount += STACK_EXTRA_VARS;
1684 jd->vartop += STACK_EXTRA_VARS;
1686 /* The verifier needs space for saving invars in some cases and */
1687 /* extra variables. */
1689 #if defined(ENABLE_VERIFIER)
1690 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
1691 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1692 jd->vartop += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1695 /* allocate and initialize the variable array */
1697 jd->var = DMNEW(varinfo, jd->varcount);
1698 MZERO(jd->var, varinfo, jd->varcount);
1700 /* set types of all locals in jd->var */
1702 for(mapptr = local_map, i = 0; i < (cd->maxlocals * 5); i++, mapptr++)
1703 if (*mapptr != UNUSED)
1704 VAR(*mapptr)->type = i%5;
1707 /* everything's ok */
1711 /*** goto labels for throwing verifier exceptions *************************/
1713 #if defined(ENABLE_VERIFIER)
1715 throw_unexpected_end_of_bytecode:
1716 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1719 throw_invalid_bytecode_index:
1720 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1723 throw_illegal_local_variable_number:
1724 exceptions_throw_verifyerror(m, "Illegal local variable number");
1727 #endif /* ENABLE_VERIFIER */
1732 * These are local overrides for various environment variables in Emacs.
1733 * Please do not remove this and leave it at the end of the file, where
1734 * Emacs will automagically detect them.
1735 * ---------------------------------------------------------------------
1738 * indent-tabs-mode: t
1742 * vim:noexpandtab:sw=4:ts=4: