Project

General

Profile

Actions

Feature #18439

open

YJIT: Support Microsoft x86 calling convention

Added by usa (Usaku NAKAMURA) almost 3 years ago. Updated 1 day ago.

Status:
Assigned
Assignee:
Target version:
-
[ruby-core:106834]

Description

I heard that supporting YJIT for VC++ needs mmap from k0kubun-san, so I implemented tiny mmap emulation on Windows and committed it to master.
And, I found we need more changes to actually enabled YJIT for VC++, at least:

  • YJIT requires OPT_DIRECT_THREADED_CODE or OPT_CALL_THREADED_CODE in rb_yjit_compile_iseq(). Really?
  • Maybe ABI deffers between VC++ and YJIT's expectation.

Can I get support to fix above?


Related issues 1 (1 open0 closed)

Has duplicate Ruby master - Feature #19325: YJIT: Windows support lacking.AssignedyjitActions

Updated by k0kubun (Takashi Kokubun) almost 3 years ago

  • Assignee set to maximecb (Maxime Chevalier-Boisvert)

Updated by jhawthorn (John Hawthorn) almost 3 years ago

YJIT requires OPT_DIRECT_THREADED_CODE or OPT_CALL_THREADED_CODE in rb_yjit_compile_iseq().

What option do we use under windows?

Maybe ABI differs between VC++ and YJIT's expectation.

Yes. We would need to switch to the Windows calling convention, which is different enough to be a non-trivial change. It only passes 4 arguments via registers vs 6 in the System V ABI (and also uses different registers) as well as requiring 32 bytes of reserved stack space from the callee ("shadow space").

I think we could likely do this with minimal (but non-trivial) changes by:

  • Reserving the 32 bytes of stack "shadow space" in the YJIT entrypoint
  • Reserving another 16 bytes on the stack in the YJIT entrypoint for the 5th and 6th argument
    • This could be an opportunity to do the same and support more arguments on SysV as well
  • Conditionally under Windows defining C_ARG_REGS as RCX, RDX, R8, R9, [RSP+32], [RSP+40]
    • Alternatively we could reduce NUM_C_ARG_REGS to 4 and handle the 5th and 6th argument specially where we need them
  • Rewriting the two instructions (gen_toregexp/gen_newhash) whose codegen currently modifies the machine stack (we could use a relative stack location instead of push/pop, a callee-saved register, or introduce runtime helper methods)

However I'd like to hear the opinions of YJIT folks when they're back from holidays next week on whether this is the best way to approach this.

Updated by alanwu (Alan Wu) almost 3 years ago

Yes, supporting Window's x64 calling convention is non-trivial.
In addition to what John already mentioned we also need to uphold unwindability
constraints so among other things, longjmp can work. I think longjmp() is used for Ruby exceptions on MSVC like on POSIX.
This means YJIT can't generate PUSH and POP outside of prolog and epilog anymore as they puts the stack pointer temporarily out of
alignment. YJIT will also need to supply unwinding info through RtlInstallFunctionTableCallback().

Actions #4

Updated by alanwu (Alan Wu) almost 3 years ago

  • Tracker changed from Bug to Feature
  • Backport deleted (2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN)

Updated by maximecb (Maxime Chevalier-Boisvert) almost 3 years ago

Supporting Windows is in the plans, but as my colleagues have said it's fairly tricky as it could add a fair bit of complexity in several places. We're hoping to potentially migrate the YJIT codebase to Rust, which would give us more tools to manage the complexity, and could facilitate a project like this.

Updated by hsbt (Hiroshi SHIBATA) almost 2 years ago

  • Status changed from Open to Assigned
  • Assignee changed from maximecb (Maxime Chevalier-Boisvert) to yjit

YJIT has been rewrote with rust in Ruby 3.2. Should we close this?

Updated by k0kubun (Takashi Kokubun) almost 2 years ago

  • Subject changed from Support YJIT for VC++ to YJIT: Support Microsoft x86 calling convention

What's used for compiling YJIT itself, which was changed from a C compiler to rustc, wasn't a huge concern for supporting Windows. Given that @usa (Usaku NAKAMURA) has an idea for the mmap part, the main challenge for supporting Windows would be ABI support in JITed code. I changed the ticket description to clarify what's to be done.

Actions #8

Updated by k0kubun (Takashi Kokubun) almost 2 years ago

Updated by dsisnero (Dominic Sisneros) 2 days ago

Any updates, thoughts. As a forced windows user for work - would like some of the speed improvements that yjit brings. Thanks

Updated by maximecb (Maxime Chevalier-Boisvert) 2 days ago

Any updates, thoughts. As a forced windows user for work - would like some of the speed improvements that yjit brings. Thanks

Same as before. We would need to invest time into this, but it's not really a priority for us.

The other problem is that it's not easy for us to test things since we don't have windows machines. That would make development a pain.

Updated by YO4 (Yoshinao Muramatsu) 1 day ago

The Windows version of ruby limits Integer to 30 bits even in x64 environments.
I am afraid that to support this in yjit would add complexity, which would harm the evolution of yjit.
Would 30bit Integer support actually have a negative impact?

Nevertheless, regardless of yjit support, I would like to see the Windows version of Integer's limitation removed.

Updated by maximecb (Maxime Chevalier-Boisvert) 1 day ago

It would definitely be simpler if integers were handled the same way on windows as on Linux and macOS.

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0