Skip to content

Commit 6f3ee6b

Browse files
authored
Try #2012:
2 parents 98cf81c + 1fc405b commit 6f3ee6b

File tree

2 files changed

+42
-5
lines changed

2 files changed

+42
-5
lines changed

lib/compiler-singlepass/src/emitter_x64.rs

+4
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ pub trait Emitter {
117117
fn emit_xchg(&mut self, sz: Size, src: Location, dst: Location);
118118
fn emit_lock_xadd(&mut self, sz: Size, src: Location, dst: Location);
119119
fn emit_lock_cmpxchg(&mut self, sz: Size, src: Location, dst: Location);
120+
fn emit_rep_stosq(&mut self);
120121

121122
fn emit_btc_gpr_imm8_32(&mut self, src: u8, dst: GPR);
122123
fn emit_btc_gpr_imm8_64(&mut self, src: u8, dst: GPR);
@@ -1176,6 +1177,9 @@ impl Emitter for Assembler {
11761177
}
11771178
}
11781179

1180+
fn emit_rep_stosq(&mut self) {
1181+
dynasm!(self ; rep stosq);
1182+
}
11791183
fn emit_btc_gpr_imm8_32(&mut self, src: u8, dst: GPR) {
11801184
dynasm!(self ; btc Rd(dst as u8), BYTE src as i8);
11811185
}

lib/compiler-singlepass/src/machine.rs

+38-5
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ use crate::emitter_x64::*;
33
use crate::x64_decl::{new_machine_state, X64Register};
44
use smallvec::smallvec;
55
use smallvec::SmallVec;
6+
use std::cmp;
67
use std::collections::HashSet;
78
use wasmer_compiler::wasmparser::Type as WpType;
89

10+
const NATIVE_PAGE_SIZE: usize = 4096;
11+
912
struct MachineStackOffset(usize);
1013

1114
pub struct Machine {
@@ -447,18 +450,48 @@ impl Machine {
447450
}
448451
}
449452

450-
// Initialize all normal locals to zero.
451-
for i in n_params..n {
452-
a.emit_mov(Size::S64, Location::Imm32(0), locations[i]);
453-
}
454-
455453
// Load vmctx into R15.
456454
a.emit_mov(
457455
Size::S64,
458456
Self::get_param_location(0),
459457
Location::GPR(GPR::R15),
460458
);
461459

460+
// Stack probe.
461+
//
462+
// `rep stosq` writes data from low address to high address and may skip the stack guard page.
463+
// so here we probe it explicitly when needed.
464+
for i in (n_params..n).step_by(NATIVE_PAGE_SIZE / 8).skip(1) {
465+
a.emit_mov(Size::S64, Location::Imm32(0), locations[i]);
466+
}
467+
468+
//Initialize all normal locals to zero.
469+
let mut init_stack_loc_cnt = 0;
470+
let mut last_stack_loc = Location::Memory(GPR::RBP, i32::MAX);
471+
for i in n_params..n {
472+
match locations[i] {
473+
Location::Memory(_, _) => {
474+
init_stack_loc_cnt += 1;
475+
last_stack_loc = cmp::min(last_stack_loc, locations[i]);
476+
}
477+
Location::GPR(_) => {
478+
a.emit_mov(Size::S64, Location::Imm32(0), locations[i]);
479+
}
480+
_ => unreachable!(),
481+
}
482+
}
483+
if init_stack_loc_cnt > 0 {
484+
// Since this assemblies takes up 24 bytes, If initialize more than 2 slots, These assemblies are smallar.
485+
a.emit_mov(
486+
Size::S64,
487+
Location::Imm64(init_stack_loc_cnt as u64),
488+
Location::GPR(GPR::RCX),
489+
);
490+
a.emit_xor(Size::S64, Location::GPR(GPR::RAX), Location::GPR(GPR::RAX));
491+
a.emit_lea(Size::S64, last_stack_loc, Location::GPR(GPR::RDI));
492+
a.emit_rep_stosq();
493+
}
494+
462495
// Add the size of all locals allocated to stack.
463496
self.stack_offset.0 += static_area_size - callee_saved_regs_size;
464497

0 commit comments

Comments
 (0)