aboutsummaryrefslogtreecommitdiff
path: root/src/lj_record.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_record.c')
-rw-r--r--src/lj_record.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/src/lj_record.c b/src/lj_record.c
index 61e09b6d..a76f5d94 100644
--- a/src/lj_record.c
+++ b/src/lj_record.c
@@ -563,12 +563,32 @@ static void rec_loop_jit(jit_State *J, TraceNo lnk, LoopEvent ev)
563 563
564/* -- Record calls and returns -------------------------------------------- */ 564/* -- Record calls and returns -------------------------------------------- */
565 565
566/* Specialize to the runtime value of the called function or its prototype. */
567static TRef rec_call_specialize(jit_State *J, GCfunc *fn, TRef tr)
568{
569 TRef kfunc;
570 if (isluafunc(fn)) {
571 GCproto *pt = funcproto(fn);
572 /* 3 or more closures created? Probably not a monomorphic function. */
573 if (pt->flags >= 3*PROTO_CLCOUNT) { /* Specialize to prototype instead. */
574 TRef trpt = emitir(IRT(IR_FLOAD, IRT_P32), tr, IRFL_FUNC_PC);
575 emitir(IRTG(IR_EQ, IRT_P32), trpt, lj_ir_kptr(J, proto_bc(pt)));
576 (void)lj_ir_kgc(J, obj2gco(pt), IRT_PROTO); /* Prevent GC of proto. */
577 return tr;
578 }
579 }
580 /* Otherwise specialize to the function (closure) value itself. */
581 kfunc = lj_ir_kfunc(J, fn);
582 emitir(IRTG(IR_EQ, IRT_FUNC), tr, kfunc);
583 return kfunc;
584}
585
566/* Record call setup. */ 586/* Record call setup. */
567static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs) 587static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
568{ 588{
569 RecordIndex ix; 589 RecordIndex ix;
570 TValue *functv = &J->L->base[func]; 590 TValue *functv = &J->L->base[func];
571 TRef trfunc, *fbase = &J->base[func]; 591 TRef *fbase = &J->base[func];
572 ptrdiff_t i; 592 ptrdiff_t i;
573 for (i = 0; i <= nargs; i++) 593 for (i = 0; i <= nargs; i++)
574 (void)getslot(J, func+i); /* Ensure func and all args have a reference. */ 594 (void)getslot(J, func+i); /* Ensure func and all args have a reference. */
@@ -582,11 +602,7 @@ static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs)
582 fbase[0] = ix.mobj; /* Replace function. */ 602 fbase[0] = ix.mobj; /* Replace function. */
583 functv = &ix.mobjv; 603 functv = &ix.mobjv;
584 } 604 }
585 605 fbase[0] = TREF_FRAME | rec_call_specialize(J, funcV(functv), fbase[0]);
586 /* Specialize to the runtime value of the called function. */
587 trfunc = lj_ir_kfunc(J, funcV(functv));
588 emitir(IRTG(IR_EQ, IRT_FUNC), fbase[0], trfunc);
589 fbase[0] = trfunc | TREF_FRAME;
590 J->maxslot = (BCReg)nargs; 606 J->maxslot = (BCReg)nargs;
591} 607}
592 608