Remove code offsets from Function (#3412)

* Remove code offsets from Function

* Remove reloc_jt and fix wasmtime-cranelift
This commit is contained in:
bjorn3
2021-10-07 15:54:00 +02:00
committed by GitHub
parent fc33700071
commit 2db3b5b9df
13 changed files with 6 additions and 155 deletions

View File

@@ -15,7 +15,7 @@
//! `CodeSink::put*` methods, so the performance impact of the virtual callbacks is less severe.
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
use crate::binemit::stack_map::StackMap;
use crate::ir::{ConstantOffset, ExternalName, JumpTable, Opcode, SourceLoc, TrapCode};
use crate::ir::{ConstantOffset, ExternalName, Opcode, SourceLoc, TrapCode};
use core::ptr::write_unaligned;
/// A `CodeSink` that writes binary machine code directly into memory.
@@ -82,9 +82,6 @@ pub trait RelocSink {
/// Add a relocation referencing a constant.
fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset);
/// Add a relocation referencing a jump table.
fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable);
/// Track a call site whose return address is the given CodeOffset, for the given opcode. Does
/// nothing in general, only useful for certain embedders (SpiderMonkey).
fn add_call_site(&mut self, _: Opcode, _: CodeOffset, _: SourceLoc) {}
@@ -146,11 +143,6 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
self.relocs.reloc_constant(ofs, rel, constant_offset);
}
fn reloc_jt(&mut self, rel: Reloc, jt: JumpTable) {
let ofs = self.offset();
self.relocs.reloc_jt(ofs, rel, jt);
}
fn trap(&mut self, code: TrapCode, srcloc: SourceLoc) {
let ofs = self.offset();
self.traps.trap(ofs, srcloc, code);
@@ -195,7 +187,6 @@ impl RelocSink for NullRelocSink {
) {
}
fn reloc_constant(&mut self, _: CodeOffset, _: Reloc, _: ConstantOffset) {}
fn reloc_jt(&mut self, _: CodeOffset, _: Reloc, _: JumpTable) {}
}
/// A `TrapSink` implementation that does nothing, which is convenient when

View File

@@ -11,10 +11,7 @@ pub use self::memorysink::{
TrapSink,
};
pub use self::stack_map::StackMap;
use crate::ir::{
ConstantOffset, ExternalName, Function, Inst, JumpTable, Opcode, SourceLoc, TrapCode,
};
use crate::isa::TargetIsa;
use crate::ir::{ConstantOffset, ExternalName, Opcode, SourceLoc, TrapCode};
use core::fmt;
#[cfg(feature = "enable-serde")]
use serde::{Deserialize, Serialize};
@@ -153,9 +150,6 @@ pub trait CodeSink {
/// Add a relocation referencing a constant.
fn reloc_constant(&mut self, _: Reloc, _: ConstantOffset);
/// Add a relocation referencing a jump table.
fn reloc_jt(&mut self, _: Reloc, _: JumpTable);
/// Add trap information for the current offset.
fn trap(&mut self, _: TrapCode, _: SourceLoc);
@@ -173,42 +167,3 @@ pub trait CodeSink {
// Default implementation doesn't need to do anything.
}
}
/// Emit a function to `sink`, given an instruction emitter function.
///
/// This function is called from the `TargetIsa::emit_function()` implementations with the
/// appropriate instruction emitter.
pub fn emit_function<CS, EI>(func: &Function, emit_inst: EI, sink: &mut CS, isa: &dyn TargetIsa)
where
CS: CodeSink,
EI: Fn(&Function, Inst, &mut CS, &dyn TargetIsa),
{
for block in func.layout.blocks() {
debug_assert_eq!(func.offsets[block], sink.offset());
for inst in func.layout.block_insts(block) {
emit_inst(func, inst, sink, isa);
}
}
sink.begin_jumptables();
// Output jump tables.
for (jt, jt_data) in func.jump_tables.iter() {
let jt_offset = func.jt_offsets[jt];
for block in jt_data.iter() {
let rel_offset: i32 = func.offsets[*block] as i32 - jt_offset as i32;
sink.put4(rel_offset as u32)
}
}
sink.begin_rodata();
// Output constants.
for (_, constant_data) in func.dfg.constants.iter() {
for byte in constant_data.iter() {
sink.put1(*byte)
}
}
sink.end_codegen();
}

View File

@@ -5,20 +5,19 @@
use crate::entity::{PrimaryMap, SecondaryMap};
use crate::ir;
use crate::ir::JumpTables;
use crate::ir::{
instructions::BranchInfo, Block, ExtFuncData, FuncRef, GlobalValue, GlobalValueData, Heap,
HeapData, Inst, InstructionData, JumpTable, JumpTableData, Opcode, SigRef, StackSlot,
StackSlotData, Table, TableData,
};
use crate::ir::{BlockOffsets, SourceLocs, StackSlots};
use crate::ir::{DataFlowGraph, ExternalName, Layout, Signature};
use crate::ir::{JumpTableOffsets, JumpTables};
use crate::ir::{SourceLocs, StackSlots};
use crate::isa::CallConv;
use crate::value_label::ValueLabelsRanges;
use crate::write::write_function;
#[cfg(feature = "enable-serde")]
use alloc::string::String;
use alloc::vec::Vec;
use core::fmt;
#[cfg(feature = "enable-serde")]
@@ -100,32 +99,12 @@ pub struct Function {
/// Layout of blocks and instructions in the function body.
pub layout: Layout,
/// Code offsets of the block headers.
///
/// This information is only transiently available after the `binemit::relax_branches` function
/// computes it, and it can easily be recomputed by calling that function. It is not included
/// in the textual IR format.
pub offsets: BlockOffsets,
/// Code offsets of Jump Table headers.
pub jt_offsets: JumpTableOffsets,
/// Source locations.
///
/// Track the original source location for each instruction. The source locations are not
/// interpreted by Cranelift, only preserved.
pub srclocs: SourceLocs,
/// Instruction that marks the end (inclusive) of the function's prologue.
///
/// This is used for some ABIs to generate unwind information.
pub prologue_end: Option<Inst>,
/// The instructions that mark the start (inclusive) of an epilogue in the function.
///
/// This is used for some ABIs to generate unwind information.
pub epilogues_start: Vec<(Inst, Block)>,
/// An optional global value which represents an expression evaluating to
/// the stack limit for this function. This `GlobalValue` will be
/// interpreted in the prologue, if necessary, to insert a stack check to
@@ -148,11 +127,7 @@ impl Function {
jump_tables: PrimaryMap::new(),
dfg: DataFlowGraph::new(),
layout: Layout::new(),
offsets: SecondaryMap::new(),
jt_offsets: SecondaryMap::new(),
srclocs: SecondaryMap::new(),
prologue_end: None,
epilogues_start: Vec::new(),
stack_limit: None,
}
}
@@ -167,11 +142,7 @@ impl Function {
self.jump_tables.clear();
self.dfg.clear();
self.layout.clear();
self.offsets.clear();
self.jt_offsets.clear();
self.srclocs.clear();
self.prologue_end = None;
self.epilogues_start.clear();
self.stack_limit = None;
}

View File

@@ -59,18 +59,11 @@ pub use crate::ir::types::Type;
pub use crate::value_label::LabelValueLoc;
pub use cranelift_codegen_shared::condcodes;
use crate::binemit;
use crate::entity::{entity_impl, PrimaryMap, SecondaryMap};
/// Map of jump tables.
pub type JumpTables = PrimaryMap<JumpTable, JumpTableData>;
/// Code offsets for blocks.
pub type BlockOffsets = SecondaryMap<Block, binemit::CodeOffset>;
/// Code offsets for Jump Tables.
pub type JumpTableOffsets = SecondaryMap<JumpTable, binemit::CodeOffset>;
/// Source locations for instructions.
pub type SourceLocs = SecondaryMap<Inst, SourceLoc>;

View File

@@ -2,7 +2,7 @@
#![allow(dead_code)]
use crate::binemit::{Addend, CodeOffset, CodeSink, Reloc};
use crate::ir::{ConstantOffset, ExternalName, JumpTable, Opcode, SourceLoc, TrapCode};
use crate::ir::{ConstantOffset, ExternalName, Opcode, SourceLoc, TrapCode};
use alloc::vec::Vec;
use std::string::String;
@@ -68,8 +68,6 @@ impl CodeSink for TestCodeSink {
fn reloc_constant(&mut self, _rel: Reloc, _constant_offset: ConstantOffset) {}
fn reloc_jt(&mut self, _rel: Reloc, _jt: JumpTable) {}
fn trap(&mut self, _code: TrapCode, _srcloc: SourceLoc) {}
fn begin_jumptables(&mut self) {}

View File

@@ -1641,7 +1641,7 @@ impl<I: VCodeInst> TextSectionBuilder for MachTextSectionBuilder<I> {
#[cfg(all(test, feature = "arm64"))]
mod test {
use super::*;
use crate::ir::{ConstantOffset, JumpTable};
use crate::ir::ConstantOffset;
use crate::isa::aarch64::inst::xreg;
use crate::isa::aarch64::inst::{BranchTarget, CondBrKind, EmitInfo, Inst};
use crate::machinst::MachInstEmit;
@@ -2068,7 +2068,6 @@ mod test {
self.relocs.push((self.offset, r));
}
fn reloc_constant(&mut self, _: Reloc, _: ConstantOffset) {}
fn reloc_jt(&mut self, _: Reloc, _: JumpTable) {}
fn trap(&mut self, t: TrapCode, _: SourceLoc) {
self.traps.push((self.offset, t));
}

View File

@@ -96,7 +96,6 @@ impl binemit::CodeSink for SizeSink {
) {
}
fn reloc_constant(&mut self, _: binemit::Reloc, _: ir::ConstantOffset) {}
fn reloc_jt(&mut self, _reloc: binemit::Reloc, _jt: ir::JumpTable) {}
fn trap(&mut self, _code: ir::TrapCode, _srcloc: ir::SourceLoc) {}
fn begin_jumptables(&mut self) {}
fn begin_rodata(&mut self) {}

View File

@@ -894,18 +894,6 @@ impl RelocSink for JITRelocSink {
});
}
fn reloc_jt(&mut self, _offset: CodeOffset, reloc: Reloc, _jt: ir::JumpTable) {
match reloc {
Reloc::X86PCRelRodata4 => {
// Not necessary to record this unless we are going to split apart code and its
// jumptbl/rodata.
}
_ => {
panic!("Unhandled reloc");
}
}
}
fn reloc_constant(&mut self, _offset: CodeOffset, reloc: Reloc, _constant: ir::ConstantOffset) {
match reloc {
Reloc::X86PCRelRodata4 => {

View File

@@ -735,18 +735,6 @@ impl RelocSink for ObjectRelocSink {
})
}
fn reloc_jt(&mut self, _offset: CodeOffset, reloc: Reloc, _jt: ir::JumpTable) {
match reloc {
Reloc::X86PCRelRodata4 => {
// Not necessary to record this unless we are going to split apart code and its
// jumptbl/rodata.
}
_ => {
panic!("Unhandled reloc");
}
}
}
fn reloc_constant(&mut self, _offset: CodeOffset, reloc: Reloc, _jt: ir::ConstantOffset) {
match reloc {
Reloc::X86PCRelRodata4 => {

View File

@@ -37,12 +37,6 @@ impl binemit::RelocSink for PrintRelocs {
}
}
fn reloc_jt(&mut self, where_: binemit::CodeOffset, r: binemit::Reloc, jt: ir::JumpTable) {
if self.flag_print {
writeln!(&mut self.text, "reloc_jt: {} {} at {}", r, jt, where_).unwrap();
}
}
fn reloc_constant(
&mut self,
code_offset: binemit::CodeOffset,

View File

@@ -197,7 +197,6 @@ impl wasmtime_environ::Compiler for Compiler {
let length = u32::try_from(code_buf.len()).unwrap();
Ok(Box::new(CompiledFunction {
body: code_buf,
jt_offsets: context.func.jt_offsets,
relocations: reloc_sink.func_relocs,
value_labels_ranges: ranges.unwrap_or(Default::default()),
stack_slots: context.func.stack_slots,
@@ -540,7 +539,6 @@ impl Compiler {
Ok(CompiledFunction {
body: code_buf,
jt_offsets: context.func.jt_offsets,
unwind_info,
relocations: reloc_sink.relocs,
stack_slots: Default::default(),
@@ -655,15 +653,6 @@ impl binemit::RelocSink for RelocSink {
// Do nothing for now: cranelift emits constant data after the function code and also emits
// function code with correct relative offsets to the constant data.
}
fn reloc_jt(&mut self, offset: binemit::CodeOffset, reloc: binemit::Reloc, jt: ir::JumpTable) {
self.func_relocs.push(Relocation {
reloc,
reloc_target: RelocationTarget::JumpTable(jt),
offset,
addend: 0,
});
}
}
impl RelocSink {
@@ -783,12 +772,4 @@ impl binemit::RelocSink for TrampolineRelocSink {
) {
panic!("trampoline compilation should not produce constant relocs");
}
fn reloc_jt(
&mut self,
_offset: binemit::CodeOffset,
_reloc: binemit::Reloc,
_jt: ir::JumpTable,
) {
panic!("trampoline compilation should not produce jump table relocs");
}
}

View File

@@ -114,9 +114,6 @@ pub struct CompiledFunction {
/// The machine code for this function.
body: Vec<u8>,
/// The jump tables offsets (in the body).
jt_offsets: ir::JumpTableOffsets,
/// The unwind information.
unwind_info: Option<UnwindInfo>,
@@ -181,8 +178,6 @@ enum RelocationTarget {
UserFunc(FuncIndex),
/// A compiler-generated libcall.
LibCall(ir::LibCall),
/// Jump table index.
JumpTable(ir::JumpTable),
}
/// Creates a new cranelift `Signature` with no wasm params/results for the

View File

@@ -305,7 +305,6 @@ impl<'a> ObjectBuilder<'a> {
// seem too common though so aren't necessarily that important
// to optimize.
RelocationTarget::LibCall(call) => (self.libcalls[&call], 0),
RelocationTarget::JumpTable(jt) => (symbol_id, func.jt_offsets[jt]),
};
let (kind, encoding, size) = match r.reloc {
Reloc::Abs4 => (RelocationKind::Absolute, RelocationEncoding::Generic, 32),