FFI: Compile VLA/VLS and large cdata allocs with default initialization.

This commit is contained in:
Mike Pall
2013-05-24 00:45:44 +02:00
parent b3369f3c95
commit f1f7e40318
9 changed files with 139 additions and 61 deletions

View File

@@ -975,19 +975,15 @@ dotypecheck:
static void asm_cnew(ASMState *as, IRIns *ir)
{
CTState *cts = ctype_ctsG(J2G(as->J));
CTypeID ctypeid = (CTypeID)IR(ir->op1)->i;
CTSize sz = (ir->o == IR_CNEWI || ir->op2 == REF_NIL) ?
lj_ctype_size(cts, ctypeid) : (CTSize)IR(ir->op2)->i;
CTypeID id = (CTypeID)IR(ir->op1)->i;
CTSize sz;
CTInfo info = lj_ctype_info(cts, id, &sz);
const CCallInfo *ci = &lj_ir_callinfo[IRCALL_lj_mem_newgco];
IRRef args[2];
RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
IRRef args[4];
RegSet drop = RSET_SCRATCH;
lua_assert(sz != CTSIZE_INVALID);
lua_assert(sz != CTSIZE_INVALID || (ir->o == IR_CNEW && ir->op2 != REF_NIL));
args[0] = ASMREF_L; /* lua_State *L */
args[1] = ASMREF_TMP1; /* MSize size */
as->gcsteps++;
if (ra_hasreg(ir->r))
rset_clear(drop, ir->r); /* Dest reg handled below. */
ra_evictset(as, drop);
@@ -996,6 +992,7 @@ static void asm_cnew(ASMState *as, IRIns *ir)
/* Initialize immutable cdata object. */
if (ir->o == IR_CNEWI) {
RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
int32_t ofs = sizeof(GCcdata);
lua_assert(sz == 4 || sz == 8);
if (sz == 8) {
@@ -1010,12 +1007,24 @@ static void asm_cnew(ASMState *as, IRIns *ir)
if (ofs == sizeof(GCcdata)) break;
ofs -= 4; if (LJ_BE) ir++; else ir--;
}
} else if (ir->op2 != REF_NIL) { /* Create VLA/VLS/aligned cdata. */
ci = &lj_ir_callinfo[IRCALL_lj_cdata_newv];
args[0] = ASMREF_L; /* lua_State *L */
args[1] = ir->op1; /* CTypeID id */
args[2] = ir->op2; /* CTSize sz */
args[3] = ASMREF_TMP1; /* CTSize align */
asm_gencall(as, ci, args);
emit_loadi(as, ra_releasetmp(as, ASMREF_TMP1), (int32_t)ctype_align(info));
return;
}
/* Initialize gct and ctypeid. lj_mem_newgco() already sets marked. */
emit_tsi(as, MIPSI_SB, RID_RET+1, RID_RET, offsetof(GCcdata, gct));
emit_tsi(as, MIPSI_SH, RID_TMP, RID_RET, offsetof(GCcdata, ctypeid));
emit_ti(as, MIPSI_LI, RID_RET+1, ~LJ_TCDATA);
emit_ti(as, MIPSI_LI, RID_TMP, ctypeid); /* Lower 16 bit used. Sign-ext ok. */
emit_ti(as, MIPSI_LI, RID_TMP, id); /* Lower 16 bit used. Sign-ext ok. */
args[0] = ASMREF_L; /* lua_State *L */
args[1] = ASMREF_TMP1; /* MSize size */
asm_gencall(as, ci, args);
ra_allockreg(as, (int32_t)(sz+sizeof(GCcdata)),
ra_releasetmp(as, ASMREF_TMP1));
@@ -1197,11 +1206,16 @@ static void asm_arithov(ASMState *as, IRIns *ir)
static void asm_mulov(ASMState *as, IRIns *ir)
{
#if LJ_DUALNUM
#error "NYI: MULOV"
#else
UNUSED(as); UNUSED(ir); lua_assert(0); /* Unused in single-number mode. */
#endif
Reg dest = ra_dest(as, ir, RSET_GPR);
Reg tmp, right, left = ra_alloc2(as, ir, RSET_GPR);
right = (left >> 8); left &= 255;
tmp = ra_scratch(as, rset_exclude(rset_exclude(rset_exclude(RSET_GPR, left),
right), dest));
asm_guard(as, MIPSI_BNE, RID_TMP, tmp);
emit_dta(as, MIPSI_SRA, RID_TMP, dest, 31);
emit_dst(as, MIPSI_MFHI, tmp, 0, 0);
emit_dst(as, MIPSI_MFLO, dest, 0, 0);
emit_dst(as, MIPSI_MULT, 0, left, right);
}
#if LJ_HASFFI