From 126cd5bece370a2a6e2d77b6cec6ac89e9ed918b Mon Sep 17 00:00:00 2001 From: Bogdan Marinescu Date: Thu, 5 Nov 2009 21:11:12 +0000 Subject: [PATCH] integrated Robert's EGC fix for eLua --- src/lua/ldo.c | 2 ++ src/lua/lgc.c | 10 +++++----- src/lua/lgc.h | 6 ++++++ src/lua/lobject.h | 40 +++++++++++++++++++++++----------------- src/lua/lvm.c | 19 +++++++++++++++++-- src/lua/lzio.h | 2 +- 6 files changed, 54 insertions(+), 25 deletions(-) diff --git a/src/lua/ldo.c b/src/lua/ldo.c index ea246a9d..0704187f 100644 --- a/src/lua/ldo.c +++ b/src/lua/ldo.c @@ -92,6 +92,8 @@ static void resetstack (lua_State *L, int status) { void luaD_throw (lua_State *L, int errcode) { + unfixedstack(L); /* make sure the fixedstack & block_gc flags get reset. */ + unset_block_gc(L); if (L->errorJmp) { L->errorJmp->status = errcode; LUAI_THROW(L, L->errorJmp); diff --git a/src/lua/lgc.c b/src/lua/lgc.c index 42889378..5bd10ee8 100644 --- a/src/lua/lgc.c +++ b/src/lua/lgc.c @@ -269,7 +269,8 @@ static void traversestack (global_State *g, lua_State *l) { markvalue(g, o); for (; o <= lim; o++) setnilvalue(o); - checkstacksizes(l, lim); + if (!isfixedstack(l)) /* if stack size is fixed, can't resize it. */ + checkstacksizes(l, lim); } @@ -435,13 +436,12 @@ static void checkSizes (lua_State *L) { if (g->strt.nuse < cast(lu_int32, g->strt.size/4) && g->strt.size > MINSTRTABSIZE*2) luaS_resize(L, g->strt.size/2); /* table is too big */ + /* it is not safe to re-size the buffer if it is in use. */ + if (luaZ_bufflen(&g->buff) > 0) return; /* check size of buffer */ if (luaZ_sizebuffer(&g->buff) > LUA_MINBUFFER*2) { /* buffer too big? */ size_t newsize = luaZ_sizebuffer(&g->buff) / 2; - /* make sure newsize is larger then the buffer's in use size. */ - newsize = (luaZ_bufflen(&g->buff) > newsize) ? luaZ_bufflen(&g->buff) : newsize; - if(newsize < luaZ_sizebuffer(&g->buff)) - luaZ_resizebuffer(L, &g->buff, newsize); + luaZ_resizebuffer(L, &g->buff, newsize); } } diff --git a/src/lua/lgc.h b/src/lua/lgc.h index 58b9b8d5..03f59e3e 100644 --- a/src/lua/lgc.h +++ b/src/lua/lgc.h @@ -41,6 +41,7 @@ ** Possible Garbage Collector flags. ** Layout for bit use in 'gsflags' field in global_State structure. ** bit 0 - Protect GC from recursive calls. +** bit 1 - Don't try to shrink string table if EGC was called during a string table resize. */ #define GCFlagsNone 0 #define GCBlockGCBit 0 @@ -59,6 +60,7 @@ ** bit 0 - object is white (type 0) ** bit 1 - object is white (type 1) ** bit 2 - object is black +** bit 3 - for thread: Don't resize thread's stack ** bit 3 - for userdata: has been finalized ** bit 3 - for tables: has weak keys ** bit 4 - for tables: has weak values @@ -70,6 +72,7 @@ #define WHITE0BIT 0 #define WHITE1BIT 1 #define BLACKBIT 2 +#define FIXEDSTACKBIT 3 #define FINALIZEDBIT 3 #define KEYWEAKBIT 3 #define VALUEWEAKBIT 4 @@ -92,6 +95,9 @@ #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) +#define isfixedstack(x) testbit((x)->marked, FIXEDSTACKBIT) +#define fixedstack(x) l_setbit((x)->marked, FIXEDSTACKBIT) +#define unfixedstack(x) resetbit((x)->marked, FIXEDSTACKBIT) #define luaC_checkGC(L) { \ condhardstacktests(luaD_reallocstack(L, L->stacksize - EXTRA_STACK - 1)); \ diff --git a/src/lua/lobject.h b/src/lua/lobject.h index b57c2d20..cf21749f 100644 --- a/src/lua/lobject.h +++ b/src/lua/lobject.h @@ -120,48 +120,54 @@ typedef struct lua_TValue { #define setnilvalue(obj) ((obj)->tt=LUA_TNIL) #define setnvalue(obj,x) \ - { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; } + { lua_Number i_x = (x); TValue *i_o=(obj); i_o->value.n=i_x; i_o->tt=LUA_TNUMBER; } #define setpvalue(obj,x) \ - { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; } + { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTUSERDATA; } #define setrvalue(obj,x) \ - { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TROTABLE; } + { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TROTABLE; } #define setfvalue(obj,x) \ - { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTFUNCTION; } + { void *i_x = (x); TValue *i_o=(obj); i_o->value.p=i_x; i_o->tt=LUA_TLIGHTFUNCTION; } #define setbvalue(obj,x) \ - { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; } + { int i_x = (x); TValue *i_o=(obj); i_o->value.b=i_x; i_o->tt=LUA_TBOOLEAN; } #define setsvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \ + { GCObject *i_x = cast(GCObject *, (x)); \ + TValue *i_o=(obj); \ + i_o->value.gc=i_x; i_o->tt=LUA_TSTRING; \ checkliveness(G(L),i_o); } #define setuvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \ + { GCObject *i_x = cast(GCObject *, (x)); \ + TValue *i_o=(obj); \ + i_o->value.gc=i_x; i_o->tt=LUA_TUSERDATA; \ checkliveness(G(L),i_o); } #define setthvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \ + { GCObject *i_x = cast(GCObject *, (x)); \ + TValue *i_o=(obj); \ + i_o->value.gc=i_x; i_o->tt=LUA_TTHREAD; \ checkliveness(G(L),i_o); } #define setclvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \ + { GCObject *i_x = cast(GCObject *, (x)); \ + TValue *i_o=(obj); \ + i_o->value.gc=i_x; i_o->tt=LUA_TFUNCTION; \ checkliveness(G(L),i_o); } #define sethvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \ + { GCObject *i_x = cast(GCObject *, (x)); \ + TValue *i_o=(obj); \ + i_o->value.gc=i_x; i_o->tt=LUA_TTABLE; \ checkliveness(G(L),i_o); } #define setptvalue(L,obj,x) \ - { TValue *i_o=(obj); \ - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \ + { GCObject *i_x = cast(GCObject *, (x)); \ + TValue *i_o=(obj); \ + i_o->value.gc=i_x; i_o->tt=LUA_TPROTO; \ checkliveness(G(L),i_o); } diff --git a/src/lua/lvm.c b/src/lua/lvm.c index 25df36a4..8f45019a 100644 --- a/src/lua/lvm.c +++ b/src/lua/lvm.c @@ -152,6 +152,10 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { int loop; + TValue temp; + setnilvalue(L->top); + L->top++; + fixedstack(L); for (loop = 0; loop < MAXTAGLOOP; loop++) { const TValue *tm; if (ttistable(t) || ttisrotable(t)) { /* `t' is a table? */ @@ -160,6 +164,8 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { if ((oldval && !ttisnil(oldval)) || /* result is no nil? */ (tm = fasttm(L, ttistable(t) ? ((Table*)h)->metatable : (Table*)luaR_getmeta(h), TM_NEWINDEX)) == NULL) { /* or no TM? */ if(oldval) { + L->top--; + unfixedstack(L); setobj2t(L, oldval, val); luaC_barriert(L, (Table*)h, val); } @@ -170,10 +176,15 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) luaG_typeerror(L, t, "index"); if (ttisfunction(tm) || ttislightfunction(tm)) { + L->top--; + unfixedstack(L); callTM(L, tm, t, key, val); return; } - t = tm; /* else repeat with `tm' */ + /* else repeat with `tm' */ + setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ + t = &temp; + setobj2s(L, L->top-1, t); /* need to protect value from EGC. */ } luaG_runerror(L, "loop in settable"); } @@ -300,6 +311,8 @@ int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) { void luaV_concat (lua_State *L, int total, int last) { + lu_mem max_sizet = MAX_SIZET; + if (G(L)->memlimit < max_sizet) max_sizet = G(L)->memlimit; do { StkId top = L->base + last + 1; int n = 2; /* number of elements handled in this pass (at least 2) */ @@ -313,10 +326,11 @@ void luaV_concat (lua_State *L, int total, int last) { size_t tl = tsvalue(top-1)->len; char *buffer; int i; + fixedstack(L); /* collect total length */ for (n = 1; n < total && tostring(L, top-n-1); n++) { size_t l = tsvalue(top-n-1)->len; - if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow"); + if (l >= max_sizet - tl) luaG_runerror(L, "string length overflow"); tl += l; } G(L)->buff.n = tl; @@ -329,6 +343,7 @@ void luaV_concat (lua_State *L, int total, int last) { } setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); luaZ_resetbuffer(&G(L)->buff); + unfixedstack(L); } total -= n-1; /* got `n' strings to create 1 new */ last -= n-1; diff --git a/src/lua/lzio.h b/src/lua/lzio.h index 51d695d8..d6073d7f 100644 --- a/src/lua/lzio.h +++ b/src/lua/lzio.h @@ -27,7 +27,7 @@ typedef struct Mbuffer { size_t buffsize; } Mbuffer; -#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->n = 0, (buff)->buffsize = 0) #define luaZ_buffer(buff) ((buff)->buffer) #define luaZ_sizebuffer(buff) ((buff)->buffsize)