aboutsummaryrefslogtreecommitdiff
path: root/src/lib_jit.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/lib_jit.c144
1 files changed, 123 insertions, 21 deletions
diff --git a/src/lib_jit.c b/src/lib_jit.c
index 8cf405e7..9e4fd3a8 100644
--- a/src/lib_jit.c
+++ b/src/lib_jit.c
@@ -16,7 +16,11 @@
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"
@@ -332,6 +336,13 @@ LJLIB_CF(jit_util_tracek)
332 slot = ir->op2; 336 slot = ir->op2;
333 ir = &T->ir[ir->op1]; 337 ir = &T->ir[ir->op1];
334 } 338 }
339#if LJ_HASFFI
340 if (ir->o == IR_KINT64 && !ctype_ctsG(G(L))) {
341 ptrdiff_t oldtop = savestack(L, L->top);
342 luaopen_ffi(L); /* Load FFI library on-demand. */
343 L->top = restorestack(L, oldtop);
344 }
345#endif
335 lj_ir_kvalue(L, L->top-2, ir); 346 lj_ir_kvalue(L, L->top-2, ir);
336 setintV(L->top-1, (int32_t)irt_type(ir->t)); 347 setintV(L->top-1, (int32_t)irt_type(ir->t));
337 if (slot == -1) 348 if (slot == -1)
@@ -416,6 +427,12 @@ LJLIB_CF(jit_util_ircalladdr)
416 427
417#include "lj_libdef.h" 428#include "lj_libdef.h"
418 429
430static int luaopen_jit_util(lua_State *L)
431{
432 LJ_LIB_REG(L, NULL, jit_util);
433 return 1;
434}
435
419/* -- jit.opt module ------------------------------------------------------ */ 436/* -- jit.opt module ------------------------------------------------------ */
420 437
421#if LJ_HASJIT 438#if LJ_HASJIT
@@ -513,6 +530,103 @@ LJLIB_CF(jit_opt_start)
513 530
514#endif 531#endif
515 532
533/* -- jit.profile module -------------------------------------------------- */
534
535#if LJ_HASPROFILE
536
537#define LJLIB_MODULE_jit_profile
538
539/* Not loaded by default, use: local profile = require("jit.profile") */
540
541static const char KEY_PROFILE_THREAD = 't';
542static const char KEY_PROFILE_FUNC = 'f';
543
544static void jit_profile_callback(lua_State *L2, lua_State *L, int samples,
545 int vmstate)
546{
547 TValue key;
548 cTValue *tv;
549 setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
550 tv = lj_tab_get(L, tabV(registry(L)), &key);
551 if (tvisfunc(tv)) {
552 char vmst = (char)vmstate;
553 int status;
554 setfuncV(L2, L2->top++, funcV(tv));
555 setthreadV(L2, L2->top++, L);
556 setintV(L2->top++, samples);
557 setstrV(L2, L2->top++, lj_str_new(L2, &vmst, 1));
558 status = lua_pcall(L2, 3, 0, 0); /* callback(thread, samples, vmstate) */
559 if (status) {
560 if (G(L2)->panic) G(L2)->panic(L2);
561 exit(EXIT_FAILURE);
562 }
563 }
564}
565
566/* profile.start(mode, func) */
567LJLIB_CF(jit_profile_start)
568{
569 GCtab *registry = tabV(registry(L));
570 GCstr *mode = lj_lib_optstr(L, 1);
571 GCfunc *func = lj_lib_checkfunc(L, 2);
572 lua_State *L2 = lua_newthread(L); /* Thread that runs profiler callback. */
573 TValue key;
574 /* Anchor thread and function in registry. */
575 setlightudV(&key, (void *)&KEY_PROFILE_THREAD);
576 setthreadV(L, lj_tab_set(L, registry, &key), L2);
577 setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
578 setfuncV(L, lj_tab_set(L, registry, &key), func);
579 lj_gc_anybarriert(L, registry);
580 luaJIT_profile_start(L, mode ? strdata(mode) : "",
581 (luaJIT_profile_callback)jit_profile_callback, L2);
582 return 0;
583}
584
585/* profile.stop() */
586LJLIB_CF(jit_profile_stop)
587{
588 GCtab *registry;
589 TValue key;
590 luaJIT_profile_stop(L);
591 registry = tabV(registry(L));
592 setlightudV(&key, (void *)&KEY_PROFILE_THREAD);
593 setnilV(lj_tab_set(L, registry, &key));
594 setlightudV(&key, (void *)&KEY_PROFILE_FUNC);
595 setnilV(lj_tab_set(L, registry, &key));
596 lj_gc_anybarriert(L, registry);
597 return 0;
598}
599
600/* profile.dumpstack([thread,] fmt, depth) */
601LJLIB_CF(jit_profile_dumpstack)
602{
603 lua_State *L2 = L;
604 int arg = 0;
605 size_t len;
606 int depth;
607 GCstr *fmt;
608 const char *p;
609 if (L->top > L->base && tvisthread(L->base)) {
610 L2 = threadV(L->base);
611 arg = 1;
612 }
613 fmt = lj_lib_checkstr(L, arg+1);
614 depth = lj_lib_checkint(L, arg+2);
615 p = luaJIT_profile_dumpstack(L2, strdata(fmt), depth, &len);
616 lua_pushlstring(L, p, len);
617 return 1;
618}
619
620#include "lj_libdef.h"
621
622static int luaopen_jit_profile(lua_State *L)
623{
624 LJ_LIB_REG(L, NULL, jit_profile);
625 return 1;
626}
627
628#endif
629
516/* -- JIT compiler initialization ----------------------------------------- */ 630/* -- JIT compiler initialization ----------------------------------------- */
517 631
518#if LJ_HASJIT 632#if LJ_HASJIT
@@ -538,23 +652,17 @@ static uint32_t jit_cpudetect(lua_State *L)
538 uint32_t features[4]; 652 uint32_t features[4];
539 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) { 653 if (lj_vm_cpuid(0, vendor) && lj_vm_cpuid(1, features)) {
540#if !LJ_HASJIT 654#if !LJ_HASJIT
541#define JIT_F_CMOV 1
542#define JIT_F_SSE2 2 655#define JIT_F_SSE2 2
543#endif 656#endif
544 flags |= ((features[3] >> 15)&1) * JIT_F_CMOV;
545 flags |= ((features[3] >> 26)&1) * JIT_F_SSE2; 657 flags |= ((features[3] >> 26)&1) * JIT_F_SSE2;
546#if LJ_HASJIT 658#if LJ_HASJIT
547 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3; 659 flags |= ((features[2] >> 0)&1) * JIT_F_SSE3;
548 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1; 660 flags |= ((features[2] >> 19)&1) * JIT_F_SSE4_1;
549 if (vendor[2] == 0x6c65746e) { /* Intel. */ 661 if (vendor[2] == 0x6c65746e) { /* Intel. */
550 if ((features[0] & 0x0ff00f00) == 0x00000f00) /* P4. */ 662 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; 663 flags |= JIT_F_LEA_AGU;
554 } else if (vendor[2] == 0x444d4163) { /* AMD. */ 664 } else if (vendor[2] == 0x444d4163) { /* AMD. */
555 uint32_t fam = (features[0] & 0x0ff00f00); 665 uint32_t fam = (features[0] & 0x0ff00f00);
556 if (fam == 0x00000f00) /* K8. */
557 flags |= JIT_F_SPLIT_XMM;
558 if (fam >= 0x00000f00) /* K8, K10. */ 666 if (fam >= 0x00000f00) /* K8, K10. */
559 flags |= JIT_F_PREFER_IMUL; 667 flags |= JIT_F_PREFER_IMUL;
560 } 668 }
@@ -562,14 +670,8 @@ static uint32_t jit_cpudetect(lua_State *L)
562 } 670 }
563 /* Check for required instruction set support on x86 (unnecessary on x64). */ 671 /* Check for required instruction set support on x86 (unnecessary on x64). */
564#if LJ_TARGET_X86 672#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)) 673 if (!(flags & JIT_F_SSE2))
571 luaL_error(L, "CPU does not support SSE2 (recompile without -DLUAJIT_CPU_SSE2)"); 674 luaL_error(L, "CPU with SSE2 required");
572#endif
573#endif 675#endif
574#elif LJ_TARGET_ARM 676#elif LJ_TARGET_ARM
575#if LJ_HASJIT 677#if LJ_HASJIT
@@ -631,11 +733,7 @@ static void jit_init(lua_State *L)
631 uint32_t flags = jit_cpudetect(L); 733 uint32_t flags = jit_cpudetect(L);
632#if LJ_HASJIT 734#if LJ_HASJIT
633 jit_State *J = L2J(L); 735 jit_State *J = L2J(L);
634#if LJ_TARGET_X86 736 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)); 737 memcpy(J->param, jit_param_default, sizeof(J->param));
640 lj_dispatch_update(G(L)); 738 lj_dispatch_update(G(L));
641#else 739#else
@@ -645,19 +743,23 @@ static void jit_init(lua_State *L)
645 743
646LUALIB_API int luaopen_jit(lua_State *L) 744LUALIB_API int luaopen_jit(lua_State *L)
647{ 745{
746 jit_init(L);
648 lua_pushliteral(L, LJ_OS_NAME); 747 lua_pushliteral(L, LJ_OS_NAME);
649 lua_pushliteral(L, LJ_ARCH_NAME); 748 lua_pushliteral(L, LJ_ARCH_NAME);
650 lua_pushinteger(L, LUAJIT_VERSION_NUM); 749 lua_pushinteger(L, LUAJIT_VERSION_NUM);
651 lua_pushliteral(L, LUAJIT_VERSION); 750 lua_pushliteral(L, LUAJIT_VERSION);
652 LJ_LIB_REG(L, LUA_JITLIBNAME, jit); 751 LJ_LIB_REG(L, LUA_JITLIBNAME, jit);
752#if LJ_HASPROFILE
753 lj_lib_prereg(L, LUA_JITLIBNAME ".profile", luaopen_jit_profile,
754 tabref(L->env));
755#endif
653#ifndef LUAJIT_DISABLE_JITUTIL 756#ifndef LUAJIT_DISABLE_JITUTIL
654 LJ_LIB_REG(L, "jit.util", jit_util); 757 lj_lib_prereg(L, LUA_JITLIBNAME ".util", luaopen_jit_util, tabref(L->env));
655#endif 758#endif
656#if LJ_HASJIT 759#if LJ_HASJIT
657 LJ_LIB_REG(L, "jit.opt", jit_opt); 760 LJ_LIB_REG(L, "jit.opt", jit_opt);
658#endif 761#endif
659 L->top -= 2; 762 L->top -= 2;
660 jit_init(L);
661 return 1; 763 return 1;
662} 764}
663 765