From bf1c4d254beb0e01fac1d9e6cb805de8ec6260eb Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Sat, 15 Jan 2022 23:59:37 +0900 Subject: [PATCH] [wasm] gc.c: scan wasm locals and c stack to mark living objects WebAssembly has function local infinite registers and stack values, but there is no way to scan the values in a call stack for now. This implementation uses Asyncify to spilling out wasm locals into linear memory. --- gc.c | 61 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 40 insertions(+), 21 deletions(-) diff --git a/gc.c b/gc.c index 2fa4eabc41..b87c72a477 100644 --- a/gc.c +++ b/gc.c @@ -30,6 +30,7 @@ #if defined(__wasm__) && !defined(__EMSCRIPTEN__) # include "wasm/setjmp.h" +# include "wasm/machine.h" #else # include #endif @@ -6504,7 +6505,45 @@ mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl) static void each_stack_location(rb_objspace_t *objspace, const rb_execution_context_t *ec, const VALUE *stack_start, const VALUE *stack_end, void (*cb)(rb_objspace_t *, VALUE)); -#ifndef __EMSCRIPTEN__ +#if defined(__wasm__) + + +static VALUE *rb_stack_range_tmp[2]; + +static void +rb_mark_locations(void *begin, void *end) +{ + rb_stack_range_tmp[0] = begin; + rb_stack_range_tmp[1] = end; +} + +# if defined(__EMSCRIPTEN__) + +static void +mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec) +{ + emscripten_scan_stack(rb_mark_locations); + each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], gc_mark_maybe); + + emscripten_scan_registers(rb_mark_locations); + each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], gc_mark_maybe); +} +# else // use Asyncify version + +static void +mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec) +{ + rb_wasm_scan_stack(rb_mark_locations); + each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], gc_mark_maybe); + + rb_wasm_scan_locals(rb_mark_locations); + each_stack_location(objspace, ec, rb_stack_range_tmp[0], rb_stack_range_tmp[1], gc_mark_maybe); +} + +# endif + +#else // !defined(__wasm__) + static void mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec) { @@ -6529,26 +6568,6 @@ mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec each_stack_location(objspace, ec, stack_start, stack_end, gc_mark_maybe); } -#else - -static VALUE *rb_emscripten_stack_range_tmp[2]; - -static void -rb_emscripten_mark_locations(void *begin, void *end) -{ - rb_emscripten_stack_range_tmp[0] = begin; - rb_emscripten_stack_range_tmp[1] = end; -} - -static void -mark_current_machine_context(rb_objspace_t *objspace, rb_execution_context_t *ec) -{ - emscripten_scan_stack(rb_emscripten_mark_locations); - each_stack_location(objspace, ec, rb_emscripten_stack_range_tmp[0], rb_emscripten_stack_range_tmp[1], gc_mark_maybe); - - emscripten_scan_registers(rb_emscripten_mark_locations); - each_stack_location(objspace, ec, rb_emscripten_stack_range_tmp[0], rb_emscripten_stack_range_tmp[1], gc_mark_maybe); -} #endif static void