diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-03-04 10:51:55 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-03-04 10:51:55 -0300 |
commit | 2ae2e6408e6f6585e23f4f10ddeafdcb8cf42324 (patch) | |
tree | 631c29494c5e3c8ca745231dc166c87c4d91dfc4 | |
parent | a80cada9142f9e967c710e37934067a708224161 (diff) | |
download | lua-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.c | 32 |
1 files changed, 21 insertions, 11 deletions
@@ -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 | ||
89 | static void reallymarkobject (global_State *g, GCObject *o); | 94 | static 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) { | |||
279 | static void markmt (global_State *g) { | 284 | static 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) { | |||
441 | static lu_mem traversetable (global_State *g, Table *h) { | 446 | static 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 | */ | ||
464 | static int traverseproto (global_State *g, Proto *f) { | 474 | static 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 | */ |
499 | static lu_mem traverseLclosure (global_State *g, LClosure *cl) { | 509 | static 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) { |