|
24 | 24 | #include <mono/utils/atomic.h> |
25 | 25 | #include <mono/utils/options.h> |
26 | 26 |
|
27 | | -#include "mono-wasm-pagemgr.h" |
28 | | - |
29 | 27 | #define BEGIN_CRITICAL_SECTION do { \ |
30 | 28 | MonoThreadInfo *__info = mono_thread_info_current_unchecked (); \ |
31 | 29 | if (__info) __info->inside_critical_region = TRUE; \ |
|
37 | 35 | int |
38 | 36 | mono_pagesize (void) |
39 | 37 | { |
40 | | - if (mono_opt_wasm_mmap) |
41 | | - return MWPM_PAGE_SIZE; |
42 | | - |
43 | | - static int saved_pagesize = 0; |
44 | | - |
45 | | - if (saved_pagesize) |
46 | | - return saved_pagesize; |
47 | | - |
48 | | - // Prefer sysconf () as it's signal safe. |
49 | | -#if defined (HAVE_SYSCONF) && defined (_SC_PAGESIZE) |
50 | | - saved_pagesize = sysconf (_SC_PAGESIZE); |
51 | | -#else |
52 | | - saved_pagesize = getpagesize (); |
53 | | -#endif |
54 | | - |
55 | | - return saved_pagesize; |
| 38 | + return 16384; |
56 | 39 | } |
57 | 40 |
|
58 | 41 | int |
@@ -96,122 +79,50 @@ mono_setmmapjit (int flag) |
96 | 79 | /* Ignored on HOST_WASM */ |
97 | 80 | } |
98 | 81 |
|
99 | | -static void* |
100 | | -valloc_impl (void *addr, size_t size, int flags, MonoMemAccountType type) |
101 | | -{ |
102 | | - void *ptr; |
103 | | - int mflags = 0; |
104 | | - int prot = prot_from_flags (flags); |
105 | | - |
106 | | - if (!mono_valloc_can_alloc (size)) |
107 | | - return NULL; |
108 | | - |
109 | | - if (size == 0) |
110 | | - /* emscripten throws an exception on 0 length */ |
111 | | - return NULL; |
112 | | - |
113 | | - mflags |= MAP_ANONYMOUS; |
114 | | - mflags |= MAP_PRIVATE; |
115 | | - |
116 | | - BEGIN_CRITICAL_SECTION; |
117 | | - if (mono_opt_wasm_mmap) { |
118 | | - // FIXME: Make this work if the requested address range is free |
119 | | - if ((flags & MONO_MMAP_FIXED) && addr) |
120 | | - return NULL; |
121 | | - |
122 | | - ptr = mwpm_alloc_range (size, (flags & MONO_MMAP_NOZERO) == 0); |
123 | | - if (!ptr) |
124 | | - return NULL; |
125 | | - } else |
126 | | - ptr = mmap (addr, size, prot, mflags, -1, 0); |
127 | | - END_CRITICAL_SECTION; |
128 | | - |
129 | | - if (ptr == MAP_FAILED) |
130 | | - return NULL; |
131 | | - |
132 | | - mono_account_mem (type, (ssize_t)size); |
133 | | - |
134 | | - return ptr; |
135 | | -} |
136 | 82 |
|
137 | 83 | void* |
138 | | -mono_valloc (void *addr, size_t size, int flags, MonoMemAccountType type) |
| 84 | +mono_valloc (void *addr, size_t length, int flags, MonoMemAccountType type) |
139 | 85 | { |
140 | | -#if HOST_WASI |
141 | | - // WASI implements mmap using malloc, so the returned address is not page aligned |
142 | | - // and our code depends on it |
143 | | - g_assert (!addr); |
144 | | - return mono_valloc_aligned (size, mono_pagesize (), flags, type); |
145 | | -#else |
146 | | - return valloc_impl (addr, size, flags, type); |
147 | | -#endif |
| 86 | + g_assert (addr == NULL); |
| 87 | + return mono_valloc_aligned (length, mono_pagesize (), flags, type); |
148 | 88 | } |
149 | 89 |
|
150 | | -static GHashTable *valloc_hash; |
151 | | - |
152 | | -typedef struct { |
153 | | - void *addr; |
154 | | - int size; |
155 | | -} VallocInfo; |
156 | | - |
157 | 90 | void* |
158 | 91 | mono_valloc_aligned (size_t size, size_t alignment, int flags, MonoMemAccountType type) |
159 | 92 | { |
160 | | - // We don't need padding if the alignment is compatible with the page size |
161 | | - if (mono_opt_wasm_mmap && ((MWPM_PAGE_SIZE % alignment) == 0)) |
162 | | - return valloc_impl (NULL, size, flags, type); |
163 | | - |
164 | | - /* Allocate twice the memory to be able to put the block on an aligned address */ |
165 | | - char *mem = (char *) valloc_impl (NULL, size + alignment, flags, type); |
166 | | - char *aligned; |
| 93 | +#ifdef DISABLE_THREADS |
| 94 | + void *old_sbrk = NULL; |
| 95 | + if ((flags & MONO_MMAP_NOZERO) == 0) { |
| 96 | + old_sbrk = sbrk (0); |
| 97 | + } |
| 98 | +#endif |
167 | 99 |
|
168 | | - if (!mem) |
| 100 | + void *res = NULL; |
| 101 | + if (posix_memalign (&res, alignment, size)) |
169 | 102 | return NULL; |
170 | 103 |
|
171 | | - aligned = mono_aligned_address (mem, size, alignment); |
| 104 | +#ifdef DISABLE_THREADS |
| 105 | + if ((flags & MONO_MMAP_NOZERO) == 0 && old_sbrk > res) { |
| 106 | + // this means that we got an old block, not the new block from sbrk |
| 107 | + memset (res, 0, size); |
| 108 | + } |
| 109 | +#else |
| 110 | + if ((flags & MONO_MMAP_NOZERO) == 0) { |
| 111 | + memset (res, 0, size); |
| 112 | + } |
| 113 | +#endif |
172 | 114 |
|
173 | | - /* The mmap implementation in emscripten cannot unmap parts of regions */ |
174 | | - /* Free the other two parts in when 'aligned' is freed */ |
175 | | - // FIXME: This doubles the memory usage |
176 | | - if (!valloc_hash) |
177 | | - valloc_hash = g_hash_table_new (NULL, NULL); |
178 | | - VallocInfo *info = g_new0 (VallocInfo, 1); |
179 | | - info->addr = mem; |
180 | | - info->size = size + alignment; |
181 | | - g_hash_table_insert (valloc_hash, aligned, info); |
| 115 | + mono_account_mem (type, (ssize_t)size); |
182 | 116 |
|
183 | | - return aligned; |
| 117 | + return res; |
184 | 118 | } |
185 | 119 |
|
186 | 120 | int |
187 | 121 | mono_vfree (void *addr, size_t length, MonoMemAccountType type) |
188 | 122 | { |
189 | | - VallocInfo *info = (VallocInfo*)(valloc_hash ? g_hash_table_lookup (valloc_hash, addr) : NULL); |
190 | | - |
191 | | - if (info) { |
192 | | - /* |
193 | | - * We are passed the aligned address in the middle of the mapping allocated by |
194 | | - * mono_valloc_align (), free the original mapping. |
195 | | - */ |
196 | | - BEGIN_CRITICAL_SECTION; |
197 | | - if (mono_opt_wasm_mmap) |
198 | | - mwpm_free_range (info->addr, info->size); |
199 | | - else |
200 | | - munmap (info->addr, info->size); |
201 | | - END_CRITICAL_SECTION; |
202 | | - g_free (info); |
203 | | - g_hash_table_remove (valloc_hash, addr); |
204 | | - } else { |
205 | | - // FIXME: We could be trying to unmap part of an aligned mapping, in which case the |
206 | | - // hash lookup failed because addr isn't exactly the start of the mapping. |
207 | | - // Ideally if the custom page manager is enabled, we won't have done aligned alloc. |
208 | | - BEGIN_CRITICAL_SECTION; |
209 | | - if (mono_opt_wasm_mmap) |
210 | | - mwpm_free_range (addr, length); |
211 | | - else |
212 | | - munmap (addr, length); |
213 | | - END_CRITICAL_SECTION; |
214 | | - } |
| 123 | + // NOTE: this doesn't implement partial freeing like munmap does |
| 124 | + // we set MS_BLOCK_ALLOC_NUM to 1 to avoid partial freeing |
| 125 | + g_free (addr); |
215 | 126 |
|
216 | 127 | mono_account_mem (type, -(ssize_t)length); |
217 | 128 |
|
@@ -267,6 +178,9 @@ mono_file_unmap (void *addr, void *handle) |
267 | 178 | int |
268 | 179 | mono_mprotect (void *addr, size_t length, int flags) |
269 | 180 | { |
| 181 | + if (flags & MONO_MMAP_DISCARD) { |
| 182 | + memset (addr, 0, length); |
| 183 | + } |
270 | 184 | return 0; |
271 | 185 | } |
272 | 186 |
|
|
0 commit comments