aboutsummaryrefslogtreecommitdiff
path: root/src/lj_tab.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_tab.c')
-rw-r--r--src/lj_tab.c54
1 files changed, 44 insertions, 10 deletions
diff --git a/src/lj_tab.c b/src/lj_tab.c
index a45ddaca..dcd24d31 100644
--- a/src/lj_tab.c
+++ b/src/lj_tab.c
@@ -28,8 +28,12 @@ static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash)
28 28
29#define hashlohi(t, lo, hi) hashmask((t), hashrot((lo), (hi))) 29#define hashlohi(t, lo, hi) hashmask((t), hashrot((lo), (hi)))
30#define hashnum(t, o) hashlohi((t), (o)->u32.lo, ((o)->u32.hi << 1)) 30#define hashnum(t, o) hashlohi((t), (o)->u32.lo, ((o)->u32.hi << 1))
31#define hashptr(t, p) hashlohi((t), u32ptr(p), u32ptr(p) + HASH_BIAS) 31#if LJ_GC64
32#define hashgcref(t, r) \
33 hashlohi((t), (uint32_t)gcrefu(r), (uint32_t)(gcrefu(r) >> 32))
34#else
32#define hashgcref(t, r) hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS) 35#define hashgcref(t, r) hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS)
36#endif
33 37
34/* Hash an arbitrary key and return its anchor position in the hash table. */ 38/* Hash an arbitrary key and return its anchor position in the hash table. */
35static Node *hashkey(const GCtab *t, cTValue *key) 39static Node *hashkey(const GCtab *t, cTValue *key)
@@ -58,8 +62,8 @@ static LJ_AINLINE void newhpart(lua_State *L, GCtab *t, uint32_t hbits)
58 lj_err_msg(L, LJ_ERR_TABOV); 62 lj_err_msg(L, LJ_ERR_TABOV);
59 hsize = 1u << hbits; 63 hsize = 1u << hbits;
60 node = lj_mem_newvec(L, hsize, Node); 64 node = lj_mem_newvec(L, hsize, Node);
61 setmref(node->freetop, &node[hsize]);
62 setmref(t->node, node); 65 setmref(t->node, node);
66 setfreetop(t, node, &node[hsize]);
63 t->hmask = hsize-1; 67 t->hmask = hsize-1;
64} 68}
65 69
@@ -98,6 +102,7 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
98 GCtab *t; 102 GCtab *t;
99 /* First try to colocate the array part. */ 103 /* First try to colocate the array part. */
100 if (LJ_MAX_COLOSIZE != 0 && asize > 0 && asize <= LJ_MAX_COLOSIZE) { 104 if (LJ_MAX_COLOSIZE != 0 && asize > 0 && asize <= LJ_MAX_COLOSIZE) {
105 Node *nilnode;
101 lua_assert((sizeof(GCtab) & 7) == 0); 106 lua_assert((sizeof(GCtab) & 7) == 0);
102 t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize)); 107 t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize));
103 t->gct = ~LJ_TTAB; 108 t->gct = ~LJ_TTAB;
@@ -107,8 +112,13 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
107 setgcrefnull(t->metatable); 112 setgcrefnull(t->metatable);
108 t->asize = asize; 113 t->asize = asize;
109 t->hmask = 0; 114 t->hmask = 0;
110 setmref(t->node, &G(L)->nilnode); 115 nilnode = &G(L)->nilnode;
116 setmref(t->node, nilnode);
117#if LJ_GC64
118 setmref(t->freetop, nilnode);
119#endif
111 } else { /* Otherwise separately allocate the array part. */ 120 } else { /* Otherwise separately allocate the array part. */
121 Node *nilnode;
112 t = lj_mem_newobj(L, GCtab); 122 t = lj_mem_newobj(L, GCtab);
113 t->gct = ~LJ_TTAB; 123 t->gct = ~LJ_TTAB;
114 t->nomm = (uint8_t)~0; 124 t->nomm = (uint8_t)~0;
@@ -117,7 +127,11 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits)
117 setgcrefnull(t->metatable); 127 setgcrefnull(t->metatable);
118 t->asize = 0; /* In case the array allocation fails. */ 128 t->asize = 0; /* In case the array allocation fails. */
119 t->hmask = 0; 129 t->hmask = 0;
120 setmref(t->node, &G(L)->nilnode); 130 nilnode = &G(L)->nilnode;
131 setmref(t->node, nilnode);
132#if LJ_GC64
133 setmref(t->freetop, nilnode);
134#endif
121 if (asize > 0) { 135 if (asize > 0) {
122 if (asize > LJ_MAX_ASIZE) 136 if (asize > LJ_MAX_ASIZE)
123 lj_err_msg(L, LJ_ERR_TABOV); 137 lj_err_msg(L, LJ_ERR_TABOV);
@@ -149,6 +163,12 @@ GCtab *lj_tab_new(lua_State *L, uint32_t asize, uint32_t hbits)
149 return t; 163 return t;
150} 164}
151 165
166/* The API of this function conforms to lua_createtable(). */
167GCtab *lj_tab_new_ah(lua_State *L, int32_t a, int32_t h)
168{
169 return lj_tab_new(L, (uint32_t)(a > 0 ? a+1 : 0), hsize2hbits(h));
170}
171
152#if LJ_HASJIT 172#if LJ_HASJIT
153GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize) 173GCtab * LJ_FASTCALL lj_tab_new1(lua_State *L, uint32_t ahsize)
154{ 174{
@@ -185,7 +205,7 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
185 Node *node = noderef(t->node); 205 Node *node = noderef(t->node);
186 Node *knode = noderef(kt->node); 206 Node *knode = noderef(kt->node);
187 ptrdiff_t d = (char *)node - (char *)knode; 207 ptrdiff_t d = (char *)node - (char *)knode;
188 setmref(node->freetop, (Node *)((char *)noderef(knode->freetop) + d)); 208 setfreetop(t, node, (Node *)((char *)getfreetop(kt, knode) + d));
189 for (i = 0; i <= hmask; i++) { 209 for (i = 0; i <= hmask; i++) {
190 Node *kn = &knode[i]; 210 Node *kn = &knode[i];
191 Node *n = &node[i]; 211 Node *n = &node[i];
@@ -198,6 +218,17 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt)
198 return t; 218 return t;
199} 219}
200 220
221/* Clear a table. */
222void LJ_FASTCALL lj_tab_clear(GCtab *t)
223{
224 clearapart(t);
225 if (t->hmask > 0) {
226 Node *node = noderef(t->node);
227 setfreetop(t, node, &node[t->hmask+1]);
228 clearhpart(t);
229 }
230}
231
201/* Free a table. */ 232/* Free a table. */
202void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t) 233void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t)
203{ 234{
@@ -214,7 +245,7 @@ void LJ_FASTCALL lj_tab_free(global_State *g, GCtab *t)
214/* -- Table resizing ------------------------------------------------------ */ 245/* -- Table resizing ------------------------------------------------------ */
215 246
216/* Resize a table to fit the new array/hash part sizes. */ 247/* Resize a table to fit the new array/hash part sizes. */
217static void resizetab(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits) 248void lj_tab_resize(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits)
218{ 249{
219 Node *oldnode = noderef(t->node); 250 Node *oldnode = noderef(t->node);
220 uint32_t oldasize = t->asize; 251 uint32_t oldasize = t->asize;
@@ -247,6 +278,9 @@ static void resizetab(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits)
247 } else { 278 } else {
248 global_State *g = G(L); 279 global_State *g = G(L);
249 setmref(t->node, &g->nilnode); 280 setmref(t->node, &g->nilnode);
281#if LJ_GC64
282 setmref(t->freetop, &g->nilnode);
283#endif
250 t->hmask = 0; 284 t->hmask = 0;
251 } 285 }
252 if (asize < oldasize) { /* Array part shrinks? */ 286 if (asize < oldasize) { /* Array part shrinks? */
@@ -348,7 +382,7 @@ static void rehashtab(lua_State *L, GCtab *t, cTValue *ek)
348 asize += countint(ek, bins); 382 asize += countint(ek, bins);
349 na = bestasize(bins, &asize); 383 na = bestasize(bins, &asize);
350 total -= na; 384 total -= na;
351 resizetab(L, t, asize, hsize2hbits(total)); 385 lj_tab_resize(L, t, asize, hsize2hbits(total));
352} 386}
353 387
354#if LJ_HASFFI 388#if LJ_HASFFI
@@ -360,7 +394,7 @@ void lj_tab_rehash(lua_State *L, GCtab *t)
360 394
361void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize) 395void lj_tab_reasize(lua_State *L, GCtab *t, uint32_t nasize)
362{ 396{
363 resizetab(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0); 397 lj_tab_resize(L, t, nasize+1, t->hmask > 0 ? lj_fls(t->hmask)+1 : 0);
364} 398}
365 399
366/* -- Table getters ------------------------------------------------------- */ 400/* -- Table getters ------------------------------------------------------- */
@@ -428,7 +462,7 @@ TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)
428 Node *n = hashkey(t, key); 462 Node *n = hashkey(t, key);
429 if (!tvisnil(&n->val) || t->hmask == 0) { 463 if (!tvisnil(&n->val) || t->hmask == 0) {
430 Node *nodebase = noderef(t->node); 464 Node *nodebase = noderef(t->node);
431 Node *collide, *freenode = noderef(nodebase->freetop); 465 Node *collide, *freenode = getfreetop(t, nodebase);
432 lua_assert(freenode >= nodebase && freenode <= nodebase+t->hmask+1); 466 lua_assert(freenode >= nodebase && freenode <= nodebase+t->hmask+1);
433 do { 467 do {
434 if (freenode == nodebase) { /* No free node found? */ 468 if (freenode == nodebase) { /* No free node found? */
@@ -436,7 +470,7 @@ TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key)
436 return lj_tab_set(L, t, key); /* Retry key insertion. */ 470 return lj_tab_set(L, t, key); /* Retry key insertion. */
437 } 471 }
438 } while (!tvisnil(&(--freenode)->key)); 472 } while (!tvisnil(&(--freenode)->key));
439 setmref(nodebase->freetop, freenode); 473 setfreetop(t, nodebase, freenode);
440 lua_assert(freenode != &G(L)->nilnode); 474 lua_assert(freenode != &G(L)->nilnode);
441 collide = hashkey(t, &n->key); 475 collide = hashkey(t, &n->key);
442 if (collide != n) { /* Colliding node not the main node? */ 476 if (collide != n) { /* Colliding node not the main node? */