cranelift codegen: add a supplementary method add_call_site to CodeSink;
This allows keeping track of indirect call sites, for instance.
This commit is contained in:
@@ -2417,6 +2417,7 @@ pub(crate) fn define<'shared>(
|
||||
&func.dfg.ext_funcs[func_ref].name,
|
||||
-4);
|
||||
sink.put4(0);
|
||||
sink.add_call_site(opcode, func.srclocs[inst]);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
@@ -2431,6 +2432,7 @@ pub(crate) fn define<'shared>(
|
||||
&func.dfg.ext_funcs[func_ref].name,
|
||||
-4);
|
||||
sink.put4(0);
|
||||
sink.add_call_site(opcode, func.srclocs[inst]);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
@@ -2443,6 +2445,7 @@ pub(crate) fn define<'shared>(
|
||||
sink.trap(TrapCode::StackOverflow, func.srclocs[inst]);
|
||||
{{PUT_OP}}(bits, rex1(in_reg0), sink);
|
||||
modrm_r_bits(in_reg0, bits, sink);
|
||||
sink.add_call_site(opcode, func.srclocs[inst]);
|
||||
"#,
|
||||
),
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
|
||||
use crate::binemit::stackmap::Stackmap;
|
||||
use crate::ir::entities::Value;
|
||||
use crate::ir::{ConstantOffset, ExternalName, Function, JumpTable, SourceLoc, TrapCode};
|
||||
use crate::ir::{ConstantOffset, ExternalName, Function, JumpTable, Opcode, SourceLoc, TrapCode};
|
||||
use crate::isa::TargetIsa;
|
||||
use core::ptr::write_unaligned;
|
||||
|
||||
@@ -92,6 +92,10 @@ pub trait RelocSink {
|
||||
|
||||
/// 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) {}
|
||||
}
|
||||
|
||||
/// A trait for receiving trap codes and offsets.
|
||||
@@ -183,6 +187,15 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
|
||||
let stackmap = Stackmap::from_values(&val_list, func, isa);
|
||||
self.stackmaps.add_stackmap(ofs, stackmap);
|
||||
}
|
||||
|
||||
fn add_call_site(&mut self, opcode: Opcode, loc: SourceLoc) {
|
||||
debug_assert!(
|
||||
opcode.is_call(),
|
||||
"adding call site info for a non-call instruction."
|
||||
);
|
||||
let ret_addr = self.offset();
|
||||
self.relocs.add_call_site(opcode, ret_addr, loc);
|
||||
}
|
||||
}
|
||||
|
||||
/// A `RelocSink` implementation that does nothing, which is convenient when
|
||||
|
||||
@@ -16,7 +16,9 @@ pub use self::relaxation::relax_branches;
|
||||
pub use self::shrink::shrink_instructions;
|
||||
pub use self::stackmap::Stackmap;
|
||||
use crate::ir::entities::Value;
|
||||
use crate::ir::{ConstantOffset, ExternalName, Function, Inst, JumpTable, SourceLoc, TrapCode};
|
||||
use crate::ir::{
|
||||
ConstantOffset, ExternalName, Function, Inst, JumpTable, Opcode, SourceLoc, TrapCode,
|
||||
};
|
||||
use crate::isa::TargetIsa;
|
||||
pub use crate::regalloc::RegDiversions;
|
||||
use core::fmt;
|
||||
@@ -162,6 +164,11 @@ pub trait CodeSink {
|
||||
|
||||
/// Add a stackmap at the current code offset.
|
||||
fn add_stackmap(&mut self, _: &[Value], _: &Function, _: &dyn TargetIsa);
|
||||
|
||||
/// Add a call site for a call with the given opcode, returning at the current offset.
|
||||
fn add_call_site(&mut self, _: Opcode, _: SourceLoc) {
|
||||
// Default implementation doesn't need to do anything.
|
||||
}
|
||||
}
|
||||
|
||||
/// Type of the frame unwind information.
|
||||
|
||||
Reference in New Issue
Block a user