static void atomic (lua_State *L) { global_State *g = G(L); GCObject *origweak, *origall; lua_assert(!iswhite(obj2gco(g->mainthread))); markobject(g, L); /* mark running thread */ /* registry and global metatables may be changed by API */ markvalue(g, &g->l_registry); markmt(g); /* mark basic metatables */ /* remark occasional upvalues of (maybe) dead threads */ remarkupvals(g); /* traverse objects caught by write barrier and by 'remarkupvals' */ retraversegrays(g); convergeephemerons(g); /* at this point, all strongly accessible objects are marked. */ /* clear values from weak tables, before checking finalizers */ clearvalues(g->weak, NULL); clearvalues(g->allweak, NULL); origweak = g->weak; origall = g->allweak; separatetobefnz(L, 0); /* separate objects to be finalized */ markbeingfnz(g); /* mark userdata that will be finalized */ propagateall(g); /* remark, to propagate `preserveness' */ convergeephemerons(g); /* at this point, all resurrected objects are marked. */ /* remove dead objects from weak tables */ clearkeys(g->ephemeron, NULL); /* clear keys from all ephemeron tables */ clearkeys(g->allweak, NULL); /* clear keys from all allweak tables */ /* clear values from resurrected weak tables */ clearvalues(g->weak, origweak); clearvalues(g->allweak, origall); g->sweepstrgc = 0; /* prepare to sweep strings */ g->gcstate = GCSsweepstring; g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ /*lua_checkmemory(L);*/ }
static l_mem atomic (lua_State *L) { global_State *g = G(L); l_mem work; GCObject *origweak, *origall; GCObject *grayagain = g->grayagain; /* save original list */ lua_assert(g->ephemeron == NULL && g->weak == NULL); lua_assert(!iswhite(g->mainthread)); g->gcstate = GCSinsideatomic; g->GCmemtrav = 0; /* start counting work */ markobject(g, L); /* mark running thread */ /* registry and global metatables may be changed by API */ markvalue(g, &g->l_registry); markmt(g); /* mark global metatables */ /* remark occasional upvalues of (maybe) dead threads */ remarkupvals(g); propagateall(g); /* propagate changes */ work = g->GCmemtrav; /* stop counting (do not recount 'grayagain') */ g->gray = grayagain; propagateall(g); /* traverse 'grayagain' list */ g->GCmemtrav = 0; /* restart counting */ convergeephemerons(g); /* at this point, all strongly accessible objects are marked. */ /* Clear values from weak tables, before checking finalizers */ clearvalues(g, g->weak, NULL); clearvalues(g, g->allweak, NULL); origweak = g->weak; origall = g->allweak; work += g->GCmemtrav; /* stop counting (objects being finalized) */ separatetobefnz(g, 0); /* separate objects to be finalized */ g->gcfinnum = 1; /* there may be objects to be finalized */ markbeingfnz(g); /* mark objects that will be finalized */ propagateall(g); /* remark, to propagate 'resurrection' */ g->GCmemtrav = 0; /* restart counting */ convergeephemerons(g); /* at this point, all resurrected objects are marked. */ /* remove dead objects from weak tables */ clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ clearkeys(g, g->allweak, NULL); /* clear keys from all 'allweak' tables */ /* clear values from resurrected weak tables */ clearvalues(g, g->weak, origweak); clearvalues(g, g->allweak, origall); luaS_clearcache(g); g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ work += g->GCmemtrav; /* complete counting */ return work; /* estimate of memory marked by 'atomic' */ }
static l_mem atomic (lua_State *L) { global_State *g = G(L); l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ GCObject *origweak, *origall; lua_assert(!iswhite(obj2gco(g->mainthread))); markobject(g, L); /* mark running thread */ /* registry and global metatables may be changed by API */ markvalue(g, &g->l_registry); markmt(g); /* mark basic metatables */ /* remark occasional upvalues of (maybe) dead threads */ remarkupvals(g); propagateall(g); /* propagate changes */ work += g->GCmemtrav; /* stop counting (do not (re)count grays) */ /* traverse objects caught by write barrier and by 'remarkupvals' */ retraversegrays(g); work -= g->GCmemtrav; /* restart counting */ convergeephemerons(g); /* at this point, all strongly accessible objects are marked. */ /* clear values from weak tables, before checking finalizers */ clearvalues(g, g->weak, NULL); clearvalues(g, g->allweak, NULL); origweak = g->weak; origall = g->allweak; work += g->GCmemtrav; /* stop counting (objects being finalized) */ separatetobefnz(L, 0); /* separate objects to be finalized */ markbeingfnz(g); /* mark objects that will be finalized */ propagateall(g); /* remark, to propagate `preserveness' */ work -= g->GCmemtrav; /* restart counting */ convergeephemerons(g); /* at this point, all resurrected objects are marked. */ /* remove dead objects from weak tables */ clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */ /* clear values from resurrected weak tables */ clearvalues(g, g->weak, origweak); clearvalues(g, g->allweak, origall); g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ work += g->GCmemtrav; /* complete counting */ return work; /* estimate of memory marked by 'atomic' */ }
void assemble(char *outname) { char *aline; int dataoffset, stringsoffset, linkisoffset; int datalen, stringslen, linkislen, oldlineno; struct export *e, *eo; numfuncs = 0; numlinkis = 0; temptype = -2; if(src == NULL) return; if(verbose) fprintf(stderr, "\n%s: Assembling file `%s'\n", progname, src->filename); errors = 0; makearea(&oheaders); makearea(&ostrings); makearea(&odata); makearea(&olinkis); PARENTO = addonestrtoarea(outname); /* build header */ addinttoarea(&oheaders, 0x6a624f51); /* "QObj" */ addinttoarea(&oheaders, -1); /* creator string */ addinttoarea(&oheaders, -1); /* num funcs */ addinttoarea(&oheaders, 60); /* address func headers */ addinttoarea(&oheaders, -1); /* procos */ addinttoarea(&oheaders, 0); /* reserved */ addinttoarea(&oheaders, 2); /* obj format version */ addinttoarea(&oheaders, 0); /* address code/data */ addinttoarea(&oheaders, 0); /* length code/data */ addinttoarea(&oheaders, 0); /* address strings */ addinttoarea(&oheaders, 0); /* length strings */ addinttoarea(&oheaders, 0); /* address linkis */ addinttoarea(&oheaders, 0); /* length linkis */ addinttoarea(&oheaders, 0); /* address debug info */ addinttoarea(&oheaders, 0); /* length debug info */ strcpy(creator, "qas RISC OS ARM Assembler vsn "VERS" © Stu Smith ["__DATE__"]"); strcpy(procos, "ARM/RISCOS"); funcheadsoff = oheaders.used; /* assemble line-by-line */ parseinit(); clearvalues(&llabels); clearvalues(&rns); clearvalues(&fns); clearvalues(&cns); clearvalues(&sets); while(src) { aline = getline(); decomment(aline); stripw(aline); if(*aline) { assmline(aline); } } endprevfunc(); placeint(&oheaders, addonestrtoarea(creator), 4); placeint(&oheaders, addonestrtoarea(procos), 16); placeint(&oheaders, numfuncs, 8); /* concat headers-data-strings */ alignarea(&oheaders); alignarea(&odata); alignarea(&ostrings); dataoffset = addtoarea(&oheaders, odata.mem, odata.used); datalen = odata.used; droparea(&odata); alignarea(&oheaders); linkisoffset = addtoarea(&oheaders, olinkis.mem, olinkis.used); linkislen = olinkis.used; droparea(&olinkis); alignarea(&oheaders); stringsoffset = addtoarea(&oheaders, ostrings.mem, ostrings.used); stringslen = ostrings.used; droparea(&ostrings); alignarea(&oheaders); if(numfuncs == 0) error("No symbols defined"); placeint(&oheaders, dataoffset, 28); placeint(&oheaders, datalen, 32); placeint(&oheaders, stringsoffset, 36); placeint(&oheaders, stringslen, 40); placeint(&oheaders, linkisoffset, 44); placeint(&oheaders, linkislen, 48); placeint(&oheaders, 0, 52); placeint(&oheaders, 0, 56); e = exportlist; while(e) { oldlineno = lineno; lineno = e->line; error("Can't export symbol `%s': not defined", e->symname); lineno = oldlineno; freemem(e->symname); eo = e->next; freemem(e); e = eo; } exportlist = NULL; /* save object file */ #ifndef DEBUG if(errors == 0) #endif saveblock(outname, oheaders.mem, oheaders.used); droparea(&oheaders); }