Skip to content

Commit

Permalink
Enable wasm cache loading in wasm-c-api (bytecodealliance#1759)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lum1n0us authored Dec 5, 2022
1 parent 2758f82 commit 86a3929
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down
4 changes: 4 additions & 0 deletions build-scripts/config_common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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 ()
8 changes: 8 additions & 0 deletions build-scripts/runtime_lib.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
4 changes: 4 additions & 0 deletions core/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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_ */
83 changes: 81 additions & 2 deletions core/iwasm/common/wasm_c_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
}

Expand Down
4 changes: 4 additions & 0 deletions samples/wasm-c-api/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 ################
Expand Down

0 comments on commit 86a3929

Please sign in to comment.