diff options
-rw-r--r-- | lapi.c | 31 | ||||
-rw-r--r-- | lcode.c | 6 | ||||
-rw-r--r-- | lfunc.c | 5 | ||||
-rw-r--r-- | lgc.c | 75 | ||||
-rw-r--r-- | lgc.h | 25 | ||||
-rw-r--r-- | lparser.c | 11 | ||||
-rw-r--r-- | lstring.c | 7 | ||||
-rw-r--r-- | ltable.c | 5 | ||||
-rw-r--r-- | lvm.c | 17 |
9 files changed, 118 insertions, 64 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 1.249 2003/10/20 17:42:41 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 1.250 2003/12/01 18:22:56 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -193,7 +193,7 @@ LUA_API void lua_replace (lua_State *L, int idx) { | |||
193 | api_checknelems(L, 1); | 193 | api_checknelems(L, 1); |
194 | o = luaA_index(L, idx); | 194 | o = luaA_index(L, idx); |
195 | api_checkvalidindex(L, o); | 195 | api_checkvalidindex(L, o); |
196 | setobj(o, L->top - 1); /* write barrier */ | 196 | setobj(o, L->top - 1); /* write barrier???? */ |
197 | L->top--; | 197 | L->top--; |
198 | lua_unlock(L); | 198 | lua_unlock(L); |
199 | } | 199 | } |
@@ -615,7 +615,8 @@ LUA_API void lua_rawset (lua_State *L, int idx) { | |||
615 | api_checknelems(L, 2); | 615 | api_checknelems(L, 2); |
616 | t = luaA_index(L, idx); | 616 | t = luaA_index(L, idx); |
617 | api_check(L, ttistable(t)); | 617 | api_check(L, ttistable(t)); |
618 | setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); /* write barrier */ | 618 | setobj2t(luaH_set(L, hvalue(t), L->top-2), L->top-1); |
619 | luaC_barrier(L, hvalue(t), L->top-1); | ||
619 | L->top -= 2; | 620 | L->top -= 2; |
620 | lua_unlock(L); | 621 | lua_unlock(L); |
621 | } | 622 | } |
@@ -627,7 +628,8 @@ LUA_API void lua_rawseti (lua_State *L, int idx, int n) { | |||
627 | api_checknelems(L, 1); | 628 | api_checknelems(L, 1); |
628 | o = luaA_index(L, idx); | 629 | o = luaA_index(L, idx); |
629 | api_check(L, ttistable(o)); | 630 | api_check(L, ttistable(o)); |
630 | setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); /* write barrier */ | 631 | setobj2t(luaH_setnum(L, hvalue(o), n), L->top-1); |
632 | luaC_barrier(L, hvalue(o), L->top-1); | ||
631 | L->top--; | 633 | L->top--; |
632 | lua_unlock(L); | 634 | lua_unlock(L); |
633 | } | 635 | } |
@@ -649,11 +651,15 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
649 | } | 651 | } |
650 | switch (ttype(obj)) { | 652 | switch (ttype(obj)) { |
651 | case LUA_TTABLE: { | 653 | case LUA_TTABLE: { |
652 | hvalue(obj)->metatable = mt; /* write barrier */ | 654 | hvalue(obj)->metatable = mt; |
655 | if (mt) | ||
656 | luaC_objbarrier(L, hvalue(obj), mt); | ||
653 | break; | 657 | break; |
654 | } | 658 | } |
655 | case LUA_TUSERDATA: { | 659 | case LUA_TUSERDATA: { |
656 | uvalue(obj)->uv.metatable = mt; /* write barrier */ | 660 | uvalue(obj)->uv.metatable = mt; |
661 | if (mt) | ||
662 | luaC_objbarrier(L, uvalue(obj), mt); | ||
657 | break; | 663 | break; |
658 | } | 664 | } |
659 | default: { | 665 | default: { |
@@ -907,10 +913,8 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | |||
907 | 913 | ||
908 | 914 | ||
909 | 915 | ||
910 | static const char *aux_upvalue (lua_State *L, int funcindex, int n, | 916 | static const char *aux_upvalue (lua_State *L, StkId fi, int n, TObject **val) { |
911 | TObject **val) { | ||
912 | Closure *f; | 917 | Closure *f; |
913 | StkId fi = luaA_index(L, funcindex); | ||
914 | if (!ttisfunction(fi)) return NULL; | 918 | if (!ttisfunction(fi)) return NULL; |
915 | f = clvalue(fi); | 919 | f = clvalue(fi); |
916 | if (f->c.isC) { | 920 | if (f->c.isC) { |
@@ -931,7 +935,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { | |||
931 | const char *name; | 935 | const char *name; |
932 | TObject *val; | 936 | TObject *val; |
933 | lua_lock(L); | 937 | lua_lock(L); |
934 | name = aux_upvalue(L, funcindex, n, &val); | 938 | name = aux_upvalue(L, luaA_index(L, funcindex), n, &val); |
935 | if (name) { | 939 | if (name) { |
936 | setobj2s(L->top, val); | 940 | setobj2s(L->top, val); |
937 | api_incr_top(L); | 941 | api_incr_top(L); |
@@ -944,12 +948,15 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { | |||
944 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | 948 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { |
945 | const char *name; | 949 | const char *name; |
946 | TObject *val; | 950 | TObject *val; |
951 | StkId fi; | ||
947 | lua_lock(L); | 952 | lua_lock(L); |
953 | fi = luaA_index(L, funcindex); | ||
948 | api_checknelems(L, 1); | 954 | api_checknelems(L, 1); |
949 | name = aux_upvalue(L, funcindex, n, &val); | 955 | name = aux_upvalue(L, fi, n, &val); |
950 | if (name) { | 956 | if (name) { |
951 | L->top--; | 957 | L->top--; |
952 | setobj(val, L->top); /* write barrier */ | 958 | setobj(val, L->top); |
959 | luaC_barrier(L, clvalue(fi), L->top); | ||
953 | } | 960 | } |
954 | lua_unlock(L); | 961 | lua_unlock(L); |
955 | return name; | 962 | return name; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lcode.c,v 1.119 2003/08/27 21:01:44 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 1.120 2003/11/19 19:59:18 roberto Exp roberto $ |
3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -14,6 +14,7 @@ | |||
14 | #include "lcode.h" | 14 | #include "lcode.h" |
15 | #include "ldebug.h" | 15 | #include "ldebug.h" |
16 | #include "ldo.h" | 16 | #include "ldo.h" |
17 | #include "lgc.h" | ||
17 | #include "llex.h" | 18 | #include "llex.h" |
18 | #include "lmem.h" | 19 | #include "lmem.h" |
19 | #include "lobject.h" | 20 | #include "lobject.h" |
@@ -219,7 +220,8 @@ static int addk (FuncState *fs, TObject *k, TObject *v) { | |||
219 | luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, | 220 | luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, |
220 | MAXARG_Bx, "constant table overflow"); | 221 | MAXARG_Bx, "constant table overflow"); |
221 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); | 222 | while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); |
222 | setobj(&f->k[fs->nk], v); /* write barrier */ | 223 | setobj(&f->k[fs->nk], v); |
224 | luaC_barrier(fs->L, f, v); | ||
223 | return fs->nk++; | 225 | return fs->nk++; |
224 | } | 226 | } |
225 | } | 227 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 1.72 2003/11/24 18:50:36 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 1.73 2003/12/03 20:03:07 roberto Exp roberto $ |
3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -68,7 +68,8 @@ UpVal *luaF_findupval (lua_State *L, StkId level) { | |||
68 | void luaF_close (lua_State *L, StkId level) { | 68 | void luaF_close (lua_State *L, StkId level) { |
69 | UpVal *uv; | 69 | UpVal *uv; |
70 | while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) { | 70 | while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) { |
71 | setobj(&uv->value, uv->v); /* save current value (write barrier) */ | 71 | setobj(&uv->value, uv->v); |
72 | luaC_barrier(L, uv, uv->v); | ||
72 | uv->v = &uv->value; /* now current value lives here */ | 73 | uv->v = &uv->value; /* now current value lives here */ |
73 | L->openupval = uv->next; /* remove from `open' list */ | 74 | L->openupval = uv->next; /* remove from `open' list */ |
74 | luaC_link(L, valtogco(uv), LUA_TUPVAL); | 75 | luaC_link(L, valtogco(uv), LUA_TUPVAL); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 1.185 2003/12/04 17:22:42 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 1.186 2003/12/04 18:52:23 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 | */ |
@@ -25,12 +25,8 @@ | |||
25 | #define GCSTEPSIZE (20*sizeof(TObject)) | 25 | #define GCSTEPSIZE (20*sizeof(TObject)) |
26 | 26 | ||
27 | 27 | ||
28 | #define otherwhite(g) (g->currentwhite ^ bit2mask(WHITE0BIT, WHITE1BIT)) | ||
29 | |||
30 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | ||
31 | #define gray2black(x) setbit((x)->gch.marked, BLACKBIT) | 28 | #define gray2black(x) setbit((x)->gch.marked, BLACKBIT) |
32 | 29 | ||
33 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) | ||
34 | #define maskmarks \ | 30 | #define maskmarks \ |
35 | cast(lu_byte, ~(bitmask(BLACKBIT)|bit2mask(WHITE0BIT, WHITE1BIT))) | 31 | cast(lu_byte, ~(bitmask(BLACKBIT)|bit2mask(WHITE0BIT, WHITE1BIT))) |
36 | #define makewhite(g,x) \ | 32 | #define makewhite(g,x) \ |
@@ -47,7 +43,6 @@ | |||
47 | #define markfinalized(u) setbit((u)->uv.marked, FINALIZEDBIT) | 43 | #define markfinalized(u) setbit((u)->uv.marked, FINALIZEDBIT) |
48 | 44 | ||
49 | 45 | ||
50 | |||
51 | #define KEYWEAK bitmask(KEYWEAKBIT) | 46 | #define KEYWEAK bitmask(KEYWEAKBIT) |
52 | #define VALUEWEAK bitmask(VALUEWEAKBIT) | 47 | #define VALUEWEAK bitmask(VALUEWEAKBIT) |
53 | 48 | ||
@@ -110,7 +105,7 @@ static size_t objsize (GCObject *o) { | |||
110 | 105 | ||
111 | static void reallymarkobject (global_State *g, GCObject *o) { | 106 | static void reallymarkobject (global_State *g, GCObject *o) { |
112 | lua_assert(iswhite(o)); | 107 | lua_assert(iswhite(o)); |
113 | lua_assert(!(o->gch.marked & otherwhite(g))); | 108 | lua_assert(!isdead(g, o)); |
114 | white2gray(o); | 109 | white2gray(o); |
115 | switch (o->gch.tt) { | 110 | switch (o->gch.tt) { |
116 | case LUA_TSTRING: { | 111 | case LUA_TSTRING: { |
@@ -118,6 +113,7 @@ static void reallymarkobject (global_State *g, GCObject *o) { | |||
118 | } | 113 | } |
119 | case LUA_TUSERDATA: { | 114 | case LUA_TUSERDATA: { |
120 | Table *mt = gcotou(o)->uv.metatable; | 115 | Table *mt = gcotou(o)->uv.metatable; |
116 | gray2black(o); /* udata are never gray */ | ||
121 | if (mt) markobject(g, mt); | 117 | if (mt) markobject(g, mt); |
122 | return; | 118 | return; |
123 | } | 119 | } |
@@ -442,7 +438,6 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, int all, | |||
442 | int dead = otherwhite(g); | 438 | int dead = otherwhite(g); |
443 | while ((curr = *p) != NULL) { | 439 | while ((curr = *p) != NULL) { |
444 | int mark = curr->gch.marked; | 440 | int mark = curr->gch.marked; |
445 | lua_assert(all || !(mark & g->currentwhite)); | ||
446 | lim -= objsize(curr); | 441 | lim -= objsize(curr); |
447 | if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { | 442 | if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { |
448 | makewhite(g, curr); | 443 | makewhite(g, curr); |
@@ -469,9 +464,9 @@ static l_mem sweepstrings (lua_State *L, int all, l_mem lim) { | |||
469 | while ((curr = *p) != NULL) { | 464 | while ((curr = *p) != NULL) { |
470 | int mark = curr->gch.marked; | 465 | int mark = curr->gch.marked; |
471 | lu_mem size = sizestring(gcotots(curr)->tsv.len); | 466 | lu_mem size = sizestring(gcotots(curr)->tsv.len); |
472 | lua_assert(all || !(mark & g->currentwhite)); | ||
473 | if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { | 467 | if (!all && (!(mark & dead) || testbit(mark, FIXEDBIT))) { |
474 | makewhite(g, curr); | 468 | makewhite(g, curr); |
469 | lua_assert(iswhite(curr) && !isdead(g, curr)); | ||
475 | p = &curr->gch.next; | 470 | p = &curr->gch.next; |
476 | } | 471 | } |
477 | else { | 472 | else { |
@@ -499,8 +494,6 @@ static void checkSizes (lua_State *L) { | |||
499 | size_t newsize = luaZ_sizebuffer(&g->buff) / 2; | 494 | size_t newsize = luaZ_sizebuffer(&g->buff) / 2; |
500 | luaZ_resizebuffer(L, &g->buff, newsize); | 495 | luaZ_resizebuffer(L, &g->buff, newsize); |
501 | } | 496 | } |
502 | lua_assert(g->nblocks > g->GCthreshold); | ||
503 | g->GCthreshold = 2*G(L)->nblocks - g->GCthreshold; /* new threshold */ | ||
504 | } | 497 | } |
505 | 498 | ||
506 | 499 | ||
@@ -562,11 +555,13 @@ static void markroot (lua_State *L) { | |||
562 | 555 | ||
563 | static void atomic (lua_State *L) { | 556 | static void atomic (lua_State *L) { |
564 | global_State *g = G(L); | 557 | global_State *g = G(L); |
558 | /* there may be some gray elements due to the write barrier */ | ||
559 | propagatemarks(g, MAXLMEM); /* traverse them */ | ||
565 | lua_assert(g->gray == NULL); | 560 | lua_assert(g->gray == NULL); |
566 | g->gray = g->grayagain; | 561 | g->gray = g->grayagain; |
567 | g->grayagain = NULL; | 562 | g->grayagain = NULL; |
568 | propagatemarks(g, MAXLMEM); | 563 | propagatemarks(g, MAXLMEM); |
569 | g->GCthreshold = luaC_separateudata(L); /* separate userdata to be preserved */ | 564 | luaC_separateudata(L); /* separate userdata to be preserved */ |
570 | marktmu(g); /* mark `preserved' userdata */ | 565 | marktmu(g); /* mark `preserved' userdata */ |
571 | propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ | 566 | propagatemarks(g, MAXLMEM); /* remark, to propagate `preserveness' */ |
572 | cleartable(g->weak); /* remove collected objects from weak tables */ | 567 | cleartable(g->weak); /* remove collected objects from weak tables */ |
@@ -597,30 +592,48 @@ static void sweepstep (lua_State *L) { | |||
597 | global_State *g = G(L); | 592 | global_State *g = G(L); |
598 | l_mem lim = GCSTEPSIZE; | 593 | l_mem lim = GCSTEPSIZE; |
599 | g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim); | 594 | g->sweepgc = sweeplist(L, g->sweepgc, 0, &lim); |
600 | if (lim == GCSTEPSIZE) /* nothing more to sweep? */ | 595 | if (lim == GCSTEPSIZE) { /* nothing more to sweep? */ |
601 | g->gcstate = GCSfinalize; /* end sweep phase */ | 596 | g->gcstate = GCSfinalize; /* end sweep phase */ |
597 | checkSizes(L); | ||
598 | } | ||
602 | } | 599 | } |
603 | 600 | ||
604 | 601 | ||
605 | void luaC_collectgarbage (lua_State *L) { | 602 | void luaC_step (lua_State *L) { |
606 | global_State *g = G(L); | 603 | global_State *g = G(L); |
607 | /* GCSroot */ | 604 | switch (g->gcstate) { |
608 | markroot(L); | 605 | case GCSroot: |
609 | /* GCSpropagate */ | 606 | markroot(L); |
610 | while (g->gcstate == GCSpropagate) | 607 | break; |
611 | propagatemarks(g, GCSTEPSIZE); | 608 | case GCSpropagate: |
612 | /* atomic */ | 609 | propagatemarks(g, GCSTEPSIZE); |
613 | atomic(L); | 610 | break; |
614 | /* GCSsweepstring */ | 611 | case GCSatomic: |
615 | while (g->gcstate == GCSsweepstring) | 612 | atomic(L); |
616 | sweepstringstep(L); | 613 | break; |
617 | /* GCSsweep */ | 614 | case GCSsweepstring: |
618 | while (g->gcstate == GCSsweep) | 615 | sweepstringstep(L); |
619 | sweepstep(L); | 616 | break; |
620 | /* GCSfinalize */ | 617 | case GCSsweep: |
621 | checkSizes(L); | 618 | sweepstep(L); |
622 | while (g->gcstate == GCSfinalize) | 619 | break; |
623 | GCTM(L); | 620 | case GCSfinalize: |
621 | GCTM(L); | ||
622 | break; | ||
623 | default: lua_assert(0); | ||
624 | } | ||
625 | g->GCthreshold = g->nblocks + GCSTEPSIZE; | ||
626 | } | ||
627 | |||
628 | |||
629 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v) { | ||
630 | global_State *g = G(L); | ||
631 | lua_assert(isblack(o) && iswhite(v)); | ||
632 | lua_assert(!isdead(g, v) && !isdead(g, o)); | ||
633 | if (g->gcstate > GCSatomic) /* sweeping phases? */ | ||
634 | black2gray(o); /* just mark as gray to avoid other barriers */ | ||
635 | else /* breaking invariant! */ | ||
636 | reallymarkobject(g, v); /* restore it */ | ||
624 | } | 637 | } |
625 | 638 | ||
626 | 639 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 1.26 2003/12/03 20:03:07 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 1.27 2003/12/04 17:22:42 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 | */ |
@@ -58,18 +58,37 @@ | |||
58 | #define FIXEDBIT 5 | 58 | #define FIXEDBIT 5 |
59 | 59 | ||
60 | 60 | ||
61 | #define iswhite(x) test2bits((x)->gch.marked, WHITE0BIT, WHITE1BIT) | ||
62 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | ||
63 | |||
64 | |||
65 | #define otherwhite(g) (g->currentwhite ^ bit2mask(WHITE0BIT, WHITE1BIT)) | ||
66 | #define isdead(g,v) ((v)->gch.marked & otherwhite(g)) | ||
67 | |||
68 | #define changewhite(x) ((x)->gch.marked ^= bit2mask(WHITE0BIT, WHITE1BIT)) | ||
69 | |||
70 | #define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) | ||
71 | |||
61 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite) | 72 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite) |
62 | 73 | ||
63 | 74 | ||
64 | #define luaC_checkGC(L) { if (G(L)->nblocks >= G(L)->GCthreshold) \ | 75 | #define luaC_checkGC(L) { if (G(L)->nblocks >= G(L)->GCthreshold) \ |
65 | luaC_collectgarbage(L); } | 76 | luaC_step(L); } |
77 | |||
78 | |||
79 | #define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(valtogco(p))) \ | ||
80 | luaC_barrierf(L,valtogco(p),gcvalue(v)); } | ||
66 | 81 | ||
82 | #define luaC_objbarrier(L,p,o) \ | ||
83 | { if (iswhite(valtogco(o)) && isblack(valtogco(p))) \ | ||
84 | luaC_barrierf(L,valtogco(p),valtogco(o)); } | ||
67 | 85 | ||
68 | size_t luaC_separateudata (lua_State *L); | 86 | size_t luaC_separateudata (lua_State *L); |
69 | void luaC_callGCTM (lua_State *L); | 87 | void luaC_callGCTM (lua_State *L); |
70 | void luaC_sweepall (lua_State *L); | 88 | void luaC_sweepall (lua_State *L); |
71 | void luaC_collectgarbage (lua_State *L); | 89 | void luaC_step (lua_State *L); |
72 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt); | 90 | void luaC_link (lua_State *L, GCObject *o, lu_byte tt); |
91 | void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v); | ||
73 | 92 | ||
74 | 93 | ||
75 | #endif | 94 | #endif |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 1.220 2003/10/03 16:04:24 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 1.221 2003/10/09 17:56:23 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -151,7 +151,8 @@ static int luaI_registerlocalvar (LexState *ls, TString *varname) { | |||
151 | luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, | 151 | luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, |
152 | LocVar, USHRT_MAX, "too many local variables"); | 152 | LocVar, USHRT_MAX, "too many local variables"); |
153 | while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; | 153 | while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; |
154 | f->locvars[fs->nlocvars].varname = varname; /* write barrier */ | 154 | f->locvars[fs->nlocvars].varname = varname; |
155 | luaC_objbarrier(ls->L, f, varname); | ||
155 | return fs->nlocvars++; | 156 | return fs->nlocvars++; |
156 | } | 157 | } |
157 | 158 | ||
@@ -199,7 +200,8 @@ static int indexupvalue (FuncState *fs, TString *name, expdesc *v) { | |||
199 | luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, | 200 | luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues, |
200 | TString *, MAX_INT, ""); | 201 | TString *, MAX_INT, ""); |
201 | while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; | 202 | while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL; |
202 | f->upvalues[f->nups] = name; /* write barrier */ | 203 | f->upvalues[f->nups] = name; |
204 | luaC_objbarrier(fs->L, f, name); | ||
203 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); | 205 | lua_assert(v->k == VLOCAL || v->k == VUPVAL); |
204 | fs->upvalues[f->nups].k = cast(lu_byte, v->k); | 206 | fs->upvalues[f->nups].k = cast(lu_byte, v->k); |
205 | fs->upvalues[f->nups].info = cast(lu_byte, v->info); | 207 | fs->upvalues[f->nups].info = cast(lu_byte, v->info); |
@@ -307,7 +309,8 @@ static void pushclosure (LexState *ls, FuncState *func, expdesc *v) { | |||
307 | luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, | 309 | luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *, |
308 | MAXARG_Bx, "constant table overflow"); | 310 | MAXARG_Bx, "constant table overflow"); |
309 | while (oldsize < f->sizep) f->p[oldsize++] = NULL; | 311 | while (oldsize < f->sizep) f->p[oldsize++] = NULL; |
310 | f->p[fs->np++] = func->f; /* write barrier */ | 312 | f->p[fs->np++] = func->f; |
313 | luaC_objbarrier(ls->L, f, func->f); | ||
311 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); | 314 | init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1)); |
312 | for (i=0; i<func->f->nups; i++) { | 315 | for (i=0; i<func->f->nups; i++) { |
313 | OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; | 316 | OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.c,v 1.83 2003/12/03 20:03:07 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 1.84 2003/12/04 17:22:42 roberto Exp roberto $ |
3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -84,8 +84,11 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
84 | o != NULL; | 84 | o != NULL; |
85 | o = o->gch.next) { | 85 | o = o->gch.next) { |
86 | TString *ts = gcotots(o); | 86 | TString *ts = gcotots(o); |
87 | if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) | 87 | if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) { |
88 | /* string may be dead */ | ||
89 | if (isdead(G(L), o)) changewhite(o); | ||
88 | return ts; | 90 | return ts; |
91 | } | ||
89 | } | 92 | } |
90 | return newlstr(L, str, l, h); /* not found */ | 93 | return newlstr(L, str, l, h); /* not found */ |
91 | } | 94 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltable.c,v 1.136 2003/11/27 18:05:14 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 1.137 2003/12/01 18:22:56 roberto Exp roberto $ |
3 | ** Lua tables (hash) | 3 | ** Lua tables (hash) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -398,7 +398,8 @@ static TObject *newkey (lua_State *L, Table *t, const TObject *key) { | |||
398 | mp = n; | 398 | mp = n; |
399 | } | 399 | } |
400 | } | 400 | } |
401 | setobj2t(gkey(mp), key); /* write barrier */ | 401 | setobj2t(gkey(mp), key); |
402 | luaC_barrier(L, t, key); | ||
402 | lua_assert(ttisnil(gval(mp))); | 403 | lua_assert(ttisnil(gval(mp))); |
403 | for (;;) { /* correct `firstfree' */ | 404 | for (;;) { /* correct `firstfree' */ |
404 | if (ttisnil(gkey(t->firstfree))) | 405 | if (ttisnil(gkey(t->firstfree))) |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 1.289 2003/07/16 20:49:02 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 1.290 2003/10/27 19:14:31 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -151,7 +151,8 @@ void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) { | |||
151 | TObject *oldval = luaH_set(L, h, key); /* do a primitive set */ | 151 | TObject *oldval = luaH_set(L, h, key); /* do a primitive set */ |
152 | if (!ttisnil(oldval) || /* result is no nil? */ | 152 | if (!ttisnil(oldval) || /* result is no nil? */ |
153 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ | 153 | (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */ |
154 | setobj2t(oldval, val); /* write barrier */ | 154 | setobj2t(oldval, val); |
155 | luaC_barrier(L, h, val); | ||
155 | return; | 156 | return; |
156 | } | 157 | } |
157 | /* else will try the tag method */ | 158 | /* else will try the tag method */ |
@@ -454,8 +455,9 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
454 | break; | 455 | break; |
455 | } | 456 | } |
456 | case OP_SETUPVAL: { | 457 | case OP_SETUPVAL: { |
457 | int b = GETARG_B(i); | 458 | UpVal *uv = cl->upvals[GETARG_B(i)]; |
458 | setobj(cl->upvals[b]->v, ra); /* write barrier */ | 459 | setobj(uv->v, ra); |
460 | luaC_barrier(L, uv, ra); | ||
459 | break; | 461 | break; |
460 | } | 462 | } |
461 | case OP_SETTABLE: { | 463 | case OP_SETTABLE: { |
@@ -713,8 +715,11 @@ StkId luaV_execute (lua_State *L, int nexeccalls) { | |||
713 | L->top = L->ci->top; | 715 | L->top = L->ci->top; |
714 | } | 716 | } |
715 | bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */ | 717 | bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */ |
716 | for (; n > 0; n--) | 718 | for (; n > 0; n--) { |
717 | setobj2t(luaH_setnum(L, h, bc+n), ra+n); /* write barrier */ | 719 | TObject *val = ra+n; |
720 | setobj2t(luaH_setnum(L, h, bc+n), val); | ||
721 | luaC_barrier(L, h, val); | ||
722 | } | ||
718 | break; | 723 | break; |
719 | } | 724 | } |
720 | case OP_CLOSE: { | 725 | case OP_CLOSE: { |