Граф коммитов

98 Коммитов

Автор SHA1 Сообщение Дата
Takashi Kokubun e7c71c6c92
Make mjit_cont sharable with YJIT (#6556)
* Make mjit_cont sharable with YJIT

* Update dependencies

* Update YJIT binding
2022-10-17 09:27:59 -07:00
Takashi Kokubun b726c06e7e
Allow hooking a different method after --mjit=pause
The interface is similar to RubyVM::ISeq.translate; it's used if defined.
Same as --mjit=pause, this is an undocumented feature for MJIT experiments.
2022-09-06 15:52:02 +09:00
Takashi Kokubun 5b3bd91fcb
Add an option to lazily boot MJIT for experiments
You may use `RUBYOPT=--mjit=pause irb` to play with RubyVM::MJIT::C,
control the boot timing of MJIT, or customize the implementation while
paused. It's an undocumented feature for such experiments.
2022-09-06 15:45:10 +09:00
Takashi Kokubun f6925fab85
Do not fork the process on --mjit-wait
fork is for parallel compilation, but --mjit-wait cancels it.
It's more useful to not fork it for binding.irb, debugging, etc.
2022-09-06 15:42:02 +09:00
Takashi Kokubun cfa40e225a
Prefer stdbool for MJIT options
same motivation as d6f21b308b
2022-09-03 20:01:51 -07:00
Takashi Kokubun 485019c2bd
Rename mjit_exec to jit_exec (#6262)
* Rename mjit_exec to jit_exec

* Rename mjit_exec_slowpath to mjit_check_iseq

* Remove mjit_exec references from comments
2022-08-19 23:57:17 -07:00
Nobuyoshi Nakada b880576e59 yjit.h is not necessary for all sources using mjit.h 2022-08-17 15:23:01 +09:00
Nobuyoshi Nakada 81fbc8d553 Move `mjit_exec` to vm.c 2022-08-17 15:23:01 +09:00
Takashi Kokubun 1162523bae
Remove MJIT worker thread (#6006)
[Misc #18830]
2022-06-15 09:40:54 -07:00
Peter Zhu 5f10bd634f Add ISEQ_BODY macro
Use ISEQ_BODY macro to get the rb_iseq_constant_body of the ISeq. Using
this macro will make it easier for us to change the allocation strategy
of rb_iseq_constant_body when using Variable Width Allocation.
2022-03-24 10:03:51 -04:00
Alan Wu 7c08538aa3 Cleanup diff against upstream. Add comments
I did a `git diff --stat` against upstream and looked at all the files
that are outside of YJIT to come up with these minor changes.
2021-10-20 18:19:42 -04:00
Alan Wu 735b3a7748 Tweak mjit_exec() to remove YJIT symbol exports
We were exporting a couple of symbols in yjit.h because they could be
used by code generated by MJIT. We don't want MJIT calling into YJIT
code anyways so let's stop exporting them to libruby.so.

Also adjust indentation and comments in mjit_exec().
2021-10-20 18:19:42 -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
Alan Wu d03b7f77d4 Fix GCC warnings
Mostly unused and uninitialized warnings here and there
2021-10-20 18:19:32 -04:00
Jose Narvaez 4e2eb7695e Yet Another Ruby JIT!
Renaming uJIT to YJIT. AKA s/ujit/yjit/g.
2021-10-20 18:19:31 -04:00
Maxime Chevalier-Boisvert 824fea684f Thread EC through jit state. Add codegen status enum. 2021-10-20 18:19:30 -04:00
Maxime Chevalier-Boisvert 0710bec01e Implement --ujit-call-threshold 2021-10-20 18:19:30 -04:00
Maxime Chevalier-Boisvert e4c65ec49c Refactor uJIT code into more files for readability 2021-10-20 18:19:26 -04:00
Alan Wu 498fe0fb52 Move MicroJIT compilation threshold into MicroJIT's header 2021-10-20 18:19:25 -04:00
Alan Wu 595e3a94fd Fix MicroJIT logic in MJIT exec 2021-10-20 18:19:25 -04:00
Alan Wu 6f4d17d622 Never compile with MicroJIT when MJIT is enabled
There is a crash in there that we don't want to worry about for now.
2021-10-20 18:19:25 -04:00
Alan Wu ba45aff16b Don't call MicroJIT from MJIT output 2021-10-20 18:19:25 -04:00
Alan Wu 8bda11f690 MicroJIT: compile after ten calls 2021-10-20 18:19:25 -04:00
Takashi Kokubun b3f8c491ef
Print JIT cancel when all JIT-ed code is cancelled 2021-08-12 23:11:38 -07:00
Takashi Kokubun c5e8a49bde
Avoid enqueueing the same ISeq twice
by a race condition by multiple Ractors.

Atmically incrementing body->total_calls may have its own cost, so for
now we intentionally leave the unreliable total_calls. So we allow an
ISeq to be never pushed when you use multiple Ractors. However, if you
enqueue a single ccan node twice, get_from_list loops infinitely. Thus
this patch takes care of such a situation.
2021-06-10 00:32:24 -07:00
Takashi Kokubun 07c05b6fe9
Drop JIT_ISEQ_SIZE_THRESHOLD
Compiling everything seems to contributed to improving the final
performance in general. MJIT's compilation is slow anyway, especially
when you need to wait for JIT compaction.

This might make sense for short-time benchmarks like Optcarrot with
default parameters, but it didn't give benefits in my local environment.
2021-05-31 21:12:48 -07:00
Koichi Sasada e7fc353f04 enable constant cache on ractors
constant cache `IC` is accessed by non-atomic manner and there are
thread-safety issues, so Ruby 3.0 disables to use const cache on
non-main ractors.

This patch enables it by introducing `imemo_constcache` and allocates
it by every re-fill of const cache like `imemo_callcache`.
[Bug #17510]

Now `IC` only has one entry `IC::entry` and it points to
`iseq_inline_constant_cache_entry`, managed by T_IMEMO object.

`IC` is atomic data structure so `rb_mjit_before_vm_ic_update()` and
`rb_mjit_after_vm_ic_update()` is not needed.
2021-01-05 02:27:58 +09:00
Takashi Kokubun 095972e799
Skip mjit_wait if iseq is not a target 2021-01-04 00:24:02 -08:00
Takashi Kokubun ac2df89113
Stop managing valid class serials
`mjit_valid_class_serial_p` has no longer been used since b9007b6c54.
2020-12-29 23:01:11 -08:00
Takashi Kokubun 15b81edd86
MJIT is enabled whenever an MJIT header is used
```
$ benchmark-driver -v --rbenv 'before --jit;after --jit' --repeat-count=4 --alternate --output=all benchmark.yml
before --jit: ruby 3.0.0dev (2020-12-22T05:16:39Z master 692af8e8f8) +JIT [x86_64-linux]
after --jit: ruby 3.0.0dev (2020-12-22T06:05:59Z master d2ca23fdbc) +JIT [x86_64-linux]
last_commit=MJIT is enabled whenever an MJIT header is used
Calculating -------------------------------------
                             before --jit           after --jit
Optcarrot 180 frames    86.61115328062763     91.49245232931852 fps
                        90.18653732453176     92.31139517827663
                        91.29817884736318     93.84437713805814
                        92.76118222412521     93.91929147901106
```
2020-12-21 22:07:40 -08:00
Takashi Kokubun 1fdc97f1b7
Mark active_units
to avoid SEGV on mjit_recompile and compact_all_jit_code.

For some reason, ISeqs on stack are sometimes GC-ed (why?) and therefore
it may run mjit_recompile on a GC-ed ISeq, which I expected d07183ec85
to fix but apparently it may refer to random things if already GC-ed.
Marking active_units would workaround the situation.
http://ci.rvm.jp/results/trunk-mjit-wait@phosphorus-docker/3292740

Also, while compact_all_jit_code was executed, we saw some SEGVs where
CCs seemed to be already GC-ed, meaning their owner ISeq was not marked
properly. Even if units are still in active_units, it's not guaranteed
that their ISeqs are in use. So in this case we need to mark active_units
for a legitimate reason.
http://ci.rvm.jp/results/trunk-mjit-wait@phosphorus-docker/3293277
http://ci.rvm.jp/results/trunk-mjit-wait@phosphorus-docker/3293090
2020-12-20 22:58:45 -08:00
Takashi Kokubun a574df14e4
Stop marking unit_queue
The original motivation of this marking was https://github.com/k0kubun/yarv-mjit/issues/20.
As wanabe said, there are multiple options to mitigate the issue, and
Eric Wong introduced another fix at 143776f6fe by checking unit->iseq
inside the lock.

Therefore this particular condition has been covered in two ways, and
the script given by wanabe no longer crashes without mjit_mark().
2020-12-20 22:03:20 -08:00
Takashi Kokubun 53babf35ef
Inline getconstant on JIT (#3906)
* Inline getconstant on JIT

* Support USE_MJIT=0
2020-12-16 06:24:07 -08:00
Takashi Kokubun 2700df3c9d
ruby/internal/config.h needs to be included first
to define USE_MJIT.
2020-11-22 21:02:01 -08:00
Takashi Kokubun 0a2b987696
Make --disable-jit-support compile
vm_core.h needs to be included to know rb_execution_context_t, etc.
I also added a trivial refactoring in mjit.c and missing dependency for
process.c.
2020-11-22 20:55:33 -08:00
Takashi Kokubun 55866565c2
Combine mjit.h and internal/mjit.h
It's very hard to remember which mjit.h has what.
2020-11-22 20:22:21 -08:00
Takashi Kokubun bb4a2351cb
Do not JIT inline builtin methods
It's probably not worth it because there's nothing we can optimize in
such builtin methods. It's worth JIT only when inlined.
2020-06-24 22:59:34 -07:00
Takashi Kokubun 083a17a82a
Carve out mjit_exec_slowpath
and mark it as COLDFUN on JIT, assuming enqueue usually happens on VM.
2020-05-27 01:41:04 -07:00
Takashi Kokubun 61b14bb32b
Eliminate a call instruction on JIT cancel path
by calling combined functions specialized for each cancel type.

I'm hoping to improve locality of hot code, but this patch's impact should
be insignificant.
2020-05-26 23:01:52 -07:00
卜部昌平 9e41a75255 sed -i 's|ruby/impl|ruby/internal|'
To fix build failures.
2020-05-11 09:24:08 +09:00
卜部昌平 d7f4d732c1 sed -i s|ruby/3|ruby/impl|g
This shall fix compile errors.
2020-05-11 09:24:08 +09:00
Takashi Kokubun f5ddbba9a2
Include unit id in a function name of an inlined method
I'm trying to make it possible to include all JIT-ed code in a single C
file. This is needed to guarantee uniqueness of all function names
2020-04-30 23:08:13 -07:00
卜部昌平 4ff3f20540 add #include guard hack
According to MSVC manual (*1), cl.exe can skip including a header file
when that:

- contains #pragma once, or
- starts with #ifndef, or
- starts with #if ! defined.

GCC has a similar trick (*2), but it acts more stricter (e. g. there
must be _no tokens_ outside of #ifndef...#endif).

Sun C lacked #pragma once for a looong time.  Oracle Developer Studio
12.5 finally implemented it, but we cannot assume such recent version.

This changeset modifies header files so that each of them include
strictly one #ifndef...#endif.  I believe this is the most portable way
to trigger compiler optimizations. [Bug #16770]

*1: https://docs.microsoft.com/en-us/cpp/preprocessor/once
*2: https://gcc.gnu.org/onlinedocs/cppinternals/Guard-Macros.html
2020-04-13 16:06:00 +09:00
卜部昌平 9e6e39c351
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
2020-04-08 13:28:13 +09:00
Takashi Kokubun b736ea63bd
Optimize exivar access on JIT-ed getivar
JIT support of dd723771c1.

$ benchmark-driver -v --rbenv 'before;before --jit;after --jit' benchmark/mjit_exivar.yml --repeat-count=4
before: ruby 2.8.0dev (2020-03-30T12:32:26Z master e5db3da9d3) [x86_64-linux]
before --jit: ruby 2.8.0dev (2020-03-30T12:32:26Z master e5db3da9d3) +JIT [x86_64-linux]
after --jit: ruby 2.8.0dev (2020-03-31T05:57:24Z mjit-exivar 128625baec) +JIT [x86_64-linux]
Calculating -------------------------------------
                         before  before --jit  after --jit
         mjit_exivar    57.944M       53.579M      54.471M i/s -    200.000M times in 3.451588s 3.732772s 3.671687s

Comparison:
                      mjit_exivar
              before:  57944345.1 i/s
         after --jit:  54470876.7 i/s - 1.06x  slower
        before --jit:  53579483.4 i/s - 1.08x  slower
2020-03-30 23:16:35 -07:00
Takashi Kokubun f6a54e6e46
Add debug counter for unload_units
changing add_iseq_to_process's debug counter name as well for comparison
2020-03-15 00:24:18 -07:00
Takashi Kokubun 8562bfd150
Move code to mark jit_unit's cc_entries to mjit.c 2020-03-12 22:21:32 -07:00
Takashi Kokubun 69f377a3d6
Internalize rb_mjit_unit definition again
Fixed a TODO in b9007b6c54
2020-02-26 00:27:29 -08:00
Koichi Sasada b9007b6c54 Introduce disposable call-cache.
This patch contains several ideas:

(1) Disposable inline method cache (IMC) for race-free inline method cache
    * Making call-cache (CC) as a RVALUE (GC target object) and allocate new
      CC on cache miss.
    * This technique allows race-free access from parallel processing
      elements like RCU.
(2) Introduce per-Class method cache (pCMC)
    * Instead of fixed-size global method cache (GMC), pCMC allows flexible
      cache size.
    * Caching CCs reduces CC allocation and allow sharing CC's fast-path
      between same call-info (CI) call-sites.
(3) Invalidate an inline method cache by invalidating corresponding method
    entries (MEs)
    * Instead of using class serials, we set "invalidated" flag for method
      entry itself to represent cache invalidation.
    * Compare with using class serials, the impact of method modification
      (add/overwrite/delete) is small.
    * Updating class serials invalidate all method caches of the class and
      sub-classes.
    * Proposed approach only invalidate the method cache of only one ME.

See [Feature #16614] for more details.
2020-02-22 09:58:59 +09:00
卜部昌平 6788c375b1 suppress clang warnings
Starting clang 11, casts between pointer and (narrower-than-pointer) int
are now warned.  However all such thing in our repository are guaranteed
safe.  Let's suppress the warnings.
2020-02-20 11:46:54 +09:00