diff --git a/src/mono/mono/utils/mono-mmap-wasm.c b/src/mono/mono/utils/mono-mmap-wasm.c index e19645b90e82f2..b2f417b0860385 100644 --- a/src/mono/mono/utils/mono-mmap-wasm.c +++ b/src/mono/mono/utils/mono-mmap-wasm.c @@ -90,12 +90,12 @@ mono_setmmapjit (int flag) /* Ignored on HOST_WASM */ } -void *sbrk (intptr_t increment); - static void* valloc_impl (void *addr, size_t size, int flags, MonoMemAccountType type) { void *ptr; + int mflags = 0; + int prot = prot_from_flags (flags); if (!mono_valloc_can_alloc (size)) return NULL; @@ -104,8 +104,14 @@ valloc_impl (void *addr, size_t size, int flags, MonoMemAccountType type) /* emscripten throws an exception on 0 length */ return NULL; - ptr = sbrk (size); - if (ptr == 0) + mflags |= MAP_ANONYMOUS; + mflags |= MAP_PRIVATE; + + BEGIN_CRITICAL_SECTION; + ptr = mmap (addr, size, prot, mflags, -1, 0); + END_CRITICAL_SECTION; + + if (ptr == MAP_FAILED) return NULL; mono_account_mem (type, (ssize_t)size); @@ -161,7 +167,26 @@ mono_valloc_aligned (size_t size, size_t alignment, int flags, MonoMemAccountTyp int mono_vfree (void *addr, size_t length, MonoMemAccountType type) { - g_warning ("mono_vfree not implemented on webassembly; silently failing to free\n"); + VallocInfo *info = (VallocInfo*)(valloc_hash ? g_hash_table_lookup (valloc_hash, addr) : NULL); + + if (info) { + /* + * We are passed the aligned address in the middle of the mapping allocated by + * mono_valloc_align (), free the original mapping. + */ + BEGIN_CRITICAL_SECTION; + munmap (info->addr, info->size); + END_CRITICAL_SECTION; + g_free (info); + g_hash_table_remove (valloc_hash, addr); + } else { + BEGIN_CRITICAL_SECTION; + munmap (addr, length); + END_CRITICAL_SECTION; + } + + mono_account_mem (type, -(ssize_t)length); + return 0; }