summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lgc.c4
-rw-r--r--ltable.c46
-rw-r--r--ltable.h12
-rw-r--r--ltests.c6
4 files changed, 38 insertions, 30 deletions
diff --git a/lgc.c b/lgc.c
index 7da00442..55a51870 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.212 2016/03/31 19:02:03 roberto Exp roberto $ 2** $Id: lgc.c,v 2.213 2016/10/19 12:31: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*/
@@ -467,7 +467,7 @@ static lu_mem traversetable (global_State *g, Table *h) {
467 else /* not weak */ 467 else /* not weak */
468 traversestrongtable(g, h); 468 traversestrongtable(g, h);
469 return sizeof(Table) + sizeof(TValue) * h->sizearray + 469 return sizeof(Table) + sizeof(TValue) * h->sizearray +
470 sizeof(Node) * cast(size_t, sizenode(h)); 470 sizeof(Node) * cast(size_t, allocsizenode(h));
471} 471}
472 472
473 473
diff --git a/ltable.c b/ltable.c
index 03318a5d..92c165ad 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.116 2015/11/03 18:35:21 roberto Exp roberto $ 2** $Id: ltable.c,v 2.117 2015/11/19 19:16:22 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*/
@@ -74,8 +74,6 @@
74 74
75#define dummynode (&dummynode_) 75#define dummynode (&dummynode_)
76 76
77#define isdummy(n) ((n) == dummynode)
78
79static const Node dummynode_ = { 77static const Node dummynode_ = {
80 {NILCONSTANT}, /* value */ 78 {NILCONSTANT}, /* value */
81 {{NILCONSTANT, 0}} /* key */ 79 {{NILCONSTANT, 0}} /* key */
@@ -308,14 +306,14 @@ static void setarrayvector (lua_State *L, Table *t, unsigned int size) {
308 306
309 307
310static void setnodevector (lua_State *L, Table *t, unsigned int size) { 308static void setnodevector (lua_State *L, Table *t, unsigned int size) {
311 int lsize;
312 if (size == 0) { /* no elements to hash part? */ 309 if (size == 0) { /* no elements to hash part? */
313 t->node = cast(Node *, dummynode); /* use common 'dummynode' */ 310 t->node = cast(Node *, dummynode); /* use common 'dummynode' */
314 lsize = 0; 311 t->lsizenode = 0;
312 t->lastfree = NULL; /* signal that it is using dummy node */
315 } 313 }
316 else { 314 else {
317 int i; 315 int i;
318 lsize = luaO_ceillog2(size); 316 int lsize = luaO_ceillog2(size);
319 if (lsize > MAXHBITS) 317 if (lsize > MAXHBITS)
320 luaG_runerror(L, "table overflow"); 318 luaG_runerror(L, "table overflow");
321 size = twoto(lsize); 319 size = twoto(lsize);
@@ -326,9 +324,9 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
326 setnilvalue(wgkey(n)); 324 setnilvalue(wgkey(n));
327 setnilvalue(gval(n)); 325 setnilvalue(gval(n));
328 } 326 }
327 t->lsizenode = cast_byte(lsize);
328 t->lastfree = gnode(t, size); /* all positions are free */
329 } 329 }
330 t->lsizenode = cast_byte(lsize);
331 t->lastfree = gnode(t, size); /* all positions are free */
332} 330}
333 331
334 332
@@ -337,7 +335,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
337 unsigned int i; 335 unsigned int i;
338 int j; 336 int j;
339 unsigned int oldasize = t->sizearray; 337 unsigned int oldasize = t->sizearray;
340 int oldhsize = t->lsizenode; 338 int oldhsize = allocsizenode(t);
341 Node *nold = t->node; /* save old hash ... */ 339 Node *nold = t->node; /* save old hash ... */
342 if (nasize > oldasize) /* array part must grow? */ 340 if (nasize > oldasize) /* array part must grow? */
343 setarrayvector(L, t, nasize); 341 setarrayvector(L, t, nasize);
@@ -354,7 +352,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
354 luaM_reallocvector(L, t->array, oldasize, nasize, TValue); 352 luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
355 } 353 }
356 /* re-insert elements from hash part */ 354 /* re-insert elements from hash part */
357 for (j = twoto(oldhsize) - 1; j >= 0; j--) { 355 for (j = oldhsize - 1; j >= 0; j--) {
358 Node *old = nold + j; 356 Node *old = nold + j;
359 if (!ttisnil(gval(old))) { 357 if (!ttisnil(gval(old))) {
360 /* doesn't need barrier/invalidate cache, as entry was 358 /* doesn't need barrier/invalidate cache, as entry was
@@ -362,13 +360,13 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
362 setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); 360 setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
363 } 361 }
364 } 362 }
365 if (!isdummy(nold)) 363 if (oldhsize > 0) /* not the dummy node? */
366 luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old hash */ 364 luaM_freearray(L, nold, cast(size_t, oldhsize)); /* free old hash */
367} 365}
368 366
369 367
370void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { 368void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) {
371 int nsize = isdummy(t->node) ? 0 : sizenode(t); 369 int nsize = allocsizenode(t);
372 luaH_resize(L, t, nasize, nsize); 370 luaH_resize(L, t, nasize, nsize);
373} 371}
374 372
@@ -414,7 +412,7 @@ Table *luaH_new (lua_State *L) {
414 412
415 413
416void luaH_free (lua_State *L, Table *t) { 414void luaH_free (lua_State *L, Table *t) {
417 if (!isdummy(t->node)) 415 if (!isdummy(t))
418 luaM_freearray(L, t->node, cast(size_t, sizenode(t))); 416 luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
419 luaM_freearray(L, t->array, t->sizearray); 417 luaM_freearray(L, t->array, t->sizearray);
420 luaM_free(L, t); 418 luaM_free(L, t);
@@ -422,10 +420,12 @@ void luaH_free (lua_State *L, Table *t) {
422 420
423 421
424static Node *getfreepos (Table *t) { 422static Node *getfreepos (Table *t) {
425 while (t->lastfree > t->node) { 423 if (!isdummy(t)) {
426 t->lastfree--; 424 while (t->lastfree > t->node) {
427 if (ttisnil(gkey(t->lastfree))) 425 t->lastfree--;
428 return t->lastfree; 426 if (ttisnil(gkey(t->lastfree)))
427 return t->lastfree;
428 }
429 } 429 }
430 return NULL; /* could not find a free place */ 430 return NULL; /* could not find a free place */
431} 431}
@@ -445,7 +445,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
445 if (ttisnil(key)) luaG_runerror(L, "table index is nil"); 445 if (ttisnil(key)) luaG_runerror(L, "table index is nil");
446 else if (ttisfloat(key)) { 446 else if (ttisfloat(key)) {
447 lua_Integer k; 447 lua_Integer k;
448 if (luaV_tointeger(key, &k, 0)) { /* index is int? */ 448 if (luaV_tointeger(key, &k, 0)) { /* does index fit in an integer? */
449 setivalue(&aux, k); 449 setivalue(&aux, k);
450 key = &aux; /* insert it as an integer */ 450 key = &aux; /* insert it as an integer */
451 } 451 }
@@ -453,7 +453,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
453 luaG_runerror(L, "table index is NaN"); 453 luaG_runerror(L, "table index is NaN");
454 } 454 }
455 mp = mainposition(t, key); 455 mp = mainposition(t, key);
456 if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ 456 if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */
457 Node *othern; 457 Node *othern;
458 Node *f = getfreepos(t); /* get a free place */ 458 Node *f = getfreepos(t); /* get a free place */
459 if (f == NULL) { /* cannot find a free place? */ 459 if (f == NULL) { /* cannot find a free place? */
@@ -461,7 +461,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
461 /* whatever called 'newkey' takes care of TM cache */ 461 /* whatever called 'newkey' takes care of TM cache */
462 return luaH_set(L, t, key); /* insert key into grown table */ 462 return luaH_set(L, t, key); /* insert key into grown table */
463 } 463 }
464 lua_assert(!isdummy(f)); 464 lua_assert(!isdummy(t));
465 othern = mainposition(t, gkey(mp)); 465 othern = mainposition(t, gkey(mp));
466 if (othern != mp) { /* is colliding node out of its main position? */ 466 if (othern != mp) { /* is colliding node out of its main position? */
467 /* yes; move colliding node into free position */ 467 /* yes; move colliding node into free position */
@@ -651,7 +651,7 @@ int luaH_getn (Table *t) {
651 return i; 651 return i;
652 } 652 }
653 /* else must find a boundary in hash part */ 653 /* else must find a boundary in hash part */
654 else if (isdummy(t->node)) /* hash part is empty? */ 654 else if (isdummy(t)) /* hash part is empty? */
655 return j; /* that is easy... */ 655 return j; /* that is easy... */
656 else return unbound_search(t, j); 656 else return unbound_search(t, j);
657} 657}
@@ -664,6 +664,6 @@ Node *luaH_mainposition (const Table *t, const TValue *key) {
664 return mainposition(t, key); 664 return mainposition(t, key);
665} 665}
666 666
667int luaH_isdummy (Node *n) { return isdummy(n); } 667int luaH_isdummy (const Table *t) { return isdummy(t); }
668 668
669#endif 669#endif
diff --git a/ltable.h b/ltable.h
index bad66516..8b80a6df 100644
--- a/ltable.h
+++ b/ltable.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.h,v 2.20 2014/09/04 18:15:29 roberto Exp roberto $ 2** $Id: ltable.h,v 2.21 2015/11/03 15:47:30 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*/
@@ -27,6 +27,14 @@
27#define invalidateTMcache(t) ((t)->flags = 0) 27#define invalidateTMcache(t) ((t)->flags = 0)
28 28
29 29
30/* true when 't' is using 'dummynode' as its hash part */
31#define isdummy(t) ((t)->lastfree == NULL)
32
33
34/* allocated size for hash nodes */
35#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
36
37
30/* returns the key, given the value of a table entry */ 38/* returns the key, given the value of a table entry */
31#define keyfromval(v) \ 39#define keyfromval(v) \
32 (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) 40 (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
@@ -51,7 +59,7 @@ LUAI_FUNC int luaH_getn (Table *t);
51 59
52#if defined(LUA_DEBUG) 60#if defined(LUA_DEBUG)
53LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); 61LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key);
54LUAI_FUNC int luaH_isdummy (Node *n); 62LUAI_FUNC int luaH_isdummy (const Table *t);
55#endif 63#endif
56 64
57 65
diff --git a/ltests.c b/ltests.c
index 98fdf223..e796fac3 100644
--- a/ltests.c
+++ b/ltests.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltests.c,v 2.208 2015/09/08 16:55:43 roberto Exp roberto $ 2** $Id: ltests.c,v 2.209 2015/10/12 16:38:19 roberto Exp roberto $
3** Internal Module for Debugging of the Lua Implementation 3** Internal Module for Debugging of the Lua Implementation
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -687,8 +687,8 @@ static int table_query (lua_State *L) {
687 t = hvalue(obj_at(L, 1)); 687 t = hvalue(obj_at(L, 1));
688 if (i == -1) { 688 if (i == -1) {
689 lua_pushinteger(L, t->sizearray); 689 lua_pushinteger(L, t->sizearray);
690 lua_pushinteger(L, luaH_isdummy(t->node) ? 0 : sizenode(t)); 690 lua_pushinteger(L, allocsizenode(t));
691 lua_pushinteger(L, t->lastfree - t->node); 691 lua_pushinteger(L, isdummy(t) ? 0 : t->lastfree - t->node);
692 } 692 }
693 else if ((unsigned int)i < t->sizearray) { 693 else if ((unsigned int)i < t->sizearray) {
694 lua_pushinteger(L, i); 694 lua_pushinteger(L, i);