* merged with tip (040f180a056b)
[cacao.git] / src / vm / jit / arm / codegen.c
index 8fd10e98aa255c88e8f1d07b51c58ec10d43878a..0ba33473cc0c116f42714be81bf3c8303a287d07 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/arm/codegen.c - machine code generator for Arm
 
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
 #include "threads/lock-common.h"
 
 #include "vm/builtin.h"
-#include "vm/exceptions.h"
+#include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/vm.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/asmpart.h"
@@ -55,8 +55,8 @@
 #include "vm/jit/dseg.h"
 #include "vm/jit/emit-common.h"
 #include "vm/jit/jit.h"
+#include "vm/jit/jitcache.h"
 #include "vm/jit/linenumbertable.h"
-#include "vm/jit/md.h"
 #include "vm/jit/methodheader.h"
 #include "vm/jit/parse.h"
 #include "vm/jit/patcher-common.h"
@@ -66,9 +66,6 @@
 #include "vm/jit/allocator/lsra.h"
 #endif
 
-#include "vmcore/loader.h"
-#include "vmcore/options.h"
-
 
 /* codegen_emit ****************************************************************
 
@@ -144,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;
@@ -281,7 +284,8 @@ bool codegen_emit(jitdata *jd)
                /* get the correct lock object */
 
                if (m->flags & ACC_STATIC) {
-                       disp = dseg_add_address(cd, &m->class->object.header);
+                       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 {
@@ -290,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);
@@ -413,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;
@@ -682,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 */
@@ -711,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 */
@@ -1355,6 +1389,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 */
@@ -1385,10 +1423,10 @@ bool codegen_emit(jitdata *jd)
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
-
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               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->class, 0);
+                                                           fi->clazz, 0);
                                }
                        }
 
@@ -1438,10 +1476,10 @@ bool codegen_emit(jitdata *jd)
                                fi        = iptr->sx.s23.s3.fmiref->p.field;
                                fieldtype = fi->type;
                                disp      = dseg_add_address(cd, fi->value);
-
-                               if (!CLASS_IS_OR_ALMOST_INITIALIZED(fi->class)) {
+                               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->class, 0);
+                                                           fi->clazz, 0);
                                }
                        }
 
@@ -1631,6 +1669,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);
@@ -2119,6 +2158,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 */
@@ -2248,6 +2291,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 */
@@ -2270,7 +2315,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 */
 
@@ -2284,6 +2332,7 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEVIRTUAL:
                                if (lm == NULL) {
+
                                        patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
 
                                        s1 = 0;
@@ -2291,12 +2340,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);
@@ -2314,15 +2363,17 @@ bool codegen_emit(jitdata *jd)
                                }
                                else {
                                        s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->class->index;
-                                       s2 = sizeof(methodptr) * (lm - lm->class->methods);
+                                               sizeof(methodptr*) * lm->clazz->index;
+                                       s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
                                }
 
                                /* implicit null-pointer check */
                                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 */
 
@@ -2346,7 +2397,7 @@ bool codegen_emit(jitdata *jd)
                           our ENABLE_SOFTFLOAT define */
                        if (iptr->opc == ICMD_BUILTIN && d != TYPE_VOID && IS_FLT_DBL_TYPE(d)) {
 #if 0 && !defined(NDEBUG)
-                               dolog("BUILTIN that returns float or double (%s.%s)", m->class->name->text, m->name->text);
+                               dolog("BUILTIN that returns float or double (%s.%s)", m->clazz->name->text, m->name->text);
 #endif
                                /* we cannot use this macro, since it is not defined
                                   in ENABLE_SOFTFLOAT M_CAST_FLT_TO_INT_TYPED(d,
@@ -2405,9 +2456,6 @@ bool codegen_emit(jitdata *jd)
                                superindex = super->index;
                        }
 
-                               if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                                       CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
 
                        /* if class is not resolved, check which code to call */
@@ -2438,6 +2486,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);
                                }
@@ -2503,7 +2554,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);
                                }
@@ -2511,16 +2562,12 @@ bool codegen_emit(jitdata *jd)
                                M_LDR_INTERN(REG_ITMP2, s1, OFFSET(java_object_t, vftbl));
                                M_DSEG_LOAD(REG_ITMP3, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, baseval));
                                M_SUB(REG_ITMP2, REG_ITMP2, REG_ITMP3);
                                M_DSEG_LOAD(REG_ITMP3, disp);
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP3, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_CMP(REG_ITMP2, REG_ITMP3);
                                emit_classcast_check(cd, iptr, BRANCH_UGT, 0, s1);
 
@@ -2549,10 +2596,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 */
@@ -2585,9 +2636,6 @@ bool codegen_emit(jitdata *jd)
                                superindex = super->index;
                        }
 
-                       if ((super == NULL) || !(super->flags & ACC_INTERFACE))
-                               CODEGEN_CRITICAL_SECTION_NEW;
-
                        s1 = emit_load_s1(jd, iptr, REG_ITMP1);
                        d = codegen_reg_of_dst(jd, iptr, REG_ITMP2);
 
@@ -2631,6 +2679,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);
@@ -2701,6 +2752,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);
@@ -2710,14 +2762,10 @@ bool codegen_emit(jitdata *jd)
                                M_LDR_INTERN(REG_ITMP1, s1, OFFSET(java_object_t, vftbl));
                                M_DSEG_LOAD(REG_ITMP2, disp);
 
-                               CODEGEN_CRITICAL_SECTION_START;
-
                                M_LDR_INTERN(REG_ITMP1, REG_ITMP1, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP3, REG_ITMP2, OFFSET(vftbl_t, baseval));
                                M_LDR_INTERN(REG_ITMP2, REG_ITMP2, OFFSET(vftbl_t, diffval));
 
-                               CODEGEN_CRITICAL_SECTION_END;
-
                                M_SUB(REG_ITMP1, REG_ITMP1, REG_ITMP3);
                                M_CMP(REG_ITMP1, REG_ITMP2);
                                /* If d == REG_ITMP2, then it's destroyed */
@@ -2771,7 +2819,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 */
 
@@ -2784,6 +2835,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 */
@@ -3004,7 +3060,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);
        }
 
@@ -3025,7 +3081,7 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        /* this depends on gcc; it is independent from our ENABLE_SOFTFLOAT define */
        if (md->returntype.type != TYPE_VOID && IS_FLT_DBL_TYPE(md->returntype.type)) {
 #if 0 && !defined(NDEBUG)
-               dolog("NATIVESTUB that returns float or double (%s.%s)", m->class->name->text, m->name->text);
+               dolog("NATIVESTUB that returns float or double (%s.%s)", m->clazz->name->text, m->name->text);
 #endif
                /* we cannot use this macro, since it is not defined in ENABLE_SOFTFLOAT */
                /* M_CAST_FLT_TO_INT_TYPED(md->returntype.type, REG_FRESULT, REG_RESULT_TYPED(md->returntype.type)); */
@@ -3087,10 +3143,6 @@ void codegen_emit_stub_native(jitdata *jd, methoddesc *nmd, functionptr f, int s
        disp = dseg_add_functionptr(cd, asm_handle_nat_exception);
        M_DSEG_LOAD(REG_ITMP3, disp);       /* load asm exception handler address */
        M_MOV(REG_PC, REG_ITMP3);           /* jump to asm exception handler      */
-
-       /* generate patcher stubs */
-
-       emit_patcher_traps(jd);
 }