Always allocate linear memory using mmap (#3052)
With this approach we can omit using memset() for the newly allocated memory therefore the physical pages are not being used unless touched by the program. This also simplifies the implementation.
This commit is contained in:
12
core/shared/platform/common/memory/mremap.c
Normal file
12
core/shared/platform/common/memory/mremap.c
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bh_memutils.h"
|
||||
|
||||
void *
|
||||
os_mremap(void *old_addr, size_t old_size, size_t new_size)
|
||||
{
|
||||
return bh_memory_remap_slow(old_addr, old_size, new_size);
|
||||
}
|
||||
@ -0,0 +1,4 @@
|
||||
# Copyright (C) 2024 Amazon Inc. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
file (GLOB_RECURSE PLATFORM_COMMON_MEMORY_SOURCE ${CMAKE_CURRENT_LIST_DIR}/*.c)
|
||||
@ -16,4 +16,19 @@ else()
|
||||
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||
endif()
|
||||
|
||||
# This is to support old CMake version. Newer version of CMake could use
|
||||
# list APPEND/POP_BACK methods.
|
||||
include(CheckSymbolExists)
|
||||
set (CMAKE_REQUIRED_DEFINITIONS -D_GNU_SOURCE ${CMAKE_REQUIRED_DEFINITIONS})
|
||||
check_symbol_exists (mremap "sys/mman.h" MREMAP_EXISTS)
|
||||
list (REMOVE_AT CMAKE_REQUIRED_DEFINITIONS 0)
|
||||
|
||||
if(MREMAP_EXISTS)
|
||||
add_definitions (-DWASM_HAVE_MREMAP=1)
|
||||
else()
|
||||
add_definitions (-DWASM_HAVE_MREMAP=0)
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/../memory/platform_api_memory.cmake)
|
||||
set (source_all ${source_all} ${PLATFORM_COMMON_MEMORY_SOURCE})
|
||||
endif()
|
||||
|
||||
set (PLATFORM_COMMON_POSIX_SOURCE ${source_all} )
|
||||
|
||||
@ -3,6 +3,12 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#if !defined(_GNU_SOURCE) && WASM_HAVE_MREMAP != 0
|
||||
/* Enable mremap */
|
||||
#define _GNU_SOURCE
|
||||
#include "bh_memutils.h"
|
||||
#endif
|
||||
|
||||
#include "platform_api_vmcore.h"
|
||||
|
||||
#if defined(__APPLE__) || defined(__MACH__)
|
||||
@ -236,6 +242,23 @@ os_munmap(void *addr, size_t size)
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_HAVE_MREMAP != 0
|
||||
void *
|
||||
os_mremap(void *old_addr, size_t old_size, size_t new_size)
|
||||
{
|
||||
void *ptr = mremap(old_addr, old_size, new_size, MREMAP_MAYMOVE);
|
||||
|
||||
if (ptr == MAP_FAILED) {
|
||||
#if BH_ENABLE_TRACE_MMAP != 0
|
||||
os_printf("mremap failed: %d\n", errno);
|
||||
#endif
|
||||
return bh_memory_remap_slow(old_addr, old_size, new_size);
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
os_mprotect(void *addr, size_t size, int prot)
|
||||
{
|
||||
|
||||
@ -12,6 +12,9 @@ include (${CMAKE_CURRENT_LIST_DIR}/../common/posix/platform_api_posix.cmake)
|
||||
|
||||
file (GLOB_RECURSE source_all ${PLATFORM_SHARED_DIR}/*.c)
|
||||
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
|
||||
set (source_all ${source_all} ${PLATFORM_COMMON_MEMORY_SOURCE})
|
||||
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_POSIX_SOURCE})
|
||||
|
||||
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
|
||||
|
||||
@ -132,7 +132,7 @@ enum {
|
||||
MMAP_MAP_32BIT = 1,
|
||||
/* Don't interpret addr as a hint: place the mapping at exactly
|
||||
that address. */
|
||||
MMAP_MAP_FIXED = 2
|
||||
MMAP_MAP_FIXED = 2,
|
||||
};
|
||||
|
||||
void *
|
||||
@ -142,6 +142,11 @@ os_munmap(void *addr, size_t size);
|
||||
int
|
||||
os_mprotect(void *addr, size_t size, int prot);
|
||||
|
||||
/* Doesn't guarantee that protection flags will be preserved.
|
||||
os_mprotect() must be called after remapping. */
|
||||
void *
|
||||
os_mremap(void *old_addr, size_t old_size, size_t new_size);
|
||||
|
||||
#if (WASM_MEM_DUAL_BUS_MIRROR != 0)
|
||||
void *
|
||||
os_get_dbus_mirror(void *ibus);
|
||||
|
||||
@ -79,6 +79,8 @@ os_get_invalid_handle()
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define os_getpagesize getpagesize
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -37,6 +37,9 @@ else()
|
||||
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||
endif()
|
||||
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
|
||||
set (source_all ${source_all} ${PLATFORM_COMMON_MEMORY_SOURCE})
|
||||
|
||||
file (GLOB source_all_untrusted ${PLATFORM_SHARED_DIR}/untrusted/*.c)
|
||||
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all})
|
||||
|
||||
@ -44,6 +44,8 @@ typedef pthread_t korp_thread;
|
||||
typedef pthread_rwlock_t korp_rwlock;
|
||||
typedef sem_t korp_sem;
|
||||
|
||||
#define os_getpagesize getpagesize
|
||||
|
||||
#define OS_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
|
||||
|
||||
#define BH_APPLET_PRESERVED_STACK_SIZE (2 * BH_KB)
|
||||
|
||||
@ -16,5 +16,6 @@ if (WAMR_BUILD_LIBC_WASI EQUAL 1)
|
||||
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||
endif ()
|
||||
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE})
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all} ${PLATFORM_COMMON_MATH_SOURCE} ${PLATFORM_COMMON_MEMORY_SOURCE})
|
||||
|
||||
|
||||
@ -20,6 +20,9 @@ else()
|
||||
set(source_all ${source_all} ${PLATFORM_COMMON_LIBC_UTIL_SOURCE})
|
||||
endif()
|
||||
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/../common/memory/platform_api_memory.cmake)
|
||||
set (source_all ${source_all} ${PLATFORM_COMMON_MEMORY_SOURCE})
|
||||
|
||||
set (PLATFORM_SHARED_SOURCE ${source_all})
|
||||
|
||||
file (GLOB header ${PLATFORM_SHARED_DIR}/../include/*.h)
|
||||
|
||||
24
core/shared/utils/bh_memutils.c
Normal file
24
core/shared/utils/bh_memutils.c
Normal file
@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bh_memutils.h"
|
||||
|
||||
void *
|
||||
bh_memory_remap_slow(void *old_addr, size_t old_size, size_t new_size)
|
||||
{
|
||||
void *new_memory =
|
||||
os_mmap(NULL, new_size, MMAP_PROT_WRITE | MMAP_PROT_READ, 0, -1);
|
||||
if (!new_memory) {
|
||||
return NULL;
|
||||
}
|
||||
/*
|
||||
* bh_memcpy_s can't be used as it doesn't support values bigger than
|
||||
* UINT32_MAX
|
||||
*/
|
||||
memcpy(new_memory, old_addr, new_size < old_size ? new_size : old_size);
|
||||
os_munmap(old_addr, old_size);
|
||||
|
||||
return new_memory;
|
||||
}
|
||||
35
core/shared/utils/bh_memutils.h
Normal file
35
core/shared/utils/bh_memutils.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2024 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _BH_MEMUTILS_H
|
||||
#define _BH_MEMUTILS_H
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Remaps memory by mapping a new region, copying data from the old
|
||||
* region and umapping the old region.
|
||||
*
|
||||
* Unless the behavior is desired, in most cases os_mremap should be used
|
||||
* as it's at worst equally slow as this function, and on some platforms
|
||||
* (e.g. posix with mremap) os_mremap will perform better.
|
||||
*
|
||||
* @param old_addr an old address.
|
||||
* @param old_size a size of the old address.
|
||||
* @param new_size a size of the new memory region.
|
||||
* @return a pointer to the new memory region.
|
||||
*/
|
||||
void *
|
||||
bh_memory_remap_slow(void *old_addr, size_t old_size, size_t new_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _BH_MEMUTILS_H */
|
||||
Reference in New Issue
Block a user