summaryrefslogtreecommitdiff
path: root/src/lj_asm.c
diff options
context:
space:
mode:
authorMike Pall <mike>2013-04-04 17:19:31 +0200
committerMike Pall <mike>2013-04-04 17:19:31 +0200
commit389822d606045a953bd30e14ebc50ff97bce8a59 (patch)
treeec1fa02d2e0697737ef5f8cb87f619faf1d2e163 /src/lj_asm.c
parent6ba65cefb0652d340f1729ce8d114cb3681e914a (diff)
downloadluajit2-389822d606045a953bd30e14ebc50ff97bce8a59.tar.gz
Fix spurious red zone overflows in machine code generation.
Diffstat (limited to 'src/lj_asm.c')
-rw-r--r--src/lj_asm.c30
1 files changed, 28 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 @@
#include "lj_vm.h"
#include "lj_target.h"
+#ifdef LUA_USE_ASSERT
+#include <stdio.h>
+#endif
+
/* -- Assembler state and common macros ----------------------------------- */
/* Assembler state. */
@@ -38,6 +42,9 @@ typedef struct ASMState {
MCode *mcp; /* Current MCode pointer (grows down). */
MCode *mclim; /* Lower limit for MCode memory + red zone. */
+#ifdef LUA_USE_ASSERT
+ MCode *mcp_prev; /* Red zone overflow check. */
+#endif
IRIns *ir; /* Copy of pointer to IR instructions/constants. */
jit_State *J; /* JIT compiler state. */
@@ -110,14 +117,28 @@ typedef struct ASMState {
/* Sparse limit checks using a red zone before the actual limit. */
#define MCLIM_REDZONE 64
-#define checkmclim(as) \
- if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as)
static LJ_NORET LJ_NOINLINE void asm_mclimit(ASMState *as)
{
lj_mcode_limiterr(as->J, (size_t)(as->mctop - as->mcp + 4*MCLIM_REDZONE));
}
+static LJ_AINLINE void checkmclim(ASMState *as)
+{
+#ifdef LUA_USE_ASSERT
+ if (as->mcp + MCLIM_REDZONE < as->mcp_prev) {
+ IRIns *ir = IR(as->curins+1);
+ fprintf(stderr, "RED ZONE OVERFLOW: %p IR %04d %02d %04d %04d\n", as->mcp,
+ as->curins+1-REF_BIAS, ir->o, ir->op1-REF_BIAS, ir->op2-REF_BIAS);
+ lua_assert(0);
+ }
+#endif
+ if (LJ_UNLIKELY(as->mcp < as->mclim)) asm_mclimit(as);
+#ifdef LUA_USE_ASSERT
+ as->mcp_prev = as->mcp;
+#endif
+}
+
#ifdef RID_NUM_KREF
#define ra_iskref(ref) ((ref) < RID_NUM_KREF)
#define ra_krefreg(ref) ((Reg)(RID_MIN_KREF + (Reg)(ref)))
@@ -1181,6 +1202,7 @@ static void asm_phi_copyspill(ASMState *as)
if (ra_hasspill(irl->s) && !irt_isfp(ir->t)) {
emit_spstore(as, irl, r, sps_scale(irl->s));
emit_spload(as, ir, r, sps_scale(ir->s));
+ checkmclim(as);
}
}
}
@@ -1206,6 +1228,7 @@ static void asm_phi_copyspill(ASMState *as)
if (ra_hasspill(irl->s) && irt_isfp(ir->t)) {
emit_spstore(as, irl, r, sps_scale(irl->s));
emit_spload(as, ir, r, sps_scale(ir->s));
+ checkmclim(as);
}
}
}
@@ -1822,6 +1845,9 @@ void lj_asm_trace(jit_State *J, GCtrace *T)
do {
as->mcp = as->mctop;
+#ifdef LUA_USE_ASSERT
+ as->mcp_prev = as->mcp;
+#endif
as->curins = T->nins;
RA_DBG_START();
RA_DBGX((as, "===== STOP ====="));