Skip to content

Commit

Permalink
Save vector/float registers on ARM too.
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Jan 21, 2021
1 parent 2deb23c commit ef39985
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 45 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

22 changes: 15 additions & 7 deletions crates/fiber/src/arch/aarch64.S
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ FUNCTION(wasmtime_fiber_switch):
stp x24, x23, [sp, -16]!
stp x26, x25, [sp, -16]!
stp x28, x27, [sp, -16]!
stp d9, d8, [sp, -16]!
stp d11, d10, [sp, -16]!
stp d13, d12, [sp, -16]!
stp d15, d14, [sp, -16]!

// Load our previously saved stack pointer to resume to, and save off our
// current stack pointer on where to come back to eventually.
Expand All @@ -36,6 +40,10 @@ FUNCTION(wasmtime_fiber_switch):
// Switch to the new stack and restore all our callee-saved registers after
// the switch and return to our new stack.
mov sp, x8
ldp d15, d14, [sp], 16
ldp d13, d12, [sp], 16
ldp d11, d10, [sp], 16
ldp d9, d8, [sp], 16
ldp x28, x27, [sp], 16
ldp x26, x25, [sp], 16
ldp x24, x23, [sp], 16
Expand All @@ -58,9 +66,9 @@ FUNCTION(wasmtime_fiber_init):
stp x0, x8, [x0, -0x28] // x0 => x19, x8 => lr
stp x2, x1, [x0, -0x38] // x1 => x20, x2 => x21

// `wasmtime_fiber_switch` has an 0x60 byte stack, and we add 0x10 more for
// `wasmtime_fiber_switch` has an 0xa0 byte stack, and we add 0x10 more for
// the original reserved 16 bytes.
add x8, x0, -0x70
add x8, x0, -0xb0
str x8, [x0, -0x10]
ret
SIZE(wasmtime_fiber_init)
Expand All @@ -73,11 +81,11 @@ FUNCTION(wasmtime_fiber_start):
// See the x86_64 file for more commentary on what these CFI directives are
// doing. Like over there note that the relative offsets to registers here
// match the frame layout in `wasmtime_fiber_switch`.
.cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \
4, /* the byte length of this expression */ \
0x6f, /* DW_OP_reg31(%sp) */ \
0x06, /* DW_OP_deref */ \
0x23, 0x60 /* DW_OP_plus_uconst 0x60 */
.cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \
5, /* the byte length of this expression */ \
0x6f, /* DW_OP_reg31(%sp) */ \
0x06, /* DW_OP_deref */ \
0x23, 0xa0, 0x1 /* DW_OP_plus_uconst 0xa0 */

.cfi_rel_offset lr, -0x10
.cfi_rel_offset x19, -0x18
Expand Down
8 changes: 4 additions & 4 deletions crates/fiber/src/arch/x86_64.S
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,10 @@ FUNCTION(wasmtime_fiber_start):
// the return address of the caller's `call` instruction. Hence we offset
// another 0x38 bytes.
.cfi_escape 0x0f, /* DW_CFA_def_cfa_expression */ \
5, /* the byte length of this expression */ \
0x77, 0x18, /* DW_OP_breg7 (%rsp) + 0x18 */ \
0x06, /* DW_OP_deref */ \
0x23, 0x38 /* DW_OP_plus_uconst 0x38 */
5, /* the byte length of this expression */ \
0x77, 0x18, /* DW_OP_breg7 (%rsp) + 0x18 */ \
0x06, /* DW_OP_deref */ \
0x23, 0x38 /* DW_OP_plus_uconst 0x38 */

// And now after we've indicated where our CFA is for our parent function,
// we can define that where all of the saved registers are located. This
Expand Down
44 changes: 10 additions & 34 deletions crates/wasmtime/src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ impl Instance {
!store.is_async(),
"cannot instantiate synchronously within an asynchronous store"
);

// NB: this is the same code as `Instance::new_async`. It's intentionally
// small but should be kept in sync (modulo the async bits).
let mut i = Instantiator::new(store, module, imports)?;
loop {
if let Some((instance, items)) = i.step()? {
Expand Down Expand Up @@ -141,16 +144,16 @@ impl Instance {
"cannot instantiate asynchronously within a synchronous store"
);

assert!(
!store.is_async(),
"cannot instantiate synchronously within an asynchronous store"
);
// NB: this is the same code as `Instance::new`. It's intentionally
// small but should be kept in sync (modulo the async bits).
let mut i = Instantiator::new(store, module, imports)?;
loop {
if let Some((instance, items)) = i.step()? {
store
.on_fiber(|| Instantiator::start_raw(&instance))
.await??;
if instance.handle.module().start_func.is_some() {
store
.on_fiber(|| Instantiator::start_raw(&instance))
.await??;
}
if let Some(items) = items {
break Ok(Instance::from_wasmtime(&items, store));
}
Expand All @@ -174,33 +177,6 @@ impl Instance {
ty
}

fn start(&self) -> Result<(), Error> {
let start_func = match self.handle.module().start_func {
Some(func) => func,
None => return Ok(()),
};

let f = match self
.handle
.lookup_by_declaration(&EntityIndex::Function(start_func))
{
wasmtime_runtime::Export::Function(f) => f,
_ => unreachable!(), // valid modules shouldn't hit this
};
let vmctx_ptr = self.handle.vmctx_ptr();
unsafe {
super::func::invoke_wasm_and_catch_traps(vmctx_ptr, self.store(), || {
mem::transmute::<
*const VMFunctionBody,
unsafe extern "C" fn(*mut VMContext, *mut VMContext),
>(f.anyfunc.as_ref().func_ptr.as_ptr())(
f.anyfunc.as_ref().vmctx, vmctx_ptr
)
})?;
}
Ok(())
}

/// Returns the associated [`Store`] that this `Instance` is compiled into.
///
/// This is the [`Store`] that generally serves as a sort of global cache
Expand Down

0 comments on commit ef39985

Please sign in to comment.