{
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;
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:
* 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)
+ 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");
}
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);
}
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;
#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;