Increase range of GG_State loads via IR_FLOAD with REF_NIL.

Require 32 bit alignment and store offset/4 instead.
Otherwise this can overflow the 10 bit limit for the FOLD op2 key.
This commit is contained in:
Mike Pall 2016-11-19 19:53:46 +01:00
parent 5400c1e424
commit e577db52c5
4 changed files with 8 additions and 6 deletions

View File

@ -901,7 +901,7 @@ static void asm_fload(ASMState *as, IRIns *ir)
int32_t ofs; int32_t ofs;
if (ir->op1 == REF_NIL) { if (ir->op1 == REF_NIL) {
idx = RID_JGL; idx = RID_JGL;
ofs = ir->op2 - 32768; ofs = (ir->op2 << 2) - 32768;
} else { } else {
idx = ra_alloc1(as, ir->op1, RSET_GPR); idx = ra_alloc1(as, ir->op1, RSET_GPR);
if (ir->op2 == IRFL_TAB_ARRAY) { if (ir->op2 == IRFL_TAB_ARRAY) {

View File

@ -809,7 +809,7 @@ static void asm_fload(ASMState *as, IRIns *ir)
int32_t ofs; int32_t ofs;
if (ir->op1 == REF_NIL) { if (ir->op1 == REF_NIL) {
idx = RID_JGL; idx = RID_JGL;
ofs = ir->op2 - 32768; ofs = (ir->op2 << 2) - 32768;
} else { } else {
idx = ra_alloc1(as, ir->op1, RSET_GPR); idx = ra_alloc1(as, ir->op1, RSET_GPR);
if (ir->op2 == IRFL_TAB_ARRAY) { if (ir->op2 == IRFL_TAB_ARRAY) {

View File

@ -234,10 +234,10 @@ static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow)
as->mrm.idx = RID_NONE; as->mrm.idx = RID_NONE;
if (ir->op1 == REF_NIL) { if (ir->op1 == REF_NIL) {
#if LJ_GC64 #if LJ_GC64
as->mrm.ofs = (int32_t)ir->op2 - GG_OFS(dispatch); as->mrm.ofs = (int32_t)(ir->op2 << 2) - GG_OFS(dispatch);
as->mrm.base = RID_DISPATCH; as->mrm.base = RID_DISPATCH;
#else #else
as->mrm.ofs = (int32_t)ir->op2 + ptr2addr(J2GG(as->J)); as->mrm.ofs = (int32_t)(ir->op2 << 2) + ptr2addr(J2GG(as->J));
as->mrm.base = RID_NONE; as->mrm.base = RID_NONE;
#endif #endif
return; return;

View File

@ -145,10 +145,12 @@ TRef lj_ir_call(jit_State *J, IRCallID id, ...)
return emitir(CCI_OPTYPE(ci), tr, id); return emitir(CCI_OPTYPE(ci), tr, id);
} }
/* Load field of type t from GG_State + offset. */ /* Load field of type t from GG_State + offset. Must be 32 bit aligned. */
LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs) LJ_FUNC TRef lj_ir_ggfload(jit_State *J, IRType t, uintptr_t ofs)
{ {
lua_assert(ofs >= IRFL__MAX && ofs < REF_BIAS); lua_assert((ofs & 3) == 0);
ofs >>= 2;
lua_assert(ofs >= IRFL__MAX && ofs <= 0x3ff); /* 10 bit FOLD key limit. */
lj_ir_set(J, IRT(IR_FLOAD, t), REF_NIL, ofs); lj_ir_set(J, IRT(IR_FLOAD, t), REF_NIL, ofs);
return lj_opt_fold(J); return lj_opt_fold(J);
} }