Skip to content

ZJIT: Decouple gen_function_stub and gen_function_stub_hit_trampoline#16249

Merged
tenderlove merged 1 commit intoruby:masterfrom
tenderlove:decouple-stubs
Feb 25, 2026
Merged

ZJIT: Decouple gen_function_stub and gen_function_stub_hit_trampoline#16249
tenderlove merged 1 commit intoruby:masterfrom
tenderlove:decouple-stubs

Conversation

@tenderlove
Copy link
Copy Markdown
Member

@tenderlove tenderlove commented Feb 25, 2026

Before this change, gen_function_stub and
gen_function_stub_hit_trampoline communicated via a scratch register. We would like gen_function_stub_hit_trampoline to have more freedom with regard to the registers it uses, especially for the CCall in to function_stub_hit. Instead of communicating via scratch register, we'll communicate via stack.

Practically speaking, this means:

  • Stop using x15 (scratch reg) to communicate iseq call addr from call stub to function sub hit trampoline; use stack instead
  • Don't try to CCall with x15 as first argument; can't use scratch reg in parallel move of arguments

Here is pseudo assembly of before this commit:

some_send_direct_in_a_ruby_method(JIT code):
  mov x15, gen_function_stub
  mov x0, self
  mov x1, 1
  blr x15

gen_function_stub:
  mov x15, 0xISEQADDR (the address of the ISEQ we _want_ to compile)
  jmp function_stub_hit_trampoline

function_stub_hit_trampoline:
  function prologue
  cpush ALL_JIT_REGS
  mov x0, x15 # currently x15 is 0xISEQADDR
  mov x1, CFP
  mov x2, SP
  blr function_stub_hit
  mov x15, x0 # write jump address to x15 (code pointer for compiled iseq)
  cpop ALL_JIT_REGS
  function epilogue
  jmp x15

Here is pseudo assembly of after this commit:

some_send_direct_in_a_ruby_method(JIT code):
  mov x15, gen_function_stub
  mov x0, self
  mov x1, 1
  blr x15

gen_function_stub:
  mov x15, 0xISEQADDR (the address of the ISEQ we _want_ to compile)
  push x15
  jmp function_stub_hit_trampoline

function_stub_hit_trampoline:
  pop x15 # get the ISEQ addr from gen_function_stub
  function prologue
  cpush ALL_JIT_REGS
  mov x0, x15 # currently x15 is 0xISEQADDR
  mov x1, CFP
  mov x2, SP
  blr function_stub_hit
  mov x15, x0 # write jump address to x15 (code pointer for compiled iseq)
  cpop ALL_JIT_REGS
  function epilogue
  jmp x15

@matzbot matzbot requested a review from a team February 25, 2026 20:35
@launchable-app

This comment has been minimized.

Before this change, gen_function_stub and
gen_function_stub_hit_trampoline communicated via a scratch register.
We would like gen_function_stub_hit_trampoline to have more freedom with
regard to the registers it uses, especially for the CCall in to
function_stub_hit.  Instead of communicating via scratch register, we'll
communicate via stack.

Practically speaking, this means:

* Stop using x15 (scratch reg) to communicate iseq call addr from call
  stub to function sub hit trampoline; use stack instead
* Don't try to CCall with x15 as first argument; can't use scratch reg
  in parallel move of arguments

Here is pseudo assembly of before this commit:

```
some_send_direct_in_a_ruby_method(JIT code):
  mov x15, gen_function_stub
  mov x0, self
  mov x1, 1
  blr x15

gen_function_stub:
  mov x15, 0xISEQADDR (the address of the ISEQ we _want_ to compile)
  jmp function_stub_hit_trampoline

function_stub_hit_trampoline:
  function prologue
  cpush ALL_JIT_REGS
  mov x0, x15 # currently x15 is 0xISEQADDR
  mov x1, CFP
  mov x2, SP
  blr function_stub_hit
  mov x15, x0 # write jump address to x15 (code pointer for compiled iseq)
  cpop ALL_JIT_REGS
  function epilogue
  jmp x15
```

Here is pseudo assembly of after this commit:

```
some_send_direct_in_a_ruby_method(JIT code):
  mov x15, gen_function_stub
  mov x0, self
  mov x1, 1
  blr x15

gen_function_stub:
  mov x15, 0xISEQADDR (the address of the ISEQ we _want_ to compile)
  push x15
  jmp function_stub_hit_trampoline

function_stub_hit_trampoline:
  pop x15 # get the ISEQ addr from gen_function_stub
  function prologue
  cpush ALL_JIT_REGS
  mov x0, x15 # currently x15 is 0xISEQADDR
  mov x1, CFP
  mov x2, SP
  blr function_stub_hit
  mov x15, x0 # write jump address to x15 (code pointer for compiled iseq)
  cpop ALL_JIT_REGS
  function epilogue
  jmp x15
```
@tenderlove tenderlove enabled auto-merge (squash) February 25, 2026 21:31
@tenderlove tenderlove merged commit 9ab1dfa into ruby:master Feb 25, 2026
90 checks passed
@tenderlove tenderlove deleted the decouple-stubs branch February 25, 2026 22:13
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.

2 participants