diff options
author | Mike Pall <mike> | 2010-01-27 02:17:56 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-01-27 02:17:56 +0100 |
commit | d216cdb2b9eb41879cdfc327486d805cc260d8fa (patch) | |
tree | f65d1dd7a2c63b74aded66b0a99d5ea703217dad | |
parent | 05d67cf5660323ef139858b586977c7709ff8a4c (diff) | |
download | luajit-d216cdb2b9eb41879cdfc327486d805cc260d8fa.tar.gz luajit-d216cdb2b9eb41879cdfc327486d805cc260d8fa.tar.bz2 luajit-d216cdb2b9eb41879cdfc327486d805cc260d8fa.zip |
Add frame and continuation flags to TRef and SnapEntry.
-rw-r--r-- | src/lj_asm.c | 34 | ||||
-rw-r--r-- | src/lj_ir.h | 25 | ||||
-rw-r--r-- | src/lj_jit.h | 11 | ||||
-rw-r--r-- | src/lj_record.c | 13 | ||||
-rw-r--r-- | src/lj_snap.c | 13 |
5 files changed, 57 insertions, 39 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index b3656e00..3912bbeb 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -2467,14 +2467,15 @@ static void asm_gc_sync(ASMState *as, SnapShot *snap, Reg base) | |||
2467 | SnapEntry *map = &as->T->snapmap[snap->mapofs]; | 2467 | SnapEntry *map = &as->T->snapmap[snap->mapofs]; |
2468 | MSize n, nent = snap->nent; | 2468 | MSize n, nent = snap->nent; |
2469 | for (n = 0; n < nent; n++) { | 2469 | for (n = 0; n < nent; n++) { |
2470 | IRRef ref = snap_ref(map[n]); | 2470 | SnapEntry sn = map[n]; |
2471 | IRRef ref = snap_ref(sn); | ||
2472 | /* NYI: sync the frame, bump base, set topslot, clear new slots. */ | ||
2473 | if ((sn & (SNAP_CONT|SNAP_FRAME))) | ||
2474 | lj_trace_err(as->J, LJ_TRERR_NYIGCF); | ||
2471 | if (!irref_isk(ref)) { | 2475 | if (!irref_isk(ref)) { |
2472 | int32_t ofs = 8*(int32_t)(snap_slot(map[n])-1); | ||
2473 | IRIns *ir = IR(ref); | 2476 | IRIns *ir = IR(ref); |
2474 | if (ir->o == IR_FRAME) { | 2477 | if (irt_isgcv(ir->t)) { |
2475 | /* NYI: sync the frame, bump base, set topslot, clear new slots. */ | 2478 | int32_t ofs = 8*(int32_t)(snap_slot(sn)-1); |
2476 | lj_trace_err(as->J, LJ_TRERR_NYIGCF); | ||
2477 | } else if (irt_isgcv(ir->t)) { | ||
2478 | Reg src = ra_alloc1(as, ref, allow); | 2479 | Reg src = ra_alloc1(as, ref, allow); |
2479 | emit_movtomro(as, src, base, ofs); | 2480 | emit_movtomro(as, src, base, ofs); |
2480 | emit_movmroi(as, base, ofs+4, irt_toitype(ir->t)); | 2481 | emit_movmroi(as, base, ofs+4, irt_toitype(ir->t)); |
@@ -2975,17 +2976,16 @@ static void asm_tail_sync(ASMState *as) | |||
2975 | 2976 | ||
2976 | /* Must check all frames to find topslot (outer can be larger than inner). */ | 2977 | /* Must check all frames to find topslot (outer can be larger than inner). */ |
2977 | for (n = 0; n < nent; n++) { | 2978 | for (n = 0; n < nent; n++) { |
2978 | IRRef ref = snap_ref(map[n]); | 2979 | SnapEntry sn = map[n]; |
2979 | BCReg s = snap_slot(map[n]); | 2980 | if ((sn & SNAP_FRAME)) { |
2980 | if (!irref_isk(ref)) { | 2981 | IRIns *ir = IR(snap_ref(sn)); |
2981 | IRIns *ir = IR(ref); | 2982 | GCfunc *fn = ir_kfunc(IR(ir->op2)); |
2982 | if (ir->o == IR_FRAME && irt_isfunc(ir->t)) { | 2983 | lua_assert(ir->o == IR_FRAME && irt_isfunc(ir->t)); |
2983 | GCfunc *fn = ir_kfunc(IR(ir->op2)); | 2984 | if (isluafunc(fn)) { |
2984 | if (isluafunc(fn)) { | 2985 | BCReg s = snap_slot(sn); |
2985 | BCReg fs = s + funcproto(fn)->framesize; | 2986 | BCReg fs = s + funcproto(fn)->framesize; |
2986 | if (fs > topslot) topslot = fs; | 2987 | if (fs > topslot) topslot = fs; |
2987 | newbase = s; | 2988 | newbase = s; |
2988 | } | ||
2989 | } | 2989 | } |
2990 | } | 2990 | } |
2991 | } | 2991 | } |
diff --git a/src/lj_ir.h b/src/lj_ir.h index efc8205e..672aca4a 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
@@ -422,18 +422,29 @@ enum { | |||
422 | 422 | ||
423 | #define irref_isk(ref) ((ref) < REF_BIAS) | 423 | #define irref_isk(ref) ((ref) < REF_BIAS) |
424 | 424 | ||
425 | /* Tagged IR references. */ | 425 | /* Tagged IR references (32 bit). |
426 | ** | ||
427 | ** +-------+-------+---------------+ | ||
428 | ** | irt | flags | ref | | ||
429 | ** +-------+-------+---------------+ | ||
430 | ** | ||
431 | ** The tag holds a copy of the IRType and speeds up IR type checks. | ||
432 | */ | ||
426 | typedef uint32_t TRef; | 433 | typedef uint32_t TRef; |
427 | 434 | ||
428 | #define TREF(ref, t) (cast(TRef, (ref) + ((t)<<16))) | 435 | #define TREF_REFMASK 0x0000ffff |
436 | #define TREF_FRAME 0x00010000 | ||
437 | #define TREF_CONT 0x00020000 | ||
438 | |||
439 | #define TREF(ref, t) ((TRef)((ref) + ((t)<<24))) | ||
429 | 440 | ||
430 | #define tref_ref(tr) (cast(IRRef1, (tr))) | 441 | #define tref_ref(tr) ((IRRef1)(tr)) |
431 | #define tref_t(tr) (cast(IRType, (tr)>>16)) | 442 | #define tref_t(tr) ((IRType)((tr)>>24)) |
432 | #define tref_type(tr) (cast(IRType, ((tr)>>16) & IRT_TYPE)) | 443 | #define tref_type(tr) ((IRType)(((tr)>>24) & IRT_TYPE)) |
433 | #define tref_typerange(tr, first, last) \ | 444 | #define tref_typerange(tr, first, last) \ |
434 | ((((tr)>>16) & IRT_TYPE) - (TRef)(first) <= (TRef)(last-first)) | 445 | ((((tr)>>24) & IRT_TYPE) - (TRef)(first) <= (TRef)(last-first)) |
435 | 446 | ||
436 | #define tref_istype(tr, t) (((tr) & (IRT_TYPE<<16)) == ((t)<<16)) | 447 | #define tref_istype(tr, t) (((tr) & (IRT_TYPE<<24)) == ((t)<<24)) |
437 | #define tref_isnil(tr) (tref_istype((tr), IRT_NIL)) | 448 | #define tref_isnil(tr) (tref_istype((tr), IRT_NIL)) |
438 | #define tref_isfalse(tr) (tref_istype((tr), IRT_FALSE)) | 449 | #define tref_isfalse(tr) (tref_istype((tr), IRT_FALSE)) |
439 | #define tref_istrue(tr) (tref_istype((tr), IRT_TRUE)) | 450 | #define tref_istrue(tr) (tref_istype((tr), IRT_TRUE)) |
diff --git a/src/lj_jit.h b/src/lj_jit.h index 1a1e407a..35595cd5 100644 --- a/src/lj_jit.h +++ b/src/lj_jit.h | |||
@@ -123,9 +123,14 @@ typedef struct SnapShot { | |||
123 | /* Compressed snapshot entry. */ | 123 | /* Compressed snapshot entry. */ |
124 | typedef uint32_t SnapEntry; | 124 | typedef uint32_t SnapEntry; |
125 | 125 | ||
126 | #define SNAP_FRAME 0x010000 /* Slot has frame link. */ | 126 | #define SNAP_FRAME 0x010000 /* Frame slot. */ |
127 | 127 | #define SNAP_CONT 0x020000 /* Continuation slot. */ | |
128 | #define SNAP(slot, flags, ref) ((SnapEntry)((slot) << 24) + (flags) + (ref)) | 128 | LJ_STATIC_ASSERT(SNAP_FRAME == TREF_FRAME); |
129 | LJ_STATIC_ASSERT(SNAP_CONT == TREF_CONT); | ||
130 | |||
131 | #define SNAP(slot, flags, ref) (((SnapEntry)(slot) << 24) + (flags) + (ref)) | ||
132 | #define SNAP_TR(slot, tr) \ | ||
133 | (((SnapEntry)(slot) << 24) + ((tr) & (TREF_CONT|TREF_FRAME|TREF_REFMASK))) | ||
129 | #define SNAP_MKPC(pc) ((SnapEntry)u32ptr(pc)) | 134 | #define SNAP_MKPC(pc) ((SnapEntry)u32ptr(pc)) |
130 | #define SNAP_MKFTSZ(ftsz) ((SnapEntry)(ftsz)) | 135 | #define SNAP_MKFTSZ(ftsz) ((SnapEntry)(ftsz)) |
131 | #define snap_ref(sn) ((sn) & 0xffff) | 136 | #define snap_ref(sn) ((sn) & 0xffff) |
diff --git a/src/lj_record.c b/src/lj_record.c index c14a9e86..94ea42ed 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -424,7 +424,7 @@ static BCReg rec_mm_prep(jit_State *J, ASMFunction cont) | |||
424 | #else | 424 | #else |
425 | trcont = lj_ir_kptr(J, (void *)cont); | 425 | trcont = lj_ir_kptr(J, (void *)cont); |
426 | #endif | 426 | #endif |
427 | J->base[top] = emitir(IRTG(IR_FRAME, IRT_PTR), trcont, trcont); | 427 | J->base[top] = emitir(IRTG(IR_FRAME, IRT_PTR), trcont, trcont) | TREF_CONT; |
428 | for (s = J->maxslot; s < top; s++) | 428 | for (s = J->maxslot; s < top; s++) |
429 | J->base[s] = TREF_NIL; | 429 | J->base[s] = TREF_NIL; |
430 | return top+1; | 430 | return top+1; |
@@ -1608,7 +1608,7 @@ static int rec_call(jit_State *J, BCReg func, int cres, int nargs) | |||
1608 | } | 1608 | } |
1609 | 1609 | ||
1610 | /* Specialize to the runtime value of the called function. */ | 1610 | /* Specialize to the runtime value of the called function. */ |
1611 | res[0] = emitir(IRTG(IR_FRAME, IRT_FUNC), res[0], lj_ir_kfunc(J, rd.fn)); | 1611 | res[0] = emitir(IRTG(IR_FRAME, IRT_FUNC), res[0], lj_ir_kfunc(J, rd.fn)) | TREF_FRAME; |
1612 | 1612 | ||
1613 | if (isluafunc(rd.fn)) { /* Record call to Lua function. */ | 1613 | if (isluafunc(rd.fn)) { /* Record call to Lua function. */ |
1614 | GCproto *pt = funcproto(rd.fn); | 1614 | GCproto *pt = funcproto(rd.fn); |
@@ -2164,8 +2164,9 @@ static void rec_setup_side(jit_State *J, Trace *T) | |||
2164 | BloomFilter seen = 0; | 2164 | BloomFilter seen = 0; |
2165 | /* Emit IR for slots inherited from parent snapshot. */ | 2165 | /* Emit IR for slots inherited from parent snapshot. */ |
2166 | for (n = 0; n < nent; n++) { | 2166 | for (n = 0; n < nent; n++) { |
2167 | IRRef ref = snap_ref(map[n]); | 2167 | SnapEntry sn = map[n]; |
2168 | BCReg s = snap_slot(map[n]); | 2168 | IRRef ref = snap_ref(sn); |
2169 | BCReg s = snap_slot(sn); | ||
2169 | IRIns *ir = &T->ir[ref]; | 2170 | IRIns *ir = &T->ir[ref]; |
2170 | TRef tr; | 2171 | TRef tr; |
2171 | /* The bloom filter avoids O(nent^2) overhead for de-duping slots. */ | 2172 | /* The bloom filter avoids O(nent^2) overhead for de-duping slots. */ |
@@ -2196,10 +2197,10 @@ static void rec_setup_side(jit_State *J, Trace *T) | |||
2196 | J->framedepth++; | 2197 | J->framedepth++; |
2197 | } | 2198 | } |
2198 | tr = lj_ir_kfunc(J, ir_kfunc(&T->ir[ir->op2])); | 2199 | tr = lj_ir_kfunc(J, ir_kfunc(&T->ir[ir->op2])); |
2199 | tr = emitir_raw(IRT(IR_FRAME, IRT_FUNC), tr, tr); | 2200 | tr = emitir_raw(IRT(IR_FRAME, IRT_FUNC), tr, tr) | TREF_FRAME; |
2200 | } else { | 2201 | } else { |
2201 | tr = lj_ir_kptr(J, mref(T->ir[ir->op2].ptr, void)); | 2202 | tr = lj_ir_kptr(J, mref(T->ir[ir->op2].ptr, void)); |
2202 | tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr); | 2203 | tr = emitir_raw(IRT(IR_FRAME, IRT_PTR), tr, tr) | TREF_CONT; |
2203 | } | 2204 | } |
2204 | break; | 2205 | break; |
2205 | case IR_SLOAD: /* Inherited SLOADs don't need a guard or type check. */ | 2206 | case IR_SLOAD: /* Inherited SLOADs don't need a guard or type check. */ |
diff --git a/src/lj_snap.c b/src/lj_snap.c index d22c90a4..731b8f92 100644 --- a/src/lj_snap.c +++ b/src/lj_snap.c | |||
@@ -50,20 +50,19 @@ void lj_snap_grow_map_(jit_State *J, MSize need) | |||
50 | 50 | ||
51 | /* -- Snapshot generation ------------------------------------------------- */ | 51 | /* -- Snapshot generation ------------------------------------------------- */ |
52 | 52 | ||
53 | /* NYI: IR_FRAME should be eliminated, too. */ | ||
54 | |||
55 | /* Add all modified slots to the snapshot. */ | 53 | /* Add all modified slots to the snapshot. */ |
56 | static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) | 54 | static MSize snapshot_slots(jit_State *J, SnapEntry *map, BCReg nslots) |
57 | { | 55 | { |
58 | BCReg s; | 56 | BCReg s; |
59 | MSize n = 0; | 57 | MSize n = 0; |
60 | for (s = 0; s < nslots; s++) { | 58 | for (s = 0; s < nslots; s++) { |
61 | IRRef ref = tref_ref(J->slot[s]); | 59 | TRef tr = J->slot[s]; |
60 | IRRef ref = tref_ref(tr); | ||
62 | if (ref) { | 61 | if (ref) { |
63 | IRIns *ir = IR(ref); | 62 | IRIns *ir = IR(ref); |
64 | if (!(ir->o == IR_SLOAD && ir->op1 == s && | 63 | if (!(ir->o == IR_SLOAD && ir->op1 == s && |
65 | !(ir->op2 & IRSLOAD_INHERIT))) | 64 | !(ir->op2 & IRSLOAD_INHERIT))) |
66 | map[n++] = SNAP(s, ir->o == IR_FRAME ? SNAP_FRAME : 0, ref); | 65 | map[n++] = SNAP_TR(s, tr); |
67 | } | 66 | } |
68 | } | 67 | } |
69 | return n; | 68 | return n; |
@@ -226,8 +225,9 @@ void lj_snap_restore(jit_State *J, void *exptr) | |||
226 | /* Fill stack slots with data from the registers and spill slots. */ | 225 | /* Fill stack slots with data from the registers and spill slots. */ |
227 | frame = L->base-1; | 226 | frame = L->base-1; |
228 | for (n = 0; n < nent; n++) { | 227 | for (n = 0; n < nent; n++) { |
229 | IRRef ref = snap_ref(map[n]); | 228 | SnapEntry sn = map[n]; |
230 | BCReg s = snap_slot(map[n]); | 229 | IRRef ref = snap_ref(sn); |
230 | BCReg s = snap_slot(sn); | ||
231 | TValue *o = &frame[s]; /* Stack slots are relative to start frame. */ | 231 | TValue *o = &frame[s]; /* Stack slots are relative to start frame. */ |
232 | IRIns *ir = &T->ir[ref]; | 232 | IRIns *ir = &T->ir[ref]; |
233 | if (irref_isk(ref)) { /* Restore constant slot. */ | 233 | if (irref_isk(ref)) { /* Restore constant slot. */ |
@@ -260,6 +260,7 @@ void lj_snap_restore(jit_State *J, void *exptr) | |||
260 | setitype(o, irt_toitype(t)); | 260 | setitype(o, irt_toitype(t)); |
261 | } | 261 | } |
262 | } else { /* Restore frame slot. */ | 262 | } else { /* Restore frame slot. */ |
263 | lua_assert((sn & (SNAP_CONT|SNAP_FRAME))); | ||
263 | lua_assert(ir->o == IR_FRAME); | 264 | lua_assert(ir->o == IR_FRAME); |
264 | /* This works for both PTR and FUNC IR_FRAME. */ | 265 | /* This works for both PTR and FUNC IR_FRAME. */ |
265 | setgcrefp(o->fr.func, mref(T->ir[ir->op2].ptr, void)); | 266 | setgcrefp(o->fr.func, mref(T->ir[ir->op2].ptr, void)); |