Fix and enable GC on new x64 backend.

One critical bit of plumbing was missing: the `StackMapSink` passed to
`compile_and_emit` was not actually receiving stackmaps. This seemingly
very basic issue was not caught because the other major user of reftype
support, SpiderMonkey, extracts stackmaps with a lower-level API. The
SM integration was built this way to avoid an awkward API quirk when
passing stackmaps through a `CodeSink` that proxies them to a
`StackMapSink`: the `CodeSink` wants `Value`s for each reference slot,
while the actual `StackMapSink` does not require these. This PR tweaks
the plumbing in a slightly different way to make `wasmtime` GC tests,
and presumably other consumers of stack-map info from the top-level
Cranelift interface, happy.
This commit is contained in:
Chris Fallin
2020-11-12 16:55:18 -08:00
parent c19762d5c2
commit 01b60e81b0
2 changed files with 15 additions and 5 deletions

View File

@@ -22,7 +22,7 @@ use crate::legalize_function;
use crate::legalizer::simple_legalize; use crate::legalizer::simple_legalize;
use crate::licm::do_licm; use crate::licm::do_licm;
use crate::loop_analysis::LoopAnalysis; use crate::loop_analysis::LoopAnalysis;
use crate::machinst::MachCompileResult; use crate::machinst::{MachCompileResult, MachStackMap};
use crate::nan_canonicalization::do_nan_canonicalization; use crate::nan_canonicalization::do_nan_canonicalization;
use crate::postopt::do_postopt; use crate::postopt::do_postopt;
use crate::redundant_reload_remover::RedundantReloadRemover; use crate::redundant_reload_remover::RedundantReloadRemover;
@@ -239,10 +239,23 @@ impl Context {
let mut sink = MemoryCodeSink::new(mem, relocs, traps, stack_maps); let mut sink = MemoryCodeSink::new(mem, relocs, traps, stack_maps);
if let Some(ref result) = &self.mach_compile_result { if let Some(ref result) = &self.mach_compile_result {
result.buffer.emit(&mut sink); result.buffer.emit(&mut sink);
let info = sink.info;
// New backends do not emit StackMaps through the `CodeSink` because its interface
// requires `Value`s; instead, the `StackMap` objects are directly accessible via
// `result.buffer.stack_maps()`.
for &MachStackMap {
offset_end,
ref stack_map,
..
} in result.buffer.stack_maps()
{
stack_maps.add_stack_map(offset_end, stack_map.clone());
}
info
} else { } else {
isa.emit_function_to_memory(&self.func, &mut sink); isa.emit_function_to_memory(&self.func, &mut sink);
sink.info
} }
sink.info
} }
/// Creates unwind information for the function. /// Creates unwind information for the function.

View File

@@ -24,7 +24,6 @@ impl Drop for GcOnDrop {
} }
#[test] #[test]
#[cfg_attr(feature = "experimental_x64", ignore)] // TODO #2079 investigate.
fn smoke_test_gc() -> anyhow::Result<()> { fn smoke_test_gc() -> anyhow::Result<()> {
let (store, module) = ref_types_module( let (store, module) = ref_types_module(
r#" r#"
@@ -121,7 +120,6 @@ fn wasm_dropping_refs() -> anyhow::Result<()> {
} }
#[test] #[test]
#[cfg_attr(feature = "experimental_x64", ignore)] // TODO #2079 investigate.
fn many_live_refs() -> anyhow::Result<()> { fn many_live_refs() -> anyhow::Result<()> {
let mut wat = r#" let mut wat = r#"
(module (module
@@ -375,7 +373,6 @@ fn gc_during_gc_when_passing_refs_into_wasm() -> anyhow::Result<()> {
} }
#[test] #[test]
#[cfg_attr(feature = "experimental_x64", ignore)] // TODO #2079 investigate.
fn gc_during_gc_from_many_table_gets() -> anyhow::Result<()> { fn gc_during_gc_from_many_table_gets() -> anyhow::Result<()> {
let (store, module) = ref_types_module( let (store, module) = ref_types_module(
r#" r#"