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 | |
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.
-rw-r--r-- | src/lj_alloc.c | 12 | ||||
-rw-r--r-- | src/lj_api.c | 4 | ||||
-rw-r--r-- | src/lj_arch.h | 13 | ||||
-rw-r--r-- | src/lj_def.h | 15 | ||||
-rw-r--r-- | src/lj_ffrecord.c | 2 | ||||
-rw-r--r-- | src/lj_ir.c | 1 | ||||
-rw-r--r-- | src/lj_ir.h | 11 | ||||
-rw-r--r-- | src/lj_jit.h | 3 | ||||
-rw-r--r-- | src/lj_lib.h | 5 | ||||
-rw-r--r-- | src/lj_obj.h | 111 | ||||
-rw-r--r-- | src/lj_snap.c | 1 | ||||
-rw-r--r-- | src/lj_state.c | 2 | ||||
-rw-r--r-- | src/lj_tab.c | 32 |
13 files changed, 183 insertions, 29 deletions
diff --git a/src/lj_alloc.c b/src/lj_alloc.c index 7c7ec678..0aad826d 100644 --- a/src/lj_alloc.c +++ b/src/lj_alloc.c | |||
@@ -77,7 +77,7 @@ | |||
77 | #define WIN32_LEAN_AND_MEAN | 77 | #define WIN32_LEAN_AND_MEAN |
78 | #include <windows.h> | 78 | #include <windows.h> |
79 | 79 | ||
80 | #if LJ_64 | 80 | #if LJ_64 && !LJ_GC64 |
81 | 81 | ||
82 | /* Undocumented, but hey, that's what we all love so much about Windows. */ | 82 | /* Undocumented, but hey, that's what we all love so much about Windows. */ |
83 | typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG zbits, | 83 | typedef long (*PNTAVM)(HANDLE handle, void **addr, ULONG zbits, |
@@ -174,8 +174,10 @@ static LJ_AINLINE int CALL_MUNMAP(void *ptr, size_t size) | |||
174 | #endif | 174 | #endif |
175 | #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) | 175 | #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) |
176 | 176 | ||
177 | #if LJ_64 | 177 | #if LJ_64 && !LJ_GC64 |
178 | /* 64 bit mode needs special support for allocating memory in the lower 2GB. */ | 178 | /* 64 bit mode with 32 bit pointers needs special support for allocating |
179 | ** memory in the lower 2GB. | ||
180 | */ | ||
179 | 181 | ||
180 | #if defined(MAP_32BIT) | 182 | #if defined(MAP_32BIT) |
181 | 183 | ||
@@ -258,7 +260,7 @@ static LJ_AINLINE void *CALL_MMAP(size_t size) | |||
258 | 260 | ||
259 | #else | 261 | #else |
260 | 262 | ||
261 | /* 32 bit mode is easy. */ | 263 | /* 32 bit mode and GC64 mode is easy. */ |
262 | static LJ_AINLINE void *CALL_MMAP(size_t size) | 264 | static LJ_AINLINE void *CALL_MMAP(size_t size) |
263 | { | 265 | { |
264 | int olderr = errno; | 266 | int olderr = errno; |
@@ -294,7 +296,7 @@ static LJ_AINLINE void *CALL_MREMAP_(void *ptr, size_t osz, size_t nsz, | |||
294 | #define CALL_MREMAP(addr, osz, nsz, mv) CALL_MREMAP_((addr), (osz), (nsz), (mv)) | 296 | #define CALL_MREMAP(addr, osz, nsz, mv) CALL_MREMAP_((addr), (osz), (nsz), (mv)) |
295 | #define CALL_MREMAP_NOMOVE 0 | 297 | #define CALL_MREMAP_NOMOVE 0 |
296 | #define CALL_MREMAP_MAYMOVE 1 | 298 | #define CALL_MREMAP_MAYMOVE 1 |
297 | #if LJ_64 | 299 | #if LJ_64 && !LJ_GC64 |
298 | #define CALL_MREMAP_MV CALL_MREMAP_NOMOVE | 300 | #define CALL_MREMAP_MV CALL_MREMAP_NOMOVE |
299 | #else | 301 | #else |
300 | #define CALL_MREMAP_MV CALL_MREMAP_MAYMOVE | 302 | #define CALL_MREMAP_MV CALL_MREMAP_MAYMOVE |
diff --git a/src/lj_api.c b/src/lj_api.c index 6ad09b9d..f1843723 100644 --- a/src/lj_api.c +++ b/src/lj_api.c | |||
@@ -189,7 +189,7 @@ LUA_API int lua_type(lua_State *L, int idx) | |||
189 | cTValue *o = index2adr(L, idx); | 189 | cTValue *o = index2adr(L, idx); |
190 | if (tvisnumber(o)) { | 190 | if (tvisnumber(o)) { |
191 | return LUA_TNUMBER; | 191 | return LUA_TNUMBER; |
192 | #if LJ_64 | 192 | #if LJ_64 && !LJ_GC64 |
193 | } else if (tvislightud(o)) { | 193 | } else if (tvislightud(o)) { |
194 | return LUA_TLIGHTUSERDATA; | 194 | return LUA_TLIGHTUSERDATA; |
195 | #endif | 195 | #endif |
@@ -269,7 +269,7 @@ LUA_API int lua_equal(lua_State *L, int idx1, int idx2) | |||
269 | return 0; | 269 | return 0; |
270 | } else if (tvispri(o1)) { | 270 | } else if (tvispri(o1)) { |
271 | return o1 != niltv(L) && o2 != niltv(L); | 271 | return o1 != niltv(L) && o2 != niltv(L); |
272 | #if LJ_64 | 272 | #if LJ_64 && !LJ_GC64 |
273 | } else if (tvislightud(o1)) { | 273 | } else if (tvislightud(o1)) { |
274 | return o1->u64 == o2->u64; | 274 | return o1->u64 == o2->u64; |
275 | #endif | 275 | #endif |
diff --git a/src/lj_arch.h b/src/lj_arch.h index 8f3796fc..18555b41 100644 --- a/src/lj_arch.h +++ b/src/lj_arch.h | |||
@@ -365,11 +365,22 @@ | |||
365 | #endif | 365 | #endif |
366 | #endif | 366 | #endif |
367 | 367 | ||
368 | /* 64 bit GC references. */ | ||
369 | #if LJ_TARGET_GC64 | ||
370 | #define LJ_GC64 1 | ||
371 | #else | ||
372 | #define LJ_GC64 0 | ||
373 | #endif | ||
374 | |||
368 | /* 2-slot frame info. */ | 375 | /* 2-slot frame info. */ |
376 | #if LJ_GC64 | ||
377 | #define LJ_FR2 1 | ||
378 | #else | ||
369 | #define LJ_FR2 0 | 379 | #define LJ_FR2 0 |
380 | #endif | ||
370 | 381 | ||
371 | /* Disable or enable the JIT compiler. */ | 382 | /* Disable or enable the JIT compiler. */ |
372 | #if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT) || defined(LJ_OS_NOJIT) || LJ_FR2 | 383 | #if defined(LUAJIT_DISABLE_JIT) || defined(LJ_ARCH_NOJIT) || defined(LJ_OS_NOJIT) || LJ_FR2 || LJ_GC64 |
373 | #define LJ_HASJIT 0 | 384 | #define LJ_HASJIT 0 |
374 | #else | 385 | #else |
375 | #define LJ_HASJIT 1 | 386 | #define LJ_HASJIT 1 |
diff --git a/src/lj_def.h b/src/lj_def.h index 93420ba5..f4231239 100644 --- a/src/lj_def.h +++ b/src/lj_def.h | |||
@@ -47,7 +47,9 @@ typedef unsigned int uintptr_t; | |||
47 | 47 | ||
48 | /* Various VM limits. */ | 48 | /* Various VM limits. */ |
49 | #define LJ_MAX_MEM32 0x7fffff00 /* Max. 32 bit memory allocation. */ | 49 | #define LJ_MAX_MEM32 0x7fffff00 /* Max. 32 bit memory allocation. */ |
50 | #define LJ_MAX_MEM LJ_MAX_MEM32 /* Max. total memory allocation. */ | 50 | #define LJ_MAX_MEM64 ((uint64_t)1<<47) /* Max. 64 bit memory allocation. */ |
51 | /* Max. total memory allocation. */ | ||
52 | #define LJ_MAX_MEM (LJ_GC64 ? LJ_MAX_MEM64 : LJ_MAX_MEM32) | ||
51 | #define LJ_MAX_ALLOC LJ_MAX_MEM /* Max. individual allocation length. */ | 53 | #define LJ_MAX_ALLOC LJ_MAX_MEM /* Max. individual allocation length. */ |
52 | #define LJ_MAX_STR LJ_MAX_MEM32 /* Max. string length. */ | 54 | #define LJ_MAX_STR LJ_MAX_MEM32 /* Max. string length. */ |
53 | #define LJ_MAX_BUF LJ_MAX_MEM32 /* Max. buffer length. */ | 55 | #define LJ_MAX_BUF LJ_MAX_MEM32 /* Max. buffer length. */ |
@@ -67,7 +69,7 @@ typedef unsigned int uintptr_t; | |||
67 | #define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */ | 69 | #define LJ_MAX_UPVAL 60 /* Max. # of upvalues. */ |
68 | 70 | ||
69 | #define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */ | 71 | #define LJ_MAX_IDXCHAIN 100 /* __index/__newindex chain limit. */ |
70 | #define LJ_STACK_EXTRA 5 /* Extra stack space (metamethods). */ | 72 | #define LJ_STACK_EXTRA (5+2*LJ_FR2) /* Extra stack space (metamethods). */ |
71 | 73 | ||
72 | #define LJ_NUM_CBPAGE 1 /* Number of FFI callback pages. */ | 74 | #define LJ_NUM_CBPAGE 1 /* Number of FFI callback pages. */ |
73 | 75 | ||
@@ -101,7 +103,14 @@ typedef unsigned int uintptr_t; | |||
101 | #define checki32(x) ((x) == (int32_t)(x)) | 103 | #define checki32(x) ((x) == (int32_t)(x)) |
102 | #define checku32(x) ((x) == (uint32_t)(x)) | 104 | #define checku32(x) ((x) == (uint32_t)(x)) |
103 | #define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x)) | 105 | #define checkptr32(x) ((uintptr_t)(x) == (uint32_t)(uintptr_t)(x)) |
104 | #define checkptrGC(x) (checkptr32(x)) | 106 | #define checkptr47(x) (((uint64_t)(x) >> 47) == 0) |
107 | #if LJ_GC64 | ||
108 | #define checkptrGC(x) (checkptr47((x))) | ||
109 | #elif LJ_64 | ||
110 | #define checkptrGC(x) (checkptr32((x))) | ||
111 | #else | ||
112 | #define checkptrGC(x) 1 | ||
113 | #endif | ||
105 | 114 | ||
106 | /* Every half-decent C compiler transforms this into a rotate instruction. */ | 115 | /* Every half-decent C compiler transforms this into a rotate instruction. */ |
107 | #define lj_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1)))) | 116 | #define lj_rol(x, n) (((x)<<(n)) | ((x)>>(-(int)(n)&(8*sizeof(x)-1)))) |
diff --git a/src/lj_ffrecord.c b/src/lj_ffrecord.c index 55cdc63e..6bf26070 100644 --- a/src/lj_ffrecord.c +++ b/src/lj_ffrecord.c | |||
@@ -196,7 +196,7 @@ static void LJ_FASTCALL recff_type(jit_State *J, RecordFFData *rd) | |||
196 | uint32_t t; | 196 | uint32_t t; |
197 | if (tvisnumber(&rd->argv[0])) | 197 | if (tvisnumber(&rd->argv[0])) |
198 | t = ~LJ_TNUMX; | 198 | t = ~LJ_TNUMX; |
199 | else if (LJ_64 && tvislightud(&rd->argv[0])) | 199 | else if (LJ_64 && !LJ_GC64 && tvislightud(&rd->argv[0])) |
200 | t = ~LJ_TLIGHTUD; | 200 | t = ~LJ_TLIGHTUD; |
201 | else | 201 | else |
202 | t = ~itype(&rd->argv[0]); | 202 | t = ~itype(&rd->argv[0]); |
diff --git a/src/lj_ir.c b/src/lj_ir.c index 0689bc22..12d38909 100644 --- a/src/lj_ir.c +++ b/src/lj_ir.c | |||
@@ -307,6 +307,7 @@ TRef lj_ir_kgc(jit_State *J, GCobj *o, IRType t) | |||
307 | { | 307 | { |
308 | IRIns *ir, *cir = J->cur.ir; | 308 | IRIns *ir, *cir = J->cur.ir; |
309 | IRRef ref; | 309 | IRRef ref; |
310 | lua_assert(!LJ_GC64); /* TODO_GC64: major changes required. */ | ||
310 | lua_assert(!isdead(J2G(J), o)); | 311 | lua_assert(!isdead(J2G(J), o)); |
311 | for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev) | 312 | for (ref = J->chain[IR_KGC]; ref; ref = cir[ref].prev) |
312 | if (ir_kgc(&cir[ref]) == o) | 313 | if (ir_kgc(&cir[ref]) == o) |
diff --git a/src/lj_ir.h b/src/lj_ir.h index 14b86165..bc89edf9 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
@@ -320,6 +320,7 @@ IRTDEF(IRTENUM) | |||
320 | IRT_PTR = LJ_64 ? IRT_P64 : IRT_P32, | 320 | IRT_PTR = LJ_64 ? IRT_P64 : IRT_P32, |
321 | IRT_INTP = LJ_64 ? IRT_I64 : IRT_INT, | 321 | IRT_INTP = LJ_64 ? IRT_I64 : IRT_INT, |
322 | IRT_UINTP = LJ_64 ? IRT_U64 : IRT_U32, | 322 | IRT_UINTP = LJ_64 ? IRT_U64 : IRT_U32, |
323 | /* TODO_GC64: major changes required for all uses of IRT_P32. */ | ||
323 | 324 | ||
324 | /* Additional flags. */ | 325 | /* Additional flags. */ |
325 | IRT_MARK = 0x20, /* Marker for misc. purposes. */ | 326 | IRT_MARK = 0x20, /* Marker for misc. purposes. */ |
@@ -371,7 +372,12 @@ typedef struct IRType1 { uint8_t irt; } IRType1; | |||
371 | #define irt_isaddr(t) (irt_typerange((t), IRT_LIGHTUD, IRT_UDATA)) | 372 | #define irt_isaddr(t) (irt_typerange((t), IRT_LIGHTUD, IRT_UDATA)) |
372 | #define irt_isint64(t) (irt_typerange((t), IRT_I64, IRT_U64)) | 373 | #define irt_isint64(t) (irt_typerange((t), IRT_I64, IRT_U64)) |
373 | 374 | ||
374 | #if LJ_64 | 375 | #if LJ_GC64 |
376 | #define IRT_IS64 \ | ||
377 | ((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64)|(1u<<IRT_P64)|\ | ||
378 | (1u<<IRT_LIGHTUD)|(1u<<IRT_STR)|(1u<<IRT_THREAD)|(1u<<IRT_PROTO)|\ | ||
379 | (1u<<IRT_FUNC)|(1u<<IRT_CDATA)|(1u<<IRT_TAB)|(1u<<IRT_UDATA)) | ||
380 | #elif LJ_64 | ||
375 | #define IRT_IS64 \ | 381 | #define IRT_IS64 \ |
376 | ((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64)|(1u<<IRT_P64)|(1u<<IRT_LIGHTUD)) | 382 | ((1u<<IRT_NUM)|(1u<<IRT_I64)|(1u<<IRT_U64)|(1u<<IRT_P64)|(1u<<IRT_LIGHTUD)) |
377 | #else | 383 | #else |
@@ -392,7 +398,7 @@ static LJ_AINLINE IRType itype2irt(const TValue *tv) | |||
392 | return IRT_INT; | 398 | return IRT_INT; |
393 | else if (tvisnum(tv)) | 399 | else if (tvisnum(tv)) |
394 | return IRT_NUM; | 400 | return IRT_NUM; |
395 | #if LJ_64 | 401 | #if LJ_64 && !LJ_GC64 |
396 | else if (tvislightud(tv)) | 402 | else if (tvislightud(tv)) |
397 | return IRT_LIGHTUD; | 403 | return IRT_LIGHTUD; |
398 | #endif | 404 | #endif |
@@ -547,6 +553,7 @@ typedef union IRIns { | |||
547 | MRef ptr; /* Pointer constant (overlaps op12). */ | 553 | MRef ptr; /* Pointer constant (overlaps op12). */ |
548 | } IRIns; | 554 | } IRIns; |
549 | 555 | ||
556 | /* TODO_GC64: major changes required. */ | ||
550 | #define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)->gcr)) | 557 | #define ir_kgc(ir) check_exp((ir)->o == IR_KGC, gcref((ir)->gcr)) |
551 | #define ir_kstr(ir) (gco2str(ir_kgc((ir)))) | 558 | #define ir_kstr(ir) (gco2str(ir_kgc((ir)))) |
552 | #define ir_ktab(ir) (gco2tab(ir_kgc((ir)))) | 559 | #define ir_ktab(ir) (gco2tab(ir_kgc((ir)))) |
diff --git a/src/lj_jit.h b/src/lj_jit.h index 4246e9db..ed92f62d 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
@@ -213,6 +213,9 @@ typedef struct GCtrace { | |||
213 | uint8_t topslot; /* Top stack slot already checked to be allocated. */ | 213 | uint8_t topslot; /* Top stack slot already checked to be allocated. */ |
214 | uint8_t linktype; /* Type of link. */ | 214 | uint8_t linktype; /* Type of link. */ |
215 | IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */ | 215 | IRRef nins; /* Next IR instruction. Biased with REF_BIAS. */ |
216 | #if LJ_GC64 | ||
217 | uint32_t unused_gc64; | ||
218 | #endif | ||
216 | GCRef gclist; | 219 | GCRef gclist; |
217 | IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */ | 220 | IRIns *ir; /* IR instructions/constants. Biased with REF_BIAS. */ |
218 | IRRef nk; /* Lowest IR constant. Biased with REF_BIAS. */ | 221 | IRRef nk; /* Lowest IR constant. Biased with REF_BIAS. */ |
diff --git a/src/lj_lib.h b/src/lj_lib.h index dff99c09..95e4d4a6 100644 --- a/src/lj_lib.h +++ b/src/lj_lib.h | |||
@@ -47,7 +47,10 @@ LJ_FUNC GCtab *lj_lib_checktabornil(lua_State *L, int narg); | |||
47 | LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst); | 47 | LJ_FUNC int lj_lib_checkopt(lua_State *L, int narg, int def, const char *lst); |
48 | 48 | ||
49 | /* Avoid including lj_frame.h. */ | 49 | /* Avoid including lj_frame.h. */ |
50 | #if LJ_FR2 | 50 | #if LJ_GC64 |
51 | #define lj_lib_upvalue(L, n) \ | ||
52 | (&gcval(L->base-2)->fn.c.upvalue[(n)-1]) | ||
53 | #elif LJ_FR2 | ||
51 | #define lj_lib_upvalue(L, n) \ | 54 | #define lj_lib_upvalue(L, n) \ |
52 | (&gcref((L->base-2)->gcr)->fn.c.upvalue[(n)-1]) | 55 | (&gcref((L->base-2)->gcr)->fn.c.upvalue[(n)-1]) |
53 | #else | 56 | #else |
diff --git a/src/lj_obj.h b/src/lj_obj.h index 438c83d4..d5809229 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
@@ -17,39 +17,73 @@ | |||
17 | 17 | ||
18 | /* Memory and GC object sizes. */ | 18 | /* Memory and GC object sizes. */ |
19 | typedef uint32_t MSize; | 19 | typedef uint32_t MSize; |
20 | #if LJ_GC64 | ||
21 | typedef uint64_t GCSize; | ||
22 | #else | ||
20 | typedef uint32_t GCSize; | 23 | typedef uint32_t GCSize; |
24 | #endif | ||
21 | 25 | ||
22 | /* Memory reference */ | 26 | /* Memory reference */ |
23 | typedef struct MRef { | 27 | typedef struct MRef { |
28 | #if LJ_GC64 | ||
29 | uint64_t ptr64; /* True 64 bit pointer. */ | ||
30 | #else | ||
24 | uint32_t ptr32; /* Pseudo 32 bit pointer. */ | 31 | uint32_t ptr32; /* Pseudo 32 bit pointer. */ |
32 | #endif | ||
25 | } MRef; | 33 | } MRef; |
26 | 34 | ||
35 | #if LJ_GC64 | ||
36 | #define mref(r, t) ((t *)(void *)(r).ptr64) | ||
37 | |||
38 | #define setmref(r, p) ((r).ptr64 = (uint64_t)(void *)(p)) | ||
39 | #define setmrefr(r, v) ((r).ptr64 = (v).ptr64) | ||
40 | #else | ||
27 | #define mref(r, t) ((t *)(void *)(uintptr_t)(r).ptr32) | 41 | #define mref(r, t) ((t *)(void *)(uintptr_t)(r).ptr32) |
28 | 42 | ||
29 | #define setmref(r, p) ((r).ptr32 = (uint32_t)(uintptr_t)(void *)(p)) | 43 | #define setmref(r, p) ((r).ptr32 = (uint32_t)(uintptr_t)(void *)(p)) |
30 | #define setmrefr(r, v) ((r).ptr32 = (v).ptr32) | 44 | #define setmrefr(r, v) ((r).ptr32 = (v).ptr32) |
45 | #endif | ||
31 | 46 | ||
32 | /* -- GC object references (32 bit address space) ------------------------- */ | 47 | /* -- GC object references (32 bit address space) ------------------------- */ |
33 | 48 | ||
34 | /* GCobj reference */ | 49 | /* GCobj reference */ |
35 | typedef struct GCRef { | 50 | typedef struct GCRef { |
51 | #if LJ_GC64 | ||
52 | uint64_t gcptr64; /* True 64 bit pointer. */ | ||
53 | #else | ||
36 | uint32_t gcptr32; /* Pseudo 32 bit pointer. */ | 54 | uint32_t gcptr32; /* Pseudo 32 bit pointer. */ |
55 | #endif | ||
37 | } GCRef; | 56 | } GCRef; |
38 | 57 | ||
39 | /* Common GC header for all collectable objects. */ | 58 | /* Common GC header for all collectable objects. */ |
40 | #define GCHeader GCRef nextgc; uint8_t marked; uint8_t gct | 59 | #define GCHeader GCRef nextgc; uint8_t marked; uint8_t gct |
41 | /* This occupies 6 bytes, so use the next 2 bytes for non-32 bit fields. */ | 60 | /* This occupies 6 bytes, so use the next 2 bytes for non-32 bit fields. */ |
42 | 61 | ||
62 | #if LJ_GC64 | ||
63 | #define gcref(r) ((GCobj *)(r).gcptr64) | ||
64 | #define gcrefp(r, t) ((t *)(void *)(r).gcptr64) | ||
65 | #define gcrefu(r) ((r).gcptr64) | ||
66 | #define gcrefeq(r1, r2) ((r1).gcptr64 == (r2).gcptr64) | ||
67 | |||
68 | #define setgcref(r, gc) ((r).gcptr64 = (uint64_t)&(gc)->gch) | ||
69 | #define setgcreft(r, gc, it) \ | ||
70 | (r).gcptr64 = (uint64_t)&(gc)->gch | (((uint64_t)(it)) << 47) | ||
71 | #define setgcrefp(r, p) ((r).gcptr64 = (uint64_t)(p)) | ||
72 | #define setgcrefnull(r) ((r).gcptr64 = 0) | ||
73 | #define setgcrefr(r, v) ((r).gcptr64 = (v).gcptr64) | ||
74 | #else | ||
43 | #define gcref(r) ((GCobj *)(uintptr_t)(r).gcptr32) | 75 | #define gcref(r) ((GCobj *)(uintptr_t)(r).gcptr32) |
44 | #define gcrefp(r, t) ((t *)(void *)(uintptr_t)(r).gcptr32) | 76 | #define gcrefp(r, t) ((t *)(void *)(uintptr_t)(r).gcptr32) |
45 | #define gcrefu(r) ((r).gcptr32) | 77 | #define gcrefu(r) ((r).gcptr32) |
46 | #define gcrefeq(r1, r2) ((r1).gcptr32 == (r2).gcptr32) | 78 | #define gcrefeq(r1, r2) ((r1).gcptr32 == (r2).gcptr32) |
47 | #define gcnext(gc) (gcref((gc)->gch.nextgc)) | ||
48 | 79 | ||
49 | #define setgcref(r, gc) ((r).gcptr32 = (uint32_t)(uintptr_t)&(gc)->gch) | 80 | #define setgcref(r, gc) ((r).gcptr32 = (uint32_t)(uintptr_t)&(gc)->gch) |
50 | #define setgcrefp(r, p) ((r).gcptr32 = (uint32_t)(uintptr_t)(p)) | 81 | #define setgcrefp(r, p) ((r).gcptr32 = (uint32_t)(uintptr_t)(p)) |
51 | #define setgcrefnull(r) ((r).gcptr32 = 0) | 82 | #define setgcrefnull(r) ((r).gcptr32 = 0) |
52 | #define setgcrefr(r, v) ((r).gcptr32 = (v).gcptr32) | 83 | #define setgcrefr(r, v) ((r).gcptr32 = (v).gcptr32) |
84 | #endif | ||
85 | |||
86 | #define gcnext(gc) (gcref((gc)->gch.nextgc)) | ||
53 | 87 | ||
54 | /* IMPORTANT NOTE: | 88 | /* IMPORTANT NOTE: |
55 | ** | 89 | ** |
@@ -138,10 +172,16 @@ typedef union { | |||
138 | typedef LJ_ALIGN(8) union TValue { | 172 | typedef LJ_ALIGN(8) union TValue { |
139 | uint64_t u64; /* 64 bit pattern overlaps number. */ | 173 | uint64_t u64; /* 64 bit pattern overlaps number. */ |
140 | lua_Number n; /* Number object overlaps split tag/value object. */ | 174 | lua_Number n; /* Number object overlaps split tag/value object. */ |
175 | #if LJ_GC64 | ||
176 | GCRef gcr; /* GCobj reference with tag. */ | ||
177 | int64_t it64; | ||
178 | #endif | ||
141 | struct { | 179 | struct { |
142 | LJ_ENDIAN_LOHI( | 180 | LJ_ENDIAN_LOHI( |
143 | union { | 181 | union { |
182 | #if !LJ_GC64 | ||
144 | GCRef gcr; /* GCobj reference (if any). */ | 183 | GCRef gcr; /* GCobj reference (if any). */ |
184 | #endif | ||
145 | int32_t i; /* Integer value. */ | 185 | int32_t i; /* Integer value. */ |
146 | }; | 186 | }; |
147 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ | 187 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ |
@@ -176,6 +216,8 @@ typedef const TValue cTValue; | |||
176 | 216 | ||
177 | /* Internal object tags. | 217 | /* Internal object tags. |
178 | ** | 218 | ** |
219 | ** Format for 32 bit GC references (!LJ_GC64): | ||
220 | ** | ||
179 | ** Internal tags overlap the MSW of a number object (must be a double). | 221 | ** Internal tags overlap the MSW of a number object (must be a double). |
180 | ** Interpreted as a double these are special NaNs. The FPU only generates | 222 | ** Interpreted as a double these are special NaNs. The FPU only generates |
181 | ** one type of NaN (0xfff8_0000_0000_0000). So MSWs > 0xfff80000 are available | 223 | ** one type of NaN (0xfff8_0000_0000_0000). So MSWs > 0xfff80000 are available |
@@ -190,6 +232,18 @@ typedef const TValue cTValue; | |||
190 | ** int (LJ_DUALNUM)| itype | int | | 232 | ** int (LJ_DUALNUM)| itype | int | |
191 | ** number -------double------ | 233 | ** number -------double------ |
192 | ** | 234 | ** |
235 | ** Format for 64 bit GC references (LJ_GC64): | ||
236 | ** | ||
237 | ** The upper 13 bits must be 1 (0xfff8...) for a special NaN. The next | ||
238 | ** 4 bits hold the internal tag. The lowest 47 bits either hold a pointer, | ||
239 | ** a zero-extended 32 bit integer or all bits set to 1 for primitive types. | ||
240 | ** | ||
241 | ** ------MSW------.------LSW------ | ||
242 | ** primitive types |1..1|itype|1..................1| | ||
243 | ** GC objects/lightud |1..1|itype|-------GCRef--------| | ||
244 | ** int (LJ_DUALNUM) |1..1|itype|0..0|-----int-------| | ||
245 | ** number ------------double------------- | ||
246 | ** | ||
193 | ** ORDER LJ_T | 247 | ** ORDER LJ_T |
194 | ** Primitive types nil/false/true must be first, lightuserdata next. | 248 | ** Primitive types nil/false/true must be first, lightuserdata next. |
195 | ** GC objects are at the end, table/userdata must be lowest. | 249 | ** GC objects are at the end, table/userdata must be lowest. |
@@ -212,7 +266,7 @@ typedef const TValue cTValue; | |||
212 | #define LJ_TNUMX (~13u) | 266 | #define LJ_TNUMX (~13u) |
213 | 267 | ||
214 | /* Integers have itype == LJ_TISNUM doubles have itype < LJ_TISNUM */ | 268 | /* Integers have itype == LJ_TISNUM doubles have itype < LJ_TISNUM */ |
215 | #if LJ_64 | 269 | #if LJ_64 && !LJ_GC64 |
216 | #define LJ_TISNUM 0xfffeffffu | 270 | #define LJ_TISNUM 0xfffeffffu |
217 | #else | 271 | #else |
218 | #define LJ_TISNUM LJ_TNUMX | 272 | #define LJ_TISNUM LJ_TNUMX |
@@ -222,6 +276,10 @@ typedef const TValue cTValue; | |||
222 | #define LJ_TISGCV (LJ_TSTR+1) | 276 | #define LJ_TISGCV (LJ_TSTR+1) |
223 | #define LJ_TISTABUD LJ_TTAB | 277 | #define LJ_TISTABUD LJ_TTAB |
224 | 278 | ||
279 | #if LJ_GC64 | ||
280 | #define LJ_GCVMASK (((uint64_t)1 << 47) - 1) | ||
281 | #endif | ||
282 | |||
225 | /* -- String object ------------------------------------------------------- */ | 283 | /* -- String object ------------------------------------------------------- */ |
226 | 284 | ||
227 | /* String object header. String payload follows. */ | 285 | /* String object header. String payload follows. */ |
@@ -295,6 +353,9 @@ typedef struct GCproto { | |||
295 | uint8_t numparams; /* Number of parameters. */ | 353 | uint8_t numparams; /* Number of parameters. */ |
296 | uint8_t framesize; /* Fixed frame size. */ | 354 | uint8_t framesize; /* Fixed frame size. */ |
297 | MSize sizebc; /* Number of bytecode instructions. */ | 355 | MSize sizebc; /* Number of bytecode instructions. */ |
356 | #if LJ_GC64 | ||
357 | uint32_t unused_gc64; | ||
358 | #endif | ||
298 | GCRef gclist; | 359 | GCRef gclist; |
299 | MRef k; /* Split constant array (points to the middle). */ | 360 | MRef k; /* Split constant array (points to the middle). */ |
300 | MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */ | 361 | MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */ |
@@ -406,7 +467,9 @@ typedef struct Node { | |||
406 | TValue val; /* Value object. Must be first field. */ | 467 | TValue val; /* Value object. Must be first field. */ |
407 | TValue key; /* Key object. */ | 468 | TValue key; /* Key object. */ |
408 | MRef next; /* Hash chain. */ | 469 | MRef next; /* Hash chain. */ |
470 | #if !LJ_GC64 | ||
409 | MRef freetop; /* Top of free elements (stored in t->node[0]). */ | 471 | MRef freetop; /* Top of free elements (stored in t->node[0]). */ |
472 | #endif | ||
410 | } Node; | 473 | } Node; |
411 | 474 | ||
412 | LJ_STATIC_ASSERT(offsetof(Node, val) == 0); | 475 | LJ_STATIC_ASSERT(offsetof(Node, val) == 0); |
@@ -421,12 +484,22 @@ typedef struct GCtab { | |||
421 | MRef node; /* Hash part. */ | 484 | MRef node; /* Hash part. */ |
422 | uint32_t asize; /* Size of array part (keys [0, asize-1]). */ | 485 | uint32_t asize; /* Size of array part (keys [0, asize-1]). */ |
423 | uint32_t hmask; /* Hash part mask (size of hash part - 1). */ | 486 | uint32_t hmask; /* Hash part mask (size of hash part - 1). */ |
487 | #if LJ_GC64 | ||
488 | MRef freetop; /* Top of free elements. */ | ||
489 | #endif | ||
424 | } GCtab; | 490 | } GCtab; |
425 | 491 | ||
426 | #define sizetabcolo(n) ((n)*sizeof(TValue) + sizeof(GCtab)) | 492 | #define sizetabcolo(n) ((n)*sizeof(TValue) + sizeof(GCtab)) |
427 | #define tabref(r) (&gcref((r))->tab) | 493 | #define tabref(r) (&gcref((r))->tab) |
428 | #define noderef(r) (mref((r), Node)) | 494 | #define noderef(r) (mref((r), Node)) |
429 | #define nextnode(n) (mref((n)->next, Node)) | 495 | #define nextnode(n) (mref((n)->next, Node)) |
496 | #if LJ_GC64 | ||
497 | #define getfreetop(t, n) (noderef((t)->freetop)) | ||
498 | #define setfreetop(t, n, v) (setmref((t)->freetop, (v))) | ||
499 | #else | ||
500 | #define getfreetop(t, n) (noderef((n)->freetop)) | ||
501 | #define setfreetop(t, n, v) (setmref((n)->freetop, (v))) | ||
502 | #endif | ||
430 | 503 | ||
431 | /* -- State objects ------------------------------------------------------- */ | 504 | /* -- State objects ------------------------------------------------------- */ |
432 | 505 | ||
@@ -588,7 +661,9 @@ struct lua_State { | |||
588 | #define registry(L) (&G(L)->registrytv) | 661 | #define registry(L) (&G(L)->registrytv) |
589 | 662 | ||
590 | /* Macros to access the currently executing (Lua) function. */ | 663 | /* Macros to access the currently executing (Lua) function. */ |
591 | #if LJ_FR2 | 664 | #if LJ_GC64 |
665 | #define curr_func(L) (&gcval(L->base-2)->fn) | ||
666 | #elif LJ_FR2 | ||
592 | #define curr_func(L) (&gcref((L->base-2)->gcr)->fn) | 667 | #define curr_func(L) (&gcref((L->base-2)->gcr)->fn) |
593 | #else | 668 | #else |
594 | #define curr_func(L) (&gcref((L->base-1)->fr.func)->fn) | 669 | #define curr_func(L) (&gcref((L->base-1)->fr.func)->fn) |
@@ -656,12 +731,17 @@ typedef union GCobj { | |||
656 | #endif | 731 | #endif |
657 | 732 | ||
658 | /* Macros to test types. */ | 733 | /* Macros to test types. */ |
734 | #if LJ_GC64 | ||
735 | #define itype(o) ((uint32_t)((o)->it64 >> 47)) | ||
736 | #define tvisnil(o) ((o)->it64 == -1) | ||
737 | #else | ||
659 | #define itype(o) ((o)->it) | 738 | #define itype(o) ((o)->it) |
660 | #define tvisnil(o) (itype(o) == LJ_TNIL) | 739 | #define tvisnil(o) (itype(o) == LJ_TNIL) |
740 | #endif | ||
661 | #define tvisfalse(o) (itype(o) == LJ_TFALSE) | 741 | #define tvisfalse(o) (itype(o) == LJ_TFALSE) |
662 | #define tvistrue(o) (itype(o) == LJ_TTRUE) | 742 | #define tvistrue(o) (itype(o) == LJ_TTRUE) |
663 | #define tvisbool(o) (tvisfalse(o) || tvistrue(o)) | 743 | #define tvisbool(o) (tvisfalse(o) || tvistrue(o)) |
664 | #if LJ_64 | 744 | #if LJ_64 && !LJ_GC64 |
665 | #define tvislightud(o) (((int32_t)itype(o) >> 15) == -2) | 745 | #define tvislightud(o) (((int32_t)itype(o) >> 15) == -2) |
666 | #else | 746 | #else |
667 | #define tvislightud(o) (itype(o) == LJ_TLIGHTUD) | 747 | #define tvislightud(o) (itype(o) == LJ_TLIGHTUD) |
@@ -695,7 +775,7 @@ typedef union GCobj { | |||
695 | #define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64) | 775 | #define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64) |
696 | 776 | ||
697 | /* Macros to convert type ids. */ | 777 | /* Macros to convert type ids. */ |
698 | #if LJ_64 | 778 | #if LJ_64 && !LJ_GC64 |
699 | #define itypemap(o) \ | 779 | #define itypemap(o) \ |
700 | (tvisnumber(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o)) | 780 | (tvisnumber(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o)) |
701 | #else | 781 | #else |
@@ -703,8 +783,12 @@ typedef union GCobj { | |||
703 | #endif | 783 | #endif |
704 | 784 | ||
705 | /* Macros to get tagged values. */ | 785 | /* Macros to get tagged values. */ |
786 | #if LJ_GC64 | ||
787 | #define gcval(o) ((GCobj *)(gcrefu((o)->gcr) & LJ_GCVMASK)) | ||
788 | #else | ||
706 | #define gcval(o) (gcref((o)->gcr)) | 789 | #define gcval(o) (gcref((o)->gcr)) |
707 | #define boolV(o) check_exp(tvisbool(o), (LJ_TFALSE - (o)->it)) | 790 | #endif |
791 | #define boolV(o) check_exp(tvisbool(o), (LJ_TFALSE - itype(o))) | ||
708 | #if LJ_64 | 792 | #if LJ_64 |
709 | #define lightudV(o) \ | 793 | #define lightudV(o) \ |
710 | check_exp(tvislightud(o), (void *)((o)->u64 & U64x(00007fff,ffffffff))) | 794 | check_exp(tvislightud(o), (void *)((o)->u64 & U64x(00007fff,ffffffff))) |
@@ -723,14 +807,23 @@ typedef union GCobj { | |||
723 | #define intV(o) check_exp(tvisint(o), (int32_t)(o)->i) | 807 | #define intV(o) check_exp(tvisint(o), (int32_t)(o)->i) |
724 | 808 | ||
725 | /* Macros to set tagged values. */ | 809 | /* Macros to set tagged values. */ |
810 | #if LJ_GC64 | ||
811 | #define setitype(o, i) ((o)->it = ((i) << 15)) | ||
812 | #define setnilV(o) ((o)->it64 = -1) | ||
813 | #define setpriV(o, x) ((o)->it64 = (int64_t)~((uint64_t)~(x)<<47)) | ||
814 | #define setboolV(o, x) ((o)->it64 = (int64_t)~((uint64_t)((x)+1)<<47)) | ||
815 | #else | ||
726 | #define setitype(o, i) ((o)->it = (i)) | 816 | #define setitype(o, i) ((o)->it = (i)) |
727 | #define setnilV(o) ((o)->it = LJ_TNIL) | 817 | #define setnilV(o) ((o)->it = LJ_TNIL) |
728 | #define setboolV(o, x) ((o)->it = LJ_TFALSE-(uint32_t)(x)) | 818 | #define setboolV(o, x) ((o)->it = LJ_TFALSE-(uint32_t)(x)) |
729 | #define setpriV(o, i) (setitype((o), (i))) | 819 | #define setpriV(o, i) (setitype((o), (i))) |
820 | #endif | ||
730 | 821 | ||
731 | static LJ_AINLINE void setlightudV(TValue *o, void *p) | 822 | static LJ_AINLINE void setlightudV(TValue *o, void *p) |
732 | { | 823 | { |
733 | #if LJ_64 | 824 | #if LJ_GC64 |
825 | o->u64 = (uint64_t)p | (((uint64_t)LJ_TLIGHTUD) << 47); | ||
826 | #elif LJ_64 | ||
734 | o->u64 = (uint64_t)p | (((uint64_t)0xffff) << 48); | 827 | o->u64 = (uint64_t)p | (((uint64_t)0xffff) << 48); |
735 | #else | 828 | #else |
736 | setgcrefp(o->gcr, p); setitype(o, LJ_TLIGHTUD); | 829 | setgcrefp(o->gcr, p); setitype(o, LJ_TLIGHTUD); |
@@ -759,7 +852,11 @@ static LJ_AINLINE void setlightudV(TValue *o, void *p) | |||
759 | 852 | ||
760 | static LJ_AINLINE void setgcVraw(TValue *o, GCobj *v, uint32_t itype) | 853 | static LJ_AINLINE void setgcVraw(TValue *o, GCobj *v, uint32_t itype) |
761 | { | 854 | { |
855 | #if LJ_GC64 | ||
856 | setgcreft(o->gcr, v, itype); | ||
857 | #else | ||
762 | setgcref(o->gcr, v); setitype(o, itype); | 858 | setgcref(o->gcr, v); setitype(o, itype); |
859 | #endif | ||
763 | } | 860 | } |
764 | 861 | ||
765 | static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t it) | 862 | static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t it) |
diff --git a/src/lj_snap.c b/src/lj_snap.c index 4bac2d28..abc943b7 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -602,6 +602,7 @@ static void snap_restoreval(jit_State *J, GCtrace *T, ExitState *ex, | |||
602 | } | 602 | } |
603 | if (LJ_UNLIKELY(bloomtest(rfilt, ref))) | 603 | if (LJ_UNLIKELY(bloomtest(rfilt, ref))) |
604 | rs = snap_renameref(T, snapno, ref, rs); | 604 | rs = snap_renameref(T, snapno, ref, rs); |
605 | lua_assert(!LJ_GC64); /* TODO_GC64: handle 64 bit references. */ | ||
605 | if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */ | 606 | if (ra_hasspill(regsp_spill(rs))) { /* Restore from spill slot. */ |
606 | int32_t *sps = &ex->spill[regsp_spill(rs)]; | 607 | int32_t *sps = &ex->spill[regsp_spill(rs)]; |
607 | if (irt_isinteger(t)) { | 608 | if (irt_isinteger(t)) { |
diff --git a/src/lj_state.c b/src/lj_state.c index f7cdb8f3..2b19b747 100644 --- a/src/lj_state.c +++ b/src/lj_state.c | |||
@@ -207,7 +207,9 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) | |||
207 | setnilV(registry(L)); | 207 | setnilV(registry(L)); |
208 | setnilV(&g->nilnode.val); | 208 | setnilV(&g->nilnode.val); |
209 | setnilV(&g->nilnode.key); | 209 | setnilV(&g->nilnode.key); |
210 | #if !LJ_GC64 | ||
210 | setmref(g->nilnode.freetop, &g->nilnode); | 211 | setmref(g->nilnode.freetop, &g->nilnode); |
212 | #endif | ||
211 | lj_buf_init(NULL, &g->tmpbuf); | 213 | lj_buf_init(NULL, &g->tmpbuf); |
212 | g->gc.state = GCSpause; | 214 | g->gc.state = GCSpause; |
213 | setgcref(g->gc.root, obj2gco(L)); | 215 | setgcref(g->gc.root, obj2gco(L)); |
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? */ |