Преглед изворни кода

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.
Mike Pall пре 8 година
родитељ
комит
e577db52c5
4 измењених фајлова са 8 додато и 6 уклоњено
  1. 1 1
      src/lj_asm_mips.h
  2. 1 1
      src/lj_asm_ppc.h
  3. 2 2
      src/lj_asm_x86.h
  4. 4 2
      src/lj_ir.c

+ 1 - 1
src/lj_asm_mips.h

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

+ 1 - 1
src/lj_asm_ppc.h

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

+ 2 - 2
src/lj_asm_x86.h

@@ -234,10 +234,10 @@ static void asm_fusefref(ASMState *as, IRIns *ir, RegSet allow)
   as->mrm.idx = RID_NONE;
   if (ir->op1 == REF_NIL) {
 #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;
 #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;
 #endif
     return;

+ 4 - 2
src/lj_ir.c

@@ -145,10 +145,12 @@ TRef lj_ir_call(jit_State *J, IRCallID 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)
 {
-  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);
   return lj_opt_fold(J);
 }