Skip to content

Commit

Permalink
Minor tweaks to the LuaJIT mcode hack (#285)
Browse files Browse the repository at this point in the history
* Minor tweaks to the LuaJIT mcode patch

  * Better comments in lj_mcode_clear
  * Follow the same code flow as mcode_allocarea, because it's
    effectively serving the same purpose
  * Handle non-contiguous links properly anywhere in the chain
  • Loading branch information
NiLuJe committed Jan 3, 2021
1 parent 0e65369 commit 180513e
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 30 deletions.
29 changes: 15 additions & 14 deletions jni/luajit/koreader-luajit-mcode-debug.patch
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,14 @@ index 1d0ff54..8ef29a3 100644
} else {
if (!(mode & LUAJIT_MODE_ON))
diff --git a/src/lj_mcode.c b/src/lj_mcode.c
index 241c86a..198fdd2 100644
index 9cb7a21..4b7b649 100644
--- a/src/lj_mcode.c
+++ b/src/lj_mcode.c
@@ -109,12 +109,14 @@ static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot, b
if (!hint) lj_trace_err(J, LJ_TRERR_MCODEAL);
p = NULL;
}
+ LJ_LOG("mapped at @ %p (%zuK)", p, sz / 1024U);
+ LJ_LOG("mapped %zuK at @ %p", sz / 1024U, p);
return p;
}

Expand Down Expand Up @@ -105,7 +105,7 @@ index 241c86a..198fdd2 100644
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);
+ LJ_LOG("new %zuK mcarea @ %p (oldarea @ %p)", sz, J->mcarea, oldarea);
+ LJ_LOG("new %zuK mcarea @ %p (oldarea @ %p)", sz / 1024U, J->mcarea, oldarea);
J->szmcarea = sz;
J->mcprot = MCPROT_GEN;
J->mctop = (MCode *)((char *)J->mcarea + J->szmcarea);
Expand All @@ -125,33 +125,34 @@ index 241c86a..198fdd2 100644
}

/* Clear all MCode areas. */
@@ -326,7 +336,9 @@ void lj_mcode_clear(jit_State *J)
szallmcarea += size;
@@ -328,8 +338,10 @@ void lj_mcode_clear(jit_State *J)
mcarea = mc;
prevsize = size;
szmcarea = size;
szallmcarea += size;
+ LJ_LOG("contiguous %zuK link detected @ %p (total: %zuK) (next @ %p)", size / 1024U, mc, szallmcarea / 1024U, next);
} else {
+ LJ_LOG("non-contiguous %zuK link detected @ %p (next @ %p)!", size / 1024U, mc, next);
mcarea = NULL;
+ LJ_LOG("non-contiguous %zuK link detected @ %p (next @ %p)!", size / 1024U, mc, next);
/* A non-contiguous link anywhere in the chain means we scrap the whole chain, to keep things simple */
break;
}
mc = next;
@@ -353,6 +365,7 @@ void lj_mcode_clear(jit_State *J)
@@ -358,6 +370,7 @@ void lj_mcode_clear(jit_State *J)
((MCLink *)J->mcarea)->next = NULL;
((MCLink *)J->mcarea)->size = J->szmcarea;
/* Update the protection cache */
J->mcprot = MCPROT_GEN;
+ LJ_LOG("recycled mcarea @ %p (%zuK)", J->mcarea, J->szmcarea / 1024U);
J->szallmcarea = J->szmcarea;
+ LJ_LOG("recycled %zuK mcarea @ %p", J->szmcarea / 1024U, J->mcarea);
}

/* -- MCode transactions -------------------------------------------------- */
@@ -360,6 +373,7 @@ void lj_mcode_clear(jit_State *J)
@@ -365,6 +378,7 @@ void lj_mcode_clear(jit_State *J)
/* Reserve the remainder of the current MCode area. */
MCode *lj_mcode_reserve(jit_State *J, MCode **lim)
{
+ //LJ_LOG("J->mcarea: %p // lim: %p // mctop: %p // mcbot: %p", (void *) J->mcarea, (void *) *lim, (void *) J->mctop, (void *) J->mcbot);
if (!J->mcarea)
mcode_allocarea(J);
else
@@ -424,6 +438,7 @@ void lj_mcode_limiterr(jit_State *J, size_t need)
@@ -429,6 +443,7 @@ void lj_mcode_limiterr(jit_State *J, size_t need)
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;
Expand Down
37 changes: 21 additions & 16 deletions jni/luajit/koreader-luajit-mcode-reserve-hack.patch
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ index 655b84c..1fa6292 100644
MCode *mctop; /* Top of current mcode area. */
MCode *mcbot; /* Bottom of current mcode area. */
diff --git a/src/lj_mcode.c b/src/lj_mcode.c
index a5153b2..241c86a 100644
index a5153b2..9cb7a21 100644
--- a/src/lj_mcode.c
+++ b/src/lj_mcode.c
@@ -98,9 +98,13 @@ static int mcode_setprot(void *p, size_t sz, DWORD prot)
Expand Down Expand Up @@ -103,11 +103,11 @@ index a5153b2..241c86a 100644
#endif
}

@@ -280,8 +303,56 @@ void lj_mcode_free(jit_State *J)
@@ -280,8 +303,61 @@ void lj_mcode_free(jit_State *J)
while (mc) {
MCode *next = ((MCLink *)mc)->next;
mcode_free(J, mc, ((MCLink *)mc)->size);
+ /* Remember the oldest link as lastmcarea */
+ /* Remember the oldest (i.e., highest address) link as lastmcarea */
+ if (!next) {
+ J->lastmcarea = mc;
+ }
Expand All @@ -119,44 +119,49 @@ index a5153b2..241c86a 100644
+void lj_mcode_clear(jit_State *J)
+{
+ MCode *mc = J->mcarea;
+ /* Keep track of the previous link in the chain */
+ MCode *mcarea = J->mcarea;
+ size_t szallmcarea = 0;
+ size_t prevsize = 0;
+ size_t szmcarea = 0;
+ while (mc) {
+ MCode *next = ((MCLink *)mc)->next;
+ size_t size = ((MCLink *)mc)->size;
+ /* Reset mcarea to the oldest contiguous link */
+ if ((next && next == mc + size) || (!next && mc == mcarea + prevsize) || (!next && mc == mcarea)) {
+ szallmcarea += size;
+ if ((next && next == mc + size) || (!next && mc == mcarea + szmcarea) || (!next && mc == mcarea)) {
+ /* ^ next link is contiguous ^ last link is contiguous ^ single link in the chain */
+ mcarea = mc;
+ prevsize = size;
+ szmcarea = size;
+ szallmcarea += size;
+ } else {
+ mcarea = NULL;
+ /* A non-contiguous link anywhere in the chain means we scrap the whole chain, to keep things simple */
+ break;
+ }
mc = next;
}
+
+ /* If there were non-contiguous links, fallback to lj_mcode_free */
+ /* If we hit a non-contiguous link, fallback to lj_mcode_free */
+ if (!mcarea) {
+ return lj_mcode_free(J);
+ }
+
+ /* Recycle the full chain */
+ J->mcarea = mcarea + prevsize - szallmcarea;
+ /* Ready to recycle the full chain */
+ /* Rewind to the lowest address (as links are allocated high to low, c.f., mcode_alloc) */
+ J->mcarea = mcarea + szmcarea - szallmcarea;
+ J->szmcarea = szallmcarea;
+ J->szallmcarea = szallmcarea;
+ /* Tell the JIT that it once again has the full area available to generate code in, c.f., mcode_allocarea */
+ J->mctop = (MCode *)((char *)J->mcarea + J->szmcarea);
+ J->mcbot = (MCode *)((char *)J->mcarea + sizeof(MCLink));
+ /* We need write access to clear it */
+ if (LJ_UNLIKELY(mcode_setprot(J->mcarea, J->szmcarea, MCPROT_GEN)))
+ mcode_protfail(J);
+ /* Update the protection cache */
+ J->mcprot = MCPROT_GEN;
+ memset(J->mcarea, 0, J->szmcarea);
+ /* Tell the JIT that it once again has the full area available to generate code in, c.f., mcode_allocarea */
+ J->mctop = (MCode *)((char *)J->mcarea + J->szmcarea);
+ J->mcbot = (MCode *)((char *)J->mcarea + sizeof(MCLink));
+ /* Update the MCLink data for the newly coalesced area */
+ ((MCLink *)J->mcarea)->next = NULL;
+ ((MCLink *)J->mcarea)->size = J->szmcarea;
+ /* Update the protection cache */
+ J->mcprot = MCPROT_GEN;
+ J->szallmcarea = J->szmcarea;
}

/* -- MCode transactions -------------------------------------------------- */
Expand Down

0 comments on commit 180513e

Please sign in to comment.