From 235ab3bf6f8736081185dc4115d31bdd806199f5 Mon Sep 17 00:00:00 2001 From: fsfod Date: Tue, 9 Feb 2016 08:04:51 +0000 Subject: [PATCH] Added support for separate mcode areas --- src/lj_jit.h | 17 +++++++---- src/lj_mcode.c | 82 +++++++++++++++++++++++++++----------------------- src/lj_mcode.h | 4 +-- src/lj_trace.c | 8 ++--- 4 files changed, 61 insertions(+), 50 deletions(-) diff --git a/src/lj_jit.h b/src/lj_jit.h index 5d41ef4b..ec431a61 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h @@ -389,6 +389,15 @@ typedef struct FoldState { IRIns right[2]; /* Instruction referenced by right operand. */ } FoldState; +typedef struct MCodeArea { + int prot; /* Protection of current mcode area. */ + MCode *base; /* Base of current mcode area. */ + MCode *top; /* Top of current mcode area. */ + MCode *bot; /* Bottom of current mcode area. */ + size_t sz; /* Size of current mcode area. */ + size_t szall; /* Total size of all allocated mcode areas in this chain. */ +} MCodeArea; + /* JIT compiler state. */ typedef struct jit_State { GCtrace cur; /* Current trace. */ @@ -474,12 +483,8 @@ typedef struct jit_State { BCIns *patchpc; /* PC for pending re-patch. */ BCIns patchins; /* Instruction for pending re-patch. */ - int mcprot; /* Protection of current mcode area. */ - MCode *mcarea; /* Base of current mcode area. */ - MCode *mctop; /* Top of current mcode area. */ - MCode *mcbot; /* Bottom of current mcode area. */ - size_t szmcarea; /* Size of current mcode area. */ - size_t szallmcarea; /* Total size of all allocated mcode areas. */ + MCodeArea mcarea; /* JIT mcode area */ + MCodeArea *curmcarea; /* Current mcode area by default is mcarea */ TValue errinfo; /* Additional info element for trace errors. */ diff --git a/src/lj_mcode.c b/src/lj_mcode.c index 64b0ca90..e09e3a56 100644 --- a/src/lj_mcode.c +++ b/src/lj_mcode.c @@ -191,12 +191,12 @@ static LJ_NOINLINE void mcode_protfail(jit_State *J) } /* Change protection of MCode area. */ -static void mcode_protect(jit_State *J, int prot) +static void mcode_protect(jit_State *J, MCodeArea *area, int prot) { - if (J->mcprot != prot) { - if (LJ_UNLIKELY(mcode_setprot(J->mcarea, J->szmcarea, prot))) + if (area->prot != prot) { + if (LJ_UNLIKELY(mcode_setprot(area->base, area->sz, prot))) mcode_protfail(J); - J->mcprot = prot; + area->prot = prot; } } @@ -213,7 +213,7 @@ static void mcode_protect(jit_State *J, int prot) #ifdef LJ_TARGET_JUMPRANGE /* Get memory within relative jump distance of our code in 64 bit mode. */ -static void *mcode_alloc(jit_State *J, size_t sz) +static void *mcode_alloc(jit_State *J, MCodeArea *area, size_t sz) { /* Target an address in the static assembler code (64K aligned). ** Try addresses within a distance of target-range/2+1MB..target+range/2-1MB. @@ -228,7 +228,7 @@ static void *mcode_alloc(jit_State *J, size_t sz) #endif const uintptr_t range = (1u << (LJ_TARGET_JUMPRANGE-1)) - (1u << 21); /* First try a contiguous area below the last one. */ - uintptr_t hint = J->mcarea ? (uintptr_t)J->mcarea - sz : 0; + uintptr_t hint = area->base ? (uintptr_t)area->base - sz : 0; int i; /* Limit probing iterations, depending on the available pool size. */ for (i = 0; i < LJ_TARGET_JUMPRANGE; i++) { @@ -253,7 +253,7 @@ static void *mcode_alloc(jit_State *J, size_t sz) #else /* All memory addresses are reachable by relative jumps. */ -static void *mcode_alloc(jit_State *J, size_t sz) +static void *mcode_alloc(jit_State *J, MCodeArea *area, size_t sz) { #if defined(__OpenBSD__) || LJ_TARGET_UWP /* Allow better executable memory allocation for OpenBSD W^X mode. */ @@ -273,27 +273,28 @@ static void *mcode_alloc(jit_State *J, size_t sz) /* -- MCode area management ----------------------------------------------- */ /* Allocate a new MCode area. */ -static void mcode_allocarea(jit_State *J) +static void mcode_allocarea(jit_State *J, MCodeArea *area) { - MCode *oldarea = J->mcarea; + MCode *oldarea = area->base; + size_t sz = (size_t)J->param[JIT_P_sizemcode] << 10; sz = (sz + LJ_PAGESIZE-1) & ~(size_t)(LJ_PAGESIZE - 1); - J->mcarea = (MCode *)mcode_alloc(J, sz); - J->szmcarea = sz; - J->mcprot = MCPROT_GEN; - J->mctop = (MCode *)((char *)J->mcarea + J->szmcarea); - J->mcbot = (MCode *)((char *)J->mcarea + sizeof(MCLink)); - ((MCLink *)J->mcarea)->next = oldarea; - ((MCLink *)J->mcarea)->size = sz; - J->szallmcarea += sz; + area->base = (MCode *)mcode_alloc(J, area, sz); + area->sz = sz; + area->prot = MCPROT_GEN; + area->top = (MCode *)((char *)area->base + area->sz); + area->bot = (MCode *)((char *)area->base + sizeof(MCLink)); + ((MCLink *)area->base)->next = oldarea; + ((MCLink *)area->base)->size = sz; + area->szall += sz; } -/* Free all MCode areas. */ -void lj_mcode_free(jit_State *J) +/* Free an MCode areas. */ +void lj_mcode_free(jit_State *J, MCodeArea *area) { - MCode *mc = J->mcarea; - J->mcarea = NULL; - J->szallmcarea = 0; + MCode *mc = area->base; + area->base = NULL; + area->szall = 0; while (mc) { MCode *next = ((MCLink *)mc)->next; mcode_free(J, mc, ((MCLink *)mc)->size); @@ -306,26 +307,29 @@ void lj_mcode_free(jit_State *J) /* Reserve the remainder of the current MCode area. */ MCode *lj_mcode_reserve(jit_State *J, MCode **lim) { - if (!J->mcarea) - mcode_allocarea(J); + MCodeArea *area = J->curmcarea; + if (!area->base) + mcode_allocarea(J, area); else - mcode_protect(J, MCPROT_GEN); - *lim = J->mcbot; - return J->mctop; + mcode_protect(J, area, MCPROT_GEN); + *lim = area->bot; + return area->top; } /* Commit the top part of the current MCode area. */ void lj_mcode_commit(jit_State *J, MCode *top) { - J->mctop = top; - mcode_protect(J, MCPROT_RUN); + MCodeArea *area = J->curmcarea; + area->top = top; + mcode_protect(J, area, MCPROT_RUN); } /* Abort the reservation. */ void lj_mcode_abort(jit_State *J) { - if (J->mcarea) - mcode_protect(J, MCPROT_RUN); + MCodeArea *area = J->curmcarea; + if (area->base) + mcode_protect(J, area, MCPROT_RUN); } /* Set/reset protection to allow patching of MCode areas. */ @@ -335,17 +339,18 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) UNUSED(J); UNUSED(ptr); UNUSED(finish); return NULL; #else + MCodeArea *area = J->curmcarea; if (finish) { - if (J->mcarea == ptr) - mcode_protect(J, MCPROT_RUN); + if (area->base == ptr) + mcode_protect(J, area, MCPROT_RUN); else if (LJ_UNLIKELY(mcode_setprot(ptr, ((MCLink *)ptr)->size, MCPROT_RUN))) mcode_protfail(J); return NULL; } else { - MCode *mc = J->mcarea; + MCode *mc = area->base; /* Try current area first to use the protection cache. */ - if (ptr >= mc && ptr < (MCode *)((char *)mc + J->szmcarea)) { - mcode_protect(J, MCPROT_GEN); + if (ptr >= mc && ptr < (MCode *)((char *)mc + area->sz)) { + mcode_protect(J, area, MCPROT_GEN); return mc; } /* Otherwise search through the list of MCode areas. */ @@ -366,15 +371,16 @@ MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish) void lj_mcode_limiterr(jit_State *J, size_t need) { size_t sizemcode, maxmcode; + MCodeArea *area = J->curmcarea; lj_mcode_abort(J); sizemcode = (size_t)J->param[JIT_P_sizemcode] << 10; sizemcode = (sizemcode + LJ_PAGESIZE-1) & ~(size_t)(LJ_PAGESIZE - 1); maxmcode = (size_t)J->param[JIT_P_maxmcode] << 10; if ((size_t)need > sizemcode) lj_trace_err(J, LJ_TRERR_MCODEOV); /* Too long for any area. */ - if (J->szallmcarea + sizemcode > maxmcode) + if (area == &J->mcarea && area->szall + sizemcode > maxmcode) lj_trace_err(J, LJ_TRERR_MCODEAL); - mcode_allocarea(J); + mcode_allocarea(J, area); lj_trace_err(J, LJ_TRERR_MCODELM); /* Retry with new area. */ } diff --git a/src/lj_mcode.h b/src/lj_mcode.h index f0847e93..6f0b549e 100644 --- a/src/lj_mcode.h +++ b/src/lj_mcode.h @@ -16,14 +16,14 @@ LJ_FUNC void lj_mcode_sync(void *start, void *end); #include "lj_jit.h" -LJ_FUNC void lj_mcode_free(jit_State *J); +LJ_FUNC void lj_mcode_free(jit_State *J, MCodeArea *area); LJ_FUNC MCode *lj_mcode_reserve(jit_State *J, MCode **lim); LJ_FUNC void lj_mcode_commit(jit_State *J, MCode *m); LJ_FUNC void lj_mcode_abort(jit_State *J); LJ_FUNC MCode *lj_mcode_patch(jit_State *J, MCode *ptr, int finish); LJ_FUNC_NORET void lj_mcode_limiterr(jit_State *J, size_t need); -#define lj_mcode_commitbot(J, m) (J->mcbot = (m)) +#define lj_mcode_commitbot(J, m) (J->curmcarea->bot = (m)) #endif diff --git a/src/lj_trace.c b/src/lj_trace.c index d85b47f8..525eacdd 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c @@ -294,7 +294,7 @@ int lj_trace_flushall(lua_State *L) /* Clear penalty cache. */ memset(J->penalty, 0, sizeof(J->penalty)); /* Free the whole machine code and invalidate all exit stub groups. */ - lj_mcode_free(J); + lj_mcode_free(J, &J->mcarea); memset(J->exitstubgroup, 0, sizeof(J->exitstubgroup)); lj_vmevent_send(L, TRACE, setstrV(L, L->top++, lj_str_newlit(L, "flush")); @@ -307,8 +307,8 @@ void lj_trace_initstate(global_State *g) { jit_State *J = G2J(g); TValue *tv; - - /* Initialize aligned SIMD constants. */ + J->curmcarea = &J->mcarea; + /* Initialize SIMD constants. */ tv = LJ_KSIMD(J, LJ_KSIMD_ABS); tv[0].u64 = U64x(7fffffff,ffffffff); tv[1].u64 = U64x(7fffffff,ffffffff); @@ -356,7 +356,7 @@ void lj_trace_freestate(global_State *g) lua_assert(i == (ptrdiff_t)J->cur.traceno || traceref(J, i) == NULL); } #endif - lj_mcode_free(J); + lj_mcode_free(J, &J->mcarea); lj_mem_freevec(g, J->snapmapbuf, J->sizesnapmap, SnapEntry); lj_mem_freevec(g, J->snapbuf, J->sizesnap, SnapShot); lj_mem_freevec(g, J->irbuf + J->irbotlim, J->irtoplim - J->irbotlim, IRIns);