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 5657 2006-10-03 21:19:05Z 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 /*******************************************************************************
153 function 'parse' scans the JavaVM code and generates intermediate code
155 During parsing the block index table is used to store at bit pos 0
156 a flag which marks basic block starts and at position 1 to 31 the
157 intermediate instruction index. After parsing the block index table
158 is scanned, for marked positions a block is generated and the block
159 number is stored in the block index table.
161 *******************************************************************************/
163 static exceptiontable * fillextable(
166 exceptiontable *extable,
167 exceptiontable *raw_extable,
168 int exceptiontablelength,
173 if (exceptiontablelength == 0)
176 b_count = *block_count;
178 for (src = exceptiontablelength-1; src >=0; src--) {
179 /* the start of the handled region becomes a basic block start */
180 p = raw_extable[src].startpc;
181 CHECK_BYTECODE_INDEX(p);
182 extable->startpc = p;
185 p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
186 CHECK_BYTECODE_INDEX_EXCLUSIVE(p);
188 #if defined(ENABLE_VERIFIER)
189 if (p <= raw_extable[src].startpc) {
190 exceptions_throw_verifyerror(m,
191 "Invalid exception handler range");
197 /* end of handled region becomes a basic block boundary */
198 /* (If it is the bytecode end, we'll use the special */
199 /* end block that is created anyway.) */
200 if (p < m->jcodelength)
203 /* the start of the handler becomes a basic block start */
204 p = raw_extable[src].handlerpc;
205 CHECK_BYTECODE_INDEX(p);
206 extable->handlerpc = p;
209 extable->catchtype = raw_extable[src].catchtype;
210 extable->next = NULL;
211 extable->down = &extable[1];
215 *block_count = b_count;
220 #if defined(ENABLE_VERIFIER)
221 throw_invalid_bytecode_index:
222 exceptions_throw_verifyerror(m,
223 "Illegal bytecode index in exception table");
228 /*** macro for checking the length of the bytecode ***/
230 #if defined(ENABLE_VERIFIER)
231 #define CHECK_END_OF_BYTECODE(neededlength) \
233 if ((neededlength) > m->jcodelength) \
234 goto throw_unexpected_end_of_bytecode; \
236 #else /* !ENABLE_VERIFIER */
237 #define CHECK_END_OF_BYTECODE(neededlength)
238 #endif /* ENABLE_VERIFIER */
240 bool parse(jitdata *jd)
242 methodinfo *m; /* method being parsed */
246 instruction *iptr; /* current ptr into instruction array */
247 s4 ipc; /* intermediate instruction counter */
248 s4 p; /* java instruction counter */
249 s4 nextp; /* start of next java instruction */
250 s4 opcode; /* java opcode */
253 int b_count = 0; /* basic block counter */
254 int s_count = 0; /* stack element counter */
255 bool blockend = false; /* true if basic block end has been reached */
256 bool iswide = false; /* true if last instruction was a wide */
257 constant_classref *cr;
258 constant_classref *compr;
260 builtintable_entry *bte;
263 unresolved_method *um;
264 resolve_result_t result;
271 int *local_map; /* local pointer to renaming structore */
272 /* is assigned to rd->local_map at the end */
273 /* get required compiler data */
279 /* allocate buffers for local variable renaming */
280 local_map = DMNEW(int, cd->maxlocals * 5);
281 for (i = 0; i < cd->maxlocals; i++) {
282 local_map[i * 5 + 0] = 0;
283 local_map[i * 5 + 1] = 0;
284 local_map[i * 5 + 2] = 0;
285 local_map[i * 5 + 3] = 0;
286 local_map[i * 5 + 4] = 0;
289 /* initialize the parse data structures */
291 parse_setup(jd, &pd);
293 /* initialize local variables */
295 iptr = pd.instructions;
298 /* compute branch targets of exception table */
300 if (!fillextable(jd, m,
301 &(cd->exceptiontable[cd->exceptiontablelength-1]),
303 m->exceptiontablelength,
309 s_count = 1 + m->exceptiontablelength; /* initialize stack element counter */
311 #if defined(ENABLE_THREADS)
312 if (checksync && (m->flags & ACC_SYNCHRONIZED))
313 jd->isleafmethod = false;
316 /* setup line number info */
321 if (m->linenumbercount == 0) {
325 linepcchange = m->linenumbers[0].start_pc;
328 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
330 for (p = 0; p < m->jcodelength; p = nextp) {
332 /* mark this position as a valid instruction start */
334 pd.instructionstart[p] = 1;
336 /* change the current line number, if necessary */
338 /* XXX rewrite this using pointer arithmetic */
340 if (linepcchange == p) {
341 if (m->linenumbercount > lineindex) {
343 currentline = m->linenumbers[lineindex].line_number;
345 if (lineindex < m->linenumbercount) {
346 linepcchange = m->linenumbers[lineindex].start_pc;
347 if (linepcchange == p)
348 goto next_linenumber;
354 /* fetch next opcode */
356 opcode = SUCK_BE_U1(m->jcode + p);
358 /* some compilers put a JAVA_NOP after a blockend instruction */
360 if (blockend && (opcode != JAVA_NOP)) {
361 /* start new block */
367 if (JITDATA_HAS_FLAG_REORDER(jd)) {
368 /* We need a NOP as last instruction in each basic block
369 for basic block reordering (may be replaced with a GOTO
372 if (jd->basicblockindex[p] & 1) {
373 INSTRUCTIONS_CHECK(1);
378 /* store intermediate instruction count (bit 0 mark block starts) */
380 jd->basicblockindex[p] |= (ipc << 1);
382 /* compute next instruction start */
384 nextp = p + jcommandsize[opcode];
386 CHECK_END_OF_BYTECODE(nextp);
388 /* add stack elements produced by this instruction */
390 s_count += stackreq[opcode];
392 /* We check here for the space of 1 instruction in the
393 instruction array. If an opcode is converted to more than
394 1 instruction, this is checked in the corresponding
397 INSTRUCTIONS_CHECK(1);
399 /* translate this bytecode instruction */
405 /* pushing constants onto the stack ***********************************/
408 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
412 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
416 i = SUCK_BE_U1(m->jcode + p + 1);
417 goto pushconstantitem;
421 i = SUCK_BE_U2(m->jcode + p + 1);
425 #if defined(ENABLE_VERIFIER)
426 if (i >= m->class->cpcount) {
427 exceptions_throw_verifyerror(m,
428 "Attempt to access constant outside range");
433 switch (m->class->cptags[i]) {
434 case CONSTANT_Integer:
435 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
438 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
441 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
443 case CONSTANT_Double:
444 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
446 case CONSTANT_String:
447 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
450 cr = (constant_classref *) (m->class->cpinfos[i]);
452 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
455 /* if not resolved, c == NULL */
457 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
461 #if defined(ENABLE_VERIFIER)
463 exceptions_throw_verifyerror(m,
464 "Invalid constant type to push");
470 case JAVA_ACONST_NULL:
481 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
486 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
492 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
497 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
500 /* stack operations ***************************************************/
502 /* We need space for additional ICMDs so we can translate these */
503 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
506 INSTRUCTIONS_CHECK(4);
514 INSTRUCTIONS_CHECK(6);
524 INSTRUCTIONS_CHECK(2);
530 INSTRUCTIONS_CHECK(7);
541 INSTRUCTIONS_CHECK(9);
554 INSTRUCTIONS_CHECK(3);
560 /* local variable access instructions *********************************/
565 if (iswide == false) {
566 i = SUCK_BE_U1(m->jcode + p + 1);
569 i = SUCK_BE_U2(m->jcode + p + 1);
573 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
578 if (iswide == false) {
579 i = SUCK_BE_U1(m->jcode + p + 1);
582 i = SUCK_BE_U2(m->jcode + p + 1);
586 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
593 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
600 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
607 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
614 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
621 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
627 if (iswide == false) {
628 i = SUCK_BE_U1(m->jcode + p + 1);
631 i = SUCK_BE_U2(m->jcode + p + 1);
635 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
640 if (iswide == false) {
641 i = SUCK_BE_U1(m->jcode + p + 1);
644 i = SUCK_BE_U2(m->jcode + p + 1);
648 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
655 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
662 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
669 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
676 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
683 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
690 if (iswide == false) {
691 i = SUCK_BE_U1(m->jcode + p + 1);
692 v = SUCK_BE_S1(m->jcode + p + 2);
696 i = SUCK_BE_U2(m->jcode + p + 1);
697 v = SUCK_BE_S2(m->jcode + p + 3);
702 LOCALTYPE_USED(i, TYPE_INT);
703 OP_LOCALINDEX_I(opcode, i, v);
707 /* wider index for loading, storing and incrementing ******************/
714 /* managing arrays ****************************************************/
717 switch (SUCK_BE_S1(m->jcode + p + 1)) {
719 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
722 bte = builtintable_get_internal(BUILTIN_newarray_char);
725 bte = builtintable_get_internal(BUILTIN_newarray_float);
728 bte = builtintable_get_internal(BUILTIN_newarray_double);
731 bte = builtintable_get_internal(BUILTIN_newarray_byte);
734 bte = builtintable_get_internal(BUILTIN_newarray_short);
737 bte = builtintable_get_internal(BUILTIN_newarray_int);
740 bte = builtintable_get_internal(BUILTIN_newarray_long);
742 #if defined(ENABLE_VERIFIER)
744 exceptions_throw_verifyerror(m, "Invalid array-type to create");
748 OP_BUILTIN_CHECK_EXCEPTION(bte);
752 i = SUCK_BE_U2(m->jcode + p + 1);
753 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
757 if (!(cr = class_get_classref_multiarray_of(1, compr)))
760 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
763 INSTRUCTIONS_CHECK(2);
764 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
765 bte = builtintable_get_internal(BUILTIN_newarray);
766 OP_BUILTIN_CHECK_EXCEPTION(bte);
770 case JAVA_MULTIANEWARRAY:
771 jd->isleafmethod = false;
772 i = SUCK_BE_U2(m->jcode + p + 1);
773 j = SUCK_BE_U1(m->jcode + p + 3);
775 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
779 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
782 /* if unresolved, c == NULL */
784 iptr->s1.argcount = j;
785 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
788 /* control flow instructions ******************************************/
807 i = p + SUCK_BE_S2(m->jcode + p + 1);
808 CHECK_BYTECODE_INDEX(i);
811 OP_INSINDEX(opcode, i);
815 i = p + SUCK_BE_S4(m->jcode + p + 1);
816 CHECK_BYTECODE_INDEX(i);
819 OP_INSINDEX(opcode, i);
823 i = p + SUCK_BE_S2(m->jcode + p + 1);
825 CHECK_BYTECODE_INDEX(i);
828 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
829 iptr->sx.s23.s3.jsrtarget.insindex = i;
834 i = p + SUCK_BE_S4(m->jcode + p + 1);
838 if (iswide == false) {
839 i = SUCK_BE_U1(m->jcode + p + 1);
842 i = SUCK_BE_U2(m->jcode + p + 1);
848 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
858 /* XXX ARETURN will need a flag in the typechecker */
864 /* XXX ATHROW will need a flag in the typechecker */
869 /* table jumps ********************************************************/
871 case JAVA_LOOKUPSWITCH:
874 lookup_target_t *lookup;
875 #if defined(ENABLE_VERIFIER)
879 nextp = ALIGN((p + 1), 4);
881 CHECK_END_OF_BYTECODE(nextp + 8);
883 OP_PREPARE_ZEROFLAGS(opcode);
887 j = p + SUCK_BE_S4(m->jcode + nextp);
888 iptr->sx.s23.s3.lookupdefault.insindex = j;
890 CHECK_BYTECODE_INDEX(j);
893 /* number of pairs */
895 num = SUCK_BE_U4(m->jcode + nextp);
896 iptr->sx.s23.s2.lookupcount = num;
899 /* allocate the intermediate code table */
901 lookup = DMNEW(lookup_target_t, num);
902 iptr->dst.lookup = lookup;
904 /* iterate over the lookup table */
906 CHECK_END_OF_BYTECODE(nextp + 8 * num);
908 for (i = 0; i < num; i++) {
911 j = SUCK_BE_S4(m->jcode + nextp);
916 #if defined(ENABLE_VERIFIER)
917 /* check if the lookup table is sorted correctly */
919 if (i && (j <= prevvalue)) {
920 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
927 j = p + SUCK_BE_S4(m->jcode + nextp);
928 lookup->target.insindex = j;
931 CHECK_BYTECODE_INDEX(j);
940 case JAVA_TABLESWITCH:
944 branch_target_t *table;
947 nextp = ALIGN((p + 1), 4);
949 CHECK_END_OF_BYTECODE(nextp + 12);
951 OP_PREPARE_ZEROFLAGS(opcode);
955 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
957 CHECK_BYTECODE_INDEX(deftarget);
958 MARK_BASICBLOCK(deftarget);
962 j = SUCK_BE_S4(m->jcode + nextp);
963 iptr->sx.s23.s2.tablelow = j;
968 num = SUCK_BE_S4(m->jcode + nextp);
969 iptr->sx.s23.s3.tablehigh = num;
972 /* calculate the number of table entries */
976 #if defined(ENABLE_VERIFIER)
978 exceptions_throw_verifyerror(m,
979 "invalid TABLESWITCH: upper bound < lower bound");
983 /* create the intermediate code table */
984 /* the first entry is the default target */
986 table = MNEW(branch_target_t, 1 + num);
987 iptr->dst.table = table;
988 (table++)->insindex = deftarget;
990 /* iterate over the target table */
992 CHECK_END_OF_BYTECODE(nextp + 4 * num);
994 for (i = 0; i < num; i++) {
995 j = p + SUCK_BE_S4(m->jcode + nextp);
996 (table++)->insindex = j;
998 CHECK_BYTECODE_INDEX(j);
1007 /* load and store of object fields ************************************/
1011 jd->isleafmethod = false;
1014 case JAVA_GETSTATIC:
1015 case JAVA_PUTSTATIC:
1019 constant_FMIref *fr;
1020 unresolved_field *uf;
1022 i = SUCK_BE_U2(m->jcode + p + 1);
1023 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1027 OP_PREPARE_ZEROFLAGS(opcode);
1028 iptr->sx.s23.s3.fmiref = fr;
1030 /* only with -noverify, otherwise the typechecker does this */
1032 #if defined(ENABLE_VERIFIER)
1033 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1035 result = resolve_field_lazy(jd, iptr, m);
1036 if (result == resolveFailed)
1039 if (result != resolveSucceeded) {
1040 uf = create_unresolved_field(m->class, m, iptr);
1045 /* store the unresolved_field pointer */
1047 iptr->sx.s23.s3.uf = uf;
1048 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1050 #if defined(ENABLE_VERIFIER)
1058 /* method invocation **************************************************/
1060 case JAVA_INVOKESTATIC:
1061 i = SUCK_BE_U2(m->jcode + p + 1);
1062 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1067 md = mr->parseddesc.md;
1069 if (md->params == NULL)
1070 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1075 case JAVA_INVOKEINTERFACE:
1076 i = SUCK_BE_U2(m->jcode + p + 1);
1078 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1080 goto invoke_nonstatic_method;
1082 case JAVA_INVOKESPECIAL:
1083 case JAVA_INVOKEVIRTUAL:
1084 i = SUCK_BE_U2(m->jcode + p + 1);
1085 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1087 invoke_nonstatic_method:
1091 md = mr->parseddesc.md;
1093 if (md->params == NULL)
1094 if (!descriptor_params_from_paramtypes(md, 0))
1098 jd->isleafmethod = false;
1100 OP_PREPARE_ZEROFLAGS(opcode);
1101 iptr->sx.s23.s3.fmiref = mr;
1103 /* only with -noverify, otherwise the typechecker does this */
1105 #if defined(ENABLE_VERIFIER)
1106 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1108 result = resolve_method_lazy(jd, iptr, m);
1109 if (result == resolveFailed)
1112 if (result != resolveSucceeded) {
1113 um = create_unresolved_method(m->class, m, iptr);
1118 /* store the unresolved_method pointer */
1120 iptr->sx.s23.s3.um = um;
1121 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1123 #if defined(ENABLE_VERIFIER)
1129 /* instructions taking class arguments ********************************/
1132 i = SUCK_BE_U2(m->jcode + p + 1);
1133 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1137 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1140 INSTRUCTIONS_CHECK(2);
1141 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1142 bte = builtintable_get_internal(BUILTIN_new);
1143 OP_BUILTIN_CHECK_EXCEPTION(bte);
1147 case JAVA_CHECKCAST:
1148 i = SUCK_BE_U2(m->jcode + p + 1);
1149 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1153 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1156 if (cr->name->text[0] == '[') {
1157 /* array type cast-check */
1158 flags = INS_FLAG_ARRAY;
1159 jd->isleafmethod = false;
1162 /* object type cast-check */
1165 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1168 case JAVA_INSTANCEOF:
1169 i = SUCK_BE_U2(m->jcode + p + 1);
1170 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1174 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1177 if (cr->name->text[0] == '[') {
1178 /* array type cast-check */
1179 INSTRUCTIONS_CHECK(2);
1180 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1181 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1182 OP_BUILTIN_NO_EXCEPTION(bte);
1186 /* object type cast-check */
1187 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1191 /* synchronization instructions ***************************************/
1193 case JAVA_MONITORENTER:
1194 #if defined(ENABLE_THREADS)
1196 bte = builtintable_get_internal(LOCK_monitor_enter);
1197 OP_BUILTIN_CHECK_EXCEPTION(bte);
1202 OP(ICMD_CHECKNULL_POP);
1206 case JAVA_MONITOREXIT:
1207 #if defined(ENABLE_THREADS)
1209 bte = builtintable_get_internal(LOCK_monitor_exit);
1210 OP_BUILTIN_CHECK_EXCEPTION(bte);
1215 OP(ICMD_CHECKNULL_POP);
1219 /* arithmetic instructions that may become builtin functions **********/
1222 #if !SUPPORT_DIVISION
1223 bte = builtintable_get_internal(BUILTIN_idiv);
1224 OP_BUILTIN_ARITHMETIC(opcode, bte);
1231 #if !SUPPORT_DIVISION
1232 bte = builtintable_get_internal(BUILTIN_irem);
1233 OP_BUILTIN_ARITHMETIC(opcode, bte);
1240 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1241 bte = builtintable_get_internal(BUILTIN_ldiv);
1242 OP_BUILTIN_ARITHMETIC(opcode, bte);
1249 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1250 bte = builtintable_get_internal(BUILTIN_lrem);
1251 OP_BUILTIN_ARITHMETIC(opcode, bte);
1258 #if defined(__I386__)
1261 bte = builtintable_get_internal(BUILTIN_frem);
1262 OP_BUILTIN_NO_EXCEPTION(bte);
1267 #if defined(__I386__)
1270 bte = builtintable_get_internal(BUILTIN_drem);
1271 OP_BUILTIN_NO_EXCEPTION(bte);
1276 #if defined(__ALPHA__)
1278 bte = builtintable_get_internal(BUILTIN_f2i);
1279 OP_BUILTIN_NO_EXCEPTION(bte);
1289 #if defined(__ALPHA__)
1291 bte = builtintable_get_internal(BUILTIN_f2l);
1292 OP_BUILTIN_NO_EXCEPTION(bte);
1302 #if defined(__ALPHA__)
1304 bte = builtintable_get_internal(BUILTIN_d2i);
1305 OP_BUILTIN_NO_EXCEPTION(bte);
1315 #if defined(__ALPHA__)
1317 bte = builtintable_get_internal(BUILTIN_d2l);
1318 OP_BUILTIN_NO_EXCEPTION(bte);
1327 /* invalid opcodes ****************************************************/
1329 /* check for invalid opcodes if the verifier is enabled */
1330 #if defined(ENABLE_VERIFIER)
1331 case JAVA_BREAKPOINT:
1332 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1335 case 186: /* unused opcode */
1389 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1393 #endif /* defined(ENABLE_VERIFIER) */
1395 /* opcodes that don't require translation *****************************/
1398 /* straight-forward translation to ICMD */
1404 /* verifier checks ****************************************************/
1406 #if defined(ENABLE_VERIFIER)
1407 /* If WIDE was used correctly, iswide should have been reset by now. */
1409 exceptions_throw_verifyerror(m,
1410 "Illegal instruction: WIDE before incompatible opcode");
1413 #endif /* defined(ENABLE_VERIFIER) */
1417 if (JITDATA_HAS_FLAG_REORDER(jd)) {
1418 /* add a NOP to the last basic block */
1420 INSTRUCTIONS_CHECK(1);
1424 /*** END OF LOOP **********************************************************/
1426 /* assert that we did not write more ICMDs than allocated */
1428 assert(ipc <= pd.instructionslength);
1429 assert(ipc == (iptr - pd.instructions));
1431 /*** verifier checks ******************************************************/
1433 #if defined(ENABLE_VERIFIER)
1434 if (p != m->jcodelength) {
1435 exceptions_throw_verifyerror(m,
1436 "Command-sequence crosses code-boundary");
1441 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1444 #endif /* defined(ENABLE_VERIFIER) */
1446 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1448 /* adjust block count if target 0 is not first intermediate instruction */
1450 if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1))
1453 /* copy local to method variables */
1455 jd->instructions = pd.instructions;
1456 jd->instructioncount = ipc;
1457 jd->basicblockcount = b_count;
1458 jd->stackcount = s_count + jd->basicblockcount * m->maxstack; /* in-stacks */
1460 /* allocate stack table */
1462 jd->stack = DMNEW(stackelement, jd->stackcount);
1464 /* build basic block list */
1466 bptr = jd->basicblocks = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1468 /* zero out all basic block structures */
1470 MZERO(bptr, basicblock, b_count + 1);
1475 /* additional block if target 0 is not first intermediate instruction */
1477 if (!jd->basicblockindex[0] || (jd->basicblockindex[0] > 1)) {
1478 BASICBLOCK_INIT(bptr, m);
1480 bptr->iinstr = jd->instructions;
1481 /* bptr->icount is set when the next block is allocated */
1485 bptr[-1].next = bptr;
1488 /* allocate blocks */
1490 for (p = 0; p < m->jcodelength; p++) {
1491 if (jd->basicblockindex[p] & 1) {
1492 #if defined(ENABLE_VERIFIER)
1493 /* Check if this block starts at the beginning of an
1496 if (!pd.instructionstart[p]) {
1497 exceptions_throw_verifyerror(m,
1498 "Branch into middle of instruction");
1503 /* allocate the block */
1505 BASICBLOCK_INIT(bptr, m);
1507 bptr->iinstr = jd->instructions + (jd->basicblockindex[p] >> 1);
1509 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1511 /* bptr->icount is set when the next block is allocated */
1513 jd->basicblockindex[p] = b_count;
1517 bptr[-1].next = bptr;
1521 /* set instruction count of last real block */
1524 bptr[-1].icount = (jd->instructions + jd->instructioncount) - bptr[-1].iinstr;
1527 /* allocate additional block at end */
1529 BASICBLOCK_INIT(bptr,m);
1531 /* set basicblock pointers in exception table */
1533 if (cd->exceptiontablelength > 0) {
1534 cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1537 for (i = 0; i < cd->exceptiontablelength; ++i) {
1538 p = cd->exceptiontable[i].startpc;
1539 cd->exceptiontable[i].start = jd->basicblocks + jd->basicblockindex[p];
1541 p = cd->exceptiontable[i].endpc;
1542 cd->exceptiontable[i].end = (p == m->jcodelength) ? (jd->basicblocks + jd->basicblockcount /*+ 1*/) : (jd->basicblocks + jd->basicblockindex[p]);
1544 p = cd->exceptiontable[i].handlerpc;
1545 cd->exceptiontable[i].handler = jd->basicblocks + jd->basicblockindex[p];
1548 /* XXX activate this if you want to try inlining */
1550 for (i = 0; i < m->exceptiontablelength; ++i) {
1551 p = m->exceptiontable[i].startpc;
1552 m->exceptiontable[i].start = jd->basicblocks + jd->basicblockindex[p];
1554 p = m->exceptiontable[i].endpc;
1555 m->exceptiontable[i].end = (p == m->jcodelength) ? (jd->basicblocks + jd->basicblockcount /*+ 1*/) : (jd->basicblocks + jd->basicblockindex[p]);
1557 p = m->exceptiontable[i].handlerpc;
1558 m->exceptiontable[i].handler = jd->basicblocks + jd->basicblockindex[p];
1562 jd->local_map = local_map;
1564 /* calculate local variable renaming */
1574 /* iterate over local_map[0..m->maxlocals*5] and set all existing */
1575 /* index,type pairs (local_map[index*5+type]==1) to an unique value */
1576 /* -> == new local var index */
1577 for(i = 0; i < (cd->maxlocals * 5); i++, mapptr++) {
1579 *mapptr = nlocals++;
1584 jd->localcount = nlocals;
1586 /* calculate the (maximum) number of variables needed */
1589 nlocals /* local variables */
1590 + jd->basicblockcount * m->maxstack /* invars */
1591 + s_count; /* variables created within blocks (non-invar) */
1593 /* reserve the first indices for local variables */
1595 jd->vartop = nlocals;
1597 /* The verifier needs space for saving invars in some cases and */
1598 /* extra variables. */
1600 #if defined(ENABLE_VERIFIER)
1601 if (JITDATA_HAS_FLAG_VERIFY(jd)) {
1602 jd->varcount += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1603 jd->vartop += VERIFIER_EXTRA_LOCALS + VERIFIER_EXTRA_VARS + m->maxstack;
1606 /* allocate and initialize the variable array */
1608 jd->var = DMNEW(varinfo, jd->varcount);
1609 MZERO(jd->var, varinfo, jd->varcount);
1611 /* set types of all locals in jd->var */
1613 for(mapptr = local_map, i = 0; i < (cd->maxlocals * 5); i++, mapptr++)
1614 if (*mapptr != UNUSED)
1615 VAR(*mapptr)->type = i%5;
1618 /* everything's ok */
1622 /*** goto labels for throwing verifier exceptions *************************/
1624 #if defined(ENABLE_VERIFIER)
1626 throw_unexpected_end_of_bytecode:
1627 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1630 throw_invalid_bytecode_index:
1631 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1634 throw_illegal_local_variable_number:
1635 exceptions_throw_verifyerror(m, "Illegal local variable number");
1638 #endif /* ENABLE_VERIFIER */
1643 * These are local overrides for various environment variables in Emacs.
1644 * Please do not remove this and leave it at the end of the file, where
1645 * Emacs will automagically detect them.
1646 * ---------------------------------------------------------------------
1649 * indent-tabs-mode: t
1653 * vim:noexpandtab:sw=4:ts=4: