The former states explicitly that the argument must be a literal,
and can optimize away `strlen` on all compilers.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65059 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This change resolves most of major remaining MJIT bugs on mswin.
Since Visual Studio doesn't support generating pre-processed code
preserving macros, we can't use transform_mjit_header approach for mswin.
So we need to transform MJIT header using macro like this.
vm.c: use MJIT_STATIC for non-static functions that exist on MJIT header
and cause conflict on link.
vm_insnhelper.c: ditto
test_jit.rb: remove many skips for mswin.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64940 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_insnhelper.c: remove `vm_profile_counter` because
it is replaced with debug_counters.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64890 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because r64849 seems to fix issues which we were confused about.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64850 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This reverts commit r64829. I'll prepare another temporary fix, but I'll
separately commit that to make it easier to revert that later.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64838 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
not optimizing Array#& and Array#| because vm_insnhelper.c can't easily
inline it (large amount of array.c code would be needed in vm_insnhelper.c)
and the method body is a little complicated compared to Integer's ones.
So I thought only Integer#& and Integer#| have a significant impact,
and eliminating unnecessary branches would contribute to JIT's performance.
vm_insnhelper.c: ditto
tool/transform_mjit_header.rb: make sure these instructions are inlined
on JIT.
compile.c: compile vm_opt_and and vm_opt_or.
id.def: define id for them to be used in compile.c and vm*.c
vm.c: track redefinition of Integer#& and Integer#|
vm_core.h: allow detecting redefinition of & and |
test/ruby/test_jit.rb: test new insns
test/ruby/test_optimization.rb: ditto
* Optcarrot benchmark
This is a kind of experimental thing but I'm committing this since the
performance impact is significant especially on Optcarrot with JIT.
$ benchmark-driver benchmark.yml --rbenv 'before::before --disable-gems;before+JIT::before --disable-gems --jit;after::after --disable-gems;after+JIT::after --disable-gems --jit' -v --repeat-count 24
before: ruby 2.6.0dev (2018-09-24 trunk 64821) [x86_64-linux]
before+JIT: ruby 2.6.0dev (2018-09-24 trunk 64821) +JIT [x86_64-linux]
after: ruby 2.6.0dev (2018-09-24 opt_and 64821) [x86_64-linux]
last_commit=opt_or
after+JIT: ruby 2.6.0dev (2018-09-24 opt_and 64821) +JIT [x86_64-linux]
last_commit=opt_or
Calculating -------------------------------------
before before+JIT after after+JIT
Optcarrot Lan_Master.nes 51.460 66.315 53.023 71.173 fps
Comparison:
Optcarrot Lan_Master.nes
after+JIT: 71.2 fps
before+JIT: 66.3 fps - 1.07x slower
after: 53.0 fps - 1.34x slower
before: 51.5 fps - 1.38x slower
[close https://github.com/ruby/ruby/pull/1963]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64824 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This reverts commit r64711, because EXEC_EC_CFP on JIT-ed code does not
call jit_func with the patch when catch_except_p is true. It wasn't intentional.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64730 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
ec->vm_stack is always allocated with malloc, so stack cache for
root fiber (thread stack) and non-root fibers can be shared as
long as the size is the same. The purpose of this change is to
reduce dependencies on ROOT_FIBER_CONTEXT.
[Feature #15095] [Bug #15050]
v2: vm.c: fix build with USE_THREAD_DATA_RECYCLE==0
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64703 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The code fragments that initializes coverage data were scattered into
both parse.y and compile.c. parse.y allocated a coverage data, and
compile.c initialize the data.
To remove this cross-cutting concern, this change moves the allocation
from "coverage" function of parse.y to "rb_iseq_new_top" of iseq.c.
For the sake, parse.y just counts the line number of the original source
code, and the number is passed via rb_ast_body_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64508 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
by sharing it with vm.c in internal.h.
vm.c: ditto
internal.h: ditto
mjit.h: share more.
mjit.c: make sure the third arguemnt is not used
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64253 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
and wait until JIT queue is flushed when wait option is not passed or
`wait: true` is passed.
vm.c: ditto
test/ruby/test_rubyvm_mjit.rb: added test for pause/resume
test/lib/jit_support.rb: allow retrying MJIT on JITSupport level
test/ruby/test_jit.rb: ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64250 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because such inconsistency may result in the regression fixed in r64034.
vm_exec is not touched since renaming it may be controversial...
vm_args.c: ditto.
vm_eval.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64035 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* variable.c (rb_const_search): call #const_missing method on
private constants, as well as uninitialized constants.
[Feature #14328]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (core_hash_merge_kwd): simplified to merge the second hash
into the first hash.
* compile.c (compile_array): call core#hash_merge_kwd with 2
hashes always, by passing an new empty hash to at the first
iteration.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
rb_vm_get_sourceline returns zero if cfp->iseq is NULL,
so rb_iseq_path should not try to follow NULL cfp->iseq,
either.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63837 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
`RubyVM::MJIT.enabled?`.
It's set to be TRUE even before initialization is finished.
So it was actually not "mjit initialized predicate".
This flag is also used to check whether JIT-ed code should be called
or not, but I'm going to split the responsibility to another flag.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63732 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c: use EXEC_EVENT_HOOK_AND_POP_FRAME. While exception handling, if an exception
is raised in hooks, need to pop current frame and raise this raised exception by hook.
[ruby-dev:50582] [Bug #14865]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63727 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (VM_ENV_DATA_INDEX_ENV_PROC): ep[VM_ENV_DATA_INDEX_ENV_PROC] is
allocated to mark a Proc which is created from iseq block.
However, `lep[0]` keeps Proc object itself as a block handler (Proc).
So we don't need to keep it.
* vm_core.h (VM_ENV_PROCVAL): ditto.
* vm.c (vm_make_env_each): do not need to keep blockprocval as special value.
* vm.c (vm_block_handler_escape): simply return Proc value.
* proc.c (proc_new): we don't need to check Env because a Proc type block
handler is a Proc object itself.
[Bug #14782]
* test/ruby/test_proc.rb: add a test for [Bug #14782]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63494 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Instead of allocating and registering the altstack in different
places, do it together to reduce code and improve readability.
When thread cache is enabled, storing altstack in rb_thread_t
is wasteful and we may reuse altstack in the same pthread.
This also lets us clearly allow use of xmalloc to allow GC to
recover from ENOMEM.
[ruby-core:85621] [Feature #14487]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63213 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (root_fiber_alloc): call `ConvertThreadToFiber()` here.
`rb_fiber_t` for root_fiber is allocated before running Threads.
Fiber objects wrapping this rb_fiber_t for root_fiber are created
when root Fiber object is required explicitly (for example, Fiber
switching and so on). We can put calling `ConvertThreadToFiber()`.
In other words, we can pending `ConvertThreadToFiber()`
until Fiber objects are created.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63090 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (rb_threadptr_root_fiber_setup): divide into two functions:
* rb_threadptr_root_fiber_setup_by_parent(): called by the parent thread.
* rb_threadptr_root_fiber_setup_by_child(): called by the created thread.
`rb_threadptr_root_fiber_setup()` is called by the parent thread and
set fib->fib_handle by ConvertThreadToFiber() on the parent thread on
Windows enveironment.
This means that root_fib->fib_handle of child thread is initialized
with parent thread's Fiber handle. Furthermore, second call of
`ConvertThreadToFiber()` for the same thread fails.
This patch solves this weird situateion. However, maybe we can make more
clean code.
* thread.c (thread_start_func_2): call
`rb_threadptr_root_fiber_setup_by_child()` at thread initialize routine.
* vm.c (th_init): call `rb_threadptr_root_fiber_setup_by_parent()`.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63073 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (vm_exec): hoist out handle_exception and loop to rewind
for each catching frames.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62652 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (vm_exec): moved code to get rid of cross-jumps across
branches.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62650 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Typo in a comment about "evaluator body".
[Fix GH-1824]
From: hkdnet <satoko.itse@gmail.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62551 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c: include dummy dtrace probes header in jit header.
* vm_insnhelper.c: probes headers are included by vm.c.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62489 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
tool/ruby_vm/views/_insn_name_info.erb: on Linux, rb_vm_insn_name_offset
was needed to compile with --jit-debug (Usually --jit-debug requires
more symbols than the situation without --jit-debug because -O2 skips
some functions to compile).
vm.c: when running transform_mjit_header.rb with --jit-wait,
rb_source_location_cstr was repoted to be missing.
string.c: ditto, for rb_str_eql
numeric.c: ditto, for rb_float_eql
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62313 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
to VM_ASSERT. r62197 is adding bp.
I'll try to remove bp, but let's pass CI which enables assertion.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62200 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
which has been developed by Takashi Kokubun <takashikkbn@gmail> as
YARV-MJIT. Many of its bugs are fixed by wanabe <s.wanabe@gmail.com>.
This JIT compiler is designed to be a safe migration path to introduce
JIT compiler to MRI. So this commit does not include any bytecode
changes or dynamic instruction modifications, which are done in original
MJIT.
This commit even strips off some aggressive optimizations from
YARV-MJIT, and thus it's slower than YARV-MJIT too. But it's still
fairly faster than Ruby 2.5 in some benchmarks (attached below).
Note that this JIT compiler passes `make test`, `make test-all`, `make
test-spec` without JIT, and even with JIT. Not only it's perfectly safe
with JIT disabled because it does not replace VM instructions unlike
MJIT, but also with JIT enabled it stably runs Ruby applications
including Rails applications.
I'm expecting this version as just "initial" JIT compiler. I have many
optimization ideas which are skipped for initial merging, and you may
easily replace this JIT compiler with a faster one by just replacing
mjit_compile.c. `mjit_compile` interface is designed for the purpose.
common.mk: update dependencies for mjit_compile.c.
internal.h: declare `rb_vm_insn_addr2insn` for MJIT.
vm.c: exclude some definitions if `-DMJIT_HEADER` is provided to
compiler. This avoids to include some functions which take a long time
to compile, e.g. vm_exec_core. Some of the purpose is achieved in
transform_mjit_header.rb (see `IGNORED_FUNCTIONS`) but others are
manually resolved for now. Load mjit_helper.h for MJIT header.
mjit_helper.h: New. This is a file used only by JIT-ed code. I'll
refactor `mjit_call_cfunc` later.
vm_eval.c: add some #ifdef switches to skip compiling some functions
like Init_vm_eval.
win32/mkexports.rb: export thread/ec functions, which are used by MJIT.
include/ruby/defines.h: add MJIT_FUNC_EXPORTED macro alis to clarify
that a function is exported only for MJIT.
array.c: export a function used by MJIT.
bignum.c: ditto.
class.c: ditto.
compile.c: ditto.
error.c: ditto.
gc.c: ditto.
hash.c: ditto.
iseq.c: ditto.
numeric.c: ditto.
object.c: ditto.
proc.c: ditto.
re.c: ditto.
st.c: ditto.
string.c: ditto.
thread.c: ditto.
variable.c: ditto.
vm_backtrace.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.
I would like to improve maintainability of function exports, but I
believe this way is acceptable as initial merging if we clarify the
new exports are for MJIT (so that we can use them as TODO list to fix)
and add unit tests to detect unresolved symbols.
I'll add unit tests of JIT compilations in succeeding commits.
Author: Takashi Kokubun <takashikkbn@gmail.com>
Contributor: wanabe <s.wanabe@gmail.com>
Part of [Feature #14235]
---
* Known issues
* Code generated by gcc is faster than clang. The benchmark may be worse
in macOS. Following benchmark result is provided by gcc w/ Linux.
* Performance is decreased when Google Chrome is running
* JIT can work on MinGW, but it doesn't improve performance at least
in short running benchmark.
* Currently it doesn't perform well with Rails. We'll try to fix this
before release.
---
* Benchmark reslts
Benchmarked with:
Intel 4.0GHz i7-4790K with 16GB memory under x86-64 Ubuntu 8 Cores
- 2.0.0-p0: Ruby 2.0.0-p0
- r62186: Ruby trunk (early 2.6.0), before MJIT changes
- JIT off: On this commit, but without `--jit` option
- JIT on: On this commit, and with `--jit` option
** Optcarrot fps
Benchmark: https://github.com/mame/optcarrot
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:--------|:--------|:--------|:--------|:--------|
|fps |37.32 |51.46 |51.31 |58.88 |
|vs 2.0.0 |1.00x |1.38x |1.37x |1.58x |
** MJIT benchmarks
Benchmark: https://github.com/benchmark-driver/mjit-benchmarks
(Original: https://github.com/vnmakarov/ruby/tree/rtl_mjit_branch/MJIT-benchmarks)
| |2.0.0-p0 |r62186 |JIT off |JIT on |
|:----------|:--------|:--------|:--------|:--------|
|aread |1.00 |1.09 |1.07 |2.19 |
|aref |1.00 |1.13 |1.11 |2.22 |
|aset |1.00 |1.50 |1.45 |2.64 |
|awrite |1.00 |1.17 |1.13 |2.20 |
|call |1.00 |1.29 |1.26 |2.02 |
|const2 |1.00 |1.10 |1.10 |2.19 |
|const |1.00 |1.11 |1.10 |2.19 |
|fannk |1.00 |1.04 |1.02 |1.00 |
|fib |1.00 |1.32 |1.31 |1.84 |
|ivread |1.00 |1.13 |1.12 |2.43 |
|ivwrite |1.00 |1.23 |1.21 |2.40 |
|mandelbrot |1.00 |1.13 |1.16 |1.28 |
|meteor |1.00 |2.97 |2.92 |3.17 |
|nbody |1.00 |1.17 |1.15 |1.49 |
|nest-ntimes|1.00 |1.22 |1.20 |1.39 |
|nest-while |1.00 |1.10 |1.10 |1.37 |
|norm |1.00 |1.18 |1.16 |1.24 |
|nsvb |1.00 |1.16 |1.16 |1.17 |
|red-black |1.00 |1.02 |0.99 |1.12 |
|sieve |1.00 |1.30 |1.28 |1.62 |
|trees |1.00 |1.14 |1.13 |1.19 |
|while |1.00 |1.12 |1.11 |2.41 |
** Discourse's script/bench.rb
Benchmark: https://github.com/discourse/discourse/blob/v1.8.7/script/bench.rb
NOTE: Rails performance was somehow a little degraded with JIT for now.
We should fix this.
(At least I know opt_aref is performing badly in JIT and I have an idea
to fix it. Please wait for the fix.)
*** JIT off
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 17
75: 18
90: 22
99: 29
home_admin:
50: 21
75: 21
90: 27
99: 40
topic_admin:
50: 17
75: 18
90: 22
99: 32
categories:
50: 35
75: 41
90: 43
99: 77
home:
50: 39
75: 46
90: 49
99: 95
topic:
50: 46
75: 52
90: 56
99: 101
*** JIT on
Your Results: (note for timings- percentile is first, duration is second in millisecs)
categories_admin:
50: 19
75: 21
90: 25
99: 33
home_admin:
50: 24
75: 26
90: 30
99: 35
topic_admin:
50: 19
75: 20
90: 25
99: 30
categories:
50: 40
75: 44
90: 48
99: 76
home:
50: 42
75: 48
90: 51
99: 89
topic:
50: 49
75: 55
90: 58
99: 99
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
that allows to JIT-compile Ruby methods by generating C code and
using C compiler. See the first comment of mjit.c to know what this
file does.
mjit.c is authored by Vladimir Makarov <vmakarov@redhat.com>.
After he invented great method JIT infrastructure for MRI as MJIT,
Lars Kanis <lars@greiz-reinsdorf.de> sent the patch to support MinGW
in MJIT. In addition to merging it, I ported pthread to Windows native
threads. Now this MJIT infrastructure can be compiled on Visual Studio.
This commit simplifies mjit.c to decrease code at initial merge. For
example, this commit does not provide multiple JIT threads support.
We can resurrect them later if we really want them, but I wanted to minimize
diff to make it easier to review this patch.
`/tmp/_mjitXXX` file is renamed to `/tmp/_ruby_mjitXXX` because non-Ruby
developers may not know the name "mjit" and the file name should make
sure it's from Ruby and not from some harmful programs. TODO: it may be
better to store this to some temporary directory which Ruby is already using
by Tempfile, if it's not bad for performance.
mjit.h: New. It has `mjit_exec` interface similar to `vm_exec`, which is
for triggering MJIT. This drops interface for AOT compared to the original
MJIT.
Makefile.in: define macros to let MJIT know the path of MJIT header.
Probably we can refactor this to reduce the number of macros (TODO).
win32/Makefile.sub: ditto.
common.mk: compile mjit.o and mjit_compile.o. Unlike original MJIT, this
commit separates MJIT infrastructure and JIT compiler code as independent
object files. As initial patch is NOT going to have ultra-fast JIT compiler,
it's likely to replace JIT compiler, e.g. original MJIT's compiler or some
future JIT impelementations which are not public now.
inits.c: define MJIT module. This is added because `MJIT.enabled?` was
necessary for testing.
test/lib/zombie_hunter.rb: skip if `MJIT.enabled?`. Obviously this
wouldn't work with current code when JIT is enabled.
test/ruby/test_io.rb: skip this too. This would make no sense with MJIT.
ruby.c: define MJIT CLI options. As major difference from original MJIT,
"-j:l"/"--jit:llvm" are renamed to "--jit-cc" because I want to support
not only gcc/clang but also cl.exe (Visual Studio) in the future. But it
takes only "--jit-cc=gcc", "--jit-cc=clang" for now. And only long "--jit"
options are allowed since some Ruby committers preferred it at Ruby
developers Meeting on January, and some of options are renamed.
This file also triggers to initialize MJIT thread and variables.
eval.c: finalize MJIT worker thread and variables.
test/ruby/test_rubyoptions.rb: fix number of CLI options for --jit.
thread_pthread.c: change for pthread abstraction in MJIT. Prefix rb_ for
functions which are used by other files.
thread_win32.c: ditto, for Windows. Those pthread porting is one of major
works that YARV-MJIT created, which is my fork of MJIT, in Feature 14235.
thread.c: follow rb_ prefix changes
vm.c: trigger MJIT call on VM invocation. Also trigger `mjit_mark` to avoid
SEGV by race between JIT and GC of ISeq. The improvement was provided by
wanabe <s.wanabe@gmail.com>.
In JIT compiler I created and am going to add in my next commit, I found
that having `mjit_exec` after `vm_loop_start:` is harmful because the
JIT-ed function doesn't proceed other ISeqs on RESTORE_REGS of leave insn.
Executing non-FINISH frame is unexpected for my JIT compiler and
`exception_handler` triggers executions of such ISeqs. So `mjit_exec`
here should be executed only when it directly comes from `vm_exec` call.
`RubyVM::MJIT` module and `.enabled?` method is added so that we can skip
some tests which don't expect JIT threads or compiler file descriptors.
vm_insnhelper.h: trigger MJIT on method calls during VM execution.
vm_core.h: add fields required for mjit.c. `bp` must be `cfp[6]` because
rb_control_frame_struct is likely to be casted to another struct. The
last position is the safest place to add the new field.
vm_insnhelper.c: save initial value of cfp->ep as cfp->bp. This is an
optimization which are done in both MJIT and YARV-MJIT. So this change
is added in this commit. Calculating bp from ep is a little heavy work,
so bp is kind of cache for it.
iseq.c: notify ISeq GC to MJIT. We should know which iseq in MJIT queue
is GCed to avoid SEGV. TODO: unload some GCed units in some safe way.
gc.c: add hooks so that MJIT can wait GC, and vice versa. Simultaneous
JIT and GC executions may cause SEGV and so we should synchronize them.
cont.c: save continuation information in MJIT worker. As MJIT shouldn't
unload JIT-ed code which is being used, MJIT wants to know full list of
saved execution contexts for continuation and detect ISeqs in use.
mjit_compile.c: added empty JIT compiler so that you can reuse this commit
to build your own JIT compiler. This commit tries to compile ISeqs but
all of them are considered as not supported in this commit. So you can't
use JIT compiler in this commit yet while we added --jit option now.
Patch author: Vladimir Makarov <vmakarov@redhat.com>.
Contributors:
Takashi Kokubun <takashikkbn@gmail.com>.
wanabe <s.wanabe@gmail.com>.
Lars Kanis <lars@greiz-reinsdorf.de>.
Part of Feature 12589 and 14235.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62189 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
th->altstack is never NULL, and even if it were, POSIX
stipulates free(3) on NULL to be a no-op.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62031 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_execution_context_mark): VM_ASSERT works only if
VM_CHECK_MODE > 0.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61695 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_execution_context_mark): check escaped directly
to skip assertions. Not sure why there is an inconsistency.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_execution_context_mark): r61624 and r61659 introduce marking miss
bug for Env objects as a prev_ep which is contained by Proc objects because
Proc objects can be collected when they should be living and Env objects
will collected unexpectedly. This patch solves this problem.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61691 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* insns.def (getblockparamproxy): introduce new instruction to return
the `rb_block_param_proxy` object if possible. This object responds
to `call` method and invoke given block (completely similar to `yield`).
* method.h (OPTIMIZED_METHOD_TYPE_BLOCK_CALL): add new optimized call type
which is for `rb_block_param_proxy.cal`.
* vm_insnhelper.c (vm_call_method_each_type): ditto.
* vm_insnhelper.c (vm_call_opt_block_call): ditto.
* vm_core.h (BOP_CALL, PROC_REDEFINED_OP_FLAG): add check for `Proc#call`
redefinition.
* compile.c (iseq_compile_each0): compile to use new insn
`getblockparamproxy` for method call.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61659 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
NODE_PRELUDE contains a `BEGIN` node, a main node, and compile_option.
This node is assumed that it must be located immediately under the root
NODE_SCOPE, but this strange assumption is not so good, IMO.
This change removes the assumtion; it integrates the former two nodes by
block_append, and moves compile_option into rb_ast_body_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61610 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
These functions take variadic arguments so no automatic type
promotion is expected. You have to do it by hand.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_vm_t): move `rb_execution_context_t::safe_level` to
`rb_vm_t::safe_level_` because `$SAFE` is a process (VM) global state.
* vm_core.h (rb_proc_t): remove `rb_proc_t::safe_level` because `Proc`
objects don't need to keep `$SAFE` at the creation.
Also make `is_from_method` and `is_lambda` as 1 bit fields.
* cont.c (cont_restore_thread): no need to keep `$SAFE` for Continuation.
* eval.c (ruby_cleanup): use `rb_set_safe_level_force()` instead of access
`vm->safe_level_` directly.
* eval_jump.c: End procs `END{}` doesn't keep `$SAFE`.
* proc.c (proc_dup): removed and introduce `rb_proc_dup` in vm.c.
* safe.c (rb_set_safe_level): don't check `$SAFE` 1 -> 0 changes.
* safe.c (safe_setter): use `rb_set_safe_level()`.
* thread.c (rb_thread_safe_level): `Thread#safe_level` returns `$SAFE`.
It should be obsolete.
* transcode.c (load_transcoder_entry): `rb_safe_level()` only returns
0 or 1 so that this check is not needed.
* vm.c (vm_proc_create_from_captured): don't need to keep `$SAFE` for Proc.
* vm.c (rb_proc_create): renamed to `proc_create`.
* vm.c (rb_proc_dup): moved from proc.c.
* vm.c (vm_invoke_proc): do not need to set and restore `$SAFE`
for `Proc#call`.
* vm_eval.c (rb_eval_cmd): rename a local variable to represent clearer
meaning.
* lib/drb/drb.rb: restore `$SAFE`.
* lib/erb.rb: restore `$SAFE`, too.
* test/lib/leakchecker.rb: check `$SAFE == 0` at the end of tests.
* test/rubygems/test_gem.rb: do not set `$SAFE = 1`.
* bootstraptest/test_proc.rb: catch up this change.
* spec/ruby/optional/capi/string_spec.rb: ditto.
* test/bigdecimal/test_bigdecimal.rb: ditto.
* test/fiddle/test_func.rb: ditto.
* test/fiddle/test_handle.rb: ditto.
* test/net/imap/test_imap_response_parser.rb: ditto.
* test/pathname/test_pathname.rb: ditto.
* test/readline/test_readline.rb: ditto.
* test/ruby/test_file.rb: ditto.
* test/ruby/test_optimization.rb: ditto.
* test/ruby/test_proc.rb: ditto.
* test/ruby/test_require.rb: ditto.
* test/ruby/test_thread.rb: ditto.
* test/rubygems/test_gem_specification.rb: ditto.
* test/test_tempfile.rb: ditto.
* test/test_tmpdir.rb: ditto.
* test/win32ole/test_win32ole.rb: ditto.
* test/win32ole/test_win32ole_event.rb: ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61510 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Functions declared in include/ruby/backward.h is exported only when
the condition `!defined RUBY_EXPORT && !defined RUBY_NO_OLD_COMPATIBILITY`
is met (i.e. included by include/ruby/ruby.h).
So if it is not the case when ruby is built, this will not be exported.
This was not intentional at r60994.
[Bug #14192]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61296 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* Adapt test and add specs.
* See [Feature #14143] [ruby-core:84227]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61237 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* [Feature #14143] [ruby-core:83979]
* vm.c (vm_init2): Set Thread.report_on_exception to true.
* thread.c (thread_start_func_2): Add indication the message is caused
by report_on_exception = true.
* spec/ruby: Specify the new behavior.
* test/ruby/test_thread.rb: Adapt and improve tests for
Thread.report_on_exception and Thread#report_on_exception.
* test/ruby/test_thread.rb, test/ruby/test_exception.rb: Unset
report_on_exception for tests expecting no extra output.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61183 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c: introduce `ruby_vm_event_enabled_flags` which represents which
event flags are enabled before.
* vm_trace.c: do not turn off `trace_` prefix instructions because turn on
overhead is a matter if a program repeats turn on and turn off frequently.
* iseq.c (finish_iseq_build): respect `ruby_vm_event_enabled_flags`.
* vm_insnhelper.c (vm_trace): check `ruby_vm_event_flags` and disable
lazy trace-off technique (do not disable traces).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61122 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because it was actually used in
https://github.com/tmm1/rbtrace/blob/v0.4.8/ext/rbtrace.c#L329
and deprecated in r60579 AFTER removal in r60558.
ko1 agreed that we should keep just deprecated in Ruby 2.5 and remove it
later, and I'm commiting this because I want to make rbtrace.gem
installation successful.
backward.h: modify r60579 to make rb_frame_method_id_and_class()
compilable.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60964 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_proc_create_from_captured): make this func static and renmae
with vm_ prefix.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60800 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_source_loc): rename to rb_source_location_cstr()
to make behavior clear compare with rb_source_location().
* error.c (warning_string): use rb_source_location_cstr() directly.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60792 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_source_location): return nil if path is not found.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60789 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_sourcefilename): removed because nobody use it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60788 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_t): remove rb_thread_t::event_hooks.
* vm_trace.c: all hooks are connected to vm->event_hooks and
add rb_event_hook_t::filter::th to filter invoke thread.
It will simplify invoking hooks code.
* thread.c (thread_start_func_2): clear thread specific trace_func.
* test/ruby/test_settracefunc.rb: add a test for Thread#add_trace_func.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60776 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_execution_context_t): renmae ec::fiber to
ec::fiber_ptr make consistent with ec::thread_ptr.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60670 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_frame_method_id_and_class): removed because nobody use it.
* vm.c (rb_thread_current_status): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60558 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_thread_method_id_and_class): rename to
rb_ec_frame_method_id_and_class() and accepts `ec` instead of `th`.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60513 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h: move rb_thread_t::passed_block_handler to
rb_execution_context_t::passed_block_handler.
Also move rb_thread_t::passed_bmethod_me to
rb_execution_context_t::passed_bmethod_me.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60503 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_execution_context_mark): At the beggining of GC marking,
mark_current_machine_context() marks running machine stack so that
rb_execution_context_mark() should not mark machine stack if it is
current ec.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60499 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (thread_free): simply call rb_threadptr_root_fiber_release().
* cont.c (rb_threadptr_root_fiber_release): release th->ec (ec->fiber)
iff root_fiber is NULL. If root_fiber is available, then ignore it
and root fiber object will free th->ec too.
* cont.c (rb_threadptr_root_fiber_setup): do not set th->root_fiber.
th->root_fiber will be set if a root fiber object is created.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60451 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
to represent execution context [Feature #14038]
* vm_core.h (rb_thread_t): rb_thread_t::ec is now a pointer.
There are many code using `th` to represent execution context
(such as cfp, VM stack and so on). To access `ec`, they need to
use `th->ec->...` (adding one indirection) so that we need to
replace them by passing `ec` instead of `th`.
* vm_core.h (GET_EC()): introduced to access current ec. Also
remove `ruby_current_thread` global variable.
* cont.c (rb_context_t): introduce rb_context_t::thread_ptr instead of
rb_context_t::thread_value.
* cont.c (ec_set_vm_stack): added to update vm_stack explicitly.
* cont.c (ec_switch): added to switch ec explicitly.
* cont.c (rb_fiber_close): added to terminate fibers explicitly.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60440 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* array.c (rb_to_array_type): make public to share common code
internally.
* hash.c (rb_to_hash_type): make public to share common code
internally.
* symbol.c (rb_to_symbol_type): make public to share common code
internally.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60438 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
A temporary NODE object was allocated to create iseq. Instead, this
patch allocates a dummy NODE as auto variable, and discard it soon.
This change is intended as a preparation to manage AST NODEs out of GC.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60390 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This change is for future JIT compiler introduction.
See r60231 for the purpose.
[close GH-1721]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_vm_jump_tag_but_local_jump): no longer used since
r51292.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60025 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_vm_make_jump_tag_but_local_jump): get rid of fetching
retval when it is not used. it is necessary for local jump
state only.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60024 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
when raising exception in bmethod call event
* vm.c (invoke_bmethod): set FINISH flag just before calling vm_exec.
[ruby-dev:50162] [Bug #13705]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59956 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (rb_context_t): introduce saved_ec instaad of saved_thread.
We only need to transfer ec data (not all of thread data).
Introduce `thread_value` field to point creation thread.
To acccess this field, `cont_thread_value()` is introduced.
* vm.c (rb_execution_context_mark): remove `static` and use it
from cont.c (use this function instead of `rb_thread_mark`).
* vm_insnhelper.c (rb_vm_push_frame): accept ec instead of th.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59831 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c: VM_EP_IN_HEAP_P() and vm_ep_in_heap_p_() only requires ec
pointed from th.
* vm.c (rb_execution_context_mark): GET_THREAD() returns current
running thread and we need to use marking thread here. Pass marking
thread's ec instead of current thread.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59756 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (rb_execution_context_mark): separate from thread_mark().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59752 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Sometimes, size of a hash can be calcluated a priori. By providing
such info to the constructor we can avoid unnecessary internal re-
allocations. This can boost for instance creation of hash literals.
[Bug #13861]
Signed-off-by: Urabe, Shyouhei <shyouhei@ruby-lang.org>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59744 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_insnhelper.c (threadptr_stack_overflow): set stack overflow
flag until handling execptions, to get rid of cfp consistency
error when exec tag was rewound. [ruby-core:80618] [Bug #13412]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59606 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h: Ruby processes run with two stacks, a machine stack and a
VM stack. To make it clear, this fix renames
rb_execution_context_t::stack(_size) to vm_stack(_size).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59563 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c (root_fiber_alloc): this function is called by fiber_current()
and fiber_store(). fiber_current() should clear VM stack information
in a fiber data because runnning thread knows stack information and has
responsibility to manage it. However fiber_store() requires to remain
VM stack information in a fiber data because the responsibility to manage
VM stack is moved to the Fiber from the Thread (and switch to another
fiber).
* cont.c (root_fiber_alloc): save thread's fiber and root_fiber information.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59474 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* cont.c: r55766 change the handling method of Fiber's VM stack.
Resumed Fiber points NULL as VM stack and running Thread has
responsibility to manage it (marking and releasing).
However, thread_start_func_2()@thread.c and thread_free()@vm.c
doesn't free the VM stack if corresponding root Fiber is exist.
This causes memory leak. [Bug #13772]
* cont.c (root_fiber_alloc): fib->cont.saved_thread.ec.stack should be NULL
because running thread has responsibility to manage this stack.
* vm.c (rb_thread_recycle_stack_release): assert given stack is not NULL
(callers should care it).
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59462 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_vm_struct): separate trap_list cmd and safe to
each arrays, to shrink the size.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59434 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
These caused numerous CI failures I haven't been able to
reproduce [ruby-core:82102]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59364 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The same hash keys may be loaded from tainted data sources
frequently (e.g. parsing headers from socket or loading
YAML data from a file). If a non-tainted fstring already
exists (because the application expects the hash key),
cache and deduplicate the tainted version in the new
tainted_frozen_strings table.
For non-embedded strings, this also allows sharing with the
underlying malloc-ed data.
* vm_core.h (rb_vm_struct): add tainted_frozen_strings
* vm.c (ruby_vm_destruct): free tainted_frozen_strings
(Init_vm_objects): initialize tainted_frozen_strings
(rb_vm_tfstring_table): accessor for tainted_frozen_strings
* internal.h: declare rb_fstring_existing, rb_vm_tfstring_table
* hash.c (fstring_existing_str): remove (moved to string.c)
(hash_aset_str): use rb_fstring_existing
* string.c (rb_fstring_existing): new, based on fstring_existing_str
(tainted_fstr_update): new
(rb_fstring_existing0): new, based on fstring_existing_str
(rb_tainted_fstring_existing): new, special case for tainted strings
(rb_str_free): delete from tainted_frozen_strings table
* test/ruby/test_optimization.rb (test_hash_reuse_fstring): new test
[ruby-core:82012] [Bug #13737]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59354 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (vm_init_redefined_flag): set redefinition flag for Symbol#==.
The bug was introduced in r58895.
* test/ruby/test_symbol.rb: test for above.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59250 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_ptr): added to replace GetThreadPtr() macro.
* thread.c (in some functions: use "target_th" instead of "th" to make clear
that it is not a current thread.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59192 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_t): move several fields which are copied at cont.c
to rb_execution_context_t.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59177 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_t::tag_state): move to "rb_vm_tag::state".
Lifetime of "state" should be same as current tag.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59159 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (rb_thread_t): rename rb_thread_t::state to tag_state
to make it clear.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59158 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Return value of EXEC_TAG() is saved by "int state".
Instead of "int", use "enum ruby_tag_type". First EXEC_TAG()
value should be 0, so that define TAG_NONE (= 0) and use it.
Some code used "status" instead of "state". To make them clear,
rename them to state.
We can change variable name from "state" to "tag_state", but this
ticket doesn't contain it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59155 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h (vm_block_handler_verify): this function only checks
the given block handler with VM_ASSERT(). No need to return any value.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59045 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_eval.c (yield_under): do not inform Proc is lambda or not.
After that invoke_block_from_c_bh() checks it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59017 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* internal.h (rb_yield_lambda): rename to rb_yield_force_blockarg()
because this function prohibt lambda arg setup (strict setup).
* vm.c (invoke_iseq_block_from_c): remove splattable argument because
it is not used.
* vm.c (invoke_block_from_c_splattable): rename to invoke_block_from_c_bh()
because `splattable` doesn't make sense on current this function.
Also accept `force_blockarg' parameter instead of `splattable` parameter.
It is more clear.
* vm.c (invoke_block_from_c_unsplattable): rename to
invoke_block_from_c_proc() and accept `proc` instead of `block'.
This function is used only by proc block invocation.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59016 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_args.c (enum arg_setup_type): remove arg_setup_lambda because it is
same as arg_setup_method.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59014 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
VM_FRAME_FLAG_LAMBDA. So that lambda block frame is
VM_FRAME_MAGIC_BLOCK | VM_FRAME_FLAG_LAMBDA.
* vm_core.h: remvoe VM_FRAME_MAGIC_PROC because nobody uses it.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59006 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* proc.c (ruby_binding_data_type): set RUBY_TYPED_WB_PROTECTED.
Insert write barriers (WBs) to all of writes.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58988 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h: rename absolute_path to realpath because it is expected name.
external APIs (#absolute_path methods) are remained.
* vm_core.h: remove rb_iseq_location_struct::path and
rb_iseq_location_struct::absolute_path and introduce pathobj.
if given path equals to given absolute_path (and most of case
it is true), pathobj is simply given path String. If it is not same,
pathobj is Array and pathobj[0] is path and pathobj[1] is realpath.
This size optimization reduce 8 bytes and
sizeof(struct rb_iseq_constant_body) is 200 bytes -> 192 bytes
on 64bit CPU.
To support this change, the following functions are introduced:
* pathobj_path() (defined in vm_core.h)
* pathobj_realpath() (ditto)
* rb_iseq_path() (decl. in vm_core.h)
* rb_iseq_realpath() (ditto)
* rb_iseq_pathobj_new() (ditto)
* rb_iseq_pathobj_set() (ditto)
* vm_core.h (rb_binding_t): use pathobj instead of path. If binding
is given at eval methods, realpath (absolute_path) was caller's
realpath. However, they should use binding's realpath.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58979 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
To convert the object implicitly, it has had two parts in convert_type() which are
1. lookink up the method's id
2. calling the method
Seems that strncmp() and strcmp() in convert_type() are slightly heavy to look up
the method's id for type conversion.
This patch will add and use internal APIs (rb_convert_type_with_id, rb_check_convert_type_with_id)
to call the method without looking up the method's id when convert the object.
Array#flatten -> 19 % up
Array#+ -> 3 % up
[ruby-dev:50024] [Bug #13341] [Fix GH-1537]
### Before
Array#flatten 104.119k (± 1.1%) i/s - 525.690k in 5.049517s
Array#+ 1.993M (± 1.8%) i/s - 10.010M in 5.024258s
### After
Array#flatten 124.005k (± 1.0%) i/s - 624.240k in 5.034477s
Array#+ 2.058M (± 4.8%) i/s - 10.302M in 5.019328s
### Test Code
require 'benchmark/ips'
class Foo
def to_ary
[1,2,3]
end
end
Benchmark.ips do |x|
ary = []
100.times { |i| ary << i }
array = [ary]
x.report "Array#flatten" do |i|
i.times { array.flatten }
end
x.report "Array#+" do |i|
obj = Foo.new
i.times { array + obj }
end
end
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58978 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Today, it increases IO#close performance with many threads:
Execution time (sec)
name trunk after
vm_thread_close 4.276 3.018
Speedup ratio: compare with the result of `trunk' (greater is better)
name after
vm_thread_close 1.417
This speedup comes because rb_notify_fd_close only scans threads
inside rb_thread_io_blocking_region, not all threads in the VM.
In the future, this type data structure may allow us to notify
waiters of multiple FDs on a single thread (when using
Fibers).
* thread.c (struct waiting_fd): declare
(rb_thread_io_blocking_region): use on-stack list waiter
(rb_notify_fd_close): walk vm->waiting_fds instead
(call_without_gvl): remove old field setting
(th_init): ditto
* vm_core.h (typedef struct rb_vm_struct): add waiting_fds list
* (typedef struct rb_thread_struct): remove waiting_fd field
(rb_vm_living_threads_init): initialize waiting_fds list
I am now kicking myself for not thinking about this 3 years ago
when I introduced ccan/list in [Feature #9632] to optimize this
same function :<
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58812 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm.c (ruby_vm_run_at_exit_hooks): should free by `ruby_xfree`
memories allocated by `ALLOC`.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58670 b2dd03c8-39d4-4d8f-98ff-823fe69b080e