diff options
author | Mike Pall <mike> | 2011-10-24 16:02:37 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2011-10-24 16:11:38 +0200 |
commit | a0d782755482483c09e919a51c396322dd228bf2 (patch) | |
tree | bf599dfa722e463593f44f9f8647fb75b4618381 | |
parent | 84683405fbacad0938a953d9654bec27ac75d565 (diff) | |
download | luajit-a0d782755482483c09e919a51c396322dd228bf2.tar.gz luajit-a0d782755482483c09e919a51c396322dd228bf2.tar.bz2 luajit-a0d782755482483c09e919a51c396322dd228bf2.zip |
Generalize handling of stack checks indicated by highest exit + 1.
-rw-r--r-- | src/lj_asm.c | 10 | ||||
-rw-r--r-- | src/lj_asm_arm.h | 1 | ||||
-rw-r--r-- | src/lj_target_arm.h | 2 | ||||
-rw-r--r-- | src/lj_trace.c | 21 |
4 files changed, 22 insertions, 12 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index c795b99e..bb134ac2 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -1357,9 +1357,15 @@ static void asm_head_side(ASMState *as) | |||
1357 | /* Inherit top stack slot already checked by parent trace. */ | 1357 | /* Inherit top stack slot already checked by parent trace. */ |
1358 | as->T->topslot = as->parent->topslot; | 1358 | as->T->topslot = as->parent->topslot; |
1359 | if (as->topslot > as->T->topslot) { /* Need to check for higher slot? */ | 1359 | if (as->topslot > as->T->topslot) { /* Need to check for higher slot? */ |
1360 | as->T->topslot = (uint8_t)as->topslot; /* Remember for child traces. */ | 1360 | #ifdef EXITSTATE_CHECKEXIT |
1361 | /* Highest exit + 1 indicates stack check. */ | ||
1362 | ExitNo exitno = as->T->nsnap; | ||
1363 | #else | ||
1361 | /* Reuse the parent exit in the context of the parent trace. */ | 1364 | /* Reuse the parent exit in the context of the parent trace. */ |
1362 | asm_stack_check(as, as->topslot, irp, allow & RSET_GPR, as->J->exitno); | 1365 | ExitNo exitno = as->J->exitno; |
1366 | #endif | ||
1367 | as->T->topslot = (uint8_t)as->topslot; /* Remember for child traces. */ | ||
1368 | asm_stack_check(as, as->topslot, irp, allow & RSET_GPR, exitno); | ||
1363 | } | 1369 | } |
1364 | } | 1370 | } |
1365 | 1371 | ||
diff --git a/src/lj_asm_arm.h b/src/lj_asm_arm.h index 27f1d6c1..786dd831 100644 --- a/src/lj_asm_arm.h +++ b/src/lj_asm_arm.h | |||
@@ -1418,7 +1418,6 @@ static void asm_stack_check(ASMState *as, BCReg topslot, | |||
1418 | Reg pbase; | 1418 | Reg pbase; |
1419 | uint32_t k; | 1419 | uint32_t k; |
1420 | if (irp) { | 1420 | if (irp) { |
1421 | exitno = as->T->nsnap; /* Highest exit + 1 indicates stack check. */ | ||
1422 | if (ra_hasreg(irp->r)) { | 1421 | if (ra_hasreg(irp->r)) { |
1423 | pbase = irp->r; | 1422 | pbase = irp->r; |
1424 | } else if (allow) { | 1423 | } else if (allow) { |
diff --git a/src/lj_target_arm.h b/src/lj_target_arm.h index 210fe497..0f50cf9c 100644 --- a/src/lj_target_arm.h +++ b/src/lj_target_arm.h | |||
@@ -117,6 +117,8 @@ typedef struct { | |||
117 | 117 | ||
118 | /* PC after instruction that caused an exit. Used to find the trace number. */ | 118 | /* PC after instruction that caused an exit. Used to find the trace number. */ |
119 | #define EXITSTATE_PCREG RID_PC | 119 | #define EXITSTATE_PCREG RID_PC |
120 | /* Highest exit + 1 indicates stack check. */ | ||
121 | #define EXITSTATE_CHECKEXIT 1 | ||
120 | 122 | ||
121 | #define EXITSTUB_SPACING 4 | 123 | #define EXITSTUB_SPACING 4 |
122 | #define EXITSTUBS_PER_GROUP 32 | 124 | #define EXITSTUBS_PER_GROUP 32 |
diff --git a/src/lj_trace.c b/src/lj_trace.c index f907a77f..9645ecba 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
@@ -727,14 +727,8 @@ static TraceNo trace_exit_find(jit_State *J, MCode *pc) | |||
727 | TraceNo traceno; | 727 | TraceNo traceno; |
728 | for (traceno = 1; traceno < J->sizetrace; traceno++) { | 728 | for (traceno = 1; traceno < J->sizetrace; traceno++) { |
729 | GCtrace *T = traceref(J, traceno); | 729 | GCtrace *T = traceref(J, traceno); |
730 | if (T && pc >= T->mcode && pc < (MCode *)((char *)T->mcode + T->szmcode)) { | 730 | if (T && pc >= T->mcode && pc < (MCode *)((char *)T->mcode + T->szmcode)) |
731 | if (J->exitno == T->nsnap) { /* Treat stack check like a parent exit. */ | ||
732 | lua_assert(T->root != 0); | ||
733 | traceno = T->ir[REF_BASE].op1; | ||
734 | J->exitno = T->ir[REF_BASE].op2; | ||
735 | } | ||
736 | return traceno; | 731 | return traceno; |
737 | } | ||
738 | } | 732 | } |
739 | lua_assert(0); | 733 | lua_assert(0); |
740 | return 0; | 734 | return 0; |
@@ -751,11 +745,20 @@ int LJ_FASTCALL lj_trace_exit(jit_State *J, void *exptr) | |||
751 | int errcode; | 745 | int errcode; |
752 | const BCIns *pc; | 746 | const BCIns *pc; |
753 | void *cf; | 747 | void *cf; |
748 | GCtrace *T; | ||
754 | #ifdef EXITSTATE_PCREG | 749 | #ifdef EXITSTATE_PCREG |
755 | J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]); | 750 | J->parent = trace_exit_find(J, (MCode *)(intptr_t)ex->gpr[EXITSTATE_PCREG]); |
756 | #endif | 751 | #endif |
757 | lua_assert(traceref(J, J->parent) != NULL && | 752 | T = traceref(J, J->parent); UNUSED(T); |
758 | J->exitno < traceref(J, J->parent)->nsnap); | 753 | #ifdef EXITSTATE_CHECKEXIT |
754 | if (J->exitno == T->nsnap) { /* Treat stack check like a parent exit. */ | ||
755 | lua_assert(T->root != 0); | ||
756 | J->exitno = T->ir[REF_BASE].op2; | ||
757 | J->parent = T->ir[REF_BASE].op1; | ||
758 | T = traceref(J, J->parent); | ||
759 | } | ||
760 | #endif | ||
761 | lua_assert(T != NULL && J->exitno < T->nsnap); | ||
759 | exd.J = J; | 762 | exd.J = J; |
760 | exd.exptr = exptr; | 763 | exd.exptr = exptr; |
761 | errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp); | 764 | errcode = lj_vm_cpcall(L, NULL, &exd, trace_exit_cp); |