lib_jit.c (20777B)
1 /* 2 ** JIT library. 3 ** Copyright (C) 2005-2016 Mike Pall. See Copyright Notice in luajit.h 4 */ 5 6 #define lib_jit_c 7 #define LUA_LIB 8 9 #include "lua.h" 10 #include "lauxlib.h" 11 #include "lualib.h" 12 13 #include "lj_obj.h" 14 #include "lj_gc.h" 15 #include "lj_err.h" 16 #include "lj_debug.h" 17 #include "lj_str.h" 18 #include "lj_tab.h" 19 #include "lj_state.h" 20 #include "lj_bc.h" 21 #if LJ_HASFFI 22 #include "lj_ctype.h" 23 #endif 24 #if LJ_HASJIT 25 #include "lj_ir.h" 26 #include "lj_jit.h" 27 #include "lj_ircall.h" 28 #include "lj_iropt.h" 29 #include "lj_target.h" 30 #endif 31 #include "lj_trace.h" 32 #include "lj_dispatch.h" 33 #include "lj_vm.h" 34 #include "lj_vmevent.h" 35 #include "lj_lib.h" 36 37 #include "luajit.h" 38 39 /* -- jit.* functions ----------------------------------------------------- */ 40 41 #define LJLIB_MODULE_jit 42 43 static int setjitmode(lua_State *L, int mode) 44 { 45 int idx = 0; 46 if (L->base == L->top || tvisnil(L->base)) { /* jit.on/off/flush([nil]) */ 47 mode |= LUAJIT_MODE_ENGINE; 48 } else { 49 /* jit.on/off/flush(func|proto, nil|true|false) */ 50 if (tvisfunc(L->base) || tvisproto(L->base)) 51 idx = 1; 52 else if (!tvistrue(L->base)) /* jit.on/off/flush(true, nil|true|false) */ 53 goto err; 54 if (L->base+1 < L->top && tvisbool(L->base+1)) 55 mode |= boolV(L->base+1) ? LUAJIT_MODE_ALLFUNC : LUAJIT_MODE_ALLSUBFUNC; 56 else 57 mode |= LUAJIT_MODE_FUNC; 58 } 59 if (luaJIT_setmode(L, idx, mode) != 1) { 60 if ((mode & LUAJIT_MODE_MASK) == LUAJIT_MODE_ENGINE) 61 lj_err_caller(L, LJ_ERR_NOJIT); 62 err: 63 lj_err_argt(L, 1, LUA_TFUNCTION); 64 } 65 return 0; 66 } 67 68 LJLIB_CF(jit_on) 69 { 70 return setjitmode(L, LUAJIT_MODE_ON); 71 } 72 73 LJLIB_CF(jit_off) 74 { 75 return setjitmode(L, LUAJIT_MODE_OFF); 76 } 77 78 LJLIB_CF(jit_flush) 79 { 80 #if LJ_HASJIT 81 if (L->base < L->top && tvisnumber(L->base)) { 82 int traceno = lj_lib_checkint(L, 1); 83 luaJIT_setmode(L, traceno, LUAJIT_MODE_FLUSH|LUAJIT_MODE_TRACE); 84 return 0; 85 } 86 #endif 87 return setjitmode(L, LUAJIT_MODE_FLUSH); 88 } 89 90 #if LJ_HASJIT 91 /* Push a string for every flag bit that is set. */ 92 static void flagbits_to_strings(lua_State *L, uint32_t flags, uint32_t base, 93 const char *str) 94 { 95 for (; *str; base <<= 1, str += 1+*str) 96 if (flags & base) 97 setstrV(L, L->top++, lj_str_new(L, str+1, *(uint8_t *)str)); 98 } 99 #endif 100 101 LJLIB_CF(jit_status) 102 { 103 #if LJ_HASJIT 104 jit_State *J = L2J(L); 105 L->top = L->base; 106 setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0); 107 flagbits_to_strings(L, J->flags, JIT_F_CPU_FIRST, JIT_F_CPUSTRING); 108 flagbits_to_strings(L, J->flags, JIT_F_OPT_FIRST, JIT_F_OPTSTRING); 109 return (int)(L->top - L->base); 110 #else 111 setboolV(L->top++, 0); 112 return 1; 113 #endif 114 } 115 116 LJLIB_CF(jit_attach) 117 { 118 #ifdef LUAJIT_DISABLE_VMEVENT 119 luaL_error(L, "vmevent API disabled"); 120 #else 121 GCfunc *fn = lj_lib_checkfunc(L, 1); 122 GCstr *s = lj_lib_optstr(L, 2); 123 luaL_findtable(L, LUA_REGISTRYINDEX, LJ_VMEVENTS_REGKEY, LJ_VMEVENTS_HSIZE); 124 if (s) { /* Attach to given event. */ 125 const uint8_t *p = (const uint8_t *)strdata(s); 126 uint32_t h = s->len; 127 while (*p) h = h ^ (lj_rol(h, 6) + *p++); 128 lua_pushvalue(L, 1); 129 lua_rawseti(L, -2, VMEVENT_HASHIDX(h)); 130 G(L)->vmevmask = VMEVENT_NOCACHE; /* Invalidate cache. */ 131 } else { /* Detach if no event given. */ 132 setnilV(L->top++); 133 while (lua_next(L, -2)) { 134 L->top--; 135 if (tvisfunc(L->top) && funcV(L->top) == fn) { 136 setnilV(lj_tab_set(L, tabV(L->top-2), L->top-1)); 137 } 138 } 139 } 140 #endif 141 return 0; 142 } 143 144 LJLIB_PUSH(top-5) LJLIB_SET(os) 145 LJLIB_PUSH(top-4) LJLIB_SET(arch) 146 LJLIB_PUSH(top-3) LJLIB_SET(version_num) 147 LJLIB_PUSH(top-2) LJLIB_SET(version) 148 149 #include "lj_libdef.h" 150 151 /* -- jit.util.* functions ------------------------------------------------ */ 152 153 #define LJLIB_MODULE_jit_util 154 155 /* -- Reflection API for Lua functions ------------------------------------ */ 156 157 /* Return prototype of first argument (Lua function or prototype object) */ 158 static GCproto *check_Lproto(lua_State *L, int nolua) 159 { 160 TValue *o = L->base; 161 if (L->top > o) { 162 if (tvisproto(o)) { 163 return protoV(o); 164 } else if (tvisfunc(o)) { 165 if (isluafunc(funcV(o))) 166 return funcproto(funcV(o)); 167 else if (nolua) 168 return NULL; 169 } 170 } 171 lj_err_argt(L, 1, LUA_TFUNCTION); 172 return NULL; /* unreachable */ 173 } 174 175 static void setintfield(lua_State *L, GCtab *t, const char *name, int32_t val) 176 { 177 setintV(lj_tab_setstr(L, t, lj_str_newz(L, name)), val); 178 } 179 180 /* local info = jit.util.funcinfo(func [,pc]) */ 181 LJLIB_CF(jit_util_funcinfo) 182 { 183 GCproto *pt = check_Lproto(L, 1); 184 if (pt) { 185 BCPos pc = (BCPos)lj_lib_optint(L, 2, 0); 186 GCtab *t; 187 int i; 188 lua_createtable(L, 0, 17); /* Increment hash size if fields are added. */ 189 t = tabV(L->top-1); 190 setintfield(L, t, "linedefined", pt->firstline); 191 setintfield(L, t, "lastlinedefined", pt->firstline + pt->numline); 192 setintfield(L, t, "stackslots", pt->framesize); 193 setintfield(L, t, "params", pt->numparams); 194 setintfield(L, t, "bytecodes", (int32_t)pt->sizebc); 195 setintfield(L, t, "gcconsts", (int32_t)pt->sizekgc); 196 setintfield(L, t, "nconsts", (int32_t)pt->sizekn); 197 setintfield(L, t, "upvalues", (int32_t)pt->sizeuv); 198 if (pc < pt->sizebc) 199 setintfield(L, t, "currentline", lj_debug_line(pt, pc)); 200 lua_pushboolean(L, (pt->flags & PROTO_VARARG)); 201 lua_setfield(L, -2, "isvararg"); 202 lua_pushboolean(L, (pt->flags & PROTO_CHILD)); 203 lua_setfield(L, -2, "children"); 204 setstrV(L, L->top++, proto_chunkname(pt)); 205 lua_setfield(L, -2, "source"); 206 lj_debug_pushloc(L, pt, pc); 207 lua_setfield(L, -2, "loc"); 208 /* UV prototype fields. TBD: ditto for consts? */ 209 lua_createtable(L, pt->sizeuv+1, 0); 210 for (i = 0; i < pt->sizeuv; i++) 211 setintV(lj_tab_setint(L, tabV(L->top-1), i+1), proto_uv(pt)[i]); 212 lua_setfield(L, -2, "uvinit"); 213 } else { 214 GCfunc *fn = funcV(L->base); 215 GCtab *t; 216 lua_createtable(L, 0, 4); /* Increment hash size if fields are added. */ 217 t = tabV(L->top-1); 218 if (!iscfunc(fn)) 219 setintfield(L, t, "ffid", fn->c.ffid); 220 setintptrV(lj_tab_setstr(L, t, lj_str_newlit(L, "addr")), 221 (intptr_t)(void *)fn->c.f); 222 setintfield(L, t, "upvalues", fn->c.nupvalues); 223 } 224 return 1; 225 } 226 227 /* local ins, m = jit.util.funcbc(func, pc) */ 228 LJLIB_CF(jit_util_funcbc) 229 { 230 GCproto *pt = check_Lproto(L, 0); 231 BCPos pc = (BCPos)lj_lib_checkint(L, 2); 232 if (pc < pt->sizebc) { 233 BCIns ins = proto_bc(pt)[pc]; 234 BCOp op = bc_op(ins); 235 lua_assert(op < BC__MAX); 236 setintV(L->top, ins); 237 setintV(L->top+1, lj_bc_mode[op]); 238 L->top += 2; 239 return 2; 240 } 241 return 0; 242 } 243 244 /* local k = jit.util.funck(func, idx) */ 245 LJLIB_CF(jit_util_funck) 246 { 247 GCproto *pt = check_Lproto(L, 0); 248 ptrdiff_t idx = (ptrdiff_t)lj_lib_checkint(L, 2); 249 if (idx >= 0) { 250 if (idx < (ptrdiff_t)pt->sizekn) { 251 copyTV(L, L->top-1, proto_knumtv(pt, idx)); 252 return 1; 253 } 254 } else { 255 if (~idx < (ptrdiff_t)pt->sizekgc) { 256 GCobj *gc = proto_kgc(pt, idx); 257 setgcV(L, L->top-1, gc, ~gc->gch.gct); 258 return 1; 259 } 260 } 261 return 0; 262 } 263 264 /* local name = jit.util.funcuvname(func, idx) */ 265 LJLIB_CF(jit_util_funcuvname) 266 { 267 GCproto *pt = check_Lproto(L, 0); 268 uint32_t idx = (uint32_t)lj_lib_checkint(L, 2); 269 if (idx < pt->sizeuv) { 270 setstrV(L, L->top-1, lj_str_newz(L, lj_debug_uvname(pt, idx))); 271 return 1; 272 } 273 return 0; 274 } 275 276 /* -- Reflection API for traces ------------------------------------------- */ 277 278 #if LJ_HASJIT 279 280 /* Check trace argument. Must not throw for non-existent trace numbers. */ 281 static GCtrace *jit_checktrace(lua_State *L) 282 { 283 TraceNo tr = (TraceNo)lj_lib_checkint(L, 1); 284 jit_State *J = L2J(L); 285 if (tr > 0 && tr < J->sizetrace) 286 return traceref(J, tr); 287 return NULL; 288 } 289 290 /* Names of link types. ORDER LJ_TRLINK */ 291 static const char *const jit_trlinkname[] = { 292 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion", 293 "interpreter", "return", "stitch" 294 }; 295 296 /* local info = jit.util.traceinfo(tr) */ 297 LJLIB_CF(jit_util_traceinfo) 298 { 299 GCtrace *T = jit_checktrace(L); 300 if (T) { 301 GCtab *t; 302 lua_createtable(L, 0, 8); /* Increment hash size if fields are added. */ 303 t = tabV(L->top-1); 304 setintfield(L, t, "nins", (int32_t)T->nins - REF_BIAS - 1); 305 setintfield(L, t, "nk", REF_BIAS - (int32_t)T->nk); 306 setintfield(L, t, "link", T->link); 307 setintfield(L, t, "nexit", T->nsnap); 308 setstrV(L, L->top++, lj_str_newz(L, jit_trlinkname[T->linktype])); 309 lua_setfield(L, -2, "linktype"); 310 /* There are many more fields. Add them only when needed. */ 311 return 1; 312 } 313 return 0; 314 } 315 316 /* local m, ot, op1, op2, prev = jit.util.traceir(tr, idx) */ 317 LJLIB_CF(jit_util_traceir) 318 { 319 GCtrace *T = jit_checktrace(L); 320 IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS; 321 if (T && ref >= REF_BIAS && ref < T->nins) { 322 IRIns *ir = &T->ir[ref]; 323 int32_t m = lj_ir_mode[ir->o]; 324 setintV(L->top-2, m); 325 setintV(L->top-1, ir->ot); 326 setintV(L->top++, (int32_t)ir->op1 - (irm_op1(m)==IRMref ? REF_BIAS : 0)); 327 setintV(L->top++, (int32_t)ir->op2 - (irm_op2(m)==IRMref ? REF_BIAS : 0)); 328 setintV(L->top++, ir->prev); 329 return 5; 330 } 331 return 0; 332 } 333 334 /* local k, t [, slot] = jit.util.tracek(tr, idx) */ 335 LJLIB_CF(jit_util_tracek) 336 { 337 GCtrace *T = jit_checktrace(L); 338 IRRef ref = (IRRef)lj_lib_checkint(L, 2) + REF_BIAS; 339 if (T && ref >= T->nk && ref < REF_BIAS) { 340 IRIns *ir = &T->ir[ref]; 341 int32_t slot = -1; 342 if (ir->o == IR_KSLOT) { 343 slot = ir->op2; 344 ir = &T->ir[ir->op1]; 345 } 346 #if LJ_HASFFI 347 if (ir->o == IR_KINT64 && !ctype_ctsG(G(L))) { 348 ptrdiff_t oldtop = savestack(L, L->top); 349 luaopen_ffi(L); /* Load FFI library on-demand. */ 350 L->top = restorestack(L, oldtop); 351 } 352 #endif 353 lj_ir_kvalue(L, L->top-2, ir); 354 setintV(L->top-1, (int32_t)irt_type(ir->t)); 355 if (slot == -1) 356 return 2; 357 setintV(L->top++, slot); 358 return 3; 359 } 360 return 0; 361 } 362 363 /* local snap = jit.util.tracesnap(tr, sn) */ 364 LJLIB_CF(jit_util_tracesnap) 365 { 366 GCtrace *T = jit_checktrace(L); 367 SnapNo sn = (SnapNo)lj_lib_checkint(L, 2); 368 if (T && sn < T->nsnap) { 369 SnapShot *snap = &T->snap[sn]; 370 SnapEntry *map = &T->snapmap[snap->mapofs]; 371 MSize n, nent = snap->nent; 372 GCtab *t; 373 lua_createtable(L, nent+2, 0); 374 t = tabV(L->top-1); 375 setintV(lj_tab_setint(L, t, 0), (int32_t)snap->ref - REF_BIAS); 376 setintV(lj_tab_setint(L, t, 1), (int32_t)snap->nslots); 377 for (n = 0; n < nent; n++) 378 setintV(lj_tab_setint(L, t, (int32_t)(n+2)), (int32_t)map[n]); 379 setintV(lj_tab_setint(L, t, (int32_t)(nent+2)), (int32_t)SNAP(255, 0, 0)); 380 return 1; 381 } 382 return 0; 383 } 384 385 /* local mcode, addr, loop = jit.util.tracemc(tr) */ 386 LJLIB_CF(jit_util_tracemc) 387 { 388 GCtrace *T = jit_checktrace(L); 389 if (T && T->mcode != NULL) { 390 setstrV(L, L->top-1, lj_str_new(L, (const char *)T->mcode, T->szmcode)); 391 setintptrV(L->top++, (intptr_t)(void *)T->mcode); 392 setintV(L->top++, T->mcloop); 393 return 3; 394 } 395 return 0; 396 } 397 398 /* local addr = jit.util.traceexitstub([tr,] exitno) */ 399 LJLIB_CF(jit_util_traceexitstub) 400 { 401 #ifdef EXITSTUBS_PER_GROUP 402 ExitNo exitno = (ExitNo)lj_lib_checkint(L, 1); 403 jit_State *J = L2J(L); 404 if (exitno < EXITSTUBS_PER_GROUP*LJ_MAX_EXITSTUBGR) { 405 setintptrV(L->top-1, (intptr_t)(void *)exitstub_addr(J, exitno)); 406 return 1; 407 } 408 #else 409 if (L->top > L->base+1) { /* Don't throw for one-argument variant. */ 410 GCtrace *T = jit_checktrace(L); 411 ExitNo exitno = (ExitNo)lj_lib_checkint(L, 2); 412 ExitNo maxexit = T->root ? T->nsnap+1 : T->nsnap; 413 if (T && T->mcode != NULL && exitno < maxexit) { 414 setintptrV(L->top-1, (intptr_t)(void *)exitstub_trace_addr(T, exitno)); 415 return 1; 416 } 417 } 418 #endif 419 return 0; 420 } 421 422 /* local addr = jit.util.ircalladdr(idx) */ 423 LJLIB_CF(jit_util_ircalladdr) 424 { 425 uint32_t idx = (uint32_t)lj_lib_checkint(L, 1); 426 if (idx < IRCALL__MAX) { 427 setintptrV(L->top-1, (intptr_t)(void *)lj_ir_callinfo[idx].func); 428 return 1; 429 } 430 return 0; 431 } 432 433 #endif 434 435 #include "lj_libdef.h" 436 437 static int luaopen_jit_util(lua_State *L) 438 { 439 LJ_LIB_REG(L, NULL, jit_util); 440 return 1; 441 } 442 443 /* -- jit.opt module ------------------------------------------------------ */ 444 445 #if LJ_HASJIT 446 447 #define LJLIB_MODULE_jit_opt 448 449 /* Parse optimization level. */ 450 static int jitopt_level(jit_State *J, const char *str) 451 { 452 if (str[0] >= '0' && str[0] <= '9' && str[1] == '\0') { 453 uint32_t flags; 454 if (str[0] == '0') flags = JIT_F_OPT_0; 455 else if (str[0] == '1') flags = JIT_F_OPT_1; 456 else if (str[0] == '2') flags = JIT_F_OPT_2; 457 else flags = JIT_F_OPT_3; 458 J->flags = (J->flags & ~JIT_F_OPT_MASK) | flags; 459 return 1; /* Ok. */ 460 } 461 return 0; /* No match. */ 462 } 463 464 /* Parse optimization flag. */ 465 static int jitopt_flag(jit_State *J, const char *str) 466 { 467 const char *lst = JIT_F_OPTSTRING; 468 uint32_t opt; 469 int set = 1; 470 if (str[0] == '+') { 471 str++; 472 } else if (str[0] == '-') { 473 str++; 474 set = 0; 475 } else if (str[0] == 'n' && str[1] == 'o') { 476 str += str[2] == '-' ? 3 : 2; 477 set = 0; 478 } 479 for (opt = JIT_F_OPT_FIRST; ; opt <<= 1) { 480 size_t len = *(const uint8_t *)lst; 481 if (len == 0) 482 break; 483 if (strncmp(str, lst+1, len) == 0 && str[len] == '\0') { 484 if (set) J->flags |= opt; else J->flags &= ~opt; 485 return 1; /* Ok. */ 486 } 487 lst += 1+len; 488 } 489 return 0; /* No match. */ 490 } 491 492 /* Parse optimization parameter. */ 493 static int jitopt_param(jit_State *J, const char *str) 494 { 495 const char *lst = JIT_P_STRING; 496 int i; 497 for (i = 0; i < JIT_P__MAX; i++) { 498 size_t len = *(const uint8_t *)lst; 499 lua_assert(len != 0); 500 if (strncmp(str, lst+1, len) == 0 && str[len] == '=') { 501 int32_t n = 0; 502 const char *p = &str[len+1]; 503 while (*p >= '0' && *p <= '9') 504 n = n*10 + (*p++ - '0'); 505 if (*p) return 0; /* Malformed number. */ 506 J->param[i] = n; 507 if (i == JIT_P_hotloop) 508 lj_dispatch_init_hotcount(J2G(J)); 509 return 1; /* Ok. */ 510 } 511 lst += 1+len; 512 } 513 return 0; /* No match. */ 514 } 515 516 /* jit.opt.start(flags...) */ 517 LJLIB_CF(jit_opt_start) 518 { 519 jit_State *J = L2J(L); 520 int nargs = (int)(L->top - L->base); 521 if (nargs == 0) { 522 J->flags = (J->flags & ~JIT_F_OPT_MASK) | JIT_F_OPT_DEFAULT; 523 } else { 524 int i; 525 for (i = 1; i <= nargs; i++) { 526 const char *str = strdata(lj_lib_checkstr(L, i)); 527 if (!jitopt_level(J, str) && 528 !jitopt_flag(J, str) && 529 !jitopt_param(J, str)) 530 lj_err_callerv(L, LJ_ERR_JITOPT, str); 531 } 532 } 533 return 0; 534 } 535 536 #include "lj_libdef.h" 537 538 #endif 539 540 /* -- jit.profile module -------------------------------------------------- */ 541 542 #if LJ_HASPROFILE 543 544 #define LJLIB_MODULE_jit_profile 545 546 /* Not loaded by default, use: local profile = require("jit.profile") */ 547 548 static const char KEY_PROFILE_THREAD = 't'; 549 static const char KEY_PROFILE_FUNC = 'f'; 550 551 static void jit_profile_callback(lua_State *L2, lua_State *L, int samples, 552 int vmstate) 553 { 554 TValue key; 555 cTValue *tv; 556 setlightudV(&key, (void *)&KEY_PROFILE_FUNC); 557 tv = lj_tab_get(L, tabV(registry(L)), &key); 558 if (tvisfunc(tv)) { 559 char vmst = (char)vmstate; 560 int status; 561 setfuncV(L2, L2->top++, funcV(tv)); 562 setthreadV(L2, L2->top++, L); 563 setintV(L2->top++, samples); 564 setstrV(L2, L2->top++, lj_str_new(L2, &vmst, 1)); 565 status = lua_pcall(L2, 3, 0, 0); /* callback(thread, samples, vmstate) */ 566 if (status) { 567 if (G(L2)->panic) G(L2)->panic(L2); 568 exit(EXIT_FAILURE); 569 } 570 lj_trace_abort(G(L2)); 571 } 572 } 573 574 /* profile.start(mode, cb) */ 575 LJLIB_CF(jit_profile_start) 576 { 577 GCtab *registry = tabV(registry(L)); 578 GCstr *mode = lj_lib_optstr(L, 1); 579 GCfunc *func = lj_lib_checkfunc(L, 2); 580 lua_State *L2 = lua_newthread(L); /* Thread that runs profiler callback. */ 581 TValue key; 582 /* Anchor thread and function in registry. */ 583 setlightudV(&key, (void *)&KEY_PROFILE_THREAD); 584 setthreadV(L, lj_tab_set(L, registry, &key), L2); 585 setlightudV(&key, (void *)&KEY_PROFILE_FUNC); 586 setfuncV(L, lj_tab_set(L, registry, &key), func); 587 lj_gc_anybarriert(L, registry); 588 luaJIT_profile_start(L, mode ? strdata(mode) : "", 589 (luaJIT_profile_callback)jit_profile_callback, L2); 590 return 0; 591 } 592 593 /* profile.stop() */ 594 LJLIB_CF(jit_profile_stop) 595 { 596 GCtab *registry; 597 TValue key; 598 luaJIT_profile_stop(L); 599 registry = tabV(registry(L)); 600 setlightudV(&key, (void *)&KEY_PROFILE_THREAD); 601 setnilV(lj_tab_set(L, registry, &key)); 602 setlightudV(&key, (void *)&KEY_PROFILE_FUNC); 603 setnilV(lj_tab_set(L, registry, &key)); 604 lj_gc_anybarriert(L, registry); 605 return 0; 606 } 607 608 /* dump = profile.dumpstack([thread,] fmt, depth) */ 609 LJLIB_CF(jit_profile_dumpstack) 610 { 611 lua_State *L2 = L; 612 int arg = 0; 613 size_t len; 614 int depth; 615 GCstr *fmt; 616 const char *p; 617 if (L->top > L->base && tvisthread(L->base)) { 618 L2 = threadV(L->base); 619 arg = 1; 620 } 621 fmt = lj_lib_checkstr(L, arg+1); 622 depth = lj_lib_checkint(L, arg+2); 623 p = luaJIT_profile_dumpstack(L2, strdata(fmt), depth, &len); 624 lua_pushlstring(L, p, len); 625 return 1; 626 } 627 628 #include "lj_libdef.h" 629 630 static int luaopen_jit_profile(lua_State *L) 631 { 632 LJ_LIB_REG(L, NULL, jit_profile); 633 return 1; 634 } 635 636 #endif 637 638 /* -- JIT compiler initialization ----------------------------------------- */ 639 640 #if LJ_HASJIT 641 /* Default values for JIT parameters. */ 642 static const int32_t jit_param_default[JIT_P__MAX+1] = { 643 #define JIT_PARAMINIT(len, name, value) (value), 644 JIT_PARAMDEF(JIT_PARAMINIT) 645 #undef JIT_PARAMINIT 646 0 647 }; 648 #endif 649 650 #if LJ_TARGET_ARM && LJ_TARGET_LINUX 651 #include <sys/utsname.h> 652 #endif 653 654 /* Arch-dependent CPU detection. */ 655 static uint32_t jit_cpudetect(lua_State *L) 656 { 657 uint32_t flags = 0; 658 #if LJ_TARGET_X86ORX64 659 uint32_t vendor[4]; 660 uint32_t features[4]; 661 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) { 662 #if !LJ_HASJIT 663 #define JIT_F_SSE2 2 664 #endif 665 flags |= ((features[3] >> 26)&1) * JIT_F_SSE2; 666 #if LJ_HASJIT 667 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3; 668 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1; 669 if (vendor[2] == 0x6c65746e) { /* Intel. */ 670 if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */ 671 flags |= JIT_F_LEA_AGU; 672 } else if (vendor[2] == 0x444d4163) { /* AMD. */ 673 uint32_t fam = (features[0] & 0x0ff00f00); 674 if (fam >= 0x00000f00) /* K8, K10. */ 675 flags |= JIT_F_PREFER_IMUL; 676 } 677 if (vendor[0] >= 7) { 678 uint32_t xfeatures[4]; 679 lj_vm_cpuid(7, xfeatures); 680 flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2; 681 } 682 #endif 683 } 684 /* Check for required instruction set support on x86 (unnecessary on x64). */ 685 #if LJ_TARGET_X86 686 if (!(flags & JIT_F_SSE2)) 687 luaL_error(L, "CPU with SSE2 required"); 688 #endif 689 #elif LJ_TARGET_ARM 690 #if LJ_HASJIT 691 int ver = LJ_ARCH_VERSION; /* Compile-time ARM CPU detection. */ 692 #if LJ_TARGET_LINUX 693 if (ver < 70) { /* Runtime ARM CPU detection. */ 694 struct utsname ut; 695 uname(&ut); 696 if (strncmp(ut.machine, "armv", 4) == 0) { 697 if (ut.machine[4] >= '7') 698 ver = 70; 699 else if (ut.machine[4] == '6') 700 ver = 60; 701 } 702 } 703 #endif 704 flags |= ver >= 70 ? JIT_F_ARMV7 : 705 ver >= 61 ? JIT_F_ARMV6T2_ : 706 ver >= 60 ? JIT_F_ARMV6_ : 0; 707 flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2; 708 #endif 709 #elif LJ_TARGET_ARM64 710 /* No optional CPU features to detect (for now). */ 711 #elif LJ_TARGET_PPC 712 #if LJ_HASJIT 713 #if LJ_ARCH_SQRT 714 flags |= JIT_F_SQRT; 715 #endif 716 #if LJ_ARCH_ROUND 717 flags |= JIT_F_ROUND; 718 #endif 719 #endif 720 #elif LJ_TARGET_MIPS 721 #if LJ_HASJIT 722 /* Compile-time MIPS CPU detection. */ 723 #if LJ_ARCH_VERSION >= 20 724 flags |= JIT_F_MIPSXXR2; 725 #endif 726 /* Runtime MIPS CPU detection. */ 727 #if defined(__GNUC__) 728 if (!(flags & JIT_F_MIPSXXR2)) { 729 int x; 730 #ifdef __mips16 731 x = 0; /* Runtime detection is difficult. Ensure optimal -march flags. */ 732 #else 733 /* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */ 734 __asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x) : : "$2"); 735 #endif 736 if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */ 737 } 738 #endif 739 #endif 740 #else 741 #error "Missing CPU detection for this architecture" 742 #endif 743 UNUSED(L); 744 return flags; 745 } 746 747 /* Initialize JIT compiler. */ 748 static void jit_init(lua_State *L) 749 { 750 uint32_t flags = jit_cpudetect(L); 751 #if LJ_HASJIT 752 jit_State *J = L2J(L); 753 J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT; 754 memcpy(J->param, jit_param_default, sizeof(J->param)); 755 lj_dispatch_update(G(L)); 756 #else 757 UNUSED(flags); 758 #endif 759 } 760 761 LUALIB_API int luaopen_jit(lua_State *L) 762 { 763 jit_init(L); 764 lua_pushliteral(L, LJ_OS_NAME); 765 lua_pushliteral(L, LJ_ARCH_NAME); 766 lua_pushinteger(L, LUAJIT_VERSION_NUM); 767 lua_pushliteral(L, LJ_LJX_VERSION); 768 LJ_LIB_REG(L, LUA_JITLIBNAME, jit); 769 #if LJ_HASPROFILE 770 lj_lib_prereg(L, LUA_JITLIBNAME ".profile", luaopen_jit_profile, 771 tabref(L->env)); 772 #endif 773 #ifndef LUAJIT_DISABLE_JITUTIL 774 lj_lib_prereg(L, LUA_JITLIBNAME ".util", luaopen_jit_util, tabref(L->env)); 775 #endif 776 #if LJ_HASJIT 777 LJ_LIB_REG(L, "jit.opt", jit_opt); 778 L->top -= 1; 779 #endif 780 return 1; 781 } 782