diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-07-16 13:26:09 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-07-16 13:26:09 -0300 |
| commit | 55dc7fb240d145b9e44380ab478e55c668a6797a (patch) | |
| tree | 9cb5e39cf107c50a64bd14a2e1c2b0a5f1734b54 | |
| parent | 11d7ba79f2a84a4feda8013a7fb270e479b785f8 (diff) | |
| download | lua-55dc7fb240d145b9e44380ab478e55c668a6797a.tar.gz lua-55dc7fb240d145b9e44380ab478e55c668a6797a.tar.bz2 lua-55dc7fb240d145b9e44380ab478e55c668a6797a.zip | |
bug: stack must be cleared until its end (including extra size) +
control of stack size moved to 'ldo.c'
| -rw-r--r-- | lgc.c | 35 |
1 files changed, 9 insertions, 26 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.53 2009/05/21 20:06:11 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.54 2009/06/08 19:35:59 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 | */ |
| @@ -387,7 +387,8 @@ static void traversestack (global_State *g, lua_State *L) { | |||
| 387 | for (o = L->stack; o < L->top; o++) | 387 | for (o = L->stack; o < L->top; o++) |
| 388 | markvalue(g, o); | 388 | markvalue(g, o); |
| 389 | if (g->gcstate == GCSatomic) { /* final traversal? */ | 389 | if (g->gcstate == GCSatomic) { /* final traversal? */ |
| 390 | for (; o <= L->stack_last; o++) /* clear not-marked stack slice */ | 390 | StkId lim = L->stack + L->stacksize; /* real end of stack */ |
| 391 | for (; o < lim; o++) /* clear not-marked stack slice */ | ||
| 391 | setnilvalue(o); | 392 | setnilvalue(o); |
| 392 | } | 393 | } |
| 393 | } | 394 | } |
| @@ -423,8 +424,7 @@ static l_mem propagatemark (global_State *g) { | |||
| 423 | g->grayagain = o; | 424 | g->grayagain = o; |
| 424 | black2gray(o); | 425 | black2gray(o); |
| 425 | traversestack(g, th); | 426 | traversestack(g, th); |
| 426 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize + | 427 | return sizeof(lua_State) + sizeof(TValue) * th->stacksize; |
| 427 | sizeof(CallInfo) * th->nci; | ||
| 428 | } | 428 | } |
| 429 | case LUA_TPROTO: { | 429 | case LUA_TPROTO: { |
| 430 | Proto *p = gco2p(o); | 430 | Proto *p = gco2p(o); |
| @@ -525,17 +525,6 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | 527 | ||
| 528 | static int stackinuse (lua_State *L) { | ||
| 529 | CallInfo *ci; | ||
| 530 | StkId lim = L->top; | ||
| 531 | for (ci = L->ci; ci != NULL; ci = ci->previous) { | ||
| 532 | lua_assert(ci->top <= L->stack_last); | ||
| 533 | if (lim < ci->top) lim = ci->top; | ||
| 534 | } | ||
| 535 | return cast_int(lim - L->stack) + 1; /* part of stack in use */ | ||
| 536 | } | ||
| 537 | |||
| 538 | |||
| 539 | #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) | 528 | #define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) |
| 540 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); | 529 | static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); |
| 541 | 530 | ||
| @@ -543,16 +532,10 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); | |||
| 543 | static void sweepthread (lua_State *L, lua_State *L1, int alive) { | 532 | static void sweepthread (lua_State *L, lua_State *L1, int alive) { |
| 544 | if (L1->stack == NULL) return; /* stack not completely built yet */ | 533 | if (L1->stack == NULL) return; /* stack not completely built yet */ |
| 545 | sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ | 534 | sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ |
| 546 | if (L1->nci < LUAI_MAXCALLS) /* not handling stack overflow? */ | 535 | luaE_freeCI(L1); /* free extra CallInfo slots */ |
| 547 | luaE_freeCI(L1); /* free extra CallInfo slots */ | ||
| 548 | /* should not change the stack during an emergency gc cycle */ | 536 | /* should not change the stack during an emergency gc cycle */ |
| 549 | if (alive && G(L)->gckind != KGC_EMERGENCY) { | 537 | if (alive && G(L)->gckind != KGC_EMERGENCY) |
| 550 | int goodsize = 5 * stackinuse(L1) / 4 + LUA_MINSTACK; | 538 | luaD_shrinkstack(L1); |
| 551 | if ((L1->stacksize - EXTRA_STACK) > goodsize) | ||
| 552 | luaD_reallocstack(L1, goodsize); | ||
| 553 | else | ||
| 554 | condmovestack(L1); | ||
| 555 | } | ||
| 556 | } | 539 | } |
| 557 | 540 | ||
| 558 | 541 | ||
| @@ -590,7 +573,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { | |||
| 590 | static void checkSizes (lua_State *L) { | 573 | static void checkSizes (lua_State *L) { |
| 591 | global_State *g = G(L); | 574 | global_State *g = G(L); |
| 592 | if (g->strt.nuse < cast(lu_int32, g->strt.size)) { | 575 | if (g->strt.nuse < cast(lu_int32, g->strt.size)) { |
| 593 | /* size could be the smaller power of 2 larger than 'nuse' */ | 576 | /* string-table size could be the smaller power of 2 larger than 'nuse' */ |
| 594 | int size = 1 << luaO_ceillog2(g->strt.nuse); | 577 | int size = 1 << luaO_ceillog2(g->strt.nuse); |
| 595 | if (size < g->strt.size) /* current table too large? */ | 578 | if (size < g->strt.size) /* current table too large? */ |
| 596 | luaS_resize(L, size); /* shrink it */ | 579 | luaS_resize(L, size); /* shrink it */ |
| @@ -728,7 +711,7 @@ static void atomic (lua_State *L) { | |||
| 728 | /* remark occasional upvalues of (maybe) dead threads */ | 711 | /* remark occasional upvalues of (maybe) dead threads */ |
| 729 | g->gcstate = GCSatomic; | 712 | g->gcstate = GCSatomic; |
| 730 | remarkupvals(g); | 713 | remarkupvals(g); |
| 731 | /* traverse objects cautch by write barrier and by 'remarkupvals' */ | 714 | /* traverse objects caught by write barrier and by 'remarkupvals' */ |
| 732 | propagateall(g); | 715 | propagateall(g); |
| 733 | /* remark weak tables */ | 716 | /* remark weak tables */ |
| 734 | g->gray = g->weak; | 717 | g->gray = g->weak; |
