Skip to content

Commit f51d311

Browse files
committed
Make const-expr evaluation async
This commit is extracted from bytecodealliance#11430 to accurately reflect how const-expr evaluation is an async operation due to GC pauses that may happen. The changes in this commit are: * Const-expr evaluation is, at its core, now an `async` function. * To leverage this new `async`-ness all internal operations are switched from `*_maybe_async` to `*_async` meaning all the `*_maybe_async` methods can be removed. * Some libcalls using `*_maybe_async` are switch to using `*_async` plus the `block_on!` utility to help jettison more `*_maybe_async` methods. * Instance initialization is now an `async` function. This is temporarily handled with `block_on` during instance initialization to avoid propagating the `async`-ness further upwards. This `block_on` will get deleted in future refactorings. * Const-expr evaluation has been refactored slightly to enable having a fast path in global initialization which skips an `await` point entirely, achieving performance-parity in benchmarks prior to this commit. This ended up fixing a niche issue with GC where if a wasm execution was suspended during `table.init`, for example, during a const-expr evaluation triggering a GC then if the wasm execution was cancelled it would panic the host. This panic was because the GC operation returned `Result` but it was `unwrap`'d as part of the const-expr evaluation which can fail not only to invalid-ness but also due to "computation is cancelled" traps.
1 parent bb7ec8e commit f51d311

1 file changed

Lines changed: 18 additions & 38 deletions

File tree

crates/wasmtime/src/runtime/vm/instance/allocator.rs

Lines changed: 18 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -387,48 +387,28 @@ impl dyn InstanceAllocator + '_ {
387387
self.increment_core_instance_count()?;
388388

389389
let num_defined_memories = module.num_defined_memories();
390-
let num_defined_tables = module.num_defined_tables();
391-
392-
let mut guard = DeallocateOnDrop {
393-
run_deallocate: true,
394-
memories: PrimaryMap::with_capacity(num_defined_memories),
395-
tables: PrimaryMap::with_capacity(num_defined_tables),
396-
allocator: self,
397-
};
398-
399-
self.allocate_memories(&mut request, &mut guard.memories)?;
400-
self.allocate_tables(&mut request, &mut guard.tables)?;
401-
guard.run_deallocate = false;
402-
// SAFETY: memories/tables were just allocated from the store within
403-
// `request` and this function's own contract requires that the
404-
// imports are valid.
405-
return unsafe {
406-
Ok(Instance::new(
407-
request,
408-
mem::take(&mut guard.memories),
409-
mem::take(&mut guard.tables),
410-
&module.memories,
411-
))
412-
};
413-
414-
struct DeallocateOnDrop<'a> {
415-
run_deallocate: bool,
416-
memories: PrimaryMap<DefinedMemoryIndex, (MemoryAllocationIndex, Memory)>,
417-
tables: PrimaryMap<DefinedTableIndex, (TableAllocationIndex, Table)>,
418-
allocator: &'a (dyn InstanceAllocator + 'a),
419-
}
390+
let mut memories = PrimaryMap::with_capacity(num_defined_memories);
420391

421-
impl Drop for DeallocateOnDrop<'_> {
422-
fn drop(&mut self) {
423-
if !self.run_deallocate {
424-
return;
425-
}
392+
let num_defined_tables = module.num_defined_tables();
393+
let mut tables = PrimaryMap::with_capacity(num_defined_tables);
394+
395+
match (|| {
396+
self.allocate_memories(&mut request, &mut memories)?;
397+
self.allocate_tables(&mut request, &mut tables)?;
398+
Ok(())
399+
})() {
400+
// SAFETY: memories/tables were just allocated from the store within
401+
// `request` and this function's own contract requires that the
402+
// imports are valid.
403+
Ok(_) => unsafe { Ok(Instance::new(request, memories, tables, &module.memories)) },
404+
Err(e) => {
426405
// SAFETY: these were previously allocated by this allocator
427406
unsafe {
428-
self.allocator.deallocate_memories(&mut self.memories);
429-
self.allocator.deallocate_tables(&mut self.tables);
407+
self.deallocate_memories(&mut memories);
408+
self.deallocate_tables(&mut tables);
430409
}
431-
self.allocator.decrement_core_instance_count();
410+
self.decrement_core_instance_count();
411+
Err(e)
432412
}
433413
}
434414
}

0 commit comments

Comments
 (0)