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

152 Коммитов

Автор SHA1 Сообщение Дата
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
Takashi Kokubun 9aa5fe1bf8
Split compile and link for MinGW support
MinGW test_jit fails with no error message. Perhaps linker flags should
not be passed when compilation is happening.

Anyway splitting these stages doesn't matter for performance. So let me
just split it to fix the issue. Probably this helps Solaris's issue too.
2020-05-03 16:41:25 -07:00
Takashi Kokubun 0776198486
Debug Solaris's MJIT failure
using -Winvalid-pch

https://rubyci.org/logs/rubyci.s3.amazonaws.com/solaris10-gcc/ruby-master/log/20200501T170004Z.fail.html.gz
2020-05-03 15:49:51 -07:00
Takashi Kokubun 4aca078bda
Support cc_added_args again
This support was accidentally removed in 818d6d3336.
2020-05-03 00:45:19 -07:00
Takashi Kokubun cc6afff006
Avoid infinite times of JIT compaction
It's to avoid memory leak for actual usage (because they don't get
unloaded properly), but also for fixing CI timed out due to JIT
compaction taking too long time on --jit-wait (which runs every time)
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/2911601
2020-05-02 21:43:28 -07:00
Takashi Kokubun e4d3d5ceab
Stop generating MJIT_PCH include guard
to fix
https://ci.appveyor.com/project/ruby/ruby/builds/32577700/job/yh61rom35wt2uv39

It was for JIT compaction, and we don't support it on mswin.
2020-05-01 02:54:50 -07:00
Takashi Kokubun 72aa4dd183
c_file_access_mode should be defined for Windows
as well. And also unit->c_file doesn't exist in mswin.

https://github.com/ruby/ruby/runs/635915704
2020-05-01 01:58:19 -07:00
Takashi Kokubun 818d6d3336
Deduplicate functions in compacted JIT code
to improve code locality.

Using benchmark-driver/sinatra with 100 methods JIT-ed,

[Before] 12149.97 rps
1.3M    /tmp/_ruby_mjit_p31171u145.so

[After] 12818.83 rps
260K    /tmp/_ruby_mjit_p32155u145.so

(VM is 13714.89 rps)
2020-05-01 01:38:16 -07: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
Takashi Kokubun e8a78d7df8
Do not stop the world during JIT compaction
Running C compiler for JIT compaction inside a critical section may lock
main thread for a long time when it triggers GC. As I'm planning to
increase this duration a bit, I'd like to make sure this doesn't stop
the world.

For now, I chose to give up unloading units when it's during JIT
compaction, assuming other calls may unload them later.
2020-04-30 21:38:50 -07:00
卜部昌平 4b853932ea mjit_worker: __GNUC__ is too lax
Namely icc defines __GNUC__, but doesn't have -Wdeprecated-declarations
2020-04-10 16:17:30 +09:00
Nobuyoshi Nakada 3325194ac0
Get rid of bogus warning by VC
```
c:\projects\ruby\mjit_worker.c(1219) : warning C4090: 'function' : different 'const' qualifiers
```

It seems confused by passing "pointer to pointer to const object",
not "pointer to const object".
2020-03-17 19:47:45 +09:00
Takashi Kokubun 6e405b2611
Use a human-readable funcname with --jit-debug
for perf output like:

Samples: 100K of event 'cycles:ppp', Event count (approx.): 1007750000
  Children      Self  Command  Shared Object             Symbol
+   81.58%     1.47%  ruby     ruby                      [.] rb_vm_exec
+   81.06%     7.61%  ruby     ruby                      [.] vm_exec_core
+   80.16%     0.00%  ruby     ruby                      [.] vm_sendish (inlined)
+   75.03%     0.00%  ruby     ruby                      [.] mjit_exec (inlined)
+   74.37%     0.00%  ruby     ruby                      [.] mjit_exec (inlined)
+   73.42%     0.22%  ruby     _ruby_mjit_p11277u42.so   [.] _mjit42_rack_method_override_rb_call
+   73.25%     0.10%  ruby     _ruby_mjit_p11277u41.so   [.] _mjit41_sinatra_show_exceptions_rb_call
+   73.19%     0.22%  ruby     _ruby_mjit_p11277u44.so   [.] _mjit44_rack_head_rb_call
+   73.03%     0.15%  ruby     _ruby_mjit_p11277u45.so   [.] _mjit45_sinatra_base_rb_call
+   72.87%     0.26%  ruby     _ruby_mjit_p11277u49.so   [.] _mjit49_rack_logger_rb_call
+   70.56%     0.11%  ruby     _ruby_mjit_p11277u40.so   [.] _mjit40_sinatra_base_rb_call
+   68.70%     0.11%  ruby     _ruby_mjit_p11277u39.so   [.] _mjit39_sinatra_base_rb_call
+   68.39%     0.29%  ruby     _ruby_mjit_p11277u56.so   [.] _mjit56_rack_protection_frame_options_rb_call
+   67.89%     0.18%  ruby     _ruby_mjit_p11277u37.so   [.] _mjit37_sinatra_base_rb_block_in_call
+   67.04%     0.16%  ruby     _ruby_mjit_p11277u34.so   [.] _mjit34_sinatra_base_rb_synchronize

Reverting deb1c7b97d, fixing `sprint_funcname`'s argument in `compact_all_jit_code`.
Also updating common.mk.
2020-03-14 21:02:09 -07:00
Takashi Kokubun deb1c7b97d
Revert "Use a human-readable funcname with --jit-debug"
This reverts commit cecebf55c4.

debugging test failure...
2020-03-14 20:51:12 -07:00
Takashi Kokubun cecebf55c4
Use a human-readable funcname with --jit-debug
for perf output like:

Samples: 100K of event 'cycles:ppp', Event count (approx.): 1007750000
  Children      Self  Command  Shared Object             Symbol
+   81.58%     1.47%  ruby     ruby                      [.] rb_vm_exec
+   81.06%     7.61%  ruby     ruby                      [.] vm_exec_core
+   80.16%     0.00%  ruby     ruby                      [.] vm_sendish (inlined)
+   75.03%     0.00%  ruby     ruby                      [.] mjit_exec (inlined)
+   74.37%     0.00%  ruby     ruby                      [.] mjit_exec (inlined)
+   73.42%     0.22%  ruby     _ruby_mjit_p11277u42.so   [.] _mjit42_rack_method_override_rb_call
+   73.25%     0.10%  ruby     _ruby_mjit_p11277u41.so   [.] _mjit41_sinatra_show_exceptions_rb_call
+   73.19%     0.22%  ruby     _ruby_mjit_p11277u44.so   [.] _mjit44_rack_head_rb_call
+   73.03%     0.15%  ruby     _ruby_mjit_p11277u45.so   [.] _mjit45_sinatra_base_rb_call
+   72.87%     0.26%  ruby     _ruby_mjit_p11277u49.so   [.] _mjit49_rack_logger_rb_call
+   70.56%     0.11%  ruby     _ruby_mjit_p11277u40.so   [.] _mjit40_sinatra_base_rb_call
+   68.70%     0.11%  ruby     _ruby_mjit_p11277u39.so   [.] _mjit39_sinatra_base_rb_call
+   68.39%     0.29%  ruby     _ruby_mjit_p11277u56.so   [.] _mjit56_rack_protection_frame_options_rb_call
+   67.89%     0.18%  ruby     _ruby_mjit_p11277u37.so   [.] _mjit37_sinatra_base_rb_block_in_call
+   67.04%     0.16%  ruby     _ruby_mjit_p11277u34.so   [.] _mjit34_sinatra_base_rb_synchronize
2020-03-14 20:42:47 -07:00
Takashi Kokubun 0cd7be99e9
Avoid referring to an old value of realloc
OpenBSD RubyCI has failed with SEGV since 4bcd5981e8.
https://rubyci.org/logs/rubyci.s3.amazonaws.com/openbsd-current/ruby-master/log/20200312T223005Z.fail.html.gz

This was because `status->cc_entries` could be stale after `realloc` call
for inlined iseqs.
2020-03-12 22:51:34 -07:00
Takashi Kokubun 4bcd5981e8
Capture inlined iseq's cc entries in root iseq's
jit_unit to avoid marking wrong cc entries when inlined iseq is compiled
multiple times, resolving the TODO added by daf7c48d88.

This obviates pseudo jit_unit in inlined iseq introduced by 7ec2359374
and fixes memory leak of the adhoc unit.
2020-03-10 00:53:35 -07:00
Nobuyoshi Nakada 364526cd70
[win32] suppress false warning by MSVC 2020-03-04 21:02:24 +09:00
Takashi Kokubun 83705c42ce
Add missing free on cc_entries
Looks like an oversight in b9007b6c54 and
7ec2359374.
2020-02-26 00:37:37 -08:00
Takashi Kokubun 69f377a3d6
Internalize rb_mjit_unit definition again
Fixed a TODO in b9007b6c54
2020-02-26 00:27:29 -08:00
Takashi Kokubun daf7c48d88
Explain the situation of inner cc_entries [ci skip]
Add a little more details in 7ec2359374
2020-02-25 23:55:54 -08:00
Takashi Kokubun 55923ba883
Note a situation around xmalloc vs free in MJIT [ci skip]
shared by ko1
2020-02-25 23:48:49 -08:00
Koichi Sasada 84d1a99a3f should be initialize jit_unit->cc_entries.
GC can invoke just after allocation of jit_unit->cc_entries so
it should be zero-cleared.
2020-02-25 13:37:52 +09:00
Koichi Sasada 7ec2359374 prevent GC from mjit worker.
ALLOC_N() can causes GC. Sometimes `mjit_copy_job_handler()`
can be called by mjit_worker thread which is not a Ruby thread,
so we need to prevent GC in this function. This patch has some
issues, but I introduce it to pass the tests.
2020-02-25 12:57:10 +09: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
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
Takashi Kokubun 6fa3492362
Eliminate the possibility to leave freed ISeq
in active_units

Hoping to fix:
http://ci.rvm.jp/results/trunk-mjit@silicon-docker/2311375
2019-10-13 19:31:18 -07:00
Takashi Kokubun 183b421509
Delay the free until we stop referring to a unit
`if (unit->iseq)` might have referred to a freed unit. Therefore this
commit delays its free.
2019-10-13 14:15:14 -07:00
Takashi Kokubun 26fae9aa9d
Remove the quick stop path after convert_unit_to_func
Now I'm not exactly sure why I needed to check `stop_worker_p` after
`mjit_copy_cache_from_main_thread` of `convert_unit_to_func`
in 4161674b2f.
If it's for avoiding deadlock under `in_gc` condition, we should keep it.

However, if it's not the case and it's just for retrying accidental
compilation failure or just to avoid `MJIT_ATOMIC_SET` and
`compact_all_jit_code`, I think this quick stop path is not mandatory.

Because this path is somewhat problematic in my upcoming fix in
mjit_worker, let me try to remove this first and see how CI goes.
2019-10-13 09:59:44 -07:00
Yusuke Endoh 4171909695 mjit_worker.c: Add `-lm` to the C compiler in MJIT on Android
To avoid:

    cannot locate symbol "modf" referenced by .../_ruby_mjit_XXX.so"
2019-10-10 23:22:37 +09:00
Takashi Kokubun 5d8f112505
RubyVM::MJIT.pause(wait: true) should wait
for all compilations and compaction.

Prior to this commit, the last-compiled code has not been used because
MJIT worker is stopped before setting the code, and compaction has also
been skipped.

But it was not intentional and `wait: true` pause should wait until
those two things by its feature.
2019-09-26 16:28:34 +09:00
Takashi Kokubun b0a291f6f6
Split CC_LINKER_ARGS from CC_DLDFLAGS_ARGS
to drop MJIT_DLDFLAGS from compile_c_to_o for OpenBSD failure
https://rubyci.org/logs/rubyci.s3.amazonaws.com/openbsd65/ruby-master/log/20190830T110008Z.fail.html.gz.

8c7f4e8f8b did not work for i686-linux
https://travis-ci.org/ruby/ruby/jobs/578808112.
2019-08-30 22:33:21 +09:00
Takashi Kokubun 8c7f4e8f8b
Try dropping DLDFLAGS from compile_c_to_o
I think this did not work for some environments, but this seems to fix
OpenBSD RubyCI failure:
https://rubyci.org/logs/rubyci.s3.amazonaws.com/openbsd65/ruby-master/log/20190830T110008Z.fail.html.gz

Let me check RubyCI impact by this.
2019-08-30 22:03:37 +09:00