aboutsummaryrefslogtreecommitdiff
path: root/src/lib_jit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib_jit.c')
-rw-r--r--src/lib_jit.c233
1 files changed, 165 insertions, 68 deletions
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 83ee0984..2867d420 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"
@@ -99,8 +104,8 @@ LJLIB_CF(jit_status)
99 jit_State *J = L2J(L); 104 jit_State *J = L2J(L);
100 L->top = L->base; 105 L->top = L->base;
101 setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0); 106 setboolV(L->top++, (J->flags & JIT_F_ON) ? 1 : 0);
102 flagbits_to_strings(L, J->flags, JIT_F_CPU_FIRST, JIT_F_CPUSTRING); 107 flagbits_to_strings(L, J->flags, JIT_F_CPU, JIT_F_CPUSTRING);
103 flagbits_to_strings(L, J->flags, JIT_F_OPT_FIRST, JIT_F_OPTSTRING); 108 flagbits_to_strings(L, J->flags, JIT_F_OPT, JIT_F_OPTSTRING);
104 return (int)(L->top - L->base); 109 return (int)(L->top - L->base);
105#else 110#else
106 setboolV(L->top++, 0); 111 setboolV(L->top++, 0);
@@ -108,6 +113,13 @@ LJLIB_CF(jit_status)
108#endif 113#endif
109} 114}
110 115
116LJLIB_CF(jit_security)
117{
118 int idx = lj_lib_checkopt(L, 1, -1, LJ_SECURITY_MODESTRING);
119 setintV(L->top++, ((LJ_SECURITY_MODE >> (2*idx)) & 3));
120 return 1;
121}
122
111LJLIB_CF(jit_attach) 123LJLIB_CF(jit_attach)
112{ 124{
113#ifdef LUAJIT_DISABLE_VMEVENT 125#ifdef LUAJIT_DISABLE_VMEVENT
@@ -222,7 +234,7 @@ LJLIB_CF(jit_util_funcbc)
222 if (pc < pt->sizebc) { 234 if (pc < pt->sizebc) {
223 BCIns ins = proto_bc(pt)[pc]; 235 BCIns ins = proto_bc(pt)[pc];
224 BCOp op = bc_op(ins); 236 BCOp op = bc_op(ins);
225 lua_assert(op < BC__MAX); 237 lj_assertL(op < BC__MAX, "bad bytecode op %d", op);
226 setintV(L->top, ins); 238 setintV(L->top, ins);
227 setintV(L->top+1, lj_bc_mode[op]); 239 setintV(L->top+1, lj_bc_mode[op]);
228 L->top += 2; 240 L->top += 2;
@@ -280,7 +292,7 @@ static GCtrace *jit_checktrace(lua_State *L)
280/* Names of link types. ORDER LJ_TRLINK */ 292/* Names of link types. ORDER LJ_TRLINK */
281static const char *const jit_trlinkname[] = { 293static const char *const jit_trlinkname[] = {
282 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion", 294 "none", "root", "loop", "tail-recursion", "up-recursion", "down-recursion",
283 "interpreter", "return" 295 "interpreter", "return", "stitch"
284}; 296};
285 297
286/* local info = jit.util.traceinfo(tr) */ 298/* local info = jit.util.traceinfo(tr) */
@@ -333,6 +345,9 @@ LJLIB_CF(jit_util_tracek)
333 slot = ir->op2; 345 slot = ir->op2;
334 ir = &T->ir[ir->op1]; 346 ir = &T->ir[ir->op1];
335 } 347 }
348#if LJ_HASFFI
349 if (ir->o == IR_KINT64) ctype_loadffi(L);
350#endif
336 lj_ir_kvalue(L, L->top-2, ir); 351 lj_ir_kvalue(L, L->top-2, ir);
337 setintV(L->top-1, (int32_t)irt_type(ir->t)); 352 setintV(L->top-1, (int32_t)irt_type(ir->t));
338 if (slot == -1) 353 if (slot == -1)
@@ -417,6 +432,12 @@ LJLIB_CF(jit_util_ircalladdr)
417 432
418#include "lj_libdef.h" 433#include "lj_libdef.h"
419 434
435static int luaopen_jit_util(lua_State *L)
436{
437 LJ_LIB_REG(L, NULL, jit_util);
438 return 1;
439}
440
420/* -- jit.opt module ------------------------------------------------------ */ 441/* -- jit.opt module ------------------------------------------------------ */
421 442
422#if LJ_HASJIT 443#if LJ_HASJIT
@@ -453,7 +474,7 @@ static int jitopt_flag(jit_State *J, const char *str)
453 str += str[2] == '-' ? 3 : 2; 474 str += str[2] == '-' ? 3 : 2;
454 set = 0; 475 set = 0;
455 } 476 }
456 for (opt = JIT_F_OPT_FIRST; ; opt <<= 1) { 477 for (opt = JIT_F_OPT; ; opt <<= 1) {
457 size_t len = *(const uint8_t *)lst; 478 size_t len = *(const uint8_t *)lst;
458 if (len == 0) 479 if (len == 0)
459 break; 480 break;
@@ -473,7 +494,7 @@ static int jitopt_param(jit_State *J, const char *str)
473 int i; 494 int i;
474 for (i = 0; i < JIT_P__MAX; i++) { 495 for (i = 0; i < JIT_P__MAX; i++) {
475 size_t len = *(const uint8_t *)lst; 496 size_t len = *(const uint8_t *)lst;
476 lua_assert(len != 0); 497 lj_assertJ(len != 0, "bad JIT_P_STRING");
477 if (strncmp(str, lst+1, len) == 0 && str[len] == '=') { 498 if (strncmp(str, lst+1, len) == 0 && str[len] == '=') {
478 int32_t n = 0; 499 int32_t n = 0;
479 const char *p = &str[len+1]; 500 const char *p = &str[len+1];
@@ -514,6 +535,104 @@ LJLIB_CF(jit_opt_start)
514 535
515#endif 536#endif
516 537
538/* -- jit.profile module -------------------------------------------------- */
539
540#if LJ_HASPROFILE
541
542#define LJLIB_MODULE_jit_profile
543
544/* Not loaded by default, use: local profile = require("jit.profile") */
545
546#define KEY_PROFILE_THREAD (U64x(80000000,00000000)|'t')
547#define KEY_PROFILE_FUNC (U64x(80000000,00000000)|'f')
548
549static void jit_profile_callback(lua_State *L2, lua_State *L, int samples,
550 int vmstate)
551{
552 TValue key;
553 cTValue *tv;
554 key.u64 = KEY_PROFILE_FUNC;
555 tv = lj_tab_get(L, tabV(registry(L)), &key);
556 if (tvisfunc(tv)) {
557 char vmst = (char)vmstate;
558 int status;
559 setfuncV(L2, L2->top++, funcV(tv));
560 setthreadV(L2, L2->top++, L);
561 setintV(L2->top++, samples);
562 setstrV(L2, L2->top++, lj_str_new(L2, &vmst, 1));
563 status = lua_pcall(L2, 3, 0, 0); /* callback(thread, samples, vmstate) */
564 if (status) {
565 if (G(L2)->panic) G(L2)->panic(L2);
566 exit(EXIT_FAILURE);
567 }
568 lj_trace_abort(G(L2));
569 }
570}
571
572/* profile.start(mode, cb) */
573LJLIB_CF(jit_profile_start)
574{
575 GCtab *registry = tabV(registry(L));
576 GCstr *mode = lj_lib_optstr(L, 1);
577 GCfunc *func = lj_lib_checkfunc(L, 2);
578 lua_State *L2 = lua_newthread(L); /* Thread that runs profiler callback. */
579 TValue key;
580 /* Anchor thread and function in registry. */
581 key.u64 = KEY_PROFILE_THREAD;
582 setthreadV(L, lj_tab_set(L, registry, &key), L2);
583 key.u64 = KEY_PROFILE_FUNC;
584 setfuncV(L, lj_tab_set(L, registry, &key), func);
585 lj_gc_anybarriert(L, registry);
586 luaJIT_profile_start(L, mode ? strdata(mode) : "",
587 (luaJIT_profile_callback)jit_profile_callback, L2);
588 return 0;
589}
590
591/* profile.stop() */
592LJLIB_CF(jit_profile_stop)
593{
594 GCtab *registry;
595 TValue key;
596 luaJIT_profile_stop(L);
597 registry = tabV(registry(L));
598 key.u64 = KEY_PROFILE_THREAD;
599 setnilV(lj_tab_set(L, registry, &key));
600 key.u64 = KEY_PROFILE_FUNC;
601 setnilV(lj_tab_set(L, registry, &key));
602 lj_gc_anybarriert(L, registry);
603 return 0;
604}
605
606/* dump = profile.dumpstack([thread,] fmt, depth) */
607LJLIB_CF(jit_profile_dumpstack)
608{
609 lua_State *L2 = L;
610 int arg = 0;
611 size_t len;
612 int depth;
613 GCstr *fmt;
614 const char *p;
615 if (L->top > L->base && tvisthread(L->base)) {
616 L2 = threadV(L->base);
617 arg = 1;
618 }
619 fmt = lj_lib_checkstr(L, arg+1);
620 depth = lj_lib_checkint(L, arg+2);
621 p = luaJIT_profile_dumpstack(L2, strdata(fmt), depth, &len);
622 lua_pushlstring(L, p, len);
623 return 1;
624}
625
626#include "lj_libdef.h"
627
628static int luaopen_jit_profile(lua_State *L)
629{
630 LJ_LIB_REG(L, NULL, jit_profile);
631 return 1;
632}
633
634#endif
635
517/* -- JIT compiler initialization ----------------------------------------- */ 636/* -- JIT compiler initialization ----------------------------------------- */
518 637
519#if LJ_HASJIT 638#if LJ_HASJIT
@@ -524,66 +643,41 @@ JIT_PARAMDEF(JIT_PARAMINIT)
524#undef JIT_PARAMINIT 643#undef JIT_PARAMINIT
525 0 644 0
526}; 645};
527#endif
528 646
529#if LJ_TARGET_ARM && LJ_TARGET_LINUX 647#if LJ_TARGET_ARM && LJ_TARGET_LINUX
530#include <sys/utsname.h> 648#include <sys/utsname.h>
531#endif 649#endif
532 650
533/* Arch-dependent CPU detection. */ 651/* Arch-dependent CPU feature detection. */
534static uint32_t jit_cpudetect(lua_State *L) 652static uint32_t jit_cpudetect(void)
535{ 653{
536 uint32_t flags = 0; 654 uint32_t flags = 0;
537#if LJ_TARGET_X86ORX64 655#if LJ_TARGET_X86ORX64
656
538 uint32_t vendor[4]; 657 uint32_t vendor[4];
539 uint32_t features[4]; 658 uint32_t features[4];
540 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) { 659 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
541#if !LJ_HASJIT
542#define JIT_F_CMOV 1
543#define JIT_F_SSE2 2
544#endif
545 flags |= ((features[3] >> 15)&1) * JIT_F_CMOV;
546 flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
547#if LJ_HASJIT
548 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3; 660 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
549 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1; 661 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
550 if (vendor[2] == 0x6c65746e) { /* Intel. */ 662 if (vendor[0] >= 7) {
551 if ((features[0] & 0x0ff00f00) == 0x00000f00) /* P4. */ 663 uint32_t xfeatures[4];
552 flags |= JIT_F_P4; /* Currently unused. */ 664 lj_vm_cpuid(7, xfeatures);
553 else if ((features[0] & 0x0fff0ff0) == 0x000106c0) /* Atom. */ 665 flags |= ((xfeatures[1] >> 8)&1) * JIT_F_BMI2;
554 flags |= JIT_F_LEA_AGU;
555 } else if (vendor[2] == 0x444d4163) { /* AMD. */
556 uint32_t fam = (features[0] & 0x0ff00f00);
557 if (fam == 0x00000f00) /* K8. */
558 flags |= JIT_F_SPLIT_XMM;
559 if (fam >= 0x00000f00) /* K8, K10. */
560 flags |= JIT_F_PREFER_IMUL;
561 } 666 }
562#endif
563 } 667 }
564 /* Check for required instruction set support on x86 (unnecessary on x64). */ 668 /* Don't bother checking for SSE2 -- the VM will crash before getting here. */
565#if LJ_TARGET_X86 669
566#if !defined(LUAJIT_CPU_NOCMOV)
567 if (!(flags & JIT_F_CMOV))
568 luaL_error(L, "CPU not supported");
569#endif
570#if defined(LUAJIT_CPU_SSE2)
571 if (!(flags & JIT_F_SSE2))
572 luaL_error(L, "CPU does not support SSE2 (recompile without -DLUAJIT_CPU_SSE2)");
573#endif
574#endif
575#elif LJ_TARGET_ARM 670#elif LJ_TARGET_ARM
576#if LJ_HASJIT 671
577 int ver = LJ_ARCH_VERSION; /* Compile-time ARM CPU detection. */ 672 int ver = LJ_ARCH_VERSION; /* Compile-time ARM CPU detection. */
578#if LJ_TARGET_LINUX 673#if LJ_TARGET_LINUX
579 if (ver < 70) { /* Runtime ARM CPU detection. */ 674 if (ver < 70) { /* Runtime ARM CPU detection. */
580 struct utsname ut; 675 struct utsname ut;
581 uname(&ut); 676 uname(&ut);
582 if (strncmp(ut.machine, "armv", 4) == 0) { 677 if (strncmp(ut.machine, "armv", 4) == 0) {
583 if (ut.machine[4] >= '7') 678 if (ut.machine[4] >= '8') ver = 80;
584 ver = 70; 679 else if (ut.machine[4] == '7') ver = 70;
585 else if (ut.machine[4] == '6') 680 else if (ut.machine[4] == '6') ver = 60;
586 ver = 60;
587 } 681 }
588 } 682 }
589#endif 683#endif
@@ -591,74 +685,77 @@ static uint32_t jit_cpudetect(lua_State *L)
591 ver >= 61 ? JIT_F_ARMV6T2_ : 685 ver >= 61 ? JIT_F_ARMV6T2_ :
592 ver >= 60 ? JIT_F_ARMV6_ : 0; 686 ver >= 60 ? JIT_F_ARMV6_ : 0;
593 flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2; 687 flags |= LJ_ARCH_HASFPU == 0 ? 0 : ver >= 70 ? JIT_F_VFPV3 : JIT_F_VFPV2;
594#endif 688
689#elif LJ_TARGET_ARM64
690
691 /* No optional CPU features to detect (for now). */
692
595#elif LJ_TARGET_PPC 693#elif LJ_TARGET_PPC
596#if LJ_HASJIT 694
597#if LJ_ARCH_SQRT 695#if LJ_ARCH_SQRT
598 flags |= JIT_F_SQRT; 696 flags |= JIT_F_SQRT;
599#endif 697#endif
600#if LJ_ARCH_ROUND 698#if LJ_ARCH_ROUND
601 flags |= JIT_F_ROUND; 699 flags |= JIT_F_ROUND;
602#endif 700#endif
603#endif 701
604#elif LJ_TARGET_PPCSPE
605 /* Nothing to do. */
606#elif LJ_TARGET_MIPS 702#elif LJ_TARGET_MIPS
607#if LJ_HASJIT 703
608 /* Compile-time MIPS CPU detection. */ 704 /* Compile-time MIPS CPU detection. */
609#if LJ_ARCH_VERSION >= 20 705#if LJ_ARCH_VERSION >= 20
610 flags |= JIT_F_MIPS32R2; 706 flags |= JIT_F_MIPSXXR2;
611#endif 707#endif
612 /* Runtime MIPS CPU detection. */ 708 /* Runtime MIPS CPU detection. */
613#if defined(__GNUC__) 709#if defined(__GNUC__)
614 if (!(flags & JIT_F_MIPS32R2)) { 710 if (!(flags & JIT_F_MIPSXXR2)) {
615 int x; 711 int x;
712#ifdef __mips16
713 x = 0; /* Runtime detection is difficult. Ensure optimal -march flags. */
714#else
616 /* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */ 715 /* On MIPS32R1 rotr is treated as srl. rotr r2,r2,1 -> srl r2,r2,1. */
617 __asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x) : : "$2"); 716 __asm__("li $2, 1\n\t.long 0x00221042\n\tmove %0, $2" : "=r"(x) : : "$2");
618 if (x) flags |= JIT_F_MIPS32R2; /* Either 0x80000000 (R2) or 0 (R1). */
619 }
620#endif 717#endif
718 if (x) flags |= JIT_F_MIPSXXR2; /* Either 0x80000000 (R2) or 0 (R1). */
719 }
621#endif 720#endif
721
622#else 722#else
623#error "Missing CPU detection for this architecture" 723#error "Missing CPU detection for this architecture"
624#endif 724#endif
625 UNUSED(L);
626 return flags; 725 return flags;
627} 726}
628 727
629/* Initialize JIT compiler. */ 728/* Initialize JIT compiler. */
630static void jit_init(lua_State *L) 729static void jit_init(lua_State *L)
631{ 730{
632 uint32_t flags = jit_cpudetect(L);
633#if LJ_HASJIT
634 jit_State *J = L2J(L); 731 jit_State *J = L2J(L);
635#if LJ_TARGET_X86 732 J->flags = jit_cpudetect() | JIT_F_ON | JIT_F_OPT_DEFAULT;
636 /* Silently turn off the JIT compiler on CPUs without SSE2. */
637 if ((flags & JIT_F_SSE2))
638#endif
639 J->flags = flags | JIT_F_ON | JIT_F_OPT_DEFAULT;
640 memcpy(J->param, jit_param_default, sizeof(J->param)); 733 memcpy(J->param, jit_param_default, sizeof(J->param));
641 lj_dispatch_update(G(L)); 734 lj_dispatch_update(G(L));
642#else
643 UNUSED(flags);
644#endif
645} 735}
736#endif
646 737
647LUALIB_API int luaopen_jit(lua_State *L) 738LUALIB_API int luaopen_jit(lua_State *L)
648{ 739{
740#if LJ_HASJIT
741 jit_init(L);
742#endif
649 lua_pushliteral(L, LJ_OS_NAME); 743 lua_pushliteral(L, LJ_OS_NAME);
650 lua_pushliteral(L, LJ_ARCH_NAME); 744 lua_pushliteral(L, LJ_ARCH_NAME);
651 lua_pushinteger(L, LUAJIT_VERSION_NUM); 745 lua_pushinteger(L, LUAJIT_VERSION_NUM);
652 lua_pushliteral(L, LUAJIT_VERSION); 746 lua_pushliteral(L, LUAJIT_VERSION);
653 LJ_LIB_REG(L, LUA_JITLIBNAME, jit); 747 LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
748#if LJ_HASPROFILE
749 lj_lib_prereg(L, LUA_JITLIBNAME ".profile", luaopen_jit_profile,
750 tabref(L->env));
751#endif
654#ifndef LUAJIT_DISABLE_JITUTIL 752#ifndef LUAJIT_DISABLE_JITUTIL
655 LJ_LIB_REG(L, "jit.util", jit_util); 753 lj_lib_prereg(L, LUA_JITLIBNAME ".util", luaopen_jit_util, tabref(L->env));
656#endif 754#endif
657#if LJ_HASJIT 755#if LJ_HASJIT
658 LJ_LIB_REG(L, "jit.opt", jit_opt); 756 LJ_LIB_REG(L, "jit.opt", jit_opt);
659#endif 757#endif
660 L->top -= 2; 758 L->top -= 2;
661 jit_init(L);
662 return 1; 759 return 1;
663} 760}
664 761