Previously all stack operands would become unknown once the stack grew
beyond a certain size. This worked, but unnecessarily hid available
information.
If we hit this at PC > 0 (ie. with an optional argument) the provided
types and context are likely incorrect and it is likely this block can't
be used.
If `--disable-jit-support` is passed to configure, then `jit_func` is
removed from the iseq body and we can't compile YJIT. This commit
detects when the JIT function pointer is gone and disables YJIT in that
case.
Methods with optional parameters don't always start executing at the
first PC, but we compile all methods assuming that they do. This commit
adds a guard to ensure that we're actually starting at the first PC for
methods with optional params
We clear locals when we know their values might change (ex. when
performing a method call). However previously values on the stack which
were originally pushed from a local would still point back to that
local.
With this commit, when clearing locals, we'll now iterate over the
mappings of the stack and copy the known type from the local to the
stack mapping, removing the association to the local.
This should mean both that we'll retain any information we already know
about the local type, and that if a local is modified we won't
incorrectly infer it's new type from the existing value on the stack.
Make sure `opt_getinlinecache` is in a block all on its own, and
invalidate it from the interpreter when `opt_setinlinecache`.
It will recompile with a filled cache the second time around.
This lets YJIT runs well when the IC for constant is cold.
ASAN can catch these type of things for us, but the scraper can't
handle ASAN :/.
To be more resilient to refactoring, extend the lifetime of
`generic_ctx` in branch_stub_hit() too.
The old code decides branch->shape based on the write position of the
native code block, which is unsound in case the block already exists
and no new code is written to the write position.
Make this decision with the start address of the target block instead.
Also handle when the branch becomes smaller after patching.
This is playing it safe. Ruby headers rely on some macros generated by
autoconf that affect what system headers behave. We should take care to
bring in those configs before including systme headers to stay
consistent with the rest of Ruby.