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

72 Коммитов

Автор SHA1 Сообщение Дата
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
卜部昌平 5e22f873ed decouple internal.h headers
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead.  This would significantly
speed up incremental builds.

We take the following inclusion order in this changeset:

1.  "ruby/config.h", where _GNU_SOURCE is defined (must be the very
    first thing among everything).
2.  RUBY_EXTCONF_H if any.
3.  Standard C headers, sorted alphabetically.
4.  Other system headers, maybe guarded by #ifdef
5.  Everything else, sorted alphabetically.

Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
2019-12-26 20:45:12 +09:00
Nobuyoshi Nakada 4e03a7298b
Constified mjit_init 2019-12-01 20:26:28 +09:00
Takashi Kokubun a19d625e66
Allow specifying arbitrary MJIT flags by --jit-debug
This is a secret feature for me. It's only for testing and any behavior
with this flag override is unsupported.

I needed this because I sometimes want to add debug options but do not
want to disable optimizations, for using Linux perf.
2019-12-01 00:58:47 -08:00
卜部昌平 c9ffe751d1 delete unused functions
Looking at the list of symbols inside of libruby-static.a, I found
hundreds of functions that are defined, but used from nowhere.

There can be reasons for each of them (e.g. some functions are
specific to some platform, some are useful when debugging, etc).
However it seems the functions deleted here exist for no reason.

This changeset reduces the size of ruby binary from 26,671,456
bytes to 26,592,864 bytes on my machine.
2019-11-14 20:35:48 +09:00
Takashi Kokubun 82332c7d8b
Rename mjit_gc_finish_hook to mjit_gc_exit_hook
because @ko1 said "gc_finish" is confusing like a finish of entire GC
process
2019-05-15 23:14:07 -07:00
k0kubun ef73bee811 Prefix rb_ to MJIT wait call since it's exported
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67643 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 07:37:29 +00:00
tenderlove c784da1744 Update MJIT references
ISeq can move, so we need to tell MJIT where the new location is.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67624 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 02:40:41 +00:00
k0kubun fcd679ed11 Recompile without method inlining
if cancel happens in an inlined method.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67575 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-16 17:02:35 +00:00
k0kubun fa13bb1a6f Unify comment styles across MJIT sources
I'm writing `//` comments in newer MJIT code after C99 enablement
(because I write 1-line comments more often than multi-line comments
 and `//` requires fewer chars on 1-line) and then they are mixed
with `/* */` now.

For consistency and to avoid the conversion in future changes, let me
finish the rewrite in MJIT-related code.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67533 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-14 05:26:46 +00:00
k0kubun 9b6b4674d7 Recompile JIT-ed code without optimization
based on inline cache when JIT cancel happens by that.

This feature was in the original MJIT implementation by Vladimir, but on
merging MJIT to Ruby it was removed for simplification. This commit adds
the functionality again for the following benchmark:

52f05781f6/concurrent-map/bench.rb
(shown float is duration seconds. shorter is better)

* Before
```
$ INHERIT=0 ruby -v bench.rb
ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux]
--
1.6507579649914987

$ INHERIT=0 ruby -v --jit bench.rb
ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux]
--
1.5091587850474752

$ INHERIT=1 ruby -v bench.rb
ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux]
--
1.6124781150138006

$ INHERIT=1 ruby --jit -v bench.rb
ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux]
--
1.7495657080435194 # <-- this
```

* After
```
$ INHERIT=0 ruby -v bench.rb
ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux]
last_commit=Recompile JIT-ed code without optimization
--
1.653559010999743

$ INHERIT=0 ruby --jit -v bench.rb
ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux]
last_commit=Recompile JIT-ed code without optimization
--
1.4738391840364784

$ INHERIT=1 ruby -v bench.rb
ruby 2.7.0dev (2019-04-13 trunk 67523) [x86_64-linux]
last_commit=Recompile JIT-ed code without optimization
--
1.645227018976584

$ INHERIT=1 ruby --jit -v bench.rb
ruby 2.7.0dev (2019-04-13 trunk 67523) +JIT [x86_64-linux]
last_commit=Recompile JIT-ed code without optimization
--
1.523708809982054 # <-- this
```

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67530 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-14 04:52:02 +00:00
k0kubun 5a6b0e39a1 Add debug counter for VM <-> MJIT calls
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67460 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-06 14:42:02 +00:00
k0kubun bb5ab13bf5 Add debug counters for MJIT
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67375 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-29 12:52:59 +00:00
k0kubun 4d426e28d2 Resurrect r67287 and r67288
I noticed that r67287 was illegal because memory allocated by `alloca`
was used after the stack is expired.

So I just replaced that with `malloc` and `free` for now.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67299 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-18 16:32:48 +00:00
k0kubun 78e87b7d4f Revert "Eliminate mjit_copy_job_t reference from mjit_worker"
This reverts commit ba51ae0109.

CI is failing again...

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67297 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-18 16:14:57 +00:00
k0kubun ba51ae0109 Eliminate mjit_copy_job_t reference from mjit_worker
Take 2 of r67287.

For some reasons, passing pointer of pointer on stack to a function
and assigning an addresse to a pointer dereferenced from the pointer
seems not working on mswin.

So I achieved to return multiple values by returning struct instead of
taking pointers.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67296 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-18 14:01:52 +00:00
k0kubun 908b530112 Revert "Request inline cache values from mjit_compile"
This reverts commit 4161674b2f.

Revert "Eliminate mjit_copy_job_t reference from mjit_worker"

This reverts commit d86a1aa045.

Reverting them because of CI failures

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67291 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-18 01:52:45 +00:00
k0kubun 4161674b2f Request inline cache values from mjit_compile
rather than preparing beforehand.

By having this change, implementing inlining by calling
`mjit_copy_cache_from_main_thread` for inlined methods was made
possible.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67288 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-17 18:29:30 +00:00
k0kubun 56bf732aaf mjit.c: use boolean type for boolean variables
and functions to clarify the intention and make sure it's not used in a
surprising way (like using 2, 3, ... other than 0, 1 even while it seems
to be a boolean).

This is a retry of r66775. It included some typos...

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66778 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-10 14:31:18 +00:00
k0kubun efd99b5331 Revert "mjit.c: use boolean type for boolean variables"
This reverts commit bb1a1aeab0.

We hit something on ci.rvm.jp, reverting until investigation is done.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66776 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-10 13:29:29 +00:00
k0kubun bb1a1aeab0 mjit.c: use boolean type for boolean variables
and functions to clarify the intention and make sure it's not used in a
surprising way (like using 2, 3, ... other than 0, 1 even while it seems
to be a boolean).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66775 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-10 13:21:58 +00:00
k0kubun 67485fee42 vm_trace.c: MJIT-limited thread-safety for postponed_job
[Bug #15316]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66001 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-26 15:47:20 +00:00
k0kubun 5b12501163 Revert "process.c: try to workaroun SEGV by r65994"
This reverts commit 0e6aba22c6.

because it didn't help, at all.
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/1480207

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65998 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-26 15:12:30 +00:00
k0kubun 0e6aba22c6 process.c: try to workaroun SEGV by r65994
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/1480173

It tries to print C backtrace but fails. And core file on the server
seems to be stopping on the irrelevant place due to its own signal
handler for the dump.

And I failed to reproduce this SEGV on my machine.

I don't know why it's broken, so let me try this change to investigate
the reason of SEGV.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65997 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-26 14:45:39 +00:00
k0kubun 08e1705eec process.c: finish MJIT prior to #exec
to prevent ruby from leaving MJIT-related files.

test_jit.rb: add a test to prevent that

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65994 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-26 13:39:53 +00:00
k0kubun 13df05acfa mjit.c: copy call cache values to MJIT worker
same as r65275 but for call cache.

=== Optcarrot Benchmark ===
$ benchmark-driver benchmark.yml --rbenv 'before::before --disable-gems --jit;after::after --disable-gems --jit' -v --repeat-count 24
before: ruby 2.6.0dev (2018-10-21 trunk 65277) +JIT [x86_64-linux]
after: ruby 2.6.0dev (2018-10-21 trunk 65277) +JIT [x86_64-linux]
last_commit=mjit.c: copy call cache values to MJIT worker
Calculating -------------------------------------
                             before       after
Optcarrot Lan_Master.nes     85.372      85.359 fps

Comparison:
             Optcarrot Lan_Master.nes
                  before:        85.4 fps
                   after:        85.4 fps - 1.00x  slower

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65279 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-21 14:23:24 +00:00
k0kubun 1b5aa4f516 mjit.c: copy inline cache values to MJIT worker
on VM_CHECK_INTS. Letting MJIT worker directly see inline cache which
may be being updated could result in inconsistent IC index and serial.

mjit_worker.c: request the copy job after dequeue, and receive the
result synchronously.

tool/ruby_vm/views/_mjit_compile_ivar.erb: use the copied IC

mjit_compile.c: change the interface to pass is_entries
mjit.h: ditto

=== Optcarrot Benchmark ===
Thankfully this didn't have major performance regression.

$ benchmark-driver benchmark.yml --rbenv 'before::before --disable-gems --jit;after::after --disable-gems --jit' -v --repeat-count 24
before: ruby 2.6.0dev (2018-10-21 trunk 65263) +JIT [x86_64-linux]
after: ruby 2.6.0dev (2018-10-21 trunk 65263) +JIT [x86_64-linux]
last_commit=mjit.c: copy inline cache values to MJIT worker
Calculating -------------------------------------
                             before       after
Optcarrot Lan_Master.nes     85.421      85.454 fps

Comparison:
             Optcarrot Lan_Master.nes
                   after:        85.5 fps
                  before:        85.4 fps - 1.00x  slower

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65275 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-21 13:21:28 +00:00