1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
* Fix asm.load(VALUE)

- `<VALUE as impl Into<Opnd>>` didn't track that the value is a value
- `Iterator::map` doesn't evaluate the closure you give it until you
  call `collect`. Use a for loop instead so we put the gc offsets
  into the compiled block properly.

* x64: Mov(mem, VALUE) should load the value first

Tripped in codegen for putobject now that we are actually feeding
`Opnd::Value` into the backend.

* x64 split: Canonicallize VALUE loads

* Update yjit/src/backend/x86_64/mod.rs
This commit is contained in:
Alan Wu 2022-08-03 18:25:01 -04:00 committed by Takashi Kokubun
parent 4539c21367
commit ddee4d3af8
No known key found for this signature in database
GPG key ID: 6FFC433B12EE23DD
3 changed files with 15 additions and 12 deletions

View file

@ -313,8 +313,7 @@ impl From<u32> for Opnd {
impl From<VALUE> for Opnd {
fn from(value: VALUE) -> Self {
let VALUE(uimm) = value;
Opnd::UImm(uimm as u64)
Opnd::Value(value)
}
}

View file

@ -95,20 +95,22 @@ impl Assembler
let live_ranges: Vec<usize> = std::mem::take(&mut self.live_ranges);
self.forward_pass(|asm, index, op, opnds, target, text, pos_marker, original_opnds| {
// Load heap object operands into registers because most
// instructions can't directly work with 64-bit constants
// Load VALUEs into registers because
// - Most instructions can't be encoded with 64-bit immediates.
// - We look for Op::Load specifically when emiting to keep GC'ed
// VALUEs alive. This is a sort of canonicalization.
let opnds = match op {
Op::Load | Op::Mov => opnds,
Op::Load => opnds,
_ => opnds.into_iter().map(|opnd| {
if let Opnd::Value(value) = opnd {
if !value.special_const_p() {
asm.load(opnd)
} else {
opnd
// Since mov(mem64, imm32) sign extends, as_i64() makes sure we split
// when the extended value is different.
if !value.special_const_p() || imm_num_bits(value.as_i64()) > 32 {
return asm.load(opnd);
}
} else {
opnd
}
opnd
}).collect()
};

View file

@ -849,7 +849,9 @@ pub fn gen_single_block(
let mut block = jit.block.borrow_mut();
// Add the GC offsets to the block
gc_offsets.iter().map(|offs| { block.add_gc_obj_offset(*offs) });
for offset in gc_offsets {
block.add_gc_obj_offset(offset)
}
// Mark the end position of the block
block.set_end_addr(cb.get_write_ptr());