Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Basic support for Multi-Memory proposal #3381

Open
TianlongLiang opened this issue Apr 30, 2024 · 4 comments
Open

[RFC] Basic support for Multi-Memory proposal #3381

TianlongLiang opened this issue Apr 30, 2024 · 4 comments
Labels
new feature New feature request

Comments

@TianlongLiang
Copy link
Contributor

Summary

Plan to implement basic support for the multi-memory proposal, first focusing on the classic interpreter and AOT running modes.

Overview of Basic Support Plan

With basic support completed, users should experience the following:

  • Use cmake -DWAMR_BUILD_MULTI_MEMORY=1 to compile a multi-memory-enabled iwasm VM core(Disable it by default). When the multi-memory macro is turned on, the wasm/aot runtime will be able to support both non-multi-memory and multi-memory wasm/aot files.

  • For the wamrc AOT compiler, no extra work is required during compile time. To compile a multi-memory aot file, use wamrc --enable-multi-memory -o test.aot test.wasm to generate a multi-memory aot file, will set the corresponding feature bit in the aot file if actually has multiple memory sections in the wasm file.

  • When you integrate a WAMR VMcore into your host application, you can use certain APIs that WAMR exports. These APIs help manage linear memory and enable the conversion and verification of addresses between the host's native environment and the app's linear memory.
    But for multi-memory, the behavior of those existing APIs will need some modification and a new set of counterpart (extended) APIs should be added. The existing APIs now use the assumingly main memory, namely the first non-import memory[0](if at least one memory section is present) or import_memory[0](if no memory section is present). Additionally, we should add a new set of APIs that take an extra argument mem_idx to manage the memories in multi-memory explicitly. The new APIs are as follows:

    WASM_RUNTIME_API_EXTERN bool
    wasm_runtime_validate_app_addr_ex(WASMModuleInstanceCommon *module_inst, uint64 app_offset, uint64 size, uint32 memidx);
    
    WASM_RUNTIME_API_EXTERN bool
    wasm_runtime_validate_app_str_addr_ex(WASMModuleInstanceCommon *module_inst, uint64 app_str_offset, uint32 memidx);
    
    WASM_RUNTIME_API_EXTERN bool
    wasm_runtime_validate_native_addr_ex(WASMModuleInstanceCommon *module_inst, void *native_ptr, uint64 size, uint32 memidx);
    
    WASM_RUNTIME_API_EXTERN void *
    wasm_runtime_addr_app_to_native_ex(WASMModuleInstanceCommon *module_inst, uint64 app_offset, uint32 memidx);
    
    WASM_RUNTIME_API_EXTERN uint64
    wasm_runtime_addr_native_to_app_ex(WASMModuleInstanceCommon *module_inst, void *native_ptr, uint32 memidx);
    
    WASM_RUNTIME_API_EXTERN bool
    wasm_runtime_get_app_addr_range_ex(WASMModuleInstanceCommon *module_inst, uint64 app_offset, uint64 *p_app_start_offset, uint64 *p_app_end_offset, uint32 memidx);
    
    WASM_RUNTIME_API_EXTERN bool
    wasm_runtime_get_native_addr_range_ex(WASMModuleInstanceCommon *module_inst, uint8 *native_ptr, uint8 **p_native_start_addr, uint8 **p_native_end_addr, uint32 memidx);

Impact of multi-memory proposal on WAMR's internal implementation

There should be no change in the data structure, but it will have some impact on some internal APIs, which need to take an extra argument memidx. For example, some functions accessing the func_ctx->mem_info[0], now need to index the actual memory index. Complete list of APIs. The involved APIs:

  • get_memory_check_bound
  • get_memory_curr_page_count
  • aot_check_memory_overflow
  • check_bulk_memory_overflow
  • wasm_enlarge_memory/aot_enlarge_memory
  • llvm_jit_memory_init/aot_memory_init
  • aot_check_memory_overflow
  • aot_compile_op_xxx for related opcodes

Compatibility between multi-memory and Memory32/Memory64

Assuming all the memory is the same index type, that is to say, all memory has to be either all memory 32 type or all memory64 type, and no mixing of them should be allowed.

Topics for Further Discussion

😄 Suggestions or input on any topics are appreciated.

@yamt
Copy link
Collaborator

yamt commented Apr 30, 2024

Assuming all the memory is the same index type, that is to say, all memory has to be either all memory 32 type or all memory64 type, and no mixing of them should be allowed.

the restriction sounds a bit arbitrary.
do you think it makes the implementation significantly easier? (i'm not sure)

btw, i guess threads proposal (shared memory) needs some work to remove single memory assumptions too.

@TianlongLiang
Copy link
Contributor Author

the restriction sounds a bit arbitrary. do you think it makes the implementation significantly easier? (i'm not sure)

Yes, it will make the implementation easier. I made such an assumption because I don't think this kind of flexibility is really that useful to outweigh the extra complexity burden added to the codebase. But I could be wrong, a webassembly program that manage both i32 and i64 memory can be useful in some areas, so maybe I could gather more thoughts on this topic before the actual implementation.

btw, i guess threads proposal (shared memory) needs some work to remove single memory assumptions too.

I think it won't be too much work, at least speaking from a functionality perspective, currently, the interpreter uses a global lock to ensure the atomicity, it will work for multiple shared memories, just less efficiently. And for AOT, since it now uses atomic LLVM IR, it won't need to change. As for the multi-memories address calculation(such as memory base address, boundary check, etc), following the logic in non-shared multi-memories should be okay.

@wenyongh wenyongh added the new feature New feature request label May 6, 2024
@yamt
Copy link
Collaborator

yamt commented May 7, 2024

the restriction sounds a bit arbitrary. do you think it makes the implementation significantly easier? (i'm not sure)

Yes, it will make the implementation easier. I made such an assumption because I don't think this kind of flexibility is really that useful to outweigh the extra complexity burden added to the codebase. But I could be wrong, a webassembly program that manage both i32 and i64 memory can be useful in some areas, so maybe I could gather more thoughts on this topic before the actual implementation.

do you have specific use cases?
do you have any plans on toolchain?
right now, as far as i know, there is no simple way to create wasm modules which use multi memory.

@TianlongLiang
Copy link
Contributor Author

do you have specific use cases?

No, I don't have any cases other than those simple wast cases in the multi-memory spec proposal

do you have any plans on toolchain?

No, I don't have any plans on toolchain

right now, as far as i know, there is no simple way to create wasm modules which use multi memory.

You are right that there is no easy way to generate multi-memory wasm module from high-level programming language. WebAssembly/multi-memory#45 I think currently what I am trying to do is more like do basic support so that when the future toolchain better supports more multi-memory hopefully there will be little effort on the WAMR side to support them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature request
Projects
None yet
Development

No branches or pull requests

3 participants