/* Save current trace by copying and compacting it. */ static void trace_save(jit_State *J) { size_t sztr = ((sizeof(GCtrace)+7)&~7); size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); size_t sz = sztr + szins + J->cur.nsnap*sizeof(SnapShot) + J->cur.nsnapmap*sizeof(SnapEntry); GCtrace *T = lj_mem_newt(J->L, (MSize)sz, GCtrace); char *p = (char *)T + sztr; memcpy(T, &J->cur, sizeof(GCtrace)); setgcrefr(T->nextgc, J2G(J)->gc.root); setgcrefp(J2G(J)->gc.root, T); newwhite(J2G(J), T); T->gct = ~LJ_TTRACE; T->ir = (IRIns *)p - J->cur.nk; memcpy(p, J->cur.ir+J->cur.nk, szins); p += szins; TRACE_APPENDVEC(snap, nsnap, SnapShot) TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry) J->cur.traceno = 0; setgcrefp(J->trace[T->traceno], T); lj_gc_barriertrace(J2G(J), T->traceno); lj_gdbjit_addtrace(J, T); #ifdef LUAJIT_USE_PERFTOOLS perftools_addtrace(T); #endif }
/* Find existing open upvalue for a stack slot or create a new one. */ static GCupval *func_finduv(lua_State *L, TValue *slot) { global_State *g = G(L); GCRef *pp = &L->openupval; GCupval *p; GCupval *uv; /* Search the sorted list of open upvalues. */ while (gcref(*pp) != NULL && uvval((p = gco2uv(gcref(*pp)))) >= slot) { lua_assert(!p->closed && uvval(p) != &p->tv); if (uvval(p) == slot) { /* Found open upvalue pointing to same slot? */ if (isdead(g, obj2gco(p))) /* Resurrect it, if it's dead. */ flipwhite(obj2gco(p)); return p; } pp = &p->nextgc; } /* No matching upvalue found. Create a new one. */ uv = lj_mem_newt(L, sizeof(GCupval), GCupval); newwhite(g, uv); uv->gct = ~LJ_TUPVAL; uv->closed = 0; /* Still open. */ setmref(uv->v, slot); /* Pointing to the stack slot. */ /* NOBARRIER: The GCupval is new (marked white) and open. */ setgcrefr(uv->nextgc, *pp); /* Insert into sorted list of open upvalues. */ setgcref(*pp, obj2gco(uv)); setgcref(uv->prev, obj2gco(&g->uvhead)); /* Insert into GC list, too. */ setgcrefr(uv->next, g->uvhead.next); setgcref(uvnext(uv)->prev, obj2gco(uv)); setgcref(g->uvhead.next, obj2gco(uv)); lua_assert(uvprev(uvnext(uv)) == uv && uvnext(uvprev(uv)) == uv); return uv; }
GCudata *lj_udata_new(lua_State *L, MSize sz, GCtab *env) { GCudata *ud = lj_mem_newt(L, sizeof(GCudata) + sz, GCudata); global_State *g = G(L); newwhite(g, ud); /* Not finalized. */ ud->gct = ~LJ_TUDATA; ud->udtype = UDTYPE_USERDATA; ud->len = sz; /* NOBARRIER: The GCudata is new (marked white). */ setgcrefnull(ud->metatable); setgcref(ud->env, obj2gco(env)); /* Chain to userdata list (after main thread). */ setgcrefr(ud->nextgc, mainthread(g)->nextgc); setgcref(mainthread(g)->nextgc, obj2gco(ud)); return ud; }
/* Allocate variable-sized or specially aligned C data object. */ GCcdata *lj_cdata_newv(lua_State *L, CTypeID id, CTSize sz, CTSize align) { global_State *g; MSize extra = sizeof(GCcdataVar) + sizeof(GCcdata) + (align > CT_MEMALIGN ? (1u<<align) - (1u<<CT_MEMALIGN) : 0); char *p = lj_mem_newt(L, extra + sz, char); uintptr_t adata = (uintptr_t)p + sizeof(GCcdataVar) + sizeof(GCcdata); uintptr_t almask = (1u << align) - 1u; GCcdata *cd = (GCcdata *)(((adata + almask) & ~almask) - sizeof(GCcdata)); lua_assert((char *)cd - p < 65536); cdatav(cd)->offset = (uint16_t)((char *)cd - p); cdatav(cd)->extra = extra; cdatav(cd)->len = sz; g = G(L); setgcrefr(cd->nextgc, g->gc.root); setgcref(g->gc.root, obj2gco(cd)); newwhite(g, obj2gco(cd)); cd->marked |= 0x80; cd->gct = ~LJ_TCDATA; cd->ctypeid = id; return cd; }
/* Save current trace by copying and compacting it. */ static void trace_save(jit_State *J, GCtrace *T) { size_t sztr = ((sizeof(GCtrace)+7)&~7); size_t szins = (J->cur.nins-J->cur.nk)*sizeof(IRIns); char *p = (char *)T + sztr; memcpy(T, &J->cur, sizeof(GCtrace)); setgcrefr(T->nextgc, J2G(J)->gc.root); setgcrefp(J2G(J)->gc.root, T); newwhite(J2G(J), T); T->gct = ~LJ_TTRACE; T->ir = (IRIns *)p - J->cur.nk; /* The IR has already been copied above. */ p += szins; TRACE_APPENDVEC(snap, nsnap, SnapShot) TRACE_APPENDVEC(snapmap, nsnapmap, SnapEntry) J->cur.traceno = 0; J->curfinal = NULL; setgcrefp(J->trace[T->traceno], T); lj_gc_barriertrace(J2G(J), T->traceno); lj_gdbjit_addtrace(J, T); #ifdef LUAJIT_USE_PERFTOOLS perftools_addtrace(T); #endif }