📄 ljit_x86.h
字号:
if (nargs == -1 && ii.xnargs >= 0) { dasm_put(Dst, 1435, Dt2([func+1+ii.xnargs])); } /* Now inline the function itself. */ switch (JIT_IH_LIB(ii.hidx)) { case JIT_IHLIB_BASE: jit_inline_base(J, &ii); break;#ifndef COCO_DISABLE case JIT_IHLIB_COROUTINE: jit_inline_coroutine(J, &ii); break;#endif case JIT_IHLIB_STRING: jit_inline_string(J, &ii); break; case JIT_IHLIB_TABLE: jit_inline_table(J, &ii); break; case JIT_IHLIB_MATH: jit_inline_math(J, &ii); break; default: jit_assert(0); break; } /* And add the common leadout for inlined calls. */ if (ii.nresults == -1) { if (ii.xnresults >= 0) { dasm_put(Dst, 791, Dt2([ii.res+ii.xnresults])); } } else if (ii.nargs == -1) { /* Restore L->top only if needed. */ dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top)); } if (nresults == -2) { /* Results are in place. Add return for tailcalls. */ dasm_put(Dst, 1452, sizeof(TValue), Dt1(->ci), sizeof(CallInfo)); } return -1; /* Success, call has been inlined. */}/* ------------------------------------------------------------------------ *//* Helper function for inlined iterator code. Paraphrased from luaH_next. *//* TODO: GCC has trouble optimizing this. */static int jit_table_next(lua_State *L, TValue *ra){ Table *t = hvalue(&ra[TFOR_TAB]); int i = ra[TFOR_CTL].value.b; /* Hidden control variable. */ for (; i < t->sizearray; i++) { /* First the array part. */ if (!ttisnil(&t->array[i])) { setnvalue(&ra[TFOR_KEY], cast_num(i+1)); setobj2s(L, &ra[TFOR_VAL], &t->array[i]); ra[TFOR_CTL].value.b = i+1; return 1; } } for (i -= t->sizearray; i < sizenode(t); i++) { /* Then the hash part. */ if (!ttisnil(gval(gnode(t, i)))) { setobj2s(L, &ra[TFOR_KEY], key2tval(gnode(t, i))); setobj2s(L, &ra[TFOR_VAL], gval(gnode(t, i))); ra[TFOR_CTL].value.b = i+1+t->sizearray; return 1; } } return 0; /* End of iteration. */}/* Try to inline a TFORLOOP instruction. */static int jit_inline_tforloop(jit_State *J, int ra, int nresults, int target){ const TValue *oidx = hint_get(J, INLINE); /* INLINE hint = lib/func idx. */ int idx; if (!ttisnumber(oidx)) return 0; /* No hint: don't inline anything. */ idx = (int)nvalue(oidx); if (J->flags & JIT_F_DEBUG) return 0; /* DWIM. */ switch (idx) { case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_PAIRS): dasm_put(Dst, 1465, Dt2([ra]), (ptrdiff_t)(jit_table_next), target); return 1; /* Success, iterator has been inlined. */ case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_IPAIRS): dasm_put(Dst, 1483, Dt2([ra+TFOR_CTL].value), Dt2([ra+TFOR_TAB].value), Dt2([ra+TFOR_CTL].value), (ptrdiff_t)(luaH_getnum), Dt7(->tt), Dt2([ra+TFOR_CTL].value), Dt2([ra+TFOR_KEY].tt), Dt2([ra+TFOR_KEY].value), Dt7(->value), Dt7(->value.na[1]), Dt2([ra+TFOR_VAL].tt), Dt2([ra+TFOR_VAL].value), Dt2([ra+TFOR_VAL].value.na[1]), target); return 1; /* Success, iterator has been inlined. */ } return 0; /* No support for inlining any other iterators. */}/* ------------------------------------------------------------------------ */#ifdef LUA_COMPAT_VARARGstatic void jit_vararg_table(lua_State *L){ Table *tab; StkId base, func; int i, num, numparams; luaC_checkGC(L); base = L->base; func = L->ci->func; numparams = clvalue(func)->l.p->numparams; num = base - func - numparams - 1; tab = luaH_new(L, num, 1); for (i = 0; i < num; i++) setobj2n(L, luaH_setnum(L, tab, i+1), base - num + i); setnvalue(luaH_setstr(L, tab, luaS_newliteral(L, "n")), (lua_Number)num); sethvalue(L, base + numparams, tab);}#endif/* Encode JIT function prologue. */static void jit_prologue(jit_State *J){ Proto *pt = J->pt; int numparams = pt->numparams; int stacksize = pt->maxstacksize; dasm_put(Dst, 1544, Dt3([stacksize]), Dt1(->stack_last), Dt1(->end_ci), Dt4([1]), Dt4(->func), sizeof(TValue), Dt1(->ci)); if (numparams > 0) { dasm_put(Dst, 1580, Dt2([numparams])); } if (!pt->is_vararg) { /* Fixarg function. */ /* Must cap L->top at L->base+numparams because 1st LOADNIL is omitted. */ if (numparams == 0) { dasm_put(Dst, 1586); } else if (J->flags & JIT_F_CPU_CMOV) { dasm_put(Dst, 1589); } else { dasm_put(Dst, 1594); } dasm_put(Dst, 1603, Dt2([stacksize]), Dt4(->tailcalls), Dt4(->top), Dt1(->top), Dt1(->base), Dt4(->base)); } else { /* Vararg function. */ int i; if (numparams > 0) { dasm_put(Dst, 1622); dasm_put(Dst, 1630, Dt3(->tt), sizeof(TValue)); } dasm_put(Dst, 1649, Dt1(->base), Dt4(->base), Dt4(->tailcalls)); for (i = 0; i < numparams; i++) { /* Move/clear fixargs. */ if (J->flags & JIT_F_CPU_SSE2) { dasm_put(Dst, 1659, Dt2([i].tt), Dt2([i].value), Dt3([i].tt), Dt3([i].value)); } else { dasm_put(Dst, 1677, Dt2([i].value), Dt2([i].value.na[1]), Dt3([i].value), Dt2([i].tt), Dt3([i].value.na[1]), Dt3([i].tt)); } dasm_put(Dst, 854, Dt2([i].tt)); } if (numparams > 0) { dasm_put(Dst, 332, Dt1(->ci)); } dasm_put(Dst, 1696, Dt2([stacksize]), Dt2([numparams]), Dt4(->top), Dt1(->top)); stacksize -= numparams; /* Fixargs are already cleared. */ } /* Clear undefined args and all vars. Still assumes eax = LUA_TNIL = 0. */ /* Note: cannot clear only args because L->top has grown. */ if (stacksize <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */ int i; for (i = 0; i < stacksize; i++) { dasm_put(Dst, 1712, Dt3([i].tt)); } } else { /* Standard loop. */ dasm_put(Dst, 1716, Dt3([0].tt), Dt3([1].tt), 2*sizeof(TValue)); }#ifdef LUA_COMPAT_VARARG if (pt->is_vararg & VARARG_NEEDSARG) { dasm_put(Dst, 1734, (ptrdiff_t)(jit_vararg_table)); }#endif /* Call hook check. */ if (J->flags & JIT_F_DEBUG_CALL) { dasm_put(Dst, 1740, Dt1(->hookmask), LUA_MASKCALL); }}/* Check if we can combine 'return const'. */static int jit_return_k(jit_State *J){ if (!J->combine) return 0; /* COMBINE hint set? */ /* May need to close open upvalues. */ if (!fhint_isset(J, NOCLOSE)) { dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); } if (!J->pt->is_vararg) { /* Fixarg function. */ dasm_put(Dst, 1830, Dt1(->ci), sizeof(CallInfo), sizeof(TValue)); } else { /* Vararg function. */ dasm_put(Dst, 1844, Dt1(->ci), Dt4(->func), sizeof(CallInfo), Dt1(->ci), Dt2([1])); } jit_assert(J->combine == 1); /* Required to skip next RETURN instruction. */ return 1;}static void jit_op_return(jit_State *J, int rbase, int nresults){ /* Return hook check. */ if (J->flags & JIT_F_DEBUG_CALL) { if (nresults < 0 && !(J->flags & JIT_F_DEBUG_INS)) { dasm_put(Dst, 594, Dt1(->top)); } dasm_put(Dst, 1863, Dt1(->hookmask), LUA_MASKRET); if (J->flags & JIT_F_DEBUG_INS) { dasm_put(Dst, 1878, Dt1(->savedpc)); } } /* May need to close open upvalues. */ if (!fhint_isset(J, NOCLOSE)) { dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); } /* Previous op was open: 'return f()' or 'return ...' */ if (nresults < 0) { dasm_put(Dst, 332, Dt1(->ci)); if (rbase) { dasm_put(Dst, 787, rbase*sizeof(TValue)); } dasm_put(Dst, 1933, Dt4(->func), Dt4(->func), sizeof(CallInfo), Dt1(->ci)); return; } if (!J->pt->is_vararg) { /* Fixarg function, nresults >= 0. */ int i; dasm_put(Dst, 1980, Dt1(->ci), sizeof(CallInfo), sizeof(TValue)); for (i = 0; i < nresults; i++) { if (J->flags & JIT_F_CPU_SSE2) { dasm_put(Dst, 821, Dt2([rbase+i+1].tt), Dt2([rbase+i+1].value), Dt2([i].tt), Dt2([i].value)); } else { dasm_put(Dst, 839, Dt2([rbase+i+1].value), Dt2([rbase+i+1].value.na[1]), Dt2([rbase+i+1].tt), Dt2([i].value), Dt2([i].value.na[1]), Dt2([i].tt)); } } dasm_put(Dst, 1989, Dt2([nresults])); } else { /* Vararg function, nresults >= 0. */ int i; dasm_put(Dst, 1997, Dt1(->ci), Dt4(->func), sizeof(CallInfo), Dt1(->ci)); for (i = 0; i < nresults; i++) { if (J->flags & JIT_F_CPU_SSE2) { dasm_put(Dst, 1659, Dt2([rbase+i].tt), Dt2([rbase+i].value), Dt3([i].tt), Dt3([i].value)); } else { dasm_put(Dst, 2010, Dt2([rbase+i].value), Dt2([rbase+i].value.na[1]), Dt2([rbase+i].tt), Dt3([i].value), Dt3([i].value.na[1]), Dt3([i].tt)); } } dasm_put(Dst, 2029); if (nresults) { dasm_put(Dst, 2036, nresults*sizeof(TValue)); } dasm_put(Dst, 32); }}static void jit_op_call(jit_State *J, int func, int nargs, int nresults){ int cltype = jit_inline_call(J, func, nargs, nresults); if (cltype < 0) return; /* Inlined? */ if (func) { dasm_put(Dst, 787, func*sizeof(TValue)); } dasm_put(Dst, 2040, Dt1(->ci), Dt2([0].tt)); if (nargs >= 0) { /* Previous op was not open and did not set TOP. */ dasm_put(Dst, 791, Dt2([1+nargs])); } dasm_put(Dst, 2048, Dt2(->value), (ptrdiff_t)(J->nextins), Dt4(->savedpc)); if (cltype == LUA_TFUNCTION) { if (nargs == -1) { dasm_put(Dst, 2057); } else { dasm_put(Dst, 2062); } } else { dasm_put(Dst, 2067); } dasm_put(Dst, 2116, Dt5(->jit_gate)); if (func) { dasm_put(Dst, 1984, func*sizeof(TValue)); } dasm_put(Dst, 2121, Dt1(->base)); /* Clear undefined results TOP <= o < func+nresults. */ if (nresults > 0) { dasm_put(Dst, 2125); if (nresults <= EXTRA_STACK) { /* Loopless clear. May use EXTRA_STACK. */ int i; for (i = 0; i < nresults; i++) { dasm_put(Dst, 1712, Dt3([i].tt)); } } else { /* Standard loop. TODO: move to .tail? */ dasm_put(Dst, 2128, Dt2([func+nresults]), Dt3([0].tt), Dt3([1].tt), 2*sizeof(TValue)); } } if (nresults >= 0) { /* Not an open ins. Restore L->top. */ dasm_put(Dst, 1445, Dt2([J->pt->maxstacksize]), Dt1(->top)); } /* Otherwise keep TOP for next instruction. */}static void jit_op_tailcall(jit_State *J, int func, int nargs){ int cltype; if (!fhint_isset(J, NOCLOSE)) { /* May need to close open upvalues. */ dasm_put(Dst, 1820, (ptrdiff_t)(luaF_close)); } cltype = jit_inline_call(J, func, nargs, -2); if (cltype < 0) goto finish; /* Inlined? */ if (cltype == LUA_TFUNCTION) { jit_deopt_target(J, nargs); dasm_put(Dst, 2149, Dt2([func].tt)); } else { dasm_put(Dst, 2158, Dt2([func].tt)); dasm_put(Dst, 2168); if (func) { dasm_put(Dst, 787, func*sizeof(TValue)); } if (nargs >= 0) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -