33 #elif defined(WITH_FFCALL)
36 # error neither WITH_FFI nor WITH_FFCALL defined
62 #include "vm/jit/patcher.hpp"
67 #define gen_branch(_inst) { \
69 codegen_addreference(cd, BLOCK_OF(iptr->dst.insindex)); \
72 #define index2offset(_i) (-(_i) * SIZEOF_VOID_P)
79 *((
Cell *) *mcodepp) = v;
86 *((
Cell *) *mcodepp) =
i;
113 *((java_objectheader **) *mcodepp) = a;
120 *((java_arrayheader **) *mcodepp) = a;
127 *((
Inst ***) *mcodepp) = a;
148 *((
u1 **) *mcodepp) = a;
176 *((
Cell **) *mcodepp) = a;
183 *((
Inst **) *mcodepp) = a;
212 #include <java-gen.i>
237 #if defined(ENABLE_THREADS)
242 #if !(SUPPORT_FLOAT && SUPPORT_F2L)
246 #if !(SUPPORT_DOUBLE && SUPPORT_D2L)
250 #if !(SUPPORT_FLOAT && SUPPORT_F2I)
254 #if !(SUPPORT_DOUBLE && SUPPORT_D2I)
258 #if !SUPPORT_DIVISION
263 #if !(SUPPORT_DIVISION && SUPPORT_LONG_DIV)
279 #define I(value) iptr[0].sx.val.i = (value); break;
315 #if defined(ENABLE_THREADS)
325 code->synchronizedoffset = rd->
memuse * 8;
337 dseg_addlinenumbertablesize(cd);
348 #if defined(ENABLE_THREADS)
351 gen_ACONST(cd, (java_objectheader *) m->
clazz);
359 gen_MONITORENTER(cd);
364 gen_TRACECALL(cd, m);
382 for (iptr = bptr->
iinstr; len > 0; len--, iptr++) {
383 if (iptr->
line != currentline) {
384 dseg_addlinenumber(cd, iptr->
line);
385 currentline = iptr->
line;
412 if (len >= 2 && iptr[1].opc ==
ICMD_IREM) {
413 switch (iptr[0].sx.
val.
i) {
414 case 0x00000001:
case 0x00000002:
case 0x00000004:
case 0x00000008:
415 case 0x00000010:
case 0x00000020:
case 0x00000040:
case 0x00000080:
416 case 0x00000100:
case 0x00000200:
case 0x00000400:
case 0x00000800:
417 case 0x00001000:
case 0x00002000:
case 0x00004000:
case 0x00008000:
418 case 0x00010000:
case 0x00020000:
case 0x00040000:
case 0x00080000:
419 case 0x00100000:
case 0x00200000:
case 0x00400000:
case 0x00800000:
420 case 0x01000000:
case 0x02000000:
case 0x04000000:
case 0x08000000:
421 case 0x10000000:
case 0x20000000:
case 0x40000000:
case 0x80000000:
431 if (len >= 2 && iptr[1].opc ==
ICMD_IDIV) {
432 switch (iptr[0].sx.
val.
i) {
433 case 0x00000002:
I( 1)
case 0x00000004:
I( 2)
case 0x00000008:
I( 3)
434 case 0x00000010:
I( 4)
case 0x00000020:
I( 5)
case 0x00000040:
I( 6)
case 0x00000080:
I( 7)
435 case 0x00000100:
I( 8)
case 0x00000200:
I( 9)
case 0x00000400:
I(10)
case 0x00000800:
I(11)
436 case 0x00001000:
I(12)
case 0x00002000:
I(13)
case 0x00004000:
I(14)
case 0x00008000:
I(15)
437 case 0x00010000:
I(16)
case 0x00020000:
I(17)
case 0x00040000:
I(18)
case 0x00080000:
I(19)
438 case 0x00100000:
I(20)
case 0x00200000:
I(21)
case 0x00400000:
I(22)
case 0x00800000:
I(23)
439 case 0x01000000:
I(24)
case 0x02000000:
I(25)
case 0x04000000:
I(26)
case 0x08000000:
I(27)
440 case 0x10000000:
I(28)
case 0x20000000:
I(29)
case 0x40000000:
I(30)
case 0x80000000:
I(31)
441 default:
goto dont_opt_IDIVPOW2;
452 switch (iptr[1].opc) {
459 default:
goto dont_opt_IFxx;
467 gen_ICONST(cd, iptr->
sx.
val.
i);
475 if (len >= 2 && iptr[1].opc ==
ICMD_LREM) {
476 switch (iptr[0].sx.
val.
l) {
477 case 0x00000001:
case 0x00000002:
case 0x00000004:
case 0x00000008:
478 case 0x00000010:
case 0x00000020:
case 0x00000040:
case 0x00000080:
479 case 0x00000100:
case 0x00000200:
case 0x00000400:
case 0x00000800:
480 case 0x00001000:
case 0x00002000:
case 0x00004000:
case 0x00008000:
481 case 0x00010000:
case 0x00020000:
case 0x00040000:
case 0x00080000:
482 case 0x00100000:
case 0x00200000:
case 0x00400000:
case 0x00800000:
483 case 0x01000000:
case 0x02000000:
case 0x04000000:
case 0x08000000:
484 case 0x10000000:
case 0x20000000:
case 0x40000000:
case 0x80000000:
494 if (len >= 2 && iptr[1].opc ==
ICMD_LDIV) {
495 switch (iptr[0].sx.
val.
l) {
496 case 0x00000002:
I( 1)
case 0x00000004:
I( 2)
case 0x00000008:
I( 3)
497 case 0x00000010:
I( 4)
case 0x00000020:
I( 5)
case 0x00000040:
I( 6)
case 0x00000080:
I( 7)
498 case 0x00000100:
I( 8)
case 0x00000200:
I( 9)
case 0x00000400:
I(10)
case 0x00000800:
I(11)
499 case 0x00001000:
I(12)
case 0x00002000:
I(13)
case 0x00004000:
I(14)
case 0x00008000:
I(15)
500 case 0x00010000:
I(16)
case 0x00020000:
I(17)
case 0x00040000:
I(18)
case 0x00080000:
I(19)
501 case 0x00100000:
I(20)
case 0x00200000:
I(21)
case 0x00400000:
I(22)
case 0x00800000:
I(23)
502 case 0x01000000:
I(24)
case 0x02000000:
I(25)
case 0x04000000:
I(26)
case 0x08000000:
I(27)
503 case 0x10000000:
I(28)
case 0x20000000:
I(29)
case 0x40000000:
I(30)
case 0x80000000:
I(31)
504 default:
goto dont_opt_LDIVPOW2;
514 if (len >= 3 && iptr[1].opc ==
ICMD_LCMP && iptr[2].sx.
val.
i == 0) {
515 switch (iptr[2].opc) {
522 default:
goto dont_opt_IF_Lxx;
531 gen_LCONST(cd, iptr->
sx.
val.
l);
547 gen_LCONST(cd, *(
s8 *)&(iptr->
sx.
val.
d));
554 gen_PATCHER_ACONST(cd, NULL, iptr->
sx.
val.
c.
ref);
764 gen_IDIVPOW2(cd, iptr->
sx.
val.
i);
770 gen_IREMPOW2(cd, iptr->
sx.
val.
i);
776 gen_LDIVPOW2(cd, iptr->
sx.
val.
i);
782 gen_LREMPOW2(cd, iptr->
sx.
val.
i);
850 if (len >= 2 && iptr[1].sx.
val.
i == 0) {
851 switch (iptr[1].opc) {
858 default:
goto dont_opt_IF_LCMPxx;
1014 gen_ARRAYLENGTH(cd);
1092 uf = iptr->
sx.
s23.s3.uf;
1096 fi = iptr->
sx.
s23.s3.fmiref->p.field;
1098 fieldtype = fi->
type;
1101 switch (fieldtype) {
1104 gen_PATCHER_GETSTATIC_INT(cd, 0, uf);
1106 gen_PATCHER_GETSTATIC_CLINIT_INT(cd, 0, fi);
1108 gen_GETSTATIC_INT(cd, (
u1 *) &(fi->
value.
i), fi);
1112 gen_PATCHER_GETSTATIC_FLOAT(cd, 0, uf);
1114 gen_PATCHER_GETSTATIC_CLINIT_FLOAT(cd, 0, fi);
1116 gen_GETSTATIC_FLOAT(cd, (
u1 *) &(fi->
value.
i), fi);
1121 gen_PATCHER_GETSTATIC_LONG(cd, 0, uf);
1123 gen_PATCHER_GETSTATIC_CLINIT_LONG(cd, 0, fi);
1125 gen_GETSTATIC_LONG(cd, (
u1 *) &(fi->
value.
l), fi);
1129 gen_PATCHER_GETSTATIC_CELL(cd, 0, uf);
1131 gen_PATCHER_GETSTATIC_CLINIT_CELL(cd, 0, fi);
1133 gen_GETSTATIC_CELL(cd, (
u1 *) &(fi->
value.
a), fi);
1143 uf = iptr->
sx.
s23.s3.uf;
1147 fi = iptr->
sx.
s23.s3.fmiref->p.field;
1149 fieldtype = fi->
type;
1152 switch (fieldtype) {
1155 gen_PATCHER_PUTSTATIC_INT(cd, 0, uf);
1157 gen_PATCHER_PUTSTATIC_CLINIT_INT(cd, 0, fi);
1159 gen_PUTSTATIC_INT(cd, (
u1 *) &(fi->
value.
i), fi);
1163 gen_PATCHER_PUTSTATIC_FLOAT(cd, 0, uf);
1165 gen_PATCHER_PUTSTATIC_CLINIT_FLOAT(cd, 0, fi);
1167 gen_PUTSTATIC_FLOAT(cd, (
u1 *) &(fi->
value.
i), fi);
1172 gen_PATCHER_PUTSTATIC_LONG(cd, 0, uf);
1174 gen_PATCHER_PUTSTATIC_CLINIT_LONG(cd, 0, fi);
1176 gen_PUTSTATIC_LONG(cd, (
u1 *) &(fi->
value.
l), fi);
1180 gen_PATCHER_PUTSTATIC_CELL(cd, 0, uf);
1182 gen_PATCHER_PUTSTATIC_CLINIT_CELL(cd, 0, fi);
1184 gen_PUTSTATIC_CELL(cd, (
u1 *) &(fi->
value.
a), fi);
1195 uf = iptr->
sx.
s23.s3.uf;
1199 fi = iptr->
sx.
s23.s3.fmiref->p.field;
1201 fieldtype = fi->
type;
1204 switch (fieldtype) {
1207 gen_PATCHER_GETFIELD_INT(cd, 0, uf);
1209 gen_GETFIELD_INT(cd, fi->
offset, fi);
1213 gen_PATCHER_GETFIELD_FLOAT(cd, 0, uf);
1215 gen_GETFIELD_FLOAT(cd, fi->
offset, fi);
1220 gen_PATCHER_GETFIELD_LONG(cd, 0, uf);
1222 gen_GETFIELD_LONG(cd, fi->
offset, fi);
1226 gen_PATCHER_GETFIELD_CELL(cd, 0, uf);
1228 gen_GETFIELD_CELL(cd, fi->
offset, fi);
1238 uf = iptr->
sx.
s23.s3.uf;
1242 fi = iptr->
sx.
s23.s3.fmiref->p.field;
1244 fieldtype = fi->
type;
1247 switch (fieldtype) {
1250 gen_PATCHER_PUTFIELD_INT(cd, 0, uf);
1252 gen_PUTFIELD_INT(cd, fi->
offset, fi);
1256 gen_PATCHER_PUTFIELD_FLOAT(cd, 0, uf);
1258 gen_PUTFIELD_FLOAT(cd, fi->
offset, fi);
1263 gen_PATCHER_PUTFIELD_LONG(cd, 0, uf);
1265 gen_PUTFIELD_LONG(cd, fi->
offset, fi);
1269 gen_PATCHER_PUTFIELD_CELL(cd, 0, uf);
1271 gen_PUTFIELD_CELL(cd, fi->
offset, fi);
1293 codegen_addreference(cd, BLOCK_OF(iptr->
sx.
s23.s3.jsrtarget.insindex));
1317 if (iptr->
sx.
val.
i == 0) {
1320 gen_ICONST(cd, iptr->
sx.
val.
i);
1328 if (iptr->
sx.
val.
i == 0) {
1331 gen_ICONST(cd, iptr->
sx.
val.
i);
1339 if (iptr->
sx.
val.
i == 0) {
1342 gen_ICONST(cd, iptr->
sx.
val.
i);
1350 if (iptr->
sx.
val.
i == 0) {
1353 gen_ICONST(cd, iptr->
sx.
val.
i);
1361 if (iptr->
sx.
val.
i == 0) {
1364 gen_ICONST(cd, iptr->
sx.
val.
i);
1372 if (iptr->
sx.
val.
i == 0) {
1375 gen_ICONST(cd, iptr->
sx.
val.
i);
1384 gen_LCONST(cd, iptr->
sx.
val.
l);
1391 gen_LCONST(cd, iptr->
sx.
val.
l);
1398 gen_LCONST(cd, iptr->
sx.
val.
l);
1405 gen_LCONST(cd, iptr->
sx.
val.
l);
1412 gen_LCONST(cd, iptr->
sx.
val.
l);
1419 gen_LCONST(cd, iptr->
sx.
val.
l);
1513 #if defined(ENABLE_THREADS)
1516 gen_ACONST(cd, (java_objectheader *) m->
clazz);
1520 gen_MONITOREXIT(cd);
1524 gen_TRACERETURN(cd, m);
1532 #if defined(ENABLE_THREADS)
1535 gen_ACONST(cd, (java_objectheader *) m->
clazz);
1539 gen_MONITOREXIT(cd);
1543 gen_TRACELRETURN(cd, m);
1550 #if defined(ENABLE_THREADS)
1553 gen_ACONST(cd, (java_objectheader *) m->
clazz);
1557 gen_MONITOREXIT(cd);
1561 gen_TRACERETURN(cd, m);
1574 l = iptr->
sx.
s23.s2.tablelow;
1575 i = iptr->
sx.
s23.s3.tablehigh;
1582 gen_TABLESWITCH(cd, l, i, NULL, 0, NULL);
1590 codegen_addreference(cd, BLOCK_OF(table[0].insindex));
1614 i = iptr->
sx.
s23.s2.lookupcount;
1618 gen_LOOKUPSWITCH(cd, i, NULL, 0, NULL);
1634 codegen_addreference(cd, BLOCK_OF(iptr->
sx.
s23.s3.lookupdefault.insindex));
1644 bte = iptr->
sx.
s23.s3.bte;
1650 goto gen_builtin_end;
1663 um = iptr->
sx.
s23.s3.um;
1665 gen_PATCHER_INVOKESTATIC(cd, 0, md->
paramslots, um);
1668 lm = iptr->
sx.
s23.s3.fmiref->p.method;
1677 um = iptr->
sx.
s23.s3.um;
1679 gen_PATCHER_INVOKESPECIAL(cd, 0, md->
paramslots, um);
1682 lm = iptr->
sx.
s23.s3.fmiref->p.method;
1691 um = iptr->
sx.
s23.s3.um;
1693 gen_PATCHER_INVOKEVIRTUAL(cd, 0, md->
paramslots, um);
1696 lm = iptr->
sx.
s23.s3.fmiref->p.method;
1702 gen_INVOKEVIRTUAL(cd, s1, md->
paramslots, lm);
1709 um = iptr->
sx.
s23.s3.um;
1711 gen_PATCHER_INVOKEINTERFACE(cd, 0, 0, md->
paramslots, um);
1714 lm = iptr->
sx.
s23.s3.fmiref->p.method;
1722 gen_INVOKEINTERFACE(cd, s1, s2, md->
paramslots, lm);
1733 gen_PATCHER_CHECKCAST(cd, NULL, iptr->
sx.
s23.s3.c.ref);
1735 gen_CHECKCAST(cd, iptr->
sx.
s23.s3.c.cls, NULL);
1739 gen_PATCHER_ARRAYCHECKCAST(cd, NULL, iptr->
sx.
s23.s3.c.ref);
1741 gen_ARRAYCHECKCAST(cd, iptr->
sx.
s23.s3.c.cls, NULL);
1750 gen_PATCHER_INSTANCEOF(cd, NULL, iptr->
sx.
s23.s3.c.ref);
1752 gen_INSTANCEOF(cd, iptr->
sx.
s23.s3.c.cls, iptr->
sx.
s23.s3.c.ref);
1759 gen_PATCHER_MULTIANEWARRAY(cd, NULL, iptr->
s1.
argcount, iptr->
sx.
s23.s3.c.ref);
1761 gen_MULTIANEWARRAY(cd, iptr->
sx.
s23.s3.c.cls, iptr->
s1.
argcount, NULL);
1777 dseg_createlinenumbertable(cd);
1790 for (brefs = bptr->
branchrefs; brefs != NULL; brefs = brefs->
next) {
1826 #define COMPILERSTUB_DATASIZE 2
1827 #define COMPILERSTUB_CODESIZE 4
1829 #define COMPILERSTUB_SIZE COMPILERSTUB_DATASIZE + COMPILERSTUB_CODESIZE
1851 d[1] = (
Inst *) &d[0];
1859 cd->lastinstwithoutdispatch = ~0;
1860 cd->superstarts = NULL;
1870 #if defined(ENABLE_THREADS)
1872 stackframesize += 1;
1879 gen_TRANSLATE(cd, m);
1886 #if defined(ENABLE_STATISTICS)
1888 #warning port to new statistics framework
1900 #if defined(WITH_FFI)
1901 static ffi_type *cacaotype2ffitype(
s4 cacaotype)
1903 switch (cacaotype) {
1905 #if SIZEOF_VOID_P == 8
1906 return &ffi_type_sint64;
1908 return &ffi_type_sint32;
1911 return &ffi_type_sint64;
1913 return &ffi_type_float;
1915 return &ffi_type_double;
1917 return &ffi_type_pointer;
1919 return &ffi_type_void;
1939 #if defined(WITH_FFI)
1943 ffi_cif *pcif =
NEW(ffi_cif);
1945 ffi_type **ptypes = types;
1950 *ptypes++ = &ffi_type_pointer;
1955 *ptypes++ = &ffi_type_pointer;
1978 #if defined(WITH_FFI)
2004 dseg_addlinenumbertablesize(cd);
2007 #if defined(WITH_FFI)
2010 cif = createnativecif(m, nmd);
2018 gen_TRACECALL(cd, m);
2021 gen_PATCHER_NATIVECALL(cd, m, f, (
u1 *)cif);
2024 gen_TRACENATIVECALL(cd, m, f, (
u1 *)cif);
2026 gen_NATIVECALL(cd, m, f, (
u1 *)cif);
2044 #if defined(WITH_FFCALL)
2061 av_start_long(alist, f, endsp);
2065 av_start_longlong(alist, f, endsp);
2069 av_start_float(alist, f, endsp);
2073 av_start_double(alist, f, endsp);
2077 av_start_ptr(alist, f,
void *, endsp);
2081 av_start_void(alist, f);
2092 for (i = 0, p = sp + md->
paramslots; i < md->paramcount; i++) {
2100 av_longlong(alist, *(
s8 *)p);
2104 av_float(alist, *((
float *) p));
2108 av_double(alist, *(
double *) p);
2112 av_ptr(alist,
void *, *(
void **) p);
2124 (
u1 *) fp, (
u1 *) ra);
2133 #elif defined(WITH_FFI)
2137 void **pvalues = values;
2148 pcif = (ffi_cif *) addrcif;
2158 *pvalues++ = &m->
clazz;
2162 for (i = 0, p = sp + md->
paramslots; i < md->paramcount; i++) {
2185 ffi_call(pcif, FFI_FN(f), endsp, values);
2243 dseg_addlinenumbertablesize(cd);
Cell * nativecall(functionptr f, methodinfo *m, Cell *sp, Inst *ra, Cell *fp, u1 *addrcif)
void genarg_aRef(codegendata *cd1, java_objectheader *a)
#define MSET(ptr, byte, type, num)
s4 dseg_add_unique_address(codegendata *cd, void *value)
struct builtin_gen builtin_gen_table[]
#define BUILTIN_newarray_float
void genarg_aum(codegendata *cd1, unresolved_method *a)
void genarg_avftbl(codegendata *cd1, vftbl_t *a)
#define gen_resolveanybranch(ip, target)
void genarg_i(codegendata *cd1, s4 i)
typedef void(JNICALL *jvmtiEventSingleStep)(jvmtiEnv *jvmti_env
#define BUILTIN_newarray_long
void genarg_acr(codegendata *cd1, constant_classref *a)
void genarg_ainst(codegendata *cd1, Inst *a)
void dseg_add_target(codegendata *cd, basicblock *target)
void(* genfunctionptr)(codegendata *)
#define BUILTIN_newarray_char
java_object_t * codegen_finish_native_call(u1 *sp, u1 *pv)
static int code_is_leafmethod(codeinfo *code)
u1 * intrp_createcompilerstub(methodinfo *m)
#define BUILTIN_newarray_byte
u1 * intrp_createnativestub(functionptr f, jitdata *jd, methoddesc *nmd)
void genarg_aClass(codegendata *cd1, classinfo *a)
block_count * vm_block_insert(Inst *ip)
void vm_abort(const char *text,...)
void(* functionptr)(void)
void genarg_am(codegendata *cd1, methodinfo *a)
codeinfo * code_codeinfo_new(methodinfo *m)
void genarg_addr(codegendata *cd1, u1 *a)
java_handle_t * codegen_start_native_call(u1 *sp, u1 *pv)
#define IS_2_WORD_TYPE(a)
void genarg_v(codegendata *cd1, Cell v)
#define LOCK_monitor_enter
constant_FMIref * fieldref
#define COMPILERSTUB_DATASIZE
#define BUILTIN_newarray_boolean
void exceptions_throw_internalerror(const char *message,...)
void genarg_afi(codegendata *cd1, fieldinfo *a)
#define gen_branch(_inst)
void genarg_acell(codegendata *cd1, Cell *a)
s4 dseg_add_unique_s4(codegendata *cd, s4 value)
#define COMPILERSTUB_SIZE
void genarg_aArray(codegendata *cd1, java_arrayheader *a)
union instruction::@12 sx
#define BUILTIN_arrayinstanceof
#define BUILTIN_newarray_int
#define LOCK_monitor_exit
void genarg_aaTarget(codegendata *cd1, Inst **a)
void codegen_setup(jitdata *jd)
#define BUILTIN_newarray_double
constant_FMIref * methodref
void genarg_auf(codegendata *cd1, unresolved_field *a)
void genarg_af(codegendata *cd1, functionptr a)
void genarg_l(codegendata *cd1, s8 l)
#define BUILTIN_newarray_short
static bool class_is_or_almost_initialized(classinfo *c)
void genarg_f(codegendata *cd1, float f)
u1 * createcalljavafunction(methodinfo *m)
static int code_is_synchronized(codeinfo *code)
#define INSTRUCTION_IS_UNRESOLVED(iptr)
#define vm_f2Cell(x1, x2)
struct instruction::@12::@13 s23
void genarg_b(codegendata *cd1, s4 i)
const parseddesc_t parseddesc
bool intrp_codegen(jitdata *jd)
#define vm_l2twoCell(d_, hi, lo)
void codegen_finish(jitdata *jd)