diff options
-rw-r--r-- | lgc.c | 22 | ||||
-rw-r--r-- | lgc.h | 4 |
2 files changed, 16 insertions, 10 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.174 2003/07/07 13:32:19 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.175 2003/07/16 20:49:02 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 | */ |
@@ -108,7 +108,8 @@ static void marktmu (GCState *st) { | |||
108 | 108 | ||
109 | 109 | ||
110 | /* move `dead' udata that need finalization to list `tmudata' */ | 110 | /* move `dead' udata that need finalization to list `tmudata' */ |
111 | void luaC_separateudata (lua_State *L) { | 111 | size_t luaC_separateudata (lua_State *L) { |
112 | size_t deadmem = 0; | ||
112 | GCObject **p = &G(L)->rootudata; | 113 | GCObject **p = &G(L)->rootudata; |
113 | GCObject *curr; | 114 | GCObject *curr; |
114 | GCObject *collected = NULL; /* to collect udata with gc event */ | 115 | GCObject *collected = NULL; /* to collect udata with gc event */ |
@@ -123,6 +124,7 @@ void luaC_separateudata (lua_State *L) { | |||
123 | p = &curr->gch.next; | 124 | p = &curr->gch.next; |
124 | } | 125 | } |
125 | else { /* must call its gc method */ | 126 | else { /* must call its gc method */ |
127 | deadmem += sizeudata(gcotou(curr)->uv.len); | ||
126 | markfinalized(gcotou(curr)); | 128 | markfinalized(gcotou(curr)); |
127 | *p = curr->gch.next; | 129 | *p = curr->gch.next; |
128 | curr->gch.next = NULL; /* link `curr' at the end of `collected' list */ | 130 | curr->gch.next = NULL; /* link `curr' at the end of `collected' list */ |
@@ -133,6 +135,7 @@ void luaC_separateudata (lua_State *L) { | |||
133 | /* insert collected udata with gc event into `tmudata' list */ | 135 | /* insert collected udata with gc event into `tmudata' list */ |
134 | *lastcollected = G(L)->tmudata; | 136 | *lastcollected = G(L)->tmudata; |
135 | G(L)->tmudata = collected; | 137 | G(L)->tmudata = collected; |
138 | return deadmem; | ||
136 | } | 139 | } |
137 | 140 | ||
138 | 141 | ||
@@ -377,7 +380,7 @@ static void sweepstrings (lua_State *L, int all) { | |||
377 | } | 380 | } |
378 | 381 | ||
379 | 382 | ||
380 | static void checkSizes (lua_State *L) { | 383 | static void checkSizes (lua_State *L, size_t deadmem) { |
381 | /* check size of string hash */ | 384 | /* check size of string hash */ |
382 | if (G(L)->strt.nuse < cast(lu_int32, G(L)->strt.size/4) && | 385 | if (G(L)->strt.nuse < cast(lu_int32, G(L)->strt.size/4) && |
383 | G(L)->strt.size > MINSTRTABSIZE*2) | 386 | G(L)->strt.size > MINSTRTABSIZE*2) |
@@ -387,7 +390,8 @@ static void checkSizes (lua_State *L) { | |||
387 | size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2; | 390 | size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2; |
388 | luaZ_resizebuffer(L, &G(L)->buff, newsize); | 391 | luaZ_resizebuffer(L, &G(L)->buff, newsize); |
389 | } | 392 | } |
390 | G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ | 393 | lua_assert(G(L)->nblocks > deadmem); |
394 | G(L)->GCthreshold = 2*G(L)->nblocks - deadmem; /* new threshold */ | ||
391 | } | 395 | } |
392 | 396 | ||
393 | 397 | ||
@@ -440,24 +444,26 @@ static void markroot (GCState *st, lua_State *L) { | |||
440 | } | 444 | } |
441 | 445 | ||
442 | 446 | ||
443 | static void mark (lua_State *L) { | 447 | static size_t mark (lua_State *L) { |
448 | size_t deadmem; | ||
444 | GCState st; | 449 | GCState st; |
445 | st.g = G(L); | 450 | st.g = G(L); |
446 | st.tmark = NULL; | 451 | st.tmark = NULL; |
447 | st.w = NULL; | 452 | st.w = NULL; |
448 | markroot(&st, L); | 453 | markroot(&st, L); |
449 | propagatemarks(&st); /* mark all reachable objects */ | 454 | propagatemarks(&st); /* mark all reachable objects */ |
450 | luaC_separateudata(L); /* separate userdata to be preserved */ | 455 | deadmem = luaC_separateudata(L); /* separate userdata to be preserved */ |
451 | marktmu(&st); /* mark `preserved' userdata */ | 456 | marktmu(&st); /* mark `preserved' userdata */ |
452 | propagatemarks(&st); /* remark, to propagate `preserveness' */ | 457 | propagatemarks(&st); /* remark, to propagate `preserveness' */ |
453 | cleartable(st.w); /* remove collected objects from weak tables */ | 458 | cleartable(st.w); /* remove collected objects from weak tables */ |
459 | return deadmem; | ||
454 | } | 460 | } |
455 | 461 | ||
456 | 462 | ||
457 | void luaC_collectgarbage (lua_State *L) { | 463 | void luaC_collectgarbage (lua_State *L) { |
458 | mark(L); | 464 | size_t deadmem = mark(L); |
459 | luaC_sweep(L, 0); | 465 | luaC_sweep(L, 0); |
460 | checkSizes(L); | 466 | checkSizes(L, deadmem); |
461 | luaC_callGCTM(L); | 467 | luaC_callGCTM(L); |
462 | } | 468 | } |
463 | 469 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 1.19 2003/02/28 19:45:15 roberto Exp $ | 2 | ** $Id: lgc.h,v 1.20 2003/07/16 20:49:02 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 | */ |
@@ -15,7 +15,7 @@ | |||
15 | luaC_collectgarbage(L); } | 15 | luaC_collectgarbage(L); } |
16 | 16 | ||
17 | 17 | ||
18 | void luaC_separateudata (lua_State *L); | 18 | size_t luaC_separateudata (lua_State *L); |
19 | void luaC_callGCTM (lua_State *L); | 19 | void luaC_callGCTM (lua_State *L); |
20 | void luaC_sweep (lua_State *L, int all); | 20 | void luaC_sweep (lua_State *L, int all); |
21 | void luaC_collectgarbage (lua_State *L); | 21 | void luaC_collectgarbage (lua_State *L); |