mirror of
https://github.com/LuaJIT/LuaJIT.git
synced 2025-02-08 07:34:07 +00:00
Fixes #285: Increase available allocation range in mcode_alloc()
Change mcode_alloc() so that instead of all execution threads using the same allocation range of '[target - range/2; target + range / 2]' (where 'range' is the jump range defined by the architecture), make some threads use the '[target - range; target]' range, and other ones use '[target; target + range]' based on a PRNG. The patch essentially doubles the available allocation pool for mcode_alloc() and helps reduce mmap() scalability issues for multi-threaded applications.
This commit is contained in:
parent
387d3abff4
commit
60a5e52bf7
@ -452,6 +452,10 @@ typedef struct jit_State {
|
|||||||
uint32_t penaltyslot; /* Round-robin index into penalty slots. */
|
uint32_t penaltyslot; /* Round-robin index into penalty slots. */
|
||||||
uint32_t prngstate; /* PRNG state. */
|
uint32_t prngstate; /* PRNG state. */
|
||||||
|
|
||||||
|
uintptr_t target; /* target address for mcode_alloc() */
|
||||||
|
uintptr_t range; /* allocation range for mcode_alloc() */
|
||||||
|
uintptr_t allocbase; /* allocation base addred for mcode_alloc() */
|
||||||
|
|
||||||
#ifdef LUAJIT_ENABLE_TABLE_BUMP
|
#ifdef LUAJIT_ENABLE_TABLE_BUMP
|
||||||
RBCHashEntry rbchash[RBCHASH_SLOTS]; /* Reverse bytecode map. */
|
RBCHashEntry rbchash[RBCHASH_SLOTS]; /* Reverse bytecode map. */
|
||||||
#endif
|
#endif
|
||||||
|
@ -219,18 +219,8 @@ static void mcode_protect(jit_State *J, int prot)
|
|||||||
static void *mcode_alloc(jit_State *J, size_t sz)
|
static void *mcode_alloc(jit_State *J, size_t sz)
|
||||||
{
|
{
|
||||||
/* Target an address in the static assembler code (64K aligned).
|
/* Target an address in the static assembler code (64K aligned).
|
||||||
** Try addresses within a distance of target-range/2+1MB..target+range/2-1MB.
|
** Try addresses within a distance of J->allocbase..J->allocbase+J->range.
|
||||||
** Use half the jump range so every address in the range can reach any other.
|
** First try a contiguous area below the last one. */
|
||||||
*/
|
|
||||||
#if LJ_TARGET_MIPS
|
|
||||||
/* Use the middle of the 256MB-aligned region. */
|
|
||||||
uintptr_t target = ((uintptr_t)(void *)lj_vm_exit_handler &
|
|
||||||
~(uintptr_t)0x0fffffffu) + 0x08000000u;
|
|
||||||
#else
|
|
||||||
uintptr_t target = (uintptr_t)(void *)lj_vm_exit_handler & ~(uintptr_t)0xffff;
|
|
||||||
#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 = J->mcarea ? (uintptr_t)J->mcarea - sz : 0;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 32; i++) { /* 32 attempts ought to be enough ... */
|
for (i = 0; i < 32; i++) { /* 32 attempts ought to be enough ... */
|
||||||
@ -238,15 +228,16 @@ static void *mcode_alloc(jit_State *J, size_t sz)
|
|||||||
void *p = mcode_alloc_at(J, hint, sz, MCPROT_GEN);
|
void *p = mcode_alloc_at(J, hint, sz, MCPROT_GEN);
|
||||||
|
|
||||||
if (mcode_validptr(p) &&
|
if (mcode_validptr(p) &&
|
||||||
((uintptr_t)p + sz - target < range || target - (uintptr_t)p < range))
|
((uintptr_t)p + sz - J->target < J->range ||
|
||||||
|
J->target - (uintptr_t)p < J->range))
|
||||||
return p;
|
return p;
|
||||||
if (p) mcode_free(J, p, sz); /* Free badly placed area. */
|
if (p) mcode_free(J, p, sz); /* Free badly placed area. */
|
||||||
}
|
}
|
||||||
/* Next try probing pseudo-random addresses. */
|
/* Next try probing pseudo-random addresses. */
|
||||||
do {
|
do {
|
||||||
hint = LJ_PRNG_BITS(J, LJ_TARGET_JUMPRANGE-16) << 16; /* 64K aligned. */
|
hint = LJ_PRNG_BITS(J, LJ_TARGET_JUMPRANGE-16) << 16; /* 64K aligned. */
|
||||||
} while (!(hint + sz < range*2));
|
} while (!(hint + sz < J->range));
|
||||||
hint = target + hint - range;
|
hint = J->allocbase + hint;
|
||||||
}
|
}
|
||||||
lj_trace_err(J, LJ_TRERR_MCODEAL); /* Give up. OS probably ignores hints? */
|
lj_trace_err(J, LJ_TRERR_MCODEAL); /* Give up. OS probably ignores hints? */
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -225,6 +225,23 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
L->status = 0;
|
L->status = 0;
|
||||||
|
#if LJ_TARGET_MIPS
|
||||||
|
/* Use the middle of the 256MB-aligned region. */
|
||||||
|
uintptr_t target = ((uintptr_t)(void *)lj_vm_exit_handler &
|
||||||
|
~(uintptr_t)0x0fffffffu) + 0x08000000u;
|
||||||
|
#else
|
||||||
|
uintptr_t target = (uintptr_t)(void *)lj_vm_exit_handler & ~(uintptr_t)0xffff;
|
||||||
|
#endif
|
||||||
|
uintptr_t range = (1u << LJ_TARGET_JUMPRANGE) - (1u << 21);
|
||||||
|
uintptr_t allocbase;
|
||||||
|
if (LJ_PRNG_BITS(G2J(g), 1)) {
|
||||||
|
allocbase = (target - range > target) ? 0 : target - range;
|
||||||
|
} else {
|
||||||
|
allocbase = target;
|
||||||
|
}
|
||||||
|
G2J(g)->target = target;
|
||||||
|
G2J(g)->range = range;
|
||||||
|
G2J(g)->allocbase = allocbase;
|
||||||
return L;
|
return L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user