diff options
-rw-r--r-- | lgc.c | 4 | ||||
-rw-r--r-- | ltable.c | 46 | ||||
-rw-r--r-- | ltable.h | 12 | ||||
-rw-r--r-- | ltests.c | 6 |
4 files changed, 38 insertions, 30 deletions
@@ -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 | ||
@@ -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 | |||
79 | static const Node dummynode_ = { | 77 | static 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 | ||
310 | static void setnodevector (lua_State *L, Table *t, unsigned int size) { | 308 | static 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 | ||
370 | void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { | 368 | void 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 | ||
416 | void luaH_free (lua_State *L, Table *t) { | 414 | void 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 | ||
424 | static Node *getfreepos (Table *t) { | 422 | static 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 | ||
667 | int luaH_isdummy (Node *n) { return isdummy(n); } | 667 | int luaH_isdummy (const Table *t) { return isdummy(t); } |
668 | 668 | ||
669 | #endif | 669 | #endif |
@@ -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) |
53 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); | 61 | LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); |
54 | LUAI_FUNC int luaH_isdummy (Node *n); | 62 | LUAI_FUNC int luaH_isdummy (const Table *t); |
55 | #endif | 63 | #endif |
56 | 64 | ||
57 | 65 | ||
@@ -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); |