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

259 Коммитов

Автор SHA1 Сообщение Дата
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
Koichi Sasada 79df14c04b Introduce Ractor mechanism for parallel execution
This commit introduces Ractor mechanism to run Ruby program in
parallel. See doc/ractor.md for more details about Ractor.
See ticket [Feature #17100] to see the implementation details
and discussions.

[Feature #17100]

This commit does not complete the implementation. You can find
many bugs on using Ractor. Also the specification will be changed
so that this feature is experimental. You will see a warning when
you make the first Ractor with `Ractor.new`.

I hope this feature can help programmers from thread-safety issues.
2020-09-03 21:11:06 +09:00
卜部昌平 f4950145cf mjit_mark_cc_entries: should consider VM_CALLCACHE_UNMARKABLE
Now that vm_empty_cc is VM_CALLCACHE_UNMARKABLE, it has to be properly
ruled out from being GCed.
2020-06-09 12:40:50 +09: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 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 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
Takashi Kokubun a3f6f67967
Add MJIT_COUNTER macro to dump total_calls 2020-04-12 23:10:28 -07:00
卜部昌平 9e6e39c351
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
2020-04-08 13:28:13 +09: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 43e18c68f4
Mark all cc_entries associated to compiled_iseq 2020-03-12 22:23:51 -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 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
Takashi Kokubun adcf0316d1
Prevent unloading methods used in root_fiber while calling another Fiber (#2939)
Fixing SEGVs like:
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/2744905
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/2744420
http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/2741400
2020-02-28 23:58:33 -08:00
Takashi Kokubun a8dcab7233
Avoid infinite loop on --jit-wait 2020-02-28 23:20:44 -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 eb75f0d134
Remove an unused declaration
It was unnecessary in b9007b6c54
2020-02-25 23:24:25 -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
Koichi Sasada f2286925f0 VALUE size packed callinfo (ci).
Now, rb_call_info contains how to call the method with tuple of
(mid, orig_argc, flags, kwarg). Most of cases, kwarg == NULL and
mid+argc+flags only requires 64bits. So this patch packed
rb_call_info to VALUE (1 word) on such cases. If we can not
represent it in VALUE, then use imemo_callinfo which contains
conventional callinfo (rb_callinfo, renamed from rb_call_info).

iseq->body->ci_kw_size is removed because all of callinfo is VALUE
size (packed ci or a pointer to imemo_callinfo).

To access ci information, we need to use these functions:
vm_ci_mid(ci), _flag(ci), _argc(ci), _kwarg(ci).

struct rb_call_info_kw_arg is renamed to rb_callinfo_kwarg.

rb_funcallv_with_cc() and rb_method_basic_definition_p_with_cc()
is temporary removed because cd->ci should be marked.
2020-02-22 09:58:59 +09:00
卜部昌平 ce4ea956d2 function pointers are not void*
The same as 8427fca49b.
2020-02-06 11:46:51 +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
Yusuke Endoh 8bddf1bc9b mjit.c: fix a mismatch of malloc'ed type
Coverity Scan found this issue.
2019-12-03 08:02:38 +09:00
Takashi Kokubun de74d2c3b0
Simplify variable declaration by C99 2019-12-01 17:32:50 -08:00
Nobuyoshi Nakada 4e03a7298b
Constified mjit_init 2019-12-01 20:26:28 +09:00
Nobuyoshi Nakada cb760f36aa
Constified 2019-12-01 19:29:04 +09:00
Takashi Kokubun 91af5542b5
Fix a mistake excluding NULL in the end 2019-12-01 02:00:08 -08:00
Takashi Kokubun 8a677a6e80
Workaround missing strndup on Windows
https://ci.appveyor.com/project/ruby/ruby/builds/29230976/job/c910t37313edb97k
2019-12-01 01:35:31 -08: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
Alan Wu 89e7997622 Combine call info and cache to speed up method invocation
To perform a regular method call, the VM needs two structs,
`rb_call_info` and `rb_call_cache`. At the moment, we allocate these two
structures in separate buffers. In the worst case, the CPU needs to read
4 cache lines to complete a method call. Putting the two structures
together reduces the maximum number of cache line reads to 2.

Combining the structures also saves 8 bytes per call site as the current
layout uses separate two pointers for the call info and the call cache.
This saves about 2 MiB on Discourse.

This change improves the Optcarrot benchmark at least 3%. For more
details, see attached bugs.ruby-lang.org ticket.

Complications:
 - A new instruction attribute `comptime_sp_inc` is introduced to
 calculate SP increase at compile time without using call caches. At
 compile time, a `TS_CALLDATA` operand points to a call info struct, but
 at runtime, the same operand points to a call data struct. Instruction
 that explicitly define `sp_inc` also need to define `comptime_sp_inc`.
 - MJIT code for copying call cache becomes slightly more complicated.
 - This changes the bytecode format, which might break existing tools.

[Misc #16258]
2019-10-24 18:03:42 +09: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
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 9e171b1fa0
Fix wrong allocation failure handling
`iseq->body->jit_unit->compile_info` should not be referenced before
the null check of `iseq->body->jit_unit`.
2019-09-20 21:50:33 +09:00
git efc8970336 * expand tabs. [ci skip]
Tabs are expanded because previously the file did not have any tab indentation.
Please update your editor config, and use misc/expand_tabs.rb in the pre-commit hook.
2019-08-22 22:47:05 +09:00
Takashi Kokubun a4d389d8fe
Improve the description of MJIT cancel-all [ci skip] 2019-08-22 22:46:47 +09:00
Aaron Patterson 154a67f140
Rename rb_gc_new_location to rb_gc_location
The function will return new or existing locations depending on whether
or not the object actually moved, so give it a more appropriate name.
2019-05-18 12:24:28 +03: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
Urabe, Shyouhei 34e1079aef glibc says memcpy cannot take NULL
At least since 2004, glibc's <string.h> annotates memcpy as
__attribute__((__nonnull__)).  This basedir is passed to it.  When
LOAD_RELATIVE is not defined and MJIT_SEARCH_BUILD_DIR is not set,
this variable is never updated.  Should initialize with meaningful
default value.
2019-04-29 21:52:44 +09:00
k0kubun 91faab7f14 Fix wrong critical section label
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67644 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 07:52:59 +00: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
k0kubun c2b8cd425e Revert "Revert "Skip ISeq reference for stale_units for debugging""
This reverts commit b79899b56a.

I wanted to test r67638 first. Now let me try this as well.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67639 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 05:50:19 +00:00
k0kubun b2ffafd238 Invalidate JIT-ed code if ISeq is moved by GC.compact
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67638 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 05:48:22 +00:00
k0kubun b79899b56a Revert "Skip ISeq reference for stale_units for debugging"
This reverts commit 4bd4d4e4cf.

Sorry, let me test another one first

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67637 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 05:45:56 +00:00
k0kubun 4bd4d4e4cf Skip ISeq reference for stale_units for debugging
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67636 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 05:44:47 +00:00
k0kubun b914bea88e Check ISeq references in stale_units too
This is a possible bug from recent "JIT recompile" introduction.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67631 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 04:50:21 +00:00
k0kubun 27f75cf3dc Update ISeq references in stale_units as well
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67628 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 03:29:20 +00:00
tenderlove 79accaf8d4 fix strict compile errors
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67625 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-20 03:00:08 +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