?? ljit_x86.h
字號:
JSUB_GETTABLE_KNUM, JSUB_GETTABLE_NUM, JSUB_SETTABLE_KNUM, JSUB_SETTABLE_NUM, JSUB_LOG2_TWORD, JSUB_CONCAT_STR2, JSUB__MAX};/* ------------------------------------------------------------------------ *//* Arch string. */const char luaJIT_arch[] = "x86";/* Forward declarations for C functions called from jsubs. */static void jit_hookins(lua_State *L, const Instruction *newpc);static void jit_gettable_fb(lua_State *L, Table *t, StkId dest);static void jit_settable_fb(lua_State *L, Table *t, StkId val);/* ------------------------------------------------------------------------ *//* Detect CPU features and set JIT flags. */static int jit_cpudetect(jit_State *J){ void *mcode; size_t sz; int status; /* Some of the jsubs need the flags. So compile this separately. */ unsigned int feature; dasm_setup(Dst, jit_actionlist); dasm_put(Dst, 0); (void)dasm_checkstep(Dst, DASM_SECTION_CODE); status = luaJIT_link(J, &mcode, &sz); if (status != JIT_S_OK) return status; /* Check feature bits. See the Intel/AMD manuals for the bit definitions. */ feature = ((unsigned int (*)(void))mcode)(); if (feature & (1<<15)) J->flags |= JIT_F_CPU_CMOV; if (feature & (1<<26)) J->flags |= JIT_F_CPU_SSE2; luaJIT_freemcode(J, mcode, sz); /* We don't need this code anymore. */ return JIT_S_OK;}/* Check some assumptions. Should compile to nop. */static int jit_consistency_check(jit_State *J){ do { /* Force a compiler error for inconsistent structure sizes. */ /* Check LUA_TVALUE_ALIGN in luaconf.h, too. */ int check_TVALUE_SIZE_in_ljit_x86_dash[1+16-sizeof(TValue)]; int check_TVALUE_SIZE_in_ljit_x86_dash_[1+sizeof(TValue)-16]; ((void)check_TVALUE_SIZE_in_ljit_x86_dash[0]); ((void)check_TVALUE_SIZE_in_ljit_x86_dash_[0]); if (LUA_TNIL != 0 || LUA_TBOOLEAN != 1 || PCRLUA != 0) break; if ((int)&(((Node *)0)->i_val) != (int)&(((StkId)0)->value)) break; return JIT_S_OK; } while (0); J->dasmstatus = 999999999; /* Recognizable error. */ return JIT_S_COMPILER_ERROR;}/* Compile JIT subroutines (once). */static int jit_compile_jsub(jit_State *J){ int status = jit_consistency_check(J); if (status != JIT_S_OK) return status; status = jit_cpudetect(J); if (status != JIT_S_OK) return status; dasm_setup(Dst, jit_actionlist); dasm_put(Dst, 34); dasm_put(Dst, 36, Dt1(->top), Dt2(->value), Dt1(->ci), Dt1(->nCcalls), Dt5(->jit_gate), Dt1(->ci), Dt1(->top), Dt4(->savedpc), Dt1(->savedpc), Dt4(->base), Dt1(->base), Dt1(->top), Dt3(->tt), sizeof(TValue)); dasm_put(Dst, 145, Dt1(->nCcalls), PCRC, Dt5(->p), DtE(->jit_status), JIT_S_OK, DtE(->jit_mcode), Dt5(->jit_gate), Dt4(->savedpc), Dt1(->ci), Dt1(->top), Dt1(->savedpc), Dt1(->stack), (ptrdiff_t)(luaD_precall), (ptrdiff_t)(luaV_execute), Dt1(->stack)); dasm_put(Dst, 262, Dt1(->top), Dt3([LUA_MINSTACK]), Dt1(->stack_last), Dt1(->end_ci), Dt4([1]), Dt1(->ci), Dt4(->func), Dt4(->top), Dt2(->value), sizeof(TValue), Dt1(->top), Dt1(->base), Dt4(->base), DtD(->f), Dt1(->ci)); dasm_put(Dst, 336, Dt4(->func), Dt1(->top), Dt4(->func), sizeof(CallInfo), Dt1(->ci), Dt1(->hookmask), LUA_MASKCALL, DtD(->f), Dt1(->hookmask), LUA_MASKRET); dasm_put(Dst, 421, LUA_HOOKRET, (ptrdiff_t)(luaD_callhook), LUA_HOOKCALL, (ptrdiff_t)(luaD_callhook), Dt1(->top), Dt1(->stack), (ptrdiff_t)(luaD_growstack), Dt1(->stack), Dt1(->top), Dt2(->value), Dt5(->jit_gate), Dt1(->top), (ptrdiff_t)(luaD_growCI), Dt9([-1])); dasm_put(Dst, 547, Dt2(->value), Dt1(->ci), Dt5(->jit_gate)); dasm_put(Dst, 602, Dt1(->hookmask), LUA_MASKLINE|LUA_MASKCOUNT, Dt1(->hookcount), Dt1(->hookmask), LUA_MASKLINE, (ptrdiff_t)(jit_hookins), Dt1(->base), Dt1(->top)); dasm_put(Dst, 737, (ptrdiff_t)(luaC_step), Dt1(->base)); dasm_put(Dst, 1026, Dt3([0].tt), Dt3([1].tt), Dt3([2].tt), Dt3([1].value), Dt3([2].value), Dt3([0].value), DtB(->tsv.len), sizeof(TString)-1, Dt1(->l_G), Dt6(->totalbytes)); dasm_put(Dst, 1129, Dt6(->GCthreshold), (ptrdiff_t)(luaS_newlstr)); dasm_put(Dst, 1191, Dt3([0].tt), Dt3([1].tt), Dt3([1].value), Dt3([0].value), DtB(->tsv.len), (ptrdiff_t)(luaC_step), Dt1(->base), (ptrdiff_t)(luaS_newlstr)); dasm_put(Dst, 1755, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->p), DtE(->code), Dt1(->savedpc), LUA_HOOKCALL, (ptrdiff_t)(luaD_callhook), DtE(->code), Dt1(->savedpc), Dt1(->base)); dasm_put(Dst, 1886, Dt1(->savedpc), LUA_HOOKRET, (ptrdiff_t)(luaD_callhook), Dt1(->base), Dt1(->top)); dasm_put(Dst, 2077, Dt1(->savedpc), Dt1(->top), (ptrdiff_t)(luaD_tryfuncTM), Dt1(->top), Dt2(->value), Dt1(->ci)); dasm_put(Dst, 2178, Dt1(->savedpc), Dt1(->top), (ptrdiff_t)(luaD_tryfuncTM), Dt1(->ci), Dt1(->top), Dt4(->func), Dt4(->func), Dt2(->value), sizeof(CallInfo), Dt5(->jit_gate)); dasm_put(Dst, 2570, (ptrdiff_t)(luaC_barrierf)); dasm_put(Dst, 2589, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->env)); dasm_put(Dst, 2609, Dt3(->tt), Dt3(->value), DtC(->lsizenode), DtB(->tsv.hash), DtC(->node), Dt10(->i_key.nk.tt), Dt10(->i_key.nk.value), Dt10(->i_val.tt)); if (J->flags & JIT_F_CPU_SSE2) { dasm_put(Dst, 2674, Dt10(->i_val.value), Dt2(->value)); } else { dasm_put(Dst, 2686, Dt10(->i_val.value), Dt10(->i_val.value.na[1]), Dt2(->value), Dt2(->value.na[1])); } dasm_put(Dst, 2699, Dt2(->tt), Dt1(->base), Dt10(->i_key.nk.next), DtC(->metatable), DtC(->flags), 1<<TM_INDEX, Dt2([0].tt), Dt1(->base), Dt1(->env.value), Dt1(->env.tt), Dt1(->savedpc), (ptrdiff_t)(jit_gettable_fb), Dt1(->base)); dasm_put(Dst, 32); dasm_put(Dst, 2790, Dt3(->tt), Dt7(->tt), Dt3(->value), Dt7(->value)); dasm_put(Dst, 2821, Dt1(->l_G), DtC(->marked), (~bitmask(BLACKBIT))&0xff, Dt6(->grayagain), Dt6(->grayagain), DtC(->gclist)); dasm_put(Dst, 2843, Dt1(->ci), Dt4(->func), Dt3(->value), Dt5(->env)); dasm_put(Dst, 2863, Dt3(->tt), Dt3(->value), DtC(->lsizenode), DtB(->tsv.hash), DtC(->node), Dt10(->i_key.nk.tt), Dt10(->i_key.nk.value), Dt10(->i_val.tt), DtC(->flags)); dasm_put(Dst, 2935, DtC(->marked), bitmask(BLACKBIT)); if (J->flags & JIT_F_CPU_SSE2) { dasm_put(Dst, 2947, Dt2([0].tt), Dt2([0].value), Dt7([0].tt), Dt7([0].value)); } else { dasm_put(Dst, 2965, Dt2([0].value), Dt2([0].value.na[1]), Dt2([0].tt), Dt7([0].value), Dt7([0].value.na[1]), Dt7([0].tt)); } dasm_put(Dst, 2984, Dt1(->base), Dt10(->i_key.nk.next), DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, Dt1(->env), Dt7([0].value), Dt7([0].tt), (ptrdiff_t)(luaH_newkey)); dasm_put(Dst, 3066, DtC(->metatable), DtC(->flags), 1<<TM_NEWINDEX, Dt1(->env.value), Dt1(->env.tt), Dt1(->savedpc), (ptrdiff_t)(jit_settable_fb), Dt1(->base)); dasm_put(Dst, 3127, Dt3(->tt), Dt7(->tt), Dt3(->value), Dt7(->value)); dasm_put(Dst, 3438, (ptrdiff_t)(luaH_getnum), sizeof(TValue)); dasm_put(Dst, 3476, (ptrdiff_t)(luaH_getnum)); dasm_put(Dst, 3623, (ptrdiff_t)(luaH_setnum), sizeof(TValue)); dasm_put(Dst, 3665, (ptrdiff_t)(luaH_setnum)); dasm_put(Dst, 3992); dasm_put(Dst, 4325, Dt2([0].tt), Dt2([1].tt), Dt1(->l_G), Dt2([0].value), Dt2([1].value), DtB(->tsv.len), DtB(->tsv.len), Dt6(->buff.buffsize), Dt6(->buff.buffer), sizeof(TString)); dasm_put(Dst, 4396, DtB(->tsv.len), DtB([1]), Dt1(->base), (ptrdiff_t)(luaS_newlstr), Dt1(->base), Dt6(->buff), (ptrdiff_t)(luaZ_openspace)); dasm_put(Dst, 561, Dt1(->top), Dt1(->savedpc), (ptrdiff_t)(luaJIT_deoptimize), Dt1(->base), Dt1(->top)); (void)dasm_checkstep(Dst, DASM_SECTION_CODE); status = luaJIT_link(J, &J->jsubmcode, &J->szjsubmcode); if (status != JIT_S_OK) return status; /* Copy the callgates from the globals to the global state. */ G(J->L)->jit_gateLJ = (luaJIT_GateLJ)J->jsub[JSUB_GATE_LJ]; G(J->L)->jit_gateJL = (lua_CFunction)J->jsub[JSUB_GATE_JL]; G(J->L)->jit_gateJC = (lua_CFunction)J->jsub[JSUB_GATE_JC]; return JIT_S_OK;}/* Match with number of nops above. Avoid confusing the instruction decoder. */#define DEBUGPATCH_SIZE 6/* Notify backend that the debug mode may have changed. */void luaJIT_debugnotify(jit_State *J){ unsigned char *patch = (unsigned char *)J->jsub[JSUB_GATE_JC_PATCH]; unsigned char *target = (unsigned char *)J->jsub[JSUB_GATE_JC_DEBUG]; /* Yep, this is self-modifying code -- don't tell anyone. */ if (patch[0] == 0xe9) { /* Debug patch is active. */ if (!(J->flags & JIT_F_DEBUG_CALL)) /* Deactivate it. */ memcpy(patch, target-DEBUGPATCH_SIZE, DEBUGPATCH_SIZE); } else { /* Debug patch is inactive. */ if (J->flags & JIT_F_DEBUG_CALL) { /* Activate it. */ int rel = target-(patch+5); memcpy(target-DEBUGPATCH_SIZE, patch, DEBUGPATCH_SIZE); patch[0] = 0xe9; /* jmp */ memcpy(patch+1, &rel, 4); /* Relative address. */ memset(patch+5, 0x90, DEBUGPATCH_SIZE-5); /* nop */ } }}/* Patch a jmp into existing mcode. */static void jit_patch_jmp(jit_State *J, void *mcode, void *to){ unsigned char *patch = (unsigned char *)mcode; int rel = ((unsigned char *)to)-(patch+5); patch[0] = 0xe9; /* jmp */ memcpy((void *)(patch+1), &rel, 4); /* Relative addr. */}/* ------------------------------------------------------------------------ *//* Call line/count hook. */static void jit_hookins(lua_State *L, const Instruction *newpc){ Proto *pt = ci_func(L->ci)->l.p; int pc = luaJIT_findpc(pt, newpc); /* Sloooow with mcode addrs. */ const Instruction *savedpc = L->savedpc; L->savedpc = pt->code + pc + 1; if (L->hookmask > LUA_MASKLINE && L->hookcount == 0) { resethookcount(L); luaD_callhook(L, LUA_HOOKCOUNT, -1); } if (L->hookmask & LUA_MASKLINE) { int newline = getline(pt, pc); if (pc != 0) { int oldpc = luaJIT_findpc(pt, savedpc); if (!(pc <= oldpc || newline != getline(pt, oldpc))) return; } luaD_callhook(L, LUA_HOOKLINE, newline); }}/* Insert hook check for each instruction in full debug mode. */static void jit_ins_debug(jit_State *J, int openop){ if (openop) { dasm_put(Dst, 594, Dt1(->top)); } dasm_put(Dst, 598);}/* Called before every instruction. */static void jit_ins_start(jit_State *J){ dasm_put(Dst, 663, J->nextpc);}/* Chain to another instruction. */static void jit_ins_chainto(jit_State *J, int pc){ dasm_put(Dst, 665, pc);}/* Set PC label. */static void jit_ins_setpc(jit_State *J, int pc, void *target){ dasm_put(Dst, 668, pc, (ptrdiff_t)(target));}/* Called after the last instruction has been encoded. */static void jit_ins_last(jit_State *J, int lastpc, int sizemfm){ if (J->tflags & JIT_TF_USED_DEOPT) { /* Deopt section has been used? */ dasm_put(Dst, 671); dasm_put(Dst, 673); } dasm_put(Dst, 678, lastpc+1); dasm_put(Dst, 681, lastpc+2); dasm_put(Dst, 690, sizemfm);}/* Add a deoptimize target for the current instruction. */static void jit_deopt_target(jit_State *J, int nargs){ if (nargs != -1) { dasm_put(Dst, 671); dasm_put(Dst, 702, (ptrdiff_t)(J->nextins)); J->tflags |= JIT_TF_USED_DEOPT; } else { dasm_put(Dst, 679); dasm_put(Dst, 709, (ptrdiff_t)(J->nextins)); }}/* luaC_checkGC() inlined. Destroys caller-saves + TOP (edi). Uses label 7:. *//* Use this only at the _end_ of an instruction. */static void jit_checkGC(jit_State *J){ dasm_put(Dst, 718, Dt1(->l_G), Dt6(->totalbytes), Dt6(->GCthreshold));}/* ------------------------------------------------------------------------ *//*** Function inlining support for x86 CPUs.** Copyright (C) 2005-2007 Mike Pall. See Copyright Notice in luajit.h*//* ------------------------------------------------------------------------ *//* Private structure holding function inlining info. */typedef struct jit_InlineInfo { int func; /* Function slot. 1st arg slot = func+1. */ int res; /* 1st result slot. Overlaps func/ci->func. */ int nargs; /* Number of args. */ int nresults; /* Number of results. */ int xnargs; /* Expected number of args. */ int xnresults; /* Returned number of results. */ int hidx; /* Library/function index numbers. */} jit_InlineInfo;/* ------------------------------------------------------------------------ */enum { TFOR_FUNC, TFOR_TAB, TFOR_CTL, TFOR_KEY, TFOR_VAL };static void jit_inline_base(jit_State *J, jit_InlineInfo *ii){ int func = ii->func; switch (JIT_IH_IDX(ii->hidx)) { case JIT_IH_BASE_PAIRS: case JIT_IH_BASE_IPAIRS: dasm_put(Dst, 753, Dt2([func+TFOR_TAB].tt), Dt2([func+TFOR_CTL].tt), Dt2([func+TFOR_CTL].value)); dasm_put(Dst, 771, JIT_MFM_DEOPT_PAIRS, J->nextpc-1); break; default: jit_assert(0); break; }}/* ------------------------------------------------------------------------ */#ifndef COCO_DISABLE/* Helper function for inlined coroutine.resume(). */static StkId jit_coroutine_resume(lua_State *L, StkId base, int nresults){ lua_State *co = thvalue(base-1); /* Check for proper usage. Merge of lua_resume() and auxresume() checks. */ if (co->status != LUA_YIELD) { if (co->status > LUA_YIELD) {errdead: setsvalue(L, base-1, luaS_newliteral(L, "cannot resume dead coroutine")); goto err; } else if (co->ci != co->base_ci) { setsvalue(L, base-1, luaS_newliteral(L, "cannot resume non-suspended coroutine")); goto err; } else if (co->base == co->top) { goto errdead; } } { unsigned int ndelta = (char *)L->top - (char *)base; int nargs = ndelta/sizeof(TValue); /* Compute nargs. */ int status; if ((char *)co->stack_last-(char *)co->top <= ndelta) { co->ci->top = (StkId)(((char *)co->top) + ndelta); /* Ok before grow. */ luaD_growstack(co, nargs); /* Grow thread stack. */ }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -