diff options
author | Mike Pall <mike> | 2010-01-19 16:58:26 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-01-19 16:58:26 +0100 |
commit | a61df8efbe5bbe3726d65ad0800a3106ed3a8bf0 (patch) | |
tree | db27cf4dc668742db0c60509fe339c56cf8bf2f5 /src | |
parent | 36769c2f6b78e0802cc7cd86f6da301cd7a171fe (diff) | |
download | luajit-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.c | 6 | ||||
-rw-r--r-- | src/lj_ir.h | 1 | ||||
-rw-r--r-- | src/lj_record.c | 14 |
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! */ |
126 | static TRef sloadt(jit_State *J, int32_t slot, IRType t, int mode) | 126 | static 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) | |||
135 | static TRef sload(jit_State *J, int32_t slot) | 135 | static 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; |