From 6063c47031afa2d62e6038fcf8f3c805785c7df3 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 7 Feb 2024 13:56:39 -0300 Subject: [PATCH] Field 'lastfree' changed (back) to 'Node *' Due to allignment, it is already using the space of a pointer, and a pointer generates slightly simpler code. --- ltable.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/ltable.c b/ltable.c index b86e2281..dc4621aa 100644 --- a/ltable.c +++ b/ltable.c @@ -40,24 +40,26 @@ /* -** Only tables with hash parts larget than LIMFORLAST has a 'lastfree' -** field that optimizes finding a free slot. Smaller tables do a +** Only tables with hash parts larger than 2^LIMFORLAST has a 'lastfree' +** field that optimizes finding a free slot. That field is stored just +** before the array of nodes, in the same block. Smaller tables do a ** complete search when looking for a free slot. */ -#define LLIMFORLAST 2 /* log2 of LIMTFORLAST */ -#define LIMFORLAST twoto(LLIMFORLAST) +#define LIMFORLAST 2 /* log2 of real limit */ /* -** Union to store an int field ensuring that what follows it in -** memory is properly aligned to store a TValue. +** The union 'Limbox' stores 'lastfree' and ensures that what follows it +** is properly aligned to store a Node. */ +typedef struct { Node *dummy; Node follows_pNode; } Limbox_aux; + typedef union { - int lastfree; - char padding[offsetof(struct { int i; TValue v; }, v)]; + Node *lastfree; + char padding[offsetof(Limbox_aux, follows_pNode)]; } Limbox; -#define haslastfree(t) ((t)->lsizenode > LLIMFORLAST) -#define getlastfree(t) (&((cast(Limbox *, (t)->node) - 1)->lastfree)) +#define haslastfree(t) ((t)->lsizenode > LIMFORLAST) +#define getlastfree(t) ((cast(Limbox *, (t)->node) - 1)->lastfree) /* @@ -593,13 +595,13 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) { if (lsize > MAXHBITS || (1u << lsize) > MAXHSIZE) luaG_runerror(L, "table overflow"); size = twoto(lsize); - if (lsize <= LLIMFORLAST) /* no 'lastfree' field? */ + if (lsize <= LIMFORLAST) /* no 'lastfree' field? */ t->node = luaM_newvector(L, size, Node); else { size_t bsize = size * sizeof(Node) + sizeof(Limbox); char *node = luaM_newblock(L, bsize); t->node = cast(Node *, node + sizeof(Limbox)); - *getlastfree(t) = size; /* all positions are free */ + getlastfree(t) = gnode(t, size); /* all positions are free */ } t->lsizenode = cast_byte(lsize); setnodummy(t); @@ -776,8 +778,8 @@ void luaH_free (lua_State *L, Table *t) { static Node *getfreepos (Table *t) { if (haslastfree(t)) { /* does it have 'lastfree' information? */ /* look for a spot before 'lastfree', updating 'lastfree' */ - while (*getlastfree(t) > 0) { - Node *free = gnode(t, --(*getlastfree(t))); + while (getlastfree(t) > t->node) { + Node *free = --getlastfree(t); if (keyisnil(free)) return free; }