aboutsummaryrefslogtreecommitdiff
path: root/src/lj_obj.h
diff options
context:
space:
mode:
authorMike Pall <mike>2015-01-03 15:23:58 +0100
committerMike Pall <mike>2015-01-03 15:23:58 +0100
commitcb481ddc8f9d92913ba07d998f4274bbf9711077 (patch)
tree852ffb4dd7c3cfdcf5c1ca6ae1531e5f9436d064 /src/lj_obj.h
parent054e6abe37450344e20b373ec326055071029e9b (diff)
downloadluajit-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_obj.h')
-rw-r--r--src/lj_obj.h111
1 files changed, 104 insertions, 7 deletions
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. */
19typedef uint32_t MSize; 19typedef uint32_t MSize;
20#if LJ_GC64
21typedef uint64_t GCSize;
22#else
20typedef uint32_t GCSize; 23typedef uint32_t GCSize;
24#endif
21 25
22/* Memory reference */ 26/* Memory reference */
23typedef struct MRef { 27typedef 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 */
35typedef struct GCRef { 50typedef 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 {
138typedef LJ_ALIGN(8) union TValue { 172typedef 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
412LJ_STATIC_ASSERT(offsetof(Node, val) == 0); 475LJ_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
731static LJ_AINLINE void setlightudV(TValue *o, void *p) 822static 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
760static LJ_AINLINE void setgcVraw(TValue *o, GCobj *v, uint32_t itype) 853static 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
765static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t it) 862static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t it)