diff options
author | Mike Pall <mike> | 2015-01-03 15:23:58 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2015-01-03 15:23:58 +0100 |
commit | cb481ddc8f9d92913ba07d998f4274bbf9711077 (patch) | |
tree | 852ffb4dd7c3cfdcf5c1ca6ae1531e5f9436d064 /src/lj_tab.c | |
parent | 054e6abe37450344e20b373ec326055071029e9b (diff) | |
download | luajit-cb481ddc8f9d92913ba07d998f4274bbf9711077.tar.gz luajit-cb481ddc8f9d92913ba07d998f4274bbf9711077.tar.bz2 luajit-cb481ddc8f9d92913ba07d998f4274bbf9711077.zip |
Add LJ_GC64 mode: 64 bit GC object references.
Actually NaN tagging with 47 bit pointers and 13+4 bit tags.
Diffstat (limited to 'src/lj_tab.c')
-rw-r--r-- | src/lj_tab.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/src/lj_tab.c b/src/lj_tab.c index ef19ba97..b6bb7805 100644 --- a/src/lj_tab.c +++ b/src/lj_tab.c | |||
@@ -29,7 +29,12 @@ static LJ_AINLINE Node *hashmask(const GCtab *t, uint32_t hash) | |||
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 | #define hashptr(t, p) hashlohi((t), u32ptr(p), u32ptr(p) + HASH_BIAS) |
32 | #if LJ_GC64 | ||
33 | #define hashgcref(t, r) \ | ||
34 | hashlohi((t), (uint32_t)gcrefu(r), (uint32_t)(gcrefu(r) >> 32)) | ||
35 | #else | ||
32 | #define hashgcref(t, r) hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS) | 36 | #define hashgcref(t, r) hashlohi((t), gcrefu(r), gcrefu(r) + HASH_BIAS) |
37 | #endif | ||
33 | 38 | ||
34 | /* Hash an arbitrary key and return its anchor position in the hash table. */ | 39 | /* Hash an arbitrary key and return its anchor position in the hash table. */ |
35 | static Node *hashkey(const GCtab *t, cTValue *key) | 40 | static Node *hashkey(const GCtab *t, cTValue *key) |
@@ -58,8 +63,8 @@ static LJ_AINLINE void newhpart(lua_State *L, GCtab *t, uint32_t hbits) | |||
58 | lj_err_msg(L, LJ_ERR_TABOV); | 63 | lj_err_msg(L, LJ_ERR_TABOV); |
59 | hsize = 1u << hbits; | 64 | hsize = 1u << hbits; |
60 | node = lj_mem_newvec(L, hsize, Node); | 65 | node = lj_mem_newvec(L, hsize, Node); |
61 | setmref(node->freetop, &node[hsize]); | ||
62 | setmref(t->node, node); | 66 | setmref(t->node, node); |
67 | setfreetop(t, node, &node[hsize]); | ||
63 | t->hmask = hsize-1; | 68 | t->hmask = hsize-1; |
64 | } | 69 | } |
65 | 70 | ||
@@ -98,6 +103,7 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits) | |||
98 | GCtab *t; | 103 | GCtab *t; |
99 | /* First try to colocate the array part. */ | 104 | /* First try to colocate the array part. */ |
100 | if (LJ_MAX_COLOSIZE != 0 && asize > 0 && asize <= LJ_MAX_COLOSIZE) { | 105 | if (LJ_MAX_COLOSIZE != 0 && asize > 0 && asize <= LJ_MAX_COLOSIZE) { |
106 | Node *nilnode; | ||
101 | lua_assert((sizeof(GCtab) & 7) == 0); | 107 | lua_assert((sizeof(GCtab) & 7) == 0); |
102 | t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize)); | 108 | t = (GCtab *)lj_mem_newgco(L, sizetabcolo(asize)); |
103 | t->gct = ~LJ_TTAB; | 109 | t->gct = ~LJ_TTAB; |
@@ -107,8 +113,13 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits) | |||
107 | setgcrefnull(t->metatable); | 113 | setgcrefnull(t->metatable); |
108 | t->asize = asize; | 114 | t->asize = asize; |
109 | t->hmask = 0; | 115 | t->hmask = 0; |
110 | setmref(t->node, &G(L)->nilnode); | 116 | nilnode = &G(L)->nilnode; |
117 | setmref(t->node, nilnode); | ||
118 | #if LJ_GC64 | ||
119 | setmref(t->freetop, nilnode); | ||
120 | #endif | ||
111 | } else { /* Otherwise separately allocate the array part. */ | 121 | } else { /* Otherwise separately allocate the array part. */ |
122 | Node *nilnode; | ||
112 | t = lj_mem_newobj(L, GCtab); | 123 | t = lj_mem_newobj(L, GCtab); |
113 | t->gct = ~LJ_TTAB; | 124 | t->gct = ~LJ_TTAB; |
114 | t->nomm = (uint8_t)~0; | 125 | t->nomm = (uint8_t)~0; |
@@ -117,7 +128,11 @@ static GCtab *newtab(lua_State *L, uint32_t asize, uint32_t hbits) | |||
117 | setgcrefnull(t->metatable); | 128 | setgcrefnull(t->metatable); |
118 | t->asize = 0; /* In case the array allocation fails. */ | 129 | t->asize = 0; /* In case the array allocation fails. */ |
119 | t->hmask = 0; | 130 | t->hmask = 0; |
120 | setmref(t->node, &G(L)->nilnode); | 131 | nilnode = &G(L)->nilnode; |
132 | setmref(t->node, nilnode); | ||
133 | #if LJ_GC64 | ||
134 | setmref(t->freetop, nilnode); | ||
135 | #endif | ||
121 | if (asize > 0) { | 136 | if (asize > 0) { |
122 | if (asize > LJ_MAX_ASIZE) | 137 | if (asize > LJ_MAX_ASIZE) |
123 | lj_err_msg(L, LJ_ERR_TABOV); | 138 | lj_err_msg(L, LJ_ERR_TABOV); |
@@ -191,7 +206,7 @@ GCtab * LJ_FASTCALL lj_tab_dup(lua_State *L, const GCtab *kt) | |||
191 | Node *node = noderef(t->node); | 206 | Node *node = noderef(t->node); |
192 | Node *knode = noderef(kt->node); | 207 | Node *knode = noderef(kt->node); |
193 | ptrdiff_t d = (char *)node - (char *)knode; | 208 | ptrdiff_t d = (char *)node - (char *)knode; |
194 | setmref(node->freetop, (Node *)((char *)noderef(knode->freetop) + d)); | 209 | setfreetop(t, node, (Node *)((char *)getfreetop(kt, knode) + d)); |
195 | for (i = 0; i <= hmask; i++) { | 210 | for (i = 0; i <= hmask; i++) { |
196 | Node *kn = &knode[i]; | 211 | Node *kn = &knode[i]; |
197 | Node *n = &node[i]; | 212 | Node *n = &node[i]; |
@@ -210,7 +225,7 @@ void LJ_FASTCALL lj_tab_clear(GCtab *t) | |||
210 | clearapart(t); | 225 | clearapart(t); |
211 | if (t->hmask > 0) { | 226 | if (t->hmask > 0) { |
212 | Node *node = noderef(t->node); | 227 | Node *node = noderef(t->node); |
213 | setmref(node->freetop, &node[t->hmask+1]); | 228 | setfreetop(t, node, &node[t->hmask+1]); |
214 | clearhpart(t); | 229 | clearhpart(t); |
215 | } | 230 | } |
216 | } | 231 | } |
@@ -264,6 +279,9 @@ static void resizetab(lua_State *L, GCtab *t, uint32_t asize, uint32_t hbits) | |||
264 | } else { | 279 | } else { |
265 | global_State *g = G(L); | 280 | global_State *g = G(L); |
266 | setmref(t->node, &g->nilnode); | 281 | setmref(t->node, &g->nilnode); |
282 | #if LJ_GC64 | ||
283 | setmref(t->freetop, &g->nilnode); | ||
284 | #endif | ||
267 | t->hmask = 0; | 285 | t->hmask = 0; |
268 | } | 286 | } |
269 | if (asize < oldasize) { /* Array part shrinks? */ | 287 | if (asize < oldasize) { /* Array part shrinks? */ |
@@ -445,7 +463,7 @@ TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key) | |||
445 | Node *n = hashkey(t, key); | 463 | Node *n = hashkey(t, key); |
446 | if (!tvisnil(&n->val) || t->hmask == 0) { | 464 | if (!tvisnil(&n->val) || t->hmask == 0) { |
447 | Node *nodebase = noderef(t->node); | 465 | Node *nodebase = noderef(t->node); |
448 | Node *collide, *freenode = noderef(nodebase->freetop); | 466 | Node *collide, *freenode = getfreetop(t, nodebase); |
449 | lua_assert(freenode >= nodebase && freenode <= nodebase+t->hmask+1); | 467 | lua_assert(freenode >= nodebase && freenode <= nodebase+t->hmask+1); |
450 | do { | 468 | do { |
451 | if (freenode == nodebase) { /* No free node found? */ | 469 | if (freenode == nodebase) { /* No free node found? */ |
@@ -453,7 +471,7 @@ TValue *lj_tab_newkey(lua_State *L, GCtab *t, cTValue *key) | |||
453 | return lj_tab_set(L, t, key); /* Retry key insertion. */ | 471 | return lj_tab_set(L, t, key); /* Retry key insertion. */ |
454 | } | 472 | } |
455 | } while (!tvisnil(&(--freenode)->key)); | 473 | } while (!tvisnil(&(--freenode)->key)); |
456 | setmref(nodebase->freetop, freenode); | 474 | setfreetop(t, nodebase, freenode); |
457 | lua_assert(freenode != &G(L)->nilnode); | 475 | lua_assert(freenode != &G(L)->nilnode); |
458 | collide = hashkey(t, &n->key); | 476 | collide = hashkey(t, &n->key); |
459 | if (collide != n) { /* Colliding node not the main node? */ | 477 | if (collide != n) { /* Colliding node not the main node? */ |