///|
#valtype
pub struct CodeSites {
priv sources : Array[@code_object.SourceSite]
priv traps : Array[@code_object.TrapSite]
priv safepoints : Array[@code_object.SafepointSite]
}
///|
pub fn CodeSites::new() -> CodeSites {
{ sources: [], traps: [], safepoints: [], }
}
///|
fn[Inst] code_object_root(
function : Function[Inst],
frame : FrameLayout,
value : Value,
location : Location,
) -> @code_object.RootLocation {
match location {
Register(reg) => {
let bank : @code_object.RegisterBank = match reg.class {
Int => Int
Float | Vector | FpVector => FpVector
}
Register(bank, reg.id)
}
Stack(slot) =>
Stack(
offset=frame.slot_offset(slot).unwrap(),
ty=function.value_type(value).unwrap(),
)
}
}
///|
pub fn[Inst] CodeSites::record(
self : CodeSites,
function : Function[Inst],
allocation : Allocation,
frame : FrameLayout,
instruction : Instruction,
metadata : InstructionAnnotations,
offset : Int32,
end : Int32,
) -> Unit {
if metadata.source() is Some(source) {
let length = end - offset
if length > 0 {
if self.sources.last() is Some(previous) &&
previous.source == source &&
previous.offset + previous.length == offset {
self.sources[self.sources.length() - 1] = @code_object.SourceSite::new(
previous.offset,
source,
length=previous.length + length,
)
} else {
self.sources.push(@code_object.SourceSite::new(offset, source, length~))
}
}
}
if metadata.trap() is Some(reason) {
self.traps.push(
@code_object.TrapSite::new(offset, reason, source?=metadata.source()),
)
}
if metadata.safepoint() is Some(kind) {
let roots = allocation
.safepoint_roots(instruction)
.map(entry => {
let (value, location) = entry
code_object_root(function, frame, value, location)
})
self.safepoints.push(
@code_object.SafepointSite::new(
offset,
kind,
roots,
source?=metadata.source(),
stack_map?=metadata.stack_map(),
),
)
}
}
///|
pub fn CodeSites::build(
self : CodeSites,
architecture : @code_object.Architecture,
code : Array[Byte],
relocations : Array[@code_object.Relocation],
unwind : Array[@code_object.UnwindDirective],
) -> @code_object.UnlinkedCodeObject raise @code_object.CodeObjectVerifyError {
@code_object.build(
architecture,
code,
relocations~,
sources=self.sources,
traps=self.traps,
safepoints=self.safepoints,
unwind~,
)
}