diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-12-03 18:03:07 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2003-12-03 18:03:07 -0200 |
| commit | c6eac44a9420a26a2f8907dcd5266a6aecdb18ea (patch) | |
| tree | acbf11560fe8aee5dddf37ff52b9fcaa6e697ca6 | |
| parent | 8878554b854009066eeccfe7b17e6e019c69758a (diff) | |
| download | lua-c6eac44a9420a26a2f8907dcd5266a6aecdb18ea.tar.gz lua-c6eac44a9420a26a2f8907dcd5266a6aecdb18ea.tar.bz2 lua-c6eac44a9420a26a2f8907dcd5266a6aecdb18ea.zip | |
two different white flags (to distinguish dead elements from new ones)
| -rw-r--r-- | lfunc.c | 3 | ||||
| -rw-r--r-- | lgc.c | 79 | ||||
| -rw-r--r-- | lgc.h | 21 | ||||
| -rw-r--r-- | lstate.c | 3 | ||||
| -rw-r--r-- | lstate.h | 3 | ||||
| -rw-r--r-- | lstring.c | 6 |
6 files changed, 63 insertions, 52 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 1.71 2003/11/19 19:41:30 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.72 2003/11/24 18:50:36 roberto Exp roberto $ |
| 3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -71,7 +71,6 @@ void luaF_close (lua_State *L, StkId level) { | |||
| 71 | setobj(&uv->value, uv->v); /* save current value (write barrier) */ | 71 | setobj(&uv->value, uv->v); /* save current value (write barrier) */ |
| 72 | uv->v = &uv->value; /* now current value lives here */ | 72 | uv->v = &uv->value; /* now current value lives here */ |
| 73 | L->openupval = uv->next; /* remove from `open' list */ | 73 | L->openupval = uv->next; /* remove from `open' list */ |
| 74 | resetbit(uv->marked, FIXEDBIT); /* closed upvalues can be collected */ | ||
| 75 | luaC_link(L, valtogco(uv), LUA_TUPVAL); | 74 | luaC_link(L, valtogco(uv), LUA_TUPVAL); |
| 76 | } | 75 | } |
| 77 | } | 76 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.182 2003/12/01 18:22:56 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.183 2003/12/03 12:30:41 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 | */ |
| @@ -25,26 +25,27 @@ | |||
| 25 | #define GCSTEPSIZE (20*sizeof(TObject)) | 25 | #define GCSTEPSIZE (20*sizeof(TObject)) |
| 26 | 26 | ||
| 27 | 27 | ||
| 28 | #define otherwhite(g) (g->currentwhite ^ bit2mask(WHITE0BIT, WHITE1BIT)) | ||
| 28 | 29 | ||
| 29 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | 30 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) |
| 30 | #define gray2black(x) ((x)->gch.marked++) | 31 | #define gray2black(x) setbit((x)->gch.marked, BLACKBIT) |
| 31 | #define white2black(x) setbit((x)->gch.marked, BLACKBIT) | ||
| 32 | 32 | ||
| 33 | #define iswhite(x) (!test2bits((x)->gch.marked, GRAYBIT, BLACKBIT)) | 33 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) |
| 34 | #define makewhite(x) reset2bits((x)->gch.marked, GRAYBIT, BLACKBIT) | 34 | #define maskmarks \ |
| 35 | cast(lu_byte, ~(bitmask(BLACKBIT)|bit2mask(WHITE0BIT, WHITE1BIT))) | ||
| 36 | #define makewhite(g,x) \ | ||
| 37 | ((x)->gch.marked = ((x)->gch.marked & maskmarks) | g->currentwhite) | ||
| 35 | 38 | ||
| 36 | #define isgray(x) testbit((x)->gch.marked, GRAYBIT) | 39 | #define isgray(x) (!isblack(x) && !iswhite(x)) |
| 37 | #define white2gray(x) setbit((x)->gch.marked, GRAYBIT) | 40 | #define white2gray(x) reset2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) |
| 38 | 41 | ||
| 39 | #define stringmark(s) setbit((s)->tsv.marked, BLACKBIT) | 42 | #define stringmark(s) reset2bits((s)->tsv.marked, WHITE0BIT, WHITE1BIT) |
| 40 | 43 | ||
| 41 | 44 | ||
| 42 | #define isfinalized(u) testbit((u)->uv.marked, FINALIZEDBIT) | 45 | #define isfinalized(u) testbit((u)->uv.marked, FINALIZEDBIT) |
| 43 | #define markfinalized(u) setbit((u)->uv.marked, FINALIZEDBIT) | 46 | #define markfinalized(u) setbit((u)->uv.marked, FINALIZEDBIT) |
| 44 | 47 | ||
| 45 | 48 | ||
| 46 | #define maskbf bit2mask(BLACKBIT, FIXEDBIT) | ||
| 47 | |||
| 48 | 49 | ||
| 49 | #define KEYWEAK bitmask(KEYWEAKBIT) | 50 | #define KEYWEAK bitmask(KEYWEAKBIT) |
| 50 | #define VALUEWEAK bitmask(VALUEWEAKBIT) | 51 | #define VALUEWEAK bitmask(VALUEWEAKBIT) |
| @@ -108,14 +109,14 @@ static size_t objsize (GCObject *o) { | |||
| 108 | 109 | ||
| 109 | static void reallymarkobject (global_State *g, GCObject *o) { | 110 | static void reallymarkobject (global_State *g, GCObject *o) { |
| 110 | lua_assert(iswhite(o)); | 111 | lua_assert(iswhite(o)); |
| 112 | lua_assert(!(o->gch.marked & otherwhite(g))); | ||
| 113 | white2gray(o); | ||
| 111 | switch (o->gch.tt) { | 114 | switch (o->gch.tt) { |
| 112 | case LUA_TSTRING: { | 115 | case LUA_TSTRING: { |
| 113 | white2black(o); /* strings do not go to gray list */ | ||
| 114 | return; | 116 | return; |
| 115 | } | 117 | } |
| 116 | case LUA_TUSERDATA: { | 118 | case LUA_TUSERDATA: { |
| 117 | Table *mt = gcotou(o)->uv.metatable; | 119 | Table *mt = gcotou(o)->uv.metatable; |
| 118 | white2black(o); /* userdata do not go to gray list */ | ||
| 119 | if (mt) markobject(g, mt); | 120 | if (mt) markobject(g, mt); |
| 120 | return; | 121 | return; |
| 121 | } | 122 | } |
| @@ -142,14 +143,13 @@ static void reallymarkobject (global_State *g, GCObject *o) { | |||
| 142 | default: lua_assert(0); | 143 | default: lua_assert(0); |
| 143 | } | 144 | } |
| 144 | g->gray = o; /* finish list linking */ | 145 | g->gray = o; /* finish list linking */ |
| 145 | white2gray(o); | ||
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | 148 | ||
| 149 | static void marktmu (global_State *g) { | 149 | static void marktmu (global_State *g) { |
| 150 | GCObject *u; | 150 | GCObject *u; |
| 151 | for (u = g->tmudata; u; u = u->gch.next) { | 151 | for (u = g->tmudata; u; u = u->gch.next) { |
| 152 | makewhite(u); /* may be marked, if left from previous GC */ | 152 | makewhite(g, u); /* may be marked, if left from previous GC */ |
| 153 | reallymarkobject(g, u); | 153 | reallymarkobject(g, u); |
| 154 | } | 154 | } |
| 155 | } | 155 | } |
| @@ -164,9 +164,8 @@ size_t luaC_separateudata (lua_State *L) { | |||
| 164 | GCObject **lastcollected = &collected; | 164 | GCObject **lastcollected = &collected; |
| 165 | while ((curr = *p) != NULL) { | 165 | while ((curr = *p) != NULL) { |
| 166 | lua_assert(curr->gch.tt == LUA_TUSERDATA); | 166 | lua_assert(curr->gch.tt == LUA_TUSERDATA); |
| 167 | if (isblack(curr) || isfinalized(gcotou(curr))) | 167 | if (!iswhite(curr) || isfinalized(gcotou(curr))) |
| 168 | p = &curr->gch.next; /* don't bother with them */ | 168 | p = &curr->gch.next; /* don't bother with them */ |
| 169 | |||
| 170 | else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) { | 169 | else if (fasttm(L, gcotou(curr)->uv.metatable, TM_GC) == NULL) { |
| 171 | markfinalized(gcotou(curr)); /* don't need finalization */ | 170 | markfinalized(gcotou(curr)); /* don't need finalization */ |
| 172 | p = &curr->gch.next; | 171 | p = &curr->gch.next; |
| @@ -362,7 +361,7 @@ static int iscleared (const TObject *o, int iskey) { | |||
| 362 | stringmark(tsvalue(o)); /* strings are `values', so are never weak */ | 361 | stringmark(tsvalue(o)); /* strings are `values', so are never weak */ |
| 363 | return 0; | 362 | return 0; |
| 364 | } | 363 | } |
| 365 | return !isblack(gcvalue(o)) || | 364 | return iswhite(gcvalue(o)) || |
| 366 | (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); | 365 | (ttisuserdata(o) && (!iskey && isfinalized(uvalue(o)))); |
| 367 | } | 366 | } |
| 368 | 367 | ||
| @@ -426,16 +425,19 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
| 426 | } | 425 | } |
| 427 | 426 | ||
| 428 | 427 | ||
| 429 | static GCObject **sweeplist (lua_State *L, GCObject **p, int mask, | 428 | static GCObject **sweeplist (lua_State *L, GCObject **p, int all, |
| 430 | l_mem *plim) { | 429 | l_mem *plim) { |
| 431 | GCObject *curr; | 430 | GCObject *curr; |
| 431 | global_State *g = G(L); | ||
| 432 | l_mem lim = *plim; | 432 | l_mem lim = *plim; |
| 433 | int white = otherwhite(g); | ||
| 433 | while ((curr = *p) != NULL) { | 434 | while ((curr = *p) != NULL) { |
| 434 | lua_assert(!isgray(curr)); | 435 | int mark = curr->gch.marked; |
| 435 | if (curr->gch.marked & mask) { | 436 | lua_assert(all || !(mark & g->currentwhite)); |
| 436 | lim -= objsize(curr); | 437 | if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) { |
| 437 | makewhite(curr); | 438 | makewhite(g, curr); |
| 438 | p = &curr->gch.next; | 439 | p = &curr->gch.next; |
| 440 | lim -= objsize(curr); | ||
| 439 | } | 441 | } |
| 440 | else { | 442 | else { |
| 441 | *p = curr->gch.next; | 443 | *p = curr->gch.next; |
| @@ -448,16 +450,18 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int mask, | |||
| 448 | } | 450 | } |
| 449 | 451 | ||
| 450 | 452 | ||
| 451 | static void sweepstrings (lua_State *L, int mask) { | 453 | static void sweepstrings (lua_State *L, int all) { |
| 452 | int i; | 454 | int i; |
| 453 | global_State *g = G(L); | 455 | global_State *g = G(L); |
| 456 | int white = otherwhite(g); | ||
| 454 | for (i = 0; i < g->strt.size; i++) { /* for each list */ | 457 | for (i = 0; i < g->strt.size; i++) { /* for each list */ |
| 455 | GCObject *curr; | 458 | GCObject *curr; |
| 456 | GCObject **p = &G(L)->strt.hash[i]; | 459 | GCObject **p = &G(L)->strt.hash[i]; |
| 457 | while ((curr = *p) != NULL) { | 460 | while ((curr = *p) != NULL) { |
| 458 | lua_assert(!isgray(curr) && curr->gch.tt == LUA_TSTRING); | 461 | int mark = curr->gch.marked; |
| 459 | if (curr->gch.marked & mask) { | 462 | lua_assert(all || !(mark & g->currentwhite)); |
| 460 | makewhite(curr); | 463 | if (!all && (!(mark & white) || testbit(mark, FIXEDBIT))) { |
| 464 | makewhite(g, curr); | ||
| 461 | p = &curr->gch.next; | 465 | p = &curr->gch.next; |
| 462 | } | 466 | } |
| 463 | else { | 467 | else { |
| @@ -497,7 +501,7 @@ static void GCTM (lua_State *L) { | |||
| 497 | g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ | 501 | g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ |
| 498 | udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ | 502 | udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ |
| 499 | g->firstudata->uv.next = o; | 503 | g->firstudata->uv.next = o; |
| 500 | makewhite(o); | 504 | makewhite(g, o); |
| 501 | tm = fasttm(L, udata->uv.metatable, TM_GC); | 505 | tm = fasttm(L, udata->uv.metatable, TM_GC); |
| 502 | if (tm != NULL) { | 506 | if (tm != NULL) { |
| 503 | lu_byte oldah = L->allowhook; | 507 | lu_byte oldah = L->allowhook; |
| @@ -523,8 +527,8 @@ void luaC_callGCTM (lua_State *L) { | |||
| 523 | 527 | ||
| 524 | void luaC_sweepall (lua_State *L) { | 528 | void luaC_sweepall (lua_State *L) { |
| 525 | l_mem dummy = MAXLMEM; | 529 | l_mem dummy = MAXLMEM; |
| 526 | sweepstrings(L, 0); | 530 | sweepstrings(L, 1); |
| 527 | sweeplist(L, &G(L)->rootgc, 0, &dummy); | 531 | sweeplist(L, &G(L)->rootgc, 1, &dummy); |
| 528 | } | 532 | } |
| 529 | 533 | ||
| 530 | 534 | ||
| @@ -533,7 +537,7 @@ static void markroot (lua_State *L) { | |||
| 533 | global_State *g = G(L); | 537 | global_State *g = G(L); |
| 534 | lua_assert(g->gray == NULL); | 538 | lua_assert(g->gray == NULL); |
| 535 | g->weak = NULL; | 539 | g->weak = NULL; |
| 536 | makewhite(valtogco(g->mainthread)); | 540 | makewhite(g, valtogco(g->mainthread)); |
| 537 | markobject(g, g->mainthread); | 541 | markobject(g, g->mainthread); |
| 538 | markvalue(g, registry(L)); | 542 | markvalue(g, registry(L)); |
| 539 | markobject(g, g->firstudata); | 543 | markobject(g, g->firstudata); |
| @@ -548,11 +552,13 @@ static void atomic (lua_State *L) { | |||
| 548 | marktmu(g); /* mark `preserved' userdata */ | 552 | marktmu(g); /* mark `preserved' userdata */ |
| 549 | propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ | 553 | propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ |
| 550 | cleartable(g->weak); /* remove collected objects from weak tables */ | 554 | cleartable(g->weak); /* remove collected objects from weak tables */ |
| 555 | /* echange current white */ | ||
| 556 | g->currentwhite = otherwhite(g); | ||
| 551 | /* first element of root list will be used as temporary head for sweep | 557 | /* first element of root list will be used as temporary head for sweep |
| 552 | phase, so it won't be seeped */ | 558 | phase, so it won't be seeped */ |
| 553 | makewhite(g->rootgc); | 559 | makewhite(g, g->rootgc); |
| 554 | g->sweepgc = &g->rootgc->gch.next; | 560 | g->sweepgc = &g->rootgc->gch.next; |
| 555 | sweepstrings(L, maskbf); | 561 | sweepstrings(L, 0); |
| 556 | g->gcstate = GCSsweep; | 562 | g->gcstate = GCSsweep; |
| 557 | } | 563 | } |
| 558 | 564 | ||
| @@ -560,7 +566,7 @@ static void atomic (lua_State *L) { | |||
| 560 | static void sweepstep (lua_State *L) { | 566 | static void sweepstep (lua_State *L) { |
| 561 | global_State *g = G(L); | 567 | global_State *g = G(L); |
| 562 | l_mem lim = GCSTEPSIZE; | 568 | l_mem lim = GCSTEPSIZE; |
| 563 | g->sweepgc = sweeplist(L, g->sweepgc, maskbf, &lim); | 569 | g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim); |
| 564 | if (lim == GCSTEPSIZE) { /* nothing more to sweep? */ | 570 | if (lim == GCSTEPSIZE) { /* nothing more to sweep? */ |
| 565 | g->gcstate = GCSfinalize; /* end sweep phase */ | 571 | g->gcstate = GCSfinalize; /* end sweep phase */ |
| 566 | } | 572 | } |
| @@ -587,9 +593,10 @@ void luaC_collectgarbage (lua_State *L) { | |||
| 587 | 593 | ||
| 588 | 594 | ||
| 589 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { | 595 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt) { |
| 590 | o->gch.next = G(L)->rootgc; | 596 | global_State *g = G(L); |
| 591 | G(L)->rootgc = o; | 597 | o->gch.next = g->rootgc; |
| 592 | o->gch.marked = 0; | 598 | g->rootgc = o; |
| 599 | o->gch.marked = luaC_white(g); | ||
| 593 | o->gch.tt = tt; | 600 | o->gch.tt = tt; |
| 594 | } | 601 | } |
| 595 | 602 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.h,v 1.24 2003/11/19 19:41:57 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 1.25 2003/12/01 16:33:30 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 | */ |
| @@ -22,8 +22,8 @@ | |||
| 22 | 22 | ||
| 23 | 23 | ||
| 24 | /* | 24 | /* |
| 25 | * ** some userful bit tricks | 25 | ** some userful bit tricks |
| 26 | * */ | 26 | */ |
| 27 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) | 27 | #define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) |
| 28 | #define setbits(x,m) ((x) |= (m)) | 28 | #define setbits(x,m) ((x) |= (m)) |
| 29 | #define testbits(x,m) ((x) & (m)) | 29 | #define testbits(x,m) ((x) & (m)) |
| @@ -48,13 +48,16 @@ | |||
| 48 | ** bit 4 - object is fixed (should not be collected) | 48 | ** bit 4 - object is fixed (should not be collected) |
| 49 | */ | 49 | */ |
| 50 | 50 | ||
| 51 | #define GRAYBIT 0 | 51 | #define WHITE0BIT 0 |
| 52 | #define BLACKBIT 1 | 52 | #define WHITE1BIT 1 |
| 53 | #define FINALIZEDBIT 2 | 53 | #define BLACKBIT 2 |
| 54 | #define KEYWEAKBIT 2 | 54 | #define FINALIZEDBIT 3 |
| 55 | #define VALUEWEAKBIT 3 | 55 | #define KEYWEAKBIT 3 |
| 56 | #define FIXEDBIT 4 | 56 | #define VALUEWEAKBIT 4 |
| 57 | #define FIXEDBIT 5 | ||
| 58 | |||
| 57 | 59 | ||
| 60 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite) | ||
| 58 | 61 | ||
| 59 | 62 | ||
| 60 | #define luaC_checkGC(L) { if (G(L)->nblocks >= G(L)->GCthreshold) \ | 63 | #define luaC_checkGC(L) { if (G(L)->nblocks >= G(L)->GCthreshold) \ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 1.130 2003/12/01 18:22:56 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.131 2003/12/03 12:30:41 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 | */ |
| @@ -167,6 +167,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
| 167 | g->panic = NULL; | 167 | g->panic = NULL; |
| 168 | g->gcstate = 0; | 168 | g->gcstate = 0; |
| 169 | g->rootgc = NULL; | 169 | g->rootgc = NULL; |
| 170 | g->currentwhite = bitmask(WHITE0BIT); | ||
| 170 | g->firstudata = NULL; | 171 | g->firstudata = NULL; |
| 171 | g->gray = NULL; | 172 | g->gray = NULL; |
| 172 | g->weak = NULL; | 173 | g->weak = NULL; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 1.115 2003/12/01 18:22:56 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.116 2003/12/03 12:30:41 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 | */ |
| @@ -97,6 +97,7 @@ typedef struct global_State { | |||
| 97 | stringtable strt; /* hash table for strings */ | 97 | stringtable strt; /* hash table for strings */ |
| 98 | lua_Alloc realloc; /* function to reallocate memory */ | 98 | lua_Alloc realloc; /* function to reallocate memory */ |
| 99 | void *ud; /* auxiliary data to `realloc' */ | 99 | void *ud; /* auxiliary data to `realloc' */ |
| 100 | int currentwhite; | ||
| 100 | GCObject *rootgc; /* list of all collectable objects */ | 101 | GCObject *rootgc; /* list of all collectable objects */ |
| 101 | GCObject *firstudata; /* udata go to the end of `rootgc' */ | 102 | GCObject *firstudata; /* udata go to the end of `rootgc' */ |
| 102 | GCObject **sweepgc; /* position of sweep in `rootgc' */ | 103 | GCObject **sweepgc; /* position of sweep in `rootgc' */ |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 1.81 2003/12/01 18:22:56 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.82 2003/12/03 12:30:41 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 | */ |
| @@ -54,7 +54,7 @@ static TString *newlstr (lua_State *L, const char *str, size_t l, | |||
| 54 | stringtable *tb; | 54 | stringtable *tb; |
| 55 | ts->tsv.len = l; | 55 | ts->tsv.len = l; |
| 56 | ts->tsv.hash = h; | 56 | ts->tsv.hash = h; |
| 57 | ts->tsv.marked = 0; | 57 | ts->tsv.marked = luaC_white(G(L)); |
| 58 | ts->tsv.tt = LUA_TSTRING; | 58 | ts->tsv.tt = LUA_TSTRING; |
| 59 | ts->tsv.reserved = 0; | 59 | ts->tsv.reserved = 0; |
| 60 | memcpy(ts+1, str, l*sizeof(char)); | 60 | memcpy(ts+1, str, l*sizeof(char)); |
| @@ -91,7 +91,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
| 91 | Udata *luaS_newudata (lua_State *L, size_t s) { | 91 | Udata *luaS_newudata (lua_State *L, size_t s) { |
| 92 | Udata *u; | 92 | Udata *u; |
| 93 | u = cast(Udata *, luaM_malloc(L, sizeudata(s))); | 93 | u = cast(Udata *, luaM_malloc(L, sizeudata(s))); |
| 94 | u->uv.marked = 0; /* is not finalized */ | 94 | u->uv.marked = luaC_white(G(L)); /* is not finalized */ |
| 95 | u->uv.tt = LUA_TUSERDATA; | 95 | u->uv.tt = LUA_TUSERDATA; |
| 96 | u->uv.len = s; | 96 | u->uv.len = s; |
| 97 | u->uv.metatable = NULL; | 97 | u->uv.metatable = NULL; |
