aboutsummaryrefslogtreecommitdiff
path: root/src/lib_jit.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib_jit.c159
1 files changed, 134 insertions, 25 deletions
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 921b84c8..c6330c49 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -10,13 +10,17 @@
10#include "lauxlib.h" 10#include "lauxlib.h"
11#include "lualib.h" 11#include "lualib.h"
12 12
13#include "lj_arch.h"
14#include "lj_obj.h" 13#include "lj_obj.h"
14#include "lj_gc.h"
15#include "lj_err.h" 15#include "lj_err.h"
16#include "lj_debug.h" 16#include "lj_debug.h"
17#include "lj_str.h" 17#include "lj_str.h"
18#include "lj_tab.h" 18#include "lj_tab.h"
19#include "lj_state.h"
19#include "lj_bc.h" 20#include "lj_bc.h"
21#if LJ_HASFFI
22#include "lj_ctype.h"
23#endif
20#if LJ_HASJIT 24#if LJ_HASJIT
21#include "lj_ir.h" 25#include "lj_ir.h"
22#include "lj_jit.h" 26#include "lj_jit.h"
@@ -24,6 +28,7 @@
24#include "lj_iropt.h" 28#include "lj_iropt.h"
25#include "lj_target.h" 29#include "lj_target.h"
26#endif 30#endif
31#include "lj_trace.h"
27#include "lj_dispatch.h" 32#include "lj_dispatch.h"
28#include "lj_vm.h" 33#include "lj_vm.h"
29#include "lj_vmevent.h" 34#include "lj_vmevent.h"
@@ -279,7 +284,7 @@ static GCtrace *jit_checktrace(lua_State *L)
279/* Names of link types. ORDER LJ_TRLINK */ 284/* Names of link types. ORDER LJ_TRLINK */
280static const char *const jit_trlinkname[] = { 285static const char *const jit_trlinkname[] = {
281 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion", 286 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
282 "interpreter", "return" 287 "interpreter", "return", "stitch"
283}; 288};
284 289
285/* local info = jit.util.traceinfo(tr) */ 290/* local info = jit.util.traceinfo(tr) */
@@ -332,6 +337,13 @@ LJLIB_CF(jit_util_tracek)
332 slot = ir->op2; 337 slot = ir->op2;
333 ir = &T->ir[ir->op1]; 338 ir = &T->ir[ir->op1];
334 } 339 }
340#if LJ_HASFFI
341 if (ir->o == IR_KINT64 && !ctype_ctsG(G(L))) {
342 ptrdiff_t oldtop = savestack(L, L->top);
343 luaopen_ffi(L); /* Load FFI library on-demand. */
344 L->top = restorestack(L, oldtop);
345 }
346#endif
335 lj_ir_kvalue(L, L->top-2, ir); 347 lj_ir_kvalue(L, L->top-2, ir);
336 setintV(L->top-1, (int32_t)irt_type(ir->t)); 348 setintV(L->top-1, (int32_t)irt_type(ir->t));
337 if (slot == -1) 349 if (slot == -1)
@@ -416,6 +428,12 @@ LJLIB_CF(jit_util_ircalladdr)
416 428
417#include "lj_libdef.h" 429#include "lj_libdef.h"
418 430
431static int luaopen_jit_util(lua_State *L)
432{
433 LJ_LIB_REG(L, NULL, jit_util);
434 return 1;
435}
436
419/* -- jit.opt module ------------------------------------------------------ */ 437/* -- jit.opt module ------------------------------------------------------ */
420 438
421#if LJ_HASJIT 439#if LJ_HASJIT
@@ -513,6 +531,104 @@ LJLIB_CF(jit_opt_start)
513 531
514#endif 532#endif
515 533
534/* -- jit.profile module -------------------------------------------------- */
535
536#if LJ_HASPROFILE
537
538#define LJLIB_MODULE_jit_profile
539
540/* Not loaded by default, use: local profile = require("jit.profile") */
541
542static const char KEY_PROFILE_THREAD = 't';
543static const char KEY_PROFILE_FUNC = 'f';
544
545static void jit_profile_callback(lua_State *L2, lua_State *L, int samples,
546 int vmstate)
547{
548 TValue key;
549 cTValue *tv;
550 setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
551 tv = lj_tab_get(L, tabV(registry(L)), &key);
552 if (tvisfunc(tv)) {
553 char vmst = (char)vmstate;
554 int status;
555 setfuncV(L2, L2->top++, funcV(tv));
556 setthreadV(L2, L2->top++, L);
557 setintV(L2->top++, samples);
558 setstrV(L2, L2->top++, lj_str_new(L2, &vmst, 1));
559 status = lua_pcall(L2, 3, 0, 0); /* callback(thread, samples, vmstate) */
560 if (status) {
561 if (G(L2)->panic) G(L2)->panic(L2);
562 exit(EXIT_FAILURE);
563 }
564 lj_trace_abort(G(L2));
565 }
566}
567
568/* profile.start(mode, cb) */
569LJLIB_CF(jit_profile_start)
570{
571 GCtab *registry = tabV(registry(L));
572 GCstr *mode = lj_lib_optstr(L, 1);
573 GCfunc *func = lj_lib_checkfunc(L, 2);
574 lua_State *L2 = lua_newthread(L); /* Thread that runs profiler callback. */
575 TValue key;
576 /* Anchor thread and function in registry. */
577 setlightudV(&key, (void *)&KEY_PROFILE_THREAD);
578 setthreadV(L, lj_tab_set(L, registry, &key), L2);
579 setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
580 setfuncV(L, lj_tab_set(L, registry, &key), func);
581 lj_gc_anybarriert(L, registry);
582 luaJIT_profile_start(L, mode ? strdata(mode) : "",
583 (luaJIT_profile_callback)jit_profile_callback, L2);
584 return 0;
585}
586
587/* profile.stop() */
588LJLIB_CF(jit_profile_stop)
589{
590 GCtab *registry;
591 TValue key;
592 luaJIT_profile_stop(L);
593 registry = tabV(registry(L));
594 setlightudV(&key, (void *)&KEY_PROFILE_THREAD);
595 setnilV(lj_tab_set(L, registry, &key));
596 setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
597 setnilV(lj_tab_set(L, registry, &key));
598 lj_gc_anybarriert(L, registry);
599 return 0;
600}
601
602/* dump = profile.dumpstack([thread,] fmt, depth) */
603LJLIB_CF(jit_profile_dumpstack)
604{
605 lua_State *L2 = L;
606 int arg = 0;
607 size_t len;
608 int depth;
609 GCstr *fmt;
610 const char *p;
611 if (L->top > L->base && tvisthread(L->base)) {
612 L2 = threadV(L->base);
613 arg = 1;
614 }
615 fmt = lj_lib_checkstr(L, arg+1);
616 depth = lj_lib_checkint(L, arg+2);
617 p = luaJIT_profile_dumpstack(L2, strdata(fmt), depth, &len);
618 lua_pushlstring(L, p, len);
619 return 1;
620}
621
622#include "lj_libdef.h"
623
624static int luaopen_jit_profile(lua_State *L)
625{
626 LJ_LIB_REG(L, NULL, jit_profile);
627 return 1;
628}
629
630#endif
631
516/* -- JIT compiler initialization ----------------------------------------- */ 632/* -- JIT compiler initialization ----------------------------------------- */
517 633
518#if LJ_HASJIT 634#if LJ_HASJIT
@@ -538,38 +654,31 @@ static uint32_t jit_cpudetect(lua_State *L)
538 uint32_t features[4]; 654 uint32_t features[4];
539 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) { 655 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
540#if !LJ_HASJIT 656#if !LJ_HASJIT
541#define JIT_F_CMOV 1
542#define JIT_F_SSE2 2 657#define JIT_F_SSE2 2
543#endif 658#endif
544 flags |= ((features[3] >> 15)&1) * JIT_F_CMOV;
545 flags |= ((features[3] >> 26)&1) * JIT_F_SSE2; 659 flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
546#if LJ_HASJIT 660#if LJ_HASJIT
547 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3; 661 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
548 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1; 662 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
549 if (vendor[2] == 0x6c65746e) { /* Intel. */ 663 if (vendor[2] == 0x6c65746e) { /* Intel. */
550 if ((features[0] & 0x0ff00f00) == 0x00000f00) /* P4. */ 664 if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */
551 flags |= JIT_F_P4; /* Currently unused. */
552 else if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */
553 flags |= JIT_F_LEA_AGU; 665 flags |= JIT_F_LEA_AGU;
554 } else if (vendor[2] == 0x444d4163) { /* AMD. */ 666 } else if (vendor[2] == 0x444d4163) { /* AMD. */
555 uint32_t fam = (features[0] & 0x0ff00f00); 667 uint32_t fam = (features[0] & 0x0ff00f00);
556 if (fam == 0x00000f00) /* K8. */
557 flags |= JIT_F_SPLIT_XMM;
558 if (fam >= 0x00000f00) /* K8, K10. */ 668 if (fam >= 0x00000f00) /* K8, K10. */
559 flags |= JIT_F_PREFER_IMUL; 669 flags |= JIT_F_PREFER_IMUL;
560 } 670 }
671 if (vendor[0] >= 7) {
672 uint32_t xfeatures[4];
673 lj_vm_cpuid(7, xfeatures);
674 flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2;
675 }
561#endif 676#endif
562 } 677 }
563 /* Check for required instruction set support on x86 (unnecessary on x64). */ 678 /* Check for required instruction set support on x86 (unnecessary on x64). */
564#if LJ_TARGET_X86 679#if LJ_TARGET_X86
565#if !defined(LUAJIT_CPU_NOCMOV)
566 if (!(flags & JIT_F_CMOV))
567 luaL_error(L, "CPU not supported");
568#endif
569#if defined(LUAJIT_CPU_SSE2)
570 if (!(flags & JIT_F_SSE2)) 680 if (!(flags & JIT_F_SSE2))
571 luaL_error(L, "CPU does not support SSE2 (recompile without -DLUAJIT_CPU_SSE2)"); 681 luaL_error(L, "CPU with SSE2 required");
572#endif
573#endif 682#endif
574#elif LJ_TARGET_ARM 683#elif LJ_TARGET_ARM
575#if LJ_HASJIT 684#if LJ_HASJIT
@@ -591,6 +700,8 @@ static uint32_t jit_cpudetect(lua_State *L)
591 ver >= 60 ? JIT_F_ARMV6_ : 0; 700 ver >= 60 ? JIT_F_ARMV6_ : 0;
592 flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2; 701 flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2;
593#endif 702#endif
703#elif LJ_TARGET_ARM64
704 /* No optional CPU features to detect (for now). */
594#elif LJ_TARGET_PPC 705#elif LJ_TARGET_PPC
595#if LJ_HASJIT 706#if LJ_HASJIT
596#if LJ_ARCH_SQRT 707#if LJ_ARCH_SQRT
@@ -600,8 +711,6 @@ static uint32_t jit_cpudetect(lua_State *L)
600 flags |= JIT_F_ROUND; 711 flags |= JIT_F_ROUND;
601#endif 712#endif
602#endif 713#endif
603#elif LJ_TARGET_PPCSPE
604 /* Nothing to do. */
605#elif LJ_TARGET_MIPS 714#elif LJ_TARGET_MIPS
606#if LJ_HASJIT 715#if LJ_HASJIT
607 /* Compile-time MIPS CPU detection. */ 716 /* Compile-time MIPS CPU detection. */
@@ -631,11 +740,7 @@ static void jit_init(lua_State *L)
631 uint32_t flags = jit_cpudetect(L); 740 uint32_t flags = jit_cpudetect(L);
632#if LJ_HASJIT 741#if LJ_HASJIT
633 jit_State *J = L2J(L); 742 jit_State *J = L2J(L);
634#if LJ_TARGET_X86 743 J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
635 /* Silently turn off the JIT compiler on CPUs without SSE2. */
636 if ((flags & JIT_F_SSE2))
637#endif
638 J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
639 memcpy(J->param, jit_param_default, sizeof(J->param)); 744 memcpy(J->param, jit_param_default, sizeof(J->param));
640 lj_dispatch_update(G(L)); 745 lj_dispatch_update(G(L));
641#else 746#else
@@ -645,19 +750,23 @@ static void jit_init(lua_State *L)
645 750
646LUALIB_API int luaopen_jit(lua_State *L) 751LUALIB_API int luaopen_jit(lua_State *L)
647{ 752{
753 jit_init(L);
648 lua_pushliteral(L, LJ_OS_NAME); 754 lua_pushliteral(L, LJ_OS_NAME);
649 lua_pushliteral(L, LJ_ARCH_NAME); 755 lua_pushliteral(L, LJ_ARCH_NAME);
650 lua_pushinteger(L, LUAJIT_VERSION_NUM); 756 lua_pushinteger(L, LUAJIT_VERSION_NUM);
651 lua_pushliteral(L, LUAJIT_VERSION); 757 lua_pushliteral(L, LUAJIT_VERSION);
652 LJ_LIB_REG(L, LUA_JITLIBNAME, jit); 758 LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
759#if LJ_HASPROFILE
760 lj_lib_prereg(L, LUA_JITLIBNAME ".profile", luaopen_jit_profile,
761 tabref(L->env));
762#endif
653#ifndef LUAJIT_DISABLE_JITUTIL 763#ifndef LUAJIT_DISABLE_JITUTIL
654 LJ_LIB_REG(L, "jit.util", jit_util); 764 lj_lib_prereg(L, LUA_JITLIBNAME ".util", luaopen_jit_util, tabref(L->env));
655#endif 765#endif
656#if LJ_HASJIT 766#if LJ_HASJIT
657 LJ_LIB_REG(L, "jit.opt", jit_opt); 767 LJ_LIB_REG(L, "jit.opt", jit_opt);
658#endif 768#endif
659 L->top -= 2; 769 L->top -= 2;
660 jit_init(L);
661 return 1; 770 return 1;
662} 771}
663 772