diff options
-rw-r--r-- | src/lj_asm.c | 30 | ||||
-rw-r--r-- | src/lj_asm_mips.h | 1 | ||||
-rw-r--r-- | src/lj_asm_ppc.h | 1 | ||||
-rw-r--r-- | src/lj_asm_x86.h | 1 |
4 files changed, 31 insertions, 2 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index c7365404..038f4d1c 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -30,6 +30,10 @@ | |||
30 | #include "lj_vm.h" | 30 | #include "lj_vm.h" |
31 | #include "lj_target.h" | 31 | #include "lj_target.h" |
32 | 32 | ||
33 | #ifdef LUA_USE_ASSERT | ||
34 | #include <stdio.h> | ||
35 | #endif | ||
36 | |||
33 | /* -- Assembler state and common macros ----------------------------------- */ | 37 | /* -- Assembler state and common macros ----------------------------------- */ |
34 | 38 | ||
35 | /* Assembler state. */ | 39 | /* Assembler state. */ |
@@ -38,6 +42,9 @@ typedef struct ASMState { | |||
38 | 42 | ||
39 | MCode *mcp; /* Current MCode pointer (grows down). */ | 43 | MCode *mcp; /* Current MCode pointer (grows down). */ |
40 | MCode *mclim; /* Lower limit for MCode memory + red zone. */ | 44 | MCode *mclim; /* Lower limit for MCode memory + red zone. */ |
45 | #ifdef LUA_USE_ASSERT | ||
46 | MCode *mcp_prev; /* Red zone overflow check. */ | ||
47 | #endif | ||
41 | 48 | ||
42 | IRIns *ir; /* Copy of pointer to IR instructions/constants. */ | 49 | IRIns *ir; /* Copy of pointer to IR instructions/constants. */ |
43 | jit_State *J; /* JIT compiler state. */ | 50 | jit_State *J; /* JIT compiler state. */ |
@@ -110,14 +117,28 @@ typedef struct ASMState { | |||
110 | 117 | ||
111 | /* Sparse limit checks using a red zone before the actual limit. */ | 118 | /* Sparse limit checks using a red zone before the actual limit. */ |
112 | #define MCLIM_REDZONE 64 | 119 | #define MCLIM_REDZONE 64 |
113 | #define checkmclim(as) \ | ||
114 | if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as) | ||
115 | 120 | ||
116 | static LJ_NORET LJ_NOINLINE void asm_mclimit(ASMState *as) | 121 | static LJ_NORET LJ_NOINLINE void asm_mclimit(ASMState *as) |
117 | { | 122 | { |
118 | lj_mcode_limiterr(as->J, (size_t)(as->mctop - as->mcp + 4*MCLIM_REDZONE)); | 123 | lj_mcode_limiterr(as->J, (size_t)(as->mctop - as->mcp + 4*MCLIM_REDZONE)); |
119 | } | 124 | } |
120 | 125 | ||
126 | static LJ_AINLINE void checkmclim(ASMState *as) | ||
127 | { | ||
128 | #ifdef LUA_USE_ASSERT | ||
129 | if (as->mcp + MCLIM_REDZONE < as->mcp_prev) { | ||
130 | IRIns *ir = IR(as->curins+1); | ||
131 | fprintf(stderr, "RED ZONE OVERFLOW: %p IR %04d %02d %04d %04d\n", as->mcp, | ||
132 | as->curins+1-REF_BIAS, ir->o, ir->op1-REF_BIAS, ir->op2-REF_BIAS); | ||
133 | lua_assert(0); | ||
134 | } | ||
135 | #endif | ||
136 | if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as); | ||
137 | #ifdef LUA_USE_ASSERT | ||
138 | as->mcp_prev = as->mcp; | ||
139 | #endif | ||
140 | } | ||
141 | |||
121 | #ifdef RID_NUM_KREF | 142 | #ifdef RID_NUM_KREF |
122 | #define ra_iskref(ref) ((ref) < RID_NUM_KREF) | 143 | #define ra_iskref(ref) ((ref) < RID_NUM_KREF) |
123 | #define ra_krefreg(ref) ((Reg)(RID_MIN_KREF + (Reg)(ref))) | 144 | #define ra_krefreg(ref) ((Reg)(RID_MIN_KREF + (Reg)(ref))) |
@@ -1181,6 +1202,7 @@ static void asm_phi_copyspill(ASMState *as) | |||
1181 | if (ra_hasspill(irl->s) && !irt_isfp(ir->t)) { | 1202 | if (ra_hasspill(irl->s) && !irt_isfp(ir->t)) { |
1182 | emit_spstore(as, irl, r, sps_scale(irl->s)); | 1203 | emit_spstore(as, irl, r, sps_scale(irl->s)); |
1183 | emit_spload(as, ir, r, sps_scale(ir->s)); | 1204 | emit_spload(as, ir, r, sps_scale(ir->s)); |
1205 | checkmclim(as); | ||
1184 | } | 1206 | } |
1185 | } | 1207 | } |
1186 | } | 1208 | } |
@@ -1206,6 +1228,7 @@ static void asm_phi_copyspill(ASMState *as) | |||
1206 | if (ra_hasspill(irl->s) && irt_isfp(ir->t)) { | 1228 | if (ra_hasspill(irl->s) && irt_isfp(ir->t)) { |
1207 | emit_spstore(as, irl, r, sps_scale(irl->s)); | 1229 | emit_spstore(as, irl, r, sps_scale(irl->s)); |
1208 | emit_spload(as, ir, r, sps_scale(ir->s)); | 1230 | emit_spload(as, ir, r, sps_scale(ir->s)); |
1231 | checkmclim(as); | ||
1209 | } | 1232 | } |
1210 | } | 1233 | } |
1211 | } | 1234 | } |
@@ -1822,6 +1845,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T) | |||
1822 | 1845 | ||
1823 | do { | 1846 | do { |
1824 | as->mcp = as->mctop; | 1847 | as->mcp = as->mctop; |
1848 | #ifdef LUA_USE_ASSERT | ||
1849 | as->mcp_prev = as->mcp; | ||
1850 | #endif | ||
1825 | as->curins = T->nins; | 1851 | as->curins = T->nins; |
1826 | RA_DBG_START(); | 1852 | RA_DBG_START(); |
1827 | RA_DBGX((as, "===== STOP =====")); | 1853 | RA_DBGX((as, "===== STOP =====")); |
diff --git a/src/lj_asm_mips.h b/src/lj_asm_mips.h index e80f7582..7d1a8c68 100644 --- a/src/lj_asm_mips.h +++ b/src/lj_asm_mips.h | |||
@@ -283,6 +283,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
283 | else | 283 | else |
284 | ofs += 4; | 284 | ofs += 4; |
285 | } | 285 | } |
286 | checkmclim(as); | ||
286 | } | 287 | } |
287 | } | 288 | } |
288 | 289 | ||
diff --git a/src/lj_asm_ppc.h b/src/lj_asm_ppc.h index 7637f6a6..34bd721f 100644 --- a/src/lj_asm_ppc.h +++ b/src/lj_asm_ppc.h | |||
@@ -286,6 +286,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
286 | else | 286 | else |
287 | ofs += 4; | 287 | ofs += 4; |
288 | } | 288 | } |
289 | checkmclim(as); | ||
289 | } | 290 | } |
290 | if ((ci->flags & CCI_VARARG)) /* Vararg calls need to know about FPR use. */ | 291 | if ((ci->flags & CCI_VARARG)) /* Vararg calls need to know about FPR use. */ |
291 | emit_tab(as, fpr == REGARG_FIRSTFPR ? PPCI_CRXOR : PPCI_CREQV, 6, 6, 6); | 292 | emit_tab(as, fpr == REGARG_FIRSTFPR ? PPCI_CRXOR : PPCI_CREQV, 6, 6, 6); |
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 28aa2791..8bae1789 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
@@ -512,6 +512,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args) | |||
512 | } | 512 | } |
513 | ofs += sizeof(intptr_t); | 513 | ofs += sizeof(intptr_t); |
514 | } | 514 | } |
515 | checkmclim(as); | ||
515 | } | 516 | } |
516 | #if LJ_64 && !LJ_ABI_WIN | 517 | #if LJ_64 && !LJ_ABI_WIN |
517 | if (patchnfpr) *patchnfpr = fpr - REGARG_FIRSTFPR; | 518 | if (patchnfpr) *patchnfpr = fpr - REGARG_FIRSTFPR; |