+2011-07-27 Aleksey Demakov <ademakov@gmail.com>
+
+ * jit/jit-config.h: added new file as central location for all
+ platform config macros deduced from ./configure and cpp.
+ * jit/Makefile.am: add jit-config.h.
+
+ * include/jit/jit-context.h, jit/jit-context.c
+ (jit_context_supports_threads): removed.
+ * include/jit/jit-init.h, jit/jit-init.c (jit_supports_threads):
+ added function to replace jit_context_supports_threads.
+
+ * include/jit/jit-init.h, jit/jit-init.c
+ (jit_supports_virtual_memory): added new function to check if
+ the jit supports virtual memory routines.
+
+ * include/jit/jit-vmem.h, jit/jit-vmem.c (jit_vmem_init)
+ (jit_vmem_page_size, jit_vmem_round_up, jit_vmem_round_down)
+ (jit_vmem_reserve, jit_vmem_reserve_committed, jit_vmem_release)
+ (jit_vmem_commit, jit_vmem_decommit, jit_vmem_protect): added new
+ files with virtual memory routines.
+ * include/jit/Makefile.am, include/jit/jit.h: add jit-vmem.h
+ * jit/Makefile.am: add jit-vmem.c
+
+ * jit/jit-init.c (jit_init): call jit_vmem_init().
+
2011-07-10 Aleksey Demakov <ademakov@gmail.com>
* jit/jit-reg-alloc.c (choose_output_register, _jit_regs_assign):
jit-unwind.h \
jit-util.h \
jit-value.h \
+ jit-vmem.h \
jit-walk.h
nodist_libjitinclude_HEADERS = \
jit_context_t jit_context_create(void) JIT_NOTHROW;
void jit_context_destroy(jit_context_t context) JIT_NOTHROW;
-int jit_context_supports_threads(jit_context_t context) JIT_NOTHROW;
void jit_context_build_start(jit_context_t context) JIT_NOTHROW;
void jit_context_build_end(jit_context_t context) JIT_NOTHROW;
void jit_context_set_on_demand_driver(
#endif
void jit_init(void) JIT_NOTHROW;
+
int jit_uses_interpreter(void) JIT_NOTHROW;
+int jit_supports_threads(void) JIT_NOTHROW;
+
+int jit_supports_virtual_memory(void) JIT_NOTHROW;
+
#ifdef __cplusplus
};
#endif
--- /dev/null
+/*
+ * jit-vmem.h - Virtual memory routines.
+ *
+ * Copyright (C) 2011 Southern Storm Software, Pty Ltd.
+ *
+ * The libjit library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The libjit library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the libjit library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _JIT_VMEM_H
+#define _JIT_VMEM_H
+
+#include <jit/jit-defs.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+ JIT_PROT_NONE,
+ JIT_PROT_READ,
+ JIT_PROT_READ_WRITE,
+ JIT_PROT_EXEC_READ,
+ JIT_PROT_EXEC_READ_WRITE,
+} jit_prot_t;
+
+
+void jit_vmem_init(void);
+
+jit_uint jit_vmem_page_size(void);
+jit_nuint jit_vmem_round_up(jit_nuint value);
+jit_nuint jit_vmem_round_down(jit_nuint value);
+
+void *jit_vmem_reserve(jit_uint size);
+void *jit_vmem_reserve_committed(jit_uint size, jit_prot_t prot);
+int jit_vmem_release(void *addr, jit_uint size);
+
+int jit_vmem_commit(void *addr, jit_uint size, jit_prot_t prot);
+int jit_vmem_decommit(void *addr, jit_uint size);
+
+int jit_vmem_protect(void *addr, jit_uint size, jit_prot_t prot);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _JIT_VMEM_H */
#include <jit/jit-unwind.h>
#include <jit/jit-util.h>
#include <jit/jit-value.h>
+#include <jit/jit-vmem.h>
#include <jit/jit-walk.h>
#ifdef __cplusplus
jit-cache.h \
jit-cache.c \
jit-compile.c \
+ jit-config.h \
jit-context.c \
jit-cpuid-x86.h \
jit-cpuid-x86.c \
jit-type.c \
jit-unwind.c \
jit-value.c \
+ jit-vmem.c \
jit-walk.c
EXTRA_DIST = \
* <http://www.gnu.org/licenses/>.
*/
-#include "jit-internal.h"
-#include <config.h>
+#include "jit-config.h"
+
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
--- /dev/null
+/*
+ * jit-config.h - Configuration macros for the JIT.
+ *
+ * Copyright (C) 2011 Southern Storm Software, Pty Ltd.
+ *
+ * This file is part of the libjit library.
+ *
+ * The libjit library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The libjit library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the libjit library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _JIT_CONFIG_H
+#define _JIT_CONFIG_H
+
+#include <config.h>
+
+/*
+ * Determine what kind of system we are running on.
+ */
+#if defined(__CYGWIN__) || defined(__CYGWIN32__)
+# define JIT_WIN32_CYGWIN 1
+# define JIT_WIN32_PLATFORM 1
+#elif defined(_WIN32) || defined(WIN32)
+# define JIT_WIN32_NATIVE 1
+# define JIT_WIN32_PLATFORM 1
+#elif defined(__APPLE__) && defined(__MACH__)
+# define JIT_DARWIN_PLATFORM 1
+#elif defined(__linux__)
+# define JIT_LINUX_PLATFORM 1
+#endif
+
+/*
+ * Determine the type of threading library that we are using.
+ */
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_LIBPTHREAD)
+# define JIT_THREADS_SUPPORTED 1
+# define JIT_THREADS_PTHREAD 1
+#elif defined(JIT_WIN32_PLATFORM)
+# define JIT_THREADS_SUPPORTED 1
+# define JIT_THREADS_WIN32 1
+#else
+# define JIT_THREADS_SUPPORTED 0
+#endif
+
+/*
+ * Determine the type of virtual memory API that we are using.
+ */
+#if defined(JIT_WIN32_PLATFORM)
+# define JIT_VMEM_SUPPORTED 1
+# define JIT_VMEM_WIN32 1
+#elif defined(HAVE_SYS_MMAN_H)
+# define JIT_VMEM_SUPPORTED 1
+# define JIT_VMEM_MMAP 1
+#else
+# define JIT_VMEM_SUPPORTED 0
+#endif
+
+/*
+ * Determine which backend to use.
+ */
+#if defined(USE_LIBJIT_INTERPRETER)
+# define JIT_BACKEND_INTERP 1
+# define JIT_HAVE_BACKEND 1
+#elif defined(__alpha) || defined(__alpha__)
+# define JIT_BACKEND_ALPHA 1
+# define JIT_HAVE_BACKEND 1
+#elif defined(__arm) || defined(__arm__)
+# define JIT_BACKEND_ARM 1
+# define JIT_HAVE_BACKEND 1
+#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
+# define JIT_BACKEND_X86 1
+# define JIT_HAVE_BACKEND 1
+#elif defined(__amd64) || defined(__amd64__) || defined(_x86_64) || defined(_x86_64__)
+# define JIT_BACKEND_X86_64 1
+# define JIT_HAVE_BACKEND 1
+#endif
+
+/*
+ * Fallback to interpreter if there is no appropriate native backend.
+ */
+#if !defined(JIT_HAVE_BACKEND)
+# define JIT_BACKEND_INTERP 1
+#endif
+
+/*
+#define _JIT_COMPILE_DEBUG 1
+#define _JIT_BLOCK_DEBUG 1
+ */
+
+#endif /* _JIT_CONFIG_H */
+
}
}
-/*@
- * @deftypefun int jit_context_supports_threads (jit_context_t @var{context})
- * Determine if the JIT supports threads.
- * @end deftypefun
-@*/
-int jit_context_supports_threads(jit_context_t context)
-{
- return JIT_THREADS_SUPPORTED;
-}
-
/*@
* @deftypefun void jit_context_build_start (jit_context_t @var{context})
* This routine should be called before you start building a function
#include "jit-internal.h"
#include "jit-rules.h"
#include <jit/jit-dump.h>
-#include <config.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
#include "jit-rules.h"
#include "jit-elf-defs.h"
#include "jit-memory.h"
-#include <config.h>
#ifdef JIT_WIN32_PLATFORM
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#include "jit-internal.h"
#include "jit-rules.h"
-#include <config.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#endif
*/
#include "jit-internal.h"
-#include "jit-rules.h"
/*@
* @deftypefun void jit_init (void)
* initializations are quietly ignored.
* @end deftypefun
@*/
-void jit_init(void)
+void
+jit_init(void)
{
static int init_done = 0;
_jit_signal_init();
#endif
+ /* Initialize the virtual memory system */
+ jit_vmem_init();
+
/* Initialize the backend */
_jit_init_backend();
* called prior to @code{jit_init}.
* @end deftypefun
@*/
-int jit_uses_interpreter(void)
+int
+jit_uses_interpreter(void)
{
#if defined(JIT_BACKEND_INTERP)
return 1;
return 0;
#endif
}
+
+/*@
+ * @deftypefun int jit_supports_threads (void)
+ * Determine if the JIT supports threads.
+ * @end deftypefun
+@*/
+int
+jit_supports_threads(void)
+{
+ return JIT_THREADS_SUPPORTED;
+}
+
+/*@
+ * @deftypefun int jit_supports_virtual_memory (void)
+ * Determine if the JIT supports virtual memory.
+ * @end deftypefun
+@*/
+int
+jit_supports_virtual_memory(void)
+{
+ return JIT_VMEM_SUPPORTED;
+}
#include "jit-internal.h"
#include "jit-rules.h"
#include "jit-setjmp.h"
-#include <config.h>
#if HAVE_STDLIB_H
# include <stdlib.h>
#endif
#define _JIT_INTERNAL_H
#include <jit/jit.h>
+#include "jit-config.h"
#ifdef __cplusplus
extern "C" {
#endif
-/*
-#define _JIT_COMPILE_DEBUG 1
-#define _JIT_BLOCK_DEBUG 1
-*/
-
-/*
- * Determine what kind of Win32 system we are running on.
- */
-#if defined(__CYGWIN__) || defined(__CYGWIN32__)
-#define JIT_WIN32_CYGWIN 1
-#define JIT_WIN32_PLATFORM 1
-#elif defined(_WIN32) || defined(WIN32)
-#define JIT_WIN32_NATIVE 1
-#define JIT_WIN32_PLATFORM 1
-#endif
-
/*
* We need the apply rules for "jit_redirector_size".
*/
#include "jit-interp.h"
#include "jit-rules.h"
#include "jit-memory.h"
-#include <config.h>
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
*/
#include "jit-internal.h"
-#include <config.h>
#if defined(HAVE_TGMATH_H) && !defined(JIT_NFLOAT_IS_DOUBLE)
#include <tgmath.h>
#elif defined(HAVE_MATH_H)
#ifndef _JIT_RULES_H
#define _JIT_RULES_H
+#include "jit-config.h"
#include "jit-cache.h"
-#include <config.h>
#ifdef __cplusplus
extern "C" {
#endif
-/*
- * Determine which backend to use.
- */
-#if defined(USE_LIBJIT_INTERPRETER)
-# define JIT_BACKEND_INTERP 1
-# define JIT_HAVE_BACKEND 1
-#elif defined(__alpha) || defined(__alpha__)
-# define JIT_BACKEND_ALPHA 1
-# define JIT_HAVE_BACKEND 1
-#elif defined(__arm) || defined(__arm__)
-# define JIT_BACKEND_ARM 1
-# define JIT_HAVE_BACKEND 1
-#elif defined(__i386) || defined(__i386__) || defined(_M_IX86)
-# define JIT_BACKEND_X86 1
-# define JIT_HAVE_BACKEND 1
-#elif defined(__amd64) || defined(__amd64__) || defined(_x86_64) || defined(_x86_64__)
-# define JIT_BACKEND_X86_64 1
-# define JIT_HAVE_BACKEND 1
-#endif
-
-/*
- * Fallback to interpreter if there is no appropriate native backend.
- */
-#if !defined(JIT_HAVE_BACKEND)
-# define JIT_BACKEND_INTERP 1
-#endif
-
/*
* Information about a register.
*/
* <http://www.gnu.org/licenses/>.
*/
-#include <config.h>
+#include "jit-internal.h"
#ifdef JIT_USE_SIGNALS
-#include "jit-internal.h"
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
* <http://www.gnu.org/licenses/>.
*/
-#include "jit-internal.h"
-#include <config.h>
+#include <jit/jit-util.h>
+#include "jit-config.h"
#ifdef HAVE_STRING_H
#include <string.h>
#elif defined(HAVE_STRINGS_H)
#ifndef _JIT_THREAD_H
#define _JIT_THREAD_H
-#include <config.h>
-#if defined(HAVE_PTHREAD_H) && defined(HAVE_LIBPTHREAD)
- #include <pthread.h>
-#elif defined(JIT_WIN32_PLATFORM)
- #include <windows.h>
+#include <jit/jit-defs.h>
+#include "jit-config.h"
+
+#if defined(JIT_THREADS_PTHREAD)
+# include <pthread.h>
+#elif defined(JIT_THREADS_WIN32)
+# include <windows.h>
#endif
#ifdef __cplusplus
extern "C" {
#endif
-/*
- * Determine the type of threading library that we are using.
- */
-#if defined(HAVE_PTHREAD_H) && defined(HAVE_LIBPTHREAD)
- #define JIT_THREADS_SUPPORTED 1
- #define JIT_THREADS_PTHREAD 1
-#elif defined(JIT_WIN32_PLATFORM)
- #define JIT_THREADS_SUPPORTED 1
- #define JIT_THREADS_WIN32 1
-#else
- #define JIT_THREADS_SUPPORTED 0
-#endif
-
/*
* Type that describes a thread's identifier, and the id comparison function.
*/
#include "jit-internal.h"
#include "jit-apply-rules.h"
#include "jit-rules.h"
-#include <config.h>
/*@
--- /dev/null
+/*
+ * jit-vmem.c - Virtual memory routines.
+ *
+ * Copyright (C) 2011 Southern Storm Software, Pty Ltd.
+ *
+ * The libjit library is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * The libjit library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the libjit library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#include <jit/jit-vmem.h>
+#include "jit-config.h"
+
+#if defined(JIT_VMEM_WIN32)
+# include <windows.h>
+#elif defined(JIT_VMEM_MMAP)
+# include <sys/mman.h>
+#endif
+
+#if !defined(JIT_WIN32_PLATFORM) && defined(HAVE_UNISTD_H)
+# include <unistd.h>
+#endif
+
+/*
+ * Define getpagesize() if not provided
+ */
+#if !defined(JIT_WIN32_PLATFORM) && !defined(HAVE_GETPAGESIZE)
+# if defined(NBPG)
+# define getpagesize() (NBPG)
+# elif defined(PAGE_SIZE)
+# define getpagesize() (PAGE_SIZE)
+# else
+# define getpagesize() (4096)
+# endif
+#endif
+
+/*
+ * Make sure that "MAP_ANONYMOUS" is correctly defined, because it
+ * may not exist on some variants of Unix.
+ */
+#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+static jit_uint page_size;
+
+#if defined(JIT_VMEM_WIN32)
+static DWORD
+convert_prot(jit_prot_t prot)
+{
+ switch(prot)
+ {
+ case JIT_PROT_NONE:
+ return PAGE_NOACCESS;
+ case JIT_PROT_READ:
+ return PAGE_READONLY;
+ case JIT_PROT_READ_WRITE:
+ return PAGE_READWRITE;
+ case JIT_PROT_EXEC_READ:
+ return PAGE_EXECUTE_READ;
+ case JIT_PROT_EXEC_READ_WRITE:
+ return PAGE_EXECUTE_READWRITE;
+ }
+ return PAGE_NOACCESS;
+}
+#elif defined(JIT_VMEM_MMAP)
+static int
+convert_prot(jit_prot_t prot)
+{
+ switch(prot)
+ {
+ case JIT_PROT_NONE:
+ return PROT_NONE;
+ case JIT_PROT_READ:
+ return PROT_READ;
+ case JIT_PROT_READ_WRITE:
+ return PROT_READ | PROT_WRITE;
+ case JIT_PROT_EXEC_READ:
+ return PROT_EXEC | PROT_READ;
+ case JIT_PROT_EXEC_READ_WRITE:
+ return PROT_EXEC | PROT_READ | PROT_WRITE;
+ }
+ return PROT_NONE;
+}
+#endif
+
+void
+jit_vmem_init(void)
+{
+#if defined(JIT_VMEM_WIN32)
+ /* Get the page size from a Windows-specific API */
+ SYSTEM_INFO sysInfo;
+ GetSystemInfo(&sysInfo);
+ page_size = (jit_uint) (sysInfo.dwPageSize);
+#else
+ /* Get the page size using a Unix-like sequence */
+ page_size = (jit_uint) getpagesize();
+#endif
+}
+
+jit_uint
+jit_vmem_page_size(void)
+{
+ return page_size;
+}
+
+jit_nuint
+jit_vmem_round_up(jit_nuint value)
+{
+ return (value + page_size - 1) & ~(page_size - 1);
+}
+
+jit_nuint
+jit_vmem_round_down(jit_nuint value)
+{
+ return ((jit_nuint) value) & ~(page_size - 1);
+}
+
+void *
+jit_vmem_reserve(jit_uint size)
+{
+#if defined(JIT_VMEM_WIN32)
+
+ return VirtualAlloc(NULL, size, MEM_RESERVE, PAGE_NOACCESS);
+
+#elif defined(JIT_VMEM_MMAP)
+
+ void *addr;
+
+ addr = mmap(0, size, PROT_NONE,
+ MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
+ if(addr == MAP_FAILED)
+ {
+ return (void *) 0;
+ }
+ return addr;
+
+#else
+ return (void *) 0;
+#endif
+}
+
+void *
+jit_vmem_reserve_committed(jit_uint size, jit_prot_t prot)
+{
+#if defined(JIT_VMEM_WIN32)
+
+ DWORD nprot;
+
+ nprot = convert_prot(prot);
+ return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, nprot);
+
+#elif defined(JIT_VMEM_MMAP)
+
+ void *addr;
+ int nprot;
+
+ nprot = convert_prot(prot);
+ addr = mmap(0, size, nprot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if(addr == MAP_FAILED)
+ {
+ return (void *) 0;
+ }
+ return addr;
+
+#else
+ return (void *) 0;
+#endif
+}
+
+int
+jit_vmem_release(void *addr, jit_uint size)
+{
+#if defined(JIT_VMEM_WIN32)
+
+ return VirtualFree(addr, 0, MEM_RELEASE) != 0;
+
+#elif defined(JIT_VMEM_MMAP)
+
+ return munmap(addr, size) == 0;
+
+#else
+ return 0;
+#endif
+}
+
+int
+jit_vmem_commit(void *addr, jit_uint size, jit_prot_t prot)
+{
+#if defined(JIT_VMEM_WIN32)
+
+ DWORD nprot;
+
+ nprot = convert_prot(prot);
+ return VirtualAlloc(addr, size, MEM_COMMIT, nprot);
+
+#elif defined(JIT_VMEM_MMAP)
+
+ int nprot;
+
+ nprot = convert_prot(prot);
+ addr = mmap(0, size, nprot, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ if(addr == MAP_FAILED)
+ {
+ return (void *) 0;
+ }
+ return addr;
+
+#else
+ return 0;
+#endif
+}
+
+int
+jit_vmem_decommit(void *addr, jit_uint size)
+{
+#if defined(JIT_VMEM_WIN32)
+
+ return VirtualFree(addr, size, MEM_DECOMMIT) != 0;
+
+#elif defined(JIT_VMEM_MMAP)
+
+#if defined(MADV_FREE)
+ int result = madvise(addr, size, MADV_FREE);
+ if(result < 0)
+ {
+ return 0;
+ }
+#elif defined(MADV_DONTNEED) && defined(JIT_LINUX_PLATFORM)
+ int result = madvise(addr, size, MADV_DONTNEED);
+ if(result < 0)
+ {
+ return 0;
+ }
+#endif
+
+ addr = mmap(addr, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE, -1, 0);
+ if(addr == MAP_FAILED)
+ {
+ return 0;
+ }
+ return 1;
+
+#else
+ return 0;
+#endif
+}
+
+int
+jit_vmem_protect(void *addr, jit_uint size, jit_prot_t prot)
+{
+#if defined(JIT_VMEM_WIN32)
+
+ DWORD nprot, oprot;
+
+ nprot = convert_prot(prot);
+ if(VirtualProtect(addr, size, nprot, &oprot) == 0)
+ {
+ return 0;
+ }
+ return 1;
+
+#elif defined(JIT_VMEM_MMAP)
+
+ int nprot;
+
+ nprot = convert_prot(prot);
+ if(mprotect(addr, size, nprot) < 0)
+ {
+ return 0;
+ }
+ return 1;
+
+#else
+ return 0;
+#endif
+}