------------------------------------------------------------------------------
+local symtabmt = { __index = false }
local symtab = {}
local nexitsym = 0
--- Fill symbol table with trace exit addresses.
-local function fillsymtab(nexit)
+-- Fill nested symbol table with per-trace exit stub addresses.
+local function fillsymtab_tr(tr, nexit)
+ local t = {}
+ symtabmt.__index = t
+ for i=0,nexit-1 do
+ local addr = traceexitstub(tr, i)
+ t[addr] = tostring(i)
+ end
+ local addr = traceexitstub(tr, nexit)
+ if addr then t[addr] = "stack_check" end
+end
+
+-- Fill symbol table with trace exit stub addresses.
+local function fillsymtab(tr, nexit)
local t = symtab
if nexitsym == 0 then
local ircall = vmdef.ircall
if addr ~= 0 then t[addr] = ircall[i] end
end
end
- if nexit > nexitsym then
+ if nexitsym == 1000000 then -- Per-trace exit stubs.
+ fillsymtab_tr(tr, nexit)
+ elseif nexit > nexitsym then -- Shared exit stubs.
for i=nexitsym,nexit-1 do
local addr = traceexitstub(i)
- if addr == nil then nexit = 1000000; break end
+ if addr == nil then -- Fall back to per-trace exit stubs.
+ fillsymtab_tr(tr, nexit)
+ setmetatable(symtab, symtabmt)
+ nexit = 1000000
+ break
+ end
t[addr] = tostring(i)
end
nexitsym = nexit
out:write("---- TRACE ", tr, " mcode ", #mcode, "\n")
local ctx = disass.create(mcode, addr, dumpwrite)
ctx.hexdump = 0
- ctx.symtab = fillsymtab(info.nexit)
+ ctx.symtab = fillsymtab(tr, info.nexit)
if loop ~= 0 then
symtab[addr+loop] = "LOOP"
ctx:disass(0, loop)
return 0;
}
-/* local addr = jit.util.traceexitstub(idx) */
+/* local addr = jit.util.traceexitstub([tr,] exitno) */
LJLIB_CF(jit_util_traceexitstub)
{
+#ifdef EXITSTUBS_PER_GROUP
ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1);
jit_State *J = L2J(L);
if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) {
setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno));
return 1;
}
+#else
+ if (L->top > L->base+1) { /* Don't throw for one-argument variant. */
+ GCtrace *T = jit_checktrace(L);
+ ExitNo exitno = (ExitNo)lj_lib_checkint(L, 2);
+ ExitNo maxexit = T->root ? T->nsnap+1 : T->nsnap;
+ if (T && T->mcode != NULL && exitno < maxexit) {
+ setintptrV(L->top-1, (intptr_t)(void *)exitstub_trace_addr(T, exitno));
+ return 1;
+ }
+ }
+#endif
return 0;
}
#error "Missing include for target CPU"
#endif
+#ifdef EXITSTUBS_PER_GROUP
/* Return the address of an exit stub. */
static LJ_AINLINE MCode *exitstub_addr(jit_State *J, ExitNo exitno)
{
return (MCode *)((char *)J->exitstubgroup[exitno / EXITSTUBS_PER_GROUP] +
EXITSTUB_SPACING*(exitno % EXITSTUBS_PER_GROUP));
}
+#endif
#endif