lgc.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505
  1. /*
  2. ** $Id: lgc.c,v 1.143 2002/07/17 16:25:13 roberto Exp $
  3. ** Garbage Collector
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <string.h>
  7. #include "lua.h"
  8. #include "ldebug.h"
  9. #include "ldo.h"
  10. #include "lfunc.h"
  11. #include "lgc.h"
  12. #include "lmem.h"
  13. #include "lobject.h"
  14. #include "lstate.h"
  15. #include "lstring.h"
  16. #include "ltable.h"
  17. #include "ltm.h"
  18. typedef struct GCState {
  19. Table *tmark; /* list of marked tables to be visited */
  20. Table *toclear; /* list of visited weak tables (to be cleared after GC) */
  21. lua_State *L;
  22. } GCState;
  23. /* mark a string; marks larger than 1 cannot be changed */
  24. #define strmark(s) {if ((s)->tsv.marked == 0) (s)->tsv.marked = 1;}
  25. /* unmarked tables are represented by pointing `mark' to themselves */
  26. #define ismarked(x) ((x)->mark != (x))
  27. /* `Table.flag' bits to indicate whether table is key-weak and/or value-weak */
  28. #define KEYWEAKBIT (TM_MODE+1) /* ORDER TM */
  29. #define VALUEWEAKBIT (TM_MODE+2)
  30. #define KEYWEAK (1<<KEYWEAKBIT)
  31. #define VALUEWEAK (1<<VALUEWEAKBIT)
  32. /* mark tricks for userdata */
  33. #define isudmarked(u) (u->uv.len & 1)
  34. #define markud(u) (u->uv.len |= 1)
  35. #define unmarkud(u) (u->uv.len &= (~(size_t)1))
  36. #define isfinalized(u) (u->uv.len & 2)
  37. #define markfinalized(u) (u->uv.len |= 2)
  38. /* mark tricks for upvalues (assume that open upvalues are always marked) */
  39. #define isupvalmarked(uv) ((uv)->v != &(uv)->value)
  40. #define ismarkable(o) (!((1 << ttype(o)) & \
  41. ((1 << LUA_TNIL) | (1 << LUA_TNUMBER) | \
  42. (1 << LUA_TBOOLEAN) | (1 << LUA_TLIGHTUSERDATA))))
  43. static void reallymarkobject (GCState *st, TObject *o);
  44. #define markobject(st,o) if (ismarkable(o)) reallymarkobject(st,o)
  45. static void protomark (Proto *f) {
  46. if (!f->marked) {
  47. int i;
  48. f->marked = 1;
  49. strmark(f->source);
  50. for (i=0; i<f->sizek; i++) {
  51. if (ttisstring(f->k+i))
  52. strmark(tsvalue(f->k+i));
  53. }
  54. for (i=0; i<f->sizep; i++)
  55. protomark(f->p[i]);
  56. for (i=0; i<f->sizelocvars; i++) /* mark local-variable names */
  57. strmark(f->locvars[i].varname);
  58. }
  59. lua_assert(luaG_checkcode(f));
  60. }
  61. static void marktable (GCState *st, Table *h) {
  62. if (!ismarked(h)) {
  63. h->mark = st->tmark; /* chain it for later traversal */
  64. st->tmark = h;
  65. }
  66. }
  67. static void markclosure (GCState *st, Closure *cl) {
  68. if (!cl->c.marked) {
  69. cl->c.marked = 1;
  70. if (cl->c.isC) {
  71. int i;
  72. for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */
  73. markobject(st, &cl->c.upvalue[i]);
  74. }
  75. else {
  76. int i;
  77. lua_assert(cl->l.nupvalues == cl->l.p->nupvalues);
  78. marktable(st, hvalue(&cl->l.g));
  79. protomark(cl->l.p);
  80. for (i=0; i<cl->l.nupvalues; i++) { /* mark its upvalues */
  81. UpVal *u = cl->l.upvals[i];
  82. if (!isupvalmarked(u)) {
  83. markobject(st, &u->value);
  84. u->v = NULL; /* mark it! */
  85. }
  86. }
  87. }
  88. }
  89. }
  90. static void markudata (GCState *st, Udata *u) {
  91. markud(u);
  92. marktable(st, u->uv.metatable);
  93. }
  94. static void reallymarkobject (GCState *st, TObject *o) {
  95. switch (ttype(o)) {
  96. case LUA_TSTRING:
  97. strmark(tsvalue(o));
  98. break;
  99. case LUA_TUSERDATA:
  100. if (!isudmarked(uvalue(o)))
  101. markudata(st, uvalue(o));
  102. break;
  103. case LUA_TFUNCTION:
  104. markclosure(st, clvalue(o));
  105. break;
  106. case LUA_TTABLE: {
  107. marktable(st, hvalue(o));
  108. break;
  109. }
  110. default: lua_assert(0); /* should not be called with other types */
  111. }
  112. }
  113. static void checkstacksizes (lua_State *L, StkId max) {
  114. int used = L->ci - L->base_ci; /* number of `ci' in use */
  115. if (4*used < L->size_ci && 2*BASIC_CI_SIZE < L->size_ci)
  116. luaD_reallocCI(L, L->size_ci/2); /* still big enough... */
  117. used = max - L->stack; /* part of stack in use */
  118. if (4*used < L->stacksize && 2*(BASIC_STACK_SIZE+EXTRA_STACK) < L->stacksize)
  119. luaD_reallocstack(L, L->stacksize/2); /* still big enough... */
  120. }
  121. static void markstacks (GCState *st) {
  122. lua_State *L1 = st->L;
  123. do { /* for each thread */
  124. StkId o, lim;
  125. CallInfo *ci;
  126. if (ttisnil(defaultmeta(L1))) { /* incomplete state? */
  127. lua_assert(L1 != st->L);
  128. L1 = L1->next;
  129. luaE_closethread(st->L, L1->previous); /* collect it */
  130. continue;
  131. }
  132. markobject(st, defaultmeta(L1));
  133. markobject(st, gt(L1));
  134. markobject(st, registry(L1));
  135. for (o=L1->stack; o<L1->top; o++)
  136. markobject(st, o);
  137. lim = o;
  138. for (ci = L1->base_ci; ci <= L1->ci; ci++) {
  139. lua_assert(ci->top <= L1->stack_last);
  140. if (lim < ci->top) lim = ci->top;
  141. }
  142. for (; o<=lim; o++) setnilvalue(o);
  143. checkstacksizes(L1, lim);
  144. lua_assert(L1->previous->next == L1 && L1->next->previous == L1);
  145. L1 = L1->next;
  146. } while (L1 != st->L);
  147. }
  148. static void marktmu (GCState *st) {
  149. Udata *u;
  150. for (u = G(st->L)->tmudata; u; u = u->uv.next)
  151. markudata(st, u);
  152. }
  153. /* move `dead' udata that need finalization to list `tmudata' */
  154. static void separateudata (lua_State *L) {
  155. Udata **p = &G(L)->rootudata;
  156. Udata *curr;
  157. Udata *collected = NULL; /* to collect udata with gc event */
  158. Udata **lastcollected = &collected;
  159. while ((curr = *p) != NULL) {
  160. if (isudmarked(curr) || isfinalized(curr) ||
  161. (fasttm(L, curr->uv.metatable, TM_GC) == NULL))
  162. p = &curr->uv.next;
  163. else { /* must call its gc method */
  164. *p = curr->uv.next;
  165. curr->uv.next = NULL; /* link `curr' at the end of `collected' list */
  166. *lastcollected = curr;
  167. lastcollected = &curr->uv.next;
  168. }
  169. }
  170. /* insert collected udata with gc event into `tmudata' list */
  171. *lastcollected = G(L)->tmudata;
  172. G(L)->tmudata = collected;
  173. }
  174. static void removekey (Node *n) {
  175. setnilvalue(val(n)); /* remove corresponding value ... */
  176. if (ismarkable(key(n)))
  177. setttype(key(n), LUA_TNONE); /* dead key; remove it */
  178. }
  179. static void traversetable (GCState *st, Table *h) {
  180. int i;
  181. const TObject *mode;
  182. int weakkey = 0;
  183. int weakvalue = 0;
  184. marktable(st, h->metatable);
  185. lua_assert(h->lsizenode || h->node == G(st->L)->dummynode);
  186. mode = fasttm(st->L, h->metatable, TM_MODE);
  187. if (mode && ttisstring(mode)) { /* weak table? */
  188. h->mark = st->toclear; /* must be cleared after GC, ... */
  189. st->toclear = h; /* ...put in the appropriate list */
  190. weakkey = (strchr(svalue(mode), 'k') != NULL);
  191. weakvalue = (strchr(svalue(mode), 'v') != NULL);
  192. h->flags &= ~(KEYWEAK | VALUEWEAK); /* clear bits */
  193. h->flags |= (weakkey << KEYWEAKBIT) | (weakvalue << VALUEWEAKBIT);
  194. }
  195. if (!weakvalue) {
  196. i = sizearray(h);
  197. while (i--)
  198. markobject(st, &h->array[i]);
  199. }
  200. i = sizenode(h);
  201. while (i--) {
  202. Node *n = node(h, i);
  203. if (!ttisnil(val(n))) {
  204. lua_assert(!ttisnil(key(n)));
  205. if (!weakkey) markobject(st, key(n));
  206. if (!weakvalue) markobject(st, val(n));
  207. }
  208. }
  209. }
  210. static void propagatemarks (GCState *st) {
  211. while (st->tmark) { /* traverse marked tables */
  212. Table *h = st->tmark; /* get first table from list */
  213. st->tmark = h->mark; /* remove it from list */
  214. traversetable(st, h);
  215. }
  216. }
  217. static int hasmark (const TObject *o) {
  218. switch (ttype(o)) {
  219. case LUA_TUSERDATA:
  220. return isudmarked(uvalue(o));
  221. case LUA_TTABLE:
  222. return ismarked(hvalue(o));
  223. case LUA_TFUNCTION:
  224. return clvalue(o)->c.marked;
  225. case LUA_TSTRING:
  226. strmark(tsvalue(o)); /* strings are `values', so are never weak */
  227. /* go through */
  228. default: /* number, nil, boolean, udataval */
  229. return 1;
  230. }
  231. }
  232. /*
  233. ** clear collected keys from weaktables
  234. */
  235. static void cleartablekeys (GCState *st) {
  236. Table *h;
  237. for (h = st->toclear; h; h = h->mark) {
  238. int i;
  239. if (!(h->flags & KEYWEAK)) continue;
  240. lua_assert(strchr(svalue(fasttm(st->L, h->metatable, TM_MODE)), 'k'));
  241. i = sizenode(h);
  242. while (i--) {
  243. Node *n = node(h, i);
  244. if (!hasmark(key(n)))
  245. removekey(n); /* ... and key */
  246. }
  247. }
  248. }
  249. /*
  250. ** clear collected values from weaktables
  251. */
  252. static void cleartablevalues (GCState *st) {
  253. Table *h;
  254. for (h = st->toclear; h; h = h->mark) {
  255. int i;
  256. if (!(h->flags & VALUEWEAK)) continue;
  257. lua_assert(strchr(svalue(fasttm(st->L, h->metatable, TM_MODE)), 'v'));
  258. i = sizearray(h);
  259. while (i--) {
  260. TObject *o = &h->array[i];
  261. if (!hasmark(o))
  262. setnilvalue(o); /* remove value */
  263. }
  264. i = sizenode(h);
  265. while (i--) {
  266. Node *n = node(h, i);
  267. if (!hasmark(val(n)))
  268. removekey(n); /* ... and key */
  269. }
  270. }
  271. }
  272. static void collectproto (lua_State *L) {
  273. Proto **p = &G(L)->rootproto;
  274. Proto *curr;
  275. while ((curr = *p) != NULL) {
  276. if (curr->marked) {
  277. curr->marked = 0;
  278. p = &curr->next;
  279. }
  280. else {
  281. *p = curr->next;
  282. luaF_freeproto(L, curr);
  283. }
  284. }
  285. }
  286. static void collectclosures (lua_State *L) {
  287. Closure **p = &G(L)->rootcl;
  288. Closure *curr;
  289. while ((curr = *p) != NULL) {
  290. if (curr->c.marked) {
  291. curr->c.marked = 0;
  292. p = &curr->c.next;
  293. }
  294. else {
  295. *p = curr->c.next;
  296. luaF_freeclosure(L, curr);
  297. }
  298. }
  299. }
  300. static void collectupval (lua_State *L) {
  301. UpVal **v = &G(L)->rootupval;
  302. UpVal *curr;
  303. while ((curr = *v) != NULL) {
  304. if (isupvalmarked(curr)) {
  305. lua_assert(curr->v == NULL);
  306. curr->v = &curr->value; /* unmark */
  307. v = &curr->next; /* next */
  308. }
  309. else {
  310. *v = curr->next; /* next */
  311. luaM_freelem(L, curr);
  312. }
  313. }
  314. }
  315. static void collecttable (lua_State *L) {
  316. Table **p = &G(L)->roottable;
  317. Table *curr;
  318. while ((curr = *p) != NULL) {
  319. if (ismarked(curr)) {
  320. curr->mark = curr; /* unmark */
  321. p = &curr->next;
  322. }
  323. else {
  324. *p = curr->next;
  325. luaH_free(L, curr);
  326. }
  327. }
  328. }
  329. static void collectudata (lua_State *L) {
  330. Udata **p = &G(L)->rootudata;
  331. Udata *curr;
  332. while ((curr = *p) != NULL) {
  333. if (isudmarked(curr)) {
  334. unmarkud(curr);
  335. p = &curr->uv.next;
  336. }
  337. else {
  338. *p = curr->uv.next;
  339. luaM_free(L, curr, sizeudata(curr->uv.len & (~(size_t)3)));
  340. }
  341. }
  342. }
  343. static void collectstrings (lua_State *L, int all) {
  344. int i;
  345. for (i=0; i<G(L)->strt.size; i++) { /* for each list */
  346. TString **p = &G(L)->strt.hash[i];
  347. TString *curr;
  348. while ((curr = *p) != NULL) {
  349. if (curr->tsv.marked && !all) { /* preserve? */
  350. if (curr->tsv.marked < FIXMARK) /* does not change FIXMARKs */
  351. curr->tsv.marked = 0;
  352. p = &curr->tsv.nexthash;
  353. }
  354. else { /* collect */
  355. *p = curr->tsv.nexthash;
  356. G(L)->strt.nuse--;
  357. luaM_free(L, curr, sizestring(curr->tsv.len));
  358. }
  359. }
  360. }
  361. if (G(L)->strt.nuse < cast(ls_nstr, G(L)->strt.size/4) &&
  362. G(L)->strt.size > MINSTRTABSIZE*2)
  363. luaS_resize(L, G(L)->strt.size/2); /* table is too big */
  364. }
  365. #define MINBUFFER 256
  366. static void checkMbuffer (lua_State *L) {
  367. if (G(L)->Mbuffsize > MINBUFFER*2) { /* is buffer too big? */
  368. size_t newsize = G(L)->Mbuffsize/2; /* still larger than MINBUFFER */
  369. luaM_reallocvector(L, G(L)->Mbuffer, G(L)->Mbuffsize, newsize, char);
  370. G(L)->Mbuffsize = newsize;
  371. }
  372. }
  373. static void do1gcTM (lua_State *L, Udata *udata) {
  374. const TObject *tm = fasttm(L, udata->uv.metatable, TM_GC);
  375. if (tm != NULL) {
  376. setobj(L->top, tm);
  377. setuvalue(L->top+1, udata);
  378. L->top += 2;
  379. luaD_call(L, L->top - 2, 0);
  380. }
  381. }
  382. static void callGCTM (lua_State *L) {
  383. int oldah = allowhook(L);
  384. setallowhook(L, 0); /* stop debug hooks during GC tag methods */
  385. L->top++; /* reserve space to keep udata while runs its gc method */
  386. while (G(L)->tmudata != NULL) {
  387. Udata *udata = G(L)->tmudata;
  388. G(L)->tmudata = udata->uv.next; /* remove udata from `tmudata' */
  389. udata->uv.next = G(L)->rootudata; /* return it to `root' list */
  390. G(L)->rootudata = udata;
  391. setuvalue(L->top - 1, udata); /* keep a reference to it */
  392. unmarkud(udata);
  393. markfinalized(udata);
  394. do1gcTM(L, udata);
  395. }
  396. L->top--;
  397. setallowhook(L, oldah); /* restore hooks */
  398. }
  399. void luaC_callallgcTM (lua_State *L) {
  400. separateudata(L);
  401. callGCTM(L); /* call their GC tag methods */
  402. }
  403. void luaC_collect (lua_State *L, int all) {
  404. collectudata(L);
  405. collectstrings(L, all);
  406. collecttable(L);
  407. collectproto(L);
  408. collectupval(L);
  409. collectclosures(L);
  410. }
  411. void luaC_collectgarbage (lua_State *L) {
  412. GCState st;
  413. st.L = L;
  414. st.tmark = NULL;
  415. st.toclear = NULL;
  416. markstacks(&st); /* mark all stacks */
  417. propagatemarks(&st); /* mark all reachable objects */
  418. cleartablevalues(&st);
  419. separateudata(L); /* separate userdata to be preserved */
  420. marktmu(&st); /* mark `preserved' userdata */
  421. propagatemarks(&st); /* remark */
  422. cleartablekeys(&st);
  423. luaC_collect(L, 0);
  424. checkMbuffer(L);
  425. G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
  426. callGCTM(L);
  427. }