Allow overriding max memory on module instantiation (#3198)

This PR adds a max_memory_pages parameter to module instantiation APIs,
to allow overriding the max memory defined in the WASM module.

Sticking to the max memory defined in the module is quite limiting when
using shared memory in production. If targeted devices have different
memory constraints, many wasm files have to be generated with different
max memory values. And device constraints may not be known in advance.

Being able to set the max memory value during module instantiation allows
to reuse the same wasm module, e.g. by retrying instantiation with different
max memory value.
This commit is contained in:
Enrico Loparco
2024-03-05 10:53:26 +01:00
committed by GitHub
parent 0e8d949440
commit 7692f32a94
15 changed files with 284 additions and 163 deletions

View File

@ -4872,6 +4872,19 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
const wasm_extern_vec_t *imports,
own wasm_trap_t **trap, const uint32 stack_size,
const uint32 heap_size)
{
InstantiationArgs inst_args = { 0 };
inst_args.default_stack_size = stack_size;
inst_args.host_managed_heap_size = heap_size;
return wasm_instance_new_with_args_ex(store, module, imports, trap,
&inst_args);
}
wasm_instance_t *
wasm_instance_new_with_args_ex(wasm_store_t *store, const wasm_module_t *module,
const wasm_extern_vec_t *imports,
own wasm_trap_t **trap,
const InstantiationArgs *inst_args)
{
char sub_error_buf[128] = { 0 };
char error_buf[256] = { 0 };
@ -4911,8 +4924,8 @@ wasm_instance_new_with_args(wasm_store_t *store, const wasm_module_t *module,
* will do the linking result check at the end of wasm_runtime_instantiate
*/
instance->inst_comm_rt = wasm_runtime_instantiate(
*module, stack_size, heap_size, sub_error_buf, sizeof(sub_error_buf));
instance->inst_comm_rt = wasm_runtime_instantiate_ex(
*module, inst_args, sub_error_buf, sizeof(sub_error_buf));
if (!instance->inst_comm_rt) {
goto failed;
}

View File

@ -1357,24 +1357,48 @@ wasm_runtime_unload(WASMModuleCommon *module)
#endif
}
uint32
wasm_runtime_get_max_mem(uint32 max_memory_pages, uint32 module_init_page_count,
uint32 module_max_page_count)
{
if (max_memory_pages == 0) {
/* Max memory not overwritten by runtime, use value from wasm module */
return module_max_page_count;
}
if (max_memory_pages < module_init_page_count) {
LOG_WARNING("Cannot override max memory with value lower than module "
"initial memory");
return module_init_page_count;
}
if (max_memory_pages > module_max_page_count) {
LOG_WARNING("Cannot override max memory with value greater than module "
"max memory");
return module_max_page_count;
}
return max_memory_pages;
}
WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal(WASMModuleCommon *module,
WASMModuleInstanceCommon *parent,
WASMExecEnv *exec_env_main, uint32 stack_size,
uint32 heap_size, char *error_buf,
uint32 error_buf_size)
uint32 heap_size, uint32 max_memory_pages,
char *error_buf, uint32 error_buf_size)
{
#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode)
return (WASMModuleInstanceCommon *)wasm_instantiate(
(WASMModule *)module, (WASMModuleInstance *)parent, exec_env_main,
stack_size, heap_size, error_buf, error_buf_size);
stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT)
return (WASMModuleInstanceCommon *)aot_instantiate(
(AOTModule *)module, (AOTModuleInstance *)parent, exec_env_main,
stack_size, heap_size, error_buf, error_buf_size);
stack_size, heap_size, max_memory_pages, error_buf, error_buf_size);
#endif
set_error_buf(error_buf, error_buf_size,
"Instantiate module failed, invalid module type");
@ -1385,9 +1409,21 @@ WASMModuleInstanceCommon *
wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
uint32 heap_size, char *error_buf,
uint32 error_buf_size)
{
return wasm_runtime_instantiate_internal(module, NULL, NULL, stack_size,
heap_size, 0, error_buf,
error_buf_size);
}
WASMModuleInstanceCommon *
wasm_runtime_instantiate_ex(WASMModuleCommon *module,
const InstantiationArgs *args, char *error_buf,
uint32 error_buf_size)
{
return wasm_runtime_instantiate_internal(
module, NULL, NULL, stack_size, heap_size, error_buf, error_buf_size);
module, NULL, NULL, args->default_stack_size,
args->host_managed_heap_size, args->max_memory_pages, error_buf,
error_buf_size);
}
void
@ -6403,7 +6439,8 @@ bool
wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
WASMModuleInstanceCommon *module_inst,
uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size)
uint32 max_memory_pages, char *error_buf,
uint32 error_buf_size)
{
bh_list *sub_module_inst_list = NULL;
WASMRegisteredModule *sub_module_list_node = NULL;
@ -6431,8 +6468,8 @@ wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
WASMModuleCommon *sub_module = sub_module_list_node->module;
WASMModuleInstanceCommon *sub_module_inst = NULL;
sub_module_inst = wasm_runtime_instantiate_internal(
sub_module, NULL, NULL, stack_size, heap_size, error_buf,
error_buf_size);
sub_module, NULL, NULL, stack_size, heap_size, max_memory_pages,
error_buf, error_buf_size);
if (!sub_module_inst) {
LOG_DEBUG("instantiate %s failed",
sub_module_list_node->module_name);

View File

@ -561,13 +561,18 @@ wasm_runtime_load_from_sections(WASMSection *section_list, bool is_aot,
WASM_RUNTIME_API_EXTERN void
wasm_runtime_unload(WASMModuleCommon *module);
/* Internal API */
uint32
wasm_runtime_get_max_mem(uint32 max_memory_pages, uint32 module_init_page_count,
uint32 module_max_page_count);
/* Internal API */
WASMModuleInstanceCommon *
wasm_runtime_instantiate_internal(WASMModuleCommon *module,
WASMModuleInstanceCommon *parent,
WASMExecEnv *exec_env_main, uint32 stack_size,
uint32 heap_size, char *error_buf,
uint32 error_buf_size);
uint32 heap_size, uint32 max_memory_pages,
char *error_buf, uint32 error_buf_size);
/* Internal API */
void
@ -580,6 +585,12 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 default_stack_size,
uint32 host_managed_heap_size, char *error_buf,
uint32 error_buf_size);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN WASMModuleInstanceCommon *
wasm_runtime_instantiate_ex(WASMModuleCommon *module,
const InstantiationArgs *args, char *error_buf,
uint32 error_buf_size);
/* See wasm_export.h for description */
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_set_running_mode(wasm_module_inst_t module_inst,
@ -887,7 +898,8 @@ bool
wasm_runtime_sub_module_instantiate(WASMModuleCommon *module,
WASMModuleInstanceCommon *module_inst,
uint32 stack_size, uint32 heap_size,
char *error_buf, uint32 error_buf_size);
uint32 max_memory_pages, char *error_buf,
uint32 error_buf_size);
void
wasm_runtime_sub_module_deinstantiate(WASMModuleInstanceCommon *module_inst);
#endif