diff options
| author | Rian McGuire <rian@rian.id.au> | 2025-04-28 22:50:29 +1000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-04-28 21:50:29 +0900 |
| commit | 80a1a1bb8ae8435b916ae4f66a483e91ad31356a (patch) | |
| tree | 10f0477439a3f779be6cd50656136fbc1f165402 /include/ruby | |
| parent | 37db51b4412ef385d9c57a2b106d9014e69abeab (diff) | |
YJIT: Fix potential infinite loop when OOM (GH-13186)
Avoid generating an infinite loop in the case where:
1. Block `first` is adjacent to block `second`, and the branch from `first` to
`second` is a fallthrough, and
2. Block `second` immediately exits to the interpreter, and
3. Block `second` is invalidated and YJIT is OOM
While pondering how to fix this, I think I've stumbled on another related edge case:
1. Block `incoming_one` and `incoming_two` both branch to block `second`. Block
`incoming_one` has a fallthrough
2. Block `second` immediately exits to the interpreter (so it starts with its exit)
3. When Block `second` is invalidated, the incoming fallthrough branch from
`incoming_one` might be rewritten first, which overwrites the start of block
`second` with a jump to a new branch stub.
4. YJIT runs of out memory
5. The incoming branch from `incoming_two` is then rewritten, but because we're
OOM we can't generate a new stub, so we use `second`'s exit as the branch
target. However `second`'s exit was already overwritten with a jump to the
branch stub for `incoming_one`, so `incoming_two` will end up jumping to
`incoming_one`'s branch stub.
Fixes [Bug #21257]
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/13186
Merged-By: XrXr
Diffstat (limited to 'include/ruby')
0 files changed, 0 insertions, 0 deletions
