aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2010-02-26 18:20:24 +0100
committerMike Pall <mike>2010-02-26 18:20:24 +0100
commit52b7651327b2aec4f12ae47f3ce5b56b1fb55996 (patch)
tree05c7a64bdbbcc947b529a988faa39593a2be6477 /src
parenta0fbb05bf0353ac0fede6deec15db5d2d3a9017f (diff)
downloadluajit-52b7651327b2aec4f12ae47f3ce5b56b1fb55996.tar.gz
luajit-52b7651327b2aec4f12ae47f3ce5b56b1fb55996.tar.bz2
luajit-52b7651327b2aec4f12ae47f3ce5b56b1fb55996.zip
Place dynamically generated code near static code on x64.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.dep2
-rw-r--r--src/lj_mcode.c68
-rw-r--r--src/lj_state.c1
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
81lj_mcode.o: lj_mcode.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h \ 81lj_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
84lj_meta.o: lj_meta.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h lj_gc.h \ 84lj_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
86lj_obj.o: lj_obj.c lj_obj.h lua.h luaconf.h lj_def.h lj_arch.h 86lj_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
30static LJ_AINLINE void *mcode_alloc(jit_State *J, size_t sz, DWORD prot) 31static 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
38static LJ_AINLINE void mcode_free(jit_State *J, void *p, size_t sz) 40static 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
44static LJ_AINLINE void mcode_setprot(void *p, size_t sz, DWORD prot) 46static 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
62static LJ_AINLINE void *mcode_alloc(jit_State *J, size_t sz, int prot) 64static 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
70static LJ_AINLINE void mcode_free(jit_State *J, void *p, size_t sz) 72static 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
76static LJ_AINLINE void mcode_setprot(void *p, size_t sz, int prot) 78static 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
89static LJ_AINLINE void *mcode_alloc(jit_State *J, size_t sz, int prot) 91static 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
95static LJ_AINLINE void mcode_free(jit_State *J, void *p, size_t sz) 97static 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. */
111static 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