Skip to content

Commit

Permalink
Implement support for unlimited number of gsharedvt arg trampolines.
Browse files Browse the repository at this point in the history
  • Loading branch information
vargaz committed Feb 17, 2013
1 parent b340bf5 commit 31522aa
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 4 deletions.
26 changes: 26 additions & 0 deletions mono/mini/aot-compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,31 @@ arch_emit_specific_trampoline_pages (MonoAotCompile *acfg)
g_assert (code - buf == 8);
emit_bytes (acfg, buf, code - buf);
}

/*
* gsharedvt arg trampolines: see arch_emit_gsharedvt_arg_trampoline ()
*/
emit_global (acfg, "gsharedvt_arg_trampolines_page", TRUE);
emit_label (acfg, "gsharedvt_arg_trampolines_page");
code = buf;
ARM_PUSH (code, (1 << ARMREG_R0) | (1 << ARMREG_R1) | (1 << ARMREG_R2) | (1 << ARMREG_R3) | (1 << ARMREG_LR));
imm8 = mono_arm_is_rotated_imm8 (mono_pagesize (), &rot_amount);
ARM_SUB_REG_IMM (code, ARMREG_IP, ARMREG_IP, imm8, rot_amount);
ARM_LDR_IMM (code, ARMREG_LR, ARMREG_IP, -8);
ARM_LDR_IMM (code, ARMREG_PC, ARMREG_IP, -4);
g_assert (code - buf == COMMON_TRAMP_SIZE);
/* Emit it */
emit_bytes (acfg, buf, code - buf);

for (i = 0; i < count; ++i) {
code = buf;
ARM_MOV_REG_REG (code, ARMREG_IP, ARMREG_PC);
ARM_B (code, 0);
arm_patch (code - 4, code - COMMON_TRAMP_SIZE - 8 * (i + 1));
g_assert (code - buf == 8);
emit_bytes (acfg, buf, code - buf);
}

/* now the imt trampolines: each specific trampolines puts in the ip register
* the instruction pointer address, so the generic trampoline at the start of the page
* subtracts 4096 to get to the data page and loads the values
Expand Down Expand Up @@ -5772,6 +5797,7 @@ mono_aot_parse_options (const char *aot_options, MonoAotOptions *opts)
opts->ntrampolines = 0;
opts->nrgctx_trampolines = 0;
opts->nimt_trampolines = 0;
opts->ngsharedvt_arg_trampolines = 0;
}
g_strfreev (args);
}
Expand Down
29 changes: 25 additions & 4 deletions mono/mini/aot-runtime.c
Original file line number Diff line number Diff line change
Expand Up @@ -4021,7 +4021,7 @@ static TrampolinePage* trampoline_pages [MONO_AOT_TRAMP_NUM];
* the minimum for the common code must be at least sizeof(TrampolinePage), since we store the page info at the
* beginning of the data page.
*/
static const int trampolines_pages_code_offsets [MONO_AOT_TRAMP_NUM] = {16, 16, 72};
static const int trampolines_pages_code_offsets [MONO_AOT_TRAMP_NUM] = {16, 16, 72, 16};

static unsigned char*
get_new_trampoline_from_page (int tramp_type)
Expand Down Expand Up @@ -4060,6 +4060,8 @@ get_new_trampoline_from_page (int tramp_type)
tpage = load_function (amodule, "rgctx_trampolines_page");
else if (tramp_type == MONO_AOT_TRAMP_IMT_THUNK)
tpage = load_function (amodule, "imt_trampolines_page");
else if (tramp_type == MONO_AOT_TRAMP_GSHAREDVT_ARG)
tpage = load_function (amodule, "gsharedvt_arg_trampolines_page");
else
g_error ("Incorrect tramp type for trampolines page");
g_assert (tpage);
Expand Down Expand Up @@ -4172,6 +4174,21 @@ get_new_imt_trampoline_from_page (gpointer arg)

}

static gpointer
get_new_gsharedvt_arg_trampoline_from_page (gpointer tramp, gpointer arg)
{
void *code;
gpointer *data;

code = get_new_trampoline_from_page (MONO_AOT_TRAMP_GSHAREDVT_ARG);

data = (gpointer*)((char*)code - mono_pagesize ());
data [0] = arg;
data [1] = tramp;
/*g_warning ("new rgctx trampoline at %p for data %p, tramp %p (stored at %p)", code, arg, tramp, data);*/
return code;
}

/* Return a given kind of trampoline */
static gpointer
get_numerous_trampoline (MonoAotTrampoline tramp_type, int n_got_slots, MonoAotModule **out_amodule, guint32 *got_offset, guint32 *out_tramp_size)
Expand Down Expand Up @@ -4428,10 +4445,14 @@ mono_aot_get_gsharedvt_arg_trampoline (gpointer arg, gpointer addr)
guint8 *code;
guint32 got_offset;

code = get_numerous_trampoline (MONO_AOT_TRAMP_GSHAREDVT_ARG, 2, &amodule, &got_offset, NULL);
if (USE_PAGE_TRAMPOLINES) {
code = get_new_gsharedvt_arg_trampoline_from_page (addr, arg);
} else {
code = get_numerous_trampoline (MONO_AOT_TRAMP_GSHAREDVT_ARG, 2, &amodule, &got_offset, NULL);

amodule->got [got_offset] = arg;
amodule->got [got_offset + 1] = addr;
amodule->got [got_offset] = arg;
amodule->got [got_offset + 1] = addr;
}

/* The caller expects an ftnptr */
return mono_create_ftnptr (mono_domain_get (), code);
Expand Down

0 comments on commit 31522aa

Please sign in to comment.