aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-03-04 10:51:55 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-03-04 10:51:55 -0300
commit2ae2e6408e6f6585e23f4f10ddeafdcb8cf42324 (patch)
tree631c29494c5e3c8ca745231dc166c87c4d91dfc4
parenta80cada9142f9e967c710e37934067a708224161 (diff)
downloadlua-2ae2e6408e6f6585e23f4f10ddeafdcb8cf42324.tar.gz
lua-2ae2e6408e6f6585e23f4f10ddeafdcb8cf42324.tar.bz2
lua-2ae2e6408e6f6585e23f4f10ddeafdcb8cf42324.zip
avoid testing for NULL when marking objects that cannot be NULL
-rw-r--r--lgc.c32
1 files changed, 21 insertions, 11 deletions
diff --git a/lgc.c b/lgc.c
index db4259e0..3bc0740b 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.202 2015/01/16 16:54:37 roberto Exp roberto $ 2** $Id: lgc.c,v 2.203 2015/03/04 13:31:21 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*/
@@ -83,8 +83,13 @@
83#define markvalue(g,o) { checkconsistency(o); \ 83#define markvalue(g,o) { checkconsistency(o); \
84 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } 84 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
85 85
86#define markobject(g,t) \ 86#define markobject(g,t) { if (iswhite(t)) reallymarkobject(g, obj2gco(t)); }
87 { if ((t) && iswhite(t)) reallymarkobject(g, obj2gco(t)); } 87
88/*
89** mark an object that can be NULL (either because it is really optional,
90** or it was stripped as debug info, or inside an uncompleted structure)
91*/
92#define markobjectN(g,t) { if (t) markobject(g,t); }
88 93
89static void reallymarkobject (global_State *g, GCObject *o); 94static void reallymarkobject (global_State *g, GCObject *o);
90 95
@@ -238,7 +243,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
238 } 243 }
239 case LUA_TUSERDATA: { 244 case LUA_TUSERDATA: {
240 TValue uvalue; 245 TValue uvalue;
241 markobject(g, gco2u(o)->metatable); /* mark its metatable */ 246 markobjectN(g, gco2u(o)->metatable); /* mark its metatable */
242 gray2black(o); 247 gray2black(o);
243 g->GCmemtrav += sizeudata(gco2u(o)); 248 g->GCmemtrav += sizeudata(gco2u(o));
244 getuservalue(g->mainthread, gco2u(o), &uvalue); 249 getuservalue(g->mainthread, gco2u(o), &uvalue);
@@ -279,7 +284,7 @@ static void reallymarkobject (global_State *g, GCObject *o) {
279static void markmt (global_State *g) { 284static void markmt (global_State *g) {
280 int i; 285 int i;
281 for (i=0; i < LUA_NUMTAGS; i++) 286 for (i=0; i < LUA_NUMTAGS; i++)
282 markobject(g, g->mt[i]); 287 markobjectN(g, g->mt[i]);
283} 288}
284 289
285 290
@@ -441,7 +446,7 @@ static void traversestrongtable (global_State *g, Table *h) {
441static lu_mem traversetable (global_State *g, Table *h) { 446static lu_mem traversetable (global_State *g, Table *h) {
442 const char *weakkey, *weakvalue; 447 const char *weakkey, *weakvalue;
443 const TValue *mode = gfasttm(g, h->metatable, TM_MODE); 448 const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
444 markobject(g, h->metatable); 449 markobjectN(g, h->metatable);
445 if (mode && ttisstring(mode) && /* is there a weak mode? */ 450 if (mode && ttisstring(mode) && /* is there a weak mode? */
446 ((weakkey = strchr(svalue(mode), 'k')), 451 ((weakkey = strchr(svalue(mode), 'k')),
447 (weakvalue = strchr(svalue(mode), 'v')), 452 (weakvalue = strchr(svalue(mode), 'v')),
@@ -461,19 +466,24 @@ static lu_mem traversetable (global_State *g, Table *h) {
461} 466}
462 467
463 468
469/*
470** Traverse a prototype. (While a prototype is being build, its
471** arrays can be larger than needed; the extra slots are filled with
472** NULL, so the use of 'markobjectN')
473*/
464static int traverseproto (global_State *g, Proto *f) { 474static int traverseproto (global_State *g, Proto *f) {
465 int i; 475 int i;
466 if (f->cache && iswhite(f->cache)) 476 if (f->cache && iswhite(f->cache))
467 f->cache = NULL; /* allow cache to be collected */ 477 f->cache = NULL; /* allow cache to be collected */
468 markobject(g, f->source); 478 markobjectN(g, f->source);
469 for (i = 0; i < f->sizek; i++) /* mark literals */ 479 for (i = 0; i < f->sizek; i++) /* mark literals */
470 markvalue(g, &f->k[i]); 480 markvalue(g, &f->k[i]);
471 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ 481 for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */
472 markobject(g, f->upvalues[i].name); 482 markobjectN(g, f->upvalues[i].name);
473 for (i = 0; i < f->sizep; i++) /* mark nested protos */ 483 for (i = 0; i < f->sizep; i++) /* mark nested protos */
474 markobject(g, f->p[i]); 484 markobjectN(g, f->p[i]);
475 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ 485 for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */
476 markobject(g, f->locvars[i].varname); 486 markobjectN(g, f->locvars[i].varname);
477 return sizeof(Proto) + sizeof(Instruction) * f->sizecode + 487 return sizeof(Proto) + sizeof(Instruction) * f->sizecode +
478 sizeof(Proto *) * f->sizep + 488 sizeof(Proto *) * f->sizep +
479 sizeof(TValue) * f->sizek + 489 sizeof(TValue) * f->sizek +
@@ -498,7 +508,7 @@ static lu_mem traverseCclosure (global_State *g, CClosure *cl) {
498*/ 508*/
499static lu_mem traverseLclosure (global_State *g, LClosure *cl) { 509static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
500 int i; 510 int i;
501 markobject(g, cl->p); /* mark its prototype */ 511 markobjectN(g, cl->p); /* mark its prototype */
502 for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */ 512 for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */
503 UpVal *uv = cl->upvals[i]; 513 UpVal *uv = cl->upvals[i];
504 if (uv != NULL) { 514 if (uv != NULL) {