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 /src | |
| 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.
Diffstat (limited to 'src')
| -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); |
