Merge pull request #4048 from kumpera/iface_casting_cleanup
[mono.git] / mono / mini / mini-arm64.c
index 6417c11f6c34c5d7ebd2fca88f219eaa4cab5dec..3b4dd15c8c9acb3dc3a9bed4b689f664526ffe62 100644 (file)
@@ -934,7 +934,15 @@ arm_patch_full (MonoCompile *cfg, MonoDomain *domain, guint8 *code, guint8 *targ
 {
        switch (relocation) {
        case MONO_R_ARM64_B:
-               arm_b (code, target);
+               if (arm_is_bl_disp (code, target)) {
+                       arm_b (code, target);
+               } else {
+                       gpointer thunk;
+
+                       thunk = create_thunk (cfg, domain, code, target);
+                       g_assert (arm_is_bl_disp (code, thunk));
+                       arm_b (code, thunk);
+               }
                break;
        case MONO_R_ARM64_BCC: {
                int cond;
@@ -966,7 +974,7 @@ arm_patch_full (MonoCompile *cfg, MonoDomain *domain, guint8 *code, guint8 *targ
 
                        thunk = create_thunk (cfg, domain, code, target);
                        g_assert (arm_is_bl_disp (code, thunk));
-                       arm_bl (code, thunk);                   
+                       arm_bl (code, thunk);
                }
                break;
        default:
@@ -1781,25 +1789,21 @@ mono_arch_flush_icache (guint8 *code, gint size)
         * icache/dcache cache line sizes, that can vary between cores on
         * big.LITTLE architectures. */
        guint64 end = (guint64) (code + size);
-       guint64 addr, ctr_el0;
-       static size_t icache_line_size = 0xffff, dcache_line_size = 0xffff;
-       size_t isize, dsize;
-
-       asm volatile ("mrs %0, ctr_el0" : "=r" (ctr_el0));
-       isize = 4 << ((ctr_el0 >> 0 ) & 0xf);
-       dsize = 4 << ((ctr_el0 >> 16) & 0xf);
-
-       /* determine the global minimum cache line size */
-       icache_line_size = isize = MIN (icache_line_size, isize);
-       dcache_line_size = dsize = MIN (dcache_line_size, dsize);
-
-       addr = (guint64) code & ~(guint64) (dsize - 1);
-       for (; addr < end; addr += dsize)
-               asm volatile("dc cvau, %0" : : "r" (addr) : "memory");
+       guint64 addr;
+       /* always go with cacheline size of 4 bytes as this code isn't perf critical
+        * anyway. Reading the cache line size from a machine register can be racy
+        * on a big.LITTLE architecture if the cores don't have the same cache line
+        * sizes. */
+       const size_t icache_line_size = 4;
+       const size_t dcache_line_size = 4;
+
+       addr = (guint64) code & ~(guint64) (dcache_line_size - 1);
+       for (; addr < end; addr += dcache_line_size)
+               asm volatile("dc civac, %0" : : "r" (addr) : "memory");
        asm volatile("dsb ish" : : : "memory");
 
-       addr = (guint64) code & ~(guint64) (isize - 1);
-       for (; addr < end; addr += isize)
+       addr = (guint64) code & ~(guint64) (icache_line_size - 1);
+       for (; addr < end; addr += icache_line_size)
                asm volatile("ic ivau, %0" : : "r" (addr) : "memory");
 
        asm volatile ("dsb ish" : : : "memory");
@@ -4978,14 +4982,14 @@ mono_arch_get_patch_offset (guint8 *code)
 }
 
 gpointer
-mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count,
-                                                  gpointer fail_tramp)
+mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count,
+                                                               gpointer fail_tramp)
 {
        int i, buf_len, imt_reg;
        guint8 *buf, *code;
 
 #if DEBUG_IMT
-       printf ("building IMT thunk for class %s %s entries %d code size %d code at %p end %p vtable %p\n", vtable->klass->name_space, vtable->klass->name, count, size, start, ((guint8*)start) + size, vtable);
+       printf ("building IMT trampoline for class %s %s entries %d code size %d code at %p end %p vtable %p\n", vtable->klass->name_space, vtable->klass->name, count, size, start, ((guint8*)start) + size, vtable);
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
                printf ("method %d (%p) %s vtable slot %p is_equals %d chunk size %d\n", i, item->key, item->key->name, &vtable->vtable [item->value.vtable_slot], item->is_equals, item->chunk_size);
@@ -5020,7 +5024,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        }
 
        if (fail_tramp)
-               buf = mono_method_alloc_generic_virtual_thunk (domain, buf_len);
+               buf = mono_method_alloc_generic_virtual_trampoline (domain, buf_len);
        else
                buf = mono_domain_code_reserve (domain, buf_len);
        code = buf;
@@ -5108,8 +5112,8 @@ mono_arch_get_trampolines (gboolean aot)
 #else /* DISABLE_JIT */
 
 gpointer
-mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count,
-                                                  gpointer fail_tramp)
+mono_arch_build_imt_trampoline (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count,
+                                                               gpointer fail_tramp)
 {
        g_assert_not_reached ();
        return NULL;