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

@@ -1209,19 +1209,16 @@ 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];
IRRef args[4];
RegSet allow = (RSET_GPR & ~RSET_SCRATCH);
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);
@@ -1243,16 +1240,28 @@ static void asm_cnew(ASMState *as, IRIns *ir)
if (ofs == sizeof(GCcdata)) break;
ofs -= 4; 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. */
{
uint32_t k = emit_isk12(ARMI_MOV, ctypeid);
Reg r = k ? RID_R1 : ra_allock(as, ctypeid, allow);
uint32_t k = emit_isk12(ARMI_MOV, id);
Reg r = k ? RID_R1 : ra_allock(as, id, allow);
emit_lso(as, ARMI_STRB, RID_TMP, RID_RET, offsetof(GCcdata, gct));
emit_lsox(as, ARMI_STRH, r, RID_RET, offsetof(GCcdata, ctypeid));
emit_d(as, ARMI_MOV|ARMI_K12|~LJ_TCDATA, RID_TMP);
if (k) emit_d(as, ARMI_MOV^k, RID_R1);
}
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));