Parcourir la source

32/64 bit memory ref cleanup, part 1: GCproto ->bc and ->k.

Mike Pall il y a 16 ans
Parent
commit
c8d55e8506
10 fichiers modifiés avec 84 ajouts et 66 suppressions
  1. 3 3
      src/lib_jit.c
  2. 3 3
      src/lj_dispatch.c
  3. 7 7
      src/lj_err.c
  4. 4 4
      src/lj_func.c
  5. 1 1
      src/lj_gc.c
  6. 4 1
      src/lj_gdbjit.c
  7. 14 8
      src/lj_obj.h
  8. 36 27
      src/lj_parse.c
  9. 7 7
      src/lj_record.c
  10. 5 5
      src/lj_trace.c

+ 3 - 3
src/lib_jit.c

@@ -209,7 +209,7 @@ LJLIB_CF(jit_util_funcbc)
   GCproto *pt = check_Lproto(L, 0);
   BCPos pc = (BCPos)lj_lib_checkint(L, 2) - 1;
   if (pc < pt->sizebc) {
-    BCIns ins = pt->bc[pc];
+    BCIns ins = proto_ins(pt, pc);
     BCOp op = bc_op(ins);
     lua_assert(op < BC__MAX);
     setintV(L->top, ins);
@@ -227,12 +227,12 @@ LJLIB_CF(jit_util_funck)
   ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2);
   if (idx >= 0) {
     if (idx < (ptrdiff_t)pt->sizekn) {
-      setnumV(L->top-1, pt->k.n[idx]);
+      setnumV(L->top-1, proto_knum(pt, idx));
       return 1;
     }
   } else {
     if (~idx < (ptrdiff_t)pt->sizekgc) {
-      GCobj *gc = gcref(pt->k.gc[idx]);
+      GCobj *gc = proto_kgc(pt, idx);
       setgcV(L, L->top-1, &gc->gch, ~gc->gch.gct);
       return 1;
     }

+ 3 - 3
src/lj_dispatch.c

@@ -117,7 +117,7 @@ static void setptmode_all(global_State *g, GCproto *pt, int mode)
 {
   ptrdiff_t i;
   for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) {
-    GCobj *o = gcref(pt->k.gc[i]);
+    GCobj *o = proto_kgc(pt, i);
     if (o->gch.gct == ~LJ_TPROTO) {
       setptmode(g, gco2pt(o), mode);
       setptmode_all(g, gco2pt(o), mode);
@@ -302,8 +302,8 @@ void LJ_FASTCALL lj_dispatch_ins(lua_State *L, const BCIns *pc)
     callhook(L, LUA_HOOKCOUNT, -1);
   }
   if ((g->hookmask & LUA_MASKLINE) && pt->lineinfo) {
-    BCPos npc = (BCPos)(pc - pt->bc)-1;
-    BCPos opc = (BCPos)(oldpc - pt->bc)-1;
+    BCPos npc = proto_bcpos(pt, pc) - 1;
+    BCPos opc = proto_bcpos(pt, oldpc) - 1;
     BCLine line = pt->lineinfo[npc];
     if (npc == 0 || pc <= oldpc ||
 	opc >= pt->sizebc || line != pt->lineinfo[opc]) {

+ 7 - 7
src/lj_err.c

@@ -120,7 +120,7 @@ static BCPos currentpc(lua_State *L, GCfunc *fn, cTValue *nextframe)
       ins = cframe_pc(cf);
     }
   }
-  return (BCPos)((ins - funcproto(fn)->bc) - 1);
+  return proto_bcpos(funcproto(fn), ins) - 1;
 }
 
 static BCLine currentline(lua_State *L, GCfunc *fn, cTValue *nextframe)
@@ -149,9 +149,9 @@ static const char *getobjname(GCproto *pt, const BCIns *ip, BCReg slot,
 {
   const char *lname;
 restart:
-  lname = getvarname(pt, (BCPos)(ip - pt->bc), slot);
+  lname = getvarname(pt, proto_bcpos(pt, ip), slot);
   if (lname != NULL) { *name = lname; return "local"; }
-  while (--ip >= pt->bc) {
+  while (--ip >= proto_bc(pt)) {
     BCIns ins = *ip;
     BCOp op = bc_op(ins);
     BCReg ra = bc_a(ins);
@@ -164,11 +164,11 @@ restart:
 	if (ra == slot) { slot = bc_d(ins); goto restart; }
 	break;
       case BC_GGET:
-	*name = strdata(gco2str(gcref(pt->k.gc[~(ptrdiff_t)bc_d(ins)])));
+	*name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_d(ins))));
 	return "global";
       case BC_TGETS:
-	*name = strdata(gco2str(gcref(pt->k.gc[~(ptrdiff_t)bc_c(ins)])));
-	if (ip > pt->bc) {
+	*name = strdata(gco2str(proto_kgc(pt, ~(ptrdiff_t)bc_c(ins))));
+	if (ip > proto_bc(pt)) {
 	  BCIns insp = ip[-1];
 	  if (bc_op(insp) == BC_MOV && bc_a(insp) == ra+1 &&
 	      bc_d(insp) == bc_b(ins))
@@ -201,7 +201,7 @@ static const char *getfuncname(lua_State *L, TValue *frame, const char **name)
   if (pc == ~(BCPos)0)
     return NULL;
   lua_assert(pc < funcproto(fn)->sizebc);
-  ip = &funcproto(fn)->bc[pc];
+  ip = &proto_bc(funcproto(fn))[pc];
   mm = bcmode_mm(bc_op(*ip));
   if (mm == MM_call) {
     BCReg slot = bc_a(*ip);

+ 4 - 4
src/lj_func.c

@@ -26,8 +26,8 @@ GCproto *lj_func_newproto(lua_State *L)
   pt->sizeuv = 0;
   pt->flags = 0;
   pt->trace = 0;
-  pt->k.n = NULL;
-  pt->bc = NULL;
+  setmref(pt->k, NULL);
+  setmref(pt->bc, NULL);
   pt->uv = NULL;
   pt->sizebc = 0;
   pt->sizekgc = 0;
@@ -49,8 +49,8 @@ void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt)
   MSize nkgc = round_nkgc(pt->sizekgc);
   MSize sizek = nkgc*(MSize)sizeof(GCRef) +
 		pt->sizekn*(MSize)sizeof(lua_Number);
-  lj_mem_free(g, pt->k.gc - nkgc, sizek);
-  lj_mem_freevec(g, pt->bc, pt->sizebc, BCIns);
+  lj_mem_free(g, mref(pt->k, GCRef) - nkgc, sizek);
+  lj_mem_freevec(g, proto_bc(pt), pt->sizebc, BCIns);
   lj_mem_freevec(g, pt->uv, pt->sizeuv, uint16_t);
   lj_mem_freevec(g, pt->lineinfo, pt->sizelineinfo, int32_t);
   lj_mem_freevec(g, pt->varinfo, pt->sizevarinfo, struct VarInfo);

+ 1 - 1
src/lj_gc.c

@@ -254,7 +254,7 @@ static void gc_traverse_proto(global_State *g, GCproto *pt)
   if (pt->chunkname)
     gc_mark_str(pt->chunkname);
   for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++)  /* Mark collectable consts. */
-    gc_markobj(g, gcref(pt->k.gc[i]));
+    gc_markobj(g, proto_kgc(pt, i));
   for (i = 0; i < (ptrdiff_t)pt->sizeuvname; i++)  /* Mark upvalue names. */
     if (pt->uvname[i])
       gc_mark_str(pt->uvname[i]);

+ 4 - 1
src/lj_gdbjit.c

@@ -705,7 +705,10 @@ void lj_gdbjit_addtrace(jit_State *J, Trace *T, TraceNo traceno)
   ctx.szmcode = T->szmcode;
   ctx.spadjp = CFRAME_SIZE + (MSize)(parent ? J->trace[parent]->spadjust : 0);
   ctx.spadj = CFRAME_SIZE + T->spadjust;
-  ctx.lineno = pt->lineinfo ? pt->lineinfo[startpc - pt->bc] : 0;
+  if (startpc >= proto_bc(pt))
+    ctx.lineno = pt->lineinfo ? pt->lineinfo[proto_bcpos(pt, startpc)] : 0;
+  else
+    ctx.lineno = pt->linedefined;
   ctx.filename = strdata(pt->chunkname);
   if (*ctx.filename == '@' || *ctx.filename == '=')
     ctx.filename++;

+ 14 - 8
src/lj_obj.h

@@ -335,12 +335,6 @@ enum {
 
 /* -- Prototype object ---------------------------------------------------- */
 
-/* Split constant array. Collectables are below, numbers above pointer. */
-typedef union ProtoK {
-  lua_Number *n;	/* Numbers. */
-  GCRef *gc;		/* Collectable objects (strings/table/proto). */
-} ProtoK;
-
 #define SCALE_NUM_GCO	((int32_t)sizeof(lua_Number)/sizeof(GCRef))
 #define round_nkgc(n)	(((n) + SCALE_NUM_GCO-1) & ~(SCALE_NUM_GCO-1))
 
@@ -356,8 +350,8 @@ typedef struct GCproto {
   uint8_t framesize;	/* Fixed frame size. */
   MSize sizebc;		/* Number of bytecode instructions. */
   GCRef gclist;
-  ProtoK k;		/* Split constant array (points to the middle). */
-  BCIns *bc;		/* Array of bytecode instructions. */
+  MRef k;		/* Split constant array (points to the middle). */
+  MRef bc;		/* Array of bytecode instructions. */
   uint16_t *uv;		/* Upvalue list. local slot|0x8000 or parent uv idx. */
   MSize sizekgc;	/* Number of collectable constants. */
   MSize sizekn;		/* Number of lua_Number constants. */
@@ -383,6 +377,18 @@ typedef struct GCproto {
 #define PROTO_NO_JIT		0x10
 #define PROTO_HAS_ILOOP		0x20
 
+#define proto_kgc(pt, idx) \
+  check_exp((uintptr_t)(intptr_t)(idx) >= (uintptr_t)-(intptr_t)(pt)->sizekgc, \
+	    gcref(mref((pt)->k, GCRef)[(idx)]))
+#define proto_knum(pt, idx) \
+  check_exp((uintptr_t)(idx) < (pt)->sizekn, mref((pt)->k, lua_Number)[(idx)])
+#define proto_bc(pt)		(mref((pt)->bc, BCIns))
+#define proto_ins(pt, pos) \
+  check_exp((uintptr_t)(pos) < (pt)->sizebc, proto_bc(pt)[(pos)])
+#define proto_insptr(pt, pos) \
+  check_exp((uintptr_t)(pos) < (pt)->sizebc, &proto_bc(pt)[(pos)])
+#define proto_bcpos(pt, pc)	((BCPos)((pc) - proto_bc(pt)))
+
 /* -- Upvalue object ------------------------------------------------------ */
 
 typedef struct GCupval {

+ 36 - 27
src/lj_parse.c

@@ -152,7 +152,7 @@ LJ_NORET static void err_limit(FuncState *fs, uint32_t limit, const char *what)
 
 static BCPos getjump(FuncState *fs, BCPos pc)
 {
-  ptrdiff_t delta = bc_j(fs->pt->bc[pc]);
+  ptrdiff_t delta = bc_j(proto_ins(fs->pt, pc));
   if ((BCPos)delta == NO_JMP)
     return NO_JMP;
   else
@@ -162,7 +162,7 @@ static BCPos getjump(FuncState *fs, BCPos pc)
 static int need_value(FuncState *fs, BCPos list)
 {
   for (; list != NO_JMP; list = getjump(fs, list)) {
-    BCOp op = bc_op(fs->pt->bc[list >= 1 ? list-1 : list]);
+    BCOp op = bc_op(proto_ins(fs->pt, list >= 1 ? list-1 : list));
     if (!(op == BC_ISTC || op == BC_ISFC)) return 1;
   }
   return 0;  /* Not found. */
@@ -170,7 +170,7 @@ static int need_value(FuncState *fs, BCPos list)
 
 static int patchtestreg(FuncState *fs, BCPos pc, BCReg reg)
 {
-  BCIns *i = &fs->pt->bc[pc >= 1 ? pc-1 : pc];
+  BCIns *i = proto_insptr(fs->pt, pc >= 1 ? pc-1 : pc);
   BCOp op = bc_op(*i);
   if (!(op == BC_ISTC || op == BC_ISFC))
     return 0;  /* cannot patch other instructions */
@@ -191,7 +191,7 @@ static void removevalues(FuncState *fs, BCPos list)
 
 static void fixjump(FuncState *fs, BCPos pc, BCPos dest)
 {
-  BCIns *jmp = &fs->pt->bc[pc];
+  BCIns *jmp = proto_insptr(fs->pt, pc);
   BCPos offset = dest-(pc+1)+BCBIAS_J;
   lua_assert(dest != NO_JMP);
   if (offset > BCMAX_D)
@@ -251,11 +251,14 @@ static BCPos emitINS(FuncState *fs, BCIns i)
   fs->jpc = NO_JMP;
   pt = fs->pt;
   if (LJ_UNLIKELY(fs->pc >= pt->sizebc)) {
+    BCIns *bc;
     checklimit(fs, fs->pc, LJ_MAX_BCINS, "bytecode instructions");
-    lj_mem_growvec(fs->L, pt->bc, pt->sizebc, LJ_MAX_BCINS, BCIns);
+    bc = proto_bc(pt);
+    lj_mem_growvec(fs->L, bc, pt->sizebc, LJ_MAX_BCINS, BCIns);
+    setmref(pt->bc, bc);
     lj_mem_growvec(fs->L, pt->lineinfo, pt->sizelineinfo, LJ_MAX_BCINS, BCLine);
   }
-  pt->bc[fs->pc] = i;
+  *proto_insptr(pt, fs->pc) = i;
   pt->lineinfo[fs->pc] = fs->ls->lastline;
   return fs->pc++;
 }
@@ -264,15 +267,16 @@ static BCPos emitINS(FuncState *fs, BCIns i)
 #define emitAD(fs, o, a, d)	emitINS(fs, BCINS_AD(o, a, d))
 #define emitAJ(fs, o, a, j)	emitINS(fs, BCINS_AJ(o, a, j))
 
-#define bcptr(fs, e)		(&(fs)->pt->bc[(e)->u.s.info])
+#define bcptr(fs, e)		(proto_insptr((fs)->pt, (e)->u.s.info))
 
 static BCPos emit_jump(FuncState *fs)
 {
   BCPos jpc = fs->jpc;  /* save list of jumps to here */
   BCPos j = fs->pc - 1;
   fs->jpc = NO_JMP;
-  if ((int32_t)j >= (int32_t)fs->lasttarget && bc_op(fs->pt->bc[j]) == BC_UCLO)
-    setbc_j(&fs->pt->bc[j], NO_JMP);
+  if ((int32_t)j >= (int32_t)fs->lasttarget &&
+      bc_op(proto_ins(fs->pt, j)) == BC_UCLO)
+    setbc_j(proto_insptr(fs->pt, j), NO_JMP);
   else
     j = emitAJ(fs, BC_JMP, fs->freereg, NO_JMP);
   concatjumps(fs, &j, jpc);  /* keep them on hold */
@@ -334,7 +338,7 @@ static void nilK(FuncState *fs, BCReg from, BCReg n)
   BCIns *pr;
   if (fs->pc > fs->lasttarget) {  /* no jumps to current position? */
     BCReg pfrom, pto;
-    pr = &fs->pt->bc[fs->pc-1];
+    pr = proto_insptr(fs->pt, fs->pc-1);
     pfrom = bc_a(*pr);
     switch (bc_op(*pr)) {
     case BC_KPRI:
@@ -1136,21 +1140,22 @@ static void collectk(FuncState *fs, GCproto *pt)
   Node *node;
   BCReg nkgc;
   MSize i, hmask, sizek;
-  GCRef *kstart;
+  GCRef *kptr;
   checklimitgt(fs, fs->nkn, BCMAX_D+1, "constants");
   checklimitgt(fs, fs->nkgc, BCMAX_D+1, "constants");
   nkgc = round_nkgc(fs->nkgc);
   sizek = (MSize)(nkgc*sizeof(GCRef) + fs->nkn*sizeof(lua_Number));
-  kstart = lj_mem_newt(fs->L, sizek, GCRef);
-  if (nkgc) setgcrefnull(kstart[0]);  /* May be uninitialized otherwise. */
-  pt->k.gc = kstart + nkgc;
+  kptr = lj_mem_newt(fs->L, sizek, GCRef);
+  if (nkgc) setgcrefnull(kptr[0]);  /* May be uninitialized otherwise. */
+  kptr += nkgc;
+  setmref(pt->k, kptr);
   pt->sizekn = fs->nkn;
   pt->sizekgc = fs->nkgc;
   kt = fs->kt;
   array = tvref(kt->array);
   for (i = 0; i < kt->asize; i++)
     if (tvisnum(&array[i]))
-      pt->k.n[array[i].u32.lo] = cast_num(i);
+      ((lua_Number *)kptr)[array[i].u32.lo] = cast_num(i);
   node = noderef(kt->node);
   hmask = kt->hmask;
   for (i = 0; i <= hmask; i++) {
@@ -1158,10 +1163,10 @@ static void collectk(FuncState *fs, GCproto *pt)
     if (tvisnum(&n->val)) {
       ptrdiff_t kidx = (ptrdiff_t)n->val.u32.lo;
       if (tvisnum(&n->key)) {
-	pt->k.n[kidx] = numV(&n->key);
+	((lua_Number *)kptr)[kidx] = numV(&n->key);
       } else {
 	GCobj *o = gcV(&n->key);
-	setgcref(pt->k.gc[~kidx], o);
+	setgcref(kptr[~kidx], o);
 	lj_gc_objbarrier(fs->L, pt, o);
       }
     }
@@ -1184,7 +1189,7 @@ static void finalret(FuncState *fs, GCproto *pt)
 {
   BCPos lastpc = fs->pc;
   if (lastpc > fs->lasttarget) {
-    switch (bc_op(pt->bc[lastpc-1])) {
+    switch (bc_op(proto_ins(pt, lastpc-1))) {
     case BC_CALLMT: case BC_CALLT:
     case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
       goto suppress_return;  /* already got a return */
@@ -1195,21 +1200,22 @@ static void finalret(FuncState *fs, GCproto *pt)
     emitAJ(fs, BC_UCLO, 0, 0);
   emitAD(fs, BC_RET0, 0, 1);  /* final return */
 suppress_return:
-  /* may need to fixup returns encoded before first function was created */
+  /* May need to fixup returns encoded before first function was created. */
   if (fs->pt->flags & PROTO_FIXUP_RETURN) {
     BCPos pc;
     for (pc = 0; pc < lastpc; pc++) {
-      BCIns i = pt->bc[pc];
+      BCIns i = proto_ins(pt, pc);
       BCPos offset;
       switch (bc_op(i)) {
       case BC_CALLMT: case BC_CALLT:
       case BC_RETM: case BC_RET: case BC_RET0: case BC_RET1:
-	offset = emitINS(fs, i)-(pc+1)+BCBIAS_J;  /* copy return ins */
+	offset = emitINS(fs, i)-(pc+1)+BCBIAS_J;  /* Copy return ins. */
 	if (offset > BCMAX_D)
 	  err_syntax(fs->ls, LJ_ERR_XFIXUP);
-	pt->bc[pc] = BCINS_AD(BC_UCLO, 0, offset);  /* replace w/ UCLO+branch */
+	/* Replace with UCLO plus branch. */
+	*proto_insptr(pt, pc) = BCINS_AD(BC_UCLO, 0, offset);
 	break;
-      case BC_UCLO: return;  /* we're done */
+      case BC_UCLO: return;  /* We're done. */
       default: break;
       }
     }
@@ -1221,9 +1227,12 @@ static void close_func(LexState *ls)
   lua_State *L = ls->L;
   FuncState *fs = ls->fs;
   GCproto *pt = fs->pt;
+  BCIns *bc;
   removevars(ls, 0);
   finalret(fs, pt);
-  lj_mem_reallocvec(L, pt->bc, pt->sizebc, fs->pc, BCIns);
+  bc = proto_bc(pt);
+  lj_mem_reallocvec(L, bc, pt->sizebc, fs->pc, BCIns);
+  setmref(pt->bc, bc);
   pt->sizebc = fs->pc;
   collectk(fs, pt);
   collectuv(fs, pt);
@@ -1336,7 +1345,7 @@ static void constructor(LexState *ls, ExpDesc *e)
 	BCReg kidx;
 	t = lj_tab_new(fs->L, 0, 0);
 	kidx = gcK(fs, obj2gco(t), LJ_TTAB);
-	fs->pt->bc[pc] = BCINS_AD(BC_TDUP, freg-1, kidx);
+	*proto_insptr(fs->pt, pc) = BCINS_AD(BC_TDUP, freg-1, kidx);
       }
       vcall = 0;
       kexp2tv(&k, &key);
@@ -1353,7 +1362,7 @@ static void constructor(LexState *ls, ExpDesc *e)
   }
   checkmatch(ls, '}', '{', line);
   if (vcall) {
-    BCIns *i = &fs->pt->bc[fs->pc-1];
+    BCIns *i = proto_insptr(fs->pt, fs->pc-1);
     ExpDesc en;
     lua_assert(bc_a(*i)==freg && bc_op(*i) == (narr>256?BC_TSETV:BC_TSETB));
     init_exp(&en, VKNUM, 0);
@@ -1373,7 +1382,7 @@ static void constructor(LexState *ls, ExpDesc *e)
     if (!needarr) narr = 0;
     else if (narr < 3) narr = 3;
     else if (narr > 0x7ff) narr = 0x7ff;
-    setbc_d(&fs->pt->bc[pc], (uint32_t)narr | (hsize2hbits(nhash) << 11));
+    setbc_d(proto_insptr(fs->pt, pc), (uint32_t)narr|(hsize2hbits(nhash)<<11));
   }
 }
 

+ 7 - 7
src/lj_record.c

@@ -263,7 +263,7 @@ static TRef fori_arg(jit_State *J, const BCIns *pc, BCReg slot, IRType t)
 	else
 	  return lj_ir_knum(J, cast_num(k));
       } else if (bc_op(ins) == BC_KNUM) {
-	lua_Number n = J->pt->k.n[bc_d(ins)];
+	lua_Number n = proto_knum(J->pt, bc_d(ins));
 	if (t == IRT_INT)
 	  return lj_ir_kint(J, lj_num2int(n));
 	else
@@ -1816,7 +1816,7 @@ void lj_record_ins(jit_State *J)
   case BCMnone: rb = 0; rc = bc_d(ins); break;  /* Upgrade rc to 'rd'. */
   case BCMvar:
     copyTV(J->L, rbv, &lbase[rb]); ix.tab = rb = getslot(J, rb); break;
-  case BCMnum: { lua_Number n = J->pt->k.n[rb];
+  case BCMnum: { lua_Number n = proto_knum(J->pt, rb);
     setnumV(rbv, n); ix.tab = rb = lj_ir_knumint(J, n); } break;
   default: break;  /* Handled later. */
   }
@@ -1824,9 +1824,9 @@ void lj_record_ins(jit_State *J)
   case BCMvar:
     copyTV(J->L, rcv, &lbase[rc]); ix.key = rc = getslot(J, rc); break;
   case BCMpri: setitype(rcv, (int32_t)~rc); rc = TREF_PRI(IRT_NIL+rc); break;
-  case BCMnum: { lua_Number n = J->pt->k.n[rc];
+  case BCMnum: { lua_Number n = proto_knum(J->pt, rc);
     setnumV(rcv, n); ix.key = rc = lj_ir_knumint(J, n); } break;
-  case BCMstr: { GCstr *s = strref(J->pt->k.gc[~(ptrdiff_t)rc]);
+  case BCMstr: { GCstr *s = gco2str(proto_kgc(J->pt, ~(ptrdiff_t)rc));
     setstrV(J->L, rcv, s); ix.key = rc = lj_ir_kstr(J, s); } break;
   default: break;  /* Handled later. */
   }
@@ -2018,7 +2018,7 @@ void lj_record_ins(jit_State *J)
     break;
   case BC_TDUP:
     rc = emitir(IRT(IR_TDUP, IRT_TAB),
-		lj_ir_ktab(J, tabref(J->pt->k.gc[~(ptrdiff_t)rc])), 0);
+		lj_ir_ktab(J, gco2tab(proto_kgc(J->pt, ~(ptrdiff_t)rc))), 0);
     break;
 
   /* -- Calls and vararg handling ----------------------------------------- */
@@ -2315,7 +2315,7 @@ void lj_record_setup(jit_State *J)
     /* Check whether we could at least potentially form an extra loop. */
     if (J->exitno == 0 && T->snap[0].nent == 0) {
       /* We can narrow a FORL for some side traces, too. */
-      if (J->pc > J->pt->bc && bc_op(J->pc[-1]) == BC_JFORI &&
+      if (J->pc > proto_bc(J->pt) && bc_op(J->pc[-1]) == BC_JFORI &&
 	  bc_d(J->pc[bc_j(J->pc[-1])-1]) == root) {
 	lj_snap_add(J);
 	rec_setup_forl(J, J->pc-1);
@@ -2332,7 +2332,7 @@ void lj_record_setup(jit_State *J)
       rec_stop(J, TRACE_INTERP);
   } else {  /* Root trace. */
     J->cur.root = 0;
-    if (J->pc >= J->pt->bc) {  /* Not a hot CALL? */
+    if (J->pc >= proto_bc(J->pt)) {  /* Not a hot CALL? */
       J->cur.startins = *J->pc;
       J->pc = rec_setup_root(J);
       /* Note: the loop instruction itself is recorded at the end and not

+ 5 - 5
src/lj_trace.c

@@ -146,7 +146,7 @@ void lj_trace_freeproto(global_State *g, GCproto *pt)
 void lj_trace_reenableproto(GCproto *pt)
 {
   if ((pt->flags & PROTO_HAS_ILOOP)) {
-    BCIns *bc = pt->bc;
+    BCIns *bc = proto_bc(pt);
     BCPos i, sizebc = pt->sizebc;;
     pt->flags &= ~PROTO_HAS_ILOOP;
     for (i = 0; i < sizebc; i++) {
@@ -323,7 +323,7 @@ static void trace_start(jit_State *J)
 
   if ((J->pt->flags & PROTO_NO_JIT)) {  /* JIT disabled for this proto? */
     if (J->parent == 0) {
-      if (J->pc >= J->pt->bc) {
+      if (J->pc >= proto_bc(J->pt)) {
 	/* Lazy bytecode patching to disable hotcount events. */
 	setbc_op(J->pc, (int)bc_op(*J->pc)+(int)BC_ILOOP-(int)BC_LOOP);
 	J->pt->flags |= PROTO_HAS_ILOOP;
@@ -361,7 +361,7 @@ static void trace_start(jit_State *J)
     setstrV(L, L->top++, lj_str_newlit(L, "start"));
     setintV(L->top++, J->curtrace);
     setfuncV(L, L->top++, J->fn);
-    setintV(L->top++, J->pc - J->pt->bc + 1);
+    setintV(L->top++, proto_bcpos(J->pt, J->pc) + 1);
     if (J->parent) {
       setintV(L->top++, J->parent);
       setintV(L->top++, J->exitno);
@@ -444,7 +444,7 @@ static int trace_abort(jit_State *J)
       setstrV(L, L->top++, lj_str_newlit(L, "abort"));
       setintV(L->top++, J->curtrace);
       setfuncV(L, L->top++, J->fn);
-      setintV(L->top++, J->pc - J->pt->bc + 1);
+      setintV(L->top++, proto_bcpos(J->pt, J->pc) + 1);
       copyTV(L, L->top++, restorestack(L, errobj));
       copyTV(L, L->top++, &J->errinfo);
     );
@@ -478,7 +478,7 @@ static TValue *trace_state(lua_State *L, lua_CFunction dummy, void *ud)
       lj_vmevent_send(L, RECORD,
 	setintV(L->top++, J->curtrace);
 	setfuncV(L, L->top++, J->fn);
-	setintV(L->top++, J->pc - J->pt->bc + 1);
+	setintV(L->top++, proto_bcpos(J->pt, J->pc) + 1);
 	setintV(L->top++, J->framedepth);
 	if (bcmode_mm(bc_op(*J->pc)) == MM_call) {
 	  cTValue *o = &L->base[bc_a(*J->pc)];