aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-01-19 16:58:26 +0100
committerMike Pall <mike>2010-01-19 16:58:26 +0100
commita61df8efbe5bbe3726d65ad0800a3106ed3a8bf0 (patch)
treedb27cf4dc668742db0c60509fe339c56cf8bf2f5 /src
parent36769c2f6b78e0802cc7cd86f6da301cd7a171fe (diff)
downloadluajit-a61df8efbe5bbe3726d65ad0800a3106ed3a8bf0.tar.gz
luajit-a61df8efbe5bbe3726d65ad0800a3106ed3a8bf0.tar.bz2
luajit-a61df8efbe5bbe3726d65ad0800a3106ed3a8bf0.zip
Decouple guard vs. INT check vs. TYPECHECK semantics for SLOAD.
Diffstat (limited to 'src')
-rw-r--r--src/lj_asm.c6
-rw-r--r--src/lj_ir.h1
-rw-r--r--src/lj_record.c14
3 files changed, 14 insertions, 7 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c
index 6d42cf35..eeb6aeb4 100644
--- a/src/lj_asm.c
+++ b/src/lj_asm.c
@@ -1852,6 +1852,8 @@ static void asm_sload(ASMState *as, IRIns *ir)
1852 IRType1 t = ir->t; 1852 IRType1 t = ir->t;
1853 Reg base; 1853 Reg base;
1854 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */ 1854 lua_assert(!(ir->op2 & IRSLOAD_PARENT)); /* Handled by asm_head_side(). */
1855 lua_assert(!irt_isguard(ir->t) ==
1856 !((ir->op2 & IRSLOAD_TYPECHECK) || irt_isint(t)));
1855 if (irt_isint(t)) { 1857 if (irt_isint(t)) {
1856 Reg left = ra_scratch(as, RSET_FPR); 1858 Reg left = ra_scratch(as, RSET_FPR);
1857 asm_tointg(as, ir, left); /* Frees dest reg. Do this before base alloc. */ 1859 asm_tointg(as, ir, left); /* Frees dest reg. Do this before base alloc. */
@@ -1865,11 +1867,11 @@ static void asm_sload(ASMState *as, IRIns *ir)
1865 base = ra_alloc1(as, REF_BASE, RSET_GPR); 1867 base = ra_alloc1(as, REF_BASE, RSET_GPR);
1866 emit_movrmro(as, dest, base, ofs); 1868 emit_movrmro(as, dest, base, ofs);
1867 } else { 1869 } else {
1868 if (!irt_isguard(ir->t)) 1870 if (!(ir->op2 & IRSLOAD_TYPECHECK))
1869 return; /* No type check: avoid base alloc. */ 1871 return; /* No type check: avoid base alloc. */
1870 base = ra_alloc1(as, REF_BASE, RSET_GPR); 1872 base = ra_alloc1(as, REF_BASE, RSET_GPR);
1871 } 1873 }
1872 if (irt_isguard(ir->t)) { 1874 if ((ir->op2 & IRSLOAD_TYPECHECK)) {
1873 /* Need type check, even if the load result is unused. */ 1875 /* Need type check, even if the load result is unused. */
1874 asm_guardcc(as, irt_isnum(t) ? CC_A : CC_NE); 1876 asm_guardcc(as, irt_isnum(t) ? CC_A : CC_NE);
1875 emit_i8(as, ~irt_type(t)); 1877 emit_i8(as, ~irt_type(t));
diff --git a/src/lj_ir.h b/src/lj_ir.h
index f73dcc40..efc8205e 100644
--- a/src/lj_ir.h
+++ b/src/lj_ir.h
@@ -192,6 +192,7 @@ IRFLDEF(FLENUM)
192#define IRSLOAD_INHERIT 1 /* Inherited by exits/side traces. */ 192#define IRSLOAD_INHERIT 1 /* Inherited by exits/side traces. */
193#define IRSLOAD_READONLY 2 /* Read-only, omit slot store. */ 193#define IRSLOAD_READONLY 2 /* Read-only, omit slot store. */
194#define IRSLOAD_PARENT 4 /* Coalesce with parent trace. */ 194#define IRSLOAD_PARENT 4 /* Coalesce with parent trace. */
195#define IRSLOAD_TYPECHECK 8 /* Needs type check. */
195 196
196/* XLOAD mode, stored in op2. */ 197/* XLOAD mode, stored in op2. */
197#define IRXLOAD_READONLY 1 /* Load from read-only data. */ 198#define IRXLOAD_READONLY 1 /* Load from read-only data. */
diff --git a/src/lj_record.c b/src/lj_record.c
index 950f4d82..5085d735 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -125,7 +125,7 @@ static void rec_check_slots(jit_State *J)
125/* Specialize a slot to a specific type. Note: slot can be negative! */ 125/* Specialize a slot to a specific type. Note: slot can be negative! */
126static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode) 126static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
127{ 127{
128 /* No guard, since none of the callers need a type-checking SLOAD. */ 128 /* Caller may set IRT_GUARD in t. */
129 TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode); 129 TRef ref = emitir_raw(IRT(IR_SLOAD, t), (int32_t)J->baseslot+slot, mode);
130 J->base[slot] = ref; 130 J->base[slot] = ref;
131 return ref; 131 return ref;
@@ -135,7 +135,8 @@ static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode)
135static TRef sload(jit_State *J, int32_t slot) 135static TRef sload(jit_State *J, int32_t slot)
136{ 136{
137 IRType t = itype2irt(&J->L->base[slot]); 137 IRType t = itype2irt(&J->L->base[slot]);
138 TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot, 0); 138 TRef ref = emitir_raw(IRTG(IR_SLOAD, t), (int32_t)J->baseslot+slot,
139 IRSLOAD_TYPECHECK);
139 if (irtype_ispri(t)) ref = TREF_PRI(t); /* Canonicalize primitive refs. */ 140 if (irtype_ispri(t)) ref = TREF_PRI(t); /* Canonicalize primitive refs. */
140 J->base[slot] = ref; 141 J->base[slot] = ref;
141 return ref; 142 return ref;
@@ -251,8 +252,9 @@ static TRef fori_arg(jit_State *J, const BCIns *pc, BCReg slot, IRType t)
251 } 252 }
252 if (J->base[slot]) 253 if (J->base[slot])
253 return J->base[slot]; 254 return J->base[slot];
254 else 255 if (t == IRT_INT)
255 return sloadt(J, (int32_t)slot, t, IRSLOAD_READONLY|IRSLOAD_INHERIT); 256 t |= IRT_GUARD;
257 return sloadt(J, (int32_t)slot, t, IRSLOAD_READONLY|IRSLOAD_INHERIT);
256} 258}
257 259
258/* Simulate the runtime behavior of the FOR loop iterator. 260/* Simulate the runtime behavior of the FOR loop iterator.
@@ -2107,6 +2109,8 @@ static void rec_setup_forl(jit_State *J, const BCIns *fori)
2107 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k; 2109 k = (int32_t)(dir ? 0x7fffffff : 0x80000000) - k;
2108 emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k)); 2110 emitir(IRTGI(dir ? IR_LE : IR_GE), stop, lj_ir_kint(J, k));
2109 } 2111 }
2112 if (t == IRT_INT)
2113 t |= IRT_GUARD;
2110 J->base[ra+FORL_EXT] = sloadt(J, (int32_t)(ra+FORL_IDX), t, IRSLOAD_INHERIT); 2114 J->base[ra+FORL_EXT] = sloadt(J, (int32_t)(ra+FORL_IDX), t, IRSLOAD_INHERIT);
2111 J->maxslot = ra+FORL_EXT+1; 2115 J->maxslot = ra+FORL_EXT+1;
2112} 2116}
@@ -2195,7 +2199,7 @@ static void rec_setup_side(jit_State *J, Trace *T)
2195 tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr); 2199 tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr);
2196 } 2200 }
2197 break; 2201 break;
2198 case IR_SLOAD: /* Inherited SLOADs don't need a guard. */ 2202 case IR_SLOAD: /* Inherited SLOADs don't need a guard or type check. */
2199 tr = emitir_raw(ir->ot & ~IRT_GUARD, s, 2203 tr = emitir_raw(ir->ot & ~IRT_GUARD, s,
2200 (ir->op2&IRSLOAD_READONLY) | IRSLOAD_INHERIT|IRSLOAD_PARENT); 2204 (ir->op2&IRSLOAD_READONLY) | IRSLOAD_INHERIT|IRSLOAD_PARENT);
2201 break; 2205 break;