diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-12 15:47:33 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-12 15:47:33 -0200 |
commit | 21259a50e12ca45669379a4b37fbe7e502cdd22d (patch) | |
tree | cf881a0824e24bcc58eaf4cebbe81c928419e3ba /lgc.c | |
parent | 9aff171f3bf0125314a29a5ca952470b2d83708e (diff) | |
download | lua-21259a50e12ca45669379a4b37fbe7e502cdd22d.tar.gz lua-21259a50e12ca45669379a4b37fbe7e502cdd22d.tar.bz2 lua-21259a50e12ca45669379a4b37fbe7e502cdd22d.zip |
run GC tag methods in protected mod
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 33 |
1 files changed, 23 insertions, 10 deletions
@@ -356,32 +356,30 @@ static void checkMbuffer (lua_State *L) { | |||
356 | } | 356 | } |
357 | 357 | ||
358 | 358 | ||
359 | static void callgcTM (lua_State *L, Udata *udata) { | 359 | static void do1gcTM (lua_State *L, Udata *udata) { |
360 | const TObject *tm = fasttm(L, udata->uv.eventtable, TM_GC); | 360 | const TObject *tm = fasttm(L, udata->uv.eventtable, TM_GC); |
361 | if (tm != NULL && ttype(tm) == LUA_TFUNCTION) { | 361 | if (tm != NULL) { |
362 | int oldah = L->allowhooks; | ||
363 | StkId top = L->top; | 362 | StkId top = L->top; |
364 | L->allowhooks = 0; /* stop debug hooks during GC tag methods */ | ||
365 | setobj(top, tm); | 363 | setobj(top, tm); |
366 | setuvalue(top+1, udata); | 364 | setuvalue(top+1, udata); |
367 | L->top += 2; | 365 | L->top += 2; |
368 | luaD_call(L, top); | 366 | luaD_call(L, top); |
369 | L->top = top; /* restore top */ | 367 | L->top = top; /* restore top */ |
370 | L->allowhooks = oldah; /* restore hooks */ | ||
371 | } | 368 | } |
372 | } | 369 | } |
373 | 370 | ||
374 | 371 | ||
375 | static void callgcTMudata (lua_State *L) { | 372 | static void unprotectedcallGCTM (lua_State *L, void *pu) { |
376 | luaD_checkstack(L, 3); | 373 | luaD_checkstack(L, 3); |
377 | L->top++; /* reserve space to keep udata while runs its gc method */ | 374 | L->top++; /* reserve space to keep udata while runs its gc method */ |
378 | while (G(L)->tmudata != NULL) { | 375 | while (G(L)->tmudata != NULL) { |
379 | Udata *udata = G(L)->tmudata; | 376 | Udata *udata = G(L)->tmudata; |
380 | G(L)->tmudata = udata->uv.next; /* remove udata from list */ | 377 | G(L)->tmudata = udata->uv.next; /* remove udata from list */ |
378 | *(Udata **)pu = udata; /* keep a reference to it (in case of errors) */ | ||
379 | setuvalue(L->top - 1, udata); /* and on stack (in case of recursive GC) */ | ||
381 | udata->uv.next = G(L)->rootudata; /* resurect it */ | 380 | udata->uv.next = G(L)->rootudata; /* resurect it */ |
382 | G(L)->rootudata = udata; | 381 | G(L)->rootudata = udata; |
383 | setuvalue(L->top - 1, udata); | 382 | do1gcTM(L, udata); |
384 | callgcTM(L, udata); | ||
385 | /* mark udata as finalized (default event table) */ | 383 | /* mark udata as finalized (default event table) */ |
386 | uvalue(L->top-1)->uv.eventtable = hvalue(defaultet(L)); | 384 | uvalue(L->top-1)->uv.eventtable = hvalue(defaultet(L)); |
387 | } | 385 | } |
@@ -389,11 +387,26 @@ static void callgcTMudata (lua_State *L) { | |||
389 | } | 387 | } |
390 | 388 | ||
391 | 389 | ||
390 | static void callGCTM (lua_State *L) { | ||
391 | int oldah = L->allowhooks; | ||
392 | L->allowhooks = 0; /* stop debug hooks during GC tag methods */ | ||
393 | while (G(L)->tmudata != NULL) { | ||
394 | Udata *udata; | ||
395 | if (luaD_runprotected(L, unprotectedcallGCTM, &udata) != 0) { | ||
396 | /* `udata' generated an error during its gc */ | ||
397 | /* mark it as finalized (default event table) */ | ||
398 | udata->uv.eventtable = hvalue(defaultet(L)); | ||
399 | } | ||
400 | } | ||
401 | L->allowhooks = oldah; /* restore hooks */ | ||
402 | } | ||
403 | |||
404 | |||
392 | void luaC_callallgcTM (lua_State *L) { | 405 | void luaC_callallgcTM (lua_State *L) { |
393 | lua_assert(G(L)->tmudata == NULL); | 406 | lua_assert(G(L)->tmudata == NULL); |
394 | G(L)->tmudata = G(L)->rootudata; /* all udata must be collected */ | 407 | G(L)->tmudata = G(L)->rootudata; /* all udata must be collected */ |
395 | G(L)->rootudata = NULL; | 408 | G(L)->rootudata = NULL; |
396 | callgcTMudata(L); /* call their GC tag methods */ | 409 | callGCTM(L); /* call their GC tag methods */ |
397 | } | 410 | } |
398 | 411 | ||
399 | 412 | ||
@@ -416,6 +429,6 @@ void luaC_collectgarbage (lua_State *L) { | |||
416 | luaC_collect(L, 0); | 429 | luaC_collect(L, 0); |
417 | checkMbuffer(L); | 430 | checkMbuffer(L); |
418 | G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ | 431 | G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ |
419 | callgcTMudata(L); | 432 | callGCTM(L); |
420 | } | 433 | } |
421 | 434 | ||