diff options
| -rw-r--r-- | lgc.c | 20 | ||||
| -rw-r--r-- | lstate.c | 10 | ||||
| -rw-r--r-- | lstate.h | 19 |
3 files changed, 23 insertions, 26 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 1.151 2002/09/19 19:54:22 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.152 2002/10/08 18:46:08 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 | */ |
| @@ -34,7 +34,6 @@ typedef struct GCState { | |||
| 34 | #define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b)))) | 34 | #define resetbit(x,b) ((x) &= cast(lu_byte, ~(1<<(b)))) |
| 35 | #define testbit(x,b) ((x) & (1<<(b))) | 35 | #define testbit(x,b) ((x) & (1<<(b))) |
| 36 | 36 | ||
| 37 | #define mark(x) setbit((x)->gch.marked, 0) | ||
| 38 | #define unmark(x) resetbit((x)->gch.marked, 0) | 37 | #define unmark(x) resetbit((x)->gch.marked, 0) |
| 39 | #define ismarked(x) ((x)->gch.marked & ((1<<4)|1)) | 38 | #define ismarked(x) ((x)->gch.marked & ((1<<4)|1)) |
| 40 | 39 | ||
| @@ -101,7 +100,7 @@ static void markclosure (GCState *st, Closure *cl) { | |||
| 101 | 100 | ||
| 102 | 101 | ||
| 103 | static void reallymarkobject (GCState *st, GCObject *o) { | 102 | static void reallymarkobject (GCState *st, GCObject *o) { |
| 104 | mark(o); | 103 | setbit(o->gch.marked, 0); /* mark object */ |
| 105 | switch (o->gch.tt) { | 104 | switch (o->gch.tt) { |
| 106 | case LUA_TFUNCTION: { | 105 | case LUA_TFUNCTION: { |
| 107 | markclosure(st, &o->cl); | 106 | markclosure(st, &o->cl); |
| @@ -135,15 +134,13 @@ static void traversestacks (GCState *st) { | |||
| 135 | do { /* for each thread */ | 134 | do { /* for each thread */ |
| 136 | StkId o, lim; | 135 | StkId o, lim; |
| 137 | CallInfo *ci; | 136 | CallInfo *ci; |
| 138 | if (ttisnil(defaultmeta(L1))) { /* incomplete state? */ | 137 | if (ttisnil(gt(L1))) { /* incomplete state? */ |
| 139 | lua_assert(L1 != st->L); | 138 | lua_assert(L1 != st->L); |
| 140 | L1 = L1->next; | 139 | L1 = L1->next; |
| 141 | luaE_closethread(st->L, L1->previous); /* collect it */ | 140 | luaE_closethread(st->L, L1->previous); /* collect it */ |
| 142 | continue; | 141 | continue; |
| 143 | } | 142 | } |
| 144 | markobject(st, defaultmeta(L1)); | ||
| 145 | markobject(st, gt(L1)); | 143 | markobject(st, gt(L1)); |
| 146 | markobject(st, registry(L1)); | ||
| 147 | for (o=L1->stack; o<L1->top; o++) | 144 | for (o=L1->stack; o<L1->top; o++) |
| 148 | markobject(st, o); | 145 | markobject(st, o); |
| 149 | lim = o; | 146 | lim = o; |
| @@ -156,6 +153,8 @@ static void traversestacks (GCState *st) { | |||
| 156 | lua_assert(L1->previous->next == L1 && L1->next->previous == L1); | 153 | lua_assert(L1->previous->next == L1 && L1->next->previous == L1); |
| 157 | L1 = L1->next; | 154 | L1 = L1->next; |
| 158 | } while (L1 != st->L); | 155 | } while (L1 != st->L); |
| 156 | markobject(st, defaultmeta(L1)); | ||
| 157 | markobject(st, registry(L1)); | ||
| 159 | } | 158 | } |
| 160 | 159 | ||
| 161 | 160 | ||
| @@ -342,6 +341,7 @@ static void checkSizes (lua_State *L) { | |||
| 342 | size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2; | 341 | size_t newsize = luaZ_sizebuffer(&G(L)->buff) / 2; |
| 343 | luaZ_resizebuffer(L, &G(L)->buff, newsize); | 342 | luaZ_resizebuffer(L, &G(L)->buff, newsize); |
| 344 | } | 343 | } |
| 344 | G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ | ||
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | 347 | ||
| @@ -389,7 +389,7 @@ void luaC_sweep (lua_State *L, int all) { | |||
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | 391 | ||
| 392 | void luaC_collectgarbage (lua_State *L) { | 392 | static void mark (lua_State *L) { |
| 393 | GCState st; | 393 | GCState st; |
| 394 | Table *toclear; | 394 | Table *toclear; |
| 395 | st.L = L; | 395 | st.L = L; |
| @@ -407,9 +407,13 @@ void luaC_collectgarbage (lua_State *L) { | |||
| 407 | /* `propagatemarks' may reborne some weak tables; clear them too */ | 407 | /* `propagatemarks' may reborne some weak tables; clear them too */ |
| 408 | cleartablekeys(st.toclear); | 408 | cleartablekeys(st.toclear); |
| 409 | cleartablevalues(st.toclear); | 409 | cleartablevalues(st.toclear); |
| 410 | } | ||
| 411 | |||
| 412 | |||
| 413 | void luaC_collectgarbage (lua_State *L) { | ||
| 414 | mark(L); | ||
| 410 | luaC_sweep(L, 0); | 415 | luaC_sweep(L, 0); |
| 411 | checkSizes(L); | 416 | checkSizes(L); |
| 412 | G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ | ||
| 413 | callGCTM(L); | 417 | callGCTM(L); |
| 414 | } | 418 | } |
| 415 | 419 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 1.105 2002/08/30 19:09:21 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 1.106 2002/10/08 18:46:08 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -25,7 +25,7 @@ static void close_state (lua_State *L); | |||
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | /* | 27 | /* |
| 28 | ** you can change this function through the official API | 28 | ** you can change this function through the official API: |
| 29 | ** call `lua_setpanicf' | 29 | ** call `lua_setpanicf' |
| 30 | */ | 30 | */ |
| 31 | static int default_panic (lua_State *L) { | 31 | static int default_panic (lua_State *L) { |
| @@ -61,6 +61,8 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
| 61 | G(L)->strt.size = 0; | 61 | G(L)->strt.size = 0; |
| 62 | G(L)->strt.nuse = 0; | 62 | G(L)->strt.nuse = 0; |
| 63 | G(L)->strt.hash = NULL; | 63 | G(L)->strt.hash = NULL; |
| 64 | setnilvalue(defaultmeta(L)); | ||
| 65 | setnilvalue(registry(L)); | ||
| 64 | luaZ_initbuffer(L, &G(L)->buff); | 66 | luaZ_initbuffer(L, &G(L)->buff); |
| 65 | G(L)->panic = &default_panic; | 67 | G(L)->panic = &default_panic; |
| 66 | G(L)->rootgc = NULL; | 68 | G(L)->rootgc = NULL; |
| @@ -97,9 +99,7 @@ static void preinit_state (lua_State *L) { | |||
| 97 | L->size_ci = 0; | 99 | L->size_ci = 0; |
| 98 | L->base_ci = L->ci = NULL; | 100 | L->base_ci = L->ci = NULL; |
| 99 | L->errfunc = 0; | 101 | L->errfunc = 0; |
| 100 | setnilvalue(defaultmeta(L)); | ||
| 101 | setnilvalue(gt(L)); | 102 | setnilvalue(gt(L)); |
| 102 | setnilvalue(registry(L)); | ||
| 103 | } | 103 | } |
| 104 | 104 | ||
| 105 | 105 | ||
| @@ -114,9 +114,7 @@ LUA_API lua_State *lua_newthread (lua_State *OL) { | |||
| 114 | OL->next = L; | 114 | OL->next = L; |
| 115 | L->previous = OL; | 115 | L->previous = OL; |
| 116 | stack_init(L, OL); /* init stack */ | 116 | stack_init(L, OL); /* init stack */ |
| 117 | setobj(defaultmeta(L), defaultmeta(OL)); /* share default meta table */ | ||
| 118 | setobj(gt(L), gt(OL)); /* share table of globals */ | 117 | setobj(gt(L), gt(OL)); /* share table of globals */ |
| 119 | setobj(registry(L), registry(OL)); /* share registry */ | ||
| 120 | lua_unlock(OL); | 118 | lua_unlock(OL); |
| 121 | lua_userstateopen(L); | 119 | lua_userstateopen(L); |
| 122 | return L; | 120 | return L; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 1.96 2002/09/19 13:03:53 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 1.97 2002/10/08 18:46:08 roberto Exp roberto $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -48,21 +48,14 @@ | |||
| 48 | struct lua_longjmp; /* defined in ldo.c */ | 48 | struct lua_longjmp; /* defined in ldo.c */ |
| 49 | 49 | ||
| 50 | 50 | ||
| 51 | |||
| 52 | /* | ||
| 53 | ** array of `global' objects | ||
| 54 | */ | ||
| 55 | |||
| 56 | #define NUMGLOBS 3 | ||
| 57 | |||
| 58 | /* default meta table (both for tables and udata) */ | 51 | /* default meta table (both for tables and udata) */ |
| 59 | #define defaultmeta(L) (L->globs) | 52 | #define defaultmeta(L) (&G(L)->_defaultmeta) |
| 60 | 53 | ||
| 61 | /* table of globals */ | 54 | /* table of globals */ |
| 62 | #define gt(L) (L->globs + 1) | 55 | #define gt(L) (&L->_gt) |
| 63 | 56 | ||
| 64 | /* registry */ | 57 | /* registry */ |
| 65 | #define registry(L) (L->globs + 2) | 58 | #define registry(L) (&G(L)->_registry) |
| 66 | 59 | ||
| 67 | 60 | ||
| 68 | /* extra stack space to handle TM calls and some other extras */ | 61 | /* extra stack space to handle TM calls and some other extras */ |
| @@ -129,6 +122,8 @@ typedef struct global_State { | |||
| 129 | lu_mem GCthreshold; | 122 | lu_mem GCthreshold; |
| 130 | lu_mem nblocks; /* number of `bytes' currently allocated */ | 123 | lu_mem nblocks; /* number of `bytes' currently allocated */ |
| 131 | lua_CFunction panic; /* to be called in unprotected errors */ | 124 | lua_CFunction panic; /* to be called in unprotected errors */ |
| 125 | TObject _registry; | ||
| 126 | TObject _defaultmeta; | ||
| 132 | Node dummynode[1]; /* common node array for all empty tables */ | 127 | Node dummynode[1]; /* common node array for all empty tables */ |
| 133 | TString *tmname[TM_N]; /* array with tag-method names */ | 128 | TString *tmname[TM_N]; /* array with tag-method names */ |
| 134 | } global_State; | 129 | } global_State; |
| @@ -151,12 +146,12 @@ struct lua_State { | |||
| 151 | unsigned long hookmask; | 146 | unsigned long hookmask; |
| 152 | ls_count hookcount; | 147 | ls_count hookcount; |
| 153 | lua_Hook hook; | 148 | lua_Hook hook; |
| 149 | TObject _gt; /* table of globals */ | ||
| 154 | GCObject *openupval; /* list of open upvalues in this stack */ | 150 | GCObject *openupval; /* list of open upvalues in this stack */ |
| 155 | struct lua_longjmp *errorJmp; /* current error recover point */ | 151 | struct lua_longjmp *errorJmp; /* current error recover point */ |
| 156 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 152 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
| 157 | lua_State *next; /* circular double linked list of states */ | 153 | lua_State *next; /* circular double linked list of states */ |
| 158 | lua_State *previous; | 154 | lua_State *previous; |
| 159 | TObject globs[NUMGLOBS]; /* registry, table of globals, etc. */ | ||
| 160 | }; | 155 | }; |
| 161 | 156 | ||
| 162 | 157 | ||
