Browse Source

Merge branch 'master' into v2.1

Mike Pall 12 years ago
parent
commit
ac14d88030
4 changed files with 33 additions and 8 deletions
  1. 28 2
      src/lj_asm.c
  2. 1 0
      src/lj_asm_mips.h
  3. 1 0
      src/lj_asm_ppc.h
  4. 3 6
      src/lj_asm_x86.h

+ 28 - 2
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 ====="));

+ 1 - 0
src/lj_asm_mips.h

@@ -283,6 +283,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
       else
 	ofs += 4;
     }
+    checkmclim(as);
   }
 }
 

+ 1 - 0
src/lj_asm_ppc.h

@@ -286,6 +286,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
       else
 	ofs += 4;
     }
+    checkmclim(as);
   }
   if ((ci->flags & CCI_VARARG))  /* Vararg calls need to know about FPR use. */
     emit_tab(as, fpr == REGARG_FIRSTFPR ? PPCI_CRXOR : PPCI_CREQV, 6, 6, 6);

+ 3 - 6
src/lj_asm_x86.h

@@ -512,6 +512,7 @@ static void asm_gencall(ASMState *as, const CCallInfo *ci, IRRef *args)
       }
       ofs += sizeof(intptr_t);
     }
+    checkmclim(as);
   }
 #if LJ_64 && !LJ_ABI_WIN
   if (patchnfpr) *patchnfpr = fpr - REGARG_FIRSTFPR;
@@ -2203,6 +2204,7 @@ static void asm_comp_int64(ASMState *as, IRIns *ir)
     lefthi = asm_fuseload(as, ir->op1, allow);
   } else {
     lefthi = ra_alloc1(as, ir->op1, allow);
+    rset_clear(allow, lefthi);
     righthi = asm_fuseload(as, ir->op2, allow);
     if (righthi == RID_MRM) {
       if (as->mrm.base != RID_NONE) rset_clear(allow, as->mrm.base);
@@ -2218,13 +2220,8 @@ static void asm_comp_int64(ASMState *as, IRIns *ir)
     leftlo = asm_fuseload(as, (ir-1)->op1, allow);
   } else {
     leftlo = ra_alloc1(as, (ir-1)->op1, allow);
+    rset_clear(allow, leftlo);
     rightlo = asm_fuseload(as, (ir-1)->op2, allow);
-    if (rightlo == RID_MRM) {
-      if (as->mrm.base != RID_NONE) rset_clear(allow, as->mrm.base);
-      if (as->mrm.idx != RID_NONE) rset_clear(allow, as->mrm.idx);
-    } else {
-      rset_clear(allow, rightlo);
-    }
   }
 
   /* All register allocations must be performed _before_ this point. */