diff options
-rw-r--r-- | CMakeLists.txt | 17 | ||||
-rw-r--r-- | configure.ac | 20 | ||||
-rw-r--r-- | doc/README.macros | 6 | ||||
-rw-r--r-- | os_dep.c | 9 |
4 files changed, 40 insertions, 12 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7917be50..8567e374 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -89,6 +89,7 @@ option(enable_single_obj_compilation "Compile all libgc source files into single option(disable_single_obj_compilation "Compile each libgc source file independently" OFF) option(enable_handle_fork "Attempt to ensure a usable collector after fork()" ON) option(disable_handle_fork "Prohibit installation of pthread_atfork() handlers" OFF) +option(enable_emscripten_asyncify "Use Emscripten asyncify feature" OFF) option(install_headers "Install header and pkg-config metadata files" ON) option(with_libatomic_ops "Use an external libatomic_ops" OFF) option(without_libatomic_ops "Use atomic_ops.h in libatomic_ops/src" OFF) @@ -546,6 +547,22 @@ if (HAVE_DLADDR) add_definitions("-DHAVE_DLADDR") endif() +# Check for emscripten; use asyncify feature if requested. +check_c_source_compiles(" +#ifndef __EMSCRIPTEN__\n +# error This is not Emscripten\n +#endif\n +int main(void) { return 0; }" + EMSCRIPTEN) +if (EMSCRIPTEN AND enable_emscripten_asyncify) + # Use this option if your program is targeting -sASYNCIFY. The latter is + # required to scan the stack, ASYNCIFY_STACK_SIZE is probably needed for + # gctest only. + add_definitions("-DEMSCRIPTEN_ASYNCIFY") + set(CMAKE_EXE_LINKER_FLAGS + "${CMAKE_EXE_LINKER_FLAGS} -sASYNCIFY -sASYNCIFY_STACK_SIZE=128000") +endif() + add_library(gc ${SRC}) target_link_libraries(gc PRIVATE ${ATOMIC_OPS_LIBS_CMAKE} ${THREADDLLIBS_LIST}) diff --git a/configure.ac b/configure.ac index 03e14b8e..4e9e32e4 100644 --- a/configure.ac +++ b/configure.ac @@ -86,17 +86,23 @@ esac AC_MSG_CHECKING([for emscripten]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([[ -# ifdef __EMSCRIPTEN__ -# error "this is emscripten" +# ifndef __EMSCRIPTEN__ +# error This is not Emscripten # endif - ]])], [emscripten=no], [emscripten=yes]) -# Note -s ASYNCIFY is required to scan the stack, ASYNCIFY_STACK_SIZE is -# probably needed for gctest only. -AS_IF([test "x$emscripten" = "xyes"], - [gc_cflags="${gc_cflags} -s ASYNCIFY -s ASYNCIFY_STACK_SIZE=128000"]) + ]])], [emscripten=yes], [emscripten=no]) AM_CONDITIONAL(EMSCRIPTEN, test x$emscripten = xyes) AC_MSG_RESULT([$emscripten]) +AC_ARG_ENABLE(emscripten-asyncify, + [AS_HELP_STRING([--enable-emscripten-asyncify], + [use Emscripten asyncify feature])]) +# Use this option if your program is targeting -sASYNCIFY. The latter is +# required to scan the stack, ASYNCIFY_STACK_SIZE is probably needed for +# gctest only. +AS_IF([test "${emscripten}" = yes -a "${enable_emscripten_asyncify}" = yes], + [gc_cflags="${gc_cflags} -DEMSCRIPTEN_ASYNCIFY" + gc_cflags="${gc_cflags} -sASYNCIFY -sASYNCIFY_STACK_SIZE=128000"]) + GC_CFLAGS=${gc_cflags} AC_SUBST(GC_CFLAGS) diff --git a/doc/README.macros b/doc/README.macros index 8aee5722..8fb6a76f 100644 --- a/doc/README.macros +++ b/doc/README.macros @@ -606,3 +606,9 @@ USE_GET_STACKBASE_FOR_MAIN (Linux only) Use pthread_attr_getstack() instead of __libc_stack_end (or instead of any hard-coded value) for getting the primordial thread stack bottom (useful if the client modifies the program's address space). + +EMSCRIPTEN_ASYNCIFY (Emscripten only) Use Asyncify feature. Note this is + a relatively rarely used feature of Emscripten, most developers do not use + it, and it does not scale well to moderate-to-large code bases. But the + feature is needed to pass gctest, at least. Requires -sASYNCIFY linker + flag. @@ -1242,7 +1242,7 @@ GC_INNER size_t GC_page_size = 0; # define GET_MAIN_STACKBASE_SPECIAL #elif defined(EMSCRIPTEN) -# ifdef USE_EMSCRIPTEN_SCAN_STACK +# if defined(USE_EMSCRIPTEN_SCAN_STACK) && defined(EMSCRIPTEN_ASYNCIFY) /* According to the documentation, emscripten_scan_stack() is only */ /* guaranteed to be available when building with ASYNCIFY. */ # include <emscripten.h> @@ -1260,7 +1260,7 @@ GC_INNER size_t GC_page_size = 0; ptr_t GC_get_main_stack_base(void) { -# ifdef USE_EMSCRIPTEN_SCAN_STACK +# if defined(USE_EMSCRIPTEN_SCAN_STACK) && defined(EMSCRIPTEN_ASYNCIFY) emscripten_scan_stack(scan_stack_cb); return (ptr_t)emscripten_stack_base; # else @@ -2814,7 +2814,7 @@ GC_INNER void GC_unmap_gap(ptr_t start1, size_t bytes1, ptr_t start2, /* thread stacks. */ #ifndef THREADS -# ifdef EMSCRIPTEN +# if defined(EMSCRIPTEN) && defined(EMSCRIPTEN_ASYNCIFY) # include <emscripten.h> static void scan_regs_cb(void *begin, void *end) @@ -2824,8 +2824,7 @@ GC_INNER void GC_unmap_gap(ptr_t start1, size_t bytes1, ptr_t start2, STATIC void GC_CALLBACK GC_default_push_other_roots(void) { - /* This needs "-s ASYNCIFY -s ASYNCIFY_STACK_SIZE=128000" */ - /* but hopefully the latter is only required for gctest. */ + /* Note: this needs -sASYNCIFY linker flag. */ emscripten_scan_registers(scan_regs_cb); } |