aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-03-22 15:05:37 +0100
committerMike Pall <mike>2010-03-22 15:05:37 +0100
commit361266518c1500f25f7d83464ad4b2e2bd81db51 (patch)
treeddc694f82caadb2915e9f0d6b7a24c81c162fd03 /src
parent51c14bf1c80367ec2645819cbdb93d84524060d2 (diff)
downloadluajit-361266518c1500f25f7d83464ad4b2e2bd81db51.tar.gz
luajit-361266518c1500f25f7d83464ad4b2e2bd81db51.tar.bz2
luajit-361266518c1500f25f7d83464ad4b2e2bd81db51.zip
Move free node pos to t->node[0].freetop. Saves 4 bytes in GCtab.
Diffstat (limited to 'src')
-rw-r--r--src/lj_obj.h3
-rw-r--r--src/lj_state.c1
-rw-r--r--src/lj_tab.c89
3 files changed, 38 insertions, 55 deletions
diff --git a/src/lj_obj.h b/src/lj_obj.h
index a37c0882..048a74f9 100644
--- a/src/lj_obj.h
+++ b/src/lj_obj.h
@@ -453,7 +453,7 @@ typedef struct Node {
453 TValue val; /* Value object. Must be first field. */ 453 TValue val; /* Value object. Must be first field. */
454 TValue key; /* Key object. */ 454 TValue key; /* Key object. */
455 MRef next; /* Hash chain. */ 455 MRef next; /* Hash chain. */
456 int32_t unused; /* For consistent alignment. */ 456 MRef freetop; /* Top of free elements (stored in t->node[0]). */
457} Node; 457} Node;
458 458
459LJ_STATIC_ASSERT(offsetof(Node, val) == 0); 459LJ_STATIC_ASSERT(offsetof(Node, val) == 0);
@@ -468,7 +468,6 @@ typedef struct GCtab {
468 MRef node; /* Hash part. */ 468 MRef node; /* Hash part. */
469 uint32_t asize; /* Size of array part (keys [0, asize-1]). */ 469 uint32_t asize; /* Size of array part (keys [0, asize-1]). */
470 uint32_t hmask; /* Hash part mask (size of hash part - 1). */ 470 uint32_t hmask; /* Hash part mask (size of hash part - 1). */
471 MRef lastfree; /* Any free position is before this position. */
472} GCtab; 471} GCtab;
473 472
474#define sizetabcolo(n) ((n)*sizeof(TValue) + sizeof(GCtab)) 473#define sizetabcolo(n) ((n)*sizeof(TValue) + sizeof(GCtab))
diff --git a/src/lj_state.c b/src/lj_state.c
index 1e490b28..e90359ef 100644
--- a/src/lj_state.c
+++ b/src/lj_state.c
@@ -200,6 +200,7 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
200 setnilV(registry(L)); 200 setnilV(registry(L));
201 setnilV(&g->nilnode.val); 201 setnilV(&g->nilnode.val);
202 setnilV(&g->nilnode.key); 202 setnilV(&g->nilnode.key);
203 setmref(g->nilnode.freetop, &g->nilnode);
203 lj_str_initbuf(L, &g->tmpbuf); 204 lj_str_initbuf(L, &g->tmpbuf);
204 g->gc.state = GCSpause; 205 g->gc.state = GCSpause;
205 setgcref(g->gc.root, obj2gco(L)); 206 setgcref(g->gc.root, obj2gco(L));
diff --git a/src/lj_tab.c b/src/lj_tab.c
index fc44fdb4..be26bdda 100644
--- a/src/lj_tab.c
+++ b/src/lj_tab.c
@@ -60,9 +60,9 @@ static LJ_AINLINE void newhpart(lua_State *L, GCtab *t, uint32_t hbits)
60 lj_err_msg(L, LJ_ERR_TABOV); 60 lj_err_msg(L, LJ_ERR_TABOV);
61 hsize = 1u << hbits; 61 hsize = 1u << hbits;
62 node = lj_mem_newvec(L, hsize, Node); 62 node = lj_mem_newvec(L, hsize, Node);
63 setmref(node->freetop, &node[hsize]);
63 setmref(t->node, node); 64 setmref(t->node, node);
64 t->hmask = hsize-1; 65 t->hmask = hsize-1;
65 setmref(t->lastfree, &node[hsize]);
66} 66}
67 67
68/* 68/*
@@ -116,7 +116,6 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
116 t->asize = asize; 116 t->asize = asize;
117 t->hmask = 0; 117 t->hmask = 0;
118 setmref(t->node, &g->nilnode); 118 setmref(t->node, &g->nilnode);
119 setmref(t->lastfree, &g->nilnode);
120 } else { /* Otherwise separately allocate the array part. */ 119 } else { /* Otherwise separately allocate the array part. */
121 t = lj_mem_newobj(L, GCtab); 120 t = lj_mem_newobj(L, GCtab);
122 t->gct = ~LJ_TTAB; 121 t->gct = ~LJ_TTAB;
@@ -128,7 +127,6 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
128 t->hmask = 0; 127 t->hmask = 0;
129 g = G(L); 128 g = G(L);
130 setmref(t->node, &g->nilnode); 129 setmref(t->node, &g->nilnode);
131 setmref(t->lastfree, &g->nilnode);
132 if (asize > 0) { 130 if (asize > 0) {
133 if (asize > LJ_MAX_ASIZE) 131 if (asize > LJ_MAX_ASIZE)
134 lj_err_msg(L, LJ_ERR_TABOV); 132 lj_err_msg(L, LJ_ERR_TABOV);
@@ -196,7 +194,7 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
196 Node *node = noderef(t->node); 194 Node *node = noderef(t->node);
197 Node *knode = noderef(kt->node); 195 Node *knode = noderef(kt->node);
198 ptrdiff_t d = (char *)node - (char *)knode; 196 ptrdiff_t d = (char *)node - (char *)knode;
199 setmref(t->lastfree, (Node *)((char *)noderef(kt->lastfree) + d)); 197 setmref(node->freetop, (Node *)((char *)noderef(knode->freetop) + d));
200 for (i = 0; i <= hmask; i++) { 198 for (i = 0; i <= hmask; i++) {
201 Node *kn = &knode[i]; 199 Node *kn = &knode[i];
202 Node *n = &node[i]; 200 Node *n = &node[i];
@@ -263,7 +261,6 @@ static void resizetab(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits)
263 } else { 261 } else {
264 global_State *g = G(L); 262 global_State *g = G(L);
265 setmref(t->node, &g->nilnode); 263 setmref(t->node, &g->nilnode);
266 setmref(t->lastfree, &g->nilnode);
267 t->hmask = 0; 264 t->hmask = 0;
268 } 265 }
269 if (asize < oldasize) { /* Array part shrinks? */ 266 if (asize < oldasize) { /* Array part shrinks? */
@@ -427,59 +424,45 @@ cTValue *lj_tab_get(lua_State *L, GCtab *t, cTValue *key)
427 424
428/* -- Table setters ------------------------------------------------------- */ 425/* -- Table setters ------------------------------------------------------- */
429 426
430static Node *getfreepos(GCtab *t) 427/* Insert new key. Use Brent's variation to optimize the chain length. */
431{
432 Node *node = noderef(t->node);
433 Node *lastfree = noderef(t->lastfree);
434 while (lastfree > node) {
435 lastfree--;
436 setmref(t->lastfree, lastfree);
437 if (tvisnil(&lastfree->key))
438 return lastfree;
439 }
440 return NULL; /* could not find a free place */
441}
442
443/*
444** inserts a new key into a hash table; first, check whether key's main
445** position is free. If not, check whether colliding node is in its main
446** position or not: if it is not, move colliding node to an empty place and
447** put new key in its main position; otherwise (colliding node is in its main
448** position), new key goes to an empty position.
449*/
450TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key) 428TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)
451{ 429{
452 Node *mp = hashkey(t, key); 430 Node *n = hashkey(t, key);
453 if (!tvisnil(&mp->val) || t->hmask == 0) { 431 if (!tvisnil(&n->val) || t->hmask == 0) {
454 Node *othern; 432 Node *nodebase = noderef(t->node);
455 Node *n = getfreepos(t); /* get a free place */ 433 Node *collide, *freenode = noderef(nodebase->freetop);
456 if (n == NULL) { /* cannot find a free place? */ 434 lua_assert(freenode >= nodebase && freenode <= nodebase+t->hmask+1);
457 rehashtab(L, t, key); /* grow table */ 435 do {
458 return lj_tab_set(L, t, key); /* re-insert key into grown table */ 436 if (freenode == nodebase) { /* No free node found? */
459 } 437 rehashtab(L, t, key); /* Rehash table. */
460 lua_assert(n != &G(L)->nilnode); 438 return lj_tab_set(L, t, key); /* Retry key insertion. */
461 othern = hashkey(t, &mp->key); 439 }
462 if (othern != mp) { /* is colliding node out of its main position? */ 440 } while (!tvisnil(&(--freenode)->key));
463 /* yes; move colliding node into free position */ 441 setmref(nodebase->freetop, freenode);
464 while (noderef(othern->next) != mp) 442 lua_assert(freenode != &G(L)->nilnode);
465 othern = nextnode(othern); /* find previous */ 443 collide = hashkey(t, &n->key);
466 setmref(othern->next, n); /* redo the chain with `n' in place of `mp' */ 444 if (collide != n) { /* Colliding node not the main node? */
467 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ 445 while (noderef(collide->next) != n) /* Find predecessor. */
468 setmref(mp->next, NULL); /* now `mp' is free */ 446 collide = nextnode(collide);
469 setnilV(&mp->val); 447 setmref(collide->next, freenode); /* Relink chain. */
470 } else { /* colliding node is in its own main position */ 448 /* Copy colliding node into free node and free main node. */
471 /* new node will go into free position */ 449 freenode->val = n->val;
472 setmrefr(n->next, mp->next); /* chain new position */ 450 freenode->key = n->key;
473 setmref(mp->next, n); 451 freenode->next = n->next;
474 mp = n; 452 setmref(n->next, NULL);
453 setnilV(&n->val);
454 } else { /* Otherwise use free node. */
455 setmrefr(freenode->next, n->next); /* Insert into chain. */
456 setmref(n->next, freenode);
457 n = freenode;
475 } 458 }
476 } 459 }
477 mp->key.u64 = key->u64; 460 n->key.u64 = key->u64;
478 if (LJ_UNLIKELY(tvismzero(&mp->key))) 461 if (LJ_UNLIKELY(tvismzero(&n->key)))
479 mp->key.u64 = 0; 462 n->key.u64 = 0;
480 lj_gc_barriert(L, t, key); 463 lj_gc_barriert(L, t, key);
481 lua_assert(tvisnil(&mp->val)); 464 lua_assert(tvisnil(&n->val));
482 return &mp->val; 465 return &n->val;
483} 466}
484 467
485TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key) 468TValue *lj_tab_setinth(lua_State *L, GCtab *t, int32_t key)