YJIT: Use a boxed slice for gc_obj_offsets (#7397)
* YJIT: Use a boxed slice for gc_obj_offsets * YJIT: Stop using Option * YJIT: s/add_counter/incr_counter_by/ Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
This commit is contained in:
parent
3766cbce13
commit
67ad831b5f
Notes:
git
2023-02-28 18:03:47 +00:00
Merged-By: k0kubun <takashikkbn@gmail.com>
@ -831,7 +831,7 @@ pub fn gen_single_block(
|
|||||||
let gc_offsets = asm.compile(cb);
|
let gc_offsets = asm.compile(cb);
|
||||||
|
|
||||||
// Add the GC offsets to the block
|
// Add the GC offsets to the block
|
||||||
block.add_gc_obj_offsets(gc_offsets);
|
block.set_gc_obj_offsets(gc_offsets);
|
||||||
|
|
||||||
// Mark the end position of the block
|
// Mark the end position of the block
|
||||||
block.set_end_addr(cb.get_write_ptr());
|
block.set_end_addr(cb.get_write_ptr());
|
||||||
|
@ -544,7 +544,7 @@ pub struct Block {
|
|||||||
|
|
||||||
// FIXME: should these be code pointers instead?
|
// FIXME: should these be code pointers instead?
|
||||||
// Offsets for GC managed objects in the mainline code block
|
// Offsets for GC managed objects in the mainline code block
|
||||||
gc_obj_offsets: Vec<u32>,
|
gc_obj_offsets: Box<[u32]>,
|
||||||
|
|
||||||
// CME dependencies of this block, to help to remove all pointers to this
|
// CME dependencies of this block, to help to remove all pointers to this
|
||||||
// block in the system.
|
// block in the system.
|
||||||
@ -796,7 +796,7 @@ pub extern "C" fn rb_yjit_iseq_mark(payload: *mut c_void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Walk over references to objects in generated code.
|
// Walk over references to objects in generated code.
|
||||||
for offset in &block.gc_obj_offsets {
|
for offset in block.gc_obj_offsets.iter() {
|
||||||
let value_address: *const u8 = cb.get_ptr(offset.as_usize()).raw_ptr();
|
let value_address: *const u8 = cb.get_ptr(offset.as_usize()).raw_ptr();
|
||||||
// Creating an unaligned pointer is well defined unlike in C.
|
// Creating an unaligned pointer is well defined unlike in C.
|
||||||
let value_address = value_address as *const VALUE;
|
let value_address = value_address as *const VALUE;
|
||||||
@ -843,7 +843,7 @@ pub extern "C" fn rb_yjit_iseq_update_references(payload: *mut c_void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Walk over references to objects in generated code.
|
// Walk over references to objects in generated code.
|
||||||
for offset in &block.gc_obj_offsets {
|
for offset in block.gc_obj_offsets.iter() {
|
||||||
let offset_to_value = offset.as_usize();
|
let offset_to_value = offset.as_usize();
|
||||||
let value_code_ptr = cb.get_ptr(offset_to_value);
|
let value_code_ptr = cb.get_ptr(offset_to_value);
|
||||||
let value_ptr: *const u8 = value_code_ptr.raw_ptr();
|
let value_ptr: *const u8 = value_code_ptr.raw_ptr();
|
||||||
@ -1043,7 +1043,7 @@ fn add_block_version(blockref: &BlockRef, cb: &CodeBlock) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Run write barriers for all objects in generated code.
|
// Run write barriers for all objects in generated code.
|
||||||
for offset in &block.gc_obj_offsets {
|
for offset in block.gc_obj_offsets.iter() {
|
||||||
let value_address: *const u8 = cb.get_ptr(offset.as_usize()).raw_ptr();
|
let value_address: *const u8 = cb.get_ptr(offset.as_usize()).raw_ptr();
|
||||||
// Creating an unaligned pointer is well defined unlike in C.
|
// Creating an unaligned pointer is well defined unlike in C.
|
||||||
let value_address: *const VALUE = value_address.cast();
|
let value_address: *const VALUE = value_address.cast();
|
||||||
@ -1088,7 +1088,7 @@ impl Block {
|
|||||||
end_addr: None,
|
end_addr: None,
|
||||||
incoming: Vec::new(),
|
incoming: Vec::new(),
|
||||||
outgoing: Vec::new(),
|
outgoing: Vec::new(),
|
||||||
gc_obj_offsets: Vec::new(),
|
gc_obj_offsets: Box::new([]),
|
||||||
cme_dependencies: Vec::new(),
|
cme_dependencies: Vec::new(),
|
||||||
entry_exit: None,
|
entry_exit: None,
|
||||||
};
|
};
|
||||||
@ -1147,12 +1147,12 @@ impl Block {
|
|||||||
self.end_idx = end_idx;
|
self.end_idx = end_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_gc_obj_offsets(self: &mut Block, gc_offsets: Vec<u32>) {
|
pub fn set_gc_obj_offsets(self: &mut Block, gc_offsets: Vec<u32>) {
|
||||||
for offset in gc_offsets {
|
assert_eq!(self.gc_obj_offsets.len(), 0);
|
||||||
self.gc_obj_offsets.push(offset);
|
if !gc_offsets.is_empty() {
|
||||||
incr_counter!(num_gc_obj_refs);
|
incr_counter_by!(num_gc_obj_refs, gc_offsets.len());
|
||||||
|
self.gc_obj_offsets = gc_offsets.into_boxed_slice();
|
||||||
}
|
}
|
||||||
self.gc_obj_offsets.shrink_to_fit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Instantiate a new CmeDependency struct and add it to the list of
|
/// Instantiate a new CmeDependency struct and add it to the list of
|
||||||
|
@ -141,6 +141,19 @@ macro_rules! make_counters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Macro to increase a counter by name and count
|
||||||
|
macro_rules! incr_counter_by {
|
||||||
|
// Unsafe is ok here because options are initialized
|
||||||
|
// once before any Ruby code executes
|
||||||
|
($counter_name:ident, $count:expr) => {
|
||||||
|
#[allow(unused_unsafe)]
|
||||||
|
{
|
||||||
|
unsafe { $crate::stats::COUNTERS.$counter_name += $count as u64 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub(crate) use incr_counter_by;
|
||||||
|
|
||||||
/// Macro to increment a counter by name
|
/// Macro to increment a counter by name
|
||||||
macro_rules! incr_counter {
|
macro_rules! incr_counter {
|
||||||
// Unsafe is ok here because options are initialized
|
// Unsafe is ok here because options are initialized
|
||||||
|
Loading…
x
Reference in New Issue
Block a user