diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-12-04 15:22:42 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-12-04 15:22:42 -0200 |
| commit | 9db1942bac5fb509c6e46ccc825351a6be546792 (patch) | |
| tree | d9f8091bf61610b7681c10b9b769031fc787f65e | |
| parent | c6eac44a9420a26a2f8907dcd5266a6aecdb18ea (diff) | |
| download | lua-9db1942bac5fb509c6e46ccc825351a6be546792.tar.gz lua-9db1942bac5fb509c6e46ccc825351a6be546792.tar.bz2 lua-9db1942bac5fb509c6e46ccc825351a6be546792.zip | |
sweep of strings also incremental
| -rw-r--r-- | lgc.c | 52 | ||||
| -rw-r--r-- | lgc.h | 7 | ||||
| -rw-r--r-- | lstate.c | 4 | ||||
| -rw-r--r-- | lstate.h | 3 | ||||
| -rw-r--r-- | lstring.c | 9 |
5 files changed, 50 insertions, 25 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.183 2003/12/03 12:30:41 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.184 2003/12/03 20:03:07 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 | */ |
| @@ -430,14 +430,14 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int all, | |||
| 430 | GCObject *curr; | 430 | GCObject *curr; |
| 431 | global_State *g = G(L); | 431 | global_State *g = G(L); |
| 432 | l_mem lim = *plim; | 432 | l_mem lim = *plim; |
| 433 | int white = otherwhite(g); | 433 | int dead = otherwhite(g); |
| 434 | while ((curr = *p) != NULL) { | 434 | while ((curr = *p) != NULL) { |
| 435 | int mark = curr->gch.marked; | 435 | int mark = curr->gch.marked; |
| 436 | lua_assert(all || !(mark & g->currentwhite)); | 436 | lua_assert(all || !(mark & g->currentwhite)); |
| 437 | if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) { | 437 | lim -= objsize(curr); |
| 438 | if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { | ||
| 438 | makewhite(g, curr); | 439 | makewhite(g, curr); |
| 439 | p = &curr->gch.next; | 440 | p = &curr->gch.next; |
| 440 | lim -= objsize(curr); | ||
| 441 | } | 441 | } |
| 442 | else { | 442 | else { |
| 443 | *p = curr->gch.next; | 443 | *p = curr->gch.next; |
| @@ -450,27 +450,32 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int all, | |||
| 450 | } | 450 | } |
| 451 | 451 | ||
| 452 | 452 | ||
| 453 | static void sweepstrings (lua_State *L, int all) { | 453 | static l_mem sweepstrings (lua_State *L, int all, l_mem lim) { |
| 454 | int i; | 454 | int i; |
| 455 | global_State *g = G(L); | 455 | global_State *g = G(L); |
| 456 | int white = otherwhite(g); | 456 | int dead = otherwhite(g); |
| 457 | for (i = 0; i < g->strt.size; i++) { /* for each list */ | 457 | for (i = g->sweepstrgc; i < g->strt.size; i++) { /* for each list */ |
| 458 | GCObject *curr; | 458 | GCObject *curr; |
| 459 | GCObject **p = &G(L)->strt.hash[i]; | 459 | GCObject **p = &G(L)->strt.hash[i]; |
| 460 | while ((curr = *p) != NULL) { | 460 | while ((curr = *p) != NULL) { |
| 461 | int mark = curr->gch.marked; | 461 | int mark = curr->gch.marked; |
| 462 | lu_mem size = sizestring(gcotots(curr)->tsv.len); | ||
| 462 | lua_assert(all || !(mark & g->currentwhite)); | 463 | lua_assert(all || !(mark & g->currentwhite)); |
| 463 | if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) { | 464 | if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { |
| 464 | makewhite(g, curr); | 465 | makewhite(g, curr); |
| 465 | p = &curr->gch.next; | 466 | p = &curr->gch.next; |
| 466 | } | 467 | } |
| 467 | else { | 468 | else { |
| 468 | g->strt.nuse--; | 469 | g->strt.nuse--; |
| 469 | *p = curr->gch.next; | 470 | *p = curr->gch.next; |
| 470 | luaM_free(L, curr, sizestring(gcotots(curr)->tsv.len)); | 471 | luaM_free(L, curr, size); |
| 471 | } | 472 | } |
| 473 | lim -= size; | ||
| 472 | } | 474 | } |
| 475 | if (lim <= 0) break; | ||
| 473 | } | 476 | } |
| 477 | g->sweepstrgc = i+1; | ||
| 478 | return lim; | ||
| 474 | } | 479 | } |
| 475 | 480 | ||
| 476 | 481 | ||
| @@ -527,7 +532,8 @@ void luaC_callGCTM (lua_State *L) { | |||
| 527 | 532 | ||
| 528 | void luaC_sweepall (lua_State *L) { | 533 | void luaC_sweepall (lua_State *L) { |
| 529 | l_mem dummy = MAXLMEM; | 534 | l_mem dummy = MAXLMEM; |
| 530 | sweepstrings(L, 1); | 535 | G(L)->sweepstrgc = 0; |
| 536 | sweepstrings(L, 1, dummy); | ||
| 531 | sweeplist(L, &G(L)->rootgc, 1, &dummy); | 537 | sweeplist(L, &G(L)->rootgc, 1, &dummy); |
| 532 | } | 538 | } |
| 533 | 539 | ||
| @@ -540,7 +546,6 @@ static void markroot (lua_State *L) { | |||
| 540 | makewhite(g, valtogco(g->mainthread)); | 546 | makewhite(g, valtogco(g->mainthread)); |
| 541 | markobject(g, g->mainthread); | 547 | markobject(g, g->mainthread); |
| 542 | markvalue(g, registry(L)); | 548 | markvalue(g, registry(L)); |
| 543 | markobject(g, g->firstudata); | ||
| 544 | markobject(g, L); /* mark running thread */ | 549 | markobject(g, L); /* mark running thread */ |
| 545 | g->gcstate = GCSpropagate; | 550 | g->gcstate = GCSpropagate; |
| 546 | } | 551 | } |
| @@ -552,14 +557,25 @@ static void atomic (lua_State *L) { | |||
| 552 | marktmu(g); /* mark `preserved' userdata */ | 557 | marktmu(g); /* mark `preserved' userdata */ |
| 553 | propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ | 558 | propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ |
| 554 | cleartable(g->weak); /* remove collected objects from weak tables */ | 559 | cleartable(g->weak); /* remove collected objects from weak tables */ |
| 555 | /* echange current white */ | 560 | /* flip current white */ |
| 556 | g->currentwhite = otherwhite(g); | 561 | g->currentwhite = otherwhite(g); |
| 557 | /* first element of root list will be used as temporary head for sweep | 562 | /* first element of root list will be used as temporary head for sweep |
| 558 | phase, so it won't be seeped */ | 563 | phase, so it won't be swept */ |
| 559 | makewhite(g, g->rootgc); | 564 | makewhite(g, g->rootgc); |
| 560 | g->sweepgc = &g->rootgc->gch.next; | 565 | g->sweepgc = &g->rootgc->gch.next; |
| 561 | sweepstrings(L, 0); | 566 | g->sweepstrgc = 0; |
| 562 | g->gcstate = GCSsweep; | 567 | g->gcstate = GCSsweepstring; |
| 568 | } | ||
| 569 | |||
| 570 | |||
| 571 | static void sweepstringstep (lua_State *L) { | ||
| 572 | global_State *g = G(L); | ||
| 573 | l_mem lim = sweepstrings(L, 0, GCSTEPSIZE); | ||
| 574 | if (lim == GCSTEPSIZE) { /* nothing more to sweep? */ | ||
| 575 | lua_assert(g->sweepstrgc > g->strt.size); | ||
| 576 | g->sweepstrgc = 0; | ||
| 577 | g->gcstate = GCSsweep; /* end sweep-string phase */ | ||
| 578 | } | ||
| 563 | } | 579 | } |
| 564 | 580 | ||
| 565 | 581 | ||
| @@ -567,9 +583,8 @@ static void sweepstep (lua_State *L) { | |||
| 567 | global_State *g = G(L); | 583 | global_State *g = G(L); |
| 568 | l_mem lim = GCSTEPSIZE; | 584 | l_mem lim = GCSTEPSIZE; |
| 569 | g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim); | 585 | g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim); |
| 570 | if (lim == GCSTEPSIZE) { /* nothing more to sweep? */ | 586 | if (lim == GCSTEPSIZE) /* nothing more to sweep? */ |
| 571 | g->gcstate = GCSfinalize; /* end sweep phase */ | 587 | g->gcstate = GCSfinalize; /* end sweep phase */ |
| 572 | } | ||
| 573 | } | 588 | } |
| 574 | 589 | ||
| 575 | 590 | ||
| @@ -582,6 +597,9 @@ void luaC_collectgarbage (lua_State *L) { | |||
| 582 | propagatemarks(g, GCSTEPSIZE); | 597 | propagatemarks(g, GCSTEPSIZE); |
| 583 | /* atomic */ | 598 | /* atomic */ |
| 584 | atomic(L); | 599 | atomic(L); |
| 600 | /* GCSsweepstring */ | ||
| 601 | while (g->gcstate == GCSsweepstring) | ||
| 602 | sweepstringstep(L); | ||
| 585 | /* GCSsweep */ | 603 | /* GCSsweep */ |
| 586 | while (g->gcstate == GCSsweep) | 604 | while (g->gcstate == GCSsweep) |
| 587 | sweepstep(L); | 605 | sweepstep(L); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.h,v 1.25 2003/12/01 16:33:30 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 1.26 2003/12/03 20:03:07 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 | */ |
| @@ -17,8 +17,9 @@ | |||
| 17 | #define GCSroot 0 | 17 | #define GCSroot 0 |
| 18 | #define GCSpropagate 1 | 18 | #define GCSpropagate 1 |
| 19 | #define GCSatomic 2 | 19 | #define GCSatomic 2 |
| 20 | #define GCSsweep 3 | 20 | #define GCSsweepstring 3 |
| 21 | #define GCSfinalize 4 | 21 | #define GCSsweep 4 |
| 22 | #define GCSfinalize 5 | ||
| 22 | 23 | ||
| 23 | 24 | ||
| 24 | /* | 25 | /* |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 1.131 2003/12/03 12:30:41 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.132 2003/12/03 20:03:07 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -81,6 +81,7 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
| 81 | u->uv.metatable = NULL; | 81 | u->uv.metatable = NULL; |
| 82 | G(L)->firstudata = valtogco(u); | 82 | G(L)->firstudata = valtogco(u); |
| 83 | luaC_link(L, valtogco(u), LUA_TUSERDATA); | 83 | luaC_link(L, valtogco(u), LUA_TUSERDATA); |
| 84 | setbit(u->uv.marked, FIXEDBIT); | ||
| 84 | stack_init(L, L); /* init stack */ | 85 | stack_init(L, L); /* init stack */ |
| 85 | sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */ | 86 | sethvalue(gt(L), luaH_new(L, 0, 4)); /* table of globals */ |
| 86 | sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */ | 87 | sethvalue(registry(L), luaH_new(L, 4, 4)); /* registry */ |
| @@ -167,6 +168,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
| 167 | g->panic = NULL; | 168 | g->panic = NULL; |
| 168 | g->gcstate = 0; | 169 | g->gcstate = 0; |
| 169 | g->rootgc = NULL; | 170 | g->rootgc = NULL; |
| 171 | g->sweepstrgc = 0; | ||
| 170 | g->currentwhite = bitmask(WHITE0BIT); | 172 | g->currentwhite = bitmask(WHITE0BIT); |
| 171 | g->firstudata = NULL; | 173 | g->firstudata = NULL; |
| 172 | g->gray = NULL; | 174 | g->gray = NULL; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 1.116 2003/12/03 12:30:41 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.117 2003/12/03 20:03:07 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -101,6 +101,7 @@ typedef struct global_State { | |||
| 101 | GCObject *rootgc; /* list of all collectable objects */ | 101 | GCObject *rootgc; /* list of all collectable objects */ |
| 102 | GCObject *firstudata; /* udata go to the end of `rootgc' */ | 102 | GCObject *firstudata; /* udata go to the end of `rootgc' */ |
| 103 | GCObject **sweepgc; /* position of sweep in `rootgc' */ | 103 | GCObject **sweepgc; /* position of sweep in `rootgc' */ |
| 104 | int sweepstrgc; /* position of sweep in `strt' */ | ||
| 104 | GCObject *gray; /* list of gray objects */ | 105 | GCObject *gray; /* list of gray objects */ |
| 105 | GCObject *weak; /* list of weak tables (to be cleared) */ | 106 | GCObject *weak; /* list of weak tables (to be cleared) */ |
| 106 | GCObject *tmudata; /* list of userdata to be GC */ | 107 | GCObject *tmudata; /* list of userdata to be GC */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 1.82 2003/12/03 12:30:41 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.83 2003/12/03 20:03:07 roberto Exp roberto $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -25,9 +25,12 @@ void luaS_freeall (lua_State *L) { | |||
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | void luaS_resize (lua_State *L, int newsize) { | 27 | void luaS_resize (lua_State *L, int newsize) { |
| 28 | GCObject **newhash = luaM_newvector(L, newsize, GCObject *); | 28 | GCObject **newhash; |
| 29 | stringtable *tb = &G(L)->strt; | 29 | stringtable *tb; |
| 30 | int i; | 30 | int i; |
| 31 | if (G(L)->sweepstrgc > 0) return; /* cannot resize during GC traverse */ | ||
| 32 | newhash = luaM_newvector(L, newsize, GCObject *); | ||
| 33 | tb = &G(L)->strt; | ||
| 31 | for (i=0; i<newsize; i++) newhash[i] = NULL; | 34 | for (i=0; i<newsize; i++) newhash[i] = NULL; |
| 32 | /* rehash */ | 35 | /* rehash */ |
| 33 | for (i=0; i<tb->size; i++) { | 36 | for (i=0; i<tb->size; i++) { |
