mirror of
https://github.com/ruby/ruby.git
synced 2025-08-15 13:39:04 +02:00
ZJIT: x86: split: Fix live ranges index-out-of-range panic
Previously we crashed panicked due to index bounds check running test_fixnum.rb. On ARM and in other places in the x86 backend, this isn't a problem because they inspect the output of instructions which is never replaced.
This commit is contained in:
parent
71b46938a7
commit
21cb1c9e92
1 changed files with 13 additions and 4 deletions
|
@ -148,6 +148,15 @@ impl Assembler
|
|||
};
|
||||
}
|
||||
|
||||
// When we split an operand, we can create a new VReg not in `live_ranges`.
|
||||
// So when we see a VReg with out-of-range index, it's created from splitting
|
||||
// from the loop above and we know it doesn't outlive the current instruction.
|
||||
let vreg_outlives_insn = |vreg_idx| {
|
||||
live_ranges
|
||||
.get(vreg_idx)
|
||||
.map_or(false, |live_range: &LiveRange| live_range.end() > index)
|
||||
};
|
||||
|
||||
// We are replacing instructions here so we know they are already
|
||||
// being used. It is okay not to use their output here.
|
||||
#[allow(unused_must_use)]
|
||||
|
@ -183,7 +192,7 @@ impl Assembler
|
|||
},
|
||||
// Instruction output whose live range spans beyond this instruction
|
||||
(Opnd::VReg { idx, .. }, _) => {
|
||||
if live_ranges[idx].end() > index {
|
||||
if vreg_outlives_insn(idx) {
|
||||
*left = asm.load(*left);
|
||||
}
|
||||
},
|
||||
|
@ -248,7 +257,7 @@ impl Assembler
|
|||
match opnd {
|
||||
// Instruction output whose live range spans beyond this instruction
|
||||
Opnd::VReg { idx, .. } => {
|
||||
if live_ranges[*idx].end() > index {
|
||||
if vreg_outlives_insn(*idx) {
|
||||
*opnd = asm.load(*opnd);
|
||||
}
|
||||
},
|
||||
|
@ -272,7 +281,7 @@ impl Assembler
|
|||
// If we have an instruction output whose live range
|
||||
// spans beyond this instruction, we have to load it.
|
||||
Opnd::VReg { idx, .. } => {
|
||||
if live_ranges[idx].end() > index {
|
||||
if vreg_outlives_insn(idx) {
|
||||
*truthy = asm.load(*truthy);
|
||||
}
|
||||
},
|
||||
|
@ -307,7 +316,7 @@ impl Assembler
|
|||
// If we have an instruction output whose live range
|
||||
// spans beyond this instruction, we have to load it.
|
||||
Opnd::VReg { idx, .. } => {
|
||||
if live_ranges[idx].end() > index {
|
||||
if vreg_outlives_insn(idx) {
|
||||
*opnd = asm.load(*opnd);
|
||||
}
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue