Skip to content

Commit

Permalink
fix: put additional checks in wasm_runtime_is_underlying_binary_freeable
Browse files Browse the repository at this point in the history
  • Loading branch information
eloparco committed May 15, 2024
1 parent af265e0 commit a8c3605
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 23 deletions.
9 changes: 6 additions & 3 deletions core/iwasm/common/wasm_c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -2999,10 +2999,13 @@ wasm_module_get_name(wasm_module_t *module)
}

bool
wasm_module_is_underlying_binary_freeable(const wasm_module_t *module)
wasm_module_is_underlying_binary_freeable(
const wasm_module_t *module, const struct wasm_instance_t *instance)
{
return ((wasm_module_ex_t *)module)->is_binary_cloned
&& wasm_runtime_is_underlying_binary_freeable(*module);
if (((wasm_module_ex_t *)module)->is_binary_cloned)
return true;

return wasm_runtime_is_underlying_binary_freeable(instance->inst_comm_rt);
}

static wasm_func_t *
Expand Down
34 changes: 27 additions & 7 deletions core/iwasm/common/wasm_runtime_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -7180,27 +7180,47 @@ wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
}

WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_underlying_binary_freeable(const wasm_module_t module)
wasm_runtime_is_underlying_binary_freeable(const wasm_module_inst_t module_inst)
{
uint32 i;
bool is_freeable = false;

#if WASM_ENABLE_INTERP != 0
if (module->module_type == Wasm_Module_Bytecode) {
if (module_inst->module_type == Wasm_Module_Bytecode) {
#if (WASM_ENABLE_JIT != 0 || WASM_ENABLE_FAST_JIT != 0) \
&& (WASM_ENABLE_LAZY_JIT != 0)
is_freeable = false;
#elif WASM_ENABLE_FAST_INTERP == 0
is_freeable = false;
#else
is_freeable = ((WASMModule *)module)->is_binary_freeable;
/* Fast interpreter mode */
WASMModule *module = ((WASMModuleInstance *)module_inst)->module;
is_freeable = module->is_binary_freeable;
#if WASM_ENABLE_GC != 0 && WASM_ENABLE_STRINGREF != 0
is_freeable = is_freeable && module->string_literal_ptrs == NULL;
#endif
#if WASM_ENABLE_BULK_MEMORY != 0
for (i = 0; i < module->data_seg_count; i++)
is_freeable =
is_freeable
&& bh_bitmap_get_bit(
((WASMModuleInstance *)module_inst)->e->common.data_dropped,
i);
#endif
}
#endif
#if WASM_ENABLE_AOT != 0
if (module->module_type == Wasm_Module_AoT) {
is_freeable = ((AOTModule *)module)->is_binary_freeable;
}
#endif /* WASM_ENABLE_INTERP != 0 */
#if WASM_ENABLE_AOT != 0
if (module_inst->module_type == Wasm_Module_AoT) {
AOTModule *module =
(AOTModule *)((AOTModuleInstance *)module_inst)->module;
is_freeable = module->is_binary_freeable;
#if WASM_ENABLE_GC != 0 && WASM_ENABLE_STRINGREF != 0
is_freeable = is_freeable && module->string_literal_ptrs == NULL;
#endif
}
#endif /* WASM_ENABLE_AOT != 0 */

(void)i;
return is_freeable;
}
3 changes: 2 additions & 1 deletion core/iwasm/common/wasm_runtime_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -1197,7 +1197,8 @@ wasm_runtime_detect_native_stack_overflow_size(WASMExecEnv *exec_env,
uint32 requested_size);

WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_underlying_binary_freeable(const wasm_module_t module);
wasm_runtime_is_underlying_binary_freeable(
const wasm_module_inst_t module_inst);

#if WASM_ENABLE_LINUX_PERF != 0
bool
Expand Down
2 changes: 1 addition & 1 deletion core/iwasm/include/wasm_c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ WASM_API_EXTERN void wasm_shared_module_delete(own wasm_shared_module_t*);
WASM_API_EXTERN bool wasm_module_set_name(wasm_module_t*, const char* name);
WASM_API_EXTERN const char *wasm_module_get_name(wasm_module_t*);

WASM_API_EXTERN bool wasm_module_is_underlying_binary_freeable(const wasm_module_t* module);
WASM_API_EXTERN bool wasm_module_is_underlying_binary_freeable(const wasm_module_t *module, const struct wasm_instance_t* instance);


// Function Instances
Expand Down
5 changes: 3 additions & 2 deletions core/iwasm/include/wasm_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -1870,11 +1870,12 @@ wasm_runtime_detect_native_stack_overflow_size(wasm_exec_env_t exec_env,
/**
* Query whether the wasm binary buffer used to create the module can be freed
*
* @param module the target module
* @param module_inst the target module instance
* @return true if the wasm binary buffer can be freed
*/
WASM_RUNTIME_API_EXTERN bool
wasm_runtime_is_underlying_binary_freeable(const wasm_module_t module);
wasm_runtime_is_underlying_binary_freeable(
const wasm_module_inst_t module_inst);

#ifdef __cplusplus
}
Expand Down
4 changes: 2 additions & 2 deletions doc/memory_tune.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ Normally there are some methods to tune the memory usage:
- set the app heap size with `wasm_runtime_instantiate`
- use `nostdlib` mode, add `-Wl,--strip-all`: refer to [How to reduce the footprint](./build_wasm_app.md#2-how-to-reduce-the-footprint) of building wasm app for more details
- use XIP mode, refer to [WAMR XIP (Execution In Place) feature introduction](./xip.md) for more details
- when using the Wasm C API in fast interpreter or AOT mode, set `clone_wasm_binary=false` in `LoadArgs` and free the wasm binary buffer (with `wasm_byte_vec_delete`) after module loading; `wasm_module_is_underlying_binary_freeable` can be queried to check if the wasm binary buffer can be safely freed (see [the example](../samples/basic/src/free_buffer_early.c))
- when using the wasm/AOT loader in fast interpreter or AOT mode, set `wasm_binary_freeable=true` in `LoadArgs` and free the wasm binary buffer (with `wasm_byte_vec_delete`) after module loading; `wasm_runtime_is_underlying_binary_freeable` can be queried to check if the wasm binary buffer can be safely freed
- when using the Wasm C API in fast interpreter or AOT mode, set `clone_wasm_binary=false` in `LoadArgs` and free the wasm binary buffer (with `wasm_byte_vec_delete`) after module loading; `wasm_module_is_underlying_binary_freeable` can be queried to check if the wasm binary buffer can be safely freed (see [the example](../samples/basic/src/free_buffer_early.c)); after the buffer is freed, `wasm_runtime_get_custom_section` cannot be called anymore
- when using the wasm/AOT loader in fast interpreter or AOT mode, set `wasm_binary_freeable=true` in `LoadArgs` and free the wasm binary buffer (with `wasm_byte_vec_delete`) after module loading; `wasm_runtime_is_underlying_binary_freeable` can be queried to check if the wasm binary buffer can be safely freed; after the buffer is freed, `wasm_runtime_get_custom_section` cannot be called anymore
14 changes: 7 additions & 7 deletions samples/basic/src/free_buffer_early.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ void
my_log(uint32 log_level, const char *file, int line, const char *fmt, ...)
{
char buf[200];
snprintf(buf, sizeof(buf), "[WamrLogger] %s", fmt);
snprintf(buf, sizeof(buf), "[WamrLogger] %s\n", fmt);

va_list ap;
va_start(ap, fmt);
Expand Down Expand Up @@ -89,19 +89,19 @@ main(int argc, char *argv_main[])
goto fail;
}

if (wasm_runtime_is_underlying_binary_freeable(module)) {
printf("Able to free wasm binary buffer.\n");
wasm_runtime_free(buffer);
buffer = NULL;
}

module_inst = wasm_runtime_instantiate(module, stack_size, heap_size,
error_buf, sizeof(error_buf));
if (!module_inst) {
printf("Instantiate wasm module failed. error: %s.\n", error_buf);
goto fail;
}

if (wasm_runtime_is_underlying_binary_freeable(module_inst)) {
printf("Able to free wasm binary buffer.\n");
wasm_runtime_free(buffer);
buffer = NULL;
}

char *args[1] = { "3" };
success = wasm_application_execute_func(module_inst, "mul7", 1, args);
if (!success) {
Expand Down

0 comments on commit a8c3605

Please sign in to comment.