Enable wasm cache loading in wasm-c-api (#1759)

Use sha256 to hash binary file content. If the incoming wasm binary is
cached before, wasm_module_new() simply returns the existed one.

Use -DWAMR_BUILD_WASM_CACHE=0/1 to control the feature.
OpenSSL 1.1.1 is required if the feature is enabled.
This commit is contained in:
liang.he 2022-12-05 12:25:26 +08:00 committed by GitHub
parent 84a23d43ec
commit f6d67c1cda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 107 additions and 2 deletions

View File

@ -130,6 +130,9 @@ include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
# STATIC LIBRARY
add_library(iwasm_static STATIC ${WAMR_RUNTIME_LIB_SOURCE})
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
target_link_libraries(iwasm_static OpenSSL::SSL)
endif ()
set_target_properties (iwasm_static PROPERTIES OUTPUT_NAME vmlib)
install (TARGETS iwasm_static ARCHIVE DESTINATION lib)
@ -138,6 +141,9 @@ install (TARGETS iwasm_static ARCHIVE DESTINATION lib)
add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE})
set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm)
target_link_libraries (iwasm_shared ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
target_link_libraries(iwasm_shared OpenSSL::SSL)
endif ()
if (MINGW)
target_link_libraries (iwasm_shared -lWs2_32)

View File

@ -314,3 +314,7 @@ endif ()
if (WAMR_BUILD_ALLOC_WITH_USER_DATA EQUAL 1)
add_definitions(-DWASM_MEM_ALLOC_WITH_USER_DATA=1)
endif()
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
add_definitions (-DWASM_ENABLE_WASM_CACHE=1)
message (" Wasm files cache enabled")
endif ()

View File

@ -27,6 +27,14 @@ if (DEFINED EXTRA_SDK_INCLUDE_PATH)
)
endif ()
# Need exactly OpenSSL 1.1.1
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
# Set OPENSSL_ROOT_DIR to the root directory of an OpenSSL installation.
# Like: cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl
# Especially on MacOS
find_package(OpenSSL 1.1.1 EXACT REQUIRED)
endif ()
# Set default options
# Set WAMR_BUILD_TARGET, currently values supported:

View File

@ -430,4 +430,8 @@
#define WASM_MEM_ALLOC_WITH_USER_DATA 0
#endif
#ifndef WASM_ENABLE_WASM_CACHE
#define WASM_ENABLE_WASM_CACHE 0
#endif
#endif /* end of _CONFIG_H_ */

View File

@ -2,6 +2,7 @@
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "wasm_c_api_internal.h"
#include "bh_assert.h"
@ -18,6 +19,10 @@
#endif /*WASM_ENABLE_JIT != 0 && WASM_ENABLE_LAZY_JIT == 0*/
#endif /*WASM_ENABLE_AOT != 0*/
#if WASM_ENABLE_WASM_CACHE != 0
#include <openssl/sha.h>
#endif
/*
* Thread Model:
* - Only one wasm_engine_t in one process
@ -35,6 +40,9 @@ typedef struct wasm_module_ex_t {
wasm_byte_vec_t *binary;
korp_mutex lock;
uint32 ref_count;
#if WASM_ENABLE_WASM_CACHE != 0
char hash[SHA256_DIGEST_LENGTH];
#endif
} wasm_module_ex_t;
#ifndef os_thread_local_attribute
@ -2087,16 +2095,68 @@ module_to_module_ext(wasm_module_t *module)
#define MODULE_AOT(module_comm) ((AOTModule *)(*module_comm))
#endif
#if WASM_ENABLE_WASM_CACHE != 0
static wasm_module_ex_t *
check_loaded_module(Vector *modules, char *binary_hash)
{
unsigned i;
wasm_module_ex_t *module = NULL;
for (i = 0; i < modules->num_elems; i++) {
bh_vector_get(modules, i, &module);
if (!module) {
LOG_ERROR("Unexpected failure at %d\n", __LINE__);
return NULL;
}
if (!module->ref_count)
/* deleted */
continue;
if (memcmp(module->hash, binary_hash, SHA256_DIGEST_LENGTH) == 0)
return module;
}
return NULL;
}
static wasm_module_ex_t *
try_reuse_loaded_module(wasm_store_t *store, char *binary_hash)
{
wasm_module_ex_t *cached = NULL;
wasm_module_ex_t *ret = NULL;
cached = check_loaded_module(&singleton_engine->modules, binary_hash);
if (!cached)
goto quit;
os_mutex_lock(&cached->lock);
if (!cached->ref_count)
goto unlock;
if (!bh_vector_append((Vector *)store->modules, &cached))
goto unlock;
cached->ref_count += 1;
ret = cached;
unlock:
os_mutex_unlock(&cached->lock);
quit:
return ret;
}
#endif /* WASM_ENABLE_WASM_CACHE != 0 */
wasm_module_t *
wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
{
char error_buf[128] = { 0 };
wasm_module_ex_t *module_ex = NULL;
#if WASM_ENABLE_WASM_CACHE != 0
char binary_hash[SHA256_DIGEST_LENGTH] = { 0 };
#endif
bh_assert(singleton_engine);
WASM_C_DUMP_PROC_MEM();
if (!store || !binary || binary->size == 0 || binary->size > UINT32_MAX)
goto quit;
@ -2121,6 +2181,16 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
}
}
#if WASM_ENABLE_WASM_CACHE != 0
/* if cached */
SHA256((void *)binary->data, binary->num_elems, binary_hash);
module_ex = try_reuse_loaded_module(store, binary_hash);
if (module_ex)
return module_ext_to_module(module_ex);
#endif
WASM_C_DUMP_PROC_MEM();
module_ex = malloc_internal(sizeof(wasm_module_ex_t));
if (!module_ex)
goto quit;
@ -2151,6 +2221,11 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
if (!bh_vector_append(&singleton_engine->modules, &module_ex))
goto destroy_lock;
#if WASM_ENABLE_WASM_CACHE != 0
bh_memcpy_s(module_ex->hash, sizeof(module_ex->hash), binary_hash,
sizeof(binary_hash));
#endif
module_ex->ref_count = 1;
WASM_C_DUMP_PROC_MEM();
@ -2226,6 +2301,10 @@ wasm_module_delete_internal(wasm_module_t *module)
module_ex->module_comm_rt = NULL;
}
#if WASM_ENABLE_WASM_CACHE != 0
memset(module_ex->hash, 0, sizeof(module_ex->hash));
#endif
os_mutex_unlock(&module_ex->lock);
}

View File

@ -92,6 +92,10 @@ if (MSVC)
target_compile_definitions(vmlib PRIVATE WASM_API_EXTERN=)
endif()
target_link_libraries (vmlib ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
target_link_libraries(vmlib OpenSSL::SSL)
endif ()
################################################
################ application related ################