1 /* src/vm/jit/intrp/codegen.c - code generator for Interpreter
3 Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4 R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5 C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6 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., 59 Temple Place - Suite 330, Boston, MA
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Andreas Krall
30 Changes: Christian Thalinger
33 $Id: codegen.c 3951 2005-12-20 21:13:10Z twisti $
45 #include "vm/jit/intrp/codegen.h"
47 #include "cacao/cacao.h"
48 #include "native/native.h"
49 #include "vm/builtin.h"
51 #include "vm/global.h"
52 #include "vm/loader.h"
53 #include "vm/stringlocal.h"
54 #include "vm/jit/asmpart.h"
55 #include "vm/jit/codegen.inc"
56 #include "vm/jit/jit.h"
58 #include "vm/jit/parse.h"
59 #include "vm/jit/patcher.h"
61 #include "vm/jit/intrp/intrp.h"
63 #include "libffi/include/ffi.h"
66 #define gen_branch(_inst) { \
68 codegen_addreference(cd, (basicblock *) (iptr->target), cd->mcodeptr); \
71 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
73 /* functions used by cacao-gen.i */
75 void genarg_v(codegendata *cd1, Cell v)
77 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
78 *((Cell *) *mcodepp) = v;
82 void genarg_i(codegendata *cd1, s4 i)
84 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
85 *((Cell *) *mcodepp) = i;
89 void genarg_b(codegendata *cd1, s4 i)
94 void genarg_f(codegendata *cd1, float f)
102 void genarg_l(codegendata *cd1, s8 l)
104 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
105 vm_l2twoCell(l, ((Cell *) *mcodepp)[1], ((Cell *) *mcodepp)[0]);
109 void genarg_aRef(codegendata *cd1, java_objectheader *a)
111 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
112 *((java_objectheader **) *mcodepp) = a;
116 void genarg_aArray(codegendata *cd1, java_arrayheader *a)
118 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
119 *((java_arrayheader **) *mcodepp) = a;
123 void genarg_aaTarget(codegendata *cd1, Inst **a)
125 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
126 *((Inst ***) *mcodepp) = a;
130 void genarg_aClass(codegendata *cd1, classinfo *a)
132 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
133 *((classinfo **) *mcodepp) = a;
137 void genarg_acr(codegendata *cd1, constant_classref *a)
139 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
140 *((constant_classref **) *mcodepp) = a;
144 void genarg_addr(codegendata *cd1, u1 *a)
146 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
147 *((u1 **) *mcodepp) = a;
151 void genarg_af(codegendata *cd1, functionptr a)
153 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
154 *((functionptr *) *mcodepp) = a;
158 void genarg_am(codegendata *cd1, methodinfo *a)
160 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
161 *((methodinfo **) *mcodepp) = a;
165 void genarg_acell(codegendata *cd1, Cell *a)
167 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
168 *((Cell **) *mcodepp) = a;
172 void genarg_ainst(codegendata *cd1, Inst *a)
174 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
175 *((Inst **) *mcodepp) = a;
179 void genarg_auf(codegendata *cd1, unresolved_field *a)
181 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
182 *((unresolved_field **) *mcodepp) = a;
186 void genarg_aum(codegendata *cd1, unresolved_method *a)
188 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
189 *((unresolved_method **) *mcodepp) = a;
193 void genarg_avftbl(codegendata *cd1, vftbl_t *a)
195 Inst **mcodepp = (Inst **) &(cd1->mcodeptr);
196 *((vftbl_t **) *mcodepp) = a;
201 /* include the interpreter generation functions *******************************/
203 #include "vm/jit/intrp/java-gen.i"
206 typedef void (*genfunctionptr) (codegendata *);
208 typedef struct builtin_gen builtin_gen;
215 struct builtin_gen builtin_gen_table[] = {
216 {BUILTIN_new, gen_NEW, },
217 {BUILTIN_newarray, gen_NEWARRAY, },
218 {BUILTIN_newarray_boolean, gen_NEWARRAY_BOOLEAN,},
219 {BUILTIN_newarray_byte, gen_NEWARRAY_BYTE, },
220 {BUILTIN_newarray_char, gen_NEWARRAY_CHAR, },
221 {BUILTIN_newarray_short, gen_NEWARRAY_SHORT, },
222 {BUILTIN_newarray_int, gen_NEWARRAY_INT, },
223 {BUILTIN_newarray_long, gen_NEWARRAY_LONG, },
224 {BUILTIN_newarray_float, gen_NEWARRAY_FLOAT, },
225 {BUILTIN_newarray_double, gen_NEWARRAY_DOUBLE, },
226 {BUILTIN_arrayinstanceof, gen_ARRAYINSTANCEOF, },
227 #if defined(USE_THREADS)
228 {BUILTIN_monitorenter, gen_MONITORENTER, },
229 {BUILTIN_monitorexit, gen_MONITOREXIT, },
231 {BUILTIN_f2l, gen_F2L, },
232 {BUILTIN_d2l, gen_D2L, },
233 {BUILTIN_f2i, gen_F2I, },
234 {BUILTIN_d2i, gen_D2I, },
235 {BUILTIN_idiv, gen_IDIV, },
236 {BUILTIN_irem, gen_IREM, },
237 {BUILTIN_ldiv, gen_LDIV, },
238 {BUILTIN_lrem, gen_LREM, },
239 {BUILTIN_frem, gen_FREM, },
240 {BUILTIN_drem, gen_DREM, },
244 /* codegen *********************************************************************
246 Generates machine code.
248 *******************************************************************************/
250 bool codegen(methodinfo *m, codegendata *cd, registerdata *rd)
252 s4 i, len, s1, s2, d;
258 methodinfo *lm; /* local methodinfo for ICMD_INVOKE* */
259 unresolved_method *um;
260 builtintable_entry *bte;
263 /* prevent compiler warnings */
270 /* create method header */
272 (void) dseg_addaddress(cd, m); /* MethodPointer */
273 (void) dseg_adds4(cd, m->maxlocals * SIZEOF_VOID_P); /* FrameSize */
275 #if defined(USE_THREADS)
276 if (checksync && (m->flags & ACC_SYNCHRONIZED))
277 (void) dseg_adds4(cd, 1); /* IsSync */
280 (void) dseg_adds4(cd, 0); /* IsSync */
282 (void) dseg_adds4(cd, 0); /* IsLeaf */
283 (void) dseg_adds4(cd, 0); /* IntSave */
284 (void) dseg_adds4(cd, 0); /* FltSave */
286 dseg_addlinenumbertablesize(cd);
288 (void) dseg_adds4(cd, cd->exceptiontablelength); /* ExTableSize */
290 /* create exception table */
292 for (ex = cd->exceptiontable; ex != NULL; ex = ex->down) {
293 dseg_addtarget(cd, ex->start);
294 dseg_addtarget(cd, ex->end);
295 dseg_addtarget(cd, ex->handler);
296 (void) dseg_addaddress(cd, ex->catchtype.cls);
300 /* initialize mcode variables */
302 cd->mcodeptr = cd->mcodebase;
303 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
308 #if defined(USE_THREADS)
309 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
310 if (m->flags & ACC_STATIC)
311 gen_ACONST(cd, (java_objectheader *) m->class);
315 gen_MONITORENTER(cd);
322 /* walk through all basic blocks */
324 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
326 bptr->mpc = (s4) (cd->mcodeptr - cd->mcodebase);
328 if (bptr->flags >= BBREACHED) {
330 /* walk through all instructions */
337 for (iptr = bptr->iinstr; len > 0; src = iptr->dst, len--, iptr++) {
338 if (iptr->line != currentline) {
339 dseg_addlinenumber(cd, iptr->line, cd->mcodeptr);
340 currentline = iptr->line;
343 MCODECHECK(64); /* an instruction usually needs < 64 words */
347 case ICMD_INLINE_START:
348 case ICMD_INLINE_END:
351 case ICMD_NOP: /* ... ==> ... */
354 case ICMD_CHECKNULL: /* ..., objectref ==> ..., objectref */
359 /* constant operations ************************************************/
361 case ICMD_ICONST: /* ... ==> ..., constant */
362 /* op1 = 0, val.i = constant */
364 gen_ICONST(cd, iptr->val.i);
367 case ICMD_LCONST: /* ... ==> ..., constant */
368 /* op1 = 0, val.l = constant */
370 gen_LCONST(cd, iptr->val.l);
373 case ICMD_FCONST: /* ... ==> ..., constant */
374 /* op1 = 0, val.f = constant */
378 vm_f2Cell(iptr->val.f, fi);
383 case ICMD_DCONST: /* ... ==> ..., constant */
384 /* op1 = 0, val.d = constant */
386 gen_LCONST(cd, *(s8 *)&(iptr->val.d));
389 case ICMD_ACONST: /* ... ==> ..., constant */
390 /* op1 = 0, val.a = constant */
392 if ((iptr->target != NULL) && (iptr->val.a == NULL))
393 gen_PATCHER_ACONST(cd, NULL, iptr->target);
395 gen_ACONST(cd, iptr->val.a);
399 /* load/store operations **********************************************/
401 case ICMD_ILOAD: /* ... ==> ..., content of local variable */
402 /* op1 = local variable */
404 gen_ILOAD(cd, index2offset(iptr->op1));
407 case ICMD_LLOAD: /* ... ==> ..., content of local variable */
408 /* op1 = local variable */
410 gen_LLOAD(cd, index2offset(iptr->op1));
413 case ICMD_ALOAD: /* ... ==> ..., content of local variable */
414 /* op1 = local variable */
416 gen_ALOAD(cd, index2offset(iptr->op1));
419 case ICMD_FLOAD: /* ... ==> ..., content of local variable */
420 /* op1 = local variable */
422 gen_ILOAD(cd, index2offset(iptr->op1));
425 case ICMD_DLOAD: /* ... ==> ..., content of local variable */
426 /* op1 = local variable */
428 gen_LLOAD(cd, index2offset(iptr->op1));
432 case ICMD_ISTORE: /* ..., value ==> ... */
433 /* op1 = local variable */
435 gen_ISTORE(cd, index2offset(iptr->op1));
438 case ICMD_LSTORE: /* ..., value ==> ... */
439 /* op1 = local variable */
441 gen_LSTORE(cd, index2offset(iptr->op1));
444 case ICMD_ASTORE: /* ..., value ==> ... */
445 /* op1 = local variable */
447 gen_ASTORE(cd, index2offset(iptr->op1));
451 case ICMD_FSTORE: /* ..., value ==> ... */
452 /* op1 = local variable */
454 gen_ISTORE(cd, index2offset(iptr->op1));
457 case ICMD_DSTORE: /* ..., value ==> ... */
458 /* op1 = local variable */
460 gen_LSTORE(cd, index2offset(iptr->op1));
464 /* pop/dup/swap operations ********************************************/
466 /* attention: double and longs are only one entry in CACAO ICMDs */
468 /* stack.c changes stack manipulation operations to treat
469 longs/doubles as occupying a single slot. Here we are
470 undoing that (and only those things that stack.c did). */
472 case ICMD_POP: /* ..., value ==> ... */
474 if (IS_2_WORD_TYPE(src->type))
480 case ICMD_POP2: /* ..., value, value ==> ... */
485 case ICMD_DUP: /* ..., a ==> ..., a, a */
487 if (IS_2_WORD_TYPE(src->type))
493 case ICMD_DUP_X1: /* ..., a, b ==> ..., b, a, b */
495 if (IS_2_WORD_TYPE(src->type)) {
496 if (IS_2_WORD_TYPE(src->prev->type)) {
502 if (IS_2_WORD_TYPE(src->prev->type)) {
510 case ICMD_DUP_X2: /* ..., a, b, c ==> ..., c, a, b, c */
512 if (IS_2_WORD_TYPE(src->type)) {
518 case ICMD_DUP2: /* ..., a, b ==> ..., a, b, a, b */
523 case ICMD_DUP2_X1: /* ..., a, b, c ==> ..., b, c, a, b, c */
525 if (IS_2_WORD_TYPE(src->prev->prev->type))
531 case ICMD_DUP2_X2: /* ..., a, b, c, d ==> ..., c, d, a, b, c, d */
536 case ICMD_SWAP: /* ..., a, b ==> ..., b, a */
542 /* integer operations *************************************************/
544 case ICMD_INEG: /* ..., value ==> ..., - value */
549 case ICMD_LNEG: /* ..., value ==> ..., - value */
554 case ICMD_I2L: /* ..., value ==> ..., value */
559 case ICMD_L2I: /* ..., value ==> ..., value */
564 case ICMD_INT2BYTE: /* ..., value ==> ..., value */
569 case ICMD_INT2CHAR: /* ..., value ==> ..., value */
574 case ICMD_INT2SHORT: /* ..., value ==> ..., value */
580 case ICMD_IADD: /* ..., val1, val2 ==> ..., val1 + val2 */
585 case ICMD_IADDCONST: /* ..., value ==> ..., value + constant */
586 /* val.i = constant */
588 gen_ICONST(cd, iptr->val.i);
592 case ICMD_LADD: /* ..., val1, val2 ==> ..., val1 + val2 */
597 case ICMD_LADDCONST: /* ..., value ==> ..., value + constant */
598 /* val.l = constant */
600 gen_LCONST(cd, iptr->val.l);
604 case ICMD_ISUB: /* ..., val1, val2 ==> ..., val1 - val2 */
609 case ICMD_ISUBCONST: /* ..., value ==> ..., value + constant */
610 /* val.i = constant */
612 gen_ICONST(cd, iptr->val.i);
616 case ICMD_LSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
621 case ICMD_LSUBCONST: /* ..., value ==> ..., value - constant */
622 /* val.l = constant */
624 gen_LCONST(cd, iptr->val.l);
628 case ICMD_IMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
633 case ICMD_IMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
635 gen_ICONST(cd, iptr->val.i);
639 case ICMD_LMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
644 case ICMD_LMULCONST: /* ..., val1, val2 ==> ..., val1 * val2 */
646 gen_LCONST(cd, iptr->val.l);
650 case ICMD_IDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
655 case ICMD_IREM: /* ..., val1, val2 ==> ..., val1 % val2 */
660 case ICMD_LDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
665 case ICMD_LREM: /* ..., val1, val2 ==> ..., val1 % val2 */
670 case ICMD_IDIVPOW2: /* ..., value ==> ..., value << constant */
671 /* val.i = constant */
673 gen_IDIVPOW2(cd, iptr->val.i);
676 case ICMD_IREMPOW2: /* ..., value ==> ..., value % constant */
677 /* val.i = constant */
679 gen_IREMPOW2(cd, iptr->val.i);
682 case ICMD_LDIVPOW2: /* ..., value ==> ..., value << constant */
683 /* val.i = constant */
685 gen_LDIVPOW2(cd, iptr->val.i);
688 case ICMD_LREMPOW2: /* ..., value ==> ..., value % constant */
689 /* val.l = constant */
691 gen_LREMPOW2(cd, iptr->val.i);
694 case ICMD_ISHL: /* ..., val1, val2 ==> ..., val1 << val2 */
699 case ICMD_ISHLCONST: /* ..., value ==> ..., value << constant */
700 /* val.i = constant */
702 gen_ICONST(cd, iptr->val.i);
706 case ICMD_ISHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
711 case ICMD_ISHRCONST: /* ..., value ==> ..., value >> constant */
712 /* val.i = constant */
714 gen_ICONST(cd, iptr->val.i);
718 case ICMD_IUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
723 case ICMD_IUSHRCONST: /* ..., value ==> ..., value >>> constant */
724 /* val.i = constant */
726 gen_ICONST(cd, iptr->val.i);
730 case ICMD_LSHL: /* ..., val1, val2 ==> ..., val1 << val2 */
735 case ICMD_LSHLCONST: /* ..., value ==> ..., value << constant */
736 /* val.i = constant */
738 gen_ICONST(cd, iptr->val.i);
742 case ICMD_LSHR: /* ..., val1, val2 ==> ..., val1 >> val2 */
747 case ICMD_LSHRCONST: /* ..., value ==> ..., value >> constant */
748 /* val.i = constant */
750 gen_ICONST(cd, iptr->val.i);
754 case ICMD_LUSHR: /* ..., val1, val2 ==> ..., val1 >>> val2 */
759 case ICMD_LUSHRCONST: /* ..., value ==> ..., value >>> constant */
760 /* val.i = constant */
762 gen_ICONST(cd, iptr->val.i);
766 case ICMD_IAND: /* ..., val1, val2 ==> ..., val1 & val2 */
771 case ICMD_IANDCONST: /* ..., value ==> ..., value & constant */
772 /* val.i = constant */
774 gen_ICONST(cd, iptr->val.i);
778 case ICMD_LAND: /* ..., val1, val2 ==> ..., val1 & val2 */
783 case ICMD_LANDCONST: /* ..., value ==> ..., value & constant */
784 /* val.l = constant */
786 gen_LCONST(cd, iptr->val.l);
790 case ICMD_IOR: /* ..., val1, val2 ==> ..., val1 | val2 */
795 case ICMD_IORCONST: /* ..., value ==> ..., value | constant */
796 /* val.i = constant */
798 gen_ICONST(cd, iptr->val.i);
802 case ICMD_LOR: /* ..., val1, val2 ==> ..., val1 | val2 */
807 case ICMD_LORCONST: /* ..., value ==> ..., value | constant */
808 /* val.l = constant */
810 gen_LCONST(cd, iptr->val.l);
814 case ICMD_IXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
819 case ICMD_IXORCONST: /* ..., value ==> ..., value ^ constant */
820 /* val.i = constant */
822 gen_ICONST(cd, iptr->val.i);
826 case ICMD_LXOR: /* ..., val1, val2 ==> ..., val1 ^ val2 */
831 case ICMD_LXORCONST: /* ..., value ==> ..., value ^ constant */
832 /* val.l = constant */
834 gen_LCONST(cd, iptr->val.l);
839 case ICMD_LCMP: /* ..., val1, val2 ==> ..., val1 cmp val2 */
845 case ICMD_IINC: /* ..., value ==> ..., value + constant */
846 /* op1 = variable, val.i = constant */
848 gen_IINC(cd, index2offset(iptr->op1), iptr->val.i);
852 /* floating operations ************************************************/
854 case ICMD_FNEG: /* ..., value ==> ..., - value */
859 case ICMD_DNEG: /* ..., value ==> ..., - value */
864 case ICMD_FADD: /* ..., val1, val2 ==> ..., val1 + val2 */
869 case ICMD_DADD: /* ..., val1, val2 ==> ..., val1 + val2 */
874 case ICMD_FSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
879 case ICMD_DSUB: /* ..., val1, val2 ==> ..., val1 - val2 */
884 case ICMD_FMUL: /* ..., val1, val2 ==> ..., val1 * val2 */
889 case ICMD_DMUL: /* ..., val1, val2 ==> ..., val1 *** val2 */
894 case ICMD_FDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
899 case ICMD_DDIV: /* ..., val1, val2 ==> ..., val1 / val2 */
904 case ICMD_FREM: /* ..., val1, val2 ==> ..., val1 % val2 */
909 case ICMD_DREM: /* ..., val1, val2 ==> ..., val1 % val2 */
914 case ICMD_I2F: /* ..., value ==> ..., (float) value */
919 case ICMD_L2F: /* ..., value ==> ..., (float) value */
924 case ICMD_I2D: /* ..., value ==> ..., (double) value */
929 case ICMD_L2D: /* ..., value ==> ..., (double) value */
934 case ICMD_F2I: /* ..., value ==> ..., (int) value */
939 case ICMD_D2I: /* ..., value ==> ..., (int) value */
944 case ICMD_F2L: /* ..., value ==> ..., (long) value */
949 case ICMD_D2L: /* ..., value ==> ..., (long) value */
954 case ICMD_F2D: /* ..., value ==> ..., (double) value */
959 case ICMD_D2F: /* ..., value ==> ..., (float) value */
964 case ICMD_FCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
969 case ICMD_DCMPL: /* ..., val1, val2 ==> ..., val1 fcmpl val2 */
974 case ICMD_FCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
979 case ICMD_DCMPG: /* ..., val1, val2 ==> ..., val1 fcmpg val2 */
985 /* memory operations **************************************************/
987 case ICMD_ARRAYLENGTH: /* ..., arrayref ==> ..., length */
992 case ICMD_BALOAD: /* ..., arrayref, index ==> ..., value */
997 case ICMD_CALOAD: /* ..., arrayref, index ==> ..., value */
1002 case ICMD_SALOAD: /* ..., arrayref, index ==> ..., value */
1007 case ICMD_IALOAD: /* ..., arrayref, index ==> ..., value */
1008 case ICMD_FALOAD: /* ..., arrayref, index ==> ..., value */
1013 case ICMD_LALOAD: /* ..., arrayref, index ==> ..., value */
1014 case ICMD_DALOAD: /* ..., arrayref, index ==> ..., value */
1019 case ICMD_AALOAD: /* ..., arrayref, index ==> ..., value */
1025 case ICMD_BASTORE: /* ..., arrayref, index, value ==> ... */
1030 case ICMD_CASTORE: /* ..., arrayref, index, value ==> ... */
1031 case ICMD_SASTORE: /* ..., arrayref, index, value ==> ... */
1036 case ICMD_IASTORE: /* ..., arrayref, index, value ==> ... */
1037 case ICMD_FASTORE: /* ..., arrayref, index, value ==> ... */
1042 case ICMD_LASTORE: /* ..., arrayref, index, value ==> ... */
1043 case ICMD_DASTORE: /* ..., arrayref, index, value ==> ... */
1048 case ICMD_AASTORE: /* ..., arrayref, index, value ==> ... */
1054 case ICMD_GETSTATIC: /* ... ==> ..., value */
1055 /* op1 = type, val.a = field address */
1058 fieldinfo *fi = iptr->val.a;
1059 unresolved_field *uf = iptr->target;
1061 switch (iptr->op1) {
1064 if ((fi == NULL) || !(fi->class->state & CLASS_INITIALIZED)) {
1065 gen_PATCHER_GETSTATIC_INT(cd, 0, uf);
1067 gen_GETSTATIC_INT(cd, (u1 *)&(fi->value.i), uf);
1072 if ((fi == NULL) || !(fi->class->state & CLASS_INITIALIZED)) {
1073 gen_PATCHER_GETSTATIC_LONG(cd, 0, uf);
1075 gen_GETSTATIC_LONG(cd, (u1 *)&(fi->value.l), uf);
1079 if ((fi == NULL) || !(fi->class->state & CLASS_INITIALIZED)) {
1080 gen_PATCHER_GETSTATIC_CELL(cd, 0, uf);
1082 gen_GETSTATIC_CELL(cd, (u1 *)&(fi->value.a), uf);
1089 case ICMD_PUTSTATIC: /* ..., value ==> ... */
1090 /* op1 = type, val.a = field address */
1093 fieldinfo *fi = iptr->val.a;
1094 unresolved_field *uf = iptr->target;
1096 switch (iptr->op1) {
1099 if ((fi == NULL) || !(fi->class->state & CLASS_INITIALIZED)) {
1100 gen_PATCHER_PUTSTATIC_INT(cd, 0, uf);
1102 gen_PUTSTATIC_INT(cd, (u1 *)&(fi->value.i), uf);
1107 if ((fi == NULL) || !(fi->class->state & CLASS_INITIALIZED)) {
1108 gen_PATCHER_PUTSTATIC_LONG(cd, 0, uf);
1110 gen_PUTSTATIC_LONG(cd, (u1 *)&(fi->value.l), uf);
1114 if ((fi == NULL) || !(fi->class->state & CLASS_INITIALIZED)) {
1115 gen_PATCHER_PUTSTATIC_CELL(cd, 0, uf);
1117 gen_PUTSTATIC_CELL(cd, (u1 *)&(fi->value.a), uf);
1125 case ICMD_GETFIELD: /* ... ==> ..., value */
1126 /* op1 = type, val.a = field address */
1129 fieldinfo *fi = iptr->val.a;
1130 unresolved_field *uf = iptr->target;
1132 switch (iptr->op1) {
1136 gen_PATCHER_GETFIELD_INT(cd, 0, uf);
1138 gen_GETFIELD_INT(cd, fi->offset, uf);
1144 gen_PATCHER_GETFIELD_LONG(cd, 0, uf);
1146 gen_GETFIELD_LONG(cd, fi->offset, uf);
1151 gen_PATCHER_GETFIELD_CELL(cd, 0, uf);
1153 gen_GETFIELD_CELL(cd, fi->offset, uf);
1160 case ICMD_PUTFIELD: /* ..., objectref, value ==> ... */
1161 /* op1 = type, val.a = field address */
1164 fieldinfo *fi = iptr->val.a;
1165 unresolved_field *uf = iptr->target;
1167 switch (iptr->op1) {
1171 gen_PATCHER_PUTFIELD_INT(cd, 0, uf);
1173 gen_PUTFIELD_INT(cd, fi->offset, uf);
1179 gen_PATCHER_PUTFIELD_LONG(cd, 0, uf);
1181 gen_PUTFIELD_LONG(cd, fi->offset, uf);
1186 gen_PATCHER_PUTFIELD_CELL(cd, 0, uf);
1188 gen_PUTFIELD_CELL(cd, fi->offset, uf);
1196 /* branch operations **************************************************/
1198 case ICMD_ATHROW: /* ..., objectref ==> ... (, objectref) */
1203 case ICMD_GOTO: /* ... ==> ... */
1204 /* op1 = target JavaVM pc */
1208 case ICMD_JSR: /* ... ==> ... */
1209 /* op1 = target JavaVM pc */
1213 case ICMD_RET: /* ... ==> ... */
1214 /* op1 = local variable */
1216 gen_RET(cd, index2offset(iptr->op1));
1219 case ICMD_IFNULL: /* ..., value ==> ... */
1220 /* op1 = target JavaVM pc */
1225 case ICMD_IFNONNULL: /* ..., value ==> ... */
1226 /* op1 = target JavaVM pc */
1228 gen_branch(IFNONNULL);
1231 case ICMD_IFEQ: /* ..., value ==> ... */
1232 /* op1 = target JavaVM pc, val.i = constant */
1234 if (iptr->val.i == 0) {
1237 gen_ICONST(cd, iptr->val.i);
1238 gen_branch(IF_ICMPEQ);
1242 case ICMD_IFLT: /* ..., value ==> ... */
1243 /* op1 = target JavaVM pc, val.i = constant */
1245 if (iptr->val.i == 0) {
1248 gen_ICONST(cd, iptr->val.i);
1249 gen_branch(IF_ICMPLT);
1253 case ICMD_IFLE: /* ..., value ==> ... */
1254 /* op1 = target JavaVM pc, val.i = constant */
1256 if (iptr->val.i == 0) {
1259 gen_ICONST(cd, iptr->val.i);
1260 gen_branch(IF_ICMPLE);
1264 case ICMD_IFNE: /* ..., value ==> ... */
1265 /* op1 = target JavaVM pc, val.i = constant */
1267 if (iptr->val.i == 0) {
1270 gen_ICONST(cd, iptr->val.i);
1271 gen_branch(IF_ICMPNE);
1275 case ICMD_IFGT: /* ..., value ==> ... */
1276 /* op1 = target JavaVM pc, val.i = constant */
1278 if (iptr->val.i == 0) {
1281 gen_ICONST(cd, iptr->val.i);
1282 gen_branch(IF_ICMPGT);
1286 case ICMD_IFGE: /* ..., value ==> ... */
1287 /* op1 = target JavaVM pc, val.i = constant */
1289 if (iptr->val.i == 0) {
1292 gen_ICONST(cd, iptr->val.i);
1293 gen_branch(IF_ICMPGE);
1297 case ICMD_IF_LEQ: /* ..., value ==> ... */
1298 /* op1 = target JavaVM pc, val.l = constant */
1300 gen_LCONST(cd, iptr->val.l);
1301 gen_branch(IF_LCMPEQ);
1304 case ICMD_IF_LLT: /* ..., value ==> ... */
1305 /* op1 = target JavaVM pc, val.l = constant */
1307 gen_LCONST(cd, iptr->val.l);
1308 gen_branch(IF_LCMPLT);
1311 case ICMD_IF_LLE: /* ..., value ==> ... */
1312 /* op1 = target JavaVM pc, val.l = constant */
1314 gen_LCONST(cd, iptr->val.l);
1315 gen_branch(IF_LCMPLE);
1318 case ICMD_IF_LNE: /* ..., value ==> ... */
1319 /* op1 = target JavaVM pc, val.l = constant */
1321 gen_LCONST(cd, iptr->val.l);
1322 gen_branch(IF_LCMPNE);
1325 case ICMD_IF_LGT: /* ..., value ==> ... */
1326 /* op1 = target JavaVM pc, val.l = constant */
1328 gen_LCONST(cd, iptr->val.l);
1329 gen_branch(IF_LCMPGT);
1332 case ICMD_IF_LGE: /* ..., value ==> ... */
1333 /* op1 = target JavaVM pc, val.l = constant */
1335 gen_LCONST(cd, iptr->val.l);
1336 gen_branch(IF_LCMPGE);
1339 case ICMD_IF_ICMPEQ: /* ..., value, value ==> ... */
1340 /* op1 = target JavaVM pc */
1342 gen_branch(IF_ICMPEQ);
1345 case ICMD_IF_LCMPEQ: /* ..., value, value ==> ... */
1346 /* op1 = target JavaVM pc */
1348 gen_branch(IF_LCMPEQ);
1351 case ICMD_IF_ACMPEQ: /* ..., value, value ==> ... */
1352 /* op1 = target JavaVM pc */
1354 gen_branch(IF_ACMPEQ);
1357 case ICMD_IF_ICMPNE: /* ..., value, value ==> ... */
1358 /* op1 = target JavaVM pc */
1360 gen_branch(IF_ICMPNE);
1363 case ICMD_IF_LCMPNE: /* ..., value, value ==> ... */
1364 /* op1 = target JavaVM pc */
1366 gen_branch(IF_LCMPNE);
1369 case ICMD_IF_ACMPNE: /* ..., value, value ==> ... */
1370 /* op1 = target JavaVM pc */
1372 gen_branch(IF_ACMPNE);
1375 case ICMD_IF_ICMPLT: /* ..., value, value ==> ... */
1376 /* op1 = target JavaVM pc */
1378 gen_branch(IF_ICMPLT);
1381 case ICMD_IF_LCMPLT: /* ..., value, value ==> ... */
1382 /* op1 = target JavaVM pc */
1384 gen_branch(IF_LCMPLT);
1387 case ICMD_IF_ICMPGT: /* ..., value, value ==> ... */
1388 /* op1 = target JavaVM pc */
1390 gen_branch(IF_ICMPGT);
1393 case ICMD_IF_LCMPGT: /* ..., value, value ==> ... */
1394 /* op1 = target JavaVM pc */
1396 gen_branch(IF_LCMPGT);
1399 case ICMD_IF_ICMPLE: /* ..., value, value ==> ... */
1400 /* op1 = target JavaVM pc */
1402 gen_branch(IF_ICMPLE);
1405 case ICMD_IF_LCMPLE: /* ..., value, value ==> ... */
1406 /* op1 = target JavaVM pc */
1408 gen_branch(IF_LCMPLE);
1411 case ICMD_IF_ICMPGE: /* ..., value, value ==> ... */
1412 /* op1 = target JavaVM pc */
1414 gen_branch(IF_ICMPGE);
1417 case ICMD_IF_LCMPGE: /* ..., value, value ==> ... */
1418 /* op1 = target JavaVM pc */
1420 gen_branch(IF_LCMPGE);
1424 case ICMD_ARETURN: /* ..., retvalue ==> ... */
1425 case ICMD_IRETURN: /* ..., retvalue ==> ... */
1426 case ICMD_FRETURN: /* ..., retvalue ==> ... */
1428 #if defined(USE_THREADS)
1429 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1430 if (m->flags & ACC_STATIC) {
1431 gen_ACONST(cd, (java_objectheader *) m->class);
1435 gen_MONITOREXIT(cd);
1439 gen_TRACERETURN(cd);
1441 gen_IRETURN(cd, index2offset(cd->maxlocals));
1444 case ICMD_LRETURN: /* ..., retvalue ==> ... */
1445 case ICMD_DRETURN: /* ..., retvalue ==> ... */
1447 #if defined(USE_THREADS)
1448 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1449 if (m->flags & ACC_STATIC) {
1450 gen_ACONST(cd, (java_objectheader *) m->class);
1454 gen_MONITOREXIT(cd);
1458 gen_TRACELRETURN(cd);
1460 gen_LRETURN(cd, index2offset(cd->maxlocals));
1463 case ICMD_RETURN: /* ... ==> ... */
1465 #if defined(USE_THREADS)
1466 if (checksync && (m->flags & ACC_SYNCHRONIZED)) {
1467 if (m->flags & ACC_STATIC) {
1468 gen_ACONST(cd, (java_objectheader *) m->class);
1472 gen_MONITOREXIT(cd);
1476 gen_TRACERETURN(cd);
1478 gen_RETURN(cd, index2offset(cd->maxlocals));
1482 case ICMD_TABLESWITCH: /* ..., index ==> ... */
1487 tptr = (void **) iptr->target;
1489 s4ptr = iptr->val.a;
1490 l = s4ptr[1]; /* low */
1491 i = s4ptr[2]; /* high */
1495 /* arguments: low, range, datasegment address, table offset in */
1496 /* datasegment, default target */
1497 gen_TABLESWITCH(cd, l, i, NULL, 0, NULL);
1498 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1499 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1501 /* build jump table top down and use address of lowest entry */
1506 dseg_addtarget(cd, (basicblock *) tptr[0]);
1511 /* length of dataseg after last dseg_addtarget is used by load */
1512 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1516 case ICMD_LOOKUPSWITCH: /* ..., key ==> ... */
1521 tptr = (void **) iptr->target;
1523 s4ptr = iptr->val.a;
1525 /* s4ptr[0] is equal to tptr[0] */
1526 i = s4ptr[1]; /* count */
1528 /* arguments: count, datasegment address, table offset in */
1529 /* datasegment, default target */
1530 gen_LOOKUPSWITCH(cd, i, NULL, 0, NULL);
1531 dseg_adddata(cd, (cd->mcodeptr - 2*sizeof(Inst))); /* actually -3 cells offset*/
1532 codegen_addreference(cd, (basicblock *) tptr[0], cd->mcodeptr);
1534 /* build jump table top down and use address of lowest entry */
1540 dseg_addtarget(cd, (basicblock *) tptr[0]);
1541 dseg_addaddress(cd, s4ptr[0]);
1547 /* length of dataseg after last dseg_addtarget is used by load */
1548 ((ptrint *)(cd->mcodeptr))[-2] = (ptrint) -(cd->dseglen);
1552 case ICMD_BUILTIN: /* ..., arg1, arg2, arg3 ==> ... */
1553 /* op1 = arg count val.a = builtintable entry */
1556 for (i = 0; i < sizeof(builtin_gen_table)/sizeof(builtin_gen); i++) {
1557 builtin_gen *bg = &builtin_gen_table[i];
1558 if (bg->builtin == bte->fp) {
1560 goto gen_builtin_end;
1567 case ICMD_INVOKESTATIC: /* ..., [arg1, [arg2 ...]] ==> ... */
1568 /* op1 = arg count, val.a = method pointer */
1574 md = um->methodref->parseddesc.md;
1575 gen_PATCHER_INVOKESTATIC(cd, 0, md->paramslots, um);
1578 md = lm->parseddesc;
1579 gen_INVOKESTATIC(cd, (Inst **)lm->stubroutine, md->paramslots, um);
1583 case ICMD_INVOKESPECIAL:/* ..., objectref, [arg1, [arg2 ...]] ==> ... */
1589 md = um->methodref->parseddesc.md;
1590 gen_PATCHER_INVOKESPECIAL(cd, 0, md->paramslots, um);
1593 md = lm->parseddesc;
1594 gen_INVOKESPECIAL(cd, (Inst **)lm->stubroutine, md->paramslots, um);
1598 case ICMD_INVOKEVIRTUAL:/* op1 = arg count, val.a = method pointer */
1604 md = um->methodref->parseddesc.md;
1605 gen_PATCHER_INVOKEVIRTUAL(cd, 0, md->paramslots, um);
1608 md = lm->parseddesc;
1610 s1 = OFFSET(vftbl_t, table[0]) +
1611 sizeof(methodptr) * lm->vftblindex;
1613 gen_INVOKEVIRTUAL(cd, s1, md->paramslots, um);
1617 case ICMD_INVOKEINTERFACE:/* op1 = arg count, val.a = method pointer */
1623 md = um->methodref->parseddesc.md;
1624 gen_PATCHER_INVOKEINTERFACE(cd, 0, 0, md->paramslots, um);
1627 md = lm->parseddesc;
1629 s1 = OFFSET(vftbl_t, interfacetable[0]) -
1630 sizeof(methodptr*) * lm->class->index;
1632 s2 = sizeof(methodptr) * (lm - lm->class->methods);
1634 gen_INVOKEINTERFACE(cd, s1, s2, md->paramslots, um);
1639 case ICMD_CHECKCAST: /* ..., objectref ==> ..., objectref */
1640 /* op1: 0 == array, 1 == class */
1641 /* val.a: (classinfo *) superclass */
1643 if (iptr->op1 == 1) {
1644 if (iptr->val.a == NULL)
1645 gen_PATCHER_CHECKCAST(cd, NULL, iptr->target);
1647 gen_CHECKCAST(cd, iptr->val.a, NULL);
1649 if (iptr->val.a == NULL)
1650 gen_PATCHER_ARRAYCHECKCAST(cd, NULL, iptr->target);
1652 gen_ARRAYCHECKCAST(cd, iptr->val.a, NULL);
1656 case ICMD_INSTANCEOF: /* ..., objectref ==> ..., intresult */
1657 /* op1: 0 == array, 1 == class */
1658 /* val.a: (classinfo *) superclass */
1660 if (iptr->val.a == NULL)
1661 gen_PATCHER_INSTANCEOF(cd, 0, iptr->target);
1663 gen_INSTANCEOF(cd, iptr->val.a, iptr->target);
1666 case ICMD_MULTIANEWARRAY:/* ..., cnt1, [cnt2, ...] ==> ..., arrayref */
1667 /* op1 = dimension, val.a = array descriptor */
1670 gen_PATCHER_MULTIANEWARRAY(cd, 0, iptr->op1, iptr->val.a);
1672 gen_MULTIANEWARRAY(cd, iptr->val.a, iptr->op1, 0);
1677 *exceptionptr = new_internalerror("Unknown ICMD %d", iptr->opc);
1681 } /* for instruction */
1683 } /* if (bptr -> flags >= BBREACHED) */
1684 } /* for basic block */
1686 codegen_createlinenumbertable(cd);
1688 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1691 vm_block_insert(m->mcode + m->mcodelength);
1694 /* branch resolving (walk through all basic blocks) */
1696 for (bptr = m->basicblocks; bptr != NULL; bptr = bptr->next) {
1699 for (brefs = bptr->branchrefs; brefs != NULL; brefs = brefs->next) {
1700 gen_resolveanybranch(((u1*) m->entrypoint) + brefs->branchpos,
1701 ((u1 *)m->entrypoint) + bptr->mpc);
1705 /* everything's ok */
1711 /* a stub consists of
1723 codeptr points either to TRANSLATE or to the translated threaded code
1725 all methods are called indirectly through methodptr
1728 #define COMPILERSTUB_SIZE 4
1730 u1 *createcompilerstub (methodinfo *m)
1736 s = CNEW(Inst, COMPILERSTUB_SIZE);
1738 /* mark start of dump memory area */
1740 dumpsize = dump_size();
1742 cd = DNEW(codegendata);
1743 cd->mcodeptr = (u1 *) s;
1744 cd->lastinstwithoutdispatch = ~0;
1745 cd->superstarts = NULL;
1747 genarg_ainst(cd, s + 2);
1749 if (m->flags & ACC_NATIVE) {
1750 genarg_i(cd, m->parseddesc->paramslots);
1752 genarg_i(cd, m->maxlocals);
1756 gen_TRANSLATE(cd, m);
1759 vm_block_insert(cd->mcodeptr);
1762 #if defined(STATISTICS)
1764 count_cstub_len += COMPILERSTUB_SIZE;
1767 /* release dump area */
1769 dump_release(dumpsize);
1787 static ffi_cif *createnativecif(methodinfo *m, methoddesc *nmd)
1789 methoddesc *md = m->parseddesc;
1790 ffi_cif *pcif = NEW(ffi_cif);
1791 ffi_type **types = MNEW(ffi_type *, nmd->paramcount);
1792 ffi_type **ptypes = types;
1795 /* pass env pointer */
1797 *ptypes++ = &ffi_type_pointer;
1799 /* for static methods, pass class pointer */
1801 if (m->flags & ACC_STATIC)
1802 *ptypes++ = &ffi_type_pointer;
1804 /* pass parameter to native function */
1806 for (i = 0; i < md->paramcount; i++)
1807 *ptypes++ = cacaotype2ffitype(md->paramtypes[i].type);
1809 assert(ptypes - types == nmd->paramcount);
1811 if (ffi_prep_cif(pcif, FFI_DEFAULT_ABI, nmd->paramcount, cacaotype2ffitype(md->returntype.type), types) != FFI_OK)
1818 u1 *createnativestub(functionptr f, methodinfo *m, codegendata *cd,
1819 registerdata *rd, methoddesc *nmd)
1824 cd->mcodeptr = cd->mcodebase;
1825 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
1828 /* create method header */
1830 (void) dseg_addaddress(cd, m); /* MethodPointer */
1831 (void) dseg_adds4(cd, nmd->paramslots * SIZEOF_VOID_P); /* FrameSize */
1832 (void) dseg_adds4(cd, 0); /* IsSync */
1833 (void) dseg_adds4(cd, 0); /* IsLeaf */
1834 (void) dseg_adds4(cd, 0); /* IntSave */
1835 (void) dseg_adds4(cd, 0); /* FltSave */
1836 dseg_addlinenumbertablesize(cd);
1837 (void) dseg_adds4(cd, 0); /* ExTableSize */
1839 /* prepare ffi cif structure */
1841 cif = createnativecif(m, nmd);
1849 gen_PATCHER_NATIVECALL(cd, m, f, (u1 *)cif);
1852 gen_TRACENATIVECALL(cd, m, f, (u1 *)cif);
1854 gen_NATIVECALL(cd, m, f, (u1 *)cif);
1857 codegen_finish(m, cd, (s4) (cd->mcodeptr - cd->mcodebase));
1860 vm_block_insert(m->mcode + m->mcodelength);
1863 return m->entrypoint;
1868 ffi_type *cacaotype2ffitype(s4 cacaotype)
1870 switch (cacaotype) {
1872 return &ffi_type_uint;
1874 return &ffi_type_sint64;
1876 return &ffi_type_float;
1878 return &ffi_type_double;
1880 return &ffi_type_pointer;
1882 return &ffi_type_void;
1890 /* call jni function */
1891 Cell *nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1 *addrcif)
1907 switch (md->returntype.type) {
1909 endsp = sp - 1 + md->paramslots;
1910 av_start_int(alist, f, endsp);
1913 endsp = sp - 2 + md->paramslots;
1914 av_start_longlong(alist, f, endsp);
1917 endsp = sp - 1 + md->paramslots;
1918 av_start_float(alist, f, endsp);
1921 endsp = sp - 2 + md->paramslots;
1922 av_start_double(alist, f, endsp);
1925 endsp = sp - 1 + md->paramslots;
1926 av_start_ptr(alist, f, void *, endsp);
1929 endsp = sp + md->paramslots;
1930 av_start_void(alist, f);
1936 av_ptr(alist, JNIEnv *, &env);
1938 if (m->flags & ACC_STATIC)
1939 av_ptr(alist, classinfo *, m->class);
1941 for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
1942 switch (md->paramtypes[i].type) {
1949 av_longlong(alist, *(s8 *)p);
1953 av_float(alist, *(float *) p);
1957 av_double(alist, *(double *) p);
1961 av_ptr(alist, void *, *(void **) p);
1970 /* create stackframe info structure */
1972 codegen_start_native_call(&s, (u1 *) m->entrypoint,
1978 codegen_finish_native_call(&s);
1984 methoddesc *md = m->parseddesc;
1986 void *values[md->paramcount + 2];
1987 void **pvalues = values;
1998 pcif = (ffi_cif *) addrcif;
2000 /* pass env pointer */
2002 penv = (JNIEnv *) &env;
2005 /* for static methods, pass class pointer */
2007 if (m->flags & ACC_STATIC) {
2008 *pvalues++ = &m->class;
2011 /* pass parameter to native function */
2013 for (i = 0, p = sp + md->paramslots; i < md->paramcount; i++) {
2014 if (IS_2_WORD_TYPE(md->paramtypes[i].type))
2022 /* calculate position of return value */
2024 if (md->returntype.type == TYPE_VOID)
2025 endsp = sp + md->paramslots;
2027 endsp = sp - (IS_2_WORD_TYPE(md->returntype.type) ? 2 : 1) + md->paramslots;
2031 /* create stackframe info structure */
2033 codegen_start_native_call((u1 *) (((ptrint ) &s) + sizeof(s)),
2034 (u1 *) (ptrint) m->entrypoint,
2035 (u1 *) fp, (u1 *) ra);
2037 ffi_call(pcif, FFI_FN(f), endsp, values);
2039 codegen_finish_native_call((u1 *) (((ptrint) &s) + sizeof(s)));
2048 u1 *createcalljavafunction(methodinfo *m)
2054 t_inlining_globals *id;
2058 /* mark dump memory */
2060 dumpsize = dump_size();
2062 tmpm = DNEW(methodinfo);
2063 cd = DNEW(codegendata);
2064 rd = DNEW(registerdata);
2065 id = DNEW(t_inlining_globals);
2067 /* setup code generation stuff */
2069 MSET(tmpm, 0, u1, sizeof(methodinfo));
2071 inlining_setup(tmpm, id);
2072 codegen_setup(tmpm, cd, id);
2077 cd->mcodeptr = cd->mcodebase;
2078 cd->mcodeend = (s4 *) (cd->mcodebase + cd->mcodesize);
2081 /* create method header */
2083 (void) dseg_addaddress(cd, NULL); /* MethodPointer */
2084 (void) dseg_adds4(cd, md->paramslots * SIZEOF_VOID_P); /* FrameSize */
2085 (void) dseg_adds4(cd, 0); /* IsSync */
2086 (void) dseg_adds4(cd, 0); /* IsLeaf */
2087 (void) dseg_adds4(cd, 0); /* IntSave */
2088 (void) dseg_adds4(cd, 0); /* FltSave */
2089 dseg_addlinenumbertablesize(cd);
2090 (void) dseg_adds4(cd, 0); /* ExTableSize */
2096 gen_INVOKESTATIC(cd, (Inst **)m->stubroutine, md->paramslots, 0);
2099 codegen_finish(tmpm, cd, (s4) (cd->mcodeptr - cd->mcodebase));
2102 vm_block_insert(tmpm->mcode + tmpm->mcodelength);
2104 entrypoint = tmpm->entrypoint;
2106 /* release memory */
2108 dump_release(dumpsize);
2115 * These are local overrides for various environment variables in Emacs.
2116 * Please do not remove this and leave it at the end of the file, where
2117 * Emacs will automagically detect them.
2118 * ---------------------------------------------------------------------
2121 * indent-tabs-mode: t