From d34f7ff2db44433fcdaa84039ac0911f59378c1d Mon Sep 17 00:00:00 2001 From: "Ben L. Titzer" Date: Wed, 18 Oct 2023 12:23:27 -0400 Subject: [PATCH] [exception-handling] Implement TRY_TABLE in x86-64 fast int and JIT (as nop) --- src/engine/compiler/SinglePassCompiler.v3 | 8 ++++++++ src/engine/x86-64/X86_64Interpreter.v3 | 21 ++++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/engine/compiler/SinglePassCompiler.v3 b/src/engine/compiler/SinglePassCompiler.v3 index 7f61f37b..a5b8de88 100644 --- a/src/engine/compiler/SinglePassCompiler.v3 +++ b/src/engine/compiler/SinglePassCompiler.v3 @@ -388,6 +388,10 @@ class SinglePassCompiler(xenv: SpcExecEnv, masm: MacroAssembler, regAlloc: RegAl ctl_top.opcode = Opcode.ELSE.code; emitProbe(); } + def visit_TRY(btc: BlockTypeCode) { + var pr = btc.toAbstractBlockType(module); + state.pushBlock(pr.0, pr.1, masm.newLabel(it.pc)); + } def visit_END() { var ctl_top = state.ctl_stack.peek(); if (ctl_top.opcode == Opcode.LOOP.code) { @@ -626,6 +630,10 @@ class SinglePassCompiler(xenv: SpcExecEnv, masm: MacroAssembler, regAlloc: RegAl def visit_SELECT_T(val_types: Range) { emitSelect(u32.!(val_types.length)); } + def visit_TRY_TABLE(btc: BlockTypeCode, catches: Range) { + var pr = btc.toAbstractBlockType(module); + state.pushBlock(pr.0, pr.1, masm.newLabel(it.pc)); + } def emitSelect(valcount: u32) { var sv = pop(); var base: u32 = state.sp - valcount*2; diff --git a/src/engine/x86-64/X86_64Interpreter.v3 b/src/engine/x86-64/X86_64Interpreter.v3 index 5b99750b..411f5191 100644 --- a/src/engine/x86-64/X86_64Interpreter.v3 +++ b/src/engine/x86-64/X86_64Interpreter.v3 @@ -883,6 +883,25 @@ class X86_64InterpreterGen(ic: X86_64InterpreterCode, w: DataWriter) { asm.bind(label); endHandler(); } + bindHandler(Opcode.TRY_TABLE); { // XXX: speed up with sidetable entry to skip immediates? + genSkipBlockType(); + var countGpr = r_tmp0, kindGpr = r_tmp1, tagGpr = r_tmp2; + genReadUleb32(countGpr); + var start = X86_64Label.new(), done = X86_64Label.new(), catch_all = X86_64Label.new(); + asm.bind(start); + asm.d.dec_r(countGpr); // while (--count >= 0) { + asm.jc_rel_near(C.A, done); + asm.movb_r_m(kindGpr, m_ip); // kind = *rip++; + asm.inc_r(r_ip); + genSkipLeb(); // skip LEB (tag or label) + asm.test_r_i(kindGpr, 0x02); // if (kind & 0x2 == 1), is catch_all + asm.jc_rel_near(C.NZ, catch_all); + genSkipLeb(); // skip label + asm.bind(catch_all); + asm.jmp_rel_near(start); + asm.bind(done); + endHandler(); + } } def genLoopTierUpTrigger() { // In multi-tier mode with OSR, the loop bytecode decrements {FuncDecl.tierup_trigger}. @@ -2550,7 +2569,7 @@ class X86_64InterpreterGen(ic: X86_64InterpreterCode, w: DataWriter) { genSimdBinopCommute(Opcode.I16X8_LT_U, masm.emit_i16x8_gt_u(_, _, r_xmm2)); genSimdBinopCommute(Opcode.I32X4_LT_U, masm.emit_i32x4_gt_u(_, _, r_xmm2)); - // todo: factor out this loop + // TODO: factor out this loop for (t in [ (Opcode.I8X16_NEG, masm.emit_i8x16_neg), (Opcode.I16X8_NEG, masm.emit_i16x8_neg),