eris: weak tables fixed (garbage collector updates sequence data)
This commit is contained in:
@@ -628,7 +628,7 @@ static void clearkeys (global_State *g, GCObject *l, GCObject *f) {
|
|||||||
Node *n, *limit = gnodelast(h);
|
Node *n, *limit = gnodelast(h);
|
||||||
for (n = gnode(h, 0); n < limit; n++) {
|
for (n = gnode(h, 0); n < limit; n++) {
|
||||||
if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
|
if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) {
|
||||||
setnilvalue(gval(n)); /* remove value ... */
|
luaH_setnil(h, ganode(n));
|
||||||
removeentry(n); /* and remove entry from table */
|
removeentry(n); /* and remove entry from table */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -646,13 +646,14 @@ static void clearvalues (global_State *g, GCObject *l, GCObject *f) {
|
|||||||
Node *n, *limit = gnodelast(h);
|
Node *n, *limit = gnodelast(h);
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < h->sizearray; i++) {
|
for (i = 0; i < h->sizearray; i++) {
|
||||||
|
ANode *anode = h->array + i;
|
||||||
TValue *o = &h->array[i].i_val;
|
TValue *o = &h->array[i].i_val;
|
||||||
if (iscleared(g, o)) /* value was collected? */
|
if (iscleared(g, &anode->i_val)) /* value was collected? */
|
||||||
setnilvalue(o); /* remove value */
|
luaH_setnil(h, anode);
|
||||||
}
|
}
|
||||||
for (n = gnode(h, 0); n < limit; n++) {
|
for (n = gnode(h, 0); n < limit; n++) {
|
||||||
if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
|
if (!ttisnil(gval(n)) && iscleared(g, gval(n))) {
|
||||||
setnilvalue(gval(n)); /* remove value ... */
|
luaH_setnil(h, ganode(n)); /* remove value ... */
|
||||||
removeentry(n); /* and remove entry from table */
|
removeentry(n); /* and remove entry from table */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -656,7 +656,10 @@ const TValue *luaH_get (Table *t, const TValue *key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addsequence(Table *t, ANode *anode) {
|
/* Change an entry to non-nil. */
|
||||||
|
/* This means the entry must be added to the sequence */
|
||||||
|
void luaH_setnonnil(Table *t, ANode *anode, const TValue *value) {
|
||||||
|
assert(ttisnil(&anode->i_val));
|
||||||
assert(anode->i_sequence == -1);
|
assert(anode->i_sequence == -1);
|
||||||
int index = anodeindex(t, anode);
|
int index = anodeindex(t, anode);
|
||||||
int totalanodes = t->sizearray + truesizenode(t);
|
int totalanodes = t->sizearray + truesizenode(t);
|
||||||
@@ -664,9 +667,15 @@ static void addsequence(Table *t, ANode *anode) {
|
|||||||
anode->i_sequence = t->nnkeys++;
|
anode->i_sequence = t->nnkeys++;
|
||||||
assert((anode->i_sequence >= 0) && (anode->i_sequence < totalanodes));
|
assert((anode->i_sequence >= 0) && (anode->i_sequence < totalanodes));
|
||||||
t->sequence[anode->i_sequence] = index;
|
t->sequence[anode->i_sequence] = index;
|
||||||
|
t->lastdeleted = NULL;
|
||||||
|
t->lastdelseq = -1;
|
||||||
|
setobj2t(L, &anode->i_val, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void delsequence(Table *t, ANode *anode) {
|
/* Change an entry to nil. */
|
||||||
|
/* This means the entry must be removed from the sequence */
|
||||||
|
void luaH_setnil(Table *t, ANode *anode) {
|
||||||
|
assert(!ttisnil(&anode->i_val));
|
||||||
assert((anode->i_sequence >= 0) && (anode->i_sequence < t->nnkeys));
|
assert((anode->i_sequence >= 0) && (anode->i_sequence < t->nnkeys));
|
||||||
/* remove the last item from the sequence, and get a pointer to its anode */
|
/* remove the last item from the sequence, and get a pointer to its anode */
|
||||||
int totalanodes = t->sizearray + truesizenode(t);
|
int totalanodes = t->sizearray + truesizenode(t);
|
||||||
@@ -679,11 +688,9 @@ static void delsequence(Table *t, ANode *anode) {
|
|||||||
t->sequence[freeslot] = lastanodeindex;
|
t->sequence[freeslot] = lastanodeindex;
|
||||||
t->nnkeys -= 1;
|
t->nnkeys -= 1;
|
||||||
lastanode->i_sequence = freeslot;
|
lastanode->i_sequence = freeslot;
|
||||||
/* set the last deleted variables */
|
|
||||||
t->lastdeleted = anode;
|
|
||||||
t->lastdelseq = anode->i_sequence;
|
|
||||||
/* clear out the anode */
|
/* clear out the anode */
|
||||||
anode->i_sequence = -1;
|
anode->i_sequence = -1;
|
||||||
|
setnilvalue(&anode->i_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -691,14 +698,13 @@ static void delsequence(Table *t, ANode *anode) {
|
|||||||
** barrier and invalidate the TM cache.
|
** barrier and invalidate the TM cache.
|
||||||
*/
|
*/
|
||||||
void luaH_setupdate (lua_State *L, Table *t, const TValue *key, TValue *value, const TValue *getres) {
|
void luaH_setupdate (lua_State *L, Table *t, const TValue *key, TValue *value, const TValue *getres) {
|
||||||
t->lastdeleted = NULL;
|
|
||||||
t->lastdelseq = -1;
|
|
||||||
if (!ttisnil(getres)) {
|
if (!ttisnil(getres)) {
|
||||||
if (ttisnil(value)) {
|
if (ttisnil(value)) {
|
||||||
/* replacing a non-nil value with nil */
|
/* replacing a non-nil value with nil */
|
||||||
TValue *cell = cast(TValue *, getres);
|
ANode *anode = cast(ANode *, getres);
|
||||||
delsequence(t, cast(ANode *, cell));
|
t->lastdeleted = anode;
|
||||||
setobj2t(L, cell, value);
|
t->lastdelseq = anode->i_sequence;
|
||||||
|
luaH_setnil(t, anode);
|
||||||
checksequence(t);
|
checksequence(t);
|
||||||
} else {
|
} else {
|
||||||
/* replacing a non-nil value with a different non-nil value */
|
/* replacing a non-nil value with a different non-nil value */
|
||||||
@@ -709,16 +715,17 @@ void luaH_setupdate (lua_State *L, Table *t, const TValue *key, TValue *value, c
|
|||||||
} else if (getres == luaO_nilobject) {
|
} else if (getres == luaO_nilobject) {
|
||||||
if (!ttisnil(value)) {
|
if (!ttisnil(value)) {
|
||||||
/* creating a new key with a non-nil value */
|
/* creating a new key with a non-nil value */
|
||||||
TValue *cell = luaH_newkey(L, t, key);
|
t->lastdeleted = NULL;
|
||||||
addsequence(t, cast(ANode *, cell));
|
t->lastdelseq = -1;
|
||||||
setobj2t(L, cell, value);
|
ANode *anode = cast(ANode *, luaH_newkey(L, t, key));
|
||||||
|
luaH_setnonnil(t, anode, value);
|
||||||
checksequence(t);
|
checksequence(t);
|
||||||
}
|
}
|
||||||
} else if (!ttisnil(value)) {
|
} else if (!ttisnil(value)) {
|
||||||
/* replacing a nil value with a non-nil value */
|
/* replacing a nil value with a non-nil value */
|
||||||
TValue *cell = cast(TValue *, getres);
|
t->lastdeleted = NULL;
|
||||||
addsequence(t, cast(ANode *, cell));
|
t->lastdelseq = -1;
|
||||||
setobj2t(L, cell, value);
|
luaH_setnonnil(t, cast(ANode *, getres), value);
|
||||||
checksequence(t);
|
checksequence(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
|
|
||||||
|
|
||||||
LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
|
LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
|
||||||
|
LUAI_FUNC void luaH_setnil (Table *t, ANode *anode);
|
||||||
|
LUAI_FUNC void luaH_setnonnil (Table *t, ANode *anode, const TValue *value);
|
||||||
LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
|
LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
|
||||||
LUAI_FUNC void luaH_setvalue (lua_State *L, Table *t, const TValue *key, TValue *value);
|
LUAI_FUNC void luaH_setvalue (lua_State *L, Table *t, const TValue *key, TValue *value);
|
||||||
LUAI_FUNC void luaH_setupdate (lua_State *L, Table *t, const TValue *key, TValue *value, const TValue *getres);
|
LUAI_FUNC void luaH_setupdate (lua_State *L, Table *t, const TValue *key, TValue *value, const TValue *getres);
|
||||||
|
|||||||
Reference in New Issue
Block a user