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.
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
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.
```
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".
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.
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.
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.
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.
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.
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.
To fix "gcc: -lgcc: linker input file unused because linking not done" in
https://rubyci.org/logs/rubyci.s3.amazonaws.com/openbsd65/ruby-master/log/20190826T200009Z.log.html.gz
Still I'm intentionally leaving CC_DLDFLAGS_ARGS because making compiler
options different might result in compile/link failure. (Of course
CC_DLDFLAGS_ARGS usually should not have compiler options, but it might
include by bad configure setup)
The same problem may exist in MJIT_LIBS used inside CC_LIBS as well, but
I just ignored that case because it impacts only MinGW / cygwin, hoping
that their users do not perform a wrong configure.
in GC.compact.
While `in_jit` is false, GC.compact is allowed to run and it may be
moving ISeq-related pointers. So calling rb_iseq_path() when `in_jit`
is true is illegal.
I assumed that ISeq is never GC-ed by `in_jit` + `mjit_mark` on copy job
ISeq, but unfortunately I found SEGV on `mjit_copy_job_handler` in which
iseq->body was somehow Qnil. And it seems to be fixed by disabling the
job when `mjit_free_iseq` is called for the ISeq.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67551 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
Because hard to specify commits related to r67479 only.
So please commit again.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
It seems that `debug_counter_show_results_at_exit` could be called
earlier than `mjit_finish` sometimes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67380 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
by changing interface of `mjit_copy_cache_from_main_thread`.
This is also fixing deadlock introduced by r67299.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67300 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
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 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
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
and make `copy_cache_from_main_thread` easier to use.
For implementing inlining later, I'll use `copy_cache_from_main_thread`
inside `mjit_compile`.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67287 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
and guard iseq from GC by marking iseq in mjit_copy_job.
This is a refactoring for implementing inlining later and
should not be fixing or introducing any bugs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67286 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
assuming that -nostartfiles is just optional for mingw, cygwin, and AIX.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66870 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
OpenBSD's GCC compiler has local extensions that break when
`-nostartfiles -nodefaultlibs -nostdlib` is used.
From: Jeremy Evans <merch-redmine@jeremyevans.net>
[Bug #15548]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66869 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
using `-nodefaultlibs -nostdlib`.
I assume libgcc is needed when we use -nostdlib, and it's linked on some
platforms but not linked on some platforms (like aarch64, and possibly
AIX as well) as said in https://wiki.osdev.org/Libgcc :
> You can link with libgcc by passing -lgcc when linking your kernel
with your compiler. You don't need to do this unless you pass the
-nodefaultlibs option (implied by -nostdlib)
Also note that -nostdlib is not strictly needed (rather implied
-nodefaultlibs is problematic for Gentoo like Bug#15513, which will be
approached later) but helpful for performance. So I want to keep it for
now.
[Bug #15522]
I'm not trying to add `-nodefaultlibs -nostdlib` for AIX in this commit
because AIX RubyCI is dead right now, but I'll try to add them again
once RubyCI is fixed.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66812 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This should have no impact.
The CC_LIBS was too hard to read for human.
I don't remember whether the order of -lmsvcrt and -lgcc matters or not,
but I kept that for the best safety.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66811 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
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
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
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
* configure.ac: disable using __builtin_setjmp to avoid errors when execution
globally jumps out of JITted code. Specify -std=gnu99 to JIT compilation
to avoid errors regarding the "restrict" keyword in the precompiled header.
Specify -shared in addition to -Wl,-G when building shared libraries
to make mjit_build_dir.so expose the MJIT_BUILD_DIR symbol. Use LDR_PRELOAD
to load mjit_build_dir.so.
* mjit_worker.c: do not specify -nodefaultlibs or -nostdlibs because on AIX
JITted code internally refers to the memcpy function.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66202 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
in a new variable cc_common_args.
`cflags=-save-temps=obj` makes MJIT fail like:
https://rubyci.org/logs/www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20181203T095000Z.log.html.gz
This rubyci specifies -save-temps=obj in CFLAGS to use update-deps, and
the flag is harmful when we want to use -pipe flag.
mjit_worker.c: prefer cc_common_args over CC_COMMON_ARGS
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66164 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because we mostly use cc_path now and the comment is obsolete (CC_PATH
is now absolute path and the TODO is already resolved).
mjit.c: use CC_COMMON_ARGS[0] directly
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66162 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
postponed_job is safe to use in signal handlers, but is not
thread-safe for MJIT. Implement a workqueue for MJIT
thread-safety.
[Bug #15316]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66100 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-local variable to global variable.
Consider this case:
1. MJIT worker: dequeue ISeq (stop_worker_p was still FALSE)
2. Ruby thread: call Kernel#exec, which calls mjit_finish(FALSE),
sets `stop_worker_p = TRUE`, and fires RUBY_VM_CHECK_INTS() once
3. MJIT worker: register copy job, but found stop_worker_p is TRUE.
set `worker_stopped = TRUE` and the thread stops.
4. Function-local job variable expires by the thread stop (this is eliminated by this commit)
5. Ruby thread: find `worker_stopped` becamse TRUE, start Kernel#exec.
Kernel#exec fails but exception is rescued.
6. Ruby thread: call RUBY_VM_CHECK_INTS. copy job is dispatched but job variable
is already expired.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66035 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_trace.c (rb_tracepoint_enable_for_target): support targetting
TracePoint. [Feature #15289]
Tragetting TracePoint is only enabled on specified method, proc
and so on, example: `tp.enable(target: code)`.
`code` should be consisted of InstructionSeuqnece (iseq)
(RubyVM::InstructionSeuqnece.of(code) should not return nil)
If code is a tree of iseq, TracePoint is enabled on all of
iseqs in a tree.
Enabled tragetting TracePoints can not enabled again with
and without target.
* vm_core.h (rb_iseq_t): introduce `rb_iseq_t::local_hooks`
to store local hooks.
`rb_iseq_t::aux::trace_events` is renamed to
`global_trace_events` to contrast with `local_hooks`.
* vm_core.h (rb_hook_list_t): add `rb_hook_list_t::running`
to represent how many Threads/Fibers are used this list.
If this field is 0, nobody using this hooks and we can
delete it.
This is why we can remove code from cont.c.
* vm_core.h (rb_vm_t): because of above change, we can eliminate
`rb_vm_t::trace_running` field.
Also renamed from `rb_vm_t::event_hooks` to `global_hooks`.
* vm_core.h, vm.c (ruby_vm_event_enabled_global_flags): renamed
from `ruby_vm_event_enabled_flags.
* vm_core.h, vm.c (ruby_vm_event_local_num): added to count
enabled targetting TracePoints.
* vm_core.h, vm_trace.c (rb_exec_event_hooks): accepts
hook list.
* vm_core.h (rb_vm_global_hooks): added for convinience.
* method.h (rb_method_bmethod_t): added to maintain Proc
and `rb_hook_list_t` for bmethod (defined by define_method).
* prelude.rb (TracePoint#enable): extracet a keyword parameter
(because it is easy than writing in C).
It calls `TracePoint#__enable` internal method written in C.
* vm_insnhelper.c (vm_trace): check also iseq->local_hooks.
* vm.c (invoke_bmethod): check def->body.bmethod.hooks.
* vm.c (hook_before_rewind): check iseq->local_hooks
and def->body.bmethod.hooks before rewind by exception.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66003 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
by launching MJIT worker thread in child Ruby process.
See the comment before `mjit_child_after_fork` for details.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65785 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
r65577 seems to have made MJIT_CC (MJIT_CC_COMMONA) become an absolute
path. So start_process doesn't need to find that from PATH by dln_find_exe_r.
This commit is motivated by the msys2 AppVeyor CI failure:
https://ci.appveyor.com/project/ruby/ruby/builds/20084104/job/1pg15os4dtttyl0q
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65599 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
I'm planning to use _one later, but it may be doubly registered by
switching `stop_worker_p` now and so we should not use _one for now.
Otherwise stale job may reject new job registration and
copy_cache_from_main_thread may wait forever.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65571 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-available region. reducing risk of SEGV in mjit_copy_job_handler() like
http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1446117
I'm not sure which exact part is causing "[BUG] Segmentation fault at 0x0000000000000008"
on `(mjit_copy_job_handler+0x12) [0x564a6c4ce632] /home/ko1/ruby/src/trunk-mjit/mjit.c:26`...
mjit.c: ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65569 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
When we return there, `unit` is already freed.
This is detected by coverity scan.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65496 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
In https://bugs.ruby-lang.org/issues/14867#note-98, it's considered
useless at once. So I emphasized the necessity of it in the comment.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_mjit_unit can either exist in unit_queue or active_units, but
not both. This will make state transitions for event-based MJIT
process management easier.
v2: recheck unit->iseq after GC wakeup
The iseq may be GC-ed while we were waiting for it since we
delete the unit from unit_queue during get_from_list
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65475 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
https://bugs.ruby-lang.org/issues/14867#note-112
I wanna touch similar places. To avoid our conflict, let me merge Eric's patch earlier.
Let's watch trunk-mjit / trunk-mjit-wait CIs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65473 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_mjit_unit can either exist in unit_queue or active_units, but
not both. This will make state transitions for event-based MJIT
process management easier.
[ruby-core:89654]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65468 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* hash.c, internal.h: support theap for small Hash.
Introduce RHASH_ARRAY (li_table) besides st_table and small Hash
(<=8 entries) are managed by an array data structure.
This array data can be managed by theap.
If st_table is needed, then converting array data to st_table data.
For st_table using code, we prepare "stlike" APIs which accepts hash value
and are very similar to st_ APIs.
This work is based on the GSoC achievement
by tacinight <tacingiht@gmail.com> and refined by ko1.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65454 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
when main thread is waiting for MJIT worker forever without executing
RUBY_VM_CHECK_INTS due to --jit-wait.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65323 b2dd03c8-39d4-4d8f-98ff-823fe69b080e