diff options
author | Mike Pall <mike> | 2010-12-11 19:32:12 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-12-11 19:32:12 +0100 |
commit | cdac0fa2cbd3f610159330bd8c5a36ea53b631d7 (patch) | |
tree | 65ecf2ae232bd96802d9f912c8f3cf084410cc3a /src | |
parent | 6947493687f15731b282f3f648fe97c43ce80bb9 (diff) | |
download | luajit-cdac0fa2cbd3f610159330bd8c5a36ea53b631d7.tar.gz luajit-cdac0fa2cbd3f610159330bd8c5a36ea53b631d7.tar.bz2 luajit-cdac0fa2cbd3f610159330bd8c5a36ea53b631d7.zip |
FFI: Add IR_CNEW/IR_CNEWI to allocate/init cdata objects.
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_asm.c | 91 | ||||
-rw-r--r-- | src/lj_crecord.c | 9 | ||||
-rw-r--r-- | src/lj_ir.h | 10 | ||||
-rw-r--r-- | src/lj_opt_fold.c | 35 |
4 files changed, 136 insertions, 9 deletions
diff --git a/src/lj_asm.c b/src/lj_asm.c index 3d4060b2..215dfb13 100644 --- a/src/lj_asm.c +++ b/src/lj_asm.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include "lj_str.h" | 14 | #include "lj_str.h" |
15 | #include "lj_tab.h" | 15 | #include "lj_tab.h" |
16 | #include "lj_frame.h" | 16 | #include "lj_frame.h" |
17 | #if LJ_HASFFI | ||
18 | #include "lj_ctype.h" | ||
19 | #endif | ||
17 | #include "lj_ir.h" | 20 | #include "lj_ir.h" |
18 | #include "lj_jit.h" | 21 | #include "lj_jit.h" |
19 | #include "lj_iropt.h" | 22 | #include "lj_iropt.h" |
@@ -2279,6 +2282,91 @@ static void asm_tdup(ASMState *as, IRIns *ir) | |||
2279 | asm_gencall(as, ci, args); | 2282 | asm_gencall(as, ci, args); |
2280 | } | 2283 | } |
2281 | 2284 | ||
2285 | #if LJ_HASFFI | ||
2286 | static RegSet asm_cnew_init(ASMState *as, IRRef ref, int32_t ofs, RegSet allow) | ||
2287 | { | ||
2288 | IRIns *ir = IR(ref); | ||
2289 | if (irref_isk(ref)) { | ||
2290 | #if LJ_64 | ||
2291 | if (ir->o == IR_KNUM || ir->o == IR_KINT64) { | ||
2292 | uint64_t k = ir_k64(ir)->u64; | ||
2293 | if (checki32((int64_t)k)) { | ||
2294 | emit_i32(as, (int32_t)k); | ||
2295 | emit_rmro(as, XO_MOVmi, REX_64, RID_RET, ofs); | ||
2296 | } else { | ||
2297 | emit_movtomro(as, RID_ECX|REX_64, RID_RET, ofs); | ||
2298 | emit_loadu64(as, RID_ECX, k); | ||
2299 | } | ||
2300 | } else { | ||
2301 | emit_movmroi(as, RID_RET, ofs, ir->i); | ||
2302 | } | ||
2303 | #else | ||
2304 | if (ir->o == IR_KNUM) { | ||
2305 | emit_rmro(as, XO_MOVSDto, RID_XMM0, RID_RET, ofs); | ||
2306 | emit_loadn(as, RID_XMM0, ir_k64(ir)); | ||
2307 | } else if (ir->o == IR_KINT64) { | ||
2308 | uint64_t k = ir_k64(ir)->u64; | ||
2309 | emit_movmroi(as, RID_RET, ofs, (int32_t)k); | ||
2310 | emit_movmroi(as, RID_RET, ofs+4, (int32_t)(k >> 32)); | ||
2311 | } else { | ||
2312 | emit_movmroi(as, RID_RET, ofs, ir->i); | ||
2313 | } | ||
2314 | #endif | ||
2315 | } else { | ||
2316 | Reg r; | ||
2317 | if (irt_isnum(ir->t)) { | ||
2318 | r = ra_alloc1(as, ref, (RSET_FPR & allow)); | ||
2319 | emit_rmro(as, XO_MOVSDto, r, RID_RET, ofs); | ||
2320 | } else { | ||
2321 | r = ra_alloc1(as, ref, (RSET_GPR & allow)); | ||
2322 | emit_movtomro(as, REX_64IR(ir, r), RID_RET, ofs); | ||
2323 | } | ||
2324 | rset_clear(allow, r); | ||
2325 | } | ||
2326 | return allow; | ||
2327 | } | ||
2328 | |||
2329 | static void asm_cnew(ASMState *as, IRIns *ir) | ||
2330 | { | ||
2331 | CTState *cts = ctype_ctsG(J2G(as->J)); | ||
2332 | CTypeID typeid = (CTypeID)IR(ir->op2)->i; | ||
2333 | CTSize sz = (ir->o == IR_CNEWI || ir->op1 == REF_NIL) ? | ||
2334 | lj_ctype_size(cts, typeid) : (CTSize)IR(ir->op1)->i; | ||
2335 | const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco]; | ||
2336 | IRRef args[2]; | ||
2337 | lua_assert(sz != CTSIZE_INVALID); | ||
2338 | |||
2339 | args[0] = ASMREF_L; /* lua_State *L */ | ||
2340 | args[1] = ASMREF_TMP1; /* MSize size */ | ||
2341 | as->gcsteps++; | ||
2342 | asm_setupresult(as, ir, ci); /* GCobj * */ | ||
2343 | |||
2344 | /* Initialize immutable cdata object. */ | ||
2345 | if (ir->o == IR_CNEWI) { | ||
2346 | RegSet allow = ~RSET_SCRATCH; | ||
2347 | IRRef ref = ir->op1; | ||
2348 | if (IR(ref)->o == IR_CARG) { /* 2nd initializer. */ | ||
2349 | IRIns *ira = IR(ref); | ||
2350 | allow = asm_cnew_init(as, ira->op2, sizeof(GCcdata) + (sz>>1), allow); | ||
2351 | ref = ira->op1; | ||
2352 | } | ||
2353 | asm_cnew_init(as, ref, sizeof(GCcdata), allow); /* 1st initializer. */ | ||
2354 | } | ||
2355 | |||
2356 | /* Combine initialization of marked, gct and typeid. */ | ||
2357 | emit_movtomro(as, RID_ECX, RID_RET, offsetof(GCcdata, marked)); | ||
2358 | emit_gri(as, XG_ARITHi(XOg_OR), RID_ECX, | ||
2359 | (int32_t)((~LJ_TCDATA<<8)+(typeid<<16))); | ||
2360 | emit_gri(as, XG_ARITHi(XOg_AND), RID_ECX, LJ_GC_WHITES); | ||
2361 | emit_opgl(as, XO_MOVZXb, RID_ECX, gc.currentwhite); | ||
2362 | |||
2363 | asm_gencall(as, ci, args); | ||
2364 | emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)(sz+sizeof(GCcdata))); | ||
2365 | } | ||
2366 | #else | ||
2367 | #define asm_cnew(as, ir) ((void)0) | ||
2368 | #endif | ||
2369 | |||
2282 | /* -- Write barriers ------------------------------------------------------ */ | 2370 | /* -- Write barriers ------------------------------------------------------ */ |
2283 | 2371 | ||
2284 | static void asm_tbar(ASMState *as, IRIns *ir) | 2372 | static void asm_tbar(ASMState *as, IRIns *ir) |
@@ -3587,6 +3675,7 @@ static void asm_ir(ASMState *as, IRIns *ir) | |||
3587 | case IR_SNEW: asm_snew(as, ir); break; | 3675 | case IR_SNEW: asm_snew(as, ir); break; |
3588 | case IR_TNEW: asm_tnew(as, ir); break; | 3676 | case IR_TNEW: asm_tnew(as, ir); break; |
3589 | case IR_TDUP: asm_tdup(as, ir); break; | 3677 | case IR_TDUP: asm_tdup(as, ir); break; |
3678 | case IR_CNEW: case IR_CNEWI: asm_cnew(as, ir); break; | ||
3590 | 3679 | ||
3591 | /* Write barriers. */ | 3680 | /* Write barriers. */ |
3592 | case IR_TBAR: asm_tbar(as, ir); break; | 3681 | case IR_TBAR: asm_tbar(as, ir); break; |
@@ -3704,7 +3793,7 @@ static void asm_setup_regsp(ASMState *as, GCtrace *T) | |||
3704 | if (as->evenspill < 3) /* lj_str_new and lj_tab_newkey need 3 args. */ | 3793 | if (as->evenspill < 3) /* lj_str_new and lj_tab_newkey need 3 args. */ |
3705 | as->evenspill = 3; | 3794 | as->evenspill = 3; |
3706 | #endif | 3795 | #endif |
3707 | case IR_TNEW: case IR_TDUP: case IR_TOSTR: | 3796 | case IR_TNEW: case IR_TDUP: case IR_CNEW: case IR_CNEWI: case IR_TOSTR: |
3708 | ir->prev = REGSP_HINT(RID_RET); | 3797 | ir->prev = REGSP_HINT(RID_RET); |
3709 | if (inloop) | 3798 | if (inloop) |
3710 | as->modset = RSET_SCRATCH; | 3799 | as->modset = RSET_SCRATCH; |
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index a543ffd1..314e0de7 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -238,6 +238,7 @@ static void crec_ct_ct(jit_State *J, CType *d, CType *s, TRef dp, TRef sp) | |||
238 | 238 | ||
239 | static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) | 239 | static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) |
240 | { | 240 | { |
241 | CTState *cts = ctype_ctsG(J2G(J)); | ||
241 | CTInfo sinfo = s->info; | 242 | CTInfo sinfo = s->info; |
242 | lua_assert(!ctype_isenum(sinfo)); | 243 | lua_assert(!ctype_isenum(sinfo)); |
243 | if (ctype_isnum(sinfo)) { | 244 | if (ctype_isnum(sinfo)) { |
@@ -249,8 +250,8 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) | |||
249 | return emitir(IRT(IR_XLOAD, t), sp, 0); | 250 | return emitir(IRT(IR_XLOAD, t), sp, 0); |
250 | } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { | 251 | } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { |
251 | /* Create reference. */ | 252 | /* Create reference. */ |
252 | UNUSED(sid); lj_trace_err(J, LJ_TRERR_NYICONV); | 253 | CTypeID refid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); |
253 | return 0; | 254 | return emitir(IRTG(IR_CNEWI, IRT_CDATA), sp, lj_ir_kint(J, refid)); |
254 | } else { | 255 | } else { |
255 | copyval: /* Copy value. */ | 256 | copyval: /* Copy value. */ |
256 | lj_trace_err(J, LJ_TRERR_NYICONV); | 257 | lj_trace_err(J, LJ_TRERR_NYICONV); |
@@ -281,7 +282,7 @@ static void crec_ct_tv(jit_State *J, CType *d, TRef dp, TRef sp, TValue *sval) | |||
281 | s = ctype_raw(cts, sid); | 282 | s = ctype_raw(cts, sid); |
282 | if (ctype_isptr(s->info)) { | 283 | if (ctype_isptr(s->info)) { |
283 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; | 284 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; |
284 | sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_DATA); | 285 | sp = emitir(IRT(IR_FLOAD, t), sp, IRFL_CDATA_INIT1); |
285 | if (ctype_isref(s->info)) | 286 | if (ctype_isref(s->info)) |
286 | s = ctype_rawchild(cts, s); | 287 | s = ctype_rawchild(cts, s); |
287 | else | 288 | else |
@@ -316,7 +317,7 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) | |||
316 | if (ctype_isptr(ct->info)) { | 317 | if (ctype_isptr(ct->info)) { |
317 | IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; | 318 | IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32; |
318 | if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); | 319 | if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); |
319 | ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_DATA); | 320 | ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_INIT1); |
320 | ofs = 0; | 321 | ofs = 0; |
321 | } | 322 | } |
322 | 323 | ||
diff --git a/src/lj_ir.h b/src/lj_ir.h index 7814df34..6495a780 100644 --- a/src/lj_ir.h +++ b/src/lj_ir.h | |||
@@ -107,9 +107,11 @@ | |||
107 | _(XSTORE, S , ref, ref) \ | 107 | _(XSTORE, S , ref, ref) \ |
108 | \ | 108 | \ |
109 | /* Allocations. */ \ | 109 | /* Allocations. */ \ |
110 | _(SNEW, N , ref, ref) /* CSE is ok, so not marked as A. */ \ | 110 | _(SNEW, N , ref, ref) /* CSE is ok, not marked as A. */ \ |
111 | _(TNEW, AW, lit, lit) \ | 111 | _(TNEW, AW, lit, lit) \ |
112 | _(TDUP, AW, ref, ___) \ | 112 | _(TDUP, AW, ref, ___) \ |
113 | _(CNEW, AW, ref, ref) \ | ||
114 | _(CNEWI, NW, ref, ref) /* CSE is ok, not marked as A. */ \ | ||
113 | \ | 115 | \ |
114 | /* Write barriers. */ \ | 116 | /* Write barriers. */ \ |
115 | _(TBAR, S , ref, ___) \ | 117 | _(TBAR, S , ref, ___) \ |
@@ -186,7 +188,9 @@ IRFPMDEF(FPMENUM) | |||
186 | _(UDATA_UDTYPE, offsetof(GCudata, udtype)) \ | 188 | _(UDATA_UDTYPE, offsetof(GCudata, udtype)) \ |
187 | _(UDATA_FILE, sizeof(GCudata)) \ | 189 | _(UDATA_FILE, sizeof(GCudata)) \ |
188 | _(CDATA_TYPEID, offsetof(GCcdata, typeid)) \ | 190 | _(CDATA_TYPEID, offsetof(GCcdata, typeid)) \ |
189 | _(CDATA_DATA, sizeof(GCcdata)) | 191 | _(CDATA_INIT1, sizeof(GCcdata)) \ |
192 | _(CDATA_INIT2_4, sizeof(GCcdata)+4) \ | ||
193 | _(CDATA_INIT2_8, sizeof(GCcdata)+8) | ||
190 | 194 | ||
191 | typedef enum { | 195 | typedef enum { |
192 | #define FLENUM(name, ofs) IRFL_##name, | 196 | #define FLENUM(name, ofs) IRFL_##name, |
@@ -256,6 +260,7 @@ typedef struct CCallInfo { | |||
256 | _(lj_tab_len, 1, FL, INT, 0) \ | 260 | _(lj_tab_len, 1, FL, INT, 0) \ |
257 | _(lj_gc_step_jit, 2, FS, NIL, CCI_L) \ | 261 | _(lj_gc_step_jit, 2, FS, NIL, CCI_L) \ |
258 | _(lj_gc_barrieruv, 2, FS, NIL, 0) \ | 262 | _(lj_gc_barrieruv, 2, FS, NIL, 0) \ |
263 | _(lj_mem_newgco, 2, FS, P32, CCI_L) \ | ||
259 | _(lj_math_random_step, 1, FS, NUM, CCI_CASTU64|CCI_NOFPRCLOBBER) \ | 264 | _(lj_math_random_step, 1, FS, NUM, CCI_CASTU64|CCI_NOFPRCLOBBER) \ |
260 | _(sinh, 1, N, NUM, 0) \ | 265 | _(sinh, 1, N, NUM, 0) \ |
261 | _(cosh, 1, N, NUM, 0) \ | 266 | _(cosh, 1, N, NUM, 0) \ |
@@ -297,6 +302,7 @@ typedef enum { | |||
297 | 302 | ||
298 | #define IRM_W 0x80 | 303 | #define IRM_W 0x80 |
299 | 304 | ||
305 | #define IRM_NW (IRM_N|IRM_W) | ||
300 | #define IRM_AW (IRM_A|IRM_W) | 306 | #define IRM_AW (IRM_A|IRM_W) |
301 | #define IRM_LW (IRM_L|IRM_W) | 307 | #define IRM_LW (IRM_L|IRM_W) |
302 | 308 | ||
diff --git a/src/lj_opt_fold.c b/src/lj_opt_fold.c index e8e81a3e..e61a6533 100644 --- a/src/lj_opt_fold.c +++ b/src/lj_opt_fold.c | |||
@@ -152,8 +152,8 @@ typedef IRRef (LJ_FASTCALL *FoldFunc)(jit_State *J); | |||
152 | */ | 152 | */ |
153 | #define gcstep_barrier(J, ref) \ | 153 | #define gcstep_barrier(J, ref) \ |
154 | ((ref) < J->chain[IR_LOOP] && \ | 154 | ((ref) < J->chain[IR_LOOP] && \ |
155 | (J->chain[IR_TNEW] || J->chain[IR_TDUP] || \ | 155 | (J->chain[IR_SNEW] || J->chain[IR_TNEW] || J->chain[IR_TDUP] || \ |
156 | J->chain[IR_SNEW] || J->chain[IR_TOSTR])) | 156 | J->chain[IR_CNEW] || J->chain[IR_CNEWI] || J->chain[IR_TOSTR])) |
157 | 157 | ||
158 | /* -- Constant folding ---------------------------------------------------- */ | 158 | /* -- Constant folding ---------------------------------------------------- */ |
159 | 159 | ||
@@ -1477,7 +1477,37 @@ LJFOLDF(fload_str_len_snew) | |||
1477 | return NEXTFOLD; | 1477 | return NEXTFOLD; |
1478 | } | 1478 | } |
1479 | 1479 | ||
1480 | /* The C type ID of cdata objects is immutable. */ | ||
1481 | LJFOLD(FLOAD CNEW IRFL_CDATA_TYPEID) | ||
1482 | LJFOLD(FLOAD CNEWI IRFL_CDATA_TYPEID) | ||
1483 | LJFOLDF(fload_cdata_typeid_cnewi) | ||
1484 | { | ||
1485 | if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) | ||
1486 | return fleft->op2; /* No PHI barrier needed. CNEW/CNEWI op2 is const. */ | ||
1487 | return NEXTFOLD; | ||
1488 | } | ||
1489 | |||
1490 | /* Fixed initializers in cdata objects are immutable. */ | ||
1491 | LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT1) | ||
1492 | LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT2_4) | ||
1493 | LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT2_8) | ||
1494 | LJFOLDF(fload_cdata_init_cnew) | ||
1495 | { | ||
1496 | if (LJ_LIKELY(J->flags & JIT_F_OPT_FOLD)) { | ||
1497 | IRIns *ir = fleft; | ||
1498 | PHIBARRIER(fleft); | ||
1499 | lua_assert(ir->op1 != REF_NIL); | ||
1500 | if (IR(ir->op1)->o == IR_CARG) ir = IR(ir->op1); | ||
1501 | return fins->op2 == IRFL_CDATA_INIT1 ? ir->op1 : ir->op2; | ||
1502 | } | ||
1503 | return NEXTFOLD; | ||
1504 | } | ||
1505 | |||
1480 | LJFOLD(FLOAD any IRFL_STR_LEN) | 1506 | LJFOLD(FLOAD any IRFL_STR_LEN) |
1507 | LJFOLD(FLOAD any IRFL_CDATA_TYPEID) | ||
1508 | LJFOLD(FLOAD any IRFL_CDATA_INIT1) | ||
1509 | LJFOLD(FLOAD any IRFL_CDATA_INIT2_4) | ||
1510 | LJFOLD(FLOAD any IRFL_CDATA_INIT2_8) | ||
1481 | LJFOLD(VLOAD any any) /* Vararg loads have no corresponding stores. */ | 1511 | LJFOLD(VLOAD any any) /* Vararg loads have no corresponding stores. */ |
1482 | LJFOLDX(lj_opt_cse) | 1512 | LJFOLDX(lj_opt_cse) |
1483 | 1513 | ||
@@ -1564,6 +1594,7 @@ LJFOLD(CALLL any any) /* Safeguard fallback. */ | |||
1564 | LJFOLD(RETF any any) /* Modifies BASE. */ | 1594 | LJFOLD(RETF any any) /* Modifies BASE. */ |
1565 | LJFOLD(TNEW any any) | 1595 | LJFOLD(TNEW any any) |
1566 | LJFOLD(TDUP any) | 1596 | LJFOLD(TDUP any) |
1597 | LJFOLD(CNEW any any) | ||
1567 | LJFOLDX(lj_ir_emit) | 1598 | LJFOLDX(lj_ir_emit) |
1568 | 1599 | ||
1569 | /* ------------------------------------------------------------------------ */ | 1600 | /* ------------------------------------------------------------------------ */ |