Skip to content

ZJIT: Use rb_vm_env_write() when writing locals in higher scopes #13977

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2025

Conversation

XrXr
Copy link
Member

@XrXr XrXr commented Jul 22, 2025

We weren't firing write barriers before when writing to imemo/env
objects. Wbcheck caught this with test/ruby/test_refinement.rb:

ruby -v: ruby 3.5.0dev (2025-07-22T17:05:58Z wbcheck 2569a80954) +ZJIT dev +PRISM +GC[wbcheck] [x86_64-linux]
WBCHECK ERROR: Missed write barrier detected!
  Parent object: 0x558de9f4e6e0 (wb_protected: true)
    rb_obj_info_dump: 0x0000558de9f4e6e0 T_IMEMO/<env>
  Reference counts - snapshot: 3, writebarrier: 0, current: 4, missed: 1
  Missing reference to: 0x558decf37c30
    rb_obj_info_dump: 0x0000558decf37c30 method/UnboundMethod method

WBCHECK SUMMARY: Found 1 objects with missed write barriers (1 total violations)

@matzbot matzbot requested a review from a team July 22, 2025 19:58
@k0kubun
Copy link
Member

k0kubun commented Jul 22, 2025

Similarly to YJIT, could we skip the call when the val is known to be an immediate? I guess we could let the HIR generator check the type and set a flag to Insn::SetLocal like write_barrier: true.

Feel free to merge this first and leave it for another PR though.

@tekknolagi
Copy link
Contributor

tbh we don't need a flag in the instruction -- we can make the decision at HIR->LIR codegen time with the type of val

@tekknolagi
Copy link
Contributor

@st0012 does this (with the class.h fix) fix the problems you see and enable more tests?

@k0kubun
Copy link
Member

k0kubun commented Jul 22, 2025

"with the type of val", yes. What I'm saying is that I thought the HIR generator has better/more access to the type of val, but I might be wrong. If we want to optimize only the case that it points to Opnd::Value (likely created by Insn::Const) and the VALUE of it is an immediate, the HIR can stay as is. I was worried about cases like val pointing to Insn::GuardType, but maybe find() resolves it into Insn::Const when possible?

@XrXr XrXr force-pushed the zjit-setlocal-wb branch 2 times, most recently from 4a5bca6 to ad84032 Compare July 22, 2025 21:03
We weren't firing write barriers before when writing to imemo/env
objects. Wbcheck caught this with test/ruby/test_refinement.rb:

    ruby -v: ruby 3.5.0dev (2025-07-22T17:05:58Z wbcheck 2569a80954) +ZJIT dev +PRISM +GC[wbcheck] [x86_64-linux]
    WBCHECK ERROR: Missed write barrier detected!
      Parent object: 0x558de9f4e6e0 (wb_protected: true)
        rb_obj_info_dump: 0x0000558de9f4e6e0 T_IMEMO/<env>
      Reference counts - snapshot: 3, writebarrier: 0, current: 4, missed: 1
      Missing reference to: 0x558decf37c30
        rb_obj_info_dump: 0x0000558decf37c30 method/UnboundMethod method

    WBCHECK SUMMARY: Found 1 objects with missed write barriers (1 total violations)
@XrXr XrXr force-pushed the zjit-setlocal-wb branch from ad84032 to e2ab7e1 Compare July 22, 2025 21:06
@XrXr
Copy link
Member Author

XrXr commented Jul 22, 2025

I figure things like GuardType on a constant should be handled by optimizer, so HIR->LIR translation should have the same visibility on whether something is constant.

@XrXr XrXr enabled auto-merge (rebase) July 22, 2025 21:12
@tekknolagi
Copy link
Contributor

I mean that in HIR->LIR you can do if val.is_subtype(types::Immediate) and not care at all about what instruction it comes from. That will use all available information from the optimizer

@tekknolagi
Copy link
Contributor

That gives (much) more information than looking at the exact value, which we might not know. It would handle if it's any kind of Fixnum, for example

@XrXr XrXr merged commit 3336303 into ruby:master Jul 22, 2025
92 of 94 checks passed
@XrXr XrXr deleted the zjit-setlocal-wb branch July 22, 2025 22:04
@k0kubun
Copy link
Member

k0kubun commented Jul 22, 2025

I mean that in HIR->LIR you can do if val.is_subtype(types::Immediate)

I'm not sure if I follow. is_subtype() is a function on Type, but val is hir::InsnId in HIR and lir::Opnd in codegen. How do you call is_subtype() on val?

@k0kubun
Copy link
Member

k0kubun commented Jul 22, 2025

Ah, I guess Function::insn_types keeps them for each InsnId. Nvm then. I guess we don't need to bake type-related information in the instruction itself because the function has it separately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy