aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-12-11 19:32:12 +0100
committerMike Pall <mike>2010-12-11 19:32:12 +0100
commitcdac0fa2cbd3f610159330bd8c5a36ea53b631d7 (patch)
tree65ecf2ae232bd96802d9f912c8f3cf084410cc3a /src
parent6947493687f15731b282f3f648fe97c43ce80bb9 (diff)
downloadluajit-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.c91
-rw-r--r--src/lj_crecord.c9
-rw-r--r--src/lj_ir.h10
-rw-r--r--src/lj_opt_fold.c35
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
2286static 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
2329static 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
2284static void asm_tbar(ASMState *as, IRIns *ir) 2372static 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
239static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) 239static 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
191typedef enum { 195typedef 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. */
1481LJFOLD(FLOAD CNEW IRFL_CDATA_TYPEID)
1482LJFOLD(FLOAD CNEWI IRFL_CDATA_TYPEID)
1483LJFOLDF(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. */
1491LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT1)
1492LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT2_4)
1493LJFOLD(FLOAD CNEWI IRFL_CDATA_INIT2_8)
1494LJFOLDF(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
1480LJFOLD(FLOAD any IRFL_STR_LEN) 1506LJFOLD(FLOAD any IRFL_STR_LEN)
1507LJFOLD(FLOAD any IRFL_CDATA_TYPEID)
1508LJFOLD(FLOAD any IRFL_CDATA_INIT1)
1509LJFOLD(FLOAD any IRFL_CDATA_INIT2_4)
1510LJFOLD(FLOAD any IRFL_CDATA_INIT2_8)
1481LJFOLD(VLOAD any any) /* Vararg loads have no corresponding stores. */ 1511LJFOLD(VLOAD any any) /* Vararg loads have no corresponding stores. */
1482LJFOLDX(lj_opt_cse) 1512LJFOLDX(lj_opt_cse)
1483 1513
@@ -1564,6 +1594,7 @@ LJFOLD(CALLL any any) /* Safeguard fallback. */
1564LJFOLD(RETF any any) /* Modifies BASE. */ 1594LJFOLD(RETF any any) /* Modifies BASE. */
1565LJFOLD(TNEW any any) 1595LJFOLD(TNEW any any)
1566LJFOLD(TDUP any) 1596LJFOLD(TDUP any)
1597LJFOLD(CNEW any any)
1567LJFOLDX(lj_ir_emit) 1598LJFOLDX(lj_ir_emit)
1568 1599
1569/* ------------------------------------------------------------------------ */ 1600/* ------------------------------------------------------------------------ */