diff options
Diffstat (limited to 'src/lj_record.c')
-rw-r--r-- | src/lj_record.c | 28 |
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. */ | ||
567 | static 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. */ |
567 | static void rec_call_setup(jit_State *J, BCReg func, ptrdiff_t nargs) | 587 | static 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 | ||