diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-17 11:28:06 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-04-17 11:28:06 -0300 |
commit | 4f88418170d298b065a7f71d86b1127153919ae9 (patch) | |
tree | 7e9c403890b4fe7ac13d501242cfdd967bf0285e /lgc.c | |
parent | 311e9f3ceb19eefe30a1b5f90dfad9898d8bac74 (diff) | |
download | lua-4f88418170d298b065a7f71d86b1127153919ae9.tar.gz lua-4f88418170d298b065a7f71d86b1127153919ae9.tar.bz2 lua-4f88418170d298b065a7f71d86b1127153919ae9.zip |
'CallInfo' stack implemented as double-linked list instead of an array
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 39 |
1 files changed, 19 insertions, 20 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.48 2009/02/17 19:47:58 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.49 2009/03/10 17:14:37 roberto Exp roberto $ |
3 | ** Garbage Collector | 3 | ** Garbage Collector |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -379,38 +379,34 @@ static void traverseclosure (global_State *g, Closure *cl) { | |||
379 | } | 379 | } |
380 | 380 | ||
381 | 381 | ||
382 | static void checkstacksizes (lua_State *L, StkId max) { | 382 | static void checkstacksize (lua_State *L, StkId max) { |
383 | /* should not change the stack when handling overflow or | 383 | /* should not change the stack during an emergency gc cycle */ |
384 | during an emergency gc cycle */ | 384 | if (G(L)->gckind == KGC_EMERGENCY) |
385 | if (L->size_ci > LUAI_MAXCALLS || G(L)->gckind == KGC_EMERGENCY) | 385 | return; /* do not touch the stack */ |
386 | return; /* do not touch the stacks */ | ||
387 | else { | 386 | else { |
388 | int ci_used = cast_int(L->ci - L->base_ci) + 1; /* number of `ci' in use */ | ||
389 | int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */ | 387 | int s_used = cast_int(max - L->stack) + 1; /* part of stack in use */ |
390 | if (2*ci_used < L->size_ci) | ||
391 | luaD_reallocCI(L, 2*ci_used); | ||
392 | if (2*s_used < (L->stacksize - EXTRA_STACK)) | 388 | if (2*s_used < (L->stacksize - EXTRA_STACK)) |
393 | luaD_reallocstack(L, 2*s_used); | 389 | luaD_reallocstack(L, 2*s_used); |
394 | } | 390 | } |
395 | } | 391 | } |
396 | 392 | ||
397 | 393 | ||
398 | static void traversestack (global_State *g, lua_State *l) { | 394 | static void traversestack (global_State *g, lua_State *L) { |
399 | StkId o, lim; | 395 | StkId o, lim; |
400 | CallInfo *ci; | 396 | CallInfo *ci; |
401 | if (l->stack == NULL || l->base_ci == NULL) | 397 | if (L->stack == NULL) |
402 | return; /* stack not completely built yet */ | 398 | return; /* stack not completely built yet */ |
403 | markvalue(g, gt(l)); | 399 | markvalue(g, gt(L)); |
404 | lim = l->top; | 400 | lim = L->top; |
405 | for (ci = l->base_ci; ci <= l->ci; ci++) { | 401 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
406 | lua_assert(ci->top <= l->stack_last); | 402 | lua_assert(ci->top <= L->stack_last); |
407 | if (lim < ci->top) lim = ci->top; | 403 | if (lim < ci->top) lim = ci->top; |
408 | } | 404 | } |
409 | for (o = l->stack; o < l->top; o++) | 405 | for (o = L->stack; o < L->top; o++) |
410 | markvalue(g, o); | 406 | markvalue(g, o); |
411 | for (; o <= lim; o++) | 407 | for (; o <= lim; o++) |
412 | setnilvalue(o); | 408 | setnilvalue(o); |
413 | checkstacksizes(l, lim); | 409 | checkstacksize(L, lim); |
414 | } | 410 | } |
415 | 411 | ||
416 | 412 | ||
@@ -445,7 +441,7 @@ static l_mem propagatemark (global_State *g) { | |||
445 | black2gray(o); | 441 | black2gray(o); |
446 | traversestack(g, th); | 442 | traversestack(g, th); |
447 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + | 443 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + |
448 | sizeof(CallInfo) * th->size_ci; | 444 | sizeof(CallInfo) * th->nci; |
449 | } | 445 | } |
450 | case LUA_TPROTO: { | 446 | case LUA_TPROTO: { |
451 | Proto *p = gco2p(o); | 447 | Proto *p = gco2p(o); |
@@ -554,8 +550,11 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | |||
554 | global_State *g = G(L); | 550 | global_State *g = G(L); |
555 | int deadmask = otherwhite(g); | 551 | int deadmask = otherwhite(g); |
556 | while ((curr = *p) != NULL && count-- > 0) { | 552 | while ((curr = *p) != NULL && count-- > 0) { |
557 | if (ttisthread(gch(curr))) /* sweep open upvalues of each thread */ | 553 | if (ttisthread(gch(curr))) { |
558 | sweepwholelist(L, &gco2th(curr)->openupval); | 554 | lua_State *L1 = gco2th(curr); |
555 | sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ | ||
556 | luaE_freeCI(L1); /* free extra CallInfo slots */ | ||
557 | } | ||
559 | if ((gch(curr)->marked ^ WHITEBITS) & deadmask) { /* not dead? */ | 558 | if ((gch(curr)->marked ^ WHITEBITS) & deadmask) { /* not dead? */ |
560 | lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT)); | 559 | lua_assert(!isdead(g, curr) || testbit(gch(curr)->marked, FIXEDBIT)); |
561 | makewhite(g, curr); /* make it white (for next cycle) */ | 560 | makewhite(g, curr); /* make it white (for next cycle) */ |