| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
| |
|
| |
|
|
|
|
| |
There is a crash in there that we don't want to worry about for now.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
| |
`mjit_valid_class_serial_p` has no longer been used since b9007b6c548.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
```
$ 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
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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 d07183ec85d
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
|
|
|
|
|
|
|
|
|
|
| |
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().
|
|
|
|
|
| |
* Inline getconstant on JIT
* Support USE_MJIT=0
|
|
|
|
| |
to define USE_MJIT.
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
It's very hard to remember which mjit.h has what.
|
|
|
|
|
| |
It's probably not worth it because there's nothing we can optimize in
such builtin methods. It's worth JIT only when inlined.
|
|
|
|
| |
and mark it as COLDFUN on JIT, assuming enqueue usually happens on VM.
|
|
|
|
|
|
|
| |
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.
|
|
|
|
| |
To fix build failures.
|
|
|
|
| |
This shall fix compile errors.
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
| |
Split ruby.h
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
JIT support of dd723771c11.
$ 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
|
|
|
|
| |
changing add_iseq_to_process's debug counter name as well for comparison
|
| |
|
|
|
|
| |
Fixed a TODO in b9007b6c548f91e88fd3f2ffa23de740431fa969
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
| |
because @ko1 said "gc_finish" is confusing like a finish of entire GC
process
|
|
|
|
| |
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67643 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
| |
if cancel happens in an inlined method.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67575 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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:
https://github.com/benchmark-driver/misc/blob/52f05781f65467baf895bf6ba79d172c9b0826fd/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
|
|
|
|
| |
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67460 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
|
|
| |
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67375 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
| |
This reverts commit ba51ae0109ee1d1fa7ca90b43da115ea68d7214a.
CI is failing again...
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67297 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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
|
|
|
|
|
|
|
|
|
|
|
|
| |
This reverts commit 4161674b2fbea6bdd01783ac5d3b39d88db22972.
Revert "Eliminate mjit_copy_job_t reference from mjit_worker"
This reverts commit d86a1aa045959dfbf5cd472eae0d043180259727.
Reverting them because of CI failures
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67291 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
|
|
|
|
|
|
|
|
|
|
| |
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
|