Remove add_call_site from CodeSink and RelocSink
And introduce MachBufferFinalized::call_sites() in the place.
This commit is contained in:
@@ -15,7 +15,7 @@
|
|||||||
//! `CodeSink::put*` methods, so the performance impact of the virtual callbacks is less severe.
|
//! `CodeSink::put*` methods, so the performance impact of the virtual callbacks is less severe.
|
||||||
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
|
use super::{Addend, CodeInfo, CodeOffset, CodeSink, Reloc};
|
||||||
use crate::binemit::stack_map::StackMap;
|
use crate::binemit::stack_map::StackMap;
|
||||||
use crate::ir::{ExternalName, Opcode, SourceLoc, TrapCode};
|
use crate::ir::{ExternalName, SourceLoc, TrapCode};
|
||||||
use core::ptr::write_unaligned;
|
use core::ptr::write_unaligned;
|
||||||
|
|
||||||
/// A `CodeSink` that writes binary machine code directly into memory.
|
/// A `CodeSink` that writes binary machine code directly into memory.
|
||||||
@@ -77,10 +77,6 @@ pub trait RelocSink {
|
|||||||
_: &ExternalName,
|
_: &ExternalName,
|
||||||
_: Addend,
|
_: Addend,
|
||||||
);
|
);
|
||||||
|
|
||||||
/// 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.
|
/// A trait for receiving trap codes and offsets.
|
||||||
@@ -115,15 +111,6 @@ impl<'a> CodeSink for MemoryCodeSink<'a> {
|
|||||||
let ofs = self.offset as CodeOffset;
|
let ofs = self.offset as CodeOffset;
|
||||||
self.traps.trap(ofs, srcloc, code);
|
self.traps.trap(ofs, srcloc, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 as CodeOffset;
|
|
||||||
self.relocs.add_call_site(opcode, ret_addr, loc);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A `RelocSink` implementation that does nothing, which is convenient when
|
/// A `RelocSink` implementation that does nothing, which is convenient when
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ pub use self::memorysink::{
|
|||||||
TrapSink,
|
TrapSink,
|
||||||
};
|
};
|
||||||
pub use self::stack_map::StackMap;
|
pub use self::stack_map::StackMap;
|
||||||
use crate::ir::{ExternalName, Opcode, SourceLoc, TrapCode};
|
use crate::ir::{ExternalName, SourceLoc, TrapCode};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
#[cfg(feature = "enable-serde")]
|
#[cfg(feature = "enable-serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@@ -113,9 +113,4 @@ pub trait CodeSink {
|
|||||||
|
|
||||||
/// Add trap information for the current offset.
|
/// Add trap information for the current offset.
|
||||||
fn trap(&mut self, _: TrapCode, _: SourceLoc);
|
fn trap(&mut self, _: TrapCode, _: SourceLoc);
|
||||||
|
|
||||||
/// 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.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ pub mod verifier;
|
|||||||
pub mod write;
|
pub mod write;
|
||||||
|
|
||||||
pub use crate::entity::packed_option;
|
pub use crate::entity::packed_option;
|
||||||
pub use crate::machinst::buffer::MachSrcLoc;
|
pub use crate::machinst::buffer::{MachCallSite, MachSrcLoc};
|
||||||
pub use crate::machinst::TextSectionBuilder;
|
pub use crate::machinst::TextSectionBuilder;
|
||||||
|
|
||||||
mod bitset;
|
mod bitset;
|
||||||
|
|||||||
@@ -1350,6 +1350,10 @@ impl<I: VCodeInst> MachBuffer<I> {
|
|||||||
|
|
||||||
/// Add a call-site record at the current offset.
|
/// Add a call-site record at the current offset.
|
||||||
pub fn add_call_site(&mut self, srcloc: SourceLoc, opcode: Opcode) {
|
pub fn add_call_site(&mut self, srcloc: SourceLoc, opcode: Opcode) {
|
||||||
|
debug_assert!(
|
||||||
|
opcode.is_call(),
|
||||||
|
"adding call site info for a non-call instruction."
|
||||||
|
);
|
||||||
self.call_sites.push(MachCallSite {
|
self.call_sites.push(MachCallSite {
|
||||||
ret_addr: self.data.len() as CodeOffset,
|
ret_addr: self.data.len() as CodeOffset,
|
||||||
srcloc,
|
srcloc,
|
||||||
@@ -1446,7 +1450,6 @@ impl MachBufferFinalized {
|
|||||||
|
|
||||||
let mut next_reloc = 0;
|
let mut next_reloc = 0;
|
||||||
let mut next_trap = 0;
|
let mut next_trap = 0;
|
||||||
let mut next_call_site = 0;
|
|
||||||
for (idx, byte) in self.data.iter().enumerate() {
|
for (idx, byte) in self.data.iter().enumerate() {
|
||||||
while next_reloc < self.relocs.len()
|
while next_reloc < self.relocs.len()
|
||||||
&& self.relocs[next_reloc].offset == idx as CodeOffset
|
&& self.relocs[next_reloc].offset == idx as CodeOffset
|
||||||
@@ -1461,13 +1464,6 @@ impl MachBufferFinalized {
|
|||||||
sink.trap(trap.code, trap.srcloc);
|
sink.trap(trap.code, trap.srcloc);
|
||||||
next_trap += 1;
|
next_trap += 1;
|
||||||
}
|
}
|
||||||
while next_call_site < self.call_sites.len()
|
|
||||||
&& self.call_sites[next_call_site].ret_addr == idx as CodeOffset
|
|
||||||
{
|
|
||||||
let call_site = &self.call_sites[next_call_site];
|
|
||||||
sink.add_call_site(call_site.opcode, call_site.srcloc);
|
|
||||||
next_call_site += 1;
|
|
||||||
}
|
|
||||||
sink.put1(*byte);
|
sink.put1(*byte);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1476,6 +1472,11 @@ impl MachBufferFinalized {
|
|||||||
pub fn stack_maps(&self) -> &[MachStackMap] {
|
pub fn stack_maps(&self) -> &[MachStackMap] {
|
||||||
&self.stack_maps[..]
|
&self.stack_maps[..]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the list of call sites for this code.
|
||||||
|
pub fn call_sites(&self) -> &[MachCallSite] {
|
||||||
|
&self.call_sites[..]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A constant that is deferred to the next constant-pool opportunity.
|
/// A constant that is deferred to the next constant-pool opportunity.
|
||||||
@@ -1531,13 +1532,14 @@ struct MachTrap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A call site record resulting from a compilation.
|
/// A call site record resulting from a compilation.
|
||||||
struct MachCallSite {
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct MachCallSite {
|
||||||
/// The offset of the call's return address, *relative to the containing section*.
|
/// The offset of the call's return address, *relative to the containing section*.
|
||||||
ret_addr: CodeOffset,
|
pub ret_addr: CodeOffset,
|
||||||
/// The original source location.
|
/// The original source location.
|
||||||
srcloc: SourceLoc,
|
pub srcloc: SourceLoc,
|
||||||
/// The call's opcode.
|
/// The call's opcode.
|
||||||
opcode: Opcode,
|
pub opcode: Opcode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A source-location mapping resulting from a compilation.
|
/// A source-location mapping resulting from a compilation.
|
||||||
@@ -2073,7 +2075,6 @@ mod test {
|
|||||||
struct TestCodeSink {
|
struct TestCodeSink {
|
||||||
offset: CodeOffset,
|
offset: CodeOffset,
|
||||||
traps: Vec<(CodeOffset, TrapCode)>,
|
traps: Vec<(CodeOffset, TrapCode)>,
|
||||||
callsites: Vec<(CodeOffset, Opcode)>,
|
|
||||||
relocs: Vec<(CodeOffset, Reloc)>,
|
relocs: Vec<(CodeOffset, Reloc)>,
|
||||||
}
|
}
|
||||||
impl CodeSink for TestCodeSink {
|
impl CodeSink for TestCodeSink {
|
||||||
@@ -2086,9 +2087,6 @@ mod test {
|
|||||||
fn trap(&mut self, t: TrapCode, _: SourceLoc) {
|
fn trap(&mut self, t: TrapCode, _: SourceLoc) {
|
||||||
self.traps.push((self.offset, t));
|
self.traps.push((self.offset, t));
|
||||||
}
|
}
|
||||||
fn add_call_site(&mut self, op: Opcode, _: SourceLoc) {
|
|
||||||
self.callsites.push((self.offset, op));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut sink = TestCodeSink::default();
|
let mut sink = TestCodeSink::default();
|
||||||
@@ -2103,7 +2101,13 @@ mod test {
|
|||||||
(2, TrapCode::IntegerDivisionByZero)
|
(2, TrapCode::IntegerDivisionByZero)
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
assert_eq!(sink.callsites, vec![(2, Opcode::Call),]);
|
assert_eq!(
|
||||||
|
buf.call_sites()
|
||||||
|
.iter()
|
||||||
|
.map(|call_site| (call_site.ret_addr, call_site.opcode))
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec![(2, Opcode::Call)]
|
||||||
|
);
|
||||||
assert_eq!(sink.relocs, vec![(2, Reloc::Abs4), (3, Reloc::Abs8)]);
|
assert_eq!(sink.relocs, vec![(2, Reloc::Abs4), (3, Reloc::Abs8)]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user