diff --git a/src/lib_jit.c b/src/lib_jit.c index ef6fd465..52368a8b 100644 --- a/src/lib_jit.c +++ b/src/lib_jit.c @@ -188,7 +188,7 @@ LJLIB_CF(jit_util_funcinfo) setintfield(L, t, "currentline", pt->lineinfo ? pt->lineinfo[pc-1] : 0); lua_pushboolean(L, (pt->flags & PROTO_IS_VARARG)); lua_setfield(L, -2, "isvararg"); - setstrV(L, L->top++, pt->chunkname); + setstrV(L, L->top++, proto_chunkname(pt)); lua_setfield(L, -2, "source"); lj_err_pushloc(L, pt, pc); lua_setfield(L, -2, "loc"); @@ -246,7 +246,7 @@ LJLIB_CF(jit_util_funcuvname) GCproto *pt = check_Lproto(L, 0); uint32_t idx = (uint32_t)lj_lib_checkint(L, 2); if (idx < pt->sizeuvname) { - setstrV(L, L->top-1, pt->uvname[idx]); + setstrV(L, L->top-1, gco2str(proto_uvname(pt, idx))); return 1; } return 0; diff --git a/src/lj_api.c b/src/lj_api.c index a2d29723..8216c395 100644 --- a/src/lj_api.c +++ b/src/lj_api.c @@ -813,7 +813,7 @@ static const char *aux_upvalue(cTValue *f, uint32_t idx, TValue **val) GCproto *pt = funcproto(fn); if (idx < pt->sizeuvname) { *val = uvval(&gcref(fn->l.uvptr[idx])->uv); - return strdata(pt->uvname[idx]); + return strdata(gco2str(proto_uvname(pt, idx))); } } else { if (idx < fn->c.nupvalues) { diff --git a/src/lj_err.c b/src/lj_err.c index d1e705ea..0c54cf62 100644 --- a/src/lj_err.c +++ b/src/lj_err.c @@ -176,7 +176,8 @@ restart: } return "field"; case BC_UGET: - *name = pt->uvname ? strdata(pt->uvname[bc_d(ins)]) : "?"; + *name = mref(pt->uvname, GCRef) ? + strdata(gco2str(proto_uvname(pt,bc_d(ins)))) : "?"; return "upvalue"; default: return NULL; @@ -217,7 +218,7 @@ static const char *getfuncname(lua_State *L, TValue *frame, const char **name) void lj_err_pushloc(lua_State *L, GCproto *pt, BCPos pc) { - GCstr *name = pt->chunkname; + GCstr *name = proto_chunkname(pt); if (name) { const char *s = strdata(name); MSize i, len = name->len; @@ -344,7 +345,7 @@ LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar) switch (*what) { case 'S': if (isluafunc(fn)) { - ar->source = strdata(funcproto(fn)->chunkname); + ar->source = strdata(proto_chunkname(funcproto(fn))); ar->linedefined = cast_int(funcproto(fn)->linedefined); ar->lastlinedefined = cast_int(funcproto(fn)->lastlinedefined); ar->what = (ar->linedefined == 0) ? "main" : "Lua"; @@ -819,7 +820,7 @@ LJ_NOINLINE static void err_loc(lua_State *L, const char *msg, if (isluafunc(fn)) { char buff[LUA_IDSIZE]; BCLine line = currentline(L, fn, nextframe); - err_chunkid(buff, strdata(funcproto(fn)->chunkname)); + err_chunkid(buff, strdata(proto_chunkname(funcproto(fn)))); lj_str_pushf(L, "%s:%d: %s", buff, line, msg); return; } diff --git a/src/lj_func.c b/src/lj_func.c index 27a8322f..284bd3b3 100644 --- a/src/lj_func.c +++ b/src/lj_func.c @@ -28,7 +28,7 @@ GCproto *lj_func_newproto(lua_State *L) pt->trace = 0; setmref(pt->k, NULL); setmref(pt->bc, NULL); - pt->uv = NULL; + setmref(pt->uv, NULL); pt->sizebc = 0; pt->sizekgc = 0; pt->sizekn = 0; @@ -39,8 +39,8 @@ GCproto *lj_func_newproto(lua_State *L) pt->lastlinedefined = 0; pt->lineinfo = NULL; pt->varinfo = NULL; - pt->uvname = NULL; - pt->chunkname = NULL; + setmref(pt->uvname, NULL); + setgcrefnull(pt->chunkname); return pt; } @@ -51,10 +51,10 @@ void LJ_FASTCALL lj_func_freeproto(global_State *g, GCproto *pt) pt->sizekn*(MSize)sizeof(lua_Number); 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, proto_uv(pt), pt->sizeuv, uint16_t); lj_mem_freevec(g, pt->lineinfo, pt->sizelineinfo, int32_t); lj_mem_freevec(g, pt->varinfo, pt->sizevarinfo, struct VarInfo); - lj_mem_freevec(g, pt->uvname, pt->sizeuvname, GCstr *); + lj_mem_freevec(g, mref(pt->uvname, GCRef), pt->sizeuvname, GCRef); lj_trace_freeproto(g, pt); lj_mem_freet(g, pt); } @@ -169,7 +169,7 @@ GCfunc *lj_func_newL_gc(lua_State *L, GCproto *pt, GCfuncL *parent) nuv = fn->l.nupvalues; base = L->base; for (i = 0; i < nuv; i++) { - uint32_t v = pt->uv[i]; + uint32_t v = proto_uv(pt)[i]; GCupval *uv; if ((v & 0x8000)) { uv = func_finduv(L, base + (v & 0xff)); diff --git a/src/lj_gc.c b/src/lj_gc.c index 9f0ff2b6..3c1b847a 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -251,13 +251,13 @@ static void gc_traverse_proto(global_State *g, GCproto *pt) } #endif /* GC during prototype creation could cause NULL fields. */ - if (pt->chunkname) - gc_mark_str(pt->chunkname); + if (gcref(pt->chunkname)) + gc_mark_str(proto_chunkname(pt)); for (i = -(ptrdiff_t)pt->sizekgc; i < 0; i++) /* Mark collectable consts. */ 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]); + if (proto_uvname(pt, i)) + gc_mark_str(gco2str(proto_uvname(pt, i))); for (i = 0; i < (ptrdiff_t)pt->sizevarinfo; i++) /* Mark names of locals. */ if (pt->varinfo[i].name) gc_mark_str(pt->varinfo[i].name); @@ -332,7 +332,7 @@ static size_t propagatemark(global_State *g) sizeof(uint16_t) * pt->sizeuv + sizeof(int32_t) * pt->sizelineinfo + sizeof(VarInfo) * pt->sizevarinfo + - sizeof(GCstr *) * pt->sizeuvname; + sizeof(GCRef) * pt->sizeuvname; } else { lua_State *th = gco2th(o); setgcrefr(th->gclist, g->gc.grayagain); diff --git a/src/lj_gdbjit.c b/src/lj_gdbjit.c index 6fb8a1d3..af31b277 100644 --- a/src/lj_gdbjit.c +++ b/src/lj_gdbjit.c @@ -709,7 +709,7 @@ void lj_gdbjit_addtrace(jit_State *J, Trace *T, TraceNo traceno) ctx.lineno = pt->lineinfo ? pt->lineinfo[proto_bcpos(pt, startpc)] : 0; else ctx.lineno = pt->linedefined; - ctx.filename = strdata(pt->chunkname); + ctx.filename = strdata(proto_chunkname(pt)); if (*ctx.filename == '@' || *ctx.filename == '=') ctx.filename++; else diff --git a/src/lj_obj.h b/src/lj_obj.h index 22b69c60..164ec853 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -352,7 +352,7 @@ typedef struct GCproto { GCRef gclist; 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. */ + MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */ MSize sizekgc; /* Number of collectable constants. */ MSize sizekn; /* Number of lua_Number constants. */ uint8_t sizeuv; /* Number of upvalues. */ @@ -366,8 +366,8 @@ typedef struct GCproto { BCLine lastlinedefined; /* Last line of the function definition. */ BCLine *lineinfo; /* Map from bytecode instructions to source lines. */ struct VarInfo *varinfo; /* Names and extents of local variables. */ - GCstr **uvname; /* Upvalue names. */ - GCstr *chunkname; /* Name of the chunk this function was defined in. */ + MRef uvname; /* Array of upvalue names (GCRef of GCstr). */ + GCRef chunkname; /* Name of the chunk this function was defined in. */ } GCproto; #define PROTO_IS_VARARG 0x01 @@ -388,6 +388,11 @@ typedef struct GCproto { #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))) +#define proto_uv(pt) (mref((pt)->uv, uint16_t)) +#define proto_uvname(pt, idx) \ + check_exp((uintptr_t)(idx) < (pt)->sizeuvname, \ + gcref(mref((pt)->uvname, GCRef)[(idx)])) +#define proto_chunkname(pt) (gco2str(gcref((pt)->chunkname))) /* -- Upvalue object ------------------------------------------------------ */ diff --git a/src/lj_parse.c b/src/lj_parse.c index 1a596d72..864f9e20 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -1017,20 +1017,23 @@ static uint32_t indexupvalue(FuncState *fs, GCstr *name, ExpDesc *v) { uint32_t i; GCproto *pt = fs->pt; + GCRef *uvname; for (i = 0; i < fs->nuv; i++) { if (fs->upvalues[i].info == v->u.s.info && fs->upvalues[i].k == v->k) { - lua_assert(pt->uvname[i] == name); + lua_assert(gco2str(proto_uvname(pt, i)) == name); return i; } } /* Not found, create a new upvalue for this name. */ + uvname = mref(pt->uvname, GCRef); if (LJ_UNLIKELY(fs->nuv >= pt->sizeuvname)) { MSize oldsize = pt->sizeuvname; checklimit(fs, fs->nuv, LJ_MAX_UPVAL, "upvalues"); - lj_mem_growvec(fs->L, pt->uvname, pt->sizeuvname, LJ_MAX_UPVAL, GCstr *); - while (oldsize < pt->sizeuvname) pt->uvname[oldsize++] = NULL; + lj_mem_growvec(fs->L, uvname, pt->sizeuvname, LJ_MAX_UPVAL, GCRef); + setmref(pt->uvname, uvname); + while (oldsize < pt->sizeuvname) setgcrefnull(uvname[oldsize++]); } - pt->uvname[fs->nuv] = name; + setgcref(uvname[fs->nuv], obj2gco(name)); lj_gc_objbarrier(fs->L, pt, name); lua_assert(v->k == VLOCAL || v->k == VUPVAL); fs->upvalues[fs->nuv].k = cast_byte(v->k); @@ -1123,7 +1126,7 @@ static void open_func(LexState *ls, FuncState *fs) fs->nactvar = 0; fs->nuv = 0; fs->bl = NULL; - pt->chunkname = ls->chunkname; + setgcref(pt->chunkname, obj2gco(ls->chunkname)); pt->framesize = 2; /* registers 0/1 are always valid */ fs->kt = lj_tab_new(L, 0, 0); /* anchor table of constants and prototype (to avoid being collected) */ @@ -1176,12 +1179,13 @@ static void collectk(FuncState *fs, GCproto *pt) static void collectuv(FuncState *fs, GCproto *pt) { uint32_t i; - pt->uv = lj_mem_newvec(fs->L, fs->nuv, uint16_t); + uint16_t *uv = lj_mem_newvec(fs->L, fs->nuv, uint16_t); + setmref(pt->uv, uv); pt->sizeuv = fs->nuv; for (i = 0; i < pt->sizeuv; i++) { uint32_t v = fs->upvalues[i].info; if (fs->upvalues[i].k == VLOCAL) v |= 0x8000; - pt->uv[i] = (uint16_t)v; + uv[i] = (uint16_t)v; } } @@ -1228,6 +1232,7 @@ static void close_func(LexState *ls) FuncState *fs = ls->fs; GCproto *pt = fs->pt; BCIns *bc; + GCRef *uvname; removevars(ls, 0); finalret(fs, pt); bc = proto_bc(pt); @@ -1240,7 +1245,9 @@ static void close_func(LexState *ls) pt->sizelineinfo = fs->pc; lj_mem_reallocvec(L, pt->varinfo, pt->sizevarinfo, fs->nlocvars, VarInfo); pt->sizevarinfo = fs->nlocvars; - lj_mem_reallocvec(L, pt->uvname, pt->sizeuvname, fs->nuv, GCstr *); + uvname = mref(pt->uvname, GCRef); + lj_mem_reallocvec(L, uvname, pt->sizeuvname, fs->nuv, GCRef); + setmref(pt->uvname, uvname); pt->sizeuvname = fs->nuv; lua_assert(fs->bl == NULL); lj_vmevent_send(L, BC,