Skip to content

Commit

Permalink
Merge #2681
Browse files Browse the repository at this point in the history
2681: fix singlepass slow compilation of many function wasm by using dynasm VecAssembler r=syrusakbary a=ailisp

<!-- 
Prior to submitting a PR, review the CONTRIBUTING.md document for recommendations on how to test:
https://github.com/wasmerio/wasmer/blob/master/CONTRIBUTING.md#pull-requests

-->

# Description
<!-- 
Provide details regarding the change including motivation,
links to related issues, and the context of the PR.
-->

We found in certain benchmark (a wasm with 150_000 no-op functions), compilation is slowed down by dynasmrt's mmapand mprotect syscalls, however, those mmap isn't used in wasmer and can be replaced by simpler VecAssembler. In this [bench](near/wasmer#71) it's a 10x speedup in singlepass backend compilation time.

# Review

- [ ] Add a short description of the change to the CHANGELOG.md file


Co-authored-by: Bo Yao <[email protected]>
  • Loading branch information
bors[bot] and ailisp authored Nov 15, 2021
2 parents 2b104a8 + ff3b459 commit caeb991
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 8 deletions.
12 changes: 7 additions & 5 deletions lib/compiler-singlepass/src/codegen_x64.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::address_map::get_function_address_map;
use crate::{common_decl::*, config::Singlepass, emitter_x64::*, machine::Machine, x64_decl::*};
use dynasmrt::{x64::Assembler, DynamicLabel};
use dynasmrt::{x64::X64Relocation, DynamicLabel, VecAssembler};
use smallvec::{smallvec, SmallVec};
use std::collections::BTreeMap;
use std::iter;
Expand All @@ -22,6 +22,8 @@ use wasmer_types::{
};
use wasmer_vm::{MemoryStyle, TableStyle, TrapCode, VMBuiltinFunctionIndex, VMOffsets};

type Assembler = VecAssembler<X64Relocation>;

/// The singlepass per-function code generator.
pub struct FuncGen<'a> {
// Immutable properties assigned at creation time.
Expand Down Expand Up @@ -1844,7 +1846,7 @@ impl<'a> FuncGen<'a> {
.collect(),
);

let mut assembler = Assembler::new().unwrap();
let mut assembler = Assembler::new(0);
let special_labels = SpecialLabelSet {
integer_division_by_zero: assembler.get_label(),
heap_access_oob: assembler.get_label(),
Expand Down Expand Up @@ -8811,7 +8813,7 @@ pub fn gen_std_trampoline(
sig: &FunctionType,
calling_convention: CallingConvention,
) -> FunctionBody {
let mut a = Assembler::new().unwrap();
let mut a = Assembler::new(0);

// Calculate stack offset.
let mut stack_offset: u32 = 0;
Expand Down Expand Up @@ -8921,7 +8923,7 @@ pub fn gen_std_dynamic_import_trampoline(
sig: &FunctionType,
calling_convention: CallingConvention,
) -> FunctionBody {
let mut a = Assembler::new().unwrap();
let mut a = Assembler::new(0);

// Allocate argument array.
let stack_offset: usize = 16 * std::cmp::max(sig.params().len(), sig.results().len()) + 8; // 16 bytes each + 8 bytes sysv call padding
Expand Down Expand Up @@ -9043,7 +9045,7 @@ pub fn gen_import_call_trampoline(
sig: &FunctionType,
calling_convention: CallingConvention,
) -> CustomSection {
let mut a = Assembler::new().unwrap();
let mut a = Assembler::new(0);

// TODO: ARM entry trampoline is not emitted.

Expand Down
4 changes: 3 additions & 1 deletion lib/compiler-singlepass/src/emitter_x64.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
pub use crate::x64_decl::{GPR, XMM};
use dynasm::dynasm;
use dynasmrt::{x64::Assembler, AssemblyOffset, DynamicLabel, DynasmApi, DynasmLabelApi};
use dynasmrt::{x64::X64Relocation, AssemblyOffset, DynamicLabel, DynasmApi, DynasmLabelApi, VecAssembler};

type Assembler = VecAssembler<X64Relocation>;

/// Force `dynasm!` to use the correct arch (x64) when cross-compiling.
/// `dynasm!` proc-macro tries to auto-detect it by default by looking at the
Expand Down
6 changes: 4 additions & 2 deletions lib/compiler-singlepass/src/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -586,12 +586,14 @@ impl Machine {
#[cfg(test)]
mod test {
use super::*;
use dynasmrt::x64::Assembler;
use dynasmrt::x64::X64Relocation;
use dynasmrt::VecAssembler;
type Assembler = VecAssembler<X64Relocation>;

#[test]
fn test_release_locations_keep_state_nopanic() {
let mut machine = Machine::new();
let mut assembler = Assembler::new().unwrap();
let mut assembler = Assembler::new(0);
let locs = machine.acquire_locations(
&mut assembler,
&(0..10)
Expand Down

0 comments on commit caeb991

Please sign in to comment.