Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 99 additions & 0 deletions crates/cranelift/src/alias_region.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ enum VmType {
VMContext,
VMStoreContext,
VMMemoryDefinition,
VMTableDefinition,
}

/// A key that uniquely identifies an alias region across an entire compilation.
Expand Down Expand Up @@ -103,6 +104,7 @@ impl AliasRegionKey {
const DEFINED_GLOBAL_KIND: u32 = Self::new_kind(0b0111);
const GC_HEAP_KIND: u32 = Self::new_kind(0b1000);
const VM_MEMORY_DEFINITION_KIND: u32 = Self::new_kind(0b1001);
const VM_TABLE_DEFINITION_KIND: u32 = Self::new_kind(0b1010);

/// Encode this key into a raw `u32` suitable for use as an
/// `AliasRegionData::user_id`.
Expand All @@ -114,6 +116,7 @@ impl AliasRegionKey {
VmType::VMContext => Self::VM_CONTEXT_KIND,
VmType::VMStoreContext => Self::VM_STORE_CONTEXT_KIND,
VmType::VMMemoryDefinition => Self::VM_MEMORY_DEFINITION_KIND,
VmType::VMTableDefinition => Self::VM_TABLE_DEFINITION_KIND,
};
kind | (offset & Self::OFFSET_MASK)
}
Expand Down Expand Up @@ -788,6 +791,102 @@ impl AliasRegions<VMOffsets<u8>> {
self.vmctx_vmmemory_definition_current_length_load(cursor.func, memory)
.emit(cursor, vmctx)
}

fn vmtable_definition_region(
&mut self,
func: &mut ir::Function,
offset: u32,
) -> ir::AliasRegion {
self.region(
func,
AliasRegionKey::Vm {
ty: VmType::VMTableDefinition,
offset,
},
)
}

/// Get a `Load` for an inlined-in-the-`vmctx` `VMTableDefinition`'s `base`
/// field.
pub fn vmctx_vmtable_definition_base_load(
&mut self,
func: &mut ir::Function,
table: DefinedTableIndex,
base_flags: ir::MemFlagsData,
) -> Load {
// NB: The region is keyed on the field's offset within the
// `VMTableDefinition`, not the `vmctx`, so that defined
// (`vmctx`-inlined) and imported (via-pointer) tables share one region
// per field.
let field = self.offsets.vmtable_definition_base();
let region = self.vmtable_definition_region(func, field.into());

Load {
offset: self.offsets.vmctx_vmtable_definition_base(table),
flags: base_flags.with_alias_region(Some(region)),
ty: self.pointer_type,
}
}

/// Get a `Load` for an inlined-in-the-`vmctx` `VMTableDefinition`'s
/// `current_elements` field.
///
/// The caller supplies `ty` because the field's width depends on the table
/// elements' type.
pub fn vmctx_vmtable_definition_current_elements_load(
&mut self,
func: &mut ir::Function,
table: DefinedTableIndex,
ty: ir::Type,
) -> Load {
// See note in `vmctx_vmtable_definition_base_load`.
let field = self.offsets.vmtable_definition_current_elements();
let region = self.vmtable_definition_region(func, field.into());

Load {
offset: self
.offsets
.vmctx_vmtable_definition_current_elements(table),
flags: ir::MemFlagsData::trusted().with_alias_region(Some(region)),
ty,
}
}

/// Get a `Load` for the `VMTableDefinition::base` field reached through a
/// `*mut VMTableDefinition` (an imported table), for use in a
/// `VmctxLoadChain`.
pub fn vmtable_definition_base_load(
&mut self,
func: &mut ir::Function,
base_flags: ir::MemFlagsData,
) -> Load {
let offset = self.offsets.vmtable_definition_base().into();
let region = self.vmtable_definition_region(func, offset);
Load {
offset,
flags: base_flags.with_alias_region(Some(region)),
ty: self.pointer_type,
}
}

/// Get a `Load` for the `VMTableDefinition::current_elements` field reached
/// through a `*mut VMTableDefinition` (an imported table).
///
/// The caller supplies `ty` because the field's width depends on the table
/// elements' type.
pub fn vmtable_definition_current_elements_load(
&mut self,
func: &mut ir::Function,
ty: ir::Type,
) -> Load {
let offset = self.offsets.vmtable_definition_current_elements().into();
let region = self.vmtable_definition_region(func, offset);
Load {
offset,
flags: ir::MemFlagsData::trusted().with_alias_region(Some(region)),
ty,
}
}
}

/// `VMStoreContext`-related methods.
Expand Down
84 changes: 38 additions & 46 deletions crates/cranelift/src/func_environ.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub(crate) mod stack_switching;
use crate::alias_region::AliasRegions;
use crate::compiler::Compiler;
use crate::translate::{
FuncTranslationStacks, Heap, HeapData, Load, MemoryKind, StructFieldsVec, TableData, TableSize,
FuncTranslationStacks, Heap, HeapData, MemoryKind, StructFieldsVec, TableData, TableSize,
TargetEnvironment, VmctxLoadChain,
};
use crate::trap::TranslateTrap;
Expand Down Expand Up @@ -1653,7 +1653,6 @@ impl FuncEnvironment<'_> {
func: &mut ir::Function,
index: TableIndex,
) -> (VmctxLoadChain, TableSize) {
let pointer_type = self.pointer_type();
let table = self.module.tables[index];
let bound_ty = ir::Type::int(
u16::from(self.offsets.size_of_vmtable_definition_current_elements()) * 8,
Expand All @@ -1668,58 +1667,51 @@ impl FuncEnvironment<'_> {
base_flags = base_flags.with_readonly().with_can_move();
}

let base = |from: Option<Load>, offset| {
VmctxLoadChain::new(
from.into_iter()
.chain(std::iter::once(Load {
offset,
flags: base_flags,
ty: pointer_type,
}))
.collect(),
)
};
let bound = |from: Option<Load>, offset| {
if is_static {
if let Some(def_index) = self.module.defined_table_index(index) {
// A defined table's `VMTableDefinition` is inlined into the vmctx,
// reached at an absolute `vmctx` offset.
let base = VmctxLoadChain::new(smallvec![
self.alias_regions
.vmctx_vmtable_definition_base_load(func, def_index, base_flags)
]);
let bound = if is_static {
TableSize::Static {
bound: table.limits.min,
}
} else {
TableSize::Dynamic {
bound: VmctxLoadChain::new(
from.into_iter()
.chain(std::iter::once(Load {
offset,
flags: ir::MemFlagsData::trusted(),
ty: bound_ty,
}))
.collect(),
),
bound: VmctxLoadChain::new(smallvec![
self.alias_regions
.vmctx_vmtable_definition_current_elements_load(
func, def_index, bound_ty
)
]),
}
}
};

if let Some(def_index) = self.module.defined_table_index(index) {
(
base(None, self.offsets.vmctx_vmtable_definition_base(def_index)),
bound(
None,
self.offsets
.vmctx_vmtable_definition_current_elements(def_index),
),
)
};
(base, bound)
} else {
// An imported table is reached through a `*mut VMTableDefinition`
// loaded from the `vmctx`.
let from = self.alias_regions.vmctx_vmtable_from_load(func, index);
(
base(
Some(from),
u32::from(self.offsets.vmtable_definition_base()),
),
bound(
Some(from),
u32::from(self.offsets.vmtable_definition_current_elements()),
),
)
let base = VmctxLoadChain::new(smallvec![
from,
self.alias_regions
.vmtable_definition_base_load(func, base_flags),
]);
let bound = if is_static {
TableSize::Static {
bound: table.limits.min,
}
} else {
TableSize::Dynamic {
bound: VmctxLoadChain::new(smallvec![
from,
self.alias_regions
.vmtable_definition_current_elements_load(func, bound_ty),
]),
}
};
(base, bound)
}
}

Expand Down
22 changes: 12 additions & 10 deletions tests/disas/alias-region-tables.wat
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@
;; region0 = 8 "VMContext+0x8"
;; region1 = 268435480 "VMStoreContext+0x18"
;; region2 = 48 "VMContext+0x30"
;; region3 = 1073741824 "PublicTable"
;; region4 = 1342177280 "DefinedTable(StaticModuleIndex(0), DefinedTableIndex(0))"
;; region5 = 40 "VMContext+0x28"
;; region3 = 2684354560 "VMTableDefinition+0x0"
;; region4 = 2684354568 "VMTableDefinition+0x8"
;; region5 = 1073741824 "PublicTable"
;; region6 = 1342177280 "DefinedTable(StaticModuleIndex(0), DefinedTableIndex(0))"
;; region7 = 40 "VMContext+0x28"
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly can_move region0 gv0+8
;; gv2 = load.i64 notrap aligned region1 gv1+24
Expand All @@ -32,8 +34,8 @@
;;
;; block0(v0: i64, v1: i64, v2: i32, v3: i64):
;; @0043 v5 = load.i64 notrap aligned readonly can_move region2 v0+48
;; @0043 v6 = load.i64 notrap aligned v5+8
;; @0043 v11 = load.i64 notrap aligned v5
;; @0043 v6 = load.i64 notrap aligned region4 v5+8
;; @0043 v11 = load.i64 notrap aligned region3 v5
;; @0043 v17 = iconst.i64 1
;; @0043 v18 = bor v3, v17 ; v17 = 1
;; @0043 v7 = ireduce.i32 v6
Expand All @@ -44,14 +46,14 @@
;; @0043 v13 = ishl v9, v12 ; v12 = 3
;; @0043 v14 = iadd v11, v13
;; @0043 v16 = select_spectre_guard v8, v15, v14 ; v15 = 0
;; @0043 store user6 aligned region3 v18, v16
;; @0049 v19 = load.i64 notrap aligned v0+80
;; @0049 v23 = load.i64 notrap aligned v0+72
;; @0043 store user6 aligned region5 v18, v16
;; @0049 v19 = load.i64 notrap aligned region4 v0+80
;; @0049 v23 = load.i64 notrap aligned region3 v0+72
;; @0049 v20 = ireduce.i32 v19
;; @0049 v21 = icmp uge v2, v20
;; @0049 v26 = iadd v23, v13
;; @0049 v28 = select_spectre_guard v21, v15, v26 ; v15 = 0
;; @0049 store user6 aligned region4 v18, v28
;; @0049 store user6 aligned region6 v18, v28
;; @004d v44 = iconst.i64 -2
;; @004d v45 = band v18, v44 ; v44 = -2
;; @004d brif v18, block3(v45), block2
Expand All @@ -63,7 +65,7 @@
;;
;; block3(v46: i64):
;; @004d v52 = load.i32 user7 aligned readonly v46+16
;; @004d v50 = load.i64 notrap aligned readonly can_move region5 v0+40
;; @004d v50 = load.i64 notrap aligned readonly can_move region7 v0+40
;; @004d v51 = load.i32 notrap aligned readonly can_move v50
;; @004d v53 = icmp eq v52, v51
;; @004d trapz v53, user8
Expand Down
14 changes: 8 additions & 6 deletions tests/disas/call-indirect-with-gc.wat
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
;; function u0:0(i64 vmctx, i64, i32, i32) -> i32 tail {
;; region0 = 8 "VMContext+0x8"
;; region1 = 268435480 "VMStoreContext+0x18"
;; region2 = 1073741824 "PublicTable"
;; region3 = 40 "VMContext+0x28"
;; region2 = 2684354560 "VMTableDefinition+0x0"
;; region3 = 2684354568 "VMTableDefinition+0x8"
;; region4 = 1073741824 "PublicTable"
;; region5 = 40 "VMContext+0x28"
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly can_move region0 gv0+8
;; gv2 = load.i64 notrap aligned region1 gv1+24
Expand All @@ -23,8 +25,8 @@
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64, v2: i32, v3: i32):
;; @0035 v5 = load.i64 notrap aligned v0+56
;; @0035 v9 = load.i64 notrap aligned v0+48
;; @0035 v5 = load.i64 notrap aligned region3 v0+56
;; @0035 v9 = load.i64 notrap aligned region2 v0+48
;; @0035 v6 = ireduce.i32 v5
;; @0035 v7 = icmp uge v3, v6
;; @0035 v13 = iconst.i64 0
Expand All @@ -33,7 +35,7 @@
;; @0035 v11 = ishl v8, v10 ; v10 = 3
;; @0035 v12 = iadd v9, v11
;; @0035 v14 = select_spectre_guard v7, v13, v12 ; v13 = 0
;; @0035 v15 = load.i64 user6 aligned region2 v14
;; @0035 v15 = load.i64 user6 aligned region4 v14
;; @0035 v16 = iconst.i64 -2
;; @0035 v17 = band v15, v16 ; v16 = -2
;; @0035 brif v15, block3(v17), block2
Expand All @@ -45,7 +47,7 @@
;;
;; block3(v18: i64):
;; @0035 v24 = load.i32 user7 aligned readonly v18+16
;; @0035 v22 = load.i64 notrap aligned readonly can_move region3 v0+40
;; @0035 v22 = load.i64 notrap aligned readonly can_move region5 v0+40
;; @0035 v23 = load.i32 notrap aligned readonly can_move v22+4
;; @0035 v25 = icmp eq v24, v23
;; @0035 trapz v25, user8
Expand Down
14 changes: 8 additions & 6 deletions tests/disas/call-indirect-without-gc.wat
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
;; function u0:0(i64 vmctx, i64, i32, i32) -> i32 tail {
;; region0 = 8 "VMContext+0x8"
;; region1 = 268435480 "VMStoreContext+0x18"
;; region2 = 1073741824 "PublicTable"
;; region3 = 40 "VMContext+0x28"
;; region2 = 2684354560 "VMTableDefinition+0x0"
;; region3 = 2684354568 "VMTableDefinition+0x8"
;; region4 = 1073741824 "PublicTable"
;; region5 = 40 "VMContext+0x28"
;; gv0 = vmctx
;; gv1 = load.i64 notrap aligned readonly can_move region0 gv0+8
;; gv2 = load.i64 notrap aligned region1 gv1+24
Expand All @@ -23,8 +25,8 @@
;; stack_limit = gv2
;;
;; block0(v0: i64, v1: i64, v2: i32, v3: i32):
;; @0035 v5 = load.i64 notrap aligned v0+56
;; @0035 v9 = load.i64 notrap aligned v0+48
;; @0035 v5 = load.i64 notrap aligned region3 v0+56
;; @0035 v9 = load.i64 notrap aligned region2 v0+48
;; @0035 v6 = ireduce.i32 v5
;; @0035 v7 = icmp uge v3, v6
;; @0035 v13 = iconst.i64 0
Expand All @@ -33,7 +35,7 @@
;; @0035 v11 = ishl v8, v10 ; v10 = 3
;; @0035 v12 = iadd v9, v11
;; @0035 v14 = select_spectre_guard v7, v13, v12 ; v13 = 0
;; @0035 v15 = load.i64 user6 aligned region2 v14
;; @0035 v15 = load.i64 user6 aligned region4 v14
;; @0035 v16 = iconst.i64 -2
;; @0035 v17 = band v15, v16 ; v16 = -2
;; @0035 brif v15, block3(v17), block2
Expand All @@ -45,7 +47,7 @@
;;
;; block3(v18: i64):
;; @0035 v24 = load.i32 user7 aligned readonly v18+16
;; @0035 v22 = load.i64 notrap aligned readonly can_move region3 v0+40
;; @0035 v22 = load.i64 notrap aligned readonly can_move region5 v0+40
;; @0035 v23 = load.i32 notrap aligned readonly can_move v22+4
;; @0035 v25 = icmp eq v24, v23
;; @0035 trapz v25, user8
Expand Down
Loading
Loading