diff options
Diffstat (limited to 'src/lj_obj.h')
-rw-r--r-- | src/lj_obj.h | 194 |
1 files changed, 161 insertions, 33 deletions
diff --git a/src/lj_obj.h b/src/lj_obj.h index 5c3c88fc..7d582949 100644 --- a/src/lj_obj.h +++ b/src/lj_obj.h | |||
@@ -15,42 +15,75 @@ | |||
15 | 15 | ||
16 | /* -- Memory references (32 bit address space) ---------------------------- */ | 16 | /* -- Memory references (32 bit address space) ---------------------------- */ |
17 | 17 | ||
18 | /* Memory size. */ | 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 | ||
23 | typedef uint32_t GCSize; | ||
24 | #endif | ||
20 | 25 | ||
21 | /* Memory reference */ | 26 | /* Memory reference */ |
22 | typedef struct MRef { | 27 | typedef struct MRef { |
28 | #if LJ_GC64 | ||
29 | uint64_t ptr64; /* True 64 bit pointer. */ | ||
30 | #else | ||
23 | uint32_t ptr32; /* Pseudo 32 bit pointer. */ | 31 | uint32_t ptr32; /* Pseudo 32 bit pointer. */ |
32 | #endif | ||
24 | } MRef; | 33 | } MRef; |
25 | 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 | ||
26 | #define mref(r, t) ((t *)(void *)(uintptr_t)(r).ptr32) | 41 | #define mref(r, t) ((t *)(void *)(uintptr_t)(r).ptr32) |
27 | 42 | ||
28 | #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)) |
29 | #define setmrefr(r, v) ((r).ptr32 = (v).ptr32) | 44 | #define setmrefr(r, v) ((r).ptr32 = (v).ptr32) |
45 | #endif | ||
30 | 46 | ||
31 | /* -- GC object references (32 bit address space) ------------------------- */ | 47 | /* -- GC object references (32 bit address space) ------------------------- */ |
32 | 48 | ||
33 | /* GCobj reference */ | 49 | /* GCobj reference */ |
34 | typedef struct GCRef { | 50 | typedef struct GCRef { |
51 | #if LJ_GC64 | ||
52 | uint64_t gcptr64; /* True 64 bit pointer. */ | ||
53 | #else | ||
35 | uint32_t gcptr32; /* Pseudo 32 bit pointer. */ | 54 | uint32_t gcptr32; /* Pseudo 32 bit pointer. */ |
55 | #endif | ||
36 | } GCRef; | 56 | } GCRef; |
37 | 57 | ||
38 | /* Common GC header for all collectable objects. */ | 58 | /* Common GC header for all collectable objects. */ |
39 | #define GCHeader GCRef nextgc; uint8_t marked; uint8_t gct | 59 | #define GCHeader GCRef nextgc; uint8_t marked; uint8_t gct |
40 | /* 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. */ |
41 | 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 | ||
42 | #define gcref(r) ((GCobj *)(uintptr_t)(r).gcptr32) | 75 | #define gcref(r) ((GCobj *)(uintptr_t)(r).gcptr32) |
43 | #define gcrefp(r, t) ((t *)(void *)(uintptr_t)(r).gcptr32) | 76 | #define gcrefp(r, t) ((t *)(void *)(uintptr_t)(r).gcptr32) |
44 | #define gcrefu(r) ((r).gcptr32) | 77 | #define gcrefu(r) ((r).gcptr32) |
45 | #define gcrefi(r) ((int32_t)(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 setgcrefi(r, i) ((r).gcptr32 = (uint32_t)(i)) | ||
51 | #define setgcrefp(r, p) ((r).gcptr32 = (uint32_t)(uintptr_t)(p)) | 81 | #define setgcrefp(r, p) ((r).gcptr32 = (uint32_t)(uintptr_t)(p)) |
52 | #define setgcrefnull(r) ((r).gcptr32 = 0) | 82 | #define setgcrefnull(r) ((r).gcptr32 = 0) |
53 | #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)) | ||
54 | 87 | ||
55 | /* IMPORTANT NOTE: | 88 | /* IMPORTANT NOTE: |
56 | ** | 89 | ** |
@@ -119,11 +152,12 @@ typedef int32_t BCLine; /* Bytecode line number. */ | |||
119 | /* Internal assembler functions. Never call these directly from C. */ | 152 | /* Internal assembler functions. Never call these directly from C. */ |
120 | typedef void (*ASMFunction)(void); | 153 | typedef void (*ASMFunction)(void); |
121 | 154 | ||
122 | /* Resizable string buffer. Need this here, details in lj_str.h. */ | 155 | /* Resizable string buffer. Need this here, details in lj_buf.h. */ |
123 | typedef struct SBuf { | 156 | typedef struct SBuf { |
124 | char *buf; /* String buffer base. */ | 157 | MRef p; /* String buffer pointer. */ |
125 | MSize n; /* String buffer length. */ | 158 | MRef e; /* String buffer end pointer. */ |
126 | MSize sz; /* String buffer size. */ | 159 | MRef b; /* String buffer base. */ |
160 | MRef L; /* lua_State, used for buffer resizing. */ | ||
127 | } SBuf; | 161 | } SBuf; |
128 | 162 | ||
129 | /* -- Tags and values ----------------------------------------------------- */ | 163 | /* -- Tags and values ----------------------------------------------------- */ |
@@ -131,13 +165,23 @@ typedef struct SBuf { | |||
131 | /* Frame link. */ | 165 | /* Frame link. */ |
132 | typedef union { | 166 | typedef union { |
133 | int32_t ftsz; /* Frame type and size of previous frame. */ | 167 | int32_t ftsz; /* Frame type and size of previous frame. */ |
134 | MRef pcr; /* Overlaps PC for Lua frames. */ | 168 | MRef pcr; /* Or PC for Lua frames. */ |
135 | } FrameLink; | 169 | } FrameLink; |
136 | 170 | ||
137 | /* Tagged value. */ | 171 | /* Tagged value. */ |
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 | struct { | ||
179 | LJ_ENDIAN_LOHI( | ||
180 | int32_t i; /* Integer value. */ | ||
181 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ | ||
182 | ) | ||
183 | }; | ||
184 | #else | ||
141 | struct { | 185 | struct { |
142 | LJ_ENDIAN_LOHI( | 186 | LJ_ENDIAN_LOHI( |
143 | union { | 187 | union { |
@@ -147,12 +191,17 @@ typedef LJ_ALIGN(8) union TValue { | |||
147 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ | 191 | , uint32_t it; /* Internal object tag. Must overlap MSW of number. */ |
148 | ) | 192 | ) |
149 | }; | 193 | }; |
194 | #endif | ||
195 | #if LJ_FR2 | ||
196 | int64_t ftsz; /* Frame type and size of previous frame, or PC. */ | ||
197 | #else | ||
150 | struct { | 198 | struct { |
151 | LJ_ENDIAN_LOHI( | 199 | LJ_ENDIAN_LOHI( |
152 | GCRef func; /* Function for next frame (or dummy L). */ | 200 | GCRef func; /* Function for next frame (or dummy L). */ |
153 | , FrameLink tp; /* Link to previous frame. */ | 201 | , FrameLink tp; /* Link to previous frame. */ |
154 | ) | 202 | ) |
155 | } fr; | 203 | } fr; |
204 | #endif | ||
156 | struct { | 205 | struct { |
157 | LJ_ENDIAN_LOHI( | 206 | LJ_ENDIAN_LOHI( |
158 | uint32_t lo; /* Lower 32 bits of number. */ | 207 | uint32_t lo; /* Lower 32 bits of number. */ |
@@ -172,6 +221,8 @@ typedef const TValue cTValue; | |||
172 | 221 | ||
173 | /* Internal object tags. | 222 | /* Internal object tags. |
174 | ** | 223 | ** |
224 | ** Format for 32 bit GC references (!LJ_GC64): | ||
225 | ** | ||
175 | ** Internal tags overlap the MSW of a number object (must be a double). | 226 | ** Internal tags overlap the MSW of a number object (must be a double). |
176 | ** Interpreted as a double these are special NaNs. The FPU only generates | 227 | ** Interpreted as a double these are special NaNs. The FPU only generates |
177 | ** one type of NaN (0xfff8_0000_0000_0000). So MSWs > 0xfff80000 are available | 228 | ** one type of NaN (0xfff8_0000_0000_0000). So MSWs > 0xfff80000 are available |
@@ -186,6 +237,18 @@ typedef const TValue cTValue; | |||
186 | ** int (LJ_DUALNUM)| itype | int | | 237 | ** int (LJ_DUALNUM)| itype | int | |
187 | ** number -------double------ | 238 | ** number -------double------ |
188 | ** | 239 | ** |
240 | ** Format for 64 bit GC references (LJ_GC64): | ||
241 | ** | ||
242 | ** The upper 13 bits must be 1 (0xfff8...) for a special NaN. The next | ||
243 | ** 4 bits hold the internal tag. The lowest 47 bits either hold a pointer, | ||
244 | ** a zero-extended 32 bit integer or all bits set to 1 for primitive types. | ||
245 | ** | ||
246 | ** ------MSW------.------LSW------ | ||
247 | ** primitive types |1..1|itype|1..................1| | ||
248 | ** GC objects/lightud |1..1|itype|-------GCRef--------| | ||
249 | ** int (LJ_DUALNUM) |1..1|itype|0..0|-----int-------| | ||
250 | ** number ------------double------------- | ||
251 | ** | ||
189 | ** ORDER LJ_T | 252 | ** ORDER LJ_T |
190 | ** Primitive types nil/false/true must be first, lightuserdata next. | 253 | ** Primitive types nil/false/true must be first, lightuserdata next. |
191 | ** GC objects are at the end, table/userdata must be lowest. | 254 | ** GC objects are at the end, table/userdata must be lowest. |
@@ -208,7 +271,7 @@ typedef const TValue cTValue; | |||
208 | #define LJ_TNUMX (~13u) | 271 | #define LJ_TNUMX (~13u) |
209 | 272 | ||
210 | /* Integers have itype == LJ_TISNUM doubles have itype < LJ_TISNUM */ | 273 | /* Integers have itype == LJ_TISNUM doubles have itype < LJ_TISNUM */ |
211 | #if LJ_64 | 274 | #if LJ_64 && !LJ_GC64 |
212 | #define LJ_TISNUM 0xfffeffffu | 275 | #define LJ_TISNUM 0xfffeffffu |
213 | #else | 276 | #else |
214 | #define LJ_TISNUM LJ_TNUMX | 277 | #define LJ_TISNUM LJ_TNUMX |
@@ -218,6 +281,10 @@ typedef const TValue cTValue; | |||
218 | #define LJ_TISGCV (LJ_TSTR+1) | 281 | #define LJ_TISGCV (LJ_TSTR+1) |
219 | #define LJ_TISTABUD LJ_TTAB | 282 | #define LJ_TISTABUD LJ_TTAB |
220 | 283 | ||
284 | #if LJ_GC64 | ||
285 | #define LJ_GCVMASK (((uint64_t)1 << 47) - 1) | ||
286 | #endif | ||
287 | |||
221 | /* -- String object ------------------------------------------------------- */ | 288 | /* -- String object ------------------------------------------------------- */ |
222 | 289 | ||
223 | /* String object header. String payload follows. */ | 290 | /* String object header. String payload follows. */ |
@@ -291,6 +358,9 @@ typedef struct GCproto { | |||
291 | uint8_t numparams; /* Number of parameters. */ | 358 | uint8_t numparams; /* Number of parameters. */ |
292 | uint8_t framesize; /* Fixed frame size. */ | 359 | uint8_t framesize; /* Fixed frame size. */ |
293 | MSize sizebc; /* Number of bytecode instructions. */ | 360 | MSize sizebc; /* Number of bytecode instructions. */ |
361 | #if LJ_GC64 | ||
362 | uint32_t unused_gc64; | ||
363 | #endif | ||
294 | GCRef gclist; | 364 | GCRef gclist; |
295 | MRef k; /* Split constant array (points to the middle). */ | 365 | MRef k; /* Split constant array (points to the middle). */ |
296 | MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */ | 366 | MRef uv; /* Upvalue list. local slot|0x8000 or parent uv idx. */ |
@@ -402,7 +472,9 @@ typedef struct Node { | |||
402 | TValue val; /* Value object. Must be first field. */ | 472 | TValue val; /* Value object. Must be first field. */ |
403 | TValue key; /* Key object. */ | 473 | TValue key; /* Key object. */ |
404 | MRef next; /* Hash chain. */ | 474 | MRef next; /* Hash chain. */ |
475 | #if !LJ_GC64 | ||
405 | MRef freetop; /* Top of free elements (stored in t->node[0]). */ | 476 | MRef freetop; /* Top of free elements (stored in t->node[0]). */ |
477 | #endif | ||
406 | } Node; | 478 | } Node; |
407 | 479 | ||
408 | LJ_STATIC_ASSERT(offsetof(Node, val) == 0); | 480 | LJ_STATIC_ASSERT(offsetof(Node, val) == 0); |
@@ -417,12 +489,22 @@ typedef struct GCtab { | |||
417 | MRef node; /* Hash part. */ | 489 | MRef node; /* Hash part. */ |
418 | uint32_t asize; /* Size of array part (keys [0, asize-1]). */ | 490 | uint32_t asize; /* Size of array part (keys [0, asize-1]). */ |
419 | uint32_t hmask; /* Hash part mask (size of hash part - 1). */ | 491 | uint32_t hmask; /* Hash part mask (size of hash part - 1). */ |
492 | #if LJ_GC64 | ||
493 | MRef freetop; /* Top of free elements. */ | ||
494 | #endif | ||
420 | } GCtab; | 495 | } GCtab; |
421 | 496 | ||
422 | #define sizetabcolo(n) ((n)*sizeof(TValue) + sizeof(GCtab)) | 497 | #define sizetabcolo(n) ((n)*sizeof(TValue) + sizeof(GCtab)) |
423 | #define tabref(r) (&gcref((r))->tab) | 498 | #define tabref(r) (&gcref((r))->tab) |
424 | #define noderef(r) (mref((r), Node)) | 499 | #define noderef(r) (mref((r), Node)) |
425 | #define nextnode(n) (mref((n)->next, Node)) | 500 | #define nextnode(n) (mref((n)->next, Node)) |
501 | #if LJ_GC64 | ||
502 | #define getfreetop(t, n) (noderef((t)->freetop)) | ||
503 | #define setfreetop(t, n, v) (setmref((t)->freetop, (v))) | ||
504 | #else | ||
505 | #define getfreetop(t, n) (noderef((n)->freetop)) | ||
506 | #define setfreetop(t, n, v) (setmref((n)->freetop, (v))) | ||
507 | #endif | ||
426 | 508 | ||
427 | /* -- State objects ------------------------------------------------------- */ | 509 | /* -- State objects ------------------------------------------------------- */ |
428 | 510 | ||
@@ -489,8 +571,8 @@ typedef enum { | |||
489 | #define mmname_str(g, mm) (strref((g)->gcroot[GCROOT_MMNAME+(mm)])) | 571 | #define mmname_str(g, mm) (strref((g)->gcroot[GCROOT_MMNAME+(mm)])) |
490 | 572 | ||
491 | typedef struct GCState { | 573 | typedef struct GCState { |
492 | MSize total; /* Memory currently allocated. */ | 574 | GCSize total; /* Memory currently allocated. */ |
493 | MSize threshold; /* Memory threshold. */ | 575 | GCSize threshold; /* Memory threshold. */ |
494 | uint8_t currentwhite; /* Current white color. */ | 576 | uint8_t currentwhite; /* Current white color. */ |
495 | uint8_t state; /* GC state. */ | 577 | uint8_t state; /* GC state. */ |
496 | uint8_t nocdatafin; /* No cdata finalizer called. */ | 578 | uint8_t nocdatafin; /* No cdata finalizer called. */ |
@@ -502,9 +584,9 @@ typedef struct GCState { | |||
502 | GCRef grayagain; /* List of objects for atomic traversal. */ | 584 | GCRef grayagain; /* List of objects for atomic traversal. */ |
503 | GCRef weak; /* List of weak tables (to be cleared). */ | 585 | GCRef weak; /* List of weak tables (to be cleared). */ |
504 | GCRef mmudata; /* List of userdata (to be finalized). */ | 586 | GCRef mmudata; /* List of userdata (to be finalized). */ |
587 | GCSize debt; /* Debt (how much GC is behind schedule). */ | ||
588 | GCSize estimate; /* Estimate of memory actually in use. */ | ||
505 | MSize stepmul; /* Incremental GC step granularity. */ | 589 | MSize stepmul; /* Incremental GC step granularity. */ |
506 | MSize debt; /* Debt (how much GC is behind schedule). */ | ||
507 | MSize estimate; /* Estimate of memory actually in use. */ | ||
508 | MSize pause; /* Pause between successive GC cycles. */ | 590 | MSize pause; /* Pause between successive GC cycles. */ |
509 | } GCState; | 591 | } GCState; |
510 | 592 | ||
@@ -516,8 +598,8 @@ typedef struct global_State { | |||
516 | lua_Alloc allocf; /* Memory allocator. */ | 598 | lua_Alloc allocf; /* Memory allocator. */ |
517 | void *allocd; /* Memory allocator data. */ | 599 | void *allocd; /* Memory allocator data. */ |
518 | GCState gc; /* Garbage collector. */ | 600 | GCState gc; /* Garbage collector. */ |
519 | SBuf tmpbuf; /* Temporary buffer for string concatenation. */ | 601 | volatile int32_t vmstate; /* VM state or current JIT code trace number. */ |
520 | Node nilnode; /* Fallback 1-element hash part (nil key and value). */ | 602 | SBuf tmpbuf; /* Temporary string buffer. */ |
521 | GCstr strempty; /* Empty string. */ | 603 | GCstr strempty; /* Empty string. */ |
522 | uint8_t stremptyz; /* Zero terminator of empty string. */ | 604 | uint8_t stremptyz; /* Zero terminator of empty string. */ |
523 | uint8_t hookmask; /* Hook mask. */ | 605 | uint8_t hookmask; /* Hook mask. */ |
@@ -526,17 +608,17 @@ typedef struct global_State { | |||
526 | GCRef mainthref; /* Link to main thread. */ | 608 | GCRef mainthref; /* Link to main thread. */ |
527 | TValue registrytv; /* Anchor for registry. */ | 609 | TValue registrytv; /* Anchor for registry. */ |
528 | TValue tmptv, tmptv2; /* Temporary TValues. */ | 610 | TValue tmptv, tmptv2; /* Temporary TValues. */ |
611 | Node nilnode; /* Fallback 1-element hash part (nil key and value). */ | ||
529 | GCupval uvhead; /* Head of double-linked list of all open upvalues. */ | 612 | GCupval uvhead; /* Head of double-linked list of all open upvalues. */ |
530 | int32_t hookcount; /* Instruction hook countdown. */ | 613 | int32_t hookcount; /* Instruction hook countdown. */ |
531 | int32_t hookcstart; /* Start count for instruction hook counter. */ | 614 | int32_t hookcstart; /* Start count for instruction hook counter. */ |
532 | lua_Hook hookf; /* Hook function. */ | 615 | lua_Hook hookf; /* Hook function. */ |
533 | lua_CFunction wrapf; /* Wrapper for C function calls. */ | 616 | lua_CFunction wrapf; /* Wrapper for C function calls. */ |
534 | lua_CFunction panic; /* Called as a last resort for errors. */ | 617 | lua_CFunction panic; /* Called as a last resort for errors. */ |
535 | volatile int32_t vmstate; /* VM state or current JIT code trace number. */ | ||
536 | BCIns bc_cfunc_int; /* Bytecode for internal C function calls. */ | 618 | BCIns bc_cfunc_int; /* Bytecode for internal C function calls. */ |
537 | BCIns bc_cfunc_ext; /* Bytecode for external C function calls. */ | 619 | BCIns bc_cfunc_ext; /* Bytecode for external C function calls. */ |
538 | GCRef jit_L; /* Current JIT code lua_State or NULL. */ | 620 | GCRef cur_L; /* Currently executing lua_State. */ |
539 | MRef jit_base; /* Current JIT code L->base. */ | 621 | MRef jit_base; /* Current JIT code L->base or NULL. */ |
540 | MRef ctype_state; /* Pointer to C type state. */ | 622 | MRef ctype_state; /* Pointer to C type state. */ |
541 | GCRef gcroot[GCROOT_MAX]; /* GC roots. */ | 623 | GCRef gcroot[GCROOT_MAX]; /* GC roots. */ |
542 | } global_State; | 624 | } global_State; |
@@ -553,9 +635,11 @@ typedef struct global_State { | |||
553 | #define HOOK_ACTIVE_SHIFT 4 | 635 | #define HOOK_ACTIVE_SHIFT 4 |
554 | #define HOOK_VMEVENT 0x20 | 636 | #define HOOK_VMEVENT 0x20 |
555 | #define HOOK_GC 0x40 | 637 | #define HOOK_GC 0x40 |
638 | #define HOOK_PROFILE 0x80 | ||
556 | #define hook_active(g) ((g)->hookmask & HOOK_ACTIVE) | 639 | #define hook_active(g) ((g)->hookmask & HOOK_ACTIVE) |
557 | #define hook_enter(g) ((g)->hookmask |= HOOK_ACTIVE) | 640 | #define hook_enter(g) ((g)->hookmask |= HOOK_ACTIVE) |
558 | #define hook_entergc(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_GC)) | 641 | #define hook_entergc(g) \ |
642 | ((g)->hookmask = ((g)->hookmask | (HOOK_ACTIVE|HOOK_GC)) & ~HOOK_PROFILE) | ||
559 | #define hook_vmevent(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_VMEVENT)) | 643 | #define hook_vmevent(g) ((g)->hookmask |= (HOOK_ACTIVE|HOOK_VMEVENT)) |
560 | #define hook_leave(g) ((g)->hookmask &= ~HOOK_ACTIVE) | 644 | #define hook_leave(g) ((g)->hookmask &= ~HOOK_ACTIVE) |
561 | #define hook_save(g) ((g)->hookmask & ~HOOK_EVENTMASK) | 645 | #define hook_save(g) ((g)->hookmask & ~HOOK_EVENTMASK) |
@@ -583,7 +667,13 @@ struct lua_State { | |||
583 | #define registry(L) (&G(L)->registrytv) | 667 | #define registry(L) (&G(L)->registrytv) |
584 | 668 | ||
585 | /* Macros to access the currently executing (Lua) function. */ | 669 | /* Macros to access the currently executing (Lua) function. */ |
670 | #if LJ_GC64 | ||
671 | #define curr_func(L) (&gcval(L->base-2)->fn) | ||
672 | #elif LJ_FR2 | ||
673 | #define curr_func(L) (&gcref((L->base-2)->gcr)->fn) | ||
674 | #else | ||
586 | #define curr_func(L) (&gcref((L->base-1)->fr.func)->fn) | 675 | #define curr_func(L) (&gcref((L->base-1)->fr.func)->fn) |
676 | #endif | ||
587 | #define curr_funcisL(L) (isluafunc(curr_func(L))) | 677 | #define curr_funcisL(L) (isluafunc(curr_func(L))) |
588 | #define curr_proto(L) (funcproto(curr_func(L))) | 678 | #define curr_proto(L) (funcproto(curr_func(L))) |
589 | #define curr_topL(L) (L->base + curr_proto(L)->framesize) | 679 | #define curr_topL(L) (L->base + curr_proto(L)->framesize) |
@@ -647,12 +737,17 @@ typedef union GCobj { | |||
647 | #endif | 737 | #endif |
648 | 738 | ||
649 | /* Macros to test types. */ | 739 | /* Macros to test types. */ |
740 | #if LJ_GC64 | ||
741 | #define itype(o) ((uint32_t)((o)->it64 >> 47)) | ||
742 | #define tvisnil(o) ((o)->it64 == -1) | ||
743 | #else | ||
650 | #define itype(o) ((o)->it) | 744 | #define itype(o) ((o)->it) |
651 | #define tvisnil(o) (itype(o) == LJ_TNIL) | 745 | #define tvisnil(o) (itype(o) == LJ_TNIL) |
746 | #endif | ||
652 | #define tvisfalse(o) (itype(o) == LJ_TFALSE) | 747 | #define tvisfalse(o) (itype(o) == LJ_TFALSE) |
653 | #define tvistrue(o) (itype(o) == LJ_TTRUE) | 748 | #define tvistrue(o) (itype(o) == LJ_TTRUE) |
654 | #define tvisbool(o) (tvisfalse(o) || tvistrue(o)) | 749 | #define tvisbool(o) (tvisfalse(o) || tvistrue(o)) |
655 | #if LJ_64 | 750 | #if LJ_64 && !LJ_GC64 |
656 | #define tvislightud(o) (((int32_t)itype(o) >> 15) == -2) | 751 | #define tvislightud(o) (((int32_t)itype(o) >> 15) == -2) |
657 | #else | 752 | #else |
658 | #define tvislightud(o) (itype(o) == LJ_TLIGHTUD) | 753 | #define tvislightud(o) (itype(o) == LJ_TLIGHTUD) |
@@ -686,7 +781,7 @@ typedef union GCobj { | |||
686 | #define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64) | 781 | #define rawnumequal(o1, o2) ((o1)->u64 == (o2)->u64) |
687 | 782 | ||
688 | /* Macros to convert type ids. */ | 783 | /* Macros to convert type ids. */ |
689 | #if LJ_64 | 784 | #if LJ_64 && !LJ_GC64 |
690 | #define itypemap(o) \ | 785 | #define itypemap(o) \ |
691 | (tvisnumber(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o)) | 786 | (tvisnumber(o) ? ~LJ_TNUMX : tvislightud(o) ? ~LJ_TLIGHTUD : ~itype(o)) |
692 | #else | 787 | #else |
@@ -694,8 +789,12 @@ typedef union GCobj { | |||
694 | #endif | 789 | #endif |
695 | 790 | ||
696 | /* Macros to get tagged values. */ | 791 | /* Macros to get tagged values. */ |
792 | #if LJ_GC64 | ||
793 | #define gcval(o) ((GCobj *)(gcrefu((o)->gcr) & LJ_GCVMASK)) | ||
794 | #else | ||
697 | #define gcval(o) (gcref((o)->gcr)) | 795 | #define gcval(o) (gcref((o)->gcr)) |
698 | #define boolV(o) check_exp(tvisbool(o), (LJ_TFALSE - (o)->it)) | 796 | #endif |
797 | #define boolV(o) check_exp(tvisbool(o), (LJ_TFALSE - itype(o))) | ||
699 | #if LJ_64 | 798 | #if LJ_64 |
700 | #define lightudV(o) \ | 799 | #define lightudV(o) \ |
701 | check_exp(tvislightud(o), (void *)((o)->u64 & U64x(00007fff,ffffffff))) | 800 | check_exp(tvislightud(o), (void *)((o)->u64 & U64x(00007fff,ffffffff))) |
@@ -714,13 +813,23 @@ typedef union GCobj { | |||
714 | #define intV(o) check_exp(tvisint(o), (int32_t)(o)->i) | 813 | #define intV(o) check_exp(tvisint(o), (int32_t)(o)->i) |
715 | 814 | ||
716 | /* Macros to set tagged values. */ | 815 | /* Macros to set tagged values. */ |
816 | #if LJ_GC64 | ||
817 | #define setitype(o, i) ((o)->it = ((i) << 15)) | ||
818 | #define setnilV(o) ((o)->it64 = -1) | ||
819 | #define setpriV(o, x) ((o)->it64 = (int64_t)~((uint64_t)~(x)<<47)) | ||
820 | #define setboolV(o, x) ((o)->it64 = (int64_t)~((uint64_t)((x)+1)<<47)) | ||
821 | #else | ||
717 | #define setitype(o, i) ((o)->it = (i)) | 822 | #define setitype(o, i) ((o)->it = (i)) |
718 | #define setnilV(o) ((o)->it = LJ_TNIL) | 823 | #define setnilV(o) ((o)->it = LJ_TNIL) |
719 | #define setboolV(o, x) ((o)->it = LJ_TFALSE-(uint32_t)(x)) | 824 | #define setboolV(o, x) ((o)->it = LJ_TFALSE-(uint32_t)(x)) |
825 | #define setpriV(o, i) (setitype((o), (i))) | ||
826 | #endif | ||
720 | 827 | ||
721 | static LJ_AINLINE void setlightudV(TValue *o, void *p) | 828 | static LJ_AINLINE void setlightudV(TValue *o, void *p) |
722 | { | 829 | { |
723 | #if LJ_64 | 830 | #if LJ_GC64 |
831 | o->u64 = (uint64_t)p | (((uint64_t)LJ_TLIGHTUD) << 47); | ||
832 | #elif LJ_64 | ||
724 | o->u64 = (uint64_t)p | (((uint64_t)0xffff) << 48); | 833 | o->u64 = (uint64_t)p | (((uint64_t)0xffff) << 48); |
725 | #else | 834 | #else |
726 | setgcrefp(o->gcr, p); setitype(o, LJ_TLIGHTUD); | 835 | setgcrefp(o->gcr, p); setitype(o, LJ_TLIGHTUD); |
@@ -730,20 +839,39 @@ static LJ_AINLINE void setlightudV(TValue *o, void *p) | |||
730 | #if LJ_64 | 839 | #if LJ_64 |
731 | #define checklightudptr(L, p) \ | 840 | #define checklightudptr(L, p) \ |
732 | (((uint64_t)(p) >> 47) ? (lj_err_msg(L, LJ_ERR_BADLU), NULL) : (p)) | 841 | (((uint64_t)(p) >> 47) ? (lj_err_msg(L, LJ_ERR_BADLU), NULL) : (p)) |
842 | #else | ||
843 | #define checklightudptr(L, p) (p) | ||
844 | #endif | ||
845 | |||
846 | #if LJ_FR2 | ||
847 | #define contptr(f) ((void *)(f)) | ||
848 | #define setcont(o, f) ((o)->u64 = (uint64_t)(uintptr_t)contptr(f)) | ||
849 | #elif LJ_64 | ||
850 | #define contptr(f) \ | ||
851 | ((void *)(uintptr_t)(uint32_t)((intptr_t)(f) - (intptr_t)lj_vm_asm_begin)) | ||
733 | #define setcont(o, f) \ | 852 | #define setcont(o, f) \ |
734 | ((o)->u64 = (uint64_t)(void *)(f) - (uint64_t)lj_vm_asm_begin) | 853 | ((o)->u64 = (uint64_t)(void *)(f) - (uint64_t)lj_vm_asm_begin) |
735 | #else | 854 | #else |
736 | #define checklightudptr(L, p) (p) | 855 | #define contptr(f) ((void *)(f)) |
737 | #define setcont(o, f) setlightudV((o), (void *)(f)) | 856 | #define setcont(o, f) setlightudV((o), contptr(f)) |
738 | #endif | 857 | #endif |
739 | 858 | ||
740 | #define tvchecklive(L, o) \ | 859 | #define tvchecklive(L, o) \ |
741 | UNUSED(L), lua_assert(!tvisgcv(o) || \ | 860 | UNUSED(L), lua_assert(!tvisgcv(o) || \ |
742 | ((~itype(o) == gcval(o)->gch.gct) && !isdead(G(L), gcval(o)))) | 861 | ((~itype(o) == gcval(o)->gch.gct) && !isdead(G(L), gcval(o)))) |
743 | 862 | ||
744 | static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t itype) | 863 | static LJ_AINLINE void setgcVraw(TValue *o, GCobj *v, uint32_t itype) |
745 | { | 864 | { |
746 | setgcref(o->gcr, v); setitype(o, itype); tvchecklive(L, o); | 865 | #if LJ_GC64 |
866 | setgcreft(o->gcr, v, itype); | ||
867 | #else | ||
868 | setgcref(o->gcr, v); setitype(o, itype); | ||
869 | #endif | ||
870 | } | ||
871 | |||
872 | static LJ_AINLINE void setgcV(lua_State *L, TValue *o, GCobj *v, uint32_t it) | ||
873 | { | ||
874 | setgcVraw(o, v, it); tvchecklive(L, o); | ||
747 | } | 875 | } |
748 | 876 | ||
749 | #define define_setV(name, type, tag) \ | 877 | #define define_setV(name, type, tag) \ |
@@ -797,6 +925,9 @@ static LJ_AINLINE void copyTV(lua_State *L, TValue *o1, const TValue *o2) | |||
797 | 925 | ||
798 | #if LJ_SOFTFP | 926 | #if LJ_SOFTFP |
799 | LJ_ASMF int32_t lj_vm_tobit(double x); | 927 | LJ_ASMF int32_t lj_vm_tobit(double x); |
928 | #if LJ_TARGET_MIPS64 | ||
929 | LJ_ASMF int32_t lj_vm_tointg(double x); | ||
930 | #endif | ||
800 | #endif | 931 | #endif |
801 | 932 | ||
802 | static LJ_AINLINE int32_t lj_num2bit(lua_Number n) | 933 | static LJ_AINLINE int32_t lj_num2bit(lua_Number n) |
@@ -810,11 +941,7 @@ static LJ_AINLINE int32_t lj_num2bit(lua_Number n) | |||
810 | #endif | 941 | #endif |
811 | } | 942 | } |
812 | 943 | ||
813 | #if LJ_TARGET_X86 && !defined(__SSE2__) | ||
814 | #define lj_num2int(n) lj_num2bit((n)) | ||
815 | #else | ||
816 | #define lj_num2int(n) ((int32_t)(n)) | 944 | #define lj_num2int(n) ((int32_t)(n)) |
817 | #endif | ||
818 | 945 | ||
819 | /* | 946 | /* |
820 | ** This must match the JIT backend behavior. In particular for archs | 947 | ** This must match the JIT backend behavior. In particular for archs |
@@ -859,6 +986,7 @@ LJ_DATA const char *const lj_obj_itypename[~LJ_TNUMX+1]; | |||
859 | #define lj_typename(o) (lj_obj_itypename[itypemap(o)]) | 986 | #define lj_typename(o) (lj_obj_itypename[itypemap(o)]) |
860 | 987 | ||
861 | /* Compare two objects without calling metamethods. */ | 988 | /* Compare two objects without calling metamethods. */ |
862 | LJ_FUNC int lj_obj_equal(cTValue *o1, cTValue *o2); | 989 | LJ_FUNC int LJ_FASTCALL lj_obj_equal(cTValue *o1, cTValue *o2); |
990 | LJ_FUNC const void * LJ_FASTCALL lj_obj_ptr(cTValue *o); | ||
863 | 991 | ||
864 | #endif | 992 | #endif |