Merged branch subtype-trunk into default.
[cacao.git] / src / vm / jit / arm / codegen.c
index efe6d3d746eac7d775dae8bc56eb9495294cb972..a0085a806efce8d275e22c62404722e04352c67c 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/arm/arch.h"
 #include "vm/jit/arm/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
 #include "vm/jit/dseg.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/parse.hpp"
 #include "vm/jit/patcher-common.hpp"
 #include "vm/jit/reg.h"
 
@@ -141,13 +140,7 @@ 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;
@@ -285,7 +278,6 @@ 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 {
@@ -294,8 +286,6 @@ 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);
@@ -419,33 +409,7 @@ 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;
@@ -714,7 +678,6 @@ 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 */
@@ -744,7 +707,6 @@ 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 */
@@ -1405,10 +1367,6 @@ 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 */
@@ -1439,7 +1397,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);
@@ -1492,7 +1450,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);
@@ -1685,7 +1643,6 @@ 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);
@@ -2174,10 +2131,6 @@ 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 */
@@ -2307,8 +2260,6 @@ 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 */
@@ -2331,10 +2282,7 @@ 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 */
 
@@ -2348,22 +2296,33 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEVIRTUAL:
                                if (lm == NULL) {
+                                       int32_t disp = dseg_add_unique_s4(cd, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, disp);
+
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
 
-                                       patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
+                                       // Sanity check.
+                                       assert(REG_ITMP1 != REG_METHODPTR);
+                                       assert(REG_ITMP2 == REG_METHODPTR);
 
-                                       s1 = 0;
+                                       M_DSEG_LOAD(REG_ITMP1, disp);
+                                       M_ADD(REG_METHODPTR, REG_METHODPTR, REG_ITMP1);
+
+                                       // This must be a load with displacement,
+                                       // otherwise the JIT method address patching does
+                                       // not work anymore (see md_jit_method_patch_address).
+                                       M_LDR_INTERN(REG_PV, REG_METHODPTR, 0);
                                }
-                               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 */
+                               else {
+                                       s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
 
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
+                                       M_LDR(REG_PV, REG_METHODPTR, s1);
+                               }
+
+                               // Generate the actual call.
                                M_MOV(REG_LR, REG_PC);
                                M_MOV(REG_PC, REG_PV);
                                s1 = (s4) (cd->mcodeptr - cd->mcodebase);
@@ -2372,27 +2331,43 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEINTERFACE:
                                if (lm == NULL) {
-                                       patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
+                                       int32_t disp  = dseg_add_unique_s4(cd, 0);
+                                       int32_t disp2 = dseg_add_unique_s4(cd, 0);
 
-                                       s1 = 0;
-                                       s2 = 0;
+                                       // XXX We need two displacements.
+                                       assert(disp2 == disp - 4);
+                                       patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, disp);
+
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
+
+                                       // Sanity check.
+                                       assert(REG_ITMP1 != REG_METHODPTR);
+                                       assert(REG_ITMP2 == REG_METHODPTR);
+                                       assert(REG_ITMP3 != REG_METHODPTR);
+
+                                       M_DSEG_LOAD(REG_ITMP1, disp);
+                                       M_LDR_REG(REG_METHODPTR, REG_METHODPTR, REG_ITMP1);
+
+                                       M_DSEG_LOAD(REG_ITMP3, disp2);
+                                       M_ADD(REG_METHODPTR, REG_METHODPTR, REG_ITMP3);
+
+                                       // This must be a load with displacement,
+                                       // otherwise the JIT method address patching does
+                                       // not work anymore (see md_jit_method_patch_address).
+                                       M_LDR_INTERN(REG_PV, REG_METHODPTR, 0);
                                }
                                else {
-                                       s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->clazz->index;
+                                       s1 = OFFSET(vftbl_t, interfacetable[0]) - 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 */
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
+                                       M_LDR(REG_METHODPTR, REG_METHODPTR, s1);
+                                       M_LDR(REG_PV, REG_METHODPTR, s2);
+                               }
 
+                               // Generate the actual call.
                                M_MOV(REG_LR, REG_PC);
                                M_MOV(REG_PC, REG_PV);
                                s1 = (s4) (cd->mcodeptr - cd->mcodebase);
@@ -2502,9 +2477,6 @@ 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);
                                }
@@ -2570,7 +2542,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);
                                }
@@ -2612,14 +2584,10 @@ 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 */
@@ -2695,9 +2663,6 @@ 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);
@@ -2768,7 +2733,6 @@ 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);
@@ -2835,10 +2799,7 @@ 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 */
 
@@ -2851,11 +2812,6 @@ 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 */