* src/vm/jit/parse.cpp,
[cacao.git] / src / vm / jit / arm / codegen.c
index 387822a685811141e507b66cd7882461e3e109d6..0df334e9ada5e4effd16a5da8fc7af1400bbddb6 100644 (file)
 
 #include "mm/memory.h"
 
-#include "native/localref.h"
-#include "native/native.h"
+#include "native/localref.hpp"
+#include "native/native.hpp"
 
-#include "threads/lock-common.h"
+#include "threads/lock.hpp"
 
-#include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/loader.hpp"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
-#include "vm/jit/codegen-common.h"
+#include "vm/jit/codegen-common.hpp"
 #include "vm/jit/dseg.h"
-#include "vm/jit/emit-common.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/linenumbertable.h"
+#include "vm/jit/emit-common.hpp"
+#include "vm/jit/jit.hpp"
+#include "vm/jit/jitcache.hpp"
+#include "vm/jit/linenumbertable.hpp"
 #include "vm/jit/methodheader.h"
-#include "vm/jit/parse.h"
-#include "vm/jit/patcher-common.h"
+#include "vm/jit/parse.hpp"
+#include "vm/jit/patcher-common.hpp"
 #include "vm/jit/reg.h"
 
 #if defined(ENABLE_LSRA)
 #include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 
 /* codegen_emit ****************************************************************
 
@@ -141,7 +141,13 @@ bool codegen_emit(jitdata *jd)
        /* SECTION: Method Header */
        /* create method header */
 
+#if defined(ENABLE_JITCACHE)
+       disp = dseg_add_unique_address(cd, code);                          /* CodeinfoPointer */
+       jitcache_add_cached_ref(code, CRT_CODEINFO, 0, disp);
+#else
        (void) dseg_add_unique_address(cd, code);              /* CodeinfoPointer */
+#endif
+
        (void) dseg_add_unique_s4(cd, cd->stackframesize);     /* FrameSize       */
 
        code->synchronizedoffset = rd->memuse * 8;
@@ -279,6 +285,7 @@ bool codegen_emit(jitdata *jd)
 
                if (m->flags & ACC_STATIC) {
                        disp = dseg_add_address(cd, &m->clazz->object.header);
+                       JITCACHE_ADD_CACHED_REF(code, CRT_OBJECT_HEADER, m->clazz, disp);
                        M_DSEG_LOAD(REG_A0, disp);
                }
                else {
@@ -287,6 +294,8 @@ bool codegen_emit(jitdata *jd)
 
                M_STR(REG_A0, REG_SP, s1);
                disp = dseg_add_functionptr(cd, LOCK_monitor_enter);
+               JITCACHE_ADD_CACHED_REF(code,
+                       CRT_BUILTIN_FP, builtintable_get_internal(LOCK_monitor_enter), disp);
                M_DSEG_BRANCH(disp);
                s1 = (s4) (cd->mcodeptr - cd->mcodebase);
                M_RECOMPUTE_PV(s1);
@@ -410,7 +419,33 @@ bool codegen_emit(jitdata *jd)
                                M_DSEG_LOAD(d, disp);
                        }
                        else {
+#if defined(ENABLE_JITCACHE)
+                               /* Dealing with ICONST and the JIT cache is tricky because
+                                * ICONST generates different code depending on the value of the
+                                * number. We therefore go the slightly less optimal way and
+                                * generate an entry in the data segment.
+                                * For the null constant however we use the plain integer load.
+                               */
+                               if (iptr->sx.val.anyptr)
+                               {
+                                       disp = dseg_add_unique_address(cd, iptr->sx.val.anyptr);
+
+                                       jitcache_add_cached_ref(code, 
+                                               (iptr->flags.bits & INS_FLAG_CLASS) ? CRT_CLASSINFO
+                                                                                                                       : CRT_STRING,
+                                               (iptr->flags.bits & INS_FLAG_CLASS) ? iptr->sx.val.c.cls
+                                                                                                                       : iptr->sx.val.stringconst,
+                                               disp);
+
+                                       M_DSEG_LOAD(d, disp);
+                               }
+                               else {
+                                       ICONST(d, (u4) 0);
+                               }
+
+#else
                                ICONST(d, (u4) iptr->sx.val.anyptr);
+#endif
                        }
                        emit_store_dst(jd, iptr, d);
                        break;
@@ -679,6 +714,7 @@ bool codegen_emit(jitdata *jd)
                        /* call builtin function */
                        bte = iptr->sx.s23.s3.bte;
                        disp = dseg_add_functionptr(cd, bte->fp);
+                       JITCACHE_ADD_CACHED_REF(code, CRT_BUILTIN_FP, bte, disp);
                        M_DSEG_BRANCH(disp);
 
                        /* recompute pv */
@@ -708,6 +744,7 @@ bool codegen_emit(jitdata *jd)
                        /* call builtin function */
                        bte = iptr->sx.s23.s3.bte;
                        disp = dseg_add_functionptr(cd, bte->fp);
+                       JITCACHE_ADD_CACHED_REF(code, CRT_BUILTIN_FP, bte, disp);
                        M_DSEG_BRANCH(disp);
 
                        /* recompute pv */
@@ -1014,7 +1051,12 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+#if defined(__VFP_FP__)
+                       M_FMSR(s1, d);
+                       M_CVTIF(d, d);
+#else
                        M_CVTIF(s1, d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1022,7 +1064,12 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_FTMP1);
+#if defined(__VFP_FP__)
+                       M_FMSR(s1, d);
+                       M_CVTID(d, d);
+#else
                        M_CVTID(s1, d);
+#endif
                        emit_store_dst(jd, iptr, d);
                        break;
 
@@ -1030,9 +1077,12 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+#if defined(__VFP_FP__)
+                       M_CVTFI(s1, REG_FTMP2);
+                       M_FMRS(REG_FTMP2, d);
+#else
                        /* this uses round towards zero, as Java likes it */
                        M_CVTFI(s1, d);
-#if !defined(__VFP_FP__)
                        /* this checks for NaN; to return zero as Java likes it */
                        M_FCMP(s1, 0x8);
                        M_MOVVS_IMM(0, d);
@@ -1044,9 +1094,12 @@ bool codegen_emit(jitdata *jd)
 
                        s1 = emit_load_s1(jd, iptr, REG_FTMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP1);
+#if defined(__VFP_FP__)
+                       M_CVTDI(s1, REG_FTMP2);
+                       M_FMRS(REG_FTMP2, d);
+#else
                        /* this uses round towards zero, as Java likes it */
                        M_CVTDI(s1, d);
-#if !defined(__VFP_FP__)
                        /* this checks for NaN; to return zero as Java likes it */
                        M_DCMP(s1, 0x8);
                        M_MOVVS_IMM(0, d);
@@ -1352,6 +1405,10 @@ bool codegen_emit(jitdata *jd)
 
                        /* call builtin function */
                        disp = dseg_add_functionptr(cd, BUILTIN_FAST_canstore);
+                       JITCACHE_ADD_CACHED_REF(
+                               code, CRT_BUILTIN_FP,
+                               builtintable_get_internal(BUILTIN_FAST_canstore), disp);
+
                        M_DSEG_BRANCH(disp);
 
                        /* recompute pv */
@@ -1382,7 +1439,7 @@ bool codegen_emit(jitdata *jd)
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
-
+                               JITCACHE_ADD_CACHED_REF(code, CRT_FIELDINFO_VALUE, fi, disp);
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
                                                            fi->clazz, 0);
@@ -1435,7 +1492,7 @@ bool codegen_emit(jitdata *jd)
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
-
+                               JITCACHE_ADD_CACHED_REF(code, CRT_FIELDINFO_VALUE, fi, disp);
                                if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->clazz)) {
                                        patcher_add_patch_ref(jd, PATCHER_initialize_class,
                                                            fi->clazz, 0);
@@ -1628,6 +1685,7 @@ bool codegen_emit(jitdata *jd)
                                                                        iptr->sx.s23.s2.uc, 0);
                        }
                        disp = dseg_add_functionptr(cd, asm_handle_exception);
+                       JITCACHE_ADD_CACHED_REF(code, CRT_ASM_HANDLE_EXCEPTION, NULL, disp);
                        M_DSEG_LOAD(REG_ITMP3, disp);
                        M_MOV(REG_ITMP2_XPC, REG_PC);
                        M_MOV(REG_PC, REG_ITMP3);
@@ -2116,6 +2174,10 @@ bool codegen_emit(jitdata *jd)
 
                                M_LDR(REG_A0, REG_SP, s1);
                                disp = dseg_add_functionptr(cd, LOCK_monitor_exit);
+                               JITCACHE_ADD_CACHED_REF(code,
+                                       CRT_BUILTIN_FP, builtintable_get_internal(LOCK_monitor_exit),
+                                       disp);
+
                                M_DSEG_BRANCH(disp);
 
                                /* we no longer need PV here, no more loading */
@@ -2245,6 +2307,8 @@ bool codegen_emit(jitdata *jd)
                                        disp = dseg_add_functionptr(cd, bte->stub);
                                }
 
+                               JITCACHE_ADD_CACHED_REF(code, CRT_BUILTIN, bte, disp);
+
                                M_DSEG_LOAD(REG_PV, disp); /* pointer to built-in-function */
 
                                /* generate the actual call */
@@ -2267,7 +2331,10 @@ bool codegen_emit(jitdata *jd)
                                                                                um, disp);
                                }
                                else
+                               {
                                        disp = dseg_add_address(cd, lm->stubroutine);
+                                       JITCACHE_ADD_CACHED_REF(code, CRT_METHODINFO_STUBROUTINE, lm, disp);
+                               }
 
                                M_DSEG_LOAD(REG_PV, disp);            /* Pointer to method */
 
@@ -2281,6 +2348,7 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEVIRTUAL:
                                if (lm == NULL) {
+
                                        patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
 
                                        s1 = 0;
@@ -2288,12 +2356,12 @@ bool codegen_emit(jitdata *jd)
                                else
                                        s1 = OFFSET(vftbl_t, table[0]) +
                                                sizeof(methodptr) * lm->vftblindex;
+                               
 
                                /* implicit null-pointer check */
                                M_LDR_INTERN(REG_METHODPTR, REG_A0,
                                                         OFFSET(java_object_t, vftbl));
                                M_LDR_INTERN(REG_PV, REG_METHODPTR, s1);
-
                                /* generate the actual call */
 
                                M_MOV(REG_LR, REG_PC);
@@ -2319,7 +2387,9 @@ bool codegen_emit(jitdata *jd)
                                M_LDR_INTERN(REG_METHODPTR, REG_A0,
                                                         OFFSET(java_object_t, vftbl));
                                M_LDR_INTERN(REG_METHODPTR, REG_METHODPTR, s1);
+
                                M_LDR_INTERN(REG_PV, REG_METHODPTR, s2);
+                               JITCACHE_ADD_CACHED_REF_MD_JD(jd, CRT_METHODINFO_METHODOFFSET, 1, lm);
 
                                /* generate the actual call */
 
@@ -2432,6 +2502,9 @@ bool codegen_emit(jitdata *jd)
                                                            iptr->sx.s23.s3.c.ref, disp);
                                }
                                else {
+/*
+                                       JITCACHE_ADD_CACHED_REF_JD(jd, CRT_CLASSINFO_INDEX, super, disp);
+*/
                                        M_TST(s1, s1);
                                        emit_label_beq(cd, BRANCH_LABEL_3);
                                }
@@ -2497,7 +2570,7 @@ bool codegen_emit(jitdata *jd)
                                }
                                else {
                                        disp = dseg_add_address(cd, super->vftbl);
-
+                                       JITCACHE_ADD_CACHED_REF(code, CRT_CLASSINFO_VFTBL, super, disp);
                                        M_TST(s1, s1);
                                        emit_label_beq(cd, BRANCH_LABEL_5);
                                }
@@ -2539,10 +2612,14 @@ bool codegen_emit(jitdata *jd)
                                                                                disp);
                                }
                                else
+                               {
                                        disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
+                                       JITCACHE_ADD_CACHED_REF(code, CRT_CLASSINFO, iptr->sx.s23.s3.c.cls, disp);
+                               }
 
                                M_DSEG_LOAD(REG_A1, disp);
                                disp = dseg_add_functionptr(cd, BUILTIN_arraycheckcast);
+                               JITCACHE_ADD_CACHED_REF(code, CRT_BUILTIN, builtintable_get_internal(BUILTIN_arraycheckcast), disp);
                                M_DSEG_BRANCH(disp);
 
                                /* recompute pv */
@@ -2618,6 +2695,9 @@ bool codegen_emit(jitdata *jd)
                                                            iptr->sx.s23.s3.c.ref, disp);
                                }
                                else {
+/* TODO: Not needed?
+                                       JITCACHE_ADD_CACHED_REF(code, CRT_CLASSINFO_INDEX, super, disp);
+*/
                                        M_EOR(d, d, d);
                                        M_TST(s1, s1);
                                        emit_label_beq(cd, BRANCH_LABEL_3);
@@ -2688,6 +2768,7 @@ bool codegen_emit(jitdata *jd)
                                }
                                else {
                                        disp = dseg_add_address(cd, super->vftbl);
+                                       JITCACHE_ADD_CACHED_REF(code, CRT_CLASSINFO_VFTBL, super, disp);
 
                                        M_EOR(d, d, d);
                                        M_TST(s1, s1);
@@ -2754,7 +2835,10 @@ bool codegen_emit(jitdata *jd)
                                                                        iptr->sx.s23.s3.c.ref, disp);
                        }
                        else
+                       {
                                disp = dseg_add_address(cd, iptr->sx.s23.s3.c.cls);
+                               JITCACHE_ADD_CACHED_REF(code, CRT_CLASSINFO, iptr->sx.s23.s3.c.cls, disp);
+                       }
 
                        /* a1 = arraydescriptor */
 
@@ -2767,6 +2851,11 @@ bool codegen_emit(jitdata *jd)
                        /* call builtin_multianewarray here */
 
                        disp = dseg_add_functionptr(cd, BUILTIN_multianewarray);
+                       /*
+                       * For some unknown reason this causes an illegal instruction.
+                       * JITCACHE_ADD_CACHED_REF(code, CRT_BUILTIN, builtintable_get_internal(BUILTIN_multianewarray), disp);
+                       */
+
                        M_DSEG_BRANCH(disp);
 
                        /* recompute pv */
@@ -2811,29 +2900,6 @@ bool codegen_emit(jitdata *jd)
 }
 
 
-/* codegen_emit_stub_compiler **************************************************
-
-   Emits a stub routine which calls the compiler.
-       
-*******************************************************************************/
-
-void codegen_emit_stub_compiler(jitdata *jd)
-{
-       methodinfo  *m;
-       codegendata *cd;
-
-       /* get required compiler data */
-
-       m  = jd->m;
-       cd = jd->cd;
-
-       /* code for the stub */
-
-       M_LDR_INTERN(REG_ITMP1, REG_PC, -(2 * 4 + 2 * SIZEOF_VOID_P));
-       M_LDR_INTERN(REG_PC, REG_PC, -(3 * 4 + 3 * SIZEOF_VOID_P));
-}
-
-
 /* codegen_emit_stub_native ****************************************************
 
    Emits a stub routine which calls a native method.
@@ -2987,7 +3053,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
 
                /* put env into first argument register */
 
-               disp = dseg_add_address(cd, _Jv_env);
+               disp = dseg_add_address(cd, VM_get_jnienv());
                M_DSEG_LOAD(REG_A0, disp);
        }