Before this change, when we encounter a constant cache that is specific
to a lexical scope, we unconditionally exit. This change falls back to
the interpreter's cache in this situation.
This should help constant expressions in `class << self`, which is popular
at Shopify due to the style guide.
This change relies on the cache being warm while compiling to detect the
need for checking the lexical scope for simplicity.
YJIT expects the VM to invalidate opt_getinlinecache when updating the
constant cache, and the invalidation used to happen even when YJIT can't
use the cached value.
Once the first invalidation happens, the block for opt_getinlinecache
becomes a stub. When the stub is hit, YJIT fails to compile the
instruction as the cache is not usable. The stub becomes a block that
exits for opt_getinlinecache which can be invalidated again. Some
workloads that bust the interpreter's constant cache can create an
invalidation loop with this behavior.
Check if the cache is usable become doing invalidation to fix this
problem.
In the test harness, evaluate the test script in a lambda instead of a
proc so `return` doesn't return out of the harness.
Send instructions currently generate the exact same side exit twice.
Cache the exit the first time we generate it. Also add a comment
explaining what side exits do.
Closes GH-117.
We need to fire the write barrier during ivar set. This function
extracts the write barrier function then calls it.
Co-Authored-By: John Hawthorn <john@hawthorn.email>
We have a check to ensure we don't have to push args on the stack to
call a cfunc with many args. However we never need to use the stack for
variadic cfuncs, so we shouldn't care about the number of arguments.
The code path for leave that returns to the interpreter
(gen_leave() -> yjit_gen_leave_exit()) used to have the logic:
```
cfp->sp++;
cfp->sp[-1] = return_val;
cfp->sp--;
return return_val;
```
The SP changes it made was unnecessary and this change removes it.
After this change, `leave` doesn't adjust the `cfp->sp` of the caller
and only writes `cfp->sp[0]`. To accomodate this in the JIT-to-JIT
return case, return stubs have an `sp_offset` of 1.
The change removes sp adjustment from the JIT-to-JIT return case, too,
making it more efficient. Also, since the C method case of `send`
has an `sp_offset` of 1 after the call, this change enables block
version sharing.