From 215865a4627830533d53c5c24d52ffbe7f076dfc Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Sat, 30 Mar 2024 16:20:55 -0700 Subject: [PATCH] Experimental wasm support --- CMakeLists.txt | 106 +++++++++++++++++++++++++++++----------------- Internal.h | 8 ++-- RealDataBench.cpp | 4 +- 3 files changed, 73 insertions(+), 45 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ae561bb..cc8289d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -42,10 +42,25 @@ else() add_link_options(-Wl,--gc-sections) endif() +if(EMSCRIPTEN) + # https://github.com/emscripten-core/emscripten/issues/15377#issuecomment-1285167486 + add_link_options(-lnodefs.js -lnoderawfs.js) +endif() + include(CheckIncludeFileCXX) include(CMakePushCheckState) if(NOT USE_SIMD_FALLBACK) + cmake_push_check_state() + list(APPEND CMAKE_REQUIRED_FLAGS -msimd128) + check_include_file_cxx("wasm_simd128.h" HAS_WASM_SIMD) + if(HAS_WASM_SIMD) + # https://emscripten.org/docs/porting/simd.html#using-simd-with-webassembly + add_compile_options(-msimd128) + add_compile_definitions(HAS_WASM_SIMD) + endif() + cmake_pop_check_state() + cmake_push_check_state() list(APPEND CMAKE_REQUIRED_FLAGS -mavx) check_include_file_cxx("immintrin.h" HAS_AVX) @@ -105,30 +120,50 @@ include(CTest) if(BUILD_TESTING) - # Shared library version of FoundationDB's skip list implementation - add_library(skip_list SHARED SkipList.cpp) - target_compile_options(skip_list PRIVATE -fPIC -fno-exceptions - -fvisibility=hidden) - target_include_directories(skip_list PUBLIC ${CMAKE_SOURCE_DIR}/include) - set_target_properties(skip_list PROPERTIES LIBRARY_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/skip_list") - set_target_properties(skip_list PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) - set_target_properties(skip_list PROPERTIES VERSION ${PROJECT_VERSION} - SOVERSION ${PROJECT_VERSION_MAJOR}) + # corpus tests, which are test - # Shared library version of a std::unordered_map-based conflict set (point - # queries only) - add_library(hash_table SHARED HashTable.cpp) - target_compile_options(hash_table PRIVATE -fPIC -fno-exceptions - -fvisibility=hidden) - target_include_directories(hash_table PUBLIC ${CMAKE_SOURCE_DIR}/include) - set_target_properties(hash_table PROPERTIES LIBRARY_OUTPUT_DIRECTORY - "${CMAKE_BINARY_DIR}/hash_table") - set_target_properties(hash_table PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) - set_target_properties( - hash_table PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION - ${PROJECT_VERSION_MAJOR}) + file(GLOB CORPUS_TESTS ${CMAKE_SOURCE_DIR}/corpus/*) + # extra testing that relies on shared libraries, which aren't available with + # emscripten + if(NOT EMSCRIPTEN) + # Shared library version of FoundationDB's skip list implementation + add_library(skip_list SHARED SkipList.cpp) + target_compile_options(skip_list PRIVATE -fPIC -fno-exceptions + -fvisibility=hidden) + target_include_directories(skip_list PUBLIC ${CMAKE_SOURCE_DIR}/include) + set_target_properties(skip_list PROPERTIES LIBRARY_OUTPUT_DIRECTORY + "${CMAKE_BINARY_DIR}/skip_list") + set_target_properties(skip_list PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) + set_target_properties( + skip_list PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION + ${PROJECT_VERSION_MAJOR}) + + # Shared library version of a std::unordered_map-based conflict set (point + # queries only) + add_library(hash_table SHARED HashTable.cpp) + target_compile_options(hash_table PRIVATE -fPIC -fno-exceptions + -fvisibility=hidden) + target_include_directories(hash_table PUBLIC ${CMAKE_SOURCE_DIR}/include) + set_target_properties( + hash_table PROPERTIES LIBRARY_OUTPUT_DIRECTORY + "${CMAKE_BINARY_DIR}/hash_table") + set_target_properties(hash_table PROPERTIES OUTPUT_NAME ${PROJECT_NAME}) + set_target_properties( + hash_table PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION + ${PROJECT_VERSION_MAJOR}) + + add_executable(driver_skip_list TestDriver.cpp) + target_compile_options(driver_skip_list PRIVATE ${TEST_FLAGS}) + target_link_libraries(driver_skip_list PRIVATE skip_list) + + foreach(TEST ${CORPUS_TESTS}) + get_filename_component(hash ${TEST} NAME) + add_test(NAME skip_list_${hash} COMMAND driver_skip_list ${TEST}) + endforeach() + endif() + + # ad hoc testing add_executable(conflict_set_main ConflictSet.cpp) target_include_directories(conflict_set_main PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -155,10 +190,7 @@ if(BUILD_TESTING) endif() endif() - # corpus tests - - file(GLOB CORPUS_TESTS ${CMAKE_SOURCE_DIR}/corpus/*) - + # fuzz/whitebox tests add_executable(fuzz_driver ConflictSet.cpp FuzzTestDriver.cpp) target_compile_options(fuzz_driver PRIVATE ${TEST_FLAGS}) if(NOT CMAKE_CROSSCOMPILING) @@ -173,8 +205,7 @@ if(BUILD_TESTING) add_test(NAME conflict_set_fuzz_${hash} COMMAND fuzz_driver ${TEST}) endforeach() - # tsan - + # tsan tests if(NOT CMAKE_CROSSCOMPILING AND NOT CMAKE_BUILD_TYPE STREQUAL Debug) add_executable(tsan_driver ConflictSet.cpp FuzzTestDriver.cpp) target_compile_options(tsan_driver PRIVATE ${TEST_FLAGS} -fsanitize=thread) @@ -188,9 +219,14 @@ if(BUILD_TESTING) endforeach() endif() + # blackbox tests add_executable(driver TestDriver.cpp) target_compile_options(driver PRIVATE ${TEST_FLAGS}) target_link_libraries(driver PRIVATE ${PROJECT_NAME}) + foreach(TEST ${CORPUS_TESTS}) + get_filename_component(hash ${TEST} NAME) + add_test(NAME conflict_set_blackbox_${hash} COMMAND driver ${TEST}) + endforeach() add_executable(script_test ScriptTest.cpp) target_compile_options(script_test PRIVATE ${TEST_FLAGS}) @@ -202,10 +238,6 @@ if(BUILD_TESTING) add_test(NAME conflict_set_script_${name} COMMAND script_test ${TEST}) endforeach() - add_executable(driver_skip_list TestDriver.cpp) - target_compile_options(driver_skip_list PRIVATE ${TEST_FLAGS}) - target_link_libraries(driver_skip_list PRIVATE skip_list) - find_program(VALGRIND_EXE valgrind) if(VALGRIND_EXE AND NOT CMAKE_CROSSCOMPILING) add_test(NAME conflict_set_blackbox_valgrind @@ -213,12 +245,6 @@ if(BUILD_TESTING) $ ${CORPUS_TESTS}) endif() - foreach(TEST ${CORPUS_TESTS}) - get_filename_component(hash ${TEST} NAME) - add_test(NAME conflict_set_blackbox_${hash} COMMAND driver ${TEST}) - add_test(NAME skip_list_${hash} COMMAND driver_skip_list ${TEST}) - endforeach() - # api smoke tests # c90 @@ -239,7 +265,9 @@ if(BUILD_TESTING) PROPERTIES CXX_STANDARD_REQUIRED ON) add_test(NAME conflict_set_cxx_api_test COMMAND conflict_set_cxx_api_test) - if(NOT APPLE AND NOT CMAKE_BUILD_TYPE STREQUAL Debug) + if(NOT EMSCRIPTEN + AND NOT APPLE + AND NOT CMAKE_BUILD_TYPE STREQUAL Debug) add_test( NAME conflict_set_shared_symbols COMMAND ${CMAKE_SOURCE_DIR}/test_symbols.sh diff --git a/Internal.h b/Internal.h index 92b4eb7..e50c6ac 100644 --- a/Internal.h +++ b/Internal.h @@ -177,12 +177,10 @@ struct Arena::ArenaImpl { uint8_t *begin() { return reinterpret_cast(this + 1); } }; -static_assert(sizeof(Arena::ArenaImpl) == 16); -static_assert(alignof(Arena::ArenaImpl) == 8); - inline Arena::Arena(int initialSize) : impl(nullptr) { if (initialSize > 0) { - auto allocationSize = align_up(initialSize + sizeof(ArenaImpl), 16); + auto allocationSize = + align_up(initialSize + sizeof(ArenaImpl), sizeof(ArenaImpl)); impl = (Arena::ArenaImpl *)safe_malloc(allocationSize); impl->prev = nullptr; impl->capacity = allocationSize - sizeof(ArenaImpl); @@ -218,7 +216,7 @@ inline void *operator new(size_t size, std::align_val_t align, Arena &arena) { (arena.impl ? std::max(sizeof(Arena::ArenaImpl), arena.impl->capacity * 2) : 0)), - 16); + sizeof(Arena::ArenaImpl)); auto *impl = (Arena::ArenaImpl *)safe_malloc(allocationSize); impl->prev = arena.impl; impl->capacity = allocationSize - sizeof(Arena::ArenaImpl); diff --git a/RealDataBench.cpp b/RealDataBench.cpp index b3e5038..570b9c8 100644 --- a/RealDataBench.cpp +++ b/RealDataBench.cpp @@ -1,8 +1,10 @@ #include #include +#include #include #include +#include #include #include #include @@ -131,4 +133,4 @@ int main(int argc, const char **argv) { checkTime, checkBytes / checkTime * 1e-6, addTime, addBytes / addTime * 1e-6, gcTime / (gcTime + addTime) * 1e2, double(peakMemory)); -} \ No newline at end of file +}