From 6194b1c896c78c2ba0436053dcae596725317e9c Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 8 Feb 2010 05:30:57 +0100 Subject: Redesign of prototype generation, part 5: colocation of protoype arrays. --- src/lj_parse.c | 117 ++++++++++++++++++++++++++++++--------------------------- 1 file changed, 61 insertions(+), 56 deletions(-) (limited to 'src/lj_parse.c') diff --git a/src/lj_parse.c b/src/lj_parse.c index ec355403..678dc4fa 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c @@ -853,7 +853,7 @@ static void bcemit_unop(FuncState *fs, BCOp op, ExpDesc *e) } else if (expr_isk(e)) { e->k = VKFALSE; return; - } else if (e->k == VJMP) { + } else if (e->k == VJMP) { invertcond(fs, e); return; } else if (e->k == VRELOCABLE) { @@ -1026,22 +1026,32 @@ static MSize var_lookup_(FuncState *fs, GCstr *name, ExpDesc *e, int first) /* -- Function state management ------------------------------------------- */ +/* NYI: compress debug info. */ + +/* Fixup bytecode and lineinfo for prototype. */ +static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, BCLine *lineinfo) +{ + MSize i, n = fs->pc; + BCInsLine *base = fs->bcbase; + setmref(pt->bc, bc); + setmref(pt->lineinfo, lineinfo); + pt->sizebc = n; + bc[n] = ~0u; /* Close potentially uninitialized gap between bc and kgc. */ + for (i = 0; i < n; i++) { + bc[i] = base[i].ins; + lineinfo[i] = base[i].line; + } +} + /* Fixup constants for prototype. */ -static void fs_fixup_k(FuncState *fs, GCproto *pt) +static void fs_fixup_k(FuncState *fs, GCproto *pt, void *kptr) { GCtab *kt; TValue *array; Node *node; - BCReg nkgc; - MSize i, hmask, sizek; - GCRef *kptr; + MSize i, hmask; 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)); - 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; @@ -1060,7 +1070,7 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt) ((lua_Number *)kptr)[kidx] = numV(&n->key); } else { GCobj *o = gcV(&n->key); - setgcref(kptr[~kidx], o); + setgcref(((GCRef *)kptr)[~kidx], o); lj_gc_objbarrier(fs->L, pt, o); } } @@ -1068,16 +1078,29 @@ static void fs_fixup_k(FuncState *fs, GCproto *pt) } /* Fixup upvalues for prototype. */ -static void fs_fixup_uv(FuncState *fs, GCproto *pt) +static void fs_fixup_uv(FuncState *fs, GCproto *pt, uint16_t *uv) { MSize i, n = fs->nuv; - uint16_t *uv = lj_mem_newvec(fs->L, n, uint16_t); setmref(pt->uv, uv); pt->sizeuv = n; for (i = 0; i < n; i++) uv[i] = fs->uvloc[i].slot; } +/* Fixup debug info for prototype. */ +static void fs_fixup_dbg(FuncState *fs, GCproto *pt, VarInfo *vi, MSize sizevi) +{ + MSize i, n = fs->nuv; + GCRef *uvname = (GCRef *)((char *)vi + sizevi*sizeof(VarInfo)); + VarInfo *vstack = fs->ls->vstack; + setmref(pt->varinfo, vi); + setmref(pt->uvname, uvname); + pt->sizevarinfo = sizevi; + memcpy(vi, &vstack[fs->vbase], sizevi*sizeof(VarInfo)); + for (i = 0; i < n; i++) + setgcref(uvname[i], gcref(vstack[fs->uvloc[i].vidx].name)); +} + /* Check if bytecode op returns. */ static int bcopisret(BCOp op) { @@ -1128,6 +1151,8 @@ static GCproto *fs_finish(LexState *ls, BCLine line) { lua_State *L = ls->L; FuncState *fs = ls->fs; + MSize sizevi; + size_t sizept, ofsk, ofsuv, ofsdbg, ofsli; GCproto *pt; /* Apply final fixups. */ @@ -1135,61 +1160,41 @@ static GCproto *fs_finish(LexState *ls, BCLine line) lua_assert(fs->bl == NULL); fs_fixup_ret(fs); + /* Calculate total size of prototype including all colocated arrays. */ + sizept = sizeof(GCproto) + fs->pc*sizeof(BCIns) + fs->nkgc*sizeof(GCRef); + sizept = (sizept + sizeof(lua_Number)-1) & ~(sizeof(lua_Number)-1); + ofsk = sizept; + sizept += fs->nkn*sizeof(lua_Number); + ofsuv = sizept; + sizept += ((fs->nuv+1)&~1)*2; + ofsdbg = sizept; + sizevi = ls->vtop - fs->vbase; + sizept += sizevi*sizeof(VarInfo) + fs->nuv*sizeof(GCRef); + ofsli = sizept; + sizept += fs->pc*sizeof(BCLine); + /* Allocate prototype and initialize its fields. */ - pt = lj_func_newproto(L); + pt = (GCproto *)lj_mem_newgco(L, (MSize)sizept); + pt->gct = ~LJ_TPROTO; + pt->sizept = (MSize)sizept; setgcref(pt->chunkname, obj2gco(ls->chunkname)); + pt->trace = 0; pt->flags = fs->flags; pt->numparams = fs->numparams; pt->framesize = fs->framesize; pt->linedefined = fs->linedefined; pt->lastlinedefined = line; - /* Anchor prototype since allocation of the arrays may fail. */ - setprotoV(L, L->top, pt); - incr_top(L); - - fs_fixup_k(fs, pt); - fs_fixup_uv(fs, pt); - - { - MSize i, n = fs->pc; - BCInsLine *base = fs->bcbase; - BCLine *lineinfo; - BCIns *bc = lj_mem_newvec(L, n, BCIns); - setmref(pt->bc, bc); - pt->sizebc = fs->pc; - lineinfo = lj_mem_newvec(L, n, BCLine); - setmref(pt->lineinfo, lineinfo); - pt->sizelineinfo = n; - for (i = 0; i < n; i++) { - bc[i] = base[i].ins; - lineinfo[i] = base[i].line; - } - } - - { - MSize n = ls->vtop - fs->vbase; - VarInfo *vi = lj_mem_newvec(L, n, VarInfo); - memcpy(vi, &ls->vstack[fs->vbase], n*sizeof(VarInfo)); - setmref(pt->varinfo, vi); - pt->sizevarinfo = n; - } - - { - MSize i, n = fs->nuv; - GCRef *uvname = lj_mem_newvec(L, n, GCRef); - for (i = 0; i < n; i++) - setgcref(uvname[i], gcref(ls->vstack[fs->uvloc[i].vidx].name)); - setmref(pt->uvname, uvname); - pt->sizeuvname = n; - } + fs_fixup_bc(fs, pt, (BCIns *)((char *)pt + sizeof(GCproto)), + (BCLine *)((char *)pt + ofsli)); + fs_fixup_k(fs, pt, (void *)((char *)pt + ofsk)); + fs_fixup_uv(fs, pt, (uint16_t *)((char *)pt + ofsuv)); + fs_fixup_dbg(fs, pt, (VarInfo *)((char *)pt + ofsdbg), sizevi); lj_vmevent_send(L, BC, setprotoV(L, L->top++, pt); ); - L->top--; /* Pop prototype. */ - L->top--; /* Pop table of constants. */ ls->vtop = fs->vbase; /* Reset variable stack. */ ls->fs = fs->prev; @@ -1427,7 +1432,7 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) lex_match(ls, TK_end, TK_function, line); pt = fs_finish(ls, lastline); fs->bcbase = ls->bcstack + oldbase; /* May have been reallocated. */ - fs->bclim = ls->sizebcstack - oldbase; + fs->bclim = (BCPos)(ls->sizebcstack - oldbase); /* Store new prototype in the constant array of the parent. */ kidx = const_gc(fs, obj2gco(pt), LJ_TPROTO); expr_init(e, VRELOCABLE, bcemit_AD(fs, BC_FNEW, 0, kidx)); -- cgit v1.2.3-55-g6feb