]> git.unchartedbackwaters.co.uk Git - francis/libjit.git/commitdiff
added virtual memory routines
authorAleksey Demakov <ademakov@gmail.com>
Wed, 27 Jul 2011 17:07:32 +0000 (00:07 +0700)
committerAleksey Demakov <ademakov@gmail.com>
Wed, 27 Jul 2011 17:07:32 +0000 (00:07 +0700)
24 files changed:
ChangeLog
include/jit/Makefile.am
include/jit/jit-context.h
include/jit/jit-init.h
include/jit/jit-vmem.h [new file with mode: 0644]
include/jit/jit.h
jit/Makefile.am
jit/jit-alloc.c
jit/jit-config.h [new file with mode: 0644]
jit/jit-context.c
jit/jit-dump.c
jit/jit-elf-read.c
jit/jit-except.c
jit/jit-init.c
jit/jit-insn.c
jit/jit-internal.h
jit/jit-interp.c
jit/jit-intrinsic.c
jit/jit-rules.h
jit/jit-signal.c
jit/jit-string.c
jit/jit-thread.h
jit/jit-type.c
jit/jit-vmem.c [new file with mode: 0644]

index 783ec23b65ec6dc12752ef99e1468fcc1afd7bb9..8b21823a65eda7759129886221e4abea0a9f7696 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+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):
index b7bf8bf664e4419e0ff3658eddff009fd02d539e..5ad4bf45a99d871abcd7bb97d087ce6921235c8d 100644 (file)
@@ -28,6 +28,7 @@ dist_libjitinclude_HEADERS = \
        jit-unwind.h \
        jit-util.h \
        jit-value.h \
+       jit-vmem.h \
        jit-walk.h
 
 nodist_libjitinclude_HEADERS = \
index ccb89d928523957cd9b93df0520d9769e9e2f120..cce58a6203a2ed0fbbf9940107a664859cc5b4e5 100644 (file)
@@ -29,7 +29,6 @@ extern        "C" {
 
 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(
index 27e38af61359f1a74f1cfa86ab07046dca409eb7..e213bf240f426ed1c9d29c0f5702a2a4a8c2f1ea 100644 (file)
@@ -28,8 +28,13 @@ extern       "C" {
 #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
diff --git a/include/jit/jit-vmem.h b/include/jit/jit-vmem.h
new file mode 100644 (file)
index 0000000..f5f05f2
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * 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 */
index 0cbdc754d10a96ff470437610de53c377fafdfae..c7dd475350b770bbdf3509705076175eff2855c7 100644 (file)
@@ -44,6 +44,7 @@ extern        "C" {
 #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
index 965afe9c17c4ef237ec31424ef3271aff3c4a754..de7acb09ef92cbd453dcb2689c78082c18cfed77 100644 (file)
@@ -20,6 +20,7 @@ libjit_la_SOURCES = \
        jit-cache.h \
        jit-cache.c \
        jit-compile.c \
+       jit-config.h \
        jit-context.c \
        jit-cpuid-x86.h \
        jit-cpuid-x86.c \
@@ -76,6 +77,7 @@ libjit_la_SOURCES = \
        jit-type.c \
        jit-unwind.c \
        jit-value.c \
+       jit-vmem.c \
        jit-walk.c
 
 EXTRA_DIST = \
index 7700769858b6e7c36c3f2885cd6bffe3d67e34ec..45d6a2c52f49db83ec195e60eb217c779a8153e0 100644 (file)
@@ -20,8 +20,8 @@
  * <http://www.gnu.org/licenses/>.
  */
 
-#include "jit-internal.h"
-#include <config.h>
+#include "jit-config.h"
+
 #ifdef HAVE_STDLIB_H
        #include <stdlib.h>
 #endif
diff --git a/jit/jit-config.h b/jit/jit-config.h
new file mode 100644 (file)
index 0000000..ad52a89
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * 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 */
+
index 3325960c6db9df60442160d15f7ab2b6addef115..c1ab3bf0a54d11bb24f55262da8f2df09cc90442 100644 (file)
@@ -125,16 +125,6 @@ void jit_context_destroy(jit_context_t context)
        }
 }
 
-/*@
- * @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
index 8af455efc0031e170e9eadbab777b7d67fe3b3e9..de6ac290bf5426caf0983afd644398d92e895245 100644 (file)
@@ -23,7 +23,6 @@
 #include "jit-internal.h"
 #include "jit-rules.h"
 #include <jit/jit-dump.h>
-#include <config.h>
 #ifdef HAVE_STDLIB_H
 # include <stdlib.h>
 #endif
index 3dedeeeb27ea78528341a375098eae50453cad74..cb1cf4011d370cb68eef7aaeac4087a0f27bf583 100644 (file)
@@ -24,7 +24,6 @@
 #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>
index 39649f71a742040a2c5f2bed281640970edad7e0..ae391f6782603a1b689ffc1a952ce0c58277e3eb 100644 (file)
@@ -22,7 +22,6 @@
 
 #include "jit-internal.h"
 #include "jit-rules.h"
-#include <config.h>
 #ifdef HAVE_STDLIB_H
 # include <stdlib.h>
 #endif
index e85beef034dfabc276be13e7658a06a4cd219ad7..5b08c8ae6154bf054de0a8742217bf3f9ee10ef7 100644 (file)
@@ -21,7 +21,6 @@
  */
 
 #include "jit-internal.h"
-#include "jit-rules.h"
 
 /*@
  * @deftypefun void jit_init (void)
@@ -37,7 +36,8 @@
  * initializations are quietly ignored.
  * @end deftypefun
 @*/
-void jit_init(void)
+void
+jit_init(void)
 {
        static int init_done = 0;
 
@@ -58,6 +58,9 @@ void jit_init(void)
        _jit_signal_init();
 #endif
 
+       /* Initialize the virtual memory system */
+       jit_vmem_init();
+
        /* Initialize the backend */
        _jit_init_backend();
 
@@ -72,7 +75,8 @@ done:
  * 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;
@@ -80,3 +84,25 @@ int jit_uses_interpreter(void)
        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;
+}
index 9c5b3fd0d1c3c0eb8a217a5bb64b3231b7aec502..bbd60b6adaa1bc73cfcecc59dbadc4f54db05176 100644 (file)
@@ -23,7 +23,6 @@
 #include "jit-internal.h"
 #include "jit-rules.h"
 #include "jit-setjmp.h"
-#include <config.h>
 #if HAVE_STDLIB_H
 # include <stdlib.h>
 #endif
index 5d152ca2c26ec97c8b681febba0b0aab02456dfe..911348e9ae6f0ecc58f0a3dca1a51f623889ca20 100644 (file)
 #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".
  */
index 15717c5cd3fae5a4707213293130b935894cb7d8..0e11df4284f0cd45d2854f1717456cb295aa89d2 100644 (file)
@@ -31,7 +31,6 @@ straight vanilla ANSI C.
 #include "jit-interp.h"
 #include "jit-rules.h"
 #include "jit-memory.h"
-#include <config.h>
 #if HAVE_STDLIB_H
        #include <stdlib.h>
 #endif
index 904e1b88c993497ba095b2ff6e01c4effd08c7a8..cc0e11f1724416a086b2c3d0745cf68d33c1e363 100644 (file)
@@ -21,7 +21,6 @@
  */
 
 #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)
index 3093cdd5cb29f8b4952d1a8d87abec4524572678..67909ffa5d331c411dc1bbf3b37967e859372f6a 100644 (file)
 #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.
  */
index e755c544b51daddaa8ed60cd00c41c1ce3e5702b..75d80037035055565ad691b419d0f1e6f3adf475 100644 (file)
  * <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>
index b37a9461e25697370f207cc8e670dd926cc57ab7..7deefbfc76deeee4e67c64b938f184deb714781f 100644 (file)
@@ -20,8 +20,8 @@
  * <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)
index bd64a935014ce2ecf7e497759292345bbd8908c2..e8b0046013df5d8a30a1d3d1cc201f06cceac795 100644 (file)
 #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.
  */
index 7c5fb80e1a7e1ca818540a7b82435bb7fe7f0c6a..8cec977edde06a9ce86af18c9799919560c4870d 100644 (file)
@@ -23,7 +23,6 @@
 #include "jit-internal.h"
 #include "jit-apply-rules.h"
 #include "jit-rules.h"
-#include <config.h>
 
 /*@
 
diff --git a/jit/jit-vmem.c b/jit/jit-vmem.c
new file mode 100644 (file)
index 0000000..dfdaf6c
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * 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
+}