⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ljit_x86_inline.dash

📁 采用C语言写的Lua的解释器的代码!Lua不用介绍了吧
💻 DASH
📖 第 1 页 / 共 2 页
字号:
/*** Function inlining support for x86 CPUs.** Copyright (C) 2005-2008 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:    |// Easy for regular calls: res == func. Not inlined for tailcalls.    |// Guaranteed to be inlined only if used in conjunction with TFORLOOP.    |// So we omit setting the iterator function and fake the control var.    |  istable func+TFOR_TAB; jne L_DEOPTIMIZE	// Caveat: deopt TFORLOOP, too!    |  xor eax, eax				// Assumes: LUA_TNIL == 0.    |  mov BASE[func+TFOR_CTL].tt, eax		// Fake nil type.    |  mov BASE[func+TFOR_CTL].value, eax	// Hidden control var = 0.    |//  mov BASE[func+TFOR_FUNC].tt, eax	// Kill function (not needed).    |.mfmap    |  .word JIT_MFM_DEOPT_PAIRS, J->nextpc-1	// Deoptimize TFORLOOP, too.    |.code    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. */    }    /* Copy args. */    co->top = (StkId)(((char *)co->top) + ndelta);    { StkId t = co->top, f = L->top; while (f > base) setobj2s(co, --t, --f); }    L->top = base;    status = luaCOCO_resume(co, nargs);  /* Resume Coco thread. */    if (status == 0 || status == LUA_YIELD) {  /* Ok. */      StkId f;      if (nresults == 0) return NULL;      if (nresults == -1) {	luaD_checkstack(L, co->top - co->base);  /* Grow own stack. */      }      base = L->top - 2;      setbvalue(base++, 1);  /* true */      /* Copy results. Fill unused result slots with nil. */      f = co->base;      while (--nresults != 0 && f < co->top) setobj2s(L, base++, f++);      while (nresults-- > 0) setnilvalue(base++);      co->top = co->base;      return base;    } else {  /* Error. */      base = L->top;      setobj2s(L, base-1, co->top-1);  /* Copy error object. */err:      setbvalue(base-2, 0);  /* false */      nresults -= 2;      while (--nresults >= 0) setnilvalue(base+nresults);  /* Fill results. */      return base;    }  }}static void jit_inline_coroutine(jit_State *J, jit_InlineInfo *ii){  int arg = ii->func+1;  int res = ii->res;  int i;  switch (JIT_IH_IDX(ii->hidx)) {  case JIT_IH_COROUTINE_YIELD:    |  cmp aword [L+((int)&LHASCOCO((lua_State *)0))], 0  // Got a C stack?    |  je L_DEOPTIMIZE    |  mov L->savedpc, &J->nextins		// Debugger-friendly.    |  add BASE, arg*#TVALUE    if (ii->nargs >= 0) {  /* Previous op was not open and did not set TOP. */      |  lea TOP, BASE[ii->nargs]    }    |  mov L->base, BASE    |  mov L->top, TOP    |  call &luaCOCO_yield, L    |  mov BASE, L->base    |  mov TOP, L->top    jit_assert(ii->nresults >= 0 && ii->nresults <= EXTRA_STACK);    for (i = 0; i < ii->nresults; i++) {      |  setnilvalue TOP[i]			// Clear undefined result.      |  copyslot BASE[res+i], BASE[arg+i]	// Move result down.    }    ii->nargs = -1;  /* Force restore of L->top. */    break;  case JIT_IH_COROUTINE_RESUME:    jit_assert(ii->nargs != 0 && ii->res == ii->func);    |  add BASE, (arg+1)*#TVALUE    if (ii->nargs >= 0) {  /* Previous op was not open and did not set TOP. */      |  lea TOP, BASE[ii->nargs-1]    } else {      |  cmp TOP, BASE; jb L_DEOPTIMIZE		// No thread arg? Deoptimize.    }    |  istt -1, LUA_TTHREAD; jne L_DEOPTIMIZE	// Wrong type? Deoptimize.    |  mov L:eax, BASE[-1].value    |  cmp aword [L:eax+((int)&LHASCOCO((lua_State *)0))], 0    |  je L_DEOPTIMIZE				// No C stack? Deoptimize.    |  mov L->savedpc, &J->nextins		// Debugger-friendly.    |  mov L->top, TOP    |  call &jit_coroutine_resume, L, BASE, ii->nresults    |  mov BASE, L->base    if (ii->nresults == -1) {      |  mov TOP, eax    }    ii->nargs = -1;  /* Force restore of L->top. */    break;  default:    jit_assert(0);    break;  }}#endif /* COCO_DISABLE *//* ------------------------------------------------------------------------ */static void jit_inline_string(jit_State *J, jit_InlineInfo *ii){  int arg = ii->func+1;  int res = ii->res;  switch (JIT_IH_IDX(ii->hidx)) {  case JIT_IH_STRING_LEN:    |  isstring arg; jne L_DEOPTIMIZE    |  mov TSTRING:ecx, BASE[arg].value    |  fild aword TSTRING:ecx->tsv.len	// size_t    |  settt BASE[res], LUA_TNUMBER    |  fstp qword BASE[res].value    break;  case JIT_IH_STRING_SUB:    /* TODO: inline numeric constants with help from the optimizer. */    /*       But this would save only another 15-20% in a trivial loop. */    jit_assert(ii->nargs >= 2);  /* Open op caveat is ok, too. */    if (ii->nargs > 2) {      |  lea TOP, BASE[arg]      |  call ->STRING_SUB3      |  setsvalue BASE[res], eax    } else {      |  lea TOP, BASE[arg]      |  call ->STRING_SUB2      |  setsvalue BASE[res], eax    }    break;  case JIT_IH_STRING_CHAR:    |  isnumber arg; jne L_DEOPTIMIZE    |  lea eax, L->env			// Abuse L->env to hold temp string.    |  fld qword BASE[arg].value    |  fistp dword [eax]		// LSB is at start (little-endian).    |  cmp dword [eax], 255; ja L_DEOPTIMIZE    |  call &luaS_newlstr, L, eax, 1    |  setsvalue BASE[res], eax    break;  default:    jit_assert(0);    break;  }  |//-----------------------------------------------------------------------  |.jsub STRING_SUB3			// string.sub(str, start, end)  |  mov eax, TOP[0].tt; shl eax, 4; or eax, TOP[1].tt; shl eax, 4  |  or eax, TOP[2].tt; sub eax, LUA_TSTR_NUM_NUM  |  jne ->DEOPTIMIZE_CALLER		// Wrong types? Deoptimize.  |  // eax must be zero here!  |   fld qword TOP[1].value  |  fld qword TOP[2].value  |  fistp aword TMP3			// size_t  |   fistp aword TMP2			// size_t  |   mov TSTRING:ecx, TOP[0].value  |   mov TOP, aword TSTRING:ecx->tsv.len  // size_t  |  mov edx, TMP3  |   cmp TOP, edx  |  jb >4  |1:  |  or eax, TMP2			// eax is known to be zero.  |  jle >6				// start <= 0?  |2:  |  sub edx, eax			// newlen = end-start  |  jl >7				// start > end?  |  lea ecx, [TSTRING:ecx+eax+#TSTRING-1]  // svalue()-1+start  |  inc edx  |3:  |  mov ARG2, L			// First arg for tailcall is ARG2.  |  mov ARG3, ecx			// Pointer to start.  |  mov ARG4, edx			// Length.  |   mov GL:edi, L->l_G  |   mov eax, GL:edi->totalbytes	// size_t  |   cmp eax, GL:edi->GCthreshold	// size_t  |   jae >8				// G->totalbytes >= G->GCthreshold?  |  jmp &luaS_newlstr			// Tailcall to C function.  |  |4:  // Negative end or overflow.  |  jl >5  |  lea edx, [edx+TOP+1]		// end = end+(len+1)  |  jmp <1  |5:  // Overflow  |  mov edx, TOP			// end = len  |  jmp <1  |  |6:  // Negative start or underflow.  |  je >5  |  add eax, TOP			// start = start+(len+1)  |  inc eax  |  jg <2				// start > 0?  |5:  // Underflow.  |  mov eax, 1				// start = 1  |  jmp <2  |  |7:  // Range underflow.  |  xor edx, edx			// Zero length.  |  jmp <3				// Any pointer in ecx is ok.  |.endjsub  |  |//-----------------------------------------------------------------------  |.jsub STRING_SUB2			// string.sub(str, start)  |  mov eax, TOP[0].tt; shl eax, 4; or eax, TOP[1].tt; sub eax, LUA_TSTR_NUM  |  jne ->DEOPTIMIZE_CALLER		// Wrong types? Deoptimize.  |  // eax must be zero here!  |  fld qword TOP[1].value  |  fistp aword TMP2			// size_t  |  mov TSTRING:ecx, TOP[0].value  |  mov TOP, aword TSTRING:ecx->tsv.len // size_t  |  mov edx, TOP  |  jmp <1				// See STRING_SUB3.  |  |8:  // GC threshold reached.  |  sub esp, FRAME_OFFSET  |  call &luaC_step, L  |  add esp, FRAME_OFFSET  |  mov BASE, L->base  |  jmp &luaS_newlstr			// Tailcall to C function.  |.endjsub}/* ------------------------------------------------------------------------ *//* Helper functions for inlined calls to table.*. */static void jit_table_insert(lua_State *L, TValue *arg){  setobj2t(L, luaH_setnum(L, hvalue(arg), luaH_getn(hvalue(arg))+1), arg+1);  luaC_barriert(L, hvalue(arg), arg+1);}static TValue *jit_table_remove(lua_State *L, TValue *arg, TValue *res){  int n = luaH_getn(hvalue(arg));  if (n == 0) {    setnilvalue(res);  /* For the nresults == 1 case. Harmless otherwise. */    return res;  /* For the nresults == -1 case. */  } else {    TValue *val = luaH_setnum(L, hvalue(arg), n);    setobj2s(L, res, val);    setnilvalue(val);    return res+1;  /* For the nresults == -1 case. */  }}static void jit_inline_table(jit_State *J, jit_InlineInfo *ii){  int arg = ii->func+1;  int res = ii->res;  |  istable arg; jne L_DEOPTIMIZE  switch (JIT_IH_IDX(ii->hidx)) {  case JIT_IH_TABLE_INSERT:    jit_assert(ii->nargs == 2);    |  lea TVALUE:eax, BASE[arg]    |  call &jit_table_insert, L, TVALUE:eax    break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -