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

184 Коммитов

Автор SHA1 Сообщение Дата
Nobuyoshi Nakada e4f891ce8d
Adjust styles [ci skip]
* --braces-after-func-def-line
* --dont-cuddle-else
* --procnames-start-lines
* --space-after-for
* --space-after-if
* --space-after-while
2021-06-17 10:13:40 +09: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
S.H 3208a5df2d
Improve perfomance for Integer#size method [Feature #17135] (#3476)
* Improve perfomance for Integer#size method [Feature #17135]

* re-run ci

* Let MJIT frame skip work for Integer#size

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2021-06-04 21:57:21 -07:00
Takashi Kokubun 7e14762159
Do not doubly hold an MJIT lock
This is a follow-up of 86c262541a.
CRITICAL_SECTION_START/FINISH are not needed when it's called from an
MJIT worker.

Also, ZALLOC needs to be calloc because ZALLOC may trigger GC, which an
MJIT worker must not do.
2021-06-02 23:59:33 -07:00
Takashi Kokubun 86c262541a
Fix a race condition around mjit_recompile
This fixes SEGVs like https://github.com/ruby/ruby/runs/2715166621?check_suite_focus=true.

When mjit_recompile is called when mjit_compile is compiling the exact
same iseq (and after it called mjit_capture_cc_entries), iseq->body->jit_unit
is re-created and its cc_entries becomes NULL. Then, when it tries to
lookup cc_entries through iseq->body->jit_unit, it fails.
2021-06-02 22:11:37 -07:00
Takashi Kokubun 070caf54d2
Refactor rb_vm_insn_addr2insn calls
It's been a way too much amount of ifdefs.
2021-06-02 01:16:50 -07:00
Nobuyoshi Nakada 0f97aaa6cf
Suppress false warning by MSVC
https://github.com/ruby/ruby/runs/2707566811#step:10:147
```
D:\a\ruby\ruby\src\mjit_worker.c(1212): warning C4090: 'function': different 'const' qualifiers
```
2021-06-02 13:41:54 +09:00
Takashi Kokubun 028f1887c2
Change the default --jit-max-cache to 10000
This is useful for large applications like Rails.
https://k0kubun.medium.com/ruby-3-jit-can-make-rails-faster-756310f235a
2021-05-31 22:01:04 -07:00
Takashi Kokubun 1aac0e8819
Mark inlined ISeqs during MJIT compilation (#4539)
[Bug #17584]
2021-05-30 21:42:02 -07:00
Takashi Kokubun dfe21ef7a1
Do not block JIT with pending_stale_p
Because we want to flush pending stale units before unloading units, the
pending_stale_p check is implemented in this waiting loop.

However, once all methods are called more than --jit-min-calls,
mjit_worker_wakeup will not be signaled again. As a result, when
mjit_recompile is called after that and pending_stale_p becomes true,
MJIT stops processing methods in the unit queue even if the queue is
very long and MJIT does nothing, waiting for the signal.

There should be a better way to handle this, but as a fix to be
backported to Ruby 3.0, let me make an obvious simple commit here.
2021-05-20 03:33:29 -07:00
Takashi Kokubun 9f8a50723f
Specify -c to emit pch with clang (#4423)
[Bug #17836]
2021-04-28 11:49:55 -07:00
Takashi Kokubun 4724bf856f
Avoid hanging on --jit-wait after MJIT.pause
When a worker is stopped, nobody will JIT a method for you.
2021-01-03 00:05:38 -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 f26f905b28
Mark an ISeq being JIT-ed
This is to avoid SEGV on a CC reference in a normal compilation
https://github.com/ruby/ruby/runs/1586578023
2020-12-20 23:17:37 -08:00
Takashi Kokubun 5d8f227d0e
Lazily move units from active_units to stale_units
to avoid SEGV like
http://ci.rvm.jp/results/trunk-mjit@phosphorus-docker/3289588
by a race condition between mjit_recompile and compation around active_units
2020-12-16 00:22:50 -08:00
Takashi Kokubun 5463eff5f6
Lock only active_units references
556a728508 was not good maybe because it
wasn't using list_for_each_safe. If list_for_each_safe is safe for
list_del for any nodes (is that true?), this should be fine.
2020-12-14 23:35:45 -08:00
Takashi Kokubun 3e23991345
Lock GC while searching the best iseq
To fix
http://ci.rvm.jp/results/trunk-mjit-wait@phosphorus-docker/3286265
2020-12-11 19:58:59 -08:00
Takashi Kokubun 9e8f732f39
Revert "Revert some recent JIT changes"
This reverts commit b7dc04e518.

This should be fine, rather necessary, too.
2020-12-10 00:22:57 -08:00
Takashi Kokubun 12a1a25181
Revert "Revert "Have list_node at the top of rb_mjit_unit""
This reverts commit 73b07c437e.

This was, of course, innocent.
2020-12-10 00:21:33 -08:00
Takashi Kokubun 16c765990c
Use list_for_each_safe when list_del is used inside
list_for_each seems to cause all the SEGVs we've seen.
2020-12-10 00:18:35 -08:00
Takashi Kokubun b7dc04e518
Revert some recent JIT changes
Revert "Lock the entire active_units loop"

This reverts commit 5c2ff88be2.

Revert "Lock active_units references on compaction"

This reverts commit 556a728508.

Revert "Wait for GC before unload_units"

This reverts commit a8f16df615.

Well, the previous revert actually didn't fix it, but this series of
reverts seems to rollback the situation a little.
2020-12-07 21:12:29 -08:00
Takashi Kokubun 73b07c437e
Revert "Have list_node at the top of rb_mjit_unit"
This reverts commit 3319ce3765.

I still haven't figured out why, but this seems to have increased the
failure rate.
2020-12-07 21:02:26 -08:00
Takashi Kokubun a8f16df615
Wait for GC before unload_units 2020-12-07 19:57:15 -08:00
Takashi Kokubun 5c2ff88be2
Lock the entire active_units loop
The previous fix seems not working. Let me test if this works.
2020-12-07 15:34:02 -08:00
Takashi Kokubun 3319ce3765
Have list_node at the top of rb_mjit_unit
to convert list_node to rb_mjit_unit easily in gdb.
2020-12-07 13:54:32 -08:00
Takashi Kokubun 556a728508
Lock active_units references on compaction
This might race with mjit_recompile.
2020-12-06 20:23:32 -08:00
Takashi Kokubun dbdeb92b68
Do not throttle the workaround for --jit-wait
--jit-wait CI can be stuck when the workaround is throttled
http://ci.rvm.jp/results/trunk-mjit-wait@phosphorus-docker/3274091
2020-11-28 18:49:47 -08:00
Takashi Kokubun 096f54428d
Throttle JIT compaction
The compilation for JIT compaction is very heavy. Triggering a second
compaction to include one more new method is probably not worth it. So
this triggers JIT compaction for ten more new methods after each
compaction.
2020-11-27 23:25:32 -08:00
Takashi Kokubun 122cd35939
Throttle unload_units
Because d80226e7bd often reduces the number of unloaded units, it
increases the number of unload_units calls, which are heavy.

To mitigate that, this throttles unload_units per `max_cache_size / 10`.

Also hoping to fix
https://ci.appveyor.com/project/ruby/ruby/builds/36552382/job/kjmjgw9cjyf2ksd7
2020-11-27 23:06:40 -08:00
Takashi Kokubun d80226e7bd
Avoid unloading units which have enough total_calls
instead of just unloading worst 10% methods.
2020-11-27 22:26:14 -08:00
Takashi Kokubun 12866b0d31
Log when JIT compaction is skipped due to ISeq GC 2020-11-27 21:52:47 -08:00
Takashi Kokubun 16dab6b692
Run unload_units in the JIT worker thread
to avoid "Too many JIT code, but skipped unloading units for JIT compaction".
Now we can forget the `in_compact` locking.

Moving some functions from mjit.c to mjit_worker.c because mjit_worker.c
should have functions executed in the JIT worker.
2020-11-27 21:38:51 -08:00
Nobuyoshi Nakada abb672e14f
Suppress a format-overflow warning 2020-11-23 18:31:51 +09:00
Takashi Kokubun fa1250a506
Stop leaving .c files for JIT compaction in /tmp (#3802)
* Re-generate C files for JIT compaction every time

* Refactor in_jit return logic

* Just write code in a single file

* Add a TODO comment [ci skip]
2020-11-22 07:10:44 -08:00
Takashi Kokubun 7ade7a8603
Clarify the intention of the include guard
This was a leftover of 27d5af59a3.
2020-11-21 23:44:49 -08:00
Takashi Kokubun 9eb34c2c9e
Make c_file / so_file construction consistent
convert_unit_to_func's c_func / so_func construction is unnecessarily
complicated while it's not really safer than what compact_all_jit_code
does. So I changed convert_unit_to_func to be consistent with
compact_all_jit_code.
2020-11-21 22:38:23 -08:00
Takashi Kokubun e0156bd396
Make sure all threads are scanned on unload_units
This has been a TODO since 79df14c04b. While adcf0316d1 covered the
root_fiber of the initial thread, it didn't cover root_fibers of other
threads. Now it's hooked properly in rb_threadptr_root_fiber_setup.

With regards to "XXX: Is this mjit_cont `mjit_cont_free`d?", when
rb_threadptr_root_fiber_release is called, although I'm not sure when
th->root_fiber is truthy, fiber_free seems to call cont_free and
mjit_cont_free. So mjit_conts of root_fibers seem to be freed properly.
2020-11-21 19:36:55 -08:00
Takashi Kokubun a6db9e8d7b
Remove the unused o_file definition
It's calculated inside compile_c_to_so again.
2020-11-21 00:29:52 -08:00
Takashi Kokubun 8750d001c2
Fix wrong #ifdef usages with #if
Apparently #ifdef is always true
2020-11-20 23:48:43 -08:00
Takashi Kokubun 27d5af59a3
Unify some confusing macro usages
_MSC_VER used to be the macro to switch JIT compaction. However, since
d4381d2ceb, the correct macro to switch it was changed from _MSC_VER
to _WIN32. As I didn't properly replace all relevant _MSC_VER usages
to _WIN32, these macros have been used inconsistently.

nobu replaced _WIN32 with USE_HEADER_TRANSFORMATION in 5eb446d12f.
Therefore we had USE_HEADER_TRANSFORMATION and _MSC_VER. This commit
makes sure such inconsistent _MSC_VER usages will be unified to the new
header, also renaming it to USE_JIT_COMPACTION to be more precise about
the requirements. The header transformation itself is not quite relevant
to places changed in this commit.
2020-11-20 23:39:30 -08:00
Takashi Kokubun ed8e552d4d
Shrink the blocking region for compile_compact_jit_code
Isn't setting `in_compact = true` enough to avoid a race condition
between JIT compaction and unload_units? Now I think it is.

This change will make it easier to spend more time on compile_compact_jit_code.
For now it seems to take only 0.0723ms though.
2020-11-20 22:47:54 -08:00
Takashi Kokubun 0960f56a1d
Eliminate IVC sync between JIT and Ruby threads (#3799)
Thanks to Ractor (https://github.com/ruby/ruby/pull/2888 and https://github.com/ruby/ruby/pull/3662),
inline caches support parallel access now.
2020-11-20 22:18:37 -08:00
Aaron Patterson 9a6720a15d
Revert "Add assertions when inline caches are copied to MJIT"
This reverts commit 6cb6d5abc3.
This reverts commit 1484b786ae.

I think we don't need these assertions anymore.  I believe the problem
is solved by abf678a439
2020-10-22 09:52:05 -07:00
Aaron Patterson abf678a439 Use a lock level for a less granular lock.
We are seeing an error where code that is generated with MJIT contains
references to objects that have been moved.  I believe this is due to a
race condition in the compaction function.

`gc_compact` has two steps:

1. Run a full GC to pin objects
2. Compact / update references

Step one is executed with `garbage_collect`.  `garbage_collect` calls
`gc_enter` / `gc_exit`, these functions acquire a JIT lock and release a
JIT lock.  So a lock is held for the duration of step 1.

Step two is executed by `gc_compact_after_gc`.  It also holds a JIT
lock.

I believe the problem is that the JIT is free to execute between step 1
and step 2.  It copies call cache values, but doesn't pin them when it
copies them.  So the compactor thinks it's OK to move the call cache
even though it is not safe.

We need to hold a lock for the duration of `garbage_collect` *and*
`gc_compact_after_gc`.  This patch introduces a lock level which
increments and decrements.  The compaction function can increment and
decrement the lock level and prevent MJIT from executing during both
steps.
2020-10-22 07:59:06 -07:00
Kazuhiro NISHIYAMA 1484b786ae
Suppress warnings
```
compiling ../mjit.c
In file included from ../mjit.c:28:
../mjit_worker.c:1270:33: warning: incompatible pointer to integer conversion passing 'const struct rb_callcache *' to parameter of type 'VALUE' (aka 'unsigned long') [-Wint-conversion]
            assert(BUILTIN_TYPE(cc) != T_MOVED);
                                ^~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
../include/ruby/internal/value_type.h:153:23: note: passing argument to parameter 'obj' here
RB_BUILTIN_TYPE(VALUE obj)
                      ^
In file included from ../mjit.c:28:
../mjit_worker.c:1271:33: warning: incompatible pointer to integer conversion passing 'const struct rb_callable_method_entry_struct *' to parameter of type 'VALUE' (aka 'unsigned long') [-Wint-conversion]
            assert(BUILTIN_TYPE(vm_cc_cme(cc)) != T_MOVED);
                                ^~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
../include/ruby/internal/value_type.h:153:23: note: passing argument to parameter 'obj' here
RB_BUILTIN_TYPE(VALUE obj)
                      ^
In file included from ../mjit.c:28:
../mjit_worker.c:1272:50: warning: incompatible pointer to integer conversion passing 'const struct rb_callcache *' to parameter of type 'VALUE' (aka 'unsigned long') [-Wint-conversion]
            assert(!rb_objspace_garbage_object_p(cc));
                                                 ^~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
../gc.h:128:40: note: passing argument to parameter 'obj' here
int rb_objspace_garbage_object_p(VALUE obj);
                                       ^
In file included from ../mjit.c:28:
../mjit_worker.c:1273:50: warning: incompatible pointer to integer conversion passing 'const struct rb_callable_method_entry_struct *' to parameter of type 'VALUE' (aka 'unsigned long') [-Wint-conversion]
            assert(!rb_objspace_garbage_object_p(vm_cc_cme(cc)));
                                                 ^~~~~~~~~~~~~
/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/assert.h:93:25: note: expanded from macro 'assert'
    (__builtin_expect(!(e), 0) ? __assert_rtn(__func__, __FILE__, __LINE__, #e) : (void)0)
                        ^
../gc.h:128:40: note: passing argument to parameter 'obj' here
int rb_objspace_garbage_object_p(VALUE obj);
                                       ^
4 warnings generated.
```
2020-09-30 13:37:07 +09:00
Aaron Patterson 6cb6d5abc3
Add assertions when inline caches are copied to MJIT
This is a temporary commit to try to find a GC issue.  It seems like
mjit is pointing at a moved address in the call cache.  I want to assert
that they aren't TMOVED or garbage objects at the time they get copied
2020-09-18 17:07:08 -07:00
卜部昌平 97672f669a sed -i s/RUBY3/RBIMPL/g
Devs do not love "3".  The only exception is RUBY3_KEYWORDS in parse.y,
which seems unrelated to our interests.
2020-05-11 09:24:08 +09:00
Nobuyoshi Nakada 5eb446d12f
mjit_worker.c: compile_compact_jit_code is not used on mingw 2020-05-09 13:46:47 +09:00
Takashi Kokubun 39bd1244b4
Revert 0776198486 for Solaris debug
For some reason 0776198486 didn't fail
https://rubyci.org/logs/rubyci.s3.amazonaws.com/solaris10-gcc/ruby-master/log/20200503T230004Z.log.html.gz
even while it was before 9aa5fe1bf8.

Anyway, there's no need to keep the change anymore.
2020-05-03 17:39:57 -07:00
Takashi Kokubun a8d39a051c
Test no .dSYM on macOS
I think 9aa5fe1bf8 helps this issue too.
2020-05-03 16:49:31 -07:00