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 5371 2006-09-06 14:01:23Z 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)
135 /* increase the size of the instruction array */
137 pd->instructionslength += INSTRUCTIONS_INCREMENT;
139 /* reallocate the array */
141 pd->instructions = DMREALLOC(pd->instructions, instruction, ipc,
142 pd->instructionslength);
144 /* return the iptr */
146 return pd->instructions + ipc;
150 /*******************************************************************************
152 function 'parse' scans the JavaVM code and generates intermediate code
154 During parsing the block index table is used to store at bit pos 0
155 a flag which marks basic block starts and at position 1 to 31 the
156 intermediate instruction index. After parsing the block index table
157 is scanned, for marked positions a block is generated and the block
158 number is stored in the block index table.
160 *******************************************************************************/
162 static exceptiontable * new_fillextable(
165 exceptiontable *extable,
166 exceptiontable *raw_extable,
167 int exceptiontablelength,
172 if (exceptiontablelength == 0)
175 b_count = *block_count;
177 for (src = exceptiontablelength-1; src >=0; src--) {
178 /* the start of the handled region becomes a basic block start */
179 p = raw_extable[src].startpc;
180 CHECK_BYTECODE_INDEX(p);
181 extable->startpc = p;
184 p = raw_extable[src].endpc; /* see JVM Spec 4.7.3 */
185 CHECK_BYTECODE_INDEX_EXCLUSIVE(p);
187 #if defined(ENABLE_VERIFIER)
188 if (p <= raw_extable[src].startpc) {
189 exceptions_throw_verifyerror(m,
190 "Invalid exception handler range");
196 /* end of handled region becomes a basic block boundary */
197 /* (If it is the bytecode end, we'll use the special */
198 /* end block that is created anyway.) */
199 if (p < m->jcodelength)
202 /* the start of the handler becomes a basic block start */
203 p = raw_extable[src].handlerpc;
204 CHECK_BYTECODE_INDEX(p);
205 extable->handlerpc = p;
208 extable->catchtype = raw_extable[src].catchtype;
209 extable->next = NULL;
210 extable->down = &extable[1];
214 *block_count = b_count;
219 #if defined(ENABLE_VERIFIER)
220 throw_invalid_bytecode_index:
221 exceptions_throw_verifyerror(m,
222 "Illegal bytecode index in exception table");
227 /*** macro for checking the length of the bytecode ***/
229 #if defined(ENABLE_VERIFIER)
230 #define CHECK_END_OF_BYTECODE(neededlength) \
232 if ((neededlength) > m->jcodelength) \
233 goto throw_unexpected_end_of_bytecode; \
235 #else /* !ENABLE_VERIFIER */
236 #define CHECK_END_OF_BYTECODE(neededlength)
237 #endif /* ENABLE_VERIFIER */
239 bool new_parse(jitdata *jd)
241 methodinfo *m; /* method being parsed */
244 int p; /* java instruction counter */
245 int nextp; /* start of next java instruction */
246 int opcode; /* java opcode */
247 int i; /* temporary for different uses (ctrs) */
248 int ipc = 0; /* intermediate instruction counter */
249 int b_count = 0; /* basic block counter */
250 int s_count = 0; /* stack element counter */
251 bool blockend = false; /* true if basic block end has been reached */
252 bool iswide = false; /* true if last instruction was a wide */
253 instruction *iptr; /* current ptr into instruction array */
254 u1 *instructionstart; /* 1 for pcs which are valid instr. starts */
255 constant_classref *cr;
256 constant_classref *compr;
258 builtintable_entry *bte;
261 unresolved_method *um;
262 resolve_result_t result;
270 int *local_map; /* local pointer to renaming structore */
271 /* is assigned to rd->local_map at the end */
273 /* get required compiler data */
280 /* allocate buffers for local variable renaming */
281 local_map = DMNEW(int, cd->maxlocals * 5);
282 for (i = 0; i < cd->maxlocals; i++) {
283 local_map[i * 5 + 0] = 0;
284 local_map[i * 5 + 1] = 0;
285 local_map[i * 5 + 2] = 0;
286 local_map[i * 5 + 3] = 0;
287 local_map[i * 5 + 4] = 0;
291 /* allocate instruction array and block index table */
293 /* 1 additional for end ipc */
294 jd->new_basicblockindex = DMNEW(s4, m->jcodelength + 1);
295 memset(jd->new_basicblockindex, 0, sizeof(s4) * (m->jcodelength + 1));
297 instructionstart = DMNEW(u1, m->jcodelength + 1);
298 memset(instructionstart, 0, sizeof(u1) * (m->jcodelength + 1));
300 /* IMPORTANT: We assume that parsing creates at most one instruction per */
301 /* byte of original bytecode! */
303 iptr = jd->new_instructions = DMNEW(instruction, m->jcodelength);
305 /* compute branch targets of exception table */
307 if (!new_fillextable(jd, m,
308 &(cd->exceptiontable[cd->exceptiontablelength-1]),
310 m->exceptiontablelength,
316 s_count = 1 + m->exceptiontablelength; /* initialize stack element counter */
318 #if defined(ENABLE_THREADS)
319 if (checksync && (m->flags & ACC_SYNCHRONIZED))
320 jd->isleafmethod = false;
323 /* setup line number info */
328 if (m->linenumbercount == 0) {
332 linepcchange = m->linenumbers[0].start_pc;
335 /*** LOOP OVER ALL BYTECODE INSTRUCTIONS **********************************/
337 for (p = 0; p < m->jcodelength; p = nextp) {
339 /* mark this position as a valid instruction start */
341 instructionstart[p] = 1;
343 /* change the current line number, if necessary */
345 /* XXX rewrite this using pointer arithmetic */
347 if (linepcchange == p) {
348 if (m->linenumbercount > lineindex) {
350 currentline = m->linenumbers[lineindex].line_number;
352 if (lineindex < m->linenumbercount) {
353 linepcchange = m->linenumbers[lineindex].start_pc;
354 if (linepcchange == p)
355 goto next_linenumber;
360 /* fetch next opcode */
362 opcode = SUCK_BE_U1(m->jcode + p);
364 /* store intermediate instruction count (bit 0 mark block starts) */
366 jd->new_basicblockindex[p] |= (ipc << 1);
368 /* some compilers put a JAVA_NOP after a blockend instruction */
370 if (blockend && (opcode != JAVA_NOP)) {
371 /* start new block */
377 /* compute next instruction start */
379 nextp = p + jcommandsize[opcode];
381 CHECK_END_OF_BYTECODE(nextp);
383 /* add stack elements produced by this instruction */
385 s_count += stackreq[opcode];
387 /* 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,
445 /* if not resolved, c == NULL */
447 OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, 0 /* no extra flags */);
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 /* local variable access instructions *********************************/
495 if (iswide == false) {
496 i = SUCK_BE_U1(m->jcode + p + 1);
499 i = SUCK_BE_U2(m->jcode + p + 1);
503 OP_LOAD_ONEWORD(opcode, i, opcode - JAVA_ILOAD);
508 if (iswide == false) {
509 i = SUCK_BE_U1(m->jcode + p + 1);
512 i = SUCK_BE_U2(m->jcode + p + 1);
516 OP_LOAD_TWOWORD(opcode, i, opcode - JAVA_ILOAD);
523 OP_LOAD_ONEWORD(ICMD_ILOAD, opcode - JAVA_ILOAD_0, TYPE_INT);
530 OP_LOAD_TWOWORD(ICMD_LLOAD, opcode - JAVA_LLOAD_0, TYPE_LNG);
537 OP_LOAD_ONEWORD(ICMD_FLOAD, opcode - JAVA_FLOAD_0, TYPE_FLT);
544 OP_LOAD_TWOWORD(ICMD_DLOAD, opcode - JAVA_DLOAD_0, TYPE_DBL);
551 OP_LOAD_ONEWORD(ICMD_ALOAD, opcode - JAVA_ALOAD_0, TYPE_ADR);
557 if (iswide == false) {
558 i = SUCK_BE_U1(m->jcode + p + 1);
561 i = SUCK_BE_U2(m->jcode + p + 1);
565 OP_STORE_ONEWORD(opcode, i, opcode - JAVA_ISTORE);
570 if (iswide == false) {
571 i = SUCK_BE_U1(m->jcode + p + 1);
574 i = SUCK_BE_U2(m->jcode + p + 1);
578 OP_STORE_TWOWORD(opcode, i, opcode - JAVA_ISTORE);
585 OP_STORE_ONEWORD(ICMD_ISTORE, opcode - JAVA_ISTORE_0, TYPE_INT);
592 OP_STORE_TWOWORD(ICMD_LSTORE, opcode - JAVA_LSTORE_0, TYPE_LNG);
599 OP_STORE_ONEWORD(ICMD_FSTORE, opcode - JAVA_FSTORE_0, TYPE_FLT);
606 OP_STORE_TWOWORD(ICMD_DSTORE, opcode - JAVA_DSTORE_0, TYPE_DBL);
613 OP_STORE_ONEWORD(ICMD_ASTORE, opcode - JAVA_ASTORE_0, TYPE_ADR);
620 if (iswide == false) {
621 i = SUCK_BE_U1(m->jcode + p + 1);
622 v = SUCK_BE_S1(m->jcode + p + 2);
626 i = SUCK_BE_U2(m->jcode + p + 1);
627 v = SUCK_BE_S2(m->jcode + p + 3);
632 LOCALTYPE_USED(i, TYPE_INT);
633 OP_LOCALINDEX_I(opcode, i, v);
637 /* wider index for loading, storing and incrementing ******************/
644 /* managing arrays ****************************************************/
647 switch (SUCK_BE_S1(m->jcode + p + 1)) {
649 bte = builtintable_get_internal(BUILTIN_newarray_boolean);
652 bte = builtintable_get_internal(BUILTIN_newarray_char);
655 bte = builtintable_get_internal(BUILTIN_newarray_float);
658 bte = builtintable_get_internal(BUILTIN_newarray_double);
661 bte = builtintable_get_internal(BUILTIN_newarray_byte);
664 bte = builtintable_get_internal(BUILTIN_newarray_short);
667 bte = builtintable_get_internal(BUILTIN_newarray_int);
670 bte = builtintable_get_internal(BUILTIN_newarray_long);
672 #if defined(ENABLE_VERIFIER)
674 exceptions_throw_verifyerror(m, "Invalid array-type to create");
678 OP_BUILTIN_CHECK_EXCEPTION(bte);
682 i = SUCK_BE_U2(m->jcode + p + 1);
683 compr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
687 if (!(cr = class_get_classref_multiarray_of(1, compr)))
690 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
693 OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
694 bte = builtintable_get_internal(BUILTIN_newarray);
695 OP_BUILTIN_CHECK_EXCEPTION(bte);
699 case JAVA_MULTIANEWARRAY:
700 jd->isleafmethod = false;
701 i = SUCK_BE_U2(m->jcode + p + 1);
703 s4 v = SUCK_BE_U1(m->jcode + p + 3);
705 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
709 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
712 /* if unresolved, c == NULL */
714 iptr->s1.argcount = v;
715 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags */);
719 /* control flow instructions ******************************************/
738 i = p + SUCK_BE_S2(m->jcode + p + 1);
739 CHECK_BYTECODE_INDEX(i);
742 OP_INSINDEX(opcode, i);
746 i = p + SUCK_BE_S4(m->jcode + p + 1);
747 CHECK_BYTECODE_INDEX(i);
750 OP_INSINDEX(opcode, i);
754 i = p + SUCK_BE_S2(m->jcode + p + 1);
756 CHECK_BYTECODE_INDEX(i);
759 OP_PREPARE_ZEROFLAGS(JAVA_JSR);
760 iptr->sx.s23.s3.jsrtarget.insindex = i;
765 i = p + SUCK_BE_S4(m->jcode + p + 1);
769 if (iswide == false) {
770 i = SUCK_BE_U1(m->jcode + p + 1);
773 i = SUCK_BE_U2(m->jcode + p + 1);
779 OP_LOAD_ONEWORD(opcode, i, TYPE_ADR);
789 /* XXX ARETURN will need a flag in the typechecker */
795 /* XXX ATHROW will need a flag in the typechecker */
800 /* table jumps ********************************************************/
802 case JAVA_LOOKUPSWITCH:
805 lookup_target_t *lookup;
806 #if defined(ENABLE_VERIFIER)
810 nextp = ALIGN((p + 1), 4);
812 CHECK_END_OF_BYTECODE(nextp + 8);
814 OP_PREPARE_ZEROFLAGS(opcode);
818 j = p + SUCK_BE_S4(m->jcode + nextp);
819 iptr->sx.s23.s3.lookupdefault.insindex = j;
821 CHECK_BYTECODE_INDEX(j);
824 /* number of pairs */
826 num = SUCK_BE_U4(m->jcode + nextp);
827 iptr->sx.s23.s2.lookupcount = num;
830 /* allocate the intermediate code table */
832 lookup = DMNEW(lookup_target_t, num);
833 iptr->dst.lookup = lookup;
835 /* iterate over the lookup table */
837 CHECK_END_OF_BYTECODE(nextp + 8 * num);
839 for (i = 0; i < num; i++) {
842 j = SUCK_BE_S4(m->jcode + nextp);
847 #if defined(ENABLE_VERIFIER)
848 /* check if the lookup table is sorted correctly */
850 if (i && (j <= prevvalue)) {
851 exceptions_throw_verifyerror(m, "Unsorted lookup switch");
858 j = p + SUCK_BE_S4(m->jcode + nextp);
859 lookup->target.insindex = j;
862 CHECK_BYTECODE_INDEX(j);
871 case JAVA_TABLESWITCH:
875 branch_target_t *table;
878 nextp = ALIGN((p + 1), 4);
880 CHECK_END_OF_BYTECODE(nextp + 12);
882 OP_PREPARE_ZEROFLAGS(opcode);
886 deftarget = p + SUCK_BE_S4(m->jcode + nextp);
888 CHECK_BYTECODE_INDEX(deftarget);
889 MARK_BASICBLOCK(deftarget);
893 j = SUCK_BE_S4(m->jcode + nextp);
894 iptr->sx.s23.s2.tablelow = j;
899 num = SUCK_BE_S4(m->jcode + nextp);
900 iptr->sx.s23.s3.tablehigh = num;
903 /* calculate the number of table entries */
907 #if defined(ENABLE_VERIFIER)
909 exceptions_throw_verifyerror(m,
910 "invalid TABLESWITCH: upper bound < lower bound");
914 /* create the intermediate code table */
915 /* the first entry is the default target */
917 table = MNEW(branch_target_t, 1 + num);
918 iptr->dst.table = table;
919 (table++)->insindex = deftarget;
921 /* iterate over the target table */
923 CHECK_END_OF_BYTECODE(nextp + 4 * num);
925 for (i = 0; i < num; i++) {
926 j = p + SUCK_BE_S4(m->jcode + nextp);
927 (table++)->insindex = j;
929 CHECK_BYTECODE_INDEX(j);
938 /* load and store of object fields ************************************/
942 jd->isleafmethod = false;
951 unresolved_field *uf;
953 i = SUCK_BE_U2(m->jcode + p + 1);
954 fr = class_getconstant(m->class, i, CONSTANT_Fieldref);
958 OP_PREPARE_ZEROFLAGS(opcode);
959 iptr->sx.s23.s3.fmiref = fr;
961 /* only with -noverify, otherwise the typechecker does this */
963 #if defined(ENABLE_VERIFIER)
964 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
966 result = new_resolve_field_lazy(iptr, m);
967 if (result == resolveFailed)
970 if (result != resolveSucceeded) {
971 uf = new_create_unresolved_field(m->class, m, iptr);
976 /* store the unresolved_field pointer */
978 iptr->sx.s23.s3.uf = uf;
979 iptr->flags.bits = INS_FLAG_UNRESOLVED;
981 #if defined(ENABLE_VERIFIER)
989 /* method invocation **************************************************/
991 case JAVA_INVOKESTATIC:
992 i = SUCK_BE_U2(m->jcode + p + 1);
993 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
997 md = mr->parseddesc.md;
1000 if (!descriptor_params_from_paramtypes(md, ACC_STATIC))
1005 case JAVA_INVOKEINTERFACE:
1006 i = SUCK_BE_U2(m->jcode + p + 1);
1008 mr = class_getconstant(m->class, i,
1009 CONSTANT_InterfaceMethodref);
1011 goto invoke_nonstatic_method;
1013 case JAVA_INVOKESPECIAL:
1014 case JAVA_INVOKEVIRTUAL:
1015 i = SUCK_BE_U2(m->jcode + p + 1);
1016 mr = class_getconstant(m->class, i, CONSTANT_Methodref);
1018 invoke_nonstatic_method:
1022 md = mr->parseddesc.md;
1025 if (!descriptor_params_from_paramtypes(md, 0))
1029 jd->isleafmethod = false;
1031 OP_PREPARE_ZEROFLAGS(opcode);
1032 iptr->sx.s23.s3.fmiref = mr;
1034 /* only with -noverify, otherwise the typechecker does this */
1036 #if defined(ENABLE_VERIFIER)
1037 if (!JITDATA_HAS_FLAG_VERIFY(jd)) {
1039 result = new_resolve_method_lazy(iptr, m);
1040 if (result == resolveFailed)
1043 if (result != resolveSucceeded) {
1044 um = new_create_unresolved_method(m->class, m, iptr);
1049 /* store the unresolved_method pointer */
1051 iptr->sx.s23.s3.um = um;
1052 iptr->flags.bits = INS_FLAG_UNRESOLVED;
1054 #if defined(ENABLE_VERIFIER)
1060 /* instructions taking class arguments ********************************/
1063 i = SUCK_BE_U2(m->jcode + p + 1);
1064 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1068 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1071 OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
1072 bte = builtintable_get_internal(BUILTIN_new);
1073 OP_BUILTIN_CHECK_EXCEPTION(bte);
1077 case JAVA_CHECKCAST:
1078 i = SUCK_BE_U2(m->jcode + p + 1);
1079 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1083 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1086 if (cr->name->text[0] == '[') {
1087 /* array type cast-check */
1088 flags = INS_FLAG_ARRAY;
1089 jd->isleafmethod = false;
1092 /* object type cast-check */
1095 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, flags);
1098 case JAVA_INSTANCEOF:
1099 i = SUCK_BE_U2(m->jcode + p + 1);
1100 cr = (constant_classref *) class_getconstant(m->class, i, CONSTANT_Class);
1104 if (!resolve_classref(m, cr, resolveLazy, true, true, &c))
1107 if (cr->name->text[0] == '[') {
1108 /* array type cast-check */
1109 OP_LOADCONST_CLASSINFO_OR_CLASSREF(c, cr, INS_FLAG_NOCHECK);
1110 bte = builtintable_get_internal(BUILTIN_arrayinstanceof);
1111 OP_BUILTIN_NO_EXCEPTION(bte);
1115 /* object type cast-check */
1116 OP_S3_CLASSINFO_OR_CLASSREF(opcode, c, cr, 0 /* flags*/);
1120 /* synchronization instructions ***************************************/
1122 case JAVA_MONITORENTER:
1123 #if defined(ENABLE_THREADS)
1125 bte = builtintable_get_internal(LOCK_monitor_enter);
1126 OP_BUILTIN_CHECK_EXCEPTION(bte);
1131 OP(ICMD_CHECKNULL_POP);
1135 case JAVA_MONITOREXIT:
1136 #if defined(ENABLE_THREADS)
1138 bte = builtintable_get_internal(LOCK_monitor_exit);
1139 OP_BUILTIN_CHECK_EXCEPTION(bte);
1144 OP(ICMD_CHECKNULL_POP);
1148 /* arithmetic instructions that may become builtin functions **********/
1151 #if !SUPPORT_DIVISION
1152 bte = builtintable_get_internal(BUILTIN_idiv);
1153 OP_BUILTIN_ARITHMETIC(opcode, bte);
1160 #if !SUPPORT_DIVISION
1161 bte = builtintable_get_internal(BUILTIN_irem);
1162 OP_BUILTIN_ARITHMETIC(opcode, bte);
1169 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1170 bte = builtintable_get_internal(BUILTIN_ldiv);
1171 OP_BUILTIN_ARITHMETIC(opcode, bte);
1178 #if !(SUPPORT_DIVISION && SUPPORT_LONG && SUPPORT_LONG_DIV)
1179 bte = builtintable_get_internal(BUILTIN_lrem);
1180 OP_BUILTIN_ARITHMETIC(opcode, bte);
1187 #if defined(__I386__)
1190 bte = builtintable_get_internal(BUILTIN_frem);
1191 OP_BUILTIN_NO_EXCEPTION(bte);
1196 #if defined(__I386__)
1199 bte = builtintable_get_internal(BUILTIN_drem);
1200 OP_BUILTIN_NO_EXCEPTION(bte);
1205 #if defined(__ALPHA__)
1207 bte = builtintable_get_internal(BUILTIN_f2i);
1208 OP_BUILTIN_NO_EXCEPTION(bte);
1218 #if defined(__ALPHA__)
1220 bte = builtintable_get_internal(BUILTIN_f2l);
1221 OP_BUILTIN_NO_EXCEPTION(bte);
1231 #if defined(__ALPHA__)
1233 bte = builtintable_get_internal(BUILTIN_d2i);
1234 OP_BUILTIN_NO_EXCEPTION(bte);
1244 #if defined(__ALPHA__)
1246 bte = builtintable_get_internal(BUILTIN_d2l);
1247 OP_BUILTIN_NO_EXCEPTION(bte);
1256 /* invalid opcodes ****************************************************/
1258 /* check for invalid opcodes if the verifier is enabled */
1259 #if defined(ENABLE_VERIFIER)
1260 case JAVA_BREAKPOINT:
1261 exceptions_throw_verifyerror(m, "Quick instructions shouldn't appear, yet.");
1264 case 186: /* unused opcode */
1318 exceptions_throw_verifyerror(m, "Illegal opcode %d at instr %d\n",
1322 #endif /* defined(ENABLE_VERIFIER) */
1324 /* opcodes that don't require translation *****************************/
1327 /* straight-forward translation to ICMD */
1333 /* verifier checks ****************************************************/
1335 #if defined(ENABLE_VERIFIER)
1336 /* If WIDE was used correctly, iswide should have been reset by now. */
1338 exceptions_throw_verifyerror(m,
1339 "Illegal instruction: WIDE before incompatible opcode");
1342 #endif /* defined(ENABLE_VERIFIER) */
1346 /*** END OF LOOP **********************************************************/
1348 /* assert that we did not write more ICMDs than allocated */
1350 assert(ipc == (iptr - jd->new_instructions));
1351 assert(ipc <= m->jcodelength);
1353 /*** verifier checks ******************************************************/
1355 #if defined(ENABLE_VERIFIER)
1356 if (p != m->jcodelength) {
1357 exceptions_throw_verifyerror(m,
1358 "Command-sequence crosses code-boundary");
1363 exceptions_throw_verifyerror(m, "Falling off the end of the code");
1366 #endif /* defined(ENABLE_VERIFIER) */
1368 /*** setup the methodinfo, allocate stack and basic blocks ****************/
1370 /* adjust block count if target 0 is not first intermediate instruction */
1372 if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1))
1375 /* copy local to method variables */
1377 jd->new_instructioncount = ipc;
1378 jd->new_basicblockcount = b_count;
1379 jd->new_stackcount = s_count + jd->new_basicblockcount * m->maxstack; /* in-stacks */
1381 /* allocate stack table */
1383 jd->new_stack = DMNEW(stackelement, jd->new_stackcount);
1385 /* build basic block list */
1387 bptr = jd->new_basicblocks = DMNEW(basicblock, b_count + 1); /* one more for end ipc */
1389 /* zero out all basic block structures */
1391 MZERO(bptr, basicblock, b_count + 1);
1394 jd->new_c_debug_nr = 0;
1396 /* additional block if target 0 is not first intermediate instruction */
1398 if (!jd->new_basicblockindex[0] || (jd->new_basicblockindex[0] > 1)) {
1399 BASICBLOCK_INIT(bptr, m);
1401 bptr->iinstr = jd->new_instructions;
1402 /* bptr->icount is set when the next block is allocated */
1406 bptr[-1].next = bptr;
1409 /* allocate blocks */
1411 for (p = 0; p < m->jcodelength; p++) {
1412 if (jd->new_basicblockindex[p] & 1) {
1413 /* Check if this block starts at the beginning of an */
1415 #if defined(ENABLE_VERIFIER)
1416 if (!instructionstart[p]) {
1417 exceptions_throw_verifyerror(m,
1418 "Branch into middle of instruction");
1423 /* allocate the block */
1425 BASICBLOCK_INIT(bptr, m);
1427 bptr->iinstr = jd->new_instructions + (jd->new_basicblockindex[p] >> 1);
1429 bptr[-1].icount = bptr->iinstr - bptr[-1].iinstr;
1431 /* bptr->icount is set when the next block is allocated */
1433 jd->new_basicblockindex[p] = b_count;
1437 bptr[-1].next = bptr;
1441 /* set instruction count of last real block */
1444 bptr[-1].icount = (jd->new_instructions + jd->new_instructioncount) - bptr[-1].iinstr;
1447 /* allocate additional block at end */
1449 BASICBLOCK_INIT(bptr,m);
1451 /* set basicblock pointers in exception table */
1453 if (cd->exceptiontablelength > 0) {
1454 cd->exceptiontable[cd->exceptiontablelength - 1].down = NULL;
1457 for (i = 0; i < cd->exceptiontablelength; ++i) {
1458 p = cd->exceptiontable[i].startpc;
1459 cd->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
1461 p = cd->exceptiontable[i].endpc;
1462 cd->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
1464 p = cd->exceptiontable[i].handlerpc;
1465 cd->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
1468 /* XXX activate this if you want to try inlining */
1470 for (i = 0; i < m->exceptiontablelength; ++i) {
1471 p = m->exceptiontable[i].startpc;
1472 m->exceptiontable[i].start = jd->new_basicblocks + jd->new_basicblockindex[p];
1474 p = m->exceptiontable[i].endpc;
1475 m->exceptiontable[i].end = (p == m->jcodelength) ? (jd->new_basicblocks + jd->new_basicblockcount /*+ 1*/) : (jd->new_basicblocks + jd->new_basicblockindex[p]);
1477 p = m->exceptiontable[i].handlerpc;
1478 m->exceptiontable[i].handler = jd->new_basicblocks + jd->new_basicblockindex[p];
1482 #if defined(NEW_VAR)
1483 jd->local_map = local_map;
1485 /* calculate local variable renaming */
1495 /* iterate over local_map[0..m->maxlocals*5] and set all existing */
1496 /* index,type pairs (localmap[index*5+type]==1) to an unique value */
1497 /* -> == new local var index */
1498 for(i = 0; i < (m->maxlocals * 5); i++, mapptr++) {
1500 *mapptr = nlocals++;
1502 *mapptr = LOCAL_UNUSED;
1505 jd->localcount = nlocals;
1506 /* if dropped varindices for temp stackslots get reused(?max 2* */
1507 /* m->maxstack elements for stack), nlocals + s_count would be */
1509 jd->varcount = nlocals + s_count +
1510 jd->new_basicblockcount * m->maxstack; /* out-stacks */
1512 jd->var_top = nlocals;
1513 jd->var = DMNEW(varinfo, jd->varcount);
1517 /* everything's ok */
1521 /*** goto labels for throwing verifier exceptions *************************/
1523 #if defined(ENABLE_VERIFIER)
1525 throw_unexpected_end_of_bytecode:
1526 exceptions_throw_verifyerror(m, "Unexpected end of bytecode");
1529 throw_invalid_bytecode_index:
1530 exceptions_throw_verifyerror(m, "Illegal target of branch instruction");
1533 throw_illegal_local_variable_number:
1534 exceptions_throw_verifyerror(m, "Illegal local variable number");
1537 #endif /* ENABLE_VERIFIER */
1542 * These are local overrides for various environment variables in Emacs.
1543 * Please do not remove this and leave it at the end of the file, where
1544 * Emacs will automagically detect them.
1545 * ---------------------------------------------------------------------
1548 * indent-tabs-mode: t
1552 * vim:noexpandtab:sw=4:ts=4: