diff options
| -rw-r--r-- | lib/dump.lua | 3 | ||||
| -rw-r--r-- | src/lj_asm.c | 6 | ||||
| -rw-r--r-- | src/lj_ir.h | 1 | ||||
| -rw-r--r-- | src/lj_record.c | 14 |
4 files changed, 16 insertions, 8 deletions
diff --git a/lib/dump.lua b/lib/dump.lua index 00f59977..fb40a8f8 100644 --- a/lib/dump.lua +++ b/lib/dump.lua | |||
| @@ -209,7 +209,8 @@ local colorize, irtype | |||
| 209 | 209 | ||
| 210 | -- Lookup table to convert some literals into names. | 210 | -- Lookup table to convert some literals into names. |
| 211 | local litname = { | 211 | local litname = { |
| 212 | ["SLOAD "] = { [0] = "", "I", "R", "RI", "P", "PI", "PR", "PRI", }, | 212 | ["SLOAD "] = { [0] = "", "I", "R", "RI", "P", "PI", "PR", "PRI", |
| 213 | "T", "IT", "RT", "RIT", "PT", "PIT", "PRT", "PRIT", }, | ||
| 213 | ["XLOAD "] = { [0] = "", "R", "U", "RU", }, | 214 | ["XLOAD "] = { [0] = "", "R", "U", "RU", }, |
| 214 | ["TOINT "] = { [0] = "check", "index", "", }, | 215 | ["TOINT "] = { [0] = "check", "index", "", }, |
| 215 | ["FLOAD "] = vmdef.irfield, | 216 | ["FLOAD "] = vmdef.irfield, |
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; |
