diff options
author | Alan Wu <XrXr@users.noreply.github.com> | 2022-12-15 15:10:14 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-15 15:10:14 -0500 |
commit | 5fa608ed79645464bf80fa318d89745159301471 (patch) | |
tree | 725a7c17fef47c78af9bb60008b1d6a6ed6e0c8f /shape.c | |
parent | 53db8fb450a06d6eea8c7452a006b17bd9354c67 (diff) | |
download | ruby-5fa608ed79645464bf80fa318d89745159301471.tar.gz |
YJIT: Fix code GC freeing stubs with a trampoline (#6937)
Stubs we generate for invalidation don't necessarily co-locate with the
code that jump to the stub. Since we rely on co-location to keep stubs
alive as they are in the outlined code block, it used to be possible for
code GC inside branch_stub_hit() to free the stub that's its direct
caller, leading us to return to freed code after.
Stubs used to look like:
```
mov arg0, branch_ptr
mov arg1, target_idx
mov arg2, ec
call branch_stub_hit
jmp return_reg
```
Since the call and the jump after the call is the same for all stubs, we
can extract them and use a static trampoline for them. That makes
branch_stub_hit() always return to static code. Stubs now look like:
```
mov arg0, branch_ptr
mov arg1, target_idx
jmp trampoline
```
Where the trampoline is:
```
mov arg2, ec
call branch_stub_hit
jmp return_reg
```
Code GC can now free stubs without problems since we'll always return
to the trampoline, which we generate once on boot and lives forever.
This might save a small bit of memory due to factoring out the static
part of stubs, but it's probably minor.
[Bug #19234]
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
Diffstat (limited to 'shape.c')
0 files changed, 0 insertions, 0 deletions