Skip to content

Commit f6d67c1

Browse files
authored
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.
1 parent 84a23d4 commit f6d67c1

6 files changed

Lines changed: 107 additions & 2 deletions

File tree

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
130130

131131
# STATIC LIBRARY
132132
add_library(iwasm_static STATIC ${WAMR_RUNTIME_LIB_SOURCE})
133+
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
134+
target_link_libraries(iwasm_static OpenSSL::SSL)
135+
endif ()
133136
set_target_properties (iwasm_static PROPERTIES OUTPUT_NAME vmlib)
134137

135138
install (TARGETS iwasm_static ARCHIVE DESTINATION lib)
@@ -138,6 +141,9 @@ install (TARGETS iwasm_static ARCHIVE DESTINATION lib)
138141
add_library (iwasm_shared SHARED ${WAMR_RUNTIME_LIB_SOURCE})
139142
set_target_properties (iwasm_shared PROPERTIES OUTPUT_NAME iwasm)
140143
target_link_libraries (iwasm_shared ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
144+
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
145+
target_link_libraries(iwasm_shared OpenSSL::SSL)
146+
endif ()
141147

142148
if (MINGW)
143149
target_link_libraries (iwasm_shared -lWs2_32)

build-scripts/config_common.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,7 @@ endif ()
314314
if (WAMR_BUILD_ALLOC_WITH_USER_DATA EQUAL 1)
315315
add_definitions(-DWASM_MEM_ALLOC_WITH_USER_DATA=1)
316316
endif()
317+
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
318+
add_definitions (-DWASM_ENABLE_WASM_CACHE=1)
319+
message (" Wasm files cache enabled")
320+
endif ()

build-scripts/runtime_lib.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ if (DEFINED EXTRA_SDK_INCLUDE_PATH)
2727
)
2828
endif ()
2929

30+
# Need exactly OpenSSL 1.1.1
31+
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
32+
# Set OPENSSL_ROOT_DIR to the root directory of an OpenSSL installation.
33+
# Like: cmake -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl
34+
# Especially on MacOS
35+
find_package(OpenSSL 1.1.1 EXACT REQUIRED)
36+
endif ()
37+
3038
# Set default options
3139

3240
# Set WAMR_BUILD_TARGET, currently values supported:

core/config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,4 +430,8 @@
430430
#define WASM_MEM_ALLOC_WITH_USER_DATA 0
431431
#endif
432432

433+
#ifndef WASM_ENABLE_WASM_CACHE
434+
#define WASM_ENABLE_WASM_CACHE 0
435+
#endif
436+
433437
#endif /* end of _CONFIG_H_ */

core/iwasm/common/wasm_c_api.c

Lines changed: 81 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
* Copyright (C) 2019 Intel Corporation. All rights reserved.
33
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44
*/
5+
56
#include "wasm_c_api_internal.h"
67

78
#include "bh_assert.h"
@@ -18,6 +19,10 @@
1819
#endif /*WASM_ENABLE_JIT != 0 && WASM_ENABLE_LAZY_JIT == 0*/
1920
#endif /*WASM_ENABLE_AOT != 0*/
2021

22+
#if WASM_ENABLE_WASM_CACHE != 0
23+
#include <openssl/sha.h>
24+
#endif
25+
2126
/*
2227
* Thread Model:
2328
* - Only one wasm_engine_t in one process
@@ -35,6 +40,9 @@ typedef struct wasm_module_ex_t {
3540
wasm_byte_vec_t *binary;
3641
korp_mutex lock;
3742
uint32 ref_count;
43+
#if WASM_ENABLE_WASM_CACHE != 0
44+
char hash[SHA256_DIGEST_LENGTH];
45+
#endif
3846
} wasm_module_ex_t;
3947

4048
#ifndef os_thread_local_attribute
@@ -2087,16 +2095,68 @@ module_to_module_ext(wasm_module_t *module)
20872095
#define MODULE_AOT(module_comm) ((AOTModule *)(*module_comm))
20882096
#endif
20892097

2098+
#if WASM_ENABLE_WASM_CACHE != 0
2099+
static wasm_module_ex_t *
2100+
check_loaded_module(Vector *modules, char *binary_hash)
2101+
{
2102+
unsigned i;
2103+
wasm_module_ex_t *module = NULL;
2104+
2105+
for (i = 0; i < modules->num_elems; i++) {
2106+
bh_vector_get(modules, i, &module);
2107+
if (!module) {
2108+
LOG_ERROR("Unexpected failure at %d\n", __LINE__);
2109+
return NULL;
2110+
}
2111+
2112+
if (!module->ref_count)
2113+
/* deleted */
2114+
continue;
2115+
2116+
if (memcmp(module->hash, binary_hash, SHA256_DIGEST_LENGTH) == 0)
2117+
return module;
2118+
}
2119+
return NULL;
2120+
}
2121+
2122+
static wasm_module_ex_t *
2123+
try_reuse_loaded_module(wasm_store_t *store, char *binary_hash)
2124+
{
2125+
wasm_module_ex_t *cached = NULL;
2126+
wasm_module_ex_t *ret = NULL;
2127+
2128+
cached = check_loaded_module(&singleton_engine->modules, binary_hash);
2129+
if (!cached)
2130+
goto quit;
2131+
2132+
os_mutex_lock(&cached->lock);
2133+
if (!cached->ref_count)
2134+
goto unlock;
2135+
2136+
if (!bh_vector_append((Vector *)store->modules, &cached))
2137+
goto unlock;
2138+
2139+
cached->ref_count += 1;
2140+
ret = cached;
2141+
2142+
unlock:
2143+
os_mutex_unlock(&cached->lock);
2144+
quit:
2145+
return ret;
2146+
}
2147+
#endif /* WASM_ENABLE_WASM_CACHE != 0 */
2148+
20902149
wasm_module_t *
20912150
wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
20922151
{
20932152
char error_buf[128] = { 0 };
20942153
wasm_module_ex_t *module_ex = NULL;
2154+
#if WASM_ENABLE_WASM_CACHE != 0
2155+
char binary_hash[SHA256_DIGEST_LENGTH] = { 0 };
2156+
#endif
20952157

20962158
bh_assert(singleton_engine);
20972159

2098-
WASM_C_DUMP_PROC_MEM();
2099-
21002160
if (!store || !binary || binary->size == 0 || binary->size > UINT32_MAX)
21012161
goto quit;
21022162

@@ -2121,6 +2181,16 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
21212181
}
21222182
}
21232183

2184+
#if WASM_ENABLE_WASM_CACHE != 0
2185+
/* if cached */
2186+
SHA256((void *)binary->data, binary->num_elems, binary_hash);
2187+
module_ex = try_reuse_loaded_module(store, binary_hash);
2188+
if (module_ex)
2189+
return module_ext_to_module(module_ex);
2190+
#endif
2191+
2192+
WASM_C_DUMP_PROC_MEM();
2193+
21242194
module_ex = malloc_internal(sizeof(wasm_module_ex_t));
21252195
if (!module_ex)
21262196
goto quit;
@@ -2151,6 +2221,11 @@ wasm_module_new(wasm_store_t *store, const wasm_byte_vec_t *binary)
21512221
if (!bh_vector_append(&singleton_engine->modules, &module_ex))
21522222
goto destroy_lock;
21532223

2224+
#if WASM_ENABLE_WASM_CACHE != 0
2225+
bh_memcpy_s(module_ex->hash, sizeof(module_ex->hash), binary_hash,
2226+
sizeof(binary_hash));
2227+
#endif
2228+
21542229
module_ex->ref_count = 1;
21552230

21562231
WASM_C_DUMP_PROC_MEM();
@@ -2226,6 +2301,10 @@ wasm_module_delete_internal(wasm_module_t *module)
22262301
module_ex->module_comm_rt = NULL;
22272302
}
22282303

2304+
#if WASM_ENABLE_WASM_CACHE != 0
2305+
memset(module_ex->hash, 0, sizeof(module_ex->hash));
2306+
#endif
2307+
22292308
os_mutex_unlock(&module_ex->lock);
22302309
}
22312310

samples/wasm-c-api/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,10 @@ if (MSVC)
9292
target_compile_definitions(vmlib PRIVATE WASM_API_EXTERN=)
9393
endif()
9494
target_link_libraries (vmlib ${LLVM_AVAILABLE_LIBS} ${UV_A_LIBS} -lm -ldl -lpthread)
95+
96+
if (WAMR_BUILD_WASM_CACHE EQUAL 1)
97+
target_link_libraries(vmlib OpenSSL::SSL)
98+
endif ()
9599
################################################
96100

97101
################ application related ################

0 commit comments

Comments
 (0)