diff options
| author | Mike Pall <mike> | 2010-02-26 18:20:24 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2010-02-26 18:20:24 +0100 |
| commit | 52b7651327b2aec4f12ae47f3ce5b56b1fb55996 (patch) | |
| tree | 05c7a64bdbbcc947b529a988faa39593a2be6477 | |
| parent | a0fbb05bf0353ac0fede6deec15db5d2d3a9017f (diff) | |
| download | luajit-52b7651327b2aec4f12ae47f3ce5b56b1fb55996.tar.gz luajit-52b7651327b2aec4f12ae47f3ce5b56b1fb55996.tar.bz2 luajit-52b7651327b2aec4f12ae47f3ce5b56b1fb55996.zip | |
Place dynamically generated code near static code on x64.
| -rw-r--r-- | src/Makefile.dep | 2 | ||||
| -rw-r--r-- | src/lj_mcode.c | 68 | ||||
| -rw-r--r-- | src/lj_state.c | 1 |
3 files changed, 59 insertions, 12 deletions
diff --git a/src/Makefile.dep b/src/Makefile.dep index 68b4f532..8af71749 100644 --- a/src/Makefile.dep +++ b/src/Makefile.dep | |||
| @@ -80,7 +80,7 @@ lj_lib.o: lj_lib.c lauxlib.h lua.h luaconf.h lj_obj.h lj_def.h lj_arch.h \ | |||
| 80 | lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_lib.h | 80 | lj_dispatch.h lj_jit.h lj_ir.h lj_vm.h lj_lib.h |
| 81 | lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ | 81 | lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ |
| 82 | lj_gc.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h lj_dispatch.h lj_bc.h \ | 82 | lj_gc.h lj_jit.h lj_ir.h lj_mcode.h lj_trace.h lj_dispatch.h lj_bc.h \ |
| 83 | lj_traceerr.h | 83 | lj_traceerr.h lj_vm.h |
| 84 | lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ | 84 | lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ |
| 85 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_bc.h lj_vm.h | 85 | lj_err.h lj_errmsg.h lj_str.h lj_tab.h lj_meta.h lj_bc.h lj_vm.h |
| 86 | lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h | 86 | lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h |
diff --git a/src/lj_mcode.c b/src/lj_mcode.c index 2ae0c2a9..e9921601 100644 --- a/src/lj_mcode.c +++ b/src/lj_mcode.c | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "lj_mcode.h" | 15 | #include "lj_mcode.h" |
| 16 | #include "lj_trace.h" | 16 | #include "lj_trace.h" |
| 17 | #include "lj_dispatch.h" | 17 | #include "lj_dispatch.h" |
| 18 | #include "lj_vm.h" | ||
| 18 | 19 | ||
| 19 | /* -- OS-specific functions ----------------------------------------------- */ | 20 | /* -- OS-specific functions ----------------------------------------------- */ |
| 20 | 21 | ||
| @@ -27,21 +28,22 @@ | |||
| 27 | #define MCPROT_RX PAGE_EXECUTE_READ | 28 | #define MCPROT_RX PAGE_EXECUTE_READ |
| 28 | #define MCPROT_RWX PAGE_EXECUTE_READWRITE | 29 | #define MCPROT_RWX PAGE_EXECUTE_READWRITE |
| 29 | 30 | ||
| 30 | static LJ_AINLINE void *mcode_alloc(jit_State *J, size_t sz, DWORD prot) | 31 | static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, DWORD prot) |
| 31 | { | 32 | { |
| 32 | void *p = VirtualAlloc(NULL, sz, MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, prot); | 33 | void *p = VirtualAlloc((void *)hint, sz, |
| 34 | MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN, prot); | ||
| 33 | if (!p) | 35 | if (!p) |
| 34 | lj_trace_err(J, LJ_TRERR_MCODEAL); | 36 | lj_trace_err(J, LJ_TRERR_MCODEAL); |
| 35 | return p; | 37 | return p; |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | static LJ_AINLINE void mcode_free(jit_State *J, void *p, size_t sz) | 40 | static void mcode_free(jit_State *J, void *p, size_t sz) |
| 39 | { | 41 | { |
| 40 | UNUSED(J); UNUSED(sz); | 42 | UNUSED(J); UNUSED(sz); |
| 41 | VirtualFree(p, 0, MEM_RELEASE); | 43 | VirtualFree(p, 0, MEM_RELEASE); |
| 42 | } | 44 | } |
| 43 | 45 | ||
| 44 | static LJ_AINLINE void mcode_setprot(void *p, size_t sz, DWORD prot) | 46 | static void mcode_setprot(void *p, size_t sz, DWORD prot) |
| 45 | { | 47 | { |
| 46 | DWORD oprot; | 48 | DWORD oprot; |
| 47 | VirtualProtect(p, sz, prot, &oprot); | 49 | VirtualProtect(p, sz, prot, &oprot); |
| @@ -59,21 +61,21 @@ static LJ_AINLINE void mcode_setprot(void *p, size_t sz, DWORD prot) | |||
| 59 | #define MCPROT_RX (PROT_READ|PROT_EXEC) | 61 | #define MCPROT_RX (PROT_READ|PROT_EXEC) |
| 60 | #define MCPROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC) | 62 | #define MCPROT_RWX (PROT_READ|PROT_WRITE|PROT_EXEC) |
| 61 | 63 | ||
| 62 | static LJ_AINLINE void *mcode_alloc(jit_State *J, size_t sz, int prot) | 64 | static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot) |
| 63 | { | 65 | { |
| 64 | void *p = mmap(NULL, sz, prot, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); | 66 | void *p = mmap((void *)hint, sz, prot, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); |
| 65 | if (p == MAP_FAILED) | 67 | if (p == MAP_FAILED) |
| 66 | lj_trace_err(J, LJ_TRERR_MCODEAL); | 68 | lj_trace_err(J, LJ_TRERR_MCODEAL); |
| 67 | return p; | 69 | return p; |
| 68 | } | 70 | } |
| 69 | 71 | ||
| 70 | static LJ_AINLINE void mcode_free(jit_State *J, void *p, size_t sz) | 72 | static void mcode_free(jit_State *J, void *p, size_t sz) |
| 71 | { | 73 | { |
| 72 | UNUSED(J); | 74 | UNUSED(J); |
| 73 | munmap(p, sz); | 75 | munmap(p, sz); |
| 74 | } | 76 | } |
| 75 | 77 | ||
| 76 | static LJ_AINLINE void mcode_setprot(void *p, size_t sz, int prot) | 78 | static void mcode_setprot(void *p, size_t sz, int prot) |
| 77 | { | 79 | { |
| 78 | mprotect(p, sz, prot); | 80 | mprotect(p, sz, prot); |
| 79 | } | 81 | } |
| @@ -86,13 +88,13 @@ static LJ_AINLINE void mcode_setprot(void *p, size_t sz, int prot) | |||
| 86 | #define MCPROT_RX 0 | 88 | #define MCPROT_RX 0 |
| 87 | #define MCPROT_RWX 0 | 89 | #define MCPROT_RWX 0 |
| 88 | 90 | ||
| 89 | static LJ_AINLINE void *mcode_alloc(jit_State *J, size_t sz, int prot) | 91 | static void *mcode_alloc_at(jit_State *J, uintptr_t hint, size_t sz, int prot) |
| 90 | { | 92 | { |
| 91 | UNUSED(prot); | 93 | UNUSED(hint); UNUSED(prot); |
| 92 | return lj_mem_new(J->L, sz); | 94 | return lj_mem_new(J->L, sz); |
| 93 | } | 95 | } |
| 94 | 96 | ||
| 95 | static LJ_AINLINE void mcode_free(jit_State *J, void *p, size_t sz) | 97 | static void mcode_free(jit_State *J, void *p, size_t sz) |
| 96 | { | 98 | { |
| 97 | lj_mem_free(J2G(J), p, sz); | 99 | lj_mem_free(J2G(J), p, sz); |
| 98 | } | 100 | } |
| @@ -101,6 +103,50 @@ static LJ_AINLINE void mcode_free(jit_State *J, void *p, size_t sz) | |||
| 101 | 103 | ||
| 102 | #endif | 104 | #endif |
| 103 | 105 | ||
| 106 | /* -- MCode area allocation ----------------------------------------------- */ | ||
| 107 | |||
| 108 | #if LJ_64 | ||
| 109 | |||
| 110 | /* Get memory within relative jump distance of our code in 64 bit mode. */ | ||
| 111 | static void *mcode_alloc(jit_State *J, size_t sz, int prot) | ||
| 112 | { | ||
| 113 | /* Target an address in the static assembler code. | ||
| 114 | ** Try addresses within a distance of target-1GB+1MB .. target+1GB-1MB. | ||
| 115 | */ | ||
| 116 | uintptr_t target = (uintptr_t)(void *)lj_vm_exit_handler; | ||
| 117 | const uintptr_t range = (1u<<31) - (1u << 21); | ||
| 118 | int i; | ||
| 119 | /* First try a contiguous area below the last one. */ | ||
| 120 | if (J->mcarea && (uintptr_t)J->mcarea - sz < (uintptr_t)1<<47) { | ||
| 121 | void *p = mcode_alloc_at(J, (uintptr_t)J->mcarea - sz, sz, prot); | ||
| 122 | if ((uintptr_t)p + sz - target < range || target - (uintptr_t)p < range) | ||
| 123 | return p; | ||
| 124 | mcode_free(J, p, sz); /* Free badly placed area. */ | ||
| 125 | } | ||
| 126 | /* Next try probing with hinted addresses. */ | ||
| 127 | for (i = 0; i < 32; i++) { /* 32 attempts ought to be enough ... */ | ||
| 128 | uintptr_t hint; | ||
| 129 | void *p; | ||
| 130 | do { | ||
| 131 | hint = LJ_PRNG_BITS(J, 15) << 16; | ||
| 132 | } while (!(hint + sz < range && | ||
| 133 | target + hint - (range>>1) < (uintptr_t)1<<47)); | ||
| 134 | p = mcode_alloc_at(J, target + hint - (range>>1), sz, prot); | ||
| 135 | if ((uintptr_t)p + sz - target < range || target - (uintptr_t)p < range) | ||
| 136 | return p; | ||
| 137 | mcode_free(J, p, sz); /* Free badly placed area. */ | ||
| 138 | } | ||
| 139 | lj_trace_err(J, LJ_TRERR_MCODEAL); /* Give up. OS probably ignores hints? */ | ||
| 140 | return NULL; | ||
| 141 | } | ||
| 142 | |||
| 143 | #else | ||
| 144 | |||
| 145 | /* All 32 bit memory addresses are reachable by relative jumps on x86. */ | ||
| 146 | #define mcode_alloc(J, sz, prot) mcode_alloc_at((J), 0, (sz), (prot)) | ||
| 147 | |||
| 148 | #endif | ||
| 149 | |||
| 104 | /* -- MCode area management ----------------------------------------------- */ | 150 | /* -- MCode area management ----------------------------------------------- */ |
| 105 | 151 | ||
| 106 | /* Define this ONLY if the page protection twiddling becomes a bottleneck. */ | 152 | /* Define this ONLY if the page protection twiddling becomes a bottleneck. */ |
diff --git a/src/lj_state.c b/src/lj_state.c index 3305fd18..e690a5d3 100644 --- a/src/lj_state.c +++ b/src/lj_state.c | |||
| @@ -143,6 +143,7 @@ static void close_state(lua_State *L) | |||
| 143 | global_State *g = G(L); | 143 | global_State *g = G(L); |
| 144 | #ifndef LUAJIT_USE_SYSMALLOC | 144 | #ifndef LUAJIT_USE_SYSMALLOC |
| 145 | if (g->allocf == lj_alloc_f) { | 145 | if (g->allocf == lj_alloc_f) { |
| 146 | lj_trace_freestate(g); | ||
| 146 | lj_alloc_destroy(g->allocd); | 147 | lj_alloc_destroy(g->allocd); |
| 147 | } else | 148 | } else |
| 148 | #endif | 149 | #endif |
