From 01b60e81b03b8ea3642c38d9d6ce228e82e20438 Mon Sep 17 00:00:00 2001 From: Chris Fallin Date: Thu, 12 Nov 2020 16:55:18 -0800 Subject: [PATCH] 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. --- cranelift/codegen/src/context.rs | 17 +++++++++++++++-- tests/all/gc.rs | 3 --- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cranelift/codegen/src/context.rs b/cranelift/codegen/src/context.rs index 4eb0c3b127..ef092fb818 100644 --- a/cranelift/codegen/src/context.rs +++ b/cranelift/codegen/src/context.rs @@ -22,7 +22,7 @@ use crate::legalize_function; use crate::legalizer::simple_legalize; use crate::licm::do_licm; use crate::loop_analysis::LoopAnalysis; -use crate::machinst::MachCompileResult; +use crate::machinst::{MachCompileResult, MachStackMap}; use crate::nan_canonicalization::do_nan_canonicalization; use crate::postopt::do_postopt; use crate::redundant_reload_remover::RedundantReloadRemover; @@ -239,10 +239,23 @@ impl Context { let mut sink = MemoryCodeSink::new(mem, relocs, traps, stack_maps); if let Some(ref result) = &self.mach_compile_result { 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 { isa.emit_function_to_memory(&self.func, &mut sink); + sink.info } - sink.info } /// Creates unwind information for the function. diff --git a/tests/all/gc.rs b/tests/all/gc.rs index 0f278cd961..e616b2d0c8 100644 --- a/tests/all/gc.rs +++ b/tests/all/gc.rs @@ -24,7 +24,6 @@ impl Drop for GcOnDrop { } #[test] -#[cfg_attr(feature = "experimental_x64", ignore)] // TODO #2079 investigate. fn smoke_test_gc() -> anyhow::Result<()> { let (store, module) = ref_types_module( r#" @@ -121,7 +120,6 @@ fn wasm_dropping_refs() -> anyhow::Result<()> { } #[test] -#[cfg_attr(feature = "experimental_x64", ignore)] // TODO #2079 investigate. fn many_live_refs() -> anyhow::Result<()> { let mut wat = r#" (module @@ -375,7 +373,6 @@ fn gc_during_gc_when_passing_refs_into_wasm() -> anyhow::Result<()> { } #[test] -#[cfg_attr(feature = "experimental_x64", ignore)] // TODO #2079 investigate. fn gc_during_gc_from_many_table_gets() -> anyhow::Result<()> { let (store, module) = ref_types_module( r#"