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 /src | |
parent | a0fbb05bf0353ac0fede6deec15db5d2d3a9017f (diff) | |
download | luajit-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.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 |