Commit graph

196 commits

Author SHA1 Message Date
John Hawthorn
e527912fe0 Use jit_prepare_routine_call 2021-10-20 18:19:39 -04:00
John Hawthorn
69a2531249 Implement gen_putstring 2021-10-20 18:19:39 -04:00
Alan Wu
2bd99d7d7a typo, rename, comment 2021-10-20 18:19:39 -04:00
John Hawthorn
812597676b Avoid immediate side exits in checktype
Previously checktype only supported heap objects, however it's not
uncommon to receive an immediate, for example when string interpolating
a Symbol or Integer.
2021-10-20 18:19:39 -04:00
Alan Wu
54db64f7a5 filter out internal events. add comments. reorder 2021-10-20 18:19:39 -04:00
Alan Wu
4b815abb37 Lock, don't loock. 2021-10-20 18:19:39 -04:00
Alan Wu
bd876c243a TracePoint support
This change fixes some cases where YJIT fails to fire tracing events.
Most of the situations YJIT did not handle correctly involves enabling
tracing while running inside generated code.

A new operation to invalidate all generated code is added, which uses
patching to make generated code exit at the next VM instruction
boundary. A new routine called `jit_prepare_routine_call()` is
introduced to facilitate this and should be used when generating code
that could allocate, or could otherwise use `RB_VM_LOCK_ENTER()`.

The `c_return` event is fired in the middle of an instruction as opposed
to at an instruction boundary, so it requires special handling. C method
call return points are patched to go to a fucntion which does everything
the interpreter does, including firing the `c_return` event. The
generated code for C method calls normally does not fire the event.

Invalided code should not change after patching so the exits are not
clobbered. A new variable is introduced to track the region of code that
should not change.
2021-10-20 18:19:39 -04:00
Maxime Chevalier-Boisvert
0562459473 Redo the ivtable lookp once the ivar is set 2021-10-20 18:19:39 -04:00
Maxime Chevalier-Boisvert
b3e993a64b Make sure that there is always an index table entry for getivars 2021-10-20 18:19:39 -04:00
Jean Boussier
0dc3bba6f2 Allow to compile with --yjit-stats support but not the full RUBY_DEBUG
RUBY_DEBUG have a very significant performance overhead. Enough that
YJIT with RUBY_DEBUG is noticeably slower than the interpreter without
RUBY_DEBUG.

This makes it hard to collect yjit-stats in production environments.

By allowing to collect JIT statistics without the RUBy_DEBUG overhead,
I hope to make such use cases smoother.
2021-10-20 18:19:39 -04:00
eileencodes
2ba090a1f9 Add toregexp to yjit
The FIXME is there so we remember to investigate why insns clears the
temporary array. Is this necessary? If it's not we can remove it from
both.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2021-10-20 18:19:39 -04:00
Maxime Chevalier-Boisvert
dd5082d7ca Use cmov to handle Qundef case in getivar instead of side-exit 2021-10-20 18:19:39 -04:00
Maxime Chevalier-Boisvert
c4b99d6a42 Add ASM comment 2021-10-20 18:19:39 -04:00
John Hawthorn
e18b0b6eba Implement putspecialobject 2021-10-20 18:19:39 -04:00
John Hawthorn
3edf29668e Add opt_regexpmatch2 2021-10-20 18:19:39 -04:00
John Hawthorn
595fdf8d66 Assign directly to C_ARG_REGS now when possible 2021-10-20 18:19:39 -04:00
John Hawthorn
8fa0ee4d40 Use callee-saved regs for REG_SP, REG_EP, REG_CFP 2021-10-20 18:19:39 -04:00
John Hawthorn
48dca3348a Move yjit_type_of_value into yjit_core.c 2021-10-20 18:19:38 -04:00
John Hawthorn
d78ea4abec Implement verify_ctx for debugging 2021-10-20 18:19:38 -04:00
John Hawthorn
a02002dc4f More detection of immediate constants 2021-10-20 18:19:38 -04:00
eileencodes
d2e8b99b5b Implement tostring instruction for yjit
Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2021-10-20 18:19:38 -04:00
John Hawthorn
6c80150d40 Introduce ctx_{get,set}_opnd_mapping 2021-10-20 18:19:38 -04:00
John Hawthorn
4ea69e5c0b Rename to ctx_upgrade_opnd_type 2021-10-20 18:19:38 -04:00
John Hawthorn
53079ca585 Return if fixnums impossible 2021-10-20 18:19:38 -04:00
Alan Wu
f4f940e5a6 Save PC and SP before accessing globals
These instructions are marked as not leaf in insns.def, which indicate
that they could raise exceptions and/or call Ruby methods.
2021-10-20 18:19:38 -04:00
eileencodes
b91078ea74 Add setglobal to yjit
Adds yjit support for setting global variables.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
Co-authored-by: John Hawthorn <john@hawthorn.email>
2021-10-20 18:19:38 -04:00
eileencodes
50029fb127 Add getglobal to yjit
Adds getglobal to yjit and a test for it.

Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2021-10-20 18:19:38 -04:00
Aaron Patterson
84a1e04e58 Change register definitions to match the entry point calling convention
The JIT entry point passes the CFP as RSI and the EC as RDI.  Lets match
that so we don't have to shuffle registers around.
2021-10-20 18:19:38 -04:00
Aaron Patterson
05b5a7f011 Add a guard that we start executing on the first PC
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
2021-10-20 18:19:37 -04:00
Aaron Patterson
0fdcdd267f fix alignment 2021-10-20 18:19:37 -04:00
Aaron Patterson
d0174d99c6 Always use ret to return to the interpreter
Always using `ret` to return to the interpreter means that we never have
to check the VM_FRAME_FLAG_FINISH flag.

In the case that we return `Qundef`, the interpreter will execute the
cfp.  We can take advantage of this by setting the PC to the instruction
we can't handle, and let the interpreter pick up the ball from there.

If we return a value other than Qundef, the interpreter will take that
value as the "return value" from the JIT and push that to the SP of the
caller

The leave instruction puts the return value on the top of the calling
frame's stack.  YJIT does the same thing for leave instructions.
However, when we're returning back to the interpreter, the leave
instruction _should not_ put the return value on the top of the stack,
but put it in RAX and use RET.  This commit pops the last value from the
stack pointer and puts it in RAX so that the interpreter is happy with
SP.
2021-10-20 18:19:37 -04:00
Kevin Newton
9a436da064 Ensure we guard the value before we return
Otherwise you can end up not implicitly calling `to_ary`, which if it has side-effects will result in different behavior.
2021-10-20 18:19:37 -04:00
Kevin Newton
341d5bdcb2 Code review for expandarray and tests 2021-10-20 18:19:37 -04:00
Kevin Newton
97025db90e Convert jumps to cmov 2021-10-20 18:19:37 -04:00
Kevin Deisz
bfde30c326 Implement expandarray 2021-10-20 18:19:37 -04:00
Kevin Newton
be648e0940 Implement splatarray 2021-10-20 18:19:37 -04:00
John Hawthorn
dc8aca1883 Use push and pop in jit_rb_obj_not to avoid corrupting types 2021-10-20 18:19:37 -04:00
John Hawthorn
0c390e9965 Add assertions of types in jit_guard_known_klass 2021-10-20 18:19:37 -04:00
Kevin Deisz
ba9aa1f8ef Implement opt_div 2021-10-20 18:19:37 -04:00
Kevin Deisz
b0ae4fdcfb Implement opt_mult
Basically the same thing as opt_mod, but for multiplying.
2021-10-20 18:19:37 -04:00
Maxime Chevalier-Boisvert
6cb4edd73f Implement swap instruction 2021-10-20 18:19:37 -04:00
John Hawthorn
9e0a56fb24 Add FLONUM detection 2021-10-20 18:19:37 -04:00
John Hawthorn
dfc5e5e35b Support guards against symbols and integers
This adds guards
2021-10-20 18:19:37 -04:00
John Hawthorn
c3f264b62c Allow chaining on immediate guard
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.
2021-10-20 18:19:37 -04:00
John Hawthorn
94cb5a6b1e Implement opt_neq 2021-10-20 18:19:36 -04:00
Alan Wu
3996e0ab07 Add tests, comments, and an assert for invokesuper 2021-10-20 18:19:36 -04:00
John Hawthorn
71560f8804 Add opt_size and opt_length 2021-10-20 18:19:36 -04:00
John Hawthorn
e4bf905a28 Use an st_table for optimized method codegen
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.
2021-10-20 18:19:36 -04:00
Alan Wu
0cd3b97e02 Handle non-material empty singleton class properly
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().
2021-10-20 18:19:36 -04:00
Alan Wu
89110590a3 Disable invokesuper codegen for now. Add test
The added test fails with SystemStackError with --yjit-call-threshold=1.
2021-10-20 18:19:36 -04:00