Save currently executing lua_State in g->cur_L.

This is only a good approximation due to deficiencies in the design of
the Lua/C API. It indicates _some_ valid state that is/was executing.
Also reorder L->cframe stores to achieve a synchronously consistent state.
This commit is contained in:
Mike Pall 2013-08-28 13:06:19 +02:00
parent 5120240b77
commit 517500ba48
15 changed files with 89 additions and 67 deletions

View File

@ -342,7 +342,7 @@ static Reg ra_rematk(ASMState *as, IRRef ref)
emit_getgl(as, r, jit_base); emit_getgl(as, r, jit_base);
} else if (emit_canremat(ASMREF_L) && ir->o == IR_KPRI) { } else if (emit_canremat(ASMREF_L) && ir->o == IR_KPRI) {
lua_assert(irt_isnil(ir->t)); /* REF_NIL stores ASMREF_L register. */ lua_assert(irt_isnil(ir->t)); /* REF_NIL stores ASMREF_L register. */
emit_getgl(as, r, jit_L); emit_getgl(as, r, cur_L);
#if LJ_64 #if LJ_64
} else if (ir->o == IR_KINT64) { } else if (ir->o == IR_KINT64) {
emit_loadu64(as, r, ir_kint64(ir)->u64); emit_loadu64(as, r, ir_kint64(ir)->u64);

View File

@ -1944,7 +1944,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP, emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP,
(int32_t)offsetof(lua_State, maxstack)); (int32_t)offsetof(lua_State, maxstack));
if (irp) { /* Must not spill arbitrary registers in head of side trace. */ if (irp) { /* Must not spill arbitrary registers in head of side trace. */
int32_t i = i32ptr(&J2G(as->J)->jit_L); int32_t i = i32ptr(&J2G(as->J)->cur_L);
if (ra_hasspill(irp->s)) if (ra_hasspill(irp->s))
emit_lso(as, ARMI_LDR, pbase, RID_SP, sps_scale(irp->s)); emit_lso(as, ARMI_LDR, pbase, RID_SP, sps_scale(irp->s));
emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP, (i & 4095)); emit_lso(as, ARMI_LDR, RID_TMP, RID_TMP, (i & 4095));
@ -1952,7 +1952,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
emit_lso(as, ARMI_STR, RID_RET, RID_SP, 0); /* Save temp. register. */ emit_lso(as, ARMI_STR, RID_RET, RID_SP, 0); /* Save temp. register. */
emit_loadi(as, RID_TMP, (i & ~4095)); emit_loadi(as, RID_TMP, (i & ~4095));
} else { } else {
emit_getgl(as, RID_TMP, jit_L); emit_getgl(as, RID_TMP, cur_L);
} }
} }
@ -2061,13 +2061,13 @@ static void asm_loop_fixup(ASMState *as)
/* -- Head of trace ------------------------------------------------------- */ /* -- Head of trace ------------------------------------------------------- */
/* Reload L register from g->jit_L. */ /* Reload L register from g->cur_L. */
static void asm_head_lreg(ASMState *as) static void asm_head_lreg(ASMState *as)
{ {
IRIns *ir = IR(ASMREF_L); IRIns *ir = IR(ASMREF_L);
if (ra_used(ir)) { if (ra_used(ir)) {
Reg r = ra_dest(as, ir, RSET_GPR); Reg r = ra_dest(as, ir, RSET_GPR);
emit_getgl(as, r, jit_L); emit_getgl(as, r, cur_L);
ra_evictk(as); ra_evictk(as);
} }
} }

View File

@ -1586,7 +1586,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
emit_tsi(as, MIPSI_LW, tmp, tmp, offsetof(lua_State, maxstack)); emit_tsi(as, MIPSI_LW, tmp, tmp, offsetof(lua_State, maxstack));
if (pbase == RID_TMP) if (pbase == RID_TMP)
emit_getgl(as, RID_TMP, jit_base); emit_getgl(as, RID_TMP, jit_base);
emit_getgl(as, tmp, jit_L); emit_getgl(as, tmp, cur_L);
if (allow == RSET_EMPTY) /* Spill temp. register. */ if (allow == RSET_EMPTY) /* Spill temp. register. */
emit_tsi(as, MIPSI_SW, tmp, RID_SP, 0); emit_tsi(as, MIPSI_SW, tmp, RID_SP, 0);
} }

View File

@ -1759,7 +1759,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
emit_tai(as, PPCI_LWZ, tmp, tmp, offsetof(lua_State, maxstack)); emit_tai(as, PPCI_LWZ, tmp, tmp, offsetof(lua_State, maxstack));
if (pbase == RID_TMP) if (pbase == RID_TMP)
emit_getgl(as, RID_TMP, jit_base); emit_getgl(as, RID_TMP, jit_base);
emit_getgl(as, tmp, jit_L); emit_getgl(as, tmp, cur_L);
if (allow == RSET_EMPTY) /* Spill temp. register. */ if (allow == RSET_EMPTY) /* Spill temp. register. */
emit_tai(as, PPCI_STW, tmp, RID_SP, SPOFS_TMPW); emit_tai(as, PPCI_STW, tmp, RID_SP, SPOFS_TMPW);
} }

View File

@ -2369,7 +2369,7 @@ static void asm_stack_check(ASMState *as, BCReg topslot,
emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE, emit_rmro(as, XO_ARITH(XOg_SUB), r, RID_NONE,
ptr2addr(&J2G(as->J)->jit_base)); ptr2addr(&J2G(as->J)->jit_base));
emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack)); emit_rmro(as, XO_MOV, r, r, offsetof(lua_State, maxstack));
emit_getgl(as, r, jit_L); emit_getgl(as, r, cur_L);
if (allow == RSET_EMPTY) /* Spill temp. register. */ if (allow == RSET_EMPTY) /* Spill temp. register. */
emit_rmro(as, XO_MOVto, r|REX_64, RID_ESP, 0); emit_rmro(as, XO_MOVto, r|REX_64, RID_ESP, 0);
} }

View File

@ -562,9 +562,9 @@ void LJ_FASTCALL lj_ccallback_leave(CTState *cts, TValue *o)
} }
callback_conv_result(cts, L, o); callback_conv_result(cts, L, o);
/* Finally drop C frame and continuation frame. */ /* Finally drop C frame and continuation frame. */
L->cframe = cframe_prev(L->cframe);
L->top -= 2; L->top -= 2;
L->base = obase; L->base = obase;
L->cframe = cframe_prev(L->cframe);
cts->cb.slot = 0; /* Blacklist C function that called the callback. */ cts->cb.slot = 0; /* Blacklist C function that called the callback. */
} }

View File

@ -357,6 +357,7 @@ static void callhook(lua_State *L, int event, BCLine line)
hook_enter(g); hook_enter(g);
hookf(L, &ar); hookf(L, &ar);
lua_assert(hook_active(g)); lua_assert(hook_active(g));
setgcref(g->cur_L, obj2gco(L));
hook_leave(g); hook_leave(g);
} }
} }

View File

@ -99,8 +99,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
TValue *top = restorestack(L, -nres); TValue *top = restorestack(L, -nres);
if (frame < top) { /* Frame reached? */ if (frame < top) { /* Frame reached? */
if (errcode) { if (errcode) {
L->cframe = cframe_prev(cf);
L->base = frame+1; L->base = frame+1;
L->cframe = cframe_prev(cf);
unwindstack(L, top); unwindstack(L, top);
} }
return cf; return cf;
@ -119,8 +119,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
#endif #endif
#if LJ_UNWIND_EXT #if LJ_UNWIND_EXT
if (errcode) { if (errcode) {
L->cframe = cframe_prev(cf);
L->base = frame_prevd(frame) + 1; L->base = frame_prevd(frame) + 1;
L->cframe = cframe_prev(cf);
unwindstack(L, frame); unwindstack(L, frame);
} else if (cf != stopcf) { } else if (cf != stopcf) {
cf = cframe_prev(cf); cf = cframe_prev(cf);
@ -144,8 +144,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
return cf; return cf;
} }
if (errcode) { if (errcode) {
L->cframe = cframe_prev(cf);
L->base = frame_prevd(frame) + 1; L->base = frame_prevd(frame) + 1;
L->cframe = cframe_prev(cf);
unwindstack(L, frame); unwindstack(L, frame);
} }
return cf; return cf;
@ -166,8 +166,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
} }
if (frame_typep(frame) == FRAME_PCALL) if (frame_typep(frame) == FRAME_PCALL)
hook_leave(G(L)); hook_leave(G(L));
L->cframe = cf;
L->base = frame_prevd(frame) + 1; L->base = frame_prevd(frame) + 1;
L->cframe = cf;
unwindstack(L, L->base); unwindstack(L, L->base);
} }
return (void *)((intptr_t)cf | CFRAME_UNWIND_FF); return (void *)((intptr_t)cf | CFRAME_UNWIND_FF);
@ -175,8 +175,8 @@ static void *err_unwind(lua_State *L, void *stopcf, int errcode)
} }
/* No C frame. */ /* No C frame. */
if (errcode) { if (errcode) {
L->cframe = NULL;
L->base = tvref(L->stack)+1; L->base = tvref(L->stack)+1;
L->cframe = NULL;
unwindstack(L, L->base); unwindstack(L, L->base);
if (G(L)->panic) if (G(L)->panic)
G(L)->panic(L); G(L)->panic(L);

View File

@ -696,7 +696,7 @@ void LJ_FASTCALL lj_gc_step_fixtop(lua_State *L)
/* Perform multiple GC steps. Called from JIT-compiled code. */ /* Perform multiple GC steps. Called from JIT-compiled code. */
int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps) int LJ_FASTCALL lj_gc_step_jit(global_State *g, MSize steps)
{ {
lua_State *L = gco2th(gcref(g->jit_L)); lua_State *L = gco2th(gcref(g->cur_L));
L->base = tvref(G(L)->jit_base); L->base = tvref(G(L)->jit_base);
L->top = curr_topL(L); L->top = curr_topL(L);
while (steps-- > 0 && lj_gc_step(L) == 0) while (steps-- > 0 && lj_gc_step(L) == 0)

View File

@ -536,7 +536,7 @@ typedef struct global_State {
lua_CFunction panic; /* Called as a last resort for errors. */ lua_CFunction panic; /* Called as a last resort for errors. */
BCIns bc_cfunc_int; /* Bytecode for internal C function calls. */ BCIns bc_cfunc_int; /* Bytecode for internal C function calls. */
BCIns bc_cfunc_ext; /* Bytecode for external C function calls. */ BCIns bc_cfunc_ext; /* Bytecode for external C function calls. */
GCRef jit_L; /* Current JIT code lua_State. */ GCRef cur_L; /* Currently executing lua_State. */
MRef jit_base; /* Current JIT code L->base or NULL. */ MRef jit_base; /* Current JIT code L->base or NULL. */
MRef ctype_state; /* Pointer to C type state. */ MRef ctype_state; /* Pointer to C type state. */
GCRef gcroot[GCROOT_MAX]; /* GC roots. */ GCRef gcroot[GCROOT_MAX]; /* GC roots. */

View File

@ -91,7 +91,7 @@ void lj_state_shrinkstack(lua_State *L, MSize used)
if (4*used < L->stacksize && if (4*used < L->stacksize &&
2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize && 2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize &&
/* Don't shrink stack of live trace. */ /* Don't shrink stack of live trace. */
(tvref(G(L)->jit_base) == NULL || obj2gco(L) != gcref(G(L)->jit_L))) (tvref(G(L)->jit_base) == NULL || obj2gco(L) != gcref(G(L)->cur_L)))
resizestack(L, L->stacksize >> 1); resizestack(L, L->stacksize >> 1);
} }
@ -237,6 +237,7 @@ LUA_API void lua_close(lua_State *L)
{ {
global_State *g = G(L); global_State *g = G(L);
int i; int i;
setgcrefnull(g->cur_L);
L = mainthread(g); /* Only the main thread can be closed. */ L = mainthread(g); /* Only the main thread can be closed. */
lj_func_closeuv(L, tvref(L->stack)); lj_func_closeuv(L, tvref(L->stack));
lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */ lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */
@ -248,8 +249,8 @@ LUA_API void lua_close(lua_State *L)
for (i = 0;;) { for (i = 0;;) {
hook_enter(g); hook_enter(g);
L->status = 0; L->status = 0;
L->cframe = NULL;
L->base = L->top = tvref(L->stack) + 1; L->base = L->top = tvref(L->stack) + 1;
L->cframe = NULL;
if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) { if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) {
if (++i >= 10) break; if (++i >= 10) break;
lj_gc_separateudata(g, 1); /* Separate udata again. */ lj_gc_separateudata(g, 1); /* Separate udata again. */
@ -281,6 +282,8 @@ lua_State *lj_state_new(lua_State *L)
void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L) void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L)
{ {
lua_assert(L != mainthread(g)); lua_assert(L != mainthread(g));
if (obj2gco(L) == gcref(g->cur_L))
setgcrefnull(g->cur_L);
lj_func_closeuv(L, tvref(L->stack)); lj_func_closeuv(L, tvref(L->stack));
lua_assert(gcref(L->openupval) == NULL); lua_assert(gcref(L->openupval) == NULL);
lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue); lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue);

View File

@ -419,13 +419,14 @@ static void build_subroutines(BuildCtx *ctx)
| add CARG2, sp, #CFRAME_RESUME | add CARG2, sp, #CFRAME_RESUME
| ldrb CARG1, L->status | ldrb CARG1, L->status
| str CARG3, SAVE_ERRF | str CARG3, SAVE_ERRF
| str CARG2, L->cframe | str L, SAVE_PC // Any value outside of bytecode is ok.
| str CARG3, SAVE_CFRAME | str CARG3, SAVE_CFRAME
| cmp CARG1, #0 | cmp CARG1, #0
| str L, SAVE_PC // Any value outside of bytecode is ok. | str CARG2, L->cframe
| beq >3 | beq >3
| |
| // Resume after yield (like a return). | // Resume after yield (like a return).
| str L, [DISPATCH, #DISPATCH_GL(cur_L)]
| mov RA, BASE | mov RA, BASE
| ldr BASE, L->base | ldr BASE, L->base
| ldr CARG1, L->top | ldr CARG1, L->top
@ -459,14 +460,15 @@ static void build_subroutines(BuildCtx *ctx)
| str CARG3, SAVE_NRES | str CARG3, SAVE_NRES
| mov L, CARG1 | mov L, CARG1
| str CARG1, SAVE_L | str CARG1, SAVE_L
| mov BASE, CARG2
| str sp, L->cframe // Add our C frame to cframe chain.
| ldr DISPATCH, L->glref // Setup pointer to dispatch table. | ldr DISPATCH, L->glref // Setup pointer to dispatch table.
| mov BASE, CARG2
| str CARG1, SAVE_PC // Any value outside of bytecode is ok. | str CARG1, SAVE_PC // Any value outside of bytecode is ok.
| str RC, SAVE_CFRAME | str RC, SAVE_CFRAME
| add DISPATCH, DISPATCH, #GG_G2DISP | add DISPATCH, DISPATCH, #GG_G2DISP
| str sp, L->cframe // Add our C frame to cframe chain.
| |
|3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
| str L, [DISPATCH, #DISPATCH_GL(cur_L)]
| ldr RB, L->base // RB = old base (for vmeta_call). | ldr RB, L->base // RB = old base (for vmeta_call).
| ldr CARG1, L->top | ldr CARG1, L->top
| mov MASKR8, #255 | mov MASKR8, #255
@ -492,20 +494,21 @@ static void build_subroutines(BuildCtx *ctx)
| mov L, CARG1 | mov L, CARG1
| ldr RA, L:CARG1->stack | ldr RA, L:CARG1->stack
| str CARG1, SAVE_L | str CARG1, SAVE_L
| ldr DISPATCH, L->glref // Setup pointer to dispatch table.
| ldr RB, L->top | ldr RB, L->top
| str CARG1, SAVE_PC // Any value outside of bytecode is ok. | str CARG1, SAVE_PC // Any value outside of bytecode is ok.
| ldr RC, L->cframe | ldr RC, L->cframe
| add DISPATCH, DISPATCH, #GG_G2DISP
| sub RA, RA, RB // Compute -savestack(L, L->top). | sub RA, RA, RB // Compute -savestack(L, L->top).
| str sp, L->cframe // Add our C frame to cframe chain.
| mov RB, #0 | mov RB, #0
| str RA, SAVE_NRES // Neg. delta means cframe w/o frame. | str RA, SAVE_NRES // Neg. delta means cframe w/o frame.
| str RB, SAVE_ERRF // No error function. | str RB, SAVE_ERRF // No error function.
| str RC, SAVE_CFRAME | str RC, SAVE_CFRAME
| str sp, L->cframe // Add our C frame to cframe chain.
| str L, [DISPATCH, #DISPATCH_GL(cur_L)]
| blx CARG4 // (lua_State *L, lua_CFunction func, void *ud) | blx CARG4 // (lua_State *L, lua_CFunction func, void *ud)
| ldr DISPATCH, L->glref // Setup pointer to dispatch table.
| movs BASE, CRET1 | movs BASE, CRET1
| mov PC, #FRAME_CP | mov PC, #FRAME_CP
| add DISPATCH, DISPATCH, #GG_G2DISP
| bne <3 // Else continue with the call. | bne <3 // Else continue with the call.
| b ->vm_leave_cp // No base? Just remove C frame. | b ->vm_leave_cp // No base? Just remove C frame.
| |
@ -1262,9 +1265,10 @@ static void build_subroutines(BuildCtx *ctx)
| ldr CARG3, L:RA->base | ldr CARG3, L:RA->base
| mv_vmstate CARG2, INTERP | mv_vmstate CARG2, INTERP
| ldr CARG4, L:RA->top | ldr CARG4, L:RA->top
| st_vmstate CARG2
| cmp CRET1, #LUA_YIELD | cmp CRET1, #LUA_YIELD
| ldr BASE, L->base | ldr BASE, L->base
| str L, [DISPATCH, #DISPATCH_GL(cur_L)]
| st_vmstate CARG2
| bhi >8 | bhi >8
| subs RC, CARG4, CARG3 | subs RC, CARG4, CARG3
| ldr CARG1, L->maxstack | ldr CARG1, L->maxstack
@ -2102,7 +2106,7 @@ static void build_subroutines(BuildCtx *ctx)
| add CARG1, CARG1, CARG2, asr #6 | add CARG1, CARG1, CARG2, asr #6
| ldr CARG2, [lr, #4] // Load exit stub group offset. | ldr CARG2, [lr, #4] // Load exit stub group offset.
| sub CARG1, CARG1, lr | sub CARG1, CARG1, lr
| ldr L, [DISPATCH, #DISPATCH_GL(jit_L)] | ldr L, [DISPATCH, #DISPATCH_GL(cur_L)]
| add CARG1, CARG2, CARG1, lsr #2 // Compute exit number. | add CARG1, CARG2, CARG1, lsr #2 // Compute exit number.
| ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)] | ldr BASE, [DISPATCH, #DISPATCH_GL(jit_base)]
| str CARG1, [DISPATCH, #DISPATCH_J(exitno)] | str CARG1, [DISPATCH, #DISPATCH_J(exitno)]
@ -4285,7 +4289,6 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| st_vmstate CARG2 | st_vmstate CARG2
| ldr RA, TRACE:RC->mcode | ldr RA, TRACE:RC->mcode
| str BASE, [DISPATCH, #DISPATCH_GL(jit_base)] | str BASE, [DISPATCH, #DISPATCH_GL(jit_base)]
| str L, [DISPATCH, #DISPATCH_GL(jit_L)]
| str L, [DISPATCH, #DISPATCH_GL(tmpbuf.L)] | str L, [DISPATCH, #DISPATCH_GL(tmpbuf.L)]
| bx RA | bx RA
|.endif |.endif
@ -4404,6 +4407,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| ldr BASE, L->base | ldr BASE, L->base
| mv_vmstate CARG3, INTERP | mv_vmstate CARG3, INTERP
| ldr CRET2, L->top | ldr CRET2, L->top
| str L, [DISPATCH, #DISPATCH_GL(cur_L)]
| lsl RC, CRET1, #3 | lsl RC, CRET1, #3
| st_vmstate CARG3 | st_vmstate CARG3
| ldr PC, [BASE, FRAME_PC] | ldr PC, [BASE, FRAME_PC]

View File

@ -487,12 +487,13 @@ static void build_subroutines(BuildCtx *ctx)
| addiu DISPATCH, DISPATCH, GG_G2DISP | addiu DISPATCH, DISPATCH, GG_G2DISP
| sw r0, SAVE_NRES | sw r0, SAVE_NRES
| sw r0, SAVE_ERRF | sw r0, SAVE_ERRF
| sw TMP0, L->cframe | sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
| sw r0, SAVE_CFRAME | sw r0, SAVE_CFRAME
| beqz TMP1, >3 | beqz TMP1, >3
|. sw CARG1, SAVE_PC // Any value outside of bytecode is ok. |. sw TMP0, L->cframe
| |
| // Resume after yield (like a return). | // Resume after yield (like a return).
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
| move RA, BASE | move RA, BASE
| lw BASE, L->base | lw BASE, L->base
| lw TMP1, L->top | lw TMP1, L->top
@ -526,17 +527,18 @@ static void build_subroutines(BuildCtx *ctx)
| |
|1: // Entry point for vm_pcall above (PC = ftype). |1: // Entry point for vm_pcall above (PC = ftype).
| lw TMP1, L:CARG1->cframe | lw TMP1, L:CARG1->cframe
| sw CARG3, SAVE_NRES
| move L, CARG1 | move L, CARG1
| sw CARG1, SAVE_L | sw CARG3, SAVE_NRES
| move BASE, CARG2
| sw sp, L->cframe // Add our C frame to cframe chain.
| lw DISPATCH, L->glref // Setup pointer to dispatch table. | lw DISPATCH, L->glref // Setup pointer to dispatch table.
| sw CARG1, SAVE_L
| move BASE, CARG2
| addiu DISPATCH, DISPATCH, GG_G2DISP
| sw CARG1, SAVE_PC // Any value outside of bytecode is ok. | sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
| sw TMP1, SAVE_CFRAME | sw TMP1, SAVE_CFRAME
| addiu DISPATCH, DISPATCH, GG_G2DISP | sw sp, L->cframe // Add our C frame to cframe chain.
| |
|3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
| lw TMP2, L->base // TMP2 = old base (used in vmeta_call). | lw TMP2, L->base // TMP2 = old base (used in vmeta_call).
| lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float). | lui TMP3, 0x59c0 // TOBIT = 2^52 + 2^51 (float).
| lw TMP1, L->top | lw TMP1, L->top
@ -567,20 +569,21 @@ static void build_subroutines(BuildCtx *ctx)
| lw TMP0, L:CARG1->stack | lw TMP0, L:CARG1->stack
| sw CARG1, SAVE_L | sw CARG1, SAVE_L
| lw TMP1, L->top | lw TMP1, L->top
| lw DISPATCH, L->glref // Setup pointer to dispatch table.
| sw CARG1, SAVE_PC // Any value outside of bytecode is ok. | sw CARG1, SAVE_PC // Any value outside of bytecode is ok.
| subu TMP0, TMP0, TMP1 // Compute -savestack(L, L->top). | subu TMP0, TMP0, TMP1 // Compute -savestack(L, L->top).
| lw TMP1, L->cframe | lw TMP1, L->cframe
| sw sp, L->cframe // Add our C frame to cframe chain. | addiu DISPATCH, DISPATCH, GG_G2DISP
| sw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame. | sw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame.
| sw r0, SAVE_ERRF // No error function. | sw r0, SAVE_ERRF // No error function.
| move CFUNCADDR, CARG4 | sw TMP1, SAVE_CFRAME
| sw sp, L->cframe // Add our C frame to cframe chain.
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
| jalr CARG4 // (lua_State *L, lua_CFunction func, void *ud) | jalr CARG4 // (lua_State *L, lua_CFunction func, void *ud)
|. sw TMP1, SAVE_CFRAME |. move CFUNCADDR, CARG4
| move BASE, CRET1 | move BASE, CRET1
| lw DISPATCH, L->glref // Setup pointer to dispatch table.
| li PC, FRAME_CP
| bnez CRET1, <3 // Else continue with the call. | bnez CRET1, <3 // Else continue with the call.
|. addiu DISPATCH, DISPATCH, GG_G2DISP |. li PC, FRAME_CP
| b ->vm_leave_cp // No base? Just remove C frame. | b ->vm_leave_cp // No base? Just remove C frame.
|. nop |. nop
| |
@ -1364,6 +1367,7 @@ static void build_subroutines(BuildCtx *ctx)
| lw TMP3, L:RA->top | lw TMP3, L:RA->top
| li_vmstate INTERP | li_vmstate INTERP
| lw BASE, L->base | lw BASE, L->base
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
| st_vmstate | st_vmstate
| beqz AT, >8 | beqz AT, >8
|. subu RD, TMP3, TMP2 |. subu RD, TMP3, TMP2
@ -2045,7 +2049,7 @@ static void build_subroutines(BuildCtx *ctx)
| lw TMP1, 0(TMP2) // Load exit number. | lw TMP1, 0(TMP2) // Load exit number.
| st_vmstate | st_vmstate
| sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP. | sw TMP2, 16+32*8+29*4(sp) // Store sp in RID_SP.
| lw L, DISPATCH_GL(jit_L)(DISPATCH) | lw L, DISPATCH_GL(cur_L)(DISPATCH)
| lw BASE, DISPATCH_GL(jit_base)(DISPATCH) | lw BASE, DISPATCH_GL(jit_base)(DISPATCH)
| load_got lj_trace_exit | load_got lj_trace_exit
| sw L, DISPATCH_J(L)(DISPATCH) | sw L, DISPATCH_J(L)(DISPATCH)
@ -3980,7 +3984,6 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| sw AT, DISPATCH_GL(vmstate)(DISPATCH) | sw AT, DISPATCH_GL(vmstate)(DISPATCH)
| lw TRACE:TMP2, 0(TMP1) | lw TRACE:TMP2, 0(TMP1)
| sw BASE, DISPATCH_GL(jit_base)(DISPATCH) | sw BASE, DISPATCH_GL(jit_base)(DISPATCH)
| sw L, DISPATCH_GL(jit_L)(DISPATCH)
| lw TMP2, TRACE:TMP2->mcode | lw TMP2, TRACE:TMP2->mcode
| sw L, DISPATCH_GL(tmpbuf.L)(DISPATCH) | sw L, DISPATCH_GL(tmpbuf.L)(DISPATCH)
| jr TMP2 | jr TMP2
@ -4108,6 +4111,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| li_vmstate INTERP | li_vmstate INTERP
| lw PC, FRAME_PC(BASE) // Fetch PC of caller. | lw PC, FRAME_PC(BASE) // Fetch PC of caller.
| subu RA, TMP1, RD // RA = L->top - nresults*8 | subu RA, TMP1, RD // RA = L->top - nresults*8
| sw L, DISPATCH_GL(cur_L)(DISPATCH)
| b ->vm_returnc | b ->vm_returnc
|. st_vmstate |. st_vmstate
break; break;

View File

@ -662,12 +662,13 @@ static void build_subroutines(BuildCtx *ctx)
| stw CARG3, SAVE_NRES | stw CARG3, SAVE_NRES
| cmplwi TMP1, 0 | cmplwi TMP1, 0
| stw CARG3, SAVE_ERRF | stw CARG3, SAVE_ERRF
| stp TMP0, L->cframe
| stp CARG3, SAVE_CFRAME | stp CARG3, SAVE_CFRAME
| stw CARG1, SAVE_PC // Any value outside of bytecode is ok. | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
| stp TMP0, L->cframe
| beq >3 | beq >3
| |
| // Resume after yield (like a return). | // Resume after yield (like a return).
| stw L, DISPATCH_GL(cur_L)(DISPATCH)
| mr RA, BASE | mr RA, BASE
| lp BASE, L->base | lp BASE, L->base
| li TISNUM, LJ_TISNUM // Setup type comparison constants. | li TISNUM, LJ_TISNUM // Setup type comparison constants.
@ -707,17 +708,18 @@ static void build_subroutines(BuildCtx *ctx)
| |
|1: // Entry point for vm_pcall above (PC = ftype). |1: // Entry point for vm_pcall above (PC = ftype).
| lp TMP1, L:CARG1->cframe | lp TMP1, L:CARG1->cframe
| stw CARG3, SAVE_NRES
| mr L, CARG1 | mr L, CARG1
| stw CARG1, SAVE_L | stw CARG3, SAVE_NRES
| mr BASE, CARG2
| stp sp, L->cframe // Add our C frame to cframe chain.
| lwz DISPATCH, L->glref // Setup pointer to dispatch table. | lwz DISPATCH, L->glref // Setup pointer to dispatch table.
| stw CARG1, SAVE_L
| mr BASE, CARG2
| addi DISPATCH, DISPATCH, GG_G2DISP
| stw CARG1, SAVE_PC // Any value outside of bytecode is ok. | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
| stp TMP1, SAVE_CFRAME | stp TMP1, SAVE_CFRAME
| addi DISPATCH, DISPATCH, GG_G2DISP | stp sp, L->cframe // Add our C frame to cframe chain.
| |
|3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype). |3: // Entry point for vm_cpcall/vm_resume (BASE = base, PC = ftype).
| stw L, DISPATCH_GL(cur_L)(DISPATCH)
| lp TMP2, L->base // TMP2 = old base (used in vmeta_call). | lp TMP2, L->base // TMP2 = old base (used in vmeta_call).
| li TISNUM, LJ_TISNUM // Setup type comparison constants. | li TISNUM, LJ_TISNUM // Setup type comparison constants.
| lp TMP1, L->top | lp TMP1, L->top
@ -754,15 +756,18 @@ static void build_subroutines(BuildCtx *ctx)
| lwz TMP0, L:CARG1->stack | lwz TMP0, L:CARG1->stack
| stw CARG1, SAVE_L | stw CARG1, SAVE_L
| lp TMP1, L->top | lp TMP1, L->top
| lwz DISPATCH, L->glref // Setup pointer to dispatch table.
| stw CARG1, SAVE_PC // Any value outside of bytecode is ok. | stw CARG1, SAVE_PC // Any value outside of bytecode is ok.
| sub TMP0, TMP0, TMP1 // Compute -savestack(L, L->top). | sub TMP0, TMP0, TMP1 // Compute -savestack(L, L->top).
| lp TMP1, L->cframe | lp TMP1, L->cframe
| stp sp, L->cframe // Add our C frame to cframe chain. | addi DISPATCH, DISPATCH, GG_G2DISP
| .toc lp CARG4, 0(CARG4) | .toc lp CARG4, 0(CARG4)
| li TMP2, 0 | li TMP2, 0
| stw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame. | stw TMP0, SAVE_NRES // Neg. delta means cframe w/o frame.
| stw TMP2, SAVE_ERRF // No error function. | stw TMP2, SAVE_ERRF // No error function.
| stp TMP1, SAVE_CFRAME | stp TMP1, SAVE_CFRAME
| stp sp, L->cframe // Add our C frame to cframe chain.
| stw L, DISPATCH_GL(cur_L)(DISPATCH)
| mtctr CARG4 | mtctr CARG4
| bctrl // (lua_State *L, lua_CFunction func, void *ud) | bctrl // (lua_State *L, lua_CFunction func, void *ud)
|.if PPE |.if PPE
@ -771,9 +776,7 @@ static void build_subroutines(BuildCtx *ctx)
|.else |.else
| mr. BASE, CRET1 | mr. BASE, CRET1
|.endif |.endif
| lwz DISPATCH, L->glref // Setup pointer to dispatch table. | li PC, FRAME_CP
| li PC, FRAME_CP
| addi DISPATCH, DISPATCH, GG_G2DISP
| bne <3 // Else continue with the call. | bne <3 // Else continue with the call.
| b ->vm_leave_cp // No base? Just remove C frame. | b ->vm_leave_cp // No base? Just remove C frame.
| |
@ -1629,6 +1632,7 @@ static void build_subroutines(BuildCtx *ctx)
| lp TMP3, L:SAVE0->top | lp TMP3, L:SAVE0->top
| li_vmstate INTERP | li_vmstate INTERP
| lp BASE, L->base | lp BASE, L->base
| stw L, DISPATCH_GL(cur_L)(DISPATCH)
| st_vmstate | st_vmstate
| bgt >8 | bgt >8
| sub RD, TMP3, TMP2 | sub RD, TMP3, TMP2
@ -2535,7 +2539,7 @@ static void build_subroutines(BuildCtx *ctx)
| savex_ 20,21,22,23 | savex_ 20,21,22,23
| lhz CARG4, 2(CARG3) // Load trace number. | lhz CARG4, 2(CARG3) // Load trace number.
| savex_ 24,25,26,27 | savex_ 24,25,26,27
| lwz L, DISPATCH_GL(jit_L)(DISPATCH) | lwz L, DISPATCH_GL(cur_L)(DISPATCH)
| savex_ 28,29,30,31 | savex_ 28,29,30,31
| sub CARG3, TMP0, CARG3 // Compute exit number. | sub CARG3, TMP0, CARG3 // Compute exit number.
| lp BASE, DISPATCH_GL(jit_base)(DISPATCH) | lp BASE, DISPATCH_GL(jit_base)(DISPATCH)
@ -4852,7 +4856,6 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| lp TMP2, TRACE:TMP2->mcode | lp TMP2, TRACE:TMP2->mcode
| stw BASE, DISPATCH_GL(jit_base)(DISPATCH) | stw BASE, DISPATCH_GL(jit_base)(DISPATCH)
| mtctr TMP2 | mtctr TMP2
| stw L, DISPATCH_GL(jit_L)(DISPATCH)
| addi JGL, DISPATCH, GG_DISP2G+32768 | addi JGL, DISPATCH, GG_DISP2G+32768
| stw L, DISPATCH_GL(tmpbuf.L)(DISPATCH) | stw L, DISPATCH_GL(tmpbuf.L)(DISPATCH)
| bctr | bctr
@ -4989,6 +4992,7 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| lp TMP1, L->top | lp TMP1, L->top
| li_vmstate INTERP | li_vmstate INTERP
| lwz PC, FRAME_PC(BASE) // Fetch PC of caller. | lwz PC, FRAME_PC(BASE) // Fetch PC of caller.
| stw L, DISPATCH_GL(cur_L)(DISPATCH)
| sub RA, TMP1, RD // RA = L->top - nresults*8 | sub RA, TMP1, RD // RA = L->top - nresults*8
| st_vmstate | st_vmstate
| b ->vm_returnc | b ->vm_returnc

View File

@ -630,17 +630,18 @@ static void build_subroutines(BuildCtx *ctx)
| lea KBASEa, [esp+CFRAME_RESUME] | lea KBASEa, [esp+CFRAME_RESUME]
| mov DISPATCH, L:RB->glref // Setup pointer to dispatch table. | mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
| add DISPATCH, GG_G2DISP | add DISPATCH, GG_G2DISP
| mov L:RB->cframe, KBASEa
| mov SAVE_PC, RD // Any value outside of bytecode is ok. | mov SAVE_PC, RD // Any value outside of bytecode is ok.
| mov SAVE_CFRAME, RDa | mov SAVE_CFRAME, RDa
|.if X64 |.if X64
| mov SAVE_NRES, RD | mov SAVE_NRES, RD
| mov SAVE_ERRF, RD | mov SAVE_ERRF, RD
|.endif |.endif
| mov L:RB->cframe, KBASEa
| cmp byte L:RB->status, RDL | cmp byte L:RB->status, RDL
| je >3 // Initial resume (like a call). | je >2 // Initial resume (like a call).
| |
| // Resume after yield (like a return). | // Resume after yield (like a return).
| mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
| set_vmstate INTERP | set_vmstate INTERP
| mov byte L:RB->status, RDL | mov byte L:RB->status, RDL
| mov BASE, L:RB->base | mov BASE, L:RB->base
@ -680,20 +681,19 @@ static void build_subroutines(BuildCtx *ctx)
| mov RA, INARG_BASE // Caveat: overlaps SAVE_CFRAME! | mov RA, INARG_BASE // Caveat: overlaps SAVE_CFRAME!
|.endif |.endif
| |
| mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
| mov KBASEa, L:RB->cframe // Add our C frame to cframe chain. | mov KBASEa, L:RB->cframe // Add our C frame to cframe chain.
| mov SAVE_CFRAME, KBASEa | mov SAVE_CFRAME, KBASEa
| mov SAVE_PC, L:RB // Any value outside of bytecode is ok. | mov SAVE_PC, L:RB // Any value outside of bytecode is ok.
| add DISPATCH, GG_G2DISP
|.if X64 |.if X64
| mov L:RB->cframe, rsp | mov L:RB->cframe, rsp
|.else |.else
| mov L:RB->cframe, esp | mov L:RB->cframe, esp
|.endif |.endif
| |
|2: // Entry point for vm_cpcall below (RA = base, RB = L, PC = ftype). |2: // Entry point for vm_resume/vm_cpcall (RA = base, RB = L, PC = ftype).
| mov DISPATCH, L:RB->glref // Setup pointer to dispatch table. | mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
| add DISPATCH, GG_G2DISP
|
|3: // Entry point for vm_resume above (RA = base, RB = L, PC = ftype).
| set_vmstate INTERP | set_vmstate INTERP
| mov BASE, L:RB->base // BASE = old base (used in vmeta_call). | mov BASE, L:RB->base // BASE = old base (used in vmeta_call).
| add PC, RA | add PC, RA
@ -731,14 +731,17 @@ static void build_subroutines(BuildCtx *ctx)
| |
| mov KBASE, L:RB->stack // Compute -savestack(L, L->top). | mov KBASE, L:RB->stack // Compute -savestack(L, L->top).
| sub KBASE, L:RB->top | sub KBASE, L:RB->top
| mov DISPATCH, L:RB->glref // Setup pointer to dispatch table.
| mov SAVE_ERRF, 0 // No error function. | mov SAVE_ERRF, 0 // No error function.
| mov SAVE_NRES, KBASE // Neg. delta means cframe w/o frame. | mov SAVE_NRES, KBASE // Neg. delta means cframe w/o frame.
| add DISPATCH, GG_G2DISP
| // Handler may change cframe_nres(L->cframe) or cframe_errfunc(L->cframe). | // Handler may change cframe_nres(L->cframe) or cframe_errfunc(L->cframe).
| |
|.if X64 |.if X64
| mov KBASEa, L:RB->cframe // Add our C frame to cframe chain. | mov KBASEa, L:RB->cframe // Add our C frame to cframe chain.
| mov SAVE_CFRAME, KBASEa | mov SAVE_CFRAME, KBASEa
| mov L:RB->cframe, rsp | mov L:RB->cframe, rsp
| mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
| |
| call CARG4 // (lua_State *L, lua_CFunction func, void *ud) | call CARG4 // (lua_State *L, lua_CFunction func, void *ud)
|.else |.else
@ -749,6 +752,7 @@ static void build_subroutines(BuildCtx *ctx)
| mov KBASE, L:RB->cframe // Add our C frame to cframe chain. | mov KBASE, L:RB->cframe // Add our C frame to cframe chain.
| mov SAVE_CFRAME, KBASE | mov SAVE_CFRAME, KBASE
| mov L:RB->cframe, esp | mov L:RB->cframe, esp
| mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
| |
| call BASE // (lua_State *L, lua_CFunction func, void *ud) | call BASE // (lua_State *L, lua_CFunction func, void *ud)
|.endif |.endif
@ -1840,7 +1844,6 @@ static void build_subroutines(BuildCtx *ctx)
| mov ARG3, RA | mov ARG3, RA
|.endif |.endif
| call ->vm_resume // (lua_State *L, TValue *base, 0, 0) | call ->vm_resume // (lua_State *L, TValue *base, 0, 0)
| set_vmstate INTERP
| |
| mov L:RB, SAVE_L | mov L:RB, SAVE_L
|.if X64 |.if X64
@ -1849,6 +1852,9 @@ static void build_subroutines(BuildCtx *ctx)
| mov L:PC, ARG1 // The callee doesn't modify SAVE_L. | mov L:PC, ARG1 // The callee doesn't modify SAVE_L.
|.endif |.endif
| mov BASE, L:RB->base | mov BASE, L:RB->base
| mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
| set_vmstate INTERP
|
| cmp eax, LUA_YIELD | cmp eax, LUA_YIELD
| ja >8 | ja >8
|4: |4:
@ -2705,7 +2711,7 @@ static void build_subroutines(BuildCtx *ctx)
| movsd qword [ebp-88], xmm1; movsd qword [ebp-96], xmm0 | movsd qword [ebp-88], xmm1; movsd qword [ebp-96], xmm0
|.endif |.endif
| // Caveat: RB is ebp. | // Caveat: RB is ebp.
| mov L:RB, [DISPATCH+DISPATCH_GL(jit_L)] | mov L:RB, [DISPATCH+DISPATCH_GL(cur_L)]
| mov BASE, [DISPATCH+DISPATCH_GL(jit_base)] | mov BASE, [DISPATCH+DISPATCH_GL(jit_base)]
| mov aword [DISPATCH+DISPATCH_J(L)], L:RBa | mov aword [DISPATCH+DISPATCH_J(L)], L:RBa
| mov L:RB->base, BASE | mov L:RB->base, BASE
@ -5382,7 +5388,6 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| mov RDa, TRACE:RD->mcode | mov RDa, TRACE:RD->mcode
| mov L:RB, SAVE_L | mov L:RB, SAVE_L
| mov [DISPATCH+DISPATCH_GL(jit_base)], BASE | mov [DISPATCH+DISPATCH_GL(jit_base)], BASE
| mov [DISPATCH+DISPATCH_GL(jit_L)], L:RB
| mov [DISPATCH+DISPATCH_GL(tmpbuf.L)], L:RB | mov [DISPATCH+DISPATCH_GL(tmpbuf.L)], L:RB
| // Save additional callee-save registers only used in compiled code. | // Save additional callee-save registers only used in compiled code.
|.if X64WIN |.if X64WIN
@ -5550,9 +5555,10 @@ static void build_ins(BuildCtx *ctx, BCOp op, int defop)
| // (lua_State *L, lua_CFunction f) | // (lua_State *L, lua_CFunction f)
| call aword [DISPATCH+DISPATCH_GL(wrapf)] | call aword [DISPATCH+DISPATCH_GL(wrapf)]
} }
| set_vmstate INTERP
| // nresults returned in eax (RD). | // nresults returned in eax (RD).
| mov BASE, L:RB->base | mov BASE, L:RB->base
| mov [DISPATCH+DISPATCH_GL(cur_L)], L:RB
| set_vmstate INTERP
| lea RA, [BASE+RD*8] | lea RA, [BASE+RD*8]
| neg RA | neg RA
| add RA, L:RB->top // RA = (L->top-(L->base+nresults))*8 | add RA, L:RB->top // RA = (L->top-(L->base+nresults))*8