diff options
author | Yuta Saito <[email protected]> | 2022-01-27 21:33:39 +0900 |
---|---|---|
committer | Yuta Saito <[email protected]> | 2022-02-18 18:28:18 +0900 |
commit | dff70b50d01930213e7799ee52969ff309cc3601 () | |
tree | b01dc7fbfb0875d6b513f4c141e0d3c05f060095 /wasm | |
parent | ac32b7023a7743b1f0cdcfe11156c95c0edb7c54 (diff) |
[wasm] vm.c: stop unwinding to main for every vm_exec call by setjmp
the original rb_wasm_setjmp implementation always unwinds to the root call frame to have setjmp compatible interface, and simulate sjlj's undefined behavior. Therefore, every vm_exec call unwinds to main, and a deep call stack makes setjmp call very expensive. The following snippet from optcarrot takes 5s even though it takes less than 0.3s on native. ``` [0x0, 0x4, 0x8, 0xc].map do |attr| (0..7).map do |j| (0...0x10000).map do |i| clr = i[15 - j] * 2 + i[7 - j] clr != 0 ? attr | clr : 0 end end end ``` This adds a WASI specialized vm_exec which uses lightweight try-catch API without unwinding to the root frame. After this , the above snippet takes only 0.5s.
Notes: Merged: https://.com/ruby/ruby/pull/5502
-rw-r--r-- | wasm/asyncify.h | 10 | ||||
-rw-r--r-- | wasm/setjmp.c | 70 | ||||
-rw-r--r-- | wasm/setjmp.h | 34 |
3 files changed, 114 insertions, 0 deletions
@@ -3,8 +3,18 @@ __attribute__((import_module("asyncify"), import_name("start_unwind"))) void asyncify_start_unwind(void *buf); __attribute__((import_module("asyncify"), import_name("stop_unwind"))) void asyncify_stop_unwind(void); __attribute__((import_module("asyncify"), import_name("start_rewind"))) void asyncify_start_rewind(void *buf); __attribute__((import_module("asyncify"), import_name("stop_rewind"))) @@ -57,6 +57,7 @@ async_buf_init(struct __rb_wasm_asyncify_jmp_buf* buf) // Global unwinding/rewinding jmpbuf state static rb_wasm_jmp_buf *_rb_wasm_active_jmpbuf; __attribute__((noinline)) int @@ -106,6 +107,75 @@ _rb_wasm_longjmp(rb_wasm_jmp_buf* env, int value) asyncify_start_unwind(&env->longjmp_buf); } void * rb_wasm_handle_jmp_unwind(void) { @@ -58,4 +58,38 @@ typedef rb_wasm_jmp_buf jmp_buf; #define setjmp(env) rb_wasm_setjmp(env) #define longjmp(env, payload) rb_wasm_longjmp(env, payload) #endif |