Просмотр исходного кода

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.
liang.he 3 лет назад
Родитель
Сommit
f6d67c1cda

+ 6 - 0
CMakeLists.txt

@@ -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)

+ 4 - 0
build-scripts/config_common.cmake

@@ -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 - 0
build-scripts/runtime_lib.cmake

@@ -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:

+ 4 - 0
core/config.h

@@ -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_ */

+ 81 - 2
core/iwasm/common/wasm_c_api.c

@@ -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);
 }
 

+ 4 - 0
samples/wasm-c-api/CMakeLists.txt

@@ -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  ################