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 5482 2006-09-12 21:34:03Z 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_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 * new_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 new_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 (!new_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 /* store intermediate instruction count (bit 0 mark block starts) */
369 jd->new_basicblockindex[p] |= (ipc << 1);
371 /* compute next instruction start */
373 nextp = p + jcommandsize[opcode];
375 CHECK_END_OF_BYTECODE(nextp);
377 /* add stack elements produced by this instruction */
379 s_count += stackreq[opcode];
381 /* We check here for the space of 1 instruction in the
382 instruction array. If an opcode is converted to more than
383 1 instruction, this is checked in the corresponding
386 INSTRUCTIONS_CHECK(1);
388 /* translate this bytecode instruction */
394 /* pushing constants onto the stack ***********************************/
397 OP_LOADCONST_I(SUCK_BE_S1(m->jcode + p + 1));
401 OP_LOADCONST_I(SUCK_BE_S2(m->jcode + p + 1));
405 i = SUCK_BE_U1(m->jcode + p + 1);
406 goto pushconstantitem;
410 i = SUCK_BE_U2(m->jcode + p + 1);
414 #if defined(ENABLE_VERIFIER)
415 if (i >= m->class->cpcount) {
416 exceptions_throw_verifyerror(m,
417 "Attempt to access constant outside range");
422 switch (m->class->cptags[i]) {
423 case CONSTANT_Integer:
424 OP_LOADCONST_I(((constant_integer *) (m->class->cpinfos[i]))->value);
427 OP_LOADCONST_L(((constant_long *) (m->class->cpinfos[i]))->value);
430 OP_LOADCONST_F(((constant_float *) (m->class->cpinfos[i]))->value);
432 case CONSTANT_Double:
433 OP_LOADCONST_D(((constant_double *) (m->class->cpinfos[i]))->value);
435 case CONSTANT_String:
436 OP_LOADCONST_STRING(literalstring_new((utf *) (m->class->cpinfos[i])));
439 cr = (constant_classref *) (m->class->cpinfos[i]);
441 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
444 /* if not resolved, c == NULL */
446 OP_LOADCONST_CLASSINFO_OR_CLASSREF_CHECK(c, cr);
450 #if defined(ENABLE_VERIFIER)
452 exceptions_throw_verifyerror(m,
453 "Invalid constant type to push");
459 case JAVA_ACONST_NULL:
470 OP_LOADCONST_I(opcode - JAVA_ICONST_0);
475 OP_LOADCONST_L(opcode - JAVA_LCONST_0);
481 OP_LOADCONST_F(opcode - JAVA_FCONST_0);
486 OP_LOADCONST_D(opcode - JAVA_DCONST_0);
489 /* stack operations ***************************************************/
491 /* We need space for additional ICMDs so we can translate these */
492 /* instructions to sequences of ICMD_COPY and ICMD_MOVE instructions. */
495 INSTRUCTIONS_CHECK(3);
502 INSTRUCTIONS_CHECK(4);
510 INSTRUCTIONS_CHECK(2);
516 INSTRUCTIONS_CHECK(5);
525 INSTRUCTIONS_CHECK(6);
535 INSTRUCTIONS_CHECK(2);
540 /* local variable access instructions *********************************/
545 if (iswide == false) {
546 i = SUCK_BE_U1(m->jcode + p + 1);
549 i = SUCK_BE_U2(m->jcode + p + 1);
553 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
558 if (iswide == false) {
559 i = SUCK_BE_U1(m->jcode + p + 1);
562 i = SUCK_BE_U2(m->jcode + p + 1);
566 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
573 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
580 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
587 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
594 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
601 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
607 if (iswide == false) {
608 i = SUCK_BE_U1(m->jcode + p + 1);
611 i = SUCK_BE_U2(m->jcode + p + 1);
615 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
620 if (iswide == false) {
621 i = SUCK_BE_U1(m->jcode + p + 1);
624 i = SUCK_BE_U2(m->jcode + p + 1);
628 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
635 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
642 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
649 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
656 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
663 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
670 if (iswide == false) {
671 i = SUCK_BE_U1(m->jcode + p + 1);
672 v = SUCK_BE_S1(m->jcode + p + 2);
676 i = SUCK_BE_U2(m->jcode + p + 1);
677 v = SUCK_BE_S2(m->jcode + p + 3);
682 LOCALTYPE_USED(i, TYPE_INT);
683 OP_LOCALINDEX_I(opcode, i, v);
687 /* wider index for loading, storing and incrementing ******************/
694 /* managing arrays ****************************************************/
697 switch (SUCK_BE_S1(m->jcode + p + 1)) {
699 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
702 bte = builtintable_get_internal(BUILTIN_newarray_char);
705 bte = builtintable_get_internal(BUILTIN_newarray_float);
708 bte = builtintable_get_internal(BUILTIN_newarray_double);
711 bte = builtintable_get_internal(BUILTIN_newarray_byte);
714 bte = builtintable_get_internal(BUILTIN_newarray_short);
717 bte = builtintable_get_internal(BUILTIN_newarray_int);
720 bte = builtintable_get_internal(BUILTIN_newarray_long);
722 #if defined(ENABLE_VERIFIER)
724 exceptions_throw_verifyerror(m, "Invalid array-type to create");
728 OP_BUILTIN_CHECK_EXCEPTION(bte);
732 i = SUCK_BE_U2(m->jcode + p + 1);
733 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
737 if (!(cr = class_get_classref_multiarray_of(1, compr)))
740 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
743 INSTRUCTIONS_CHECK(2);
744 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
745 bte = builtintable_get_internal(BUILTIN_newarray);
746 OP_BUILTIN_CHECK_EXCEPTION(bte);
750 case JAVA_MULTIANEWARRAY:
751 jd->isleafmethod = false;
752 i = SUCK_BE_U2(m->jcode + p + 1);
753 j = SUCK_BE_U1(m->jcode + p + 3);
755 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
759 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
762 /* if unresolved, c == NULL */
764 iptr->s1.argcount = j;
765 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
768 /* control flow instructions ******************************************/
787 i = p + SUCK_BE_S2(m->jcode + p + 1);
788 CHECK_BYTECODE_INDEX(i);
791 OP_INSINDEX(opcode, i);
795 i = p + SUCK_BE_S4(m->jcode + p + 1);
796 CHECK_BYTECODE_INDEX(i);
799 OP_INSINDEX(opcode, i);
803 i = p + SUCK_BE_S2(m->jcode + p + 1);
805 CHECK_BYTECODE_INDEX(i);
808 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
809 iptr->sx.s23.s3.jsrtarget.insindex = i;
814 i = p + SUCK_BE_S4(m->jcode + p + 1);
818 if (iswide == false) {
819 i = SUCK_BE_U1(m->jcode + p + 1);
822 i = SUCK_BE_U2(m->jcode + p + 1);
828 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
838 /* XXX ARETURN will need a flag in the typechecker */
844 /* XXX ATHROW will need a flag in the typechecker */
849 /* table jumps ********************************************************/
851 case JAVA_LOOKUPSWITCH:
854 lookup_target_t *lookup;
855 #if defined(ENABLE_VERIFIER)
859 nextp = ALIGN((p + 1), 4);
861 CHECK_END_OF_BYTECODE(nextp + 8);
863 OP_PREPARE_ZEROFLAGS(opcode);
867 j = p + SUCK_BE_S4(m->jcode + nextp);
868 iptr->sx.s23.s3.lookupdefault.insindex = j;
870 CHECK_BYTECODE_INDEX(j);
873 /* number of pairs */
875 num = SUCK_BE_U4(m->jcode + nextp);
876 iptr->sx.s23.s2.lookupcount = num;
879 /* allocate the intermediate code table */
881 lookup = DMNEW(lookup_target_t, num);
882 iptr->dst.lookup = lookup;
884 /* iterate over the lookup table */
886 CHECK_END_OF_BYTECODE(nextp + 8 * num);
888 for (i = 0; i < num; i++) {
891 j = SUCK_BE_S4(m->jcode + nextp);
896 #if defined(ENABLE_VERIFIER)
897 /* check if the lookup table is sorted correctly */
899 if (i && (j <= prevvalue)) {
900 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
907 j = p + SUCK_BE_S4(m->jcode + nextp);
908 lookup->target.insindex = j;
911 CHECK_BYTECODE_INDEX(j);
920 case JAVA_TABLESWITCH:
924 branch_target_t *table;
927 nextp = ALIGN((p + 1), 4);
929 CHECK_END_OF_BYTECODE(nextp + 12);
931 OP_PREPARE_ZEROFLAGS(opcode);
935 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
937 CHECK_BYTECODE_INDEX(deftarget);
938 MARK_BASICBLOCK(deftarget);
942 j = SUCK_BE_S4(m->jcode + nextp);
943 iptr->sx.s23.s2.tablelow = j;
948 num = SUCK_BE_S4(m->jcode + nextp);
949 iptr->sx.s23.s3.tablehigh = num;
952 /* calculate the number of table entries */
956 #if defined(ENABLE_VERIFIER)
958 exceptions_throw_verifyerror(m,
959 "invalid TABLESWITCH: upper bound < lower bound");
963 /* create the intermediate code table */
964 /* the first entry is the default target */
966 table = MNEW(branch_target_t, 1 + num);
967 iptr->dst.table = table;
968 (table++)->insindex = deftarget;
970 /* iterate over the target table */
972 CHECK_END_OF_BYTECODE(nextp + 4 * num);
974 for (i = 0; i < num; i++) {
975 j = p + SUCK_BE_S4(m->jcode + nextp);
976 (table++)->insindex = j;
978 CHECK_BYTECODE_INDEX(j);
987 /* load and store of object fields ************************************/
991 jd->isleafmethod = false;
1000 unresolved_field *uf;
1002 i = SUCK_BE_U2(m->jcode + p + 1);
1003 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
1007 OP_PREPARE_ZEROFLAGS(opcode);
1008 iptr->sx.s23.s3.fmiref = fr;
1010 /* only with -noverify, otherwise the typechecker does this */
1012 #if defined(ENABLE_VERIFIER)
1013 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1015 result = new_resolve_field_lazy(iptr, m);
1016 if (result == resolveFailed)
1019 if (result != resolveSucceeded) {
1020 uf = new_create_unresolved_field(m->class, m, iptr);
1025 /* store the unresolved_field pointer */
1027 iptr->sx.s23.s3.uf = uf;
1028 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1030 #if defined(ENABLE_VERIFIER)
1038 /* method invocation **************************************************/
1040 case JAVA_INVOKESTATIC:
1041 i = SUCK_BE_U2(m->jcode + p + 1);
1042 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1047 md = mr->parseddesc.md;
1049 if (md->params == NULL)
1050 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1055 case JAVA_INVOKEINTERFACE:
1056 i = SUCK_BE_U2(m->jcode + p + 1);
1058 mr = class_getconstant(m->class, i, CONSTANT_InterfaceMethodref);
1060 goto invoke_nonstatic_method;
1062 case JAVA_INVOKESPECIAL:
1063 case JAVA_INVOKEVIRTUAL:
1064 i = SUCK_BE_U2(m->jcode + p + 1);
1065 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1067 invoke_nonstatic_method:
1071 md = mr->parseddesc.md;
1073 if (md->params == NULL)
1074 if (!descriptor_params_from_paramtypes(md, 0))
1078 jd->isleafmethod = false;
1080 OP_PREPARE_ZEROFLAGS(opcode);
1081 iptr->sx.s23.s3.fmiref = mr;
1083 /* only with -noverify, otherwise the typechecker does this */
1085 #if defined(ENABLE_VERIFIER)
1086 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1088 result = new_resolve_method_lazy(iptr, m);
1089 if (result == resolveFailed)
1092 if (result != resolveSucceeded) {
1093 um = new_create_unresolved_method(m->class, m, iptr);
1098 /* store the unresolved_method pointer */
1100 iptr->sx.s23.s3.um = um;
1101 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1103 #if defined(ENABLE_VERIFIER)
1109 /* instructions taking class arguments ********************************/
1112 i = SUCK_BE_U2(m->jcode + p + 1);
1113 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1117 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1120 INSTRUCTIONS_CHECK(2);
1121 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1122 bte = builtintable_get_internal(BUILTIN_new);
1123 OP_BUILTIN_CHECK_EXCEPTION(bte);
1127 case JAVA_CHECKCAST:
1128 i = SUCK_BE_U2(m->jcode + p + 1);
1129 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1133 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1136 if (cr->name->text[0] == '[') {
1137 /* array type cast-check */
1138 flags = INS_FLAG_ARRAY;
1139 jd->isleafmethod = false;
1142 /* object type cast-check */
1145 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1148 case JAVA_INSTANCEOF:
1149 i = SUCK_BE_U2(m->jcode + p + 1);
1150 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1154 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1157 if (cr->name->text[0] == '[') {
1158 /* array type cast-check */
1159 INSTRUCTIONS_CHECK(2);
1160 OP_LOADCONST_CLASSINFO_OR_CLASSREF_NOCHECK(c, cr);
1161 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1162 OP_BUILTIN_NO_EXCEPTION(bte);
1166 /* object type cast-check */
1167 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1171 /* synchronization instructions ***************************************/
1173 case JAVA_MONITORENTER:
1174 #if defined(ENABLE_THREADS)
1176 bte = builtintable_get_internal(LOCK_monitor_enter);
1177 OP_BUILTIN_CHECK_EXCEPTION(bte);
1182 OP(ICMD_CHECKNULL_POP);
1186 case JAVA_MONITOREXIT:
1187 #if defined(ENABLE_THREADS)
1189 bte = builtintable_get_internal(LOCK_monitor_exit);
1190 OP_BUILTIN_CHECK_EXCEPTION(bte);
1195 OP(ICMD_CHECKNULL_POP);
1199 /* arithmetic instructions that may become builtin functions **********/
1202 #if !SUPPORT_DIVISION
1203 bte = builtintable_get_internal(BUILTIN_idiv);
1204 OP_BUILTIN_ARITHMETIC(opcode, bte);
1211 #if !SUPPORT_DIVISION
1212 bte = builtintable_get_internal(BUILTIN_irem);
1213 OP_BUILTIN_ARITHMETIC(opcode, bte);
1220 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1221 bte = builtintable_get_internal(BUILTIN_ldiv);
1222 OP_BUILTIN_ARITHMETIC(opcode, bte);
1229 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1230 bte = builtintable_get_internal(BUILTIN_lrem);
1231 OP_BUILTIN_ARITHMETIC(opcode, bte);
1238 #if defined(__I386__)
1241 bte = builtintable_get_internal(BUILTIN_frem);
1242 OP_BUILTIN_NO_EXCEPTION(bte);
1247 #if defined(__I386__)
1250 bte = builtintable_get_internal(BUILTIN_drem);
1251 OP_BUILTIN_NO_EXCEPTION(bte);
1256 #if defined(__ALPHA__)
1258 bte = builtintable_get_internal(BUILTIN_f2i);
1259 OP_BUILTIN_NO_EXCEPTION(bte);
1269 #if defined(__ALPHA__)
1271 bte = builtintable_get_internal(BUILTIN_f2l);
1272 OP_BUILTIN_NO_EXCEPTION(bte);
1282 #if defined(__ALPHA__)
1284 bte = builtintable_get_internal(BUILTIN_d2i);
1285 OP_BUILTIN_NO_EXCEPTION(bte);
1295 #if defined(__ALPHA__)
1297 bte = builtintable_get_internal(BUILTIN_d2l);
1298 OP_BUILTIN_NO_EXCEPTION(bte);
1307 /* invalid opcodes ****************************************************/
1309 /* check for invalid opcodes if the verifier is enabled */
1310 #if defined(ENABLE_VERIFIER)
1311 case JAVA_BREAKPOINT:
1312 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1315 case 186: /* unused opcode */
1369 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1373 #endif /* defined(ENABLE_VERIFIER) */
1375 /* opcodes that don't require translation *****************************/
1378 /* straight-forward translation to ICMD */
1384 /* verifier checks ****************************************************/
1386 #if defined(ENABLE_VERIFIER)
1387 /* If WIDE was used correctly, iswide should have been reset by now. */
1389 exceptions_throw_verifyerror(m,
1390 "Illegal instruction: WIDE before incompatible opcode");
1393 #endif /* defined(ENABLE_VERIFIER) */
1397 /* add a NOP to the last basic block */
1399 INSTRUCTIONS_CHECK(1);
1402 /*** END OF LOOP **********************************************************/
1404 /* assert that we did not write more ICMDs than allocated */
1406 assert(ipc <= pd.instructionslength);
1407 assert(ipc == (iptr - pd.instructions));
1409 /*** verifier checks ******************************************************/
1411 #if defined(ENABLE_VERIFIER)
1412 if (p != m->jcodelength) {
1413 exceptions_throw_verifyerror(m,
1414 "Command-sequence crosses code-boundary");
1419 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1422 #endif /* defined(ENABLE_VERIFIER) */
1424 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1426 /* adjust block count if target 0 is not first intermediate instruction */
1428 if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1))
1431 /* copy local to method variables */
1433 jd->new_instructions = pd.instructions;
1434 jd->new_instructioncount = ipc;
1435 jd->new_basicblockcount = b_count;
1436 jd->new_stackcount = s_count + jd->new_basicblockcount * m->maxstack; /* in-stacks */
1438 /* allocate stack table */
1440 jd->new_stack = DMNEW(stackelement, jd->new_stackcount);
1442 /* build basic block list */
1444 bptr = jd->new_basicblocks = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1446 /* zero out all basic block structures */
1448 MZERO(bptr, basicblock, b_count + 1);
1451 jd->new_c_debug_nr = 0;
1453 /* additional block if target 0 is not first intermediate instruction */
1455 if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1)) {
1456 BASICBLOCK_INIT(bptr, m);
1458 bptr->iinstr = jd->new_instructions;
1459 /* bptr->icount is set when the next block is allocated */
1463 bptr[-1].next = bptr;
1466 /* allocate blocks */
1468 for (p = 0; p < m->jcodelength; p++) {
1469 if (jd->new_basicblockindex[p] & 1) {
1470 #if defined(ENABLE_VERIFIER)
1471 /* Check if this block starts at the beginning of an
1474 if (!pd.instructionstart[p]) {
1475 exceptions_throw_verifyerror(m,
1476 "Branch into middle of instruction");
1481 /* allocate the block */
1483 BASICBLOCK_INIT(bptr, m);
1485 bptr->iinstr = jd->new_instructions + (jd->new_basicblockindex[p] >> 1);
1487 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1489 /* bptr->icount is set when the next block is allocated */
1491 jd->new_basicblockindex[p] = b_count;
1495 bptr[-1].next = bptr;
1499 /* set instruction count of last real block */
1502 bptr[-1].icount = (jd->new_instructions + jd->new_instructioncount) - bptr[-1].iinstr;
1505 /* allocate additional block at end */
1507 BASICBLOCK_INIT(bptr,m);
1509 /* set basicblock pointers in exception table */
1511 if (cd->exceptiontablelength > 0) {
1512 cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1515 for (i = 0; i < cd->exceptiontablelength; ++i) {
1516 p = cd->exceptiontable[i].startpc;
1517 cd->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
1519 p = cd->exceptiontable[i].endpc;
1520 cd->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
1522 p = cd->exceptiontable[i].handlerpc;
1523 cd->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
1526 /* XXX activate this if you want to try inlining */
1528 for (i = 0; i < m->exceptiontablelength; ++i) {
1529 p = m->exceptiontable[i].startpc;
1530 m->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
1532 p = m->exceptiontable[i].endpc;
1533 m->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
1535 p = m->exceptiontable[i].handlerpc;
1536 m->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
1540 jd->local_map = local_map;
1542 /* calculate local variable renaming */
1552 /* iterate over local_map[0..m->maxlocals*5] and set all existing */
1553 /* index,type pairs (localmap[index*5+type]==1) to an unique value */
1554 /* -> == new local var index */
1555 for(i = 0; i < (cd->maxlocals * 5); i++, mapptr++) {
1557 *mapptr = nlocals++;
1562 jd->localcount = nlocals;
1563 /* if dropped varindices for temp stackslots get reused(?max 2* */
1564 /* m->maxstack elements for stack), nlocals + s_count would be */
1566 jd->varcount = nlocals + s_count +
1567 jd->new_basicblockcount * m->maxstack; /* out-stacks */
1569 jd->vartop = nlocals;
1570 jd->var = DMNEW(varinfo, jd->varcount);
1571 MZERO(jd->var, varinfo, jd->varcount);
1573 /* set types of all Locals in jd->var */
1574 for(mapptr = local_map, i = 0; i < (cd->maxlocals * 5); i++, mapptr++)
1575 if (*mapptr != UNUSED)
1576 jd->var[*mapptr].type = i%5;
1579 /* everything's ok */
1583 /*** goto labels for throwing verifier exceptions *************************/
1585 #if defined(ENABLE_VERIFIER)
1587 throw_unexpected_end_of_bytecode:
1588 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1591 throw_invalid_bytecode_index:
1592 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1595 throw_illegal_local_variable_number:
1596 exceptions_throw_verifyerror(m, "Illegal local variable number");
1599 #endif /* ENABLE_VERIFIER */
1604 * These are local overrides for various environment variables in Emacs.
1605 * Please do not remove this and leave it at the end of the file, where
1606 * Emacs will automagically detect them.
1607 * ---------------------------------------------------------------------
1610 * indent-tabs-mode: t
1614 * vim:noexpandtab:sw=4:ts=4: