diff options
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 38 |
1 files changed, 26 insertions, 12 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.86 2010/05/03 17:39:48 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.87 2010/05/04 18:09:06 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 | */ |
@@ -24,13 +24,28 @@ | |||
24 | 24 | ||
25 | 25 | ||
26 | 26 | ||
27 | /* how much to allocate before next GC step */ | ||
27 | #define GCSTEPSIZE 1024 | 28 | #define GCSTEPSIZE 1024 |
29 | |||
30 | /* maximum numer of elements to sweep in each single step */ | ||
28 | #define GCSWEEPMAX 40 | 31 | #define GCSWEEPMAX 40 |
32 | |||
33 | /* cost of sweeping one element */ | ||
29 | #define GCSWEEPCOST 1 | 34 | #define GCSWEEPCOST 1 |
35 | |||
36 | /* maximum number of finalizers to call in each GC step */ | ||
30 | #define GCFINALIZENUM 4 | 37 | #define GCFINALIZENUM 4 |
38 | |||
39 | /* cost of marking the root set */ | ||
31 | #define GCROOTCOST 10 | 40 | #define GCROOTCOST 10 |
41 | |||
42 | /* cost of atomic step */ | ||
32 | #define GCATOMICCOST 1000 | 43 | #define GCATOMICCOST 1000 |
33 | 44 | ||
45 | /* basic cost to traverse one object (to be added to the links the | ||
46 | object may have) */ | ||
47 | #define TRAVCOST 5 | ||
48 | |||
34 | 49 | ||
35 | /* | 50 | /* |
36 | ** standard negative debt for GC; a reasonable "time" to wait before | 51 | ** standard negative debt for GC; a reasonable "time" to wait before |
@@ -317,7 +332,7 @@ static void traverseweakvalue (global_State *g, Table *h) { | |||
317 | markvalue(g, gkey(n)); /* mark key */ | 332 | markvalue(g, gkey(n)); /* mark key */ |
318 | } | 333 | } |
319 | } | 334 | } |
320 | linktable(h, &g->weak); /* go to appropriate list */ | 335 | linktable(h, &g->weak); /* link into appropriate list */ |
321 | } | 336 | } |
322 | 337 | ||
323 | 338 | ||
@@ -383,20 +398,20 @@ static int traversetable (global_State *g, Table *h) { | |||
383 | black2gray(obj2gco(h)); /* keep table gray */ | 398 | black2gray(obj2gco(h)); /* keep table gray */ |
384 | if (!weakkey) { /* strong keys? */ | 399 | if (!weakkey) { /* strong keys? */ |
385 | traverseweakvalue(g, h); | 400 | traverseweakvalue(g, h); |
386 | return 1 + sizenode(h); | 401 | return TRAVCOST + sizenode(h); |
387 | } | 402 | } |
388 | else if (!weakvalue) { /* strong values? */ | 403 | else if (!weakvalue) { /* strong values? */ |
389 | traverseephemeron(g, h); | 404 | traverseephemeron(g, h); |
390 | return 1 + h->sizearray + sizenode(h); | 405 | return TRAVCOST + h->sizearray + sizenode(h); |
391 | } | 406 | } |
392 | else { | 407 | else { |
393 | linktable(h, &g->allweak); /* nothing to traverse now */ | 408 | linktable(h, &g->allweak); /* nothing to traverse now */ |
394 | return 1; | 409 | return TRAVCOST; |
395 | } | 410 | } |
396 | } /* else go through */ | 411 | } /* else go through */ |
397 | } | 412 | } |
398 | traversestrongtable(g, h); | 413 | traversestrongtable(g, h); |
399 | return 1 + h->sizearray + (2 * sizenode(h)); | 414 | return TRAVCOST + h->sizearray + (2 * sizenode(h)); |
400 | } | 415 | } |
401 | 416 | ||
402 | 417 | ||
@@ -411,7 +426,7 @@ static int traverseproto (global_State *g, Proto *f) { | |||
411 | markobject(g, f->p[i]); | 426 | markobject(g, f->p[i]); |
412 | for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ | 427 | for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ |
413 | stringmark(f->locvars[i].varname); | 428 | stringmark(f->locvars[i].varname); |
414 | return 1 + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; | 429 | return TRAVCOST + f->sizek + f->sizeupvalues + f->sizep + f->sizelocvars; |
415 | } | 430 | } |
416 | 431 | ||
417 | 432 | ||
@@ -420,7 +435,6 @@ static l_mem traverseclosure (global_State *g, Closure *cl) { | |||
420 | int i; | 435 | int i; |
421 | for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ | 436 | for (i=0; i<cl->c.nupvalues; i++) /* mark its upvalues */ |
422 | markvalue(g, &cl->c.upvalue[i]); | 437 | markvalue(g, &cl->c.upvalue[i]); |
423 | return sizeCclosure(cl->c.nupvalues); | ||
424 | } | 438 | } |
425 | else { | 439 | else { |
426 | int i; | 440 | int i; |
@@ -428,14 +442,14 @@ static l_mem traverseclosure (global_State *g, Closure *cl) { | |||
428 | markobject(g, cl->l.p); /* mark its prototype */ | 442 | markobject(g, cl->l.p); /* mark its prototype */ |
429 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ | 443 | for (i=0; i<cl->l.nupvalues; i++) /* mark its upvalues */ |
430 | markobject(g, cl->l.upvals[i]); | 444 | markobject(g, cl->l.upvals[i]); |
431 | return sizeLclosure(cl->l.nupvalues); | ||
432 | } | 445 | } |
446 | return TRAVCOST + cl->c.nupvalues; | ||
433 | } | 447 | } |
434 | 448 | ||
435 | 449 | ||
436 | static int traversestack (global_State *g, lua_State *L) { | 450 | static int traversestack (global_State *g, lua_State *L) { |
437 | StkId o = L->stack; | 451 | StkId o = L->stack; |
438 | if (L->stack == NULL) | 452 | if (o == NULL) |
439 | return 1; /* stack not completely built yet */ | 453 | return 1; /* stack not completely built yet */ |
440 | for (; o < L->top; o++) | 454 | for (; o < L->top; o++) |
441 | markvalue(g, o); | 455 | markvalue(g, o); |
@@ -444,7 +458,7 @@ static int traversestack (global_State *g, lua_State *L) { | |||
444 | for (; o < lim; o++) /* clear not-marked stack slice */ | 458 | for (; o < lim; o++) /* clear not-marked stack slice */ |
445 | setnilvalue(o); | 459 | setnilvalue(o); |
446 | } | 460 | } |
447 | return 1 + cast_int(o - L->stack); | 461 | return TRAVCOST + cast_int(o - L->stack); |
448 | } | 462 | } |
449 | 463 | ||
450 | 464 | ||
@@ -803,7 +817,7 @@ static void atomic (lua_State *L) { | |||
803 | cleartable(g->weak); | 817 | cleartable(g->weak); |
804 | cleartable(g->ephemeron); | 818 | cleartable(g->ephemeron); |
805 | cleartable(g->allweak); | 819 | cleartable(g->allweak); |
806 | /*lua_checkmemory(L);*/ | 820 | lua_checkmemory(L); |
807 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ | 821 | g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ |
808 | } | 822 | } |
809 | 823 | ||