Skip to content

Commit 779fbac

Browse files
committed
wip
1 parent 4f66989 commit 779fbac

File tree

9 files changed

+144
-644
lines changed

9 files changed

+144
-644
lines changed

src/mono/browser/browser.proj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@
209209
<EmccExportedFunction Include="_malloc" />
210210
<EmccExportedFunction Include="_sbrk" />
211211
<EmccExportedFunction Include="_memalign" />
212+
<EmccExportedFunction Include="_posix_memalign" />
212213
<EmccExportedFunction Include="_memset" />
213214
<EmccExportedFunction Include="_ntohs" />
214215
<EmccExportedFunction Include="stackAlloc" />

src/mono/mono/sgen/sgen-marksweep.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,13 @@ static int ms_block_size;
4949
* Don't allocate single blocks, but alloc a contingent of this many
5050
* blocks in one swoop. This must be a power of two.
5151
*/
52+
#ifndef TARGET_WASM
5253
#define MS_BLOCK_ALLOC_NUM 32
54+
#else
55+
// WASM doesn't support partial munmap, so we can't free individual blocks
56+
// we use posix_memalign and free the whole block at once
57+
#define MS_BLOCK_ALLOC_NUM 1
58+
#endif
5359

5460
#define MS_NUM_MARK_WORDS ((ms_block_size / SGEN_ALLOC_ALIGN + sizeof (guint32) * 8 - 1) / (sizeof (guint32) * 8))
5561

@@ -2140,9 +2146,6 @@ major_free_swept_blocks (size_t section_reserve)
21402146
* a VirtualAlloc ()-ed block.
21412147
*/
21422148
return;
2143-
#elif defined(HOST_WASM)
2144-
if (!mono_opt_wasm_mmap)
2145-
return;
21462149
#endif
21472150

21482151
{

src/mono/mono/utils/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ set(utils_arch_sources "${utils_arch_sources};mono-hwcap-riscv.c")
206206
elseif(TARGET_S390X)
207207
set(utils_arch_sources "${utils_arch_sources};mono-hwcap-s390x.c")
208208
elseif(TARGET_WASM)
209-
set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c;mono-mmap-wasm.c;mono-wasm-pagemgr.c")
209+
set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c;mono-mmap-wasm.c")
210210
elseif(TARGET_WASI)
211211
set(utils_arch_sources "${utils_arch_sources};mono-hwcap-wasm.c")
212212
elseif(TARGET_POWERPC OR TARGET_POWERPC64)

src/mono/mono/utils/lock-free-alloc.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,7 @@ typedef struct {
4545
MonoMemAccountType account_type;
4646
} MonoLockFreeAllocator;
4747

48-
#ifdef HOST_WASM
49-
#define LOCK_FREE_ALLOC_SB_MAX_SIZE (mono_opt_wasm_mmap ? 65536 : 16384)
50-
#else
5148
#define LOCK_FREE_ALLOC_SB_MAX_SIZE 16384
52-
#endif
5349
#define LOCK_FREE_ALLOC_SB_HEADER_SIZE (sizeof (gpointer))
5450
#define LOCK_FREE_ALLOC_SB_USABLE_SIZE(block_size) ((block_size) - LOCK_FREE_ALLOC_SB_HEADER_SIZE)
5551

src/mono/mono/utils/mono-mmap-wasm.c

Lines changed: 29 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
#include <mono/utils/atomic.h>
2525
#include <mono/utils/options.h>
2626

27-
#include "mono-wasm-pagemgr.h"
28-
2927
#define BEGIN_CRITICAL_SECTION do { \
3028
MonoThreadInfo *__info = mono_thread_info_current_unchecked (); \
3129
if (__info) __info->inside_critical_region = TRUE; \
@@ -37,22 +35,7 @@
3735
int
3836
mono_pagesize (void)
3937
{
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;
5639
}
5740

5841
int
@@ -96,125 +79,48 @@ mono_setmmapjit (int flag)
9679
/* Ignored on HOST_WASM */
9780
}
9881

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-
}
13682

13783
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)
13985
{
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);
14888
}
14989

150-
static GHashTable *valloc_hash;
151-
152-
typedef struct {
153-
void *addr;
154-
int size;
155-
} VallocInfo;
156-
15790
void*
15891
mono_valloc_aligned (size_t size, size_t alignment, int flags, MonoMemAccountType type)
15992
{
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) {
96+
old_sbrk = sbrk (0);
97+
}
98+
#endif
16799

168-
if (!mem)
100+
void *res = NULL;
101+
if (posix_memalign (&res, alignment, size))
169102
return NULL;
170103

171-
aligned = mono_aligned_address (mem, size, alignment);
172-
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);
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
182114

183-
return aligned;
115+
return res;
184116
}
185117

186118
int
187119
mono_vfree (void *addr, size_t length, MonoMemAccountType type)
188120
{
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-
}
215-
216-
mono_account_mem (type, -(ssize_t)length);
217-
121+
// NOTE: this doesn't implement partial freeing like munmap does
122+
// we set MS_BLOCK_ALLOC_NUM to 1 to avoid partial freeing
123+
g_free (addr);
218124
return 0;
219125
}
220126

@@ -267,6 +173,9 @@ mono_file_unmap (void *addr, void *handle)
267173
int
268174
mono_mprotect (void *addr, size_t length, int flags)
269175
{
176+
if (flags & MONO_MMAP_DISCARD) {
177+
memset (addr, 0, length);
178+
}
270179
return 0;
271180
}
272181

0 commit comments

Comments
 (0)