diff --git a/src/buildvm_x64.h b/src/buildvm_x64.h index b3466037..c9e2d64f 100644 --- a/src/buildvm_x64.h +++ b/src/buildvm_x64.h @@ -1089,7 +1089,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse) dasm_put(Dst, 1814); } dasm_put(Dst, 1823, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, ~LJ_TLIGHTUD, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL); - dasm_put(Dst, 1902, DISPATCH_GL(mmname)+4*MM_metatable, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next)); + dasm_put(Dst, 1902, DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable), LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next)); dasm_put(Dst, 1960, LJ_TNIL, LJ_TUDATA, LJ_TISNUM, LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT])); dasm_put(Dst, 2029, 2+1, LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->marked), LJ_GC_BLACK, Dt6(->marked), cast_byte(~LJ_GC_BLACK)); dasm_put(Dst, 2098, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist), 2+1, LJ_TTAB, 1+1, LJ_TISNUM); diff --git a/src/buildvm_x64win.h b/src/buildvm_x64win.h index 69a8b27e..97581286 100644 --- a/src/buildvm_x64win.h +++ b/src/buildvm_x64win.h @@ -1089,7 +1089,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse) dasm_put(Dst, 1790); } dasm_put(Dst, 1799, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, ~LJ_TLIGHTUD, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL); - dasm_put(Dst, 1878, DISPATCH_GL(mmname)+4*MM_metatable, LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next)); + dasm_put(Dst, 1878, DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable), LJ_TTAB, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next)); dasm_put(Dst, 1935, LJ_TNIL, LJ_TUDATA, LJ_TISNUM, LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT])); dasm_put(Dst, 2003, 2+1, LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->marked), LJ_GC_BLACK, Dt6(->marked), cast_byte(~LJ_GC_BLACK)); dasm_put(Dst, 2072, DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist), 2+1, LJ_TTAB, 1+1, LJ_TISNUM); diff --git a/src/buildvm_x86.dasc b/src/buildvm_x86.dasc index 942889ed..69195cf6 100644 --- a/src/buildvm_x86.dasc +++ b/src/buildvm_x86.dasc @@ -1302,7 +1302,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse) | test TAB:RB, TAB:RB | mov dword [BASE-4], LJ_TNIL | jz ->fff_res1 - | mov STR:RC, [DISPATCH+DISPATCH_GL(mmname)+4*MM_metatable] + | mov STR:RC, [DISPATCH+DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable)] | mov dword [BASE-4], LJ_TTAB // Store metatable as default result. | mov [BASE-8], TAB:RB | mov RA, TAB:RB->hmask diff --git a/src/buildvm_x86.h b/src/buildvm_x86.h index 84dd2802..7a0b08a7 100644 --- a/src/buildvm_x86.h +++ b/src/buildvm_x86.h @@ -1143,7 +1143,7 @@ static void build_subroutines(BuildCtx *ctx, int cmov, int sse) } else { dasm_put(Dst, 1769); } - dasm_put(Dst, 1778, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL, DISPATCH_GL(mmname)+4*MM_metatable, LJ_TTAB); + dasm_put(Dst, 1778, ((char *)(&((GCfuncC *)0)->upvalue)), LJ_TSTR, 1+1, LJ_TTAB, Dt6(->metatable), LJ_TNIL, DISPATCH_GL(gcroot)+4*(GCROOT_MMNAME+MM_metatable), LJ_TTAB); dasm_put(Dst, 1861, Dt6(->hmask), Dt5(->hash), sizeof(Node), Dt6(->node), DtB(->key.it), LJ_TSTR, DtB(->key.gcr), DtB(->next), LJ_TNIL); dasm_put(Dst, 1919, LJ_TUDATA, LJ_TISNUM, LJ_TNUMX, DISPATCH_GL(gcroot[GCROOT_BASEMT]), 2+1); dasm_put(Dst, 1982, LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->metatable), LJ_TTAB, Dt6(->marked), LJ_GC_BLACK, Dt6(->marked), cast_byte(~LJ_GC_BLACK), DISPATCH_GL(gc.grayagain), DISPATCH_GL(gc.grayagain), Dt6(->gclist)); diff --git a/src/lib_string.c b/src/lib_string.c index ab353c20..1231aeb2 100644 --- a/src/lib_string.c +++ b/src/lib_string.c @@ -774,7 +774,6 @@ LJLIB_CF(string_format) LUALIB_API int luaopen_string(lua_State *L) { GCtab *mt; - GCstr *mmstr; global_State *g; LJ_LIB_REG(L, string); #if defined(LUA_COMPAT_GFIND) @@ -785,9 +784,7 @@ LUALIB_API int luaopen_string(lua_State *L) /* NOBARRIER: basemt is a GC root. */ g = G(L); setgcref(basemt_it(g, LJ_TSTR), obj2gco(mt)); - mmstr = strref(g->mmname[MM_index]); - if (isdead(g, obj2gco(mmstr))) flipwhite(obj2gco(mmstr)); - settabV(L, lj_tab_setstr(L, mt, mmstr), tabV(L->top-1)); + settabV(L, lj_tab_setstr(L, mt, mmname_str(g, MM_index)), tabV(L->top-1)); mt->nomm = cast_byte(~(1u<mmname[mm])); + *name = strdata(mmname_str(G(L), mm)); return "metamethod"; } else { return NULL; diff --git a/src/lj_gc.c b/src/lj_gc.c index bd31eabf..0f0ca82e 100644 --- a/src/lj_gc.c +++ b/src/lj_gc.c @@ -77,7 +77,7 @@ static void gc_mark(global_State *g, GCobj *o) static void gc_mark_gcroot(global_State *g) { ptrdiff_t i; - for (i = 0; i < GCROOT__MAX; i++) + for (i = 0; i < GCROOT_MAX; i++) if (gcref(g->gcroot[i]) != NULL) gc_markobj(g, gcref(g->gcroot[i])); } diff --git a/src/lj_meta.c b/src/lj_meta.c index 41124fdc..ab8ae8fe 100644 --- a/src/lj_meta.c +++ b/src/lj_meta.c @@ -28,14 +28,13 @@ void lj_meta_init(lua_State *L) #undef MMNAME global_State *g = G(L); const char *p, *q; - uint32_t i; - for (i = 0, p = metanames; *p; i++, p = q) { + uint32_t mm; + for (mm = 0, p = metanames; *p; mm++, p = q) { GCstr *s; for (q = p+2; *q && *q != '_'; q++) ; s = lj_str_new(L, p, (size_t)(q-p)); - fixstring(s); /* Never collect these names. */ - /* NOBARRIER: g->mmname[] is a GC root. */ - setgcref(g->mmname[i], obj2gco(s)); + /* NOBARRIER: g->gcroot[] is a GC root. */ + setgcref(g->gcroot[GCROOT_MMNAME+mm], obj2gco(s)); } } @@ -62,7 +61,7 @@ cTValue *lj_meta_lookup(lua_State *L, cTValue *o, MMS mm) else mt = tabref(basemt_obj(G(L), o)); if (mt) { - cTValue *mo = lj_tab_getstr(mt, strref(G(L)->mmname[mm])); + cTValue *mo = lj_tab_getstr(mt, mmname_str(G(L), mm)); if (mo) return mo; } diff --git a/src/lj_meta.h b/src/lj_meta.h index 9b2c3f73..0bb567cc 100644 --- a/src/lj_meta.h +++ b/src/lj_meta.h @@ -15,7 +15,7 @@ LJ_FUNC cTValue *lj_meta_lookup(lua_State *L, cTValue *o, MMS mm); #define lj_meta_fastg(g, mt, mm) \ ((mt) == NULL ? NULL : ((mt)->nomm & (1u<<(mm))) ? NULL : \ - lj_meta_cache(mt, mm, strref((g)->mmname[mm]))) + lj_meta_cache(mt, mm, mmname_str(g, mm))) #define lj_meta_fast(L, mt, mm) lj_meta_fastg(G(L), mt, mm) /* C helpers for some instructions, called from assembler VM. */ diff --git a/src/lj_obj.h b/src/lj_obj.h index b01bd97b..defb2088 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h @@ -537,15 +537,18 @@ MMDEF(MMENUM) /* GC root IDs. */ typedef enum { + GCROOT_MMNAME, /* Metamethod names. */ + GCROOT_MMNAME_LAST = GCROOT_MMNAME + MM_MAX-1, GCROOT_BASEMT, /* Metatables for base types. */ - GCROOT_BASEMT_NUM = ~LJ_TNUMX, /* Last base metatable. */ + GCROOT_BASEMT_NUM = GCROOT_BASEMT + ~LJ_TNUMX, GCROOT_IO_INPUT, /* Userdata for default I/O input file. */ GCROOT_IO_OUTPUT, /* Userdata for default I/O output file. */ - GCROOT__MAX + GCROOT_MAX } GCRootID; #define basemt_it(g, it) ((g)->gcroot[GCROOT_BASEMT+~(it)]) #define basemt_obj(g, o) ((g)->gcroot[GCROOT_BASEMT+itypemap(o)]) +#define mmname_str(g, mm) (strref((g)->gcroot[GCROOT_MMNAME+(mm)])) typedef struct GCState { MSize total; /* Memory currently allocated. */ @@ -595,8 +598,7 @@ typedef struct global_State { BCIns bc_cfunc_ext; /* Bytecode for external C function calls. */ GCRef jit_L; /* Current JIT code lua_State or NULL. */ MRef jit_base; /* Current JIT code L->base. */ - GCRef gcroot[GCROOT__MAX]; /* GC roots. */ - GCRef mmname[MM_MAX]; /* Array holding metamethod names. */ + GCRef gcroot[GCROOT_MAX]; /* GC roots. */ } global_State; #define mainthread(g) (&gcref(g->mainthref)->th) diff --git a/src/lj_record.c b/src/lj_record.c index c71aa1a4..b5e35076 100644 --- a/src/lj_record.c +++ b/src/lj_record.c @@ -677,14 +677,12 @@ static int rec_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm) emitir(IRTG(mt ? IR_NE : IR_EQ, IRT_TAB), mix.tab, lj_ir_knull(J, IRT_TAB)); nocheck: if (mt) { - GCstr *mmstr = strref(J2G(J)->mmname[mm]); + GCstr *mmstr = mmname_str(J2G(J), mm); cTValue *mo = lj_tab_getstr(mt, mmstr); if (mo && !tvisnil(mo)) copyTV(J->L, &ix->mobjv, mo); ix->mtv = mt; settabV(J->L, &mix.tabv, mt); - if (isdead(J2G(J), obj2gco(mmstr))) - flipwhite(obj2gco(mmstr)); /* Need same logic as lj_str_new(). */ setstrV(J->L, &mix.keyv, mmstr); mix.key = lj_ir_kstr(J, mmstr); mix.val = 0; @@ -914,9 +912,9 @@ static int nommstr(jit_State *J, TRef key) if (tref_isstr(key)) { if (tref_isk(key)) { GCstr *str = ir_kstr(IR(tref_ref(key))); - uint32_t i; - for (i = 0; i <= MM_FAST; i++) - if (strref(J2G(J)->mmname[i]) == str) + uint32_t mm; + for (mm = 0; mm <= MM_FAST; mm++) + if (mmname_str(J2G(J), mm) == str) return 0; /* MUST be one the fast metamethod names. */ } else { return 0; /* Variable string key MAY be a metamethod name. */ @@ -999,7 +997,7 @@ static TRef rec_idx(jit_State *J, RecordIndex *ix) /* Need to duplicate the hasmm check for the early guards. */ int hasmm = 0; if (ix->idxchain && mt) { - cTValue *mo = lj_tab_getstr(mt, strref(J2G(J)->mmname[MM_newindex])); + cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), MM_newindex)); hasmm = mo && !tvisnil(mo); } if (hasmm) diff --git a/src/lj_str.c b/src/lj_str.c index 9aa62582..7b38cecc 100644 --- a/src/lj_str.c +++ b/src/lj_str.c @@ -88,7 +88,8 @@ GCstr *lj_str_new(lua_State *L, const char *str, size_t lenx) for (o = gcref(g->strhash[h & g->strmask]); o != NULL; o = gcnext(o)) { GCstr *tso = gco2str(o); if (tso->len == len && (memcmp(str, strdata(tso), len) == 0)) { - if (isdead(g, o)) flipwhite(o); /* Resurrect if dead. */ + /* Resurrect if dead. Can only happen with fixstring() (keywords). */ + if (isdead(g, o)) flipwhite(o); return tso; /* Return existing string. */ } }