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 7596 2007-03-28 21:05:53Z twisti $
37 #include "mm/memory.h"
38 #include "native/native.h"
40 #if defined(ENABLE_THREADS)
41 # include "threads/native/lock.h"
44 #include "toolbox/logging.h"
46 #include "vm/builtin.h"
47 #include "vm/exceptions.h"
48 #include "vm/global.h"
49 #include "vm/stringlocal.h"
51 #include "vm/jit/asmpart.h"
52 #include "vm/jit/jit.h"
53 #include "vm/jit/parse.h"
54 #include "vm/jit/patcher.h"
55 #include "vm/jit/loop/loop.h"
57 #include "vmcore/linker.h"
58 #include "vmcore/loader.h"
59 #include "vmcore/options.h"
60 #include "vm/resolve.h"
62 #if defined(ENABLE_STATISTICS)
63 # include "vmcore/statistics.h"
66 #include "vmcore/suck.h"
68 #define INSTRUCTIONS_INCREMENT 5 /* number of additional instructions to */
69 /* allocate if space runs out */
72 /* parserdata_t ***************************************************************/
74 typedef struct parsedata_t parsedata_t;
77 instruction *instructions; /* instruction array */
78 s4 instructionslength; /* length of the instruction array */
83 /* parse_setup *****************************************************************
85 Fills the passed parsedata_t structure.
87 *******************************************************************************/
89 static void parse_setup(jitdata *jd, parsedata_t *pd)
93 /* get required compiler data */
97 /* Allocate instruction array and block index table (1 additional
100 jd->basicblockindex = DMNEW(s4, m->jcodelength + 1);
101 pd->instructionstart = DMNEW(u1, m->jcodelength + 1);
103 MZERO(jd->basicblockindex, s4, m->jcodelength + 1);
104 MZERO(pd->instructionstart, u1, m->jcodelength + 1);
106 /* Set the length of the instruction array. We simply add 5 more
107 instruction, as this seems to be a reasonable value. */
109 pd->instructionslength = m->jcodelength + 1;
111 /* allocate the instruction array */
113 pd->instructions = DMNEW(instruction, pd->instructionslength);
115 /* Zero the intermediate instructions array so we don't have any
116 invalid pointers in it if we cannot finish stack_analyse(). */
118 MZERO(pd->instructions, instruction, pd->instructionslength);
122 /* parse_realloc_instructions **************************************************
124 Reallocate the instructions array so there is room for at least N
125 additional instructions.
128 the new value for iptr
130 *******************************************************************************/
132 static instruction *parse_realloc_instructions(parsedata_t *pd, s4 ipc, s4 n)
134 /* increase the size of the instruction array */
136 pd->instructionslength += (n + INSTRUCTIONS_INCREMENT);
138 /* reallocate the array */
140 pd->instructions = DMREALLOC(pd->instructions, instruction, ipc,
141 pd->instructionslength);
142 MZERO(pd->instructions + ipc, instruction, (pd->instructionslength - ipc));
144 /* return the iptr */
146 return pd->instructions + ipc;
150 /* parse_mark_exception_boundaries *********************************************
152 Mark exception handlers and the boundaries of the handled regions as
153 basic block boundaries.
156 jd...............current jitdata
159 >= 0.............the number of new basic blocks marked
160 -1...............an exception has been thrown
162 *******************************************************************************/
164 static int parse_mark_exception_boundaries(jitdata *jd)
170 raw_exception_entry *rex;
175 len = m->rawexceptiontablelength;
181 rex = m->rawexceptiontable;
183 for (i = 0; i < len; ++i, ++rex) {
185 /* the start of the handled region becomes a basic block start */
188 CHECK_BYTECODE_INDEX(pc);
191 pc = rex->endpc; /* see JVM Spec 4.7.3 */
192 CHECK_BYTECODE_INDEX_EXCLUSIVE(pc);
194 /* check that the range is valid */
196 #if defined(ENABLE_VERIFIER)
197 if (pc <= rex->startpc) {
198 exceptions_throw_verifyerror(m,
199 "Invalid exception handler range");
204 /* end of handled region becomes a basic block boundary */
205 /* (If it is the bytecode end, we'll use the special */
206 /* end block that is created anyway.) */
208 if (pc < m->jcodelength)
211 jd->branchtoend = true;
213 /* the start of the handler becomes a basic block start */
216 CHECK_BYTECODE_INDEX(pc);
224 #if defined(ENABLE_VERIFIER)
225 throw_invalid_bytecode_index:
226 exceptions_throw_verifyerror(m,
227 "Illegal bytecode index in exception table");
233 /* parse_resolve_exception_table ***********************************************
235 Enter the exception handlers and their ranges, resolved to basicblock *s,
239 jd...............current jitdata
242 true.............everything ok
243 false............an exception has been thrown
245 *******************************************************************************/
247 static bool parse_resolve_exception_table(jitdata *jd)
250 raw_exception_entry *rex;
258 len = m->rawexceptiontablelength;
260 /* common case: no handler entries */
265 /* allocate the exception table */
267 jd->exceptiontablelength = len;
268 jd->exceptiontable = DMNEW(exception_entry, len + 1); /* XXX why +1? */
270 /* copy and resolve the entries */
272 ex = jd->exceptiontable;
273 rex = m->rawexceptiontable;
275 for (i = 0; i < len; ++i, ++rex, ++ex) {
276 /* resolve instruction indices to basic blocks */
278 ex->start = BLOCK_OF(rex->startpc);
279 ex->end = BLOCK_OF(rex->endpc);
280 ex->handler = BLOCK_OF(rex->handlerpc);
282 /* lazily resolve the catchtype */
284 if (rex->catchtype.any != NULL) {
285 if (!resolve_classref_or_classinfo(m,
287 resolveLazy, true, false,
291 /* if resolved, enter the result of resolution in the table */
294 rex->catchtype.cls = exclass;
297 ex->catchtype = rex->catchtype;
298 ex->next = NULL; /* set by loop analysis */
299 ex->down = ex + 1; /* link to next exception entry */
302 /* terminate the ->down linked list */
304 assert(ex != jd->exceptiontable);
311 /*******************************************************************************
313 function 'parse' scans the JavaVM code and generates intermediate code
315 During parsing the block index table is used to store at bit pos 0
316 a flag which marks basic block starts and at position 1 to 31 the
317 intermediate instruction index. After parsing the block index table
318 is scanned, for marked positions a block is generated and the block
319 number is stored in the block index table.
321 *******************************************************************************/
323 /*** macro for checking the length of the bytecode ***/
325 #if defined(ENABLE_VERIFIER)
326 #define CHECK_END_OF_BYTECODE(neededlength) \
328 if ((neededlength) > m->jcodelength) \
329 goto throw_unexpected_end_of_bytecode; \
331 #else /* !ENABLE_VERIFIER */
332 #define CHECK_END_OF_BYTECODE(neededlength)
333 #endif /* ENABLE_VERIFIER */
335 bool parse(jitdata *jd)
337 methodinfo *m; /* method being parsed */
339 instruction *iptr; /* current ptr into instruction array */
340 s4 ipc; /* intermediate instruction counter */
341 s4 p; /* java instruction counter */
342 s4 nextp; /* start of next java instruction */
343 s4 opcode; /* java opcode */
346 int b_count; /* basic block counter */
347 int s_count = 0; /* stack element counter */
348 bool blockend = false; /* true if basic block end has been reached */
349 bool iswide = false; /* true if last instruction was a wide */
350 constant_classref *cr;
351 constant_classref *compr;
353 builtintable_entry *bte;
356 unresolved_method *um;
357 resolve_result_t result;
364 int *local_map; /* local pointer to renaming structore */
365 /* is assigned to rd->local_map at the end */
366 /* get required compiler data */
370 /* allocate buffers for local variable renaming */
371 local_map = DMNEW(int, m->maxlocals * 5);
372 for (i = 0; i < m->maxlocals; i++) {
373 local_map[i * 5 + 0] = 0;
374 local_map[i * 5 + 1] = 0;
375 local_map[i * 5 + 2] = 0;
376 local_map[i * 5 + 3] = 0;
377 local_map[i * 5 + 4] = 0;
380 /* initialize the parse data structures */
382 parse_setup(jd, &pd);
384 /* initialize local variables */
386 iptr = pd.instructions;
389 /* mark basic block boundaries for exception table */
391 b_count = parse_mark_exception_boundaries(jd);
395 /* initialize stack element counter */
397 s_count = 1 + m->rawexceptiontablelength;
399 /* setup line number info */
404 if (m->linenumbercount == 0) {
408 linepcchange = m->linenumbers[0].start_pc;
411 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
413 for (p = 0; p < m->jcodelength; p = nextp) {
415 /* mark this position as a valid instruction start */
417 pd.instructionstart[p] = 1;
419 /* change the current line number, if necessary */
421 /* XXX rewrite this using pointer arithmetic */
423 if (linepcchange == p) {
424 if (m->linenumbercount > lineindex) {
426 currentline = m->linenumbers[lineindex].line_number;
428 if (lineindex < m->linenumbercount) {
429 linepcchange = m->linenumbers[lineindex].start_pc;
430 if (linepcchange == p)
431 goto next_linenumber;
437 /* fetch next opcode */
439 opcode = SUCK_BE_U1(m->jcode + p);
441 /* some compilers put a JAVA_NOP after a blockend instruction */
443 if (blockend && (opcode != JAVA_NOP)) {
444 /* start new block */
450 /* We need a NOP as last instruction in each basic block
451 for basic block reordering (may be replaced with a GOTO
454 if (jd->basicblockindex[p] & 1) {
455 INSTRUCTIONS_CHECK(1);
459 /* store intermediate instruction count (bit 0 mark block starts) */
461 jd->basicblockindex[p] |= (ipc << 1);
463 /* compute next instruction start */
465 nextp = p + jcommandsize[opcode];
467 CHECK_END_OF_BYTECODE(nextp);
469 /* add stack elements produced by this instruction */
471 s_count += stackreq[opcode];
473 /* We check here for the space of 1 instruction in the
474 instruction array. If an opcode is converted to more than
475 1 instruction, this is checked in the corresponding
478 INSTRUCTIONS_CHECK(1);
480 /* translate this bytecode instruction */
486 /* pushing constants onto the stack ***********************************/
489 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
493 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
497 i = SUCK_BE_U1(m->jcode + p + 1);
498 goto pushconstantitem;
502 i = SUCK_BE_U2(m->jcode + p + 1);
506 #if defined(ENABLE_VERIFIER)
507 if (i >= m->class->cpcount) {
508 exceptions_throw_verifyerror(m,
509 "Attempt to access constant outside range");
514 switch (m->class->cptags[i]) {
515 case CONSTANT_Integer:
516 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
519 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
522 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
524 case CONSTANT_Double:
525 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
527 case CONSTANT_String:
528 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
531 cr = (constant_classref *) (m->class->cpinfos[i]);
533 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
536 /* if not resolved, c == NULL */
538 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
542 #if defined(ENABLE_VERIFIER)
544 exceptions_throw_verifyerror(m,
545 "Invalid constant type to push");
551 case JAVA_ACONST_NULL:
562 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
567 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
573 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
578 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
581 /* stack operations ***************************************************/
583 /* We need space for additional ICMDs so we can translate these */
584 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
587 INSTRUCTIONS_CHECK(4);
595 INSTRUCTIONS_CHECK(6);
605 INSTRUCTIONS_CHECK(2);
611 INSTRUCTIONS_CHECK(7);
622 INSTRUCTIONS_CHECK(9);
635 INSTRUCTIONS_CHECK(3);
641 /* local variable access instructions *********************************/
646 if (iswide == false) {
647 i = SUCK_BE_U1(m->jcode + p + 1);
650 i = SUCK_BE_U2(m->jcode + p + 1);
654 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
659 if (iswide == false) {
660 i = SUCK_BE_U1(m->jcode + p + 1);
663 i = SUCK_BE_U2(m->jcode + p + 1);
667 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
674 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
681 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
688 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
695 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
702 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
708 if (iswide == false) {
709 i = SUCK_BE_U1(m->jcode + p + 1);
712 i = SUCK_BE_U2(m->jcode + p + 1);
716 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
721 if (iswide == false) {
722 i = SUCK_BE_U1(m->jcode + p + 1);
725 i = SUCK_BE_U2(m->jcode + p + 1);
729 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
736 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
743 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
750 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
757 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
764 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
771 if (iswide == false) {
772 i = SUCK_BE_U1(m->jcode + p + 1);
773 v = SUCK_BE_S1(m->jcode + p + 2);
777 i = SUCK_BE_U2(m->jcode + p + 1);
778 v = SUCK_BE_S2(m->jcode + p + 3);
783 LOCALTYPE_USED(i, TYPE_INT);
784 OP_LOCALINDEX_I(opcode, i, v);
788 /* wider index for loading, storing and incrementing ******************/
795 /* managing arrays ****************************************************/
798 switch (SUCK_BE_S1(m->jcode + p + 1)) {
800 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
803 bte = builtintable_get_internal(BUILTIN_newarray_char);
806 bte = builtintable_get_internal(BUILTIN_newarray_float);
809 bte = builtintable_get_internal(BUILTIN_newarray_double);
812 bte = builtintable_get_internal(BUILTIN_newarray_byte);
815 bte = builtintable_get_internal(BUILTIN_newarray_short);
818 bte = builtintable_get_internal(BUILTIN_newarray_int);
821 bte = builtintable_get_internal(BUILTIN_newarray_long);
823 #if defined(ENABLE_VERIFIER)
825 exceptions_throw_verifyerror(m, "Invalid array-type to create");
829 OP_BUILTIN_CHECK_EXCEPTION(bte);
833 i = SUCK_BE_U2(m->jcode + p + 1);
834 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
838 if (!(cr = class_get_classref_multiarray_of(1, compr)))
841 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
844 INSTRUCTIONS_CHECK(2);
845 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
846 bte = builtintable_get_internal(BUILTIN_newarray);
847 OP_BUILTIN_CHECK_EXCEPTION(bte);
851 case JAVA_MULTIANEWARRAY:
852 jd->isleafmethod = false;
853 i = SUCK_BE_U2(m->jcode + p + 1);
854 j = SUCK_BE_U1(m->jcode + p + 3);
856 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
860 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
863 /* if unresolved, c == NULL */
865 iptr->s1.argcount = j;
866 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, INS_FLAG_CHECK);
869 /* control flow instructions ******************************************/
888 i = p + SUCK_BE_S2(m->jcode + p + 1);
889 CHECK_BYTECODE_INDEX(i);
892 OP_INSINDEX(opcode, i);
896 i = p + SUCK_BE_S4(m->jcode + p + 1);
897 CHECK_BYTECODE_INDEX(i);
900 OP_INSINDEX(opcode, i);
904 i = p + SUCK_BE_S2(m->jcode + p + 1);
906 CHECK_BYTECODE_INDEX(i);
909 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
910 iptr->sx.s23.s3.jsrtarget.insindex = i;
915 i = p + SUCK_BE_S4(m->jcode + p + 1);
919 if (iswide == false) {
920 i = SUCK_BE_U1(m->jcode + p + 1);
923 i = SUCK_BE_U2(m->jcode + p + 1);
929 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
939 /* XXX ARETURN will need a flag in the typechecker */
945 /* XXX ATHROW will need a flag in the typechecker */
950 /* table jumps ********************************************************/
952 case JAVA_LOOKUPSWITCH:
955 lookup_target_t *lookup;
956 #if defined(ENABLE_VERIFIER)
960 nextp = MEMORY_ALIGN((p + 1), 4);
962 CHECK_END_OF_BYTECODE(nextp + 8);
964 OP_PREPARE_ZEROFLAGS(opcode);
968 j = p + SUCK_BE_S4(m->jcode + nextp);
969 iptr->sx.s23.s3.lookupdefault.insindex = j;
971 CHECK_BYTECODE_INDEX(j);
974 /* number of pairs */
976 num = SUCK_BE_U4(m->jcode + nextp);
977 iptr->sx.s23.s2.lookupcount = num;
980 /* allocate the intermediate code table */
982 lookup = DMNEW(lookup_target_t, num);
983 iptr->dst.lookup = lookup;
985 /* iterate over the lookup table */
987 CHECK_END_OF_BYTECODE(nextp + 8 * num);
989 for (i = 0; i < num; i++) {
992 j = SUCK_BE_S4(m->jcode + nextp);
997 #if defined(ENABLE_VERIFIER)
998 /* check if the lookup table is sorted correctly */
1000 if (i && (j <= prevvalue)) {
1001 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
1008 j = p + SUCK_BE_S4(m->jcode + nextp);
1009 lookup->target.insindex = j;
1012 CHECK_BYTECODE_INDEX(j);
1021 case JAVA_TABLESWITCH:
1025 branch_target_t *table;
1028 nextp = MEMORY_ALIGN((p + 1), 4);
1030 CHECK_END_OF_BYTECODE(nextp + 12);
1032 OP_PREPARE_ZEROFLAGS(opcode);
1034 /* default target */
1036 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
1038 CHECK_BYTECODE_INDEX(deftarget);
1039 MARK_BASICBLOCK(deftarget);
1043 j = SUCK_BE_S4(m->jcode + nextp);
1044 iptr->sx.s23.s2.tablelow = j;
1049 num = SUCK_BE_S4(m->jcode + nextp);
1050 iptr->sx.s23.s3.tablehigh = num;
1053 /* calculate the number of table entries */
1057 #if defined(ENABLE_VERIFIER)
1059 exceptions_throw_verifyerror(m,
1060 "invalid TABLESWITCH: upper bound < lower bound");
1064 /* create the intermediate code table */
1065 /* the first entry is the default target */
1067 table = DMNEW(branch_target_t, 1 + num);
1068 iptr->dst.table = table;
1069 (table++)->insindex = deftarget;
1071 /* iterate over the target table */
1073 CHECK_END_OF_BYTECODE(nextp + 4 * num);
1075 for (i = 0; i < num; i++) {
1076 j = p + SUCK_BE_S4(m->jcode + nextp);
1077 (table++)->insindex = j;
1079 CHECK_BYTECODE_INDEX(j);
1088 /* load and store of object fields ************************************/
1092 jd->isleafmethod = false;
1095 case JAVA_GETSTATIC:
1096 case JAVA_PUTSTATIC:
1100 constant_FMIref *fr;
1101 unresolved_field *uf;
1103 i = SUCK_BE_U2(m->jcode + p + 1);
1104 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1108 OP_PREPARE_ZEROFLAGS(opcode);
1109 iptr->sx.s23.s3.fmiref = fr;
1111 /* only with -noverify, otherwise the typechecker does this */
1113 #if defined(ENABLE_VERIFIER)
1114 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1116 result = resolve_field_lazy(m, fr);
1117 if (result == resolveFailed)
1120 if (result != resolveSucceeded) {
1121 uf = resolve_create_unresolved_field(m->class, m, iptr);
1126 /* store the unresolved_field pointer */
1128 iptr->sx.s23.s3.uf = uf;
1129 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1131 #if defined(ENABLE_VERIFIER)
1139 /* method invocation **************************************************/
1141 case JAVA_INVOKESTATIC:
1142 OP_PREPARE_ZEROFLAGS(opcode);
1144 i = SUCK_BE_U2(m->jcode + p + 1);
1145 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1150 md = mr->parseddesc.md;
1152 if (md->params == NULL)
1153 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1158 case JAVA_INVOKESPECIAL:
1159 OP_PREPARE_FLAGS(opcode, INS_FLAG_CHECK);
1161 i = SUCK_BE_U2(m->jcode + p + 1);
1162 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1164 goto invoke_nonstatic_method;
1166 case JAVA_INVOKEINTERFACE:
1167 OP_PREPARE_ZEROFLAGS(opcode);
1169 i = SUCK_BE_U2(m->jcode + p + 1);
1170 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1172 goto invoke_nonstatic_method;
1174 case JAVA_INVOKEVIRTUAL:
1175 OP_PREPARE_ZEROFLAGS(opcode);
1177 i = SUCK_BE_U2(m->jcode + p + 1);
1178 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1180 invoke_nonstatic_method:
1184 md = mr->parseddesc.md;
1186 if (md->params == NULL)
1187 if (!descriptor_params_from_paramtypes(md, 0))
1191 jd->isleafmethod = false;
1193 iptr->sx.s23.s3.fmiref = mr;
1195 /* only with -noverify, otherwise the typechecker does this */
1197 #if defined(ENABLE_VERIFIER)
1198 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1200 result = resolve_method_lazy(m, mr,
1201 (opcode == JAVA_INVOKESPECIAL));
1202 if (result == resolveFailed)
1205 if (result == resolveSucceeded) {
1206 methodinfo *mi = iptr->sx.s23.s3.fmiref->p.method;
1208 /* if this call is monomorphic, turn it into an
1211 assert(IS_FMIREF_RESOLVED(iptr->sx.s23.s3.fmiref));
1213 if ((iptr->opc == ICMD_INVOKEVIRTUAL)
1214 && (mi->flags & (ACC_FINAL | ACC_PRIVATE)))
1216 iptr->opc = ICMD_INVOKESPECIAL;
1217 iptr->flags.bits |= INS_FLAG_CHECK;
1221 um = resolve_create_unresolved_method(m->class, m, mr,
1222 (opcode == JAVA_INVOKESTATIC),
1223 (opcode == JAVA_INVOKESPECIAL));
1228 /* store the unresolved_method pointer */
1230 iptr->sx.s23.s3.um = um;
1231 iptr->flags.bits |= INS_FLAG_UNRESOLVED;
1233 #if defined(ENABLE_VERIFIER)
1239 /* instructions taking class arguments ********************************/
1242 i = SUCK_BE_U2(m->jcode + p + 1);
1243 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1247 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1250 INSTRUCTIONS_CHECK(2);
1251 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1252 bte = builtintable_get_internal(BUILTIN_new);
1253 OP_BUILTIN_CHECK_EXCEPTION(bte);
1257 case JAVA_CHECKCAST:
1258 i = SUCK_BE_U2(m->jcode + p + 1);
1259 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1263 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1266 if (cr->name->text[0] == '[') {
1267 /* array type cast-check */
1268 flags = INS_FLAG_CHECK | INS_FLAG_ARRAY;
1269 jd->isleafmethod = false;
1272 /* object type cast-check */
1273 flags = INS_FLAG_CHECK;
1275 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1278 case JAVA_INSTANCEOF:
1279 i = SUCK_BE_U2(m->jcode + p + 1);
1280 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1284 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1287 if (cr->name->text[0] == '[') {
1288 /* array type cast-check */
1289 INSTRUCTIONS_CHECK(2);
1290 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1291 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1292 OP_BUILTIN_NO_EXCEPTION(bte);
1296 /* object type cast-check */
1297 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1301 /* synchronization instructions ***************************************/
1303 case JAVA_MONITORENTER:
1304 #if defined(ENABLE_THREADS)
1306 bte = builtintable_get_internal(LOCK_monitor_enter);
1307 OP_BUILTIN_CHECK_EXCEPTION(bte);
1312 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1317 case JAVA_MONITOREXIT:
1318 #if defined(ENABLE_THREADS)
1320 bte = builtintable_get_internal(LOCK_monitor_exit);
1321 OP_BUILTIN_CHECK_EXCEPTION(bte);
1326 OP_CHECK_EXCEPTION(ICMD_CHECKNULL);
1331 /* arithmetic instructions that may become builtin functions **********/
1334 #if !SUPPORT_DIVISION
1335 bte = builtintable_get_internal(BUILTIN_idiv);
1336 OP_BUILTIN_ARITHMETIC(opcode, bte);
1338 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1341 OP_CHECK_EXCEPTION(opcode);
1347 #if !SUPPORT_DIVISION
1348 bte = builtintable_get_internal(BUILTIN_irem);
1349 OP_BUILTIN_ARITHMETIC(opcode, bte);
1351 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1354 OP_CHECK_EXCEPTION(opcode);
1360 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1361 bte = builtintable_get_internal(BUILTIN_ldiv);
1362 OP_BUILTIN_ARITHMETIC(opcode, bte);
1364 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1367 OP_CHECK_EXCEPTION(opcode);
1373 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1374 bte = builtintable_get_internal(BUILTIN_lrem);
1375 OP_BUILTIN_ARITHMETIC(opcode, bte);
1377 # if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
1380 OP_CHECK_EXCEPTION(opcode);
1386 #if defined(__I386__)
1389 bte = builtintable_get_internal(BUILTIN_frem);
1390 OP_BUILTIN_NO_EXCEPTION(bte);
1395 #if defined(__I386__)
1398 bte = builtintable_get_internal(BUILTIN_drem);
1399 OP_BUILTIN_NO_EXCEPTION(bte);
1404 #if defined(__ALPHA__)
1406 bte = builtintable_get_internal(BUILTIN_f2i);
1407 OP_BUILTIN_NO_EXCEPTION(bte);
1417 #if defined(__ALPHA__)
1419 bte = builtintable_get_internal(BUILTIN_f2l);
1420 OP_BUILTIN_NO_EXCEPTION(bte);
1430 #if defined(__ALPHA__)
1432 bte = builtintable_get_internal(BUILTIN_d2i);
1433 OP_BUILTIN_NO_EXCEPTION(bte);
1443 #if defined(__ALPHA__)
1445 bte = builtintable_get_internal(BUILTIN_d2l);
1446 OP_BUILTIN_NO_EXCEPTION(bte);
1455 /* invalid opcodes ****************************************************/
1457 /* check for invalid opcodes if the verifier is enabled */
1458 #if defined(ENABLE_VERIFIER)
1459 case JAVA_BREAKPOINT:
1460 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1463 case 186: /* unused opcode */
1517 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1521 #endif /* defined(ENABLE_VERIFIER) */
1523 /* opcodes that don't require translation *****************************/
1526 /* straight-forward translation to ICMD */
1532 /* verifier checks ****************************************************/
1534 #if defined(ENABLE_VERIFIER)
1535 /* If WIDE was used correctly, iswide should have been reset by now. */
1537 exceptions_throw_verifyerror(m,
1538 "Illegal instruction: WIDE before incompatible opcode");
1541 #endif /* defined(ENABLE_VERIFIER) */
1545 if (JITDATA_HAS_FLAG_REORDER(jd)) {
1546 /* add a NOP to the last basic block */
1548 INSTRUCTIONS_CHECK(1);
1552 /*** END OF LOOP **********************************************************/
1554 /* assert that we did not write more ICMDs than allocated */
1556 assert(ipc <= pd.instructionslength);
1557 assert(ipc == (iptr - pd.instructions));
1559 /*** verifier checks ******************************************************/
1561 #if defined(ENABLE_VERIFIER)
1562 if (p != m->jcodelength) {
1563 exceptions_throw_verifyerror(m,
1564 "Command-sequence crosses code-boundary");
1569 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1572 #endif /* defined(ENABLE_VERIFIER) */
1574 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1576 /* adjust block count if target 0 is not first intermediate instruction */
1578 if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1))
1581 jd->branchtoentry = true;
1583 /* copy local to method variables */
1585 jd->instructions = pd.instructions;
1586 jd->instructioncount = ipc;
1587 jd->basicblockcount = b_count;
1588 jd->stackcount = s_count + jd->basicblockcount * m->maxstack; /* in-stacks */
1590 /* allocate stack table */
1592 jd->stack = DMNEW(stackelement, jd->stackcount);
1594 /* build basic block list */
1596 bptr = jd->basicblocks = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1598 /* zero out all basic block structures */
1600 MZERO(bptr, basicblock, b_count + 1);
1604 /* additional block if target 0 is not first intermediate instruction */
1606 if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1)) {
1607 BASICBLOCK_INIT(bptr, m);
1609 bptr->iinstr = jd->instructions;
1610 /* bptr->icount is set when the next block is allocated */
1612 bptr->nr = b_count++;
1614 bptr[-1].next = bptr;
1617 /* allocate blocks */
1619 for (p = 0; p < m->jcodelength; p++) {
1620 if (jd->basicblockindex[p] & 1) {
1621 #if defined(ENABLE_VERIFIER)
1622 /* Check if this block starts at the beginning of an
1625 if (!pd.instructionstart[p]) {
1626 exceptions_throw_verifyerror(m,
1627 "Branch into middle of instruction");
1632 /* allocate the block */
1634 BASICBLOCK_INIT(bptr, m);
1636 bptr->iinstr = jd->instructions + (jd->basicblockindex[p] >> 1);
1638 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1640 /* bptr->icount is set when the next block is allocated */
1642 jd->basicblockindex[p] = b_count;
1644 bptr->nr = b_count++;
1646 bptr[-1].next = bptr;
1650 /* set instruction count of last real block */
1653 bptr[-1].icount = (jd->instructions + jd->instructioncount) - bptr[-1].iinstr;
1656 /* allocate additional block at end */
1658 BASICBLOCK_INIT(bptr,m);
1660 jd->basicblockindex[m->jcodelength] = b_count;
1662 /* set basicblock pointers in exception table */
1664 if (!parse_resolve_exception_table(jd))
1667 /* store the local map */
1669 jd->local_map = local_map;
1671 /* calculate local variable renaming */
1681 /* iterate over local_map[0..m->maxlocals*5] and set all existing */
1682 /* index,type pairs (local_map[index*5+type]==1) to an unique value */
1683 /* -> == new local var index */
1684 for(i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
1686 *mapptr = nlocals++;
1691 jd->localcount = nlocals;
1693 /* calculate the (maximum) number of variables needed */
1696 nlocals /* local variables */
1697 + jd->basicblockcount * m->maxstack /* invars */
1698 + s_count; /* variables created within blocks (non-invar) */
1700 /* reserve the first indices for local variables */
1702 jd->vartop = nlocals;
1704 /* reserve extra variables needed by stack analyse */
1706 jd->varcount += STACK_EXTRA_VARS;
1707 jd->vartop += STACK_EXTRA_VARS;
1709 /* The verifier needs space for saving invars in some cases and */
1710 /* extra variables. */
1712 #if defined(ENABLE_VERIFIER)
1713 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1714 jd->vartop += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1716 /* allocate and initialize the variable array */
1718 jd->var = DMNEW(varinfo, jd->varcount);
1719 MZERO(jd->var, varinfo, jd->varcount);
1721 /* set types of all locals in jd->var */
1723 for(mapptr = local_map, i = 0; i < (m->maxlocals * 5); i++, mapptr++)
1724 if (*mapptr != UNUSED)
1725 VAR(*mapptr)->type = i%5;
1728 /* everything's ok */
1732 /*** goto labels for throwing verifier exceptions *************************/
1734 #if defined(ENABLE_VERIFIER)
1736 throw_unexpected_end_of_bytecode:
1737 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1740 throw_invalid_bytecode_index:
1741 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1744 throw_illegal_local_variable_number:
1745 exceptions_throw_verifyerror(m, "Illegal local variable number");
1748 #endif /* ENABLE_VERIFIER */
1753 * These are local overrides for various environment variables in Emacs.
1754 * Please do not remove this and leave it at the end of the file, where
1755 * Emacs will automagically detect them.
1756 * ---------------------------------------------------------------------
1759 * indent-tabs-mode: t
1763 * vim:noexpandtab:sw=4:ts=4: