Skip to content

Commit 8d45e1f

Browse files
authored
ZJIT: Fix internal compiler error looking up profiles for trace_getinstancevariable (ruby#14969)
We treat getinstancevariable differently from other opcodes: it does not look at the stack for its self operand, but instead looks at `cfp->self`. In some cases, we might see the `trace_` variant in the front-end, so make sure we treat that the same. Example repro: ``` def test @foo end 28.times do test end trace = TracePoint.trace(:call) do |tp| puts tp.method_id end trace.enable do 30.times do test end end ```
1 parent d97fb3b commit 8d45e1f

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

zjit/src/hir.rs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4021,7 +4021,11 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
40214021
.try_into()
40224022
.unwrap();
40234023

4024-
if opcode == YARVINSN_getinstancevariable {
4024+
// If TracePoint has been enabled after we have collected profiles, we'll see
4025+
// trace_getinstancevariable in the ISEQ. We have to treat it like getinstancevariable
4026+
// for profiling purposes: there is no operand on the stack to look up; we have
4027+
// profiled cfp->self.
4028+
if opcode == YARVINSN_getinstancevariable || opcode == YARVINSN_trace_getinstancevariable {
40254029
profiles.profile_self(&exit_state, self_param);
40264030
} else {
40274031
profiles.profile_stack(&exit_state);
@@ -7408,6 +7412,29 @@ mod tests {
74087412
");
74097413
}
74107414

7415+
#[test]
7416+
fn test_trace_getinstancevariable() {
7417+
eval("
7418+
def test = @foo
7419+
test
7420+
trace = TracePoint.trace(:call) { |tp| }
7421+
trace.enable { test }
7422+
");
7423+
assert_contains_opcode("test", YARVINSN_trace_getinstancevariable);
7424+
assert_snapshot!(hir_string("test"), @r"
7425+
fn test@<compiled>:2:
7426+
bb0():
7427+
EntryPoint interpreter
7428+
v1:BasicObject = LoadSelf
7429+
Jump bb2(v1)
7430+
bb1(v4:BasicObject):
7431+
EntryPoint JIT(0)
7432+
Jump bb2(v4)
7433+
bb2(v6:BasicObject):
7434+
SideExit UnhandledYARVInsn(trace_getinstancevariable)
7435+
");
7436+
}
7437+
74117438
#[test]
74127439
fn test_setinstancevariable() {
74137440
eval("

0 commit comments

Comments
 (0)