| Age | Commit message (Collapse) | Author |
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
The last parameter to rb_struct_define_under needs to be NULL otherwise
we can get a SEGV.
|
|
|
|
|
|
|
|
This script is an lldb helper that just loops through all the comments
stored and prints out the comment along with the address corresponding
to the comment.
For example, I'm crashing in JIT code at address 0x0000000110000168.
Using the `lc` helper I can see that it's probably crashing inside the
exit back to the interpreter
```
(lldb) bt 5
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x22220021)
frame #0: 0x0000000110000168
* frame #1: 0x00000001002b5ff5 miniruby`invoke_block_from_c_bh [inlined] invoke_block(ec=0x0000000100e05350, iseq=0x0000000100c1ff10, self=0x0000000100c76cc0, captured=<unavailable>, cref=0x0000000000000000, type=<unavailable>, opt_pc=<unavailable>) at vm.c:1268:12
frame #2: 0x00000001002b5f7d miniruby`invoke_block_from_c_bh [inlined] invoke_iseq_block_from_c(ec=<unavailable>, captured=<unavailable>, self=0x0000000100c76cc0, argc=2, argv=<unavailable>, kw_splat=0, passed_block_handler=0x0000000000000000, cref=0x0000000000000000, is_lambda=<unavailable>, me=0x0000000000000000) at vm.c:1340
frame #3: 0x00000001002b5e14 miniruby`invoke_block_from_c_bh(ec=<unavailable>, block_handler=<unavailable>, argc=<unavailable>, argv=<unavailable>, kw_splat=0, passed_block_handler=0x0000000000000000, cref=0x0000000000000000, is_lambda=<unavailable>, force_blockarg=0) at vm.c:1358
frame #4: 0x000000010029860b miniruby`rb_yield_values(n=<unavailable>) at vm_eval.c:0
(lldb) lc
0x11000006d "putobject_INT2FIX_1_"
0x110000083 "leave"
0x110000087 "check for interrupts"
0x110000087 "RUBY_VM_CHECK_INTS(ec)"
0x110000098 "check for finish frame"
0x1100000ed "getlocal_WC_0"
0x110000107 "getlocal_WC_1"
0x11000012a "opt_send_without_block"
0x110000139 "opt_send_without_block"
0x11000013c "exit to interpreter"
```
|
|
|
|
Basically the same thing as opt_mod, but for multiplying.
|
|
|
|
|
|
|
|
This adds guards
|
|
In jit_guard_known_klass whenever we encounter a new class should
recompile the current instruction.
However, previously once jit_guard_known_klass had guarded for a heap
object it would not recompile for any immediate (special const) objects
arriving afterwards and would take a plain side-exit instead of a chain
guard.
This commit uses jit_chain_guard inside jit_guard_known_klass instead of
the plain side exit, so that we can recompile for any special constants
arriving afterwards.
|
|
|
|
|
|
|
|
presumably-unneeded strncpy just to be sure.
|
|
|
|
|
|
|
|
I'm looking through the places where YJIT needs notifications. It looks
like these changes to gc.c and vm_callinfo.h have become unnecessary
since 84ab77ba592. This commit just makes the diff against upstream
smaller, but otherwise shouldn't change any behavior.
|
|
|
|
|
|
|
|
|
|
For use in development for writing `test.rb` and running with `make
run`.
|
|
|
|
We recently added the ability to optimize a known cfunc with custom code
generation for it.
Previously we performed this lookup with a switch statement on the
address of the c function being called. This commit swaps that out for a
hash lookup on the method definition. For now I've kept this limited
this to cfuncs, but it wouldn't take significant changes to make this
work for other method types.
This implemenation is similar to how the interpreter keeps track of
which BOPs (basic operations) are redefined
This has a few advantages:
- Doesn't the C function's symbol to be exported (they're often static)
- This could support VM_METHOD_TYPE_OPTIMIZED in the future.
- This could support VM_METHOD_TYPE_ISEQ in the future. Kernel#class
would be a good candidate for this since to yjit it will just be a
constant push as we already know the class through BBV.
- Slightly cleaner to declare
- Less tightly coupled to each method's implementation
And a couple minor trade-offs:
- The looser coupling could be seen as a disadvantage (I don't think so,
- If a cfunc is defined multiple times we would need to declare it on
each definition. ex. BasicObject#== and BasicObject#equal?. This is
rare compared to using an alias.
|
|
|
|
|
|
|
|
This adds a method to blocks to get outgoing ids, then uses the outgoing
ids to generate a graphviz graph. Two methods were added to the Block
object. One method returns an id for the block, which is just the
address of the underlying block. The other method returns a list of
outgoing block ids. We can use Block#id in conjunction with
Block#outgoing_ids to construct a graph of blocks
|
|
|
|
Just happened to run across this, so lets fix them
|
|
As an optimization, multiple objects could share the same singleton
class. The optimization introduced in 6698e433934d810b16ee3636b63974c0a75c07f0
wasn't handling this correctly so was generating guards that never pass
for the inputs we defer compilation to wait for. After generating
identical code multiple times and failing, the call site is falsely
recognized as megamorphic and it side exits. See disassembly for the
following before this commit:
def foo(obj)
obj.itself
end
o = Object.new.singleton_class
foo(o)
puts YJIT.disasm(method(:foo))
See also: comment in rb_singleton_class_clone_and_attach().
|
|
The added test fails with SystemStackError with --yjit-call-threshold=1.
|
|
When checking for T_HASH, which is Qnil and when the type check succeeds
we were outputting to the stack a Qnil instead of a Qtrue.
|
|
Singleton classes should only ever be attached to one object. This means
that checking for the object should be the same as checking for the
class. This should be slightly faster by avoiding one memory acccess as
well as allowing us to skip checking if the receiver is a heap object.
This will be most common for calling class methods.
|
|
jit_rb_obj_not() wants to access the type information of the receiver,
but we were discarding type info of locals before jit_rb_obj_not() runs
unncessarily.
There are also cases we are unncessarily discarding local type info. For
example, ivar reader and setter methods can never change local
variables.
|
|
This commit improves opt_not by making it correct when TrueClass#!
and/or FalseClass#! is defined and genearting better code when the
receiver is a heap object.
guard_known_class() can now handle true, false, and nil, and we
introduce a codegen function reimplementing rb_obj_not(), used when we
know we are calling into rb_obj_not().
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Noah Gibbs <the.codefolio.guy@gmail.com>
|
|
invokebuiltin_delegate can be run in place of
invokebuiltin_delegate_leave because there is always a leave instruction
afterwards (the interpreter takes advantage of this as well when
rewriting iseqs for tracing).
|
|
invokebuiltin_delegate is a special version of invokebuiltin used for
sending a contiguous subset of the current method's locals.
In some cases YJIT would already handle this for trivial cases it could
be inlined, implementing this OP allows it to work when the method isn't
inlinable (not marked as 'inline', does more than just call, not called
from yjit, etc).
|
|
|
|
|