New way to keep hints for table length

Instead of using 'alimit' for keeping the size of the array and at
the same time being a hint for '#t', a table now keeps these two
values separate. The Table structure has a field 'asize' with the
size of the array, while the length hint is kept in the array itself.
That way, tables with no array part waste no space with that field.
Moreover, the space for the hint may have zero cost for small arrays,
if the array of tags plus the hint still fits in a single word.
This commit is contained in:
Roberto Ierusalimschy
2024-11-29 17:26:20 -03:00
parent 9329eeac3b
commit 002beeebe7
7 changed files with 146 additions and 249 deletions

View File

@@ -359,7 +359,7 @@ static void checkvalref (global_State *g, GCObject *f, const TValue *t) {
static void checktable (global_State *g, Table *h) {
unsigned int i;
unsigned int asize = luaH_realasize(h);
unsigned int asize = h->asize;
Node *n, *limit = gnode(h, sizenode(h));
GCObject *hgc = obj2gco(h);
checkobjrefN(g, hgc, h->metatable);
@@ -1034,11 +1034,11 @@ static int table_query (lua_State *L) {
unsigned int asize;
luaL_checktype(L, 1, LUA_TTABLE);
t = hvalue(obj_at(L, 1));
asize = luaH_realasize(t);
asize = t->asize;
if (i == -1) {
lua_pushinteger(L, cast(lua_Integer, asize));
lua_pushinteger(L, cast(lua_Integer, allocsizenode(t)));
lua_pushinteger(L, cast(lua_Integer, t->alimit));
lua_pushinteger(L, cast(lua_Integer, asize > 0 ? *lenhint(t) : 0));
return 3;
}
else if (cast_uint(i) < asize) {