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 5418 2006-09-08 12:10:39Z 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->new_basicblockindex = DMNEW(s4, m->jcodelength + 1);
103 pd->instructionstart = DMNEW(u1, m->jcodelength + 1);
105 MZERO(jd->new_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_check_instructions ****************************************************
126 Checks if there's enough room in the instructions array for the
127 required instructions. If not, reallocate the data structures.
129 *******************************************************************************/
131 static instruction *parse_check_instructions(parsedata_t *pd, s4 ipc)
133 /* increase the size of the instruction array */
135 pd->instructionslength += INSTRUCTIONS_INCREMENT;
137 /* reallocate the array */
139 pd->instructions = DMREALLOC(pd->instructions, instruction, ipc,
140 pd->instructionslength);
142 /* return the iptr */
144 return pd->instructions + ipc;
148 /*******************************************************************************
150 function 'parse' scans the JavaVM code and generates intermediate code
152 During parsing the block index table is used to store at bit pos 0
153 a flag which marks basic block starts and at position 1 to 31 the
154 intermediate instruction index. After parsing the block index table
155 is scanned, for marked positions a block is generated and the block
156 number is stored in the block index table.
158 *******************************************************************************/
160 static exceptiontable * new_fillextable(
163 exceptiontable *extable,
164 exceptiontable *raw_extable,
165 int exceptiontablelength,
170 if (exceptiontablelength == 0)
173 b_count = *block_count;
175 for (src = exceptiontablelength-1; src >=0; src--) {
176 /* the start of the handled region becomes a basic block start */
177 p = raw_extable[src].startpc;
178 CHECK_BYTECODE_INDEX(p);
179 extable->startpc = p;
182 p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
183 CHECK_BYTECODE_INDEX_EXCLUSIVE(p);
185 #if defined(ENABLE_VERIFIER)
186 if (p <= raw_extable[src].startpc) {
187 exceptions_throw_verifyerror(m,
188 "Invalid exception handler range");
194 /* end of handled region becomes a basic block boundary */
195 /* (If it is the bytecode end, we'll use the special */
196 /* end block that is created anyway.) */
197 if (p < m->jcodelength)
200 /* the start of the handler becomes a basic block start */
201 p = raw_extable[src].handlerpc;
202 CHECK_BYTECODE_INDEX(p);
203 extable->handlerpc = p;
206 extable->catchtype = raw_extable[src].catchtype;
207 extable->next = NULL;
208 extable->down = &extable[1];
212 *block_count = b_count;
217 #if defined(ENABLE_VERIFIER)
218 throw_invalid_bytecode_index:
219 exceptions_throw_verifyerror(m,
220 "Illegal bytecode index in exception table");
225 /*** macro for checking the length of the bytecode ***/
227 #if defined(ENABLE_VERIFIER)
228 #define CHECK_END_OF_BYTECODE(neededlength) \
230 if ((neededlength) > m->jcodelength) \
231 goto throw_unexpected_end_of_bytecode; \
233 #else /* !ENABLE_VERIFIER */
234 #define CHECK_END_OF_BYTECODE(neededlength)
235 #endif /* ENABLE_VERIFIER */
237 bool new_parse(jitdata *jd)
239 methodinfo *m; /* method being parsed */
243 instruction *iptr; /* current ptr into instruction array */
244 s4 ipc; /* intermediate instruction counter */
245 s4 p; /* java instruction counter */
246 s4 nextp; /* start of next java instruction */
247 s4 opcode; /* java opcode */
250 int b_count = 0; /* basic block counter */
251 int s_count = 0; /* stack element counter */
252 bool blockend = false; /* true if basic block end has been reached */
253 bool iswide = false; /* true if last instruction was a wide */
254 constant_classref *cr;
255 constant_classref *compr;
257 builtintable_entry *bte;
260 unresolved_method *um;
261 resolve_result_t result;
269 int *local_map; /* local pointer to renaming structore */
270 /* is assigned to rd->local_map at the end */
272 /* 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;
290 /* initialize the parse data structures */
292 parse_setup(jd, &pd);
294 /* initialize local variables */
296 iptr = pd.instructions;
299 /* compute branch targets of exception table */
301 if (!new_fillextable(jd, m,
302 &(cd->exceptiontable[cd->exceptiontablelength-1]),
304 m->exceptiontablelength,
310 s_count = 1 + m->exceptiontablelength; /* initialize stack element counter */
312 #if defined(ENABLE_THREADS)
313 if (checksync && (m->flags & ACC_SYNCHRONIZED))
314 jd->isleafmethod = false;
317 /* setup line number info */
322 if (m->linenumbercount == 0) {
326 linepcchange = m->linenumbers[0].start_pc;
329 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
331 for (p = 0; p < m->jcodelength; p = nextp) {
333 /* mark this position as a valid instruction start */
335 pd.instructionstart[p] = 1;
337 /* change the current line number, if necessary */
339 /* XXX rewrite this using pointer arithmetic */
341 if (linepcchange == p) {
342 if (m->linenumbercount > lineindex) {
344 currentline = m->linenumbers[lineindex].line_number;
346 if (lineindex < m->linenumbercount) {
347 linepcchange = m->linenumbers[lineindex].start_pc;
348 if (linepcchange == p)
349 goto next_linenumber;
355 /* fetch next opcode */
357 opcode = SUCK_BE_U1(m->jcode + p);
359 /* some compilers put a JAVA_NOP after a blockend instruction */
361 if (blockend && (opcode != JAVA_NOP)) {
362 /* start new block */
368 /* store intermediate instruction count (bit 0 mark block starts) */
370 jd->new_basicblockindex[p] |= (ipc << 1);
372 /* compute next instruction start */
374 nextp = p + jcommandsize[opcode];
376 CHECK_END_OF_BYTECODE(nextp);
378 /* add stack elements produced by this instruction */
380 s_count += stackreq[opcode];
382 /* We check here for the space of 1 instruction in the
383 instruction array. If an opcode is converted to more than
384 1 instruction, this is checked in the corresponding
387 INSTRUCTIONS_CHECK(1);
389 /* translate this bytecode instruction */
395 /* pushing constants onto the stack ***********************************/
398 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
402 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
406 i = SUCK_BE_U1(m->jcode + p + 1);
407 goto pushconstantitem;
411 i = SUCK_BE_U2(m->jcode + p + 1);
415 #if defined(ENABLE_VERIFIER)
416 if (i >= m->class->cpcount) {
417 exceptions_throw_verifyerror(m,
418 "Attempt to access constant outside range");
423 switch (m->class->cptags[i]) {
424 case CONSTANT_Integer:
425 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
428 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
431 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
433 case CONSTANT_Double:
434 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
436 case CONSTANT_String:
437 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
440 cr = (constant_classref *) (m->class->cpinfos[i]);
442 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
445 /* if not resolved, c == NULL */
447 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
451 #if defined(ENABLE_VERIFIER)
453 exceptions_throw_verifyerror(m,
454 "Invalid constant type to push");
460 case JAVA_ACONST_NULL:
471 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
476 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
482 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
487 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
490 /* stack operations ***************************************************/
492 /* We need space for additional ICMDs so we can translate these */
493 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
496 INSTRUCTIONS_CHECK(3);
503 INSTRUCTIONS_CHECK(4);
511 INSTRUCTIONS_CHECK(2);
517 INSTRUCTIONS_CHECK(5);
526 INSTRUCTIONS_CHECK(6);
536 INSTRUCTIONS_CHECK(2);
541 /* local variable access instructions *********************************/
546 if (iswide == false) {
547 i = SUCK_BE_U1(m->jcode + p + 1);
550 i = SUCK_BE_U2(m->jcode + p + 1);
554 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
559 if (iswide == false) {
560 i = SUCK_BE_U1(m->jcode + p + 1);
563 i = SUCK_BE_U2(m->jcode + p + 1);
567 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
574 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
581 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
588 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
595 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
602 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
608 if (iswide == false) {
609 i = SUCK_BE_U1(m->jcode + p + 1);
612 i = SUCK_BE_U2(m->jcode + p + 1);
616 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
621 if (iswide == false) {
622 i = SUCK_BE_U1(m->jcode + p + 1);
625 i = SUCK_BE_U2(m->jcode + p + 1);
629 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
636 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
643 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
650 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
657 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
664 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
671 if (iswide == false) {
672 i = SUCK_BE_U1(m->jcode + p + 1);
673 v = SUCK_BE_S1(m->jcode + p + 2);
677 i = SUCK_BE_U2(m->jcode + p + 1);
678 v = SUCK_BE_S2(m->jcode + p + 3);
683 LOCALTYPE_USED(i, TYPE_INT);
684 OP_LOCALINDEX_I(opcode, i, v);
688 /* wider index for loading, storing and incrementing ******************/
695 /* managing arrays ****************************************************/
698 switch (SUCK_BE_S1(m->jcode + p + 1)) {
700 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
703 bte = builtintable_get_internal(BUILTIN_newarray_char);
706 bte = builtintable_get_internal(BUILTIN_newarray_float);
709 bte = builtintable_get_internal(BUILTIN_newarray_double);
712 bte = builtintable_get_internal(BUILTIN_newarray_byte);
715 bte = builtintable_get_internal(BUILTIN_newarray_short);
718 bte = builtintable_get_internal(BUILTIN_newarray_int);
721 bte = builtintable_get_internal(BUILTIN_newarray_long);
723 #if defined(ENABLE_VERIFIER)
725 exceptions_throw_verifyerror(m, "Invalid array-type to create");
729 OP_BUILTIN_CHECK_EXCEPTION(bte);
733 i = SUCK_BE_U2(m->jcode + p + 1);
734 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
738 if (!(cr = class_get_classref_multiarray_of(1, compr)))
741 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
744 INSTRUCTIONS_CHECK(2);
745 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
746 bte = builtintable_get_internal(BUILTIN_newarray);
747 OP_BUILTIN_CHECK_EXCEPTION(bte);
751 case JAVA_MULTIANEWARRAY:
752 jd->isleafmethod = false;
753 i = SUCK_BE_U2(m->jcode + p + 1);
754 j = SUCK_BE_U1(m->jcode + p + 3);
756 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
760 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
763 /* if unresolved, c == NULL */
765 iptr->s1.argcount = j;
766 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
769 /* control flow instructions ******************************************/
788 i = p + SUCK_BE_S2(m->jcode + p + 1);
789 CHECK_BYTECODE_INDEX(i);
792 OP_INSINDEX(opcode, i);
796 i = p + SUCK_BE_S4(m->jcode + p + 1);
797 CHECK_BYTECODE_INDEX(i);
800 OP_INSINDEX(opcode, i);
804 i = p + SUCK_BE_S2(m->jcode + p + 1);
806 CHECK_BYTECODE_INDEX(i);
809 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
810 iptr->sx.s23.s3.jsrtarget.insindex = i;
815 i = p + SUCK_BE_S4(m->jcode + p + 1);
819 if (iswide == false) {
820 i = SUCK_BE_U1(m->jcode + p + 1);
823 i = SUCK_BE_U2(m->jcode + p + 1);
829 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
839 /* XXX ARETURN will need a flag in the typechecker */
845 /* XXX ATHROW will need a flag in the typechecker */
850 /* table jumps ********************************************************/
852 case JAVA_LOOKUPSWITCH:
855 lookup_target_t *lookup;
856 #if defined(ENABLE_VERIFIER)
860 nextp = ALIGN((p + 1), 4);
862 CHECK_END_OF_BYTECODE(nextp + 8);
864 OP_PREPARE_ZEROFLAGS(opcode);
868 j = p + SUCK_BE_S4(m->jcode + nextp);
869 iptr->sx.s23.s3.lookupdefault.insindex = j;
871 CHECK_BYTECODE_INDEX(j);
874 /* number of pairs */
876 num = SUCK_BE_U4(m->jcode + nextp);
877 iptr->sx.s23.s2.lookupcount = num;
880 /* allocate the intermediate code table */
882 lookup = DMNEW(lookup_target_t, num);
883 iptr->dst.lookup = lookup;
885 /* iterate over the lookup table */
887 CHECK_END_OF_BYTECODE(nextp + 8 * num);
889 for (i = 0; i < num; i++) {
892 j = SUCK_BE_S4(m->jcode + nextp);
897 #if defined(ENABLE_VERIFIER)
898 /* check if the lookup table is sorted correctly */
900 if (i && (j <= prevvalue)) {
901 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
908 j = p + SUCK_BE_S4(m->jcode + nextp);
909 lookup->target.insindex = j;
912 CHECK_BYTECODE_INDEX(j);
921 case JAVA_TABLESWITCH:
925 branch_target_t *table;
928 nextp = ALIGN((p + 1), 4);
930 CHECK_END_OF_BYTECODE(nextp + 12);
932 OP_PREPARE_ZEROFLAGS(opcode);
936 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
938 CHECK_BYTECODE_INDEX(deftarget);
939 MARK_BASICBLOCK(deftarget);
943 j = SUCK_BE_S4(m->jcode + nextp);
944 iptr->sx.s23.s2.tablelow = j;
949 num = SUCK_BE_S4(m->jcode + nextp);
950 iptr->sx.s23.s3.tablehigh = num;
953 /* calculate the number of table entries */
957 #if defined(ENABLE_VERIFIER)
959 exceptions_throw_verifyerror(m,
960 "invalid TABLESWITCH: upper bound < lower bound");
964 /* create the intermediate code table */
965 /* the first entry is the default target */
967 table = MNEW(branch_target_t, 1 + num);
968 iptr->dst.table = table;
969 (table++)->insindex = deftarget;
971 /* iterate over the target table */
973 CHECK_END_OF_BYTECODE(nextp + 4 * num);
975 for (i = 0; i < num; i++) {
976 j = p + SUCK_BE_S4(m->jcode + nextp);
977 (table++)->insindex = j;
979 CHECK_BYTECODE_INDEX(j);
988 /* load and store of object fields ************************************/
992 jd->isleafmethod = false;
1000 constant_FMIref *fr;
1001 unresolved_field *uf;
1003 i = SUCK_BE_U2(m->jcode + p + 1);
1004 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1008 OP_PREPARE_ZEROFLAGS(opcode);
1009 iptr->sx.s23.s3.fmiref = fr;
1011 /* only with -noverify, otherwise the typechecker does this */
1013 #if defined(ENABLE_VERIFIER)
1014 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1016 result = new_resolve_field_lazy(iptr, m);
1017 if (result == resolveFailed)
1020 if (result != resolveSucceeded) {
1021 uf = new_create_unresolved_field(m->class, m, iptr);
1026 /* store the unresolved_field pointer */
1028 iptr->sx.s23.s3.uf = uf;
1029 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1031 #if defined(ENABLE_VERIFIER)
1039 /* method invocation **************************************************/
1041 case JAVA_INVOKESTATIC:
1042 i = SUCK_BE_U2(m->jcode + p + 1);
1043 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1048 md = mr->parseddesc.md;
1050 if (md->params == NULL)
1051 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1056 case JAVA_INVOKEINTERFACE:
1057 i = SUCK_BE_U2(m->jcode + p + 1);
1059 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1061 goto invoke_nonstatic_method;
1063 case JAVA_INVOKESPECIAL:
1064 case JAVA_INVOKEVIRTUAL:
1065 i = SUCK_BE_U2(m->jcode + p + 1);
1066 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1068 invoke_nonstatic_method:
1072 md = mr->parseddesc.md;
1074 if (md->params == NULL)
1075 if (!descriptor_params_from_paramtypes(md, 0))
1079 jd->isleafmethod = false;
1081 OP_PREPARE_ZEROFLAGS(opcode);
1082 iptr->sx.s23.s3.fmiref = mr;
1084 /* only with -noverify, otherwise the typechecker does this */
1086 #if defined(ENABLE_VERIFIER)
1087 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1089 result = new_resolve_method_lazy(iptr, m);
1090 if (result == resolveFailed)
1093 if (result != resolveSucceeded) {
1094 um = new_create_unresolved_method(m->class, m, iptr);
1099 /* store the unresolved_method pointer */
1101 iptr->sx.s23.s3.um = um;
1102 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1104 #if defined(ENABLE_VERIFIER)
1110 /* instructions taking class arguments ********************************/
1113 i = SUCK_BE_U2(m->jcode + p + 1);
1114 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1118 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1121 INSTRUCTIONS_CHECK(2);
1122 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1123 bte = builtintable_get_internal(BUILTIN_new);
1124 OP_BUILTIN_CHECK_EXCEPTION(bte);
1128 case JAVA_CHECKCAST:
1129 i = SUCK_BE_U2(m->jcode + p + 1);
1130 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1134 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1137 if (cr->name->text[0] == '[') {
1138 /* array type cast-check */
1139 flags = INS_FLAG_ARRAY;
1140 jd->isleafmethod = false;
1143 /* object type cast-check */
1146 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1149 case JAVA_INSTANCEOF:
1150 i = SUCK_BE_U2(m->jcode + p + 1);
1151 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1155 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1158 if (cr->name->text[0] == '[') {
1159 /* array type cast-check */
1160 INSTRUCTIONS_CHECK(2);
1161 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1162 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1163 OP_BUILTIN_NO_EXCEPTION(bte);
1167 /* object type cast-check */
1168 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1172 /* synchronization instructions ***************************************/
1174 case JAVA_MONITORENTER:
1175 #if defined(ENABLE_THREADS)
1177 bte = builtintable_get_internal(LOCK_monitor_enter);
1178 OP_BUILTIN_CHECK_EXCEPTION(bte);
1183 OP(ICMD_CHECKNULL_POP);
1187 case JAVA_MONITOREXIT:
1188 #if defined(ENABLE_THREADS)
1190 bte = builtintable_get_internal(LOCK_monitor_exit);
1191 OP_BUILTIN_CHECK_EXCEPTION(bte);
1196 OP(ICMD_CHECKNULL_POP);
1200 /* arithmetic instructions that may become builtin functions **********/
1203 #if !SUPPORT_DIVISION
1204 bte = builtintable_get_internal(BUILTIN_idiv);
1205 OP_BUILTIN_ARITHMETIC(opcode, bte);
1212 #if !SUPPORT_DIVISION
1213 bte = builtintable_get_internal(BUILTIN_irem);
1214 OP_BUILTIN_ARITHMETIC(opcode, bte);
1221 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1222 bte = builtintable_get_internal(BUILTIN_ldiv);
1223 OP_BUILTIN_ARITHMETIC(opcode, bte);
1230 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1231 bte = builtintable_get_internal(BUILTIN_lrem);
1232 OP_BUILTIN_ARITHMETIC(opcode, bte);
1239 #if defined(__I386__)
1242 bte = builtintable_get_internal(BUILTIN_frem);
1243 OP_BUILTIN_NO_EXCEPTION(bte);
1248 #if defined(__I386__)
1251 bte = builtintable_get_internal(BUILTIN_drem);
1252 OP_BUILTIN_NO_EXCEPTION(bte);
1257 #if defined(__ALPHA__)
1259 bte = builtintable_get_internal(BUILTIN_f2i);
1260 OP_BUILTIN_NO_EXCEPTION(bte);
1270 #if defined(__ALPHA__)
1272 bte = builtintable_get_internal(BUILTIN_f2l);
1273 OP_BUILTIN_NO_EXCEPTION(bte);
1283 #if defined(__ALPHA__)
1285 bte = builtintable_get_internal(BUILTIN_d2i);
1286 OP_BUILTIN_NO_EXCEPTION(bte);
1296 #if defined(__ALPHA__)
1298 bte = builtintable_get_internal(BUILTIN_d2l);
1299 OP_BUILTIN_NO_EXCEPTION(bte);
1308 /* invalid opcodes ****************************************************/
1310 /* check for invalid opcodes if the verifier is enabled */
1311 #if defined(ENABLE_VERIFIER)
1312 case JAVA_BREAKPOINT:
1313 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1316 case 186: /* unused opcode */
1370 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1374 #endif /* defined(ENABLE_VERIFIER) */
1376 /* opcodes that don't require translation *****************************/
1379 /* straight-forward translation to ICMD */
1385 /* verifier checks ****************************************************/
1387 #if defined(ENABLE_VERIFIER)
1388 /* If WIDE was used correctly, iswide should have been reset by now. */
1390 exceptions_throw_verifyerror(m,
1391 "Illegal instruction: WIDE before incompatible opcode");
1394 #endif /* defined(ENABLE_VERIFIER) */
1398 /* add a NOP to the last basic block */
1400 INSTRUCTIONS_CHECK(1);
1403 /*** END OF LOOP **********************************************************/
1405 /* assert that we did not write more ICMDs than allocated */
1407 assert(ipc <= pd.instructionslength);
1408 assert(ipc == (iptr - pd.instructions));
1410 /*** verifier checks ******************************************************/
1412 #if defined(ENABLE_VERIFIER)
1413 if (p != m->jcodelength) {
1414 exceptions_throw_verifyerror(m,
1415 "Command-sequence crosses code-boundary");
1420 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1423 #endif /* defined(ENABLE_VERIFIER) */
1425 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1427 /* adjust block count if target 0 is not first intermediate instruction */
1429 if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1))
1432 /* copy local to method variables */
1434 jd->new_instructions = pd.instructions;
1435 jd->new_instructioncount = ipc;
1436 jd->new_basicblockcount = b_count;
1437 jd->new_stackcount = s_count + jd->new_basicblockcount * m->maxstack; /* in-stacks */
1439 /* allocate stack table */
1441 jd->new_stack = DMNEW(stackelement, jd->new_stackcount);
1443 /* build basic block list */
1445 bptr = jd->new_basicblocks = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1447 /* zero out all basic block structures */
1449 MZERO(bptr, basicblock, b_count + 1);
1452 jd->new_c_debug_nr = 0;
1454 /* additional block if target 0 is not first intermediate instruction */
1456 if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1)) {
1457 BASICBLOCK_INIT(bptr, m);
1459 bptr->iinstr = jd->new_instructions;
1460 /* bptr->icount is set when the next block is allocated */
1464 bptr[-1].next = bptr;
1467 /* allocate blocks */
1469 for (p = 0; p < m->jcodelength; p++) {
1470 if (jd->new_basicblockindex[p] & 1) {
1471 #if defined(ENABLE_VERIFIER)
1472 /* Check if this block starts at the beginning of an
1475 if (!pd.instructionstart[p]) {
1476 exceptions_throw_verifyerror(m,
1477 "Branch into middle of instruction");
1482 /* allocate the block */
1484 BASICBLOCK_INIT(bptr, m);
1486 bptr->iinstr = jd->new_instructions + (jd->new_basicblockindex[p] >> 1);
1488 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1490 /* bptr->icount is set when the next block is allocated */
1492 jd->new_basicblockindex[p] = b_count;
1496 bptr[-1].next = bptr;
1500 /* set instruction count of last real block */
1503 bptr[-1].icount = (jd->new_instructions + jd->new_instructioncount) - bptr[-1].iinstr;
1506 /* allocate additional block at end */
1508 BASICBLOCK_INIT(bptr,m);
1510 /* set basicblock pointers in exception table */
1512 if (cd->exceptiontablelength > 0) {
1513 cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1516 for (i = 0; i < cd->exceptiontablelength; ++i) {
1517 p = cd->exceptiontable[i].startpc;
1518 cd->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
1520 p = cd->exceptiontable[i].endpc;
1521 cd->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
1523 p = cd->exceptiontable[i].handlerpc;
1524 cd->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
1527 /* XXX activate this if you want to try inlining */
1529 for (i = 0; i < m->exceptiontablelength; ++i) {
1530 p = m->exceptiontable[i].startpc;
1531 m->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
1533 p = m->exceptiontable[i].endpc;
1534 m->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
1536 p = m->exceptiontable[i].handlerpc;
1537 m->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
1541 #if defined(NEW_VAR)
1542 jd->local_map = local_map;
1544 /* calculate local variable renaming */
1554 /* iterate over local_map[0..m->maxlocals*5] and set all existing */
1555 /* index,type pairs (localmap[index*5+type]==1) to an unique value */
1556 /* -> == new local var index */
1557 for(i = 0; i < (cd->maxlocals * 5); i++, mapptr++) {
1559 *mapptr = nlocals++;
1564 jd->localcount = nlocals;
1565 /* if dropped varindices for temp stackslots get reused(?max 2* */
1566 /* m->maxstack elements for stack), nlocals + s_count would be */
1568 jd->varcount = nlocals + s_count +
1569 jd->new_basicblockcount * m->maxstack; /* out-stacks */
1571 jd->vartop = nlocals;
1572 jd->var = DMNEW(varinfo, jd->varcount);
1573 MZERO(jd->var, varinfo, jd->varcount);
1575 /* set types of all Locals in jd->var */
1576 for(mapptr = local_map, i = 0; i < (cd->maxlocals * 5); i++, mapptr++)
1577 if (*mapptr != UNUSED)
1578 jd->var[*mapptr].type = i%5;
1582 /* everything's ok */
1586 /*** goto labels for throwing verifier exceptions *************************/
1588 #if defined(ENABLE_VERIFIER)
1590 throw_unexpected_end_of_bytecode:
1591 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1594 throw_invalid_bytecode_index:
1595 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1598 throw_illegal_local_variable_number:
1599 exceptions_throw_verifyerror(m, "Illegal local variable number");
1602 #endif /* ENABLE_VERIFIER */
1607 * These are local overrides for various environment variables in Emacs.
1608 * Please do not remove this and leave it at the end of the file, where
1609 * Emacs will automagically detect them.
1610 * ---------------------------------------------------------------------
1613 * indent-tabs-mode: t
1617 * vim:noexpandtab:sw=4:ts=4: