Make metamethod names proper GC roots.

master
Mike Pall 2010-04-25 18:35:47 +02:00
parent 87e4daf89c
commit ef0904e80b
12 changed files with 26 additions and 29 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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));

View File

@ -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<<MM_index));
return 1;
}

View File

@ -213,7 +213,7 @@ static const char *getfuncname(lua_State *L, TValue *frame, const char **name)
if (bc_op(*ip) == BC_ITERC) slot -= 3;
return getobjname(funcproto(fn), ip, slot, name);
} else if (mm != MM_MAX) {
*name = strdata(strref(G(L)->mmname[mm]));
*name = strdata(mmname_str(G(L), mm));
return "metamethod";
} else {
return NULL;

View File

@ -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]));
}

View File

@ -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;
}

View File

@ -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. */

View File

@ -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)

View File

@ -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)

View File

@ -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. */
}
}