[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Emacs-diffs] feature/libjit 39c6bef: Fix MS-Windows build with libjit
From: |
Eli Zaretskii |
Subject: |
[Emacs-diffs] feature/libjit 39c6bef: Fix MS-Windows build with libjit |
Date: |
Thu, 23 Aug 2018 12:43:23 -0400 (EDT) |
branch: feature/libjit
commit 39c6bef85897bd45753d9ee3a1e19d9a161f16ce
Author: Eli Zaretskii <address@hidden>
Commit: Eli Zaretskii <address@hidden>
Fix MS-Windows build with libjit
This fixes 32-bit MS-Windows build and hopefully also 64-bit
MS-Windows build (not tested). 32-bit MS-Windows build with wide ints
still doesn't work: I get invalid Lisp objects after JIT compiled code
is invoked.
* configure.ac (HAVE_LIBJIT) [mingw32]: Remove -ljit from
LIBJIT_LIBS, to avoid linking against libjit at build time and
allow loading libjit dynamically at run time.
* src/jit.c [WINDOWSNT]: Include w32.h and w32common.h.
[WINDOWSNT] (DEF_DLL_VAR, LOAD_DLL_VAR): New macros.
(init_libjit_functions) [WINDOWSNT]: New function.
(CONSTANT): A separate version for builds where EMACS_INT_MAX
is equal to INT_MAX (32-bit builds without wide ints). Use
XLI when assigning Lisp objects to integer values.
(untag, compile_make_natnum, compile_make_number)
(unary_intmath): Handle the case of EMACS_INT_MAX > LONG_MAX.
(compile_current_thread, compile): Don't use CONSTANT for
anything that is not a Lisp object.
(emacs_jit_compile): Do nothing if jit-disable is non-nil.
Use XLP to assign and compare Lisp objects to pointers.
(syms_of_jit): New boolean variable jit-disable, by default nil.
(init_jit) [WINDOWSNT]: Call init_libjit_functions.
Define lisp_object_type separately for 64-bit Windows builds
and 32-bit builds with wide ints. Fix some signatures to use
lisp_object_type and correct some that deviated from the
actual functions.
* src/lisp.h (USE_STACK_LISP_OBJECTS): Define to false for
32-bit MinGW builds with libjit.
* src/w32fns.c (syms_of_w32fns) <libjit>: New symbol.
* src/eval.c (Ffuncall, funcall_lambda): Use XLP to compare
Lisp_Object vs a pointer.
* src/emacs.c (main): Move the call to init_jit to before
init_buffer, as the latter calls Lisp and could use JIT.
* src/alloc.c (Fmake_byte_code): Use XPL to assign pointer to
a Lisp_Object field.
* lisp/term/w32-win.el (dynamic-library-alist): Add libjit-0.dll.
---
configure.ac | 4 +
lisp/term/w32-win.el | 3 +-
src/alloc.c | 2 +-
src/emacs.c | 10 +-
src/eval.c | 10 +-
src/jit.c | 418 +++++++++++++++++++++++++++++++++++++++++++++++----
src/lisp.h | 9 +-
src/w32fns.c | 1 +
8 files changed, 415 insertions(+), 42 deletions(-)
diff --git a/configure.ac b/configure.ac
index 8baeba7..9b4bcf8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3534,6 +3534,10 @@ if test "${with_libjit}" != "no"; then
EMACS_CHECK_MODULES([LIBJIT], [$LIBJIT_MODULES])
if test "${HAVE_LIBJIT}" = "yes"; then
AC_DEFINE([HAVE_LIBJIT], 1, [Define to 1 if you have the libjit library
(-ljit).])
+ ### mingw32 doesn't use -ljit, since it loads the library dynamically.
+ if test "${opsys}" = "mingw32"; then
+ LIBJIT_LIBS=
+ fi
fi
fi
diff --git a/lisp/term/w32-win.el b/lisp/term/w32-win.el
index dc57160..3d167b1 100644
--- a/lisp/term/w32-win.el
+++ b/lisp/term/w32-win.el
@@ -277,7 +277,8 @@ See the documentation of `create-fontset-from-fontset-spec'
for the format.")
'(libxml2 "libxml2-2.dll" "libxml2.dll")
'(zlib "zlib1.dll" "libz-1.dll")
'(lcms2 "liblcms2-2.dll")
- '(json "libjansson-4.dll")))
+ '(json "libjansson-4.dll")
+ '(libjit "libjit-0.dll")))
;;; multi-tty support
(defvar w32-initialized nil
diff --git a/src/alloc.c b/src/alloc.c
index ca70c0c..bc50c70 100644
--- a/src/alloc.c
+++ b/src/alloc.c
@@ -3555,7 +3555,7 @@ usage: (make-byte-code ARGLIST BYTE-CODE CONSTANTS DEPTH
&optional DOCSTRING INT
p->contents[i] = Qnil;
/* Not really a Lisp_Object. */
- p->contents[COMPILED_JIT_CODE] = (Lisp_Object) NULL;
+ p->contents[COMPILED_JIT_CODE] = XPL (NULL);
if (STRINGP (p->contents[COMPILED_BYTECODE])
&& STRING_MULTIBYTE (p->contents[COMPILED_BYTECODE]))
diff --git a/src/emacs.c b/src/emacs.c
index 25493c2..ca76bb5 100644
--- a/src/emacs.c
+++ b/src/emacs.c
@@ -1464,6 +1464,12 @@ Using an Emacs configured with --with-x-toolkit=lucid
does not have this problem
xputenv ("LANG=C");
#endif
+#ifdef HAVE_LIBJIT
+ /* This is here because init_buffer can already call Lisp. */
+ if (initialized)
+ init_jit ();
+#endif
+
/* Init buffer storage and default directory of main buffer. */
init_buffer (initialized);
@@ -1667,10 +1673,6 @@ Using an Emacs configured with --with-x-toolkit=lucid
does not have this problem
#if defined WINDOWSNT || defined HAVE_NTGUI
globals_of_w32select ();
#endif
-
-#ifdef HAVE_LIBJIT
- init_jit ();
-#endif
}
init_charset ();
diff --git a/src/eval.c b/src/eval.c
index de87f9b..6066a40 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -2825,9 +2825,9 @@ usage: (funcall FUNCTION &rest ARGUMENTS) */)
if (SUBRP (fun))
val = funcall_subr (fun, &XSUBR (fun)->function, numargs, args + 1);
else if (COMPILEDP (fun)
- && XVECTOR (fun)->contents[COMPILED_JIT_CODE] != NULL)
+ && XLP (XVECTOR (fun)->contents[COMPILED_JIT_CODE]) != NULL)
val = funcall_subr (fun,
- (struct subr_function *) XVECTOR
(fun)->contents[COMPILED_JIT_CODE],
+ (struct subr_function *) XLP (XVECTOR
(fun)->contents[COMPILED_JIT_CODE]),
numargs, args + 1);
else if (COMPILEDP (fun) || MODULE_FUNCTIONP (fun))
val = funcall_lambda (fun, numargs, args + 1);
@@ -3026,12 +3026,12 @@ funcall_lambda (Lisp_Object fun, ptrdiff_t nargs,
{
struct Lisp_Vector *vec = XVECTOR (fun);
- if (vec->contents[COMPILED_JIT_CODE] == NULL)
+ if (XLP (vec->contents[COMPILED_JIT_CODE]) == NULL)
emacs_jit_compile (fun);
- if (vec->contents[COMPILED_JIT_CODE] != NULL)
+ if (XLP (vec->contents[COMPILED_JIT_CODE]) != NULL)
return funcall_subr (fun,
- (struct subr_function *)
vec->contents[COMPILED_JIT_CODE],
+ (struct subr_function *) XLP
(vec->contents[COMPILED_JIT_CODE]),
nargs, arg_vector);
}
#endif /* HAVE_LIBJIT */
diff --git a/src/jit.c b/src/jit.c
index ebca343..c561bfe 100644
--- a/src/jit.c
+++ b/src/jit.c
@@ -33,6 +33,299 @@ along with GNU Emacs. If not, see
<https://www.gnu.org/licenses/>. */
#include <jit/jit.h>
#include <jit/jit-dump.h>
+#ifdef WINDOWSNT
+# include <windows.h>
+# include "w32common.h"
+# include "w32.h"
+
+/* Define a variable that will be loaded from a DLL. */
+#define DEF_DLL_VAR(type, var) static type *pv_##var
+
+/* Load a variable from the DLL. */
+#define LOAD_DLL_VAR(lib, var) \
+ do \
+ { \
+ pv_##var = (void *) GetProcAddress (lib, #var); \
+ if (!pv_##var) \
+ return false; \
+ } \
+ while (false)
+
+
+DEF_DLL_FN (jit_value_t, jit_value_create_nint_constant,
+ (jit_function_t, jit_type_t, jit_nint));
+# if EMACS_INT_MAX > LONG_MAX
+DEF_DLL_FN (jit_value_t, jit_value_create_long_constant,
+ (jit_function_t, jit_type_t, jit_long));
+# endif
+DEF_DLL_FN (void, jit_insn_store, (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_and,
+ (jit_function_t, jit_value_t, jit_value_t));
+# if !USE_LSB_TAG
+DEF_DLL_FN (jit_value_t, jit_insn_ushr,
+ (jit_function_t, jit_value_t, jit_value_t));
+# endif
+DEF_DLL_FN (jit_value_t, jit_insn_sub,
+ (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_sshr,
+ (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_eq,
+ (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (int, jit_insn_branch_if_not,
+ (jit_function_t, jit_value_t, jit_label_t *));
+DEF_DLL_FN (int, jit_insn_branch_if,
+ (jit_function_t, jit_value_t, jit_label_t *));
+DEF_DLL_FN (int, jit_insn_branch, (jit_function_t, jit_label_t *));
+DEF_DLL_FN (void, jit_insn_label, (jit_function_t, jit_label_t *));
+DEF_DLL_FN (jit_value_t, jit_insn_call_native,
+ (jit_function_t, const char *, void *, jit_type_t, jit_value_t *,
+ unsigned, int));
+DEF_DLL_FN (jit_value_t, jit_insn_shl,
+ (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_add,
+ (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_load_relative,
+ (jit_function_t, jit_value_t, jit_nint, jit_type_t));
+DEF_DLL_FN (jit_value_t, jit_insn_neg, (jit_function_t, jit_value_t));
+DEF_DLL_FN (int, jit_insn_store_relative,
+ (jit_function_t, jit_value_t, jit_nint, jit_value_t));
+DEF_DLL_FN (jit_function_t, jit_function_create, (jit_context_t, jit_type_t));
+DEF_DLL_FN (int, jit_function_set_meta,
+ (jit_function_t, int, void *, jit_meta_free_func, int));
+DEF_DLL_FN (jit_value_t, jit_value_create, (jit_function_t, jit_type_t));
+DEF_DLL_FN (jit_value_t, jit_value_get_param, (jit_function_t, unsigned));
+DEF_DLL_FN (jit_value_t, jit_insn_gt,
+ (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_lt,
+ (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_le,
+ (jit_function_t, jit_value_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_load_elem_address,
+ (jit_function_t, jit_value_t, jit_value_t, jit_type_t));
+DEF_DLL_FN (int, jit_insn_return, (jit_function_t, jit_value_t));
+DEF_DLL_FN (jit_value_t, jit_insn_add_relative,
+ (jit_function_t, jit_value_t, jit_nint));
+DEF_DLL_FN (jit_label_t, jit_function_reserve_label, (jit_function_t));
+DEF_DLL_FN (int, jit_insn_jump_table,
+ (jit_function_t, jit_value_t, jit_label_t *, unsigned));
+DEF_DLL_FN (jit_value_t, jit_insn_alloca, (jit_function_t, jit_value_t));
+DEF_DLL_FN (int, jit_insn_move_blocks_to_start,
+ (jit_function_t, jit_label_t, jit_label_t));
+DEF_DLL_FN (int, jit_function_compile, (jit_function_t));
+DEF_DLL_FN (void, jit_function_abandon, (jit_function_t));
+DEF_DLL_FN (void *, jit_function_to_closure, (jit_function_t));
+DEF_DLL_FN (void, jit_context_build_start, (jit_context_t));
+DEF_DLL_FN (void, jit_context_build_end, (jit_context_t));
+DEF_DLL_FN (jit_function_t, jit_function_from_closure, (jit_context_t, void
*));
+DEF_DLL_FN (void, jit_dump_function, (FILE *, jit_function_t, const char *));
+DEF_DLL_FN (void, jit_init, (void));
+DEF_DLL_FN (jit_context_t, jit_context_create, (void));
+DEF_DLL_FN (jit_type_t, jit_type_create_signature,
+ (jit_abi_t, jit_type_t, jit_type_t *, unsigned, int));
+
+DEF_DLL_VAR (jit_type_t, jit_type_void_ptr);
+DEF_DLL_VAR (jit_type_t, jit_type_uint);
+DEF_DLL_VAR (jit_type_t, jit_type_nint);
+DEF_DLL_VAR (jit_type_t, jit_type_sys_int);
+DEF_DLL_VAR (jit_type_t, jit_type_int);
+DEF_DLL_VAR (jit_type_t, jit_type_void);
+# if EMACS_INT_MAX > LONG_MAX
+DEF_DLL_VAR (jit_type_t, jit_type_sys_longlong);
+DEF_DLL_VAR (jit_type_t, jit_type_long);
+# endif
+DEF_DLL_VAR (jit_type_t, jit_type_ulong);
+
+static bool
+init_libjit_functions (void)
+{
+ HMODULE library = w32_delayed_load (Qlibjit);
+
+ if (!library)
+ return false;
+
+ LOAD_DLL_FN (library, jit_value_create_nint_constant);
+# if EMACS_INT_MAX > LONG_MAX
+ LOAD_DLL_FN (library, jit_value_create_long_constant);
+# endif
+ LOAD_DLL_FN (library, jit_insn_store);
+ LOAD_DLL_FN (library, jit_insn_and);
+# if !USE_LSB_TAG
+ LOAD_DLL_FN (library, jit_insn_ushr);
+# endif
+ LOAD_DLL_FN (library, jit_insn_sub);
+ LOAD_DLL_FN (library, jit_insn_sshr);
+ LOAD_DLL_FN (library, jit_insn_eq);
+ LOAD_DLL_FN (library, jit_insn_branch_if_not);
+ LOAD_DLL_FN (library, jit_insn_branch_if);
+ LOAD_DLL_FN (library, jit_insn_branch);
+ LOAD_DLL_FN (library, jit_insn_label);
+ LOAD_DLL_FN (library, jit_insn_call_native);
+ LOAD_DLL_FN (library, jit_insn_shl);
+ LOAD_DLL_FN (library, jit_insn_add);
+ LOAD_DLL_FN (library, jit_insn_load_relative);
+ LOAD_DLL_FN (library, jit_insn_neg);
+ LOAD_DLL_FN (library, jit_insn_store_relative);
+ LOAD_DLL_FN (library, jit_function_create);
+ LOAD_DLL_FN (library, jit_function_set_meta);
+ LOAD_DLL_FN (library, jit_value_create);
+ LOAD_DLL_FN (library, jit_value_get_param);
+ LOAD_DLL_FN (library, jit_insn_gt);
+ LOAD_DLL_FN (library, jit_insn_lt);
+ LOAD_DLL_FN (library, jit_insn_le);
+ LOAD_DLL_FN (library, jit_insn_load_elem_address);
+ LOAD_DLL_FN (library, jit_insn_return);
+ LOAD_DLL_FN (library, jit_insn_add_relative);
+ LOAD_DLL_FN (library, jit_function_reserve_label);
+ LOAD_DLL_FN (library, jit_insn_jump_table);
+ LOAD_DLL_FN (library, jit_insn_alloca);
+ LOAD_DLL_FN (library, jit_insn_move_blocks_to_start);
+ LOAD_DLL_FN (library, jit_function_compile);
+ LOAD_DLL_FN (library, jit_function_abandon);
+ LOAD_DLL_FN (library, jit_function_to_closure);
+ LOAD_DLL_FN (library, jit_context_build_start);
+ LOAD_DLL_FN (library, jit_context_build_end);
+ LOAD_DLL_FN (library, jit_function_from_closure);
+ LOAD_DLL_FN (library, jit_dump_function);
+ LOAD_DLL_FN (library, jit_init);
+ LOAD_DLL_FN (library, jit_context_create);
+ LOAD_DLL_FN (library, jit_type_create_signature);
+
+ LOAD_DLL_VAR (library, jit_type_void_ptr);
+ LOAD_DLL_VAR (library, jit_type_uint);
+ LOAD_DLL_VAR (library, jit_type_nint);
+ LOAD_DLL_VAR (library, jit_type_sys_int);
+ LOAD_DLL_VAR (library, jit_type_int);
+ LOAD_DLL_VAR (library, jit_type_void);
+# if EMACS_INT_MAX > LONG_MAX
+ LOAD_DLL_VAR (library, jit_type_sys_longlong);
+ LOAD_DLL_VAR (library, jit_type_long);
+# endif
+ LOAD_DLL_VAR (library, jit_type_ulong);
+
+ return true;
+}
+
+
+# undef jit_value_create_nint_constant
+# if EMACS_INT_MAX > LONG_MAX
+# undef jit_value_create_long_constant
+# endif
+# undef jit_insn_store
+# undef jit_insn_and
+# if !USE_LSB_TAG
+# undef jit_insn_ushr
+# endif
+# undef jit_insn_sub
+# undef jit_insn_sshr
+# undef jit_insn_eq
+# undef jit_insn_branch_if_not
+# undef jit_insn_branch_if
+# undef jit_insn_branch
+# undef jit_insn_label
+# undef jit_insn_call_native
+# undef jit_insn_shl
+# undef jit_insn_add
+# undef jit_insn_load_relative
+# undef jit_insn_neg
+# undef jit_insn_store_relative
+# undef jit_function_create
+# undef jit_function_set_meta
+# undef jit_value_create
+# undef jit_value_get_param
+# undef jit_insn_gt
+# undef jit_insn_lt
+# undef jit_insn_le
+# undef jit_insn_load_elem_address
+# undef jit_insn_return
+# undef jit_insn_add_relative
+# undef jit_function_reserve_label
+# undef jit_insn_jump_table
+# undef jit_insn_alloca
+# undef jit_insn_move_blocks_to_start
+# undef jit_function_compile
+# undef jit_function_abandon
+# undef jit_function_to_closure
+# undef jit_context_build_start
+# undef jit_context_build_end
+# undef jit_function_from_closure
+# undef jit_dump_function
+# undef jit_init
+# undef jit_context_create
+# undef jit_type_create_signature
+
+# define jit_value_create_nint_constant fn_jit_value_create_nint_constant
+# if EMACS_INT_MAX > LONG_MAX
+# define jit_value_create_long_constant fn_jit_value_create_long_constant
+# endif
+# define jit_insn_store fn_jit_insn_store
+# define jit_insn_and fn_jit_insn_and
+# if !USE_LSB_TAG
+# define jit_insn_ushr fn_jit_insn_ushr
+# endif
+# define jit_insn_sub fn_jit_insn_sub
+# define jit_insn_sshr fn_jit_insn_sshr
+# define jit_insn_eq fn_jit_insn_eq
+# define jit_insn_branch_if_not fn_jit_insn_branch_if_not
+# define jit_insn_branch_if fn_jit_insn_branch_if
+# define jit_insn_branch fn_jit_insn_branch
+# define jit_insn_label fn_jit_insn_label
+# define jit_insn_call_native fn_jit_insn_call_native
+# define jit_insn_shl fn_jit_insn_shl
+# define jit_insn_add fn_jit_insn_add
+# define jit_insn_load_relative fn_jit_insn_load_relative
+# define jit_insn_neg fn_jit_insn_neg
+# define jit_insn_store_relative fn_jit_insn_store_relative
+# define jit_function_create fn_jit_function_create
+# define jit_function_set_meta fn_jit_function_set_meta
+# define jit_value_create fn_jit_value_create
+# define jit_value_get_param fn_jit_value_get_param
+# define jit_insn_gt fn_jit_insn_gt
+# define jit_insn_lt fn_jit_insn_lt
+# define jit_insn_le fn_jit_insn_le
+# define jit_insn_load_elem_address fn_jit_insn_load_elem_address
+# define jit_insn_return fn_jit_insn_return
+# define jit_insn_add_relative fn_jit_insn_add_relative
+# define jit_function_reserve_label fn_jit_function_reserve_label
+# define jit_insn_jump_table fn_jit_insn_jump_table
+# define jit_insn_alloca fn_jit_insn_alloca
+# define jit_insn_move_blocks_to_start fn_jit_insn_move_blocks_to_start
+# define jit_function_compile fn_jit_function_compile
+# define jit_function_abandon fn_jit_function_abandon
+# define jit_function_to_closure fn_jit_function_to_closure
+# define jit_context_build_start fn_jit_context_build_start
+# define jit_context_build_end fn_jit_context_build_end
+# define jit_function_from_closure fn_jit_function_from_closure
+# define jit_dump_function fn_jit_dump_function
+# define jit_init fn_jit_init
+# define jit_context_create fn_jit_context_create
+# define jit_type_create_signature fn_jit_type_create_signature
+
+# undef jit_type_void_ptr
+# undef jit_type_uint
+# undef jit_type_nint
+# undef jit_type_sys_int
+# undef jit_type_int
+# undef jit_type_void
+# if EMACS_INT_MAX > LONG_MAX
+# undef jit_type_sys_longlong
+# undef jit_type_long
+# endif
+# undef jit_type_ulong
+
+# define jit_type_void_ptr *pv_jit_type_void_ptr
+# define jit_type_uint *pv_jit_type_uint
+# define jit_type_nint *pv_jit_type_nint
+# define jit_type_sys_int *pv_jit_type_sys_int
+# define jit_type_int *pv_jit_type_int
+# define jit_type_void *pv_jit_type_void
+# if EMACS_INT_MAX > LONG_MAX
+# define jit_type_sys_longlong *pv_jit_type_sys_longlong
+# define jit_type_long *pv_jit_type_long
+# endif
+# define jit_type_ulong *pv_jit_type_ulong
+
+#endif /* WINDOWSNT */
+
static bool emacs_jit_initialized;
jit_context_t emacs_jit_context;
@@ -52,6 +345,7 @@ static jit_type_t specbind_signature;
static jit_type_t record_unwind_protect_excursion_signature;
static jit_type_t record_unwind_protect_signature;
static jit_type_t void_void_signature;
+static jit_type_t lisp_void_signature;
static jit_type_t push_handler_signature;
static jit_type_t setjmp_signature;
@@ -61,8 +355,13 @@ static jit_type_t ptrdiff_t_type;
/* Make a pointer constant. */
+#if EMACS_INT_MAX == INT_MAX
#define CONSTANT(FUNC, VAL) \
- jit_value_create_long_constant (FUNC, jit_type_void_ptr, (jit_long)
(uintptr_t) (VAL))
+ jit_value_create_nint_constant (FUNC, jit_type_nint, XLI (VAL))
+#else
+#define CONSTANT(FUNC, VAL) \
+ jit_value_create_long_constant (FUNC, jit_type_long, (jit_long) XLI (VAL))
+#endif
/* Fetch the next byte from the bytecode stream. */
@@ -110,7 +409,11 @@ untag (jit_function_t func, jit_value_t val, EMACS_UINT
utype)
utype = utype << (USE_LSB_TAG ? 0 : VALBITS);
+#if EMACS_INT_MAX <= LONG_MAX
tem = jit_value_create_nint_constant (func, jit_type_void_ptr, utype);
+#else
+ tem = jit_value_create_long_constant (func, jit_type_ulong,
(jit_ulong)utype);
+#endif
return jit_insn_sub (func, val, tem);
}
@@ -314,9 +617,15 @@ compile_make_natnum (jit_function_t func, jit_value_t
untagged_int)
= jit_value_create_nint_constant (func, jit_type_void_ptr, Lisp_Int0);
return jit_insn_add (func, val, tag);
#else /* USE_LSB_TAG */
+# if EMACS_INT_MAX <= LONG_MAX
jit_value_t tag
= jit_value_create_nint_constant (func, jit_type_void_ptr,
((EMACS_INT) Lisp_Int0) << VALBITS);
+# else
+ jit_value_t tag
+ = jit_value_create_long_constant (func, jit_type_ulong,
+ ((EMACS_INT) Lisp_Int0) << VALBITS);
+# endif
return jit_insn_add (func, untagged_int, tag);
#endif /* not USE_LSB_TAG */
}
@@ -332,11 +641,19 @@ compile_make_number (jit_function_t func, jit_value_t
untagged_int)
= jit_value_create_nint_constant (func, jit_type_void_ptr, Lisp_Int0);
return jit_insn_add (func, val, tag);
#else /* USE_LSB_TAG */
+# if EMACS_INT_MAX <= LONG_MAX
jit_value_t mask
= jit_value_create_nint_constant (func, jit_type_void_ptr, INTMASK);
jit_value_t tag
= jit_value_create_nint_constant (func, jit_type_void_ptr,
((EMACS_INT) Lisp_Int0) << VALBITS);
+# else
+ jit_value_t mask
+ = jit_value_create_long_constant (func, jit_type_ulong, INTMASK);
+ jit_value_t tag
+ = jit_value_create_long_constant (func, jit_type_ulong,
+ ((EMACS_INT) Lisp_Int0) << VALBITS);
+# endif
jit_value_t val = jit_insn_and (func, untagged_int, mask);
return jit_insn_add (func, val, tag);
#endif /* not USE_LSB_TAG */
@@ -345,7 +662,9 @@ compile_make_number (jit_function_t func, jit_value_t
untagged_int)
static jit_value_t
compile_current_thread (jit_function_t func)
{
- jit_value_t thread_ptr = CONSTANT (func, ¤t_thread);
+ jit_value_t thread_ptr =
+ jit_value_create_nint_constant (func, jit_type_void_ptr,
+ (jit_nint) ¤t_thread);
return jit_insn_load_relative (func, thread_ptr, 0, jit_type_void_ptr);
}
@@ -487,8 +806,13 @@ unary_intmath (jit_function_t func, jit_value_t val, enum
math_op op,
{
case SUB1:
/* Don't allow (1- most-negative-fixnum). */
+#if EMACS_INT_MAX <= LONG_MAX
tem = jit_value_create_nint_constant (func, jit_type_sys_int,
MOST_NEGATIVE_FIXNUM);
+#else
+ tem = jit_value_create_long_constant (func, jit_type_sys_longlong,
+ MOST_NEGATIVE_FIXNUM);
+#endif
compare = jit_insn_eq (func, result, tem);
jit_insn_branch_if (func, compare, ¬_an_int);
@@ -498,8 +822,13 @@ unary_intmath (jit_function_t func, jit_value_t val, enum
math_op op,
case ADD1:
/* Don't allow (1+ most-positive-fixnum). */
+#if EMACS_INT_MAX <= LONG_MAX
tem = jit_value_create_nint_constant (func, jit_type_sys_int,
MOST_POSITIVE_FIXNUM);
+#else
+ tem = jit_value_create_long_constant (func, jit_type_sys_longlong,
+ MOST_POSITIVE_FIXNUM);
+#endif
compare = jit_insn_eq (func, result, tem);
jit_insn_branch_if (func, compare, ¬_an_int);
@@ -509,8 +838,13 @@ unary_intmath (jit_function_t func, jit_value_t val, enum
math_op op,
case NEGATE:
/* Don't allow (- most-negative-fixnum). */
+#if EMACS_INT_MAX <= LONG_MAX
tem = jit_value_create_nint_constant (func, jit_type_sys_int,
MOST_NEGATIVE_FIXNUM);
+#else
+ tem = jit_value_create_long_constant (func, jit_type_sys_longlong,
+ MOST_NEGATIVE_FIXNUM);
+#endif
compare = jit_insn_eq (func, result, tem);
jit_insn_branch_if (func, compare, ¬_an_int);
@@ -794,7 +1128,7 @@ compile (ptrdiff_t bytestr_length, unsigned char
*bytestr_data,
ptrdiff_t nonrest = at >> 8;
mandatory_val
- = jit_value_create_long_constant (func, ptrdiff_t_type, mandatory);
+ = jit_value_create_nint_constant (func, ptrdiff_t_type, mandatory);
nonrest_val
= jit_value_create_nint_constant (func, ptrdiff_t_type, nonrest);
@@ -1268,10 +1602,11 @@ compile (ptrdiff_t bytestr_length, unsigned char
*bytestr_data,
{
jit_value_t vals[2];
- vals[0] = CONSTANT (func, save_restriction_restore);
+ vals[0] = jit_value_create_nint_constant (func, jit_type_void_ptr,
+ (jit_nint)
save_restriction_restore);
vals[1] = jit_insn_call_native (func, "save_restriction_save",
(void *) save_restriction_save,
- void_void_signature,
+ lisp_void_signature,
NULL, 0, JIT_CALL_NOTHROW);
jit_insn_call_native (func, "record_unwind_protect",
(void *) record_unwind_protect,
@@ -1284,7 +1619,8 @@ compile (ptrdiff_t bytestr_length, unsigned char
*bytestr_data,
{
jit_value_t args[3];
- args[1] = CONSTANT (func, eval_sub);
+ args[1] = jit_value_create_nint_constant (func, jit_type_void_ptr,
+ (jit_nint) eval_sub);
args[2] = POP;
args[0] = POP;
@@ -1360,7 +1696,8 @@ compile (ptrdiff_t bytestr_length, unsigned char
*bytestr_data,
{
jit_value_t args[2];
- args[0] = CONSTANT (func, bcall0);
+ args[0] = jit_value_create_nint_constant (func, jit_type_void_ptr,
+ (jit_nint) bcall0);
args[1] = POP;
jit_insn_call_native (func, "record_unwind_protect",
(void *) record_unwind_protect,
@@ -2187,7 +2524,7 @@ compile (ptrdiff_t bytestr_length, unsigned char
*bytestr_data,
void
emacs_jit_compile (Lisp_Object func)
{
- if (!emacs_jit_initialized)
+ if (!emacs_jit_initialized || jit_disable)
return;
Lisp_Object bytestr = AREF (func, COMPILED_BYTECODE);
@@ -2215,7 +2552,7 @@ emacs_jit_compile (Lisp_Object func)
vectorp, ASIZE (vector),
AREF (func, COMPILED_ARGLIST));
- XVECTOR (func)->contents[COMPILED_JIT_CODE] = (Lisp_Object) subr;
+ XVECTOR (func)->contents[COMPILED_JIT_CODE] = XPL (subr);
jit_context_build_end (emacs_jit_context);
}
@@ -2231,7 +2568,7 @@ DEFUN ("jit-compile", Fjit_compile, Sjit_compile,
error ("Not a byte-compiled function");
vec = XVECTOR (func);
- if (vec->contents[COMPILED_JIT_CODE] == NULL)
+ if (XLP (vec->contents[COMPILED_JIT_CODE]) == NULL)
emacs_jit_compile (func);
return Qnil;
@@ -2253,7 +2590,7 @@ DEFUN ("jit-disassemble-to-string",
Fjit_disassemble_to_string,
if (!COMPILEDP (func))
error ("Not a byte-compiled function");
vec = XVECTOR (func);
- sfunc = (struct subr_function *) vec->contents[COMPILED_JIT_CODE];
+ sfunc = (struct subr_function *) XLP (vec->contents[COMPILED_JIT_CODE]);
if (sfunc == NULL)
error ("Not JIT-compiled");
@@ -2304,6 +2641,10 @@ syms_of_jit (void)
defsubr (&Sjit_compile);
defsubr (&Sjit_disassemble_to_string);
DEFSYM (Qinteractive_p, "interactive-p");
+
+ DEFVAR_BOOL ("jit-disable", jit_disable,
+ doc: /* Non-nil means disable JIT compilation even if supported. */);
+ jit_disable = 0;
}
void
@@ -2311,9 +2652,23 @@ init_jit (void)
{
#define LEN SUBR_MAX_ARGS
- jit_type_t params[LEN];
+ jit_type_t params[LEN], lisp_object_type;
int i;
+#ifdef WINDOWSNT
+ if (!init_libjit_functions ())
+ return;
+ Vlibrary_cache = Fcons (Fcons (Qlibjit, Qt), Vlibrary_cache);
+#endif
+
+#if EMACS_INT_MAX <= LONG_MAX
+ /* 32-bit builds without wide ints, 64-bit builds on Posix hosts. */
+ lisp_object_type = jit_type_void_ptr;
+#else
+ /* 64-bit builds on MS-Windows, 32-bit builds with wide ints. */
+ lisp_object_type = jit_type_sys_longlong;
+#endif
+
jit_init ();
emacs_jit_context = jit_context_create ();
@@ -2326,51 +2681,56 @@ init_jit (void)
}
for (i = 0; i < LEN; ++i)
- params[i] = jit_type_void_ptr;
+ params[i] = lisp_object_type;
for (i = 0; i < SUBR_MAX_ARGS; ++i)
subr_signature[i] = jit_type_create_signature (jit_abi_cdecl,
- jit_type_void_ptr,
+ lisp_object_type,
params, i, 1);
nullary_signature = jit_type_create_signature (jit_abi_cdecl,
- jit_type_void_ptr, params, 0,
+ lisp_object_type, params, 0,
1);
unary_signature = jit_type_create_signature (jit_abi_cdecl,
- jit_type_void_ptr, params, 1,
+ lisp_object_type, params, 1,
1);
binary_signature = jit_type_create_signature (jit_abi_cdecl,
- jit_type_void_ptr, params, 2,
+ lisp_object_type, params, 2,
1);
ternary_signature = jit_type_create_signature (jit_abi_cdecl,
- jit_type_void_ptr, params, 3,
+ lisp_object_type, params, 3,
1);
specbind_signature = jit_type_create_signature (jit_abi_cdecl,
jit_type_void, params, 2, 1);
record_unwind_protect_excursion_signature
- = jit_type_create_signature (jit_abi_cdecl, jit_type_void_ptr, NULL, 0, 1);
- record_unwind_protect_signature
- = jit_type_create_signature (jit_abi_cdecl, jit_type_void, params, 2, 1);
+ = jit_type_create_signature (jit_abi_cdecl, jit_type_void, NULL, 0, 1);
+ lisp_void_signature = jit_type_create_signature (jit_abi_cdecl,
+ lisp_object_type, NULL, 0,
1);
void_void_signature = jit_type_create_signature (jit_abi_cdecl,
jit_type_void, NULL, 0, 1);
temp_output_buffer_show_signature
- = jit_type_create_signature (jit_abi_cdecl, jit_type_void_ptr,
- params, 1, 1);
+ = jit_type_create_signature (jit_abi_cdecl, jit_type_void, params, 1, 1);
+ params[0] = jit_type_void_ptr;
+ record_unwind_protect_signature
+ = jit_type_create_signature (jit_abi_cdecl, jit_type_void, params, 2, 1);
+
+ params[0] = lisp_object_type;
params[2] = jit_type_sys_int;
arithcompare_signature = jit_type_create_signature (jit_abi_cdecl,
- jit_type_void_ptr,
+ lisp_object_type,
params, 3, 1);
params[0] = jit_type_sys_int;
unbind_n_signature = jit_type_create_signature (jit_abi_cdecl,
- jit_type_void_ptr, params, 1,
+ lisp_object_type, params, 1,
1);
params[0] = ptrdiff_t_type;
+ params[1] = jit_type_void_ptr;
callN_signature = jit_type_create_signature (jit_abi_cdecl,
- jit_type_void_ptr, params, 2,
+ lisp_object_type, params, 2,
1);
compiled_signature = callN_signature;
@@ -2380,9 +2740,9 @@ init_jit (void)
wrong_number_of_arguments_signature
= jit_type_create_signature (jit_abi_cdecl, jit_type_void, params, 3, 1);
- params[0] = jit_type_void_ptr;
- params[1] = jit_type_void_ptr;
- params[2] = jit_type_void_ptr;
+ params[0] = lisp_object_type;
+ params[1] = lisp_object_type;
+ params[2] = lisp_object_type;
params[3] = jit_type_sys_int;
set_internal_signature
= jit_type_create_signature (jit_abi_cdecl, jit_type_void, params, 4, 1);
diff --git a/src/lisp.h b/src/lisp.h
index b44d632..67fa18e 100644
--- a/src/lisp.h
+++ b/src/lisp.h
@@ -4631,8 +4631,13 @@ safe_free_unbind_to (ptrdiff_t count, ptrdiff_t
sa_count, Lisp_Object val)
Build with CPPFLAGS='-DUSE_STACK_LISP_OBJECTS=0' to disable it. */
#if (!defined USE_STACK_LISP_OBJECTS \
- && defined __GNUC__ && !defined __clang__ && ! GNUC_PREREQ (4, 3, 2))
- /* Work around GCC bugs 36584 and 35271, which were fixed in GCC 4.3.2. */
+ && defined __GNUC__ && !defined __clang__ \
+ && (! GNUC_PREREQ (4, 3, 2) \
+ || (defined __MINGW32__ && INTPTR_MAX <= INT_MAX && HAVE_LIBJIT)))
+ /* Work around GCC bugs 36584 and 35271, which were fixed in GCC 4.3.2.
+ Using libjit in 32-bit MS-Windows builds cannot ensure proper stack
+ alignment when JIT code calls back into Emacs, so disable stack-based
+ objects. */
# define USE_STACK_LISP_OBJECTS false
#endif
#ifndef USE_STACK_LISP_OBJECTS
diff --git a/src/w32fns.c b/src/w32fns.c
index 8d5293c..4ac9f10 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -10258,6 +10258,7 @@ syms_of_w32fns (void)
DEFSYM (Qzlib, "zlib");
DEFSYM (Qlcms2, "lcms2");
DEFSYM (Qjson, "json");
+ DEFSYM (Qlibjit, "libjit");
Fput (Qundefined_color, Qerror_conditions,
listn (CONSTYPE_PURE, 2, Qundefined_color, Qerror));
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Emacs-diffs] feature/libjit 39c6bef: Fix MS-Windows build with libjit,
Eli Zaretskii <=