* 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
Here, recv can be INT2FIX(-1), which is 0xFFFF_FFFFul.
INT2FIX(1) is 3ul. So `recv - 1 + INT2FIX(1)` is:
recv 0xFFFF_FFFFul
recv-1 0xFFFF_FFFEul (note: unsigned)
recv-1+INT2FIX(1) 0x0000_0001ul Here is the overflow.
Given recv is a Fixnum, it can never be 0xFFFF_FFFD. 0xFFFF_FFFF is
the only value that can overflow this way, so special-casing this
value should just suffice.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65828 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
space_size can be zero here, under the following script. We would
better bail out before bptr calculation.
% ./miniruby --dump=i -e '* = nil'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,7)> (catch: FALSE)
0000 putnil ( 1)[Li]
0001 dup
0002 expandarray 0, 0
0005 leave
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65685 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_insnhelper.c (vm_yield_with_cfunc): use passed me as bmethod.
We also need to set `VM_FRAME_FLAG_BMETHOD` if needed.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65639 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_core.h: remove `rb_execution_context_t::passed_bmethod_me`
and fix functions to pass the `me` directly.
`passed_bmethod_me` was used to make bmethod (methods defined by
`defined_method`). `rb_vm_invoke_bmethod` invoke `Proc` with `me`
information as method frame (`lambda` frame, actually).
If the proc call is not bmethod call, `passed_bmethod_me` should
be NULL. However, there is a bug which passes wrong `me` for
normal block call.
http://ci.rvm.jp/results/trunk-asserts@silicon-docker/1449470
This is because wrong `me` was remained in `passed_bmethod_me`
(and used incorrectly it after collected by GC).
We need to clear `passed_bmethod_me` just after bmethod call,
but clearing is not enough.
To solve this issue, I removed `passed_bmethod_me` and pass `me`
information as a function parameter of `rb_vm_invoke_bmethod`,
`invoke_block_from_c_proc` and `invoke_iseq_block_from_c` in vm.c.
* vm.c (invoke_iseq_block_from_c): the number of parameters is too
long so that I try to specify `ALWAYS_INLINE`.
* vm.c (invoke_block_from_c_proc): ditto.
* vm_insnhelper.c (vm_yield_with_cfunc): now there are no pathes
to use bmethod here.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65636 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
* transient_heap.c, transient_heap.h: implement TransientHeap (theap).
theap is designed for Ruby's object system. theap is like Eden heap
on generational GC terminology. theap allocation is very fast because
it only needs to bump up pointer and deallocation is also fast because
we don't do anything. However we need to evacuate (Copy GC terminology)
if theap memory is long-lived. Evacuation logic is needed for each type.
See [Bug #14858] for details.
* array.c: Now, theap for T_ARRAY is supported.
ary_heap_alloc() tries to allocate memory area from theap. If this trial
sccesses, this array has theap ptr and RARRAY_TRANSIENT_FLAG is turned on.
We don't need to free theap ptr.
* ruby.h: RARRAY_CONST_PTR() returns malloc'ed memory area. It menas that
if ary is allocated at theap, force evacuation to malloc'ed memory.
It makes programs slow, but very compatible with current code because
theap memory can be evacuated (theap memory will be recycled).
If you want to get transient heap ptr, use RARRAY_CONST_PTR_TRANSIENT()
instead of RARRAY_CONST_PTR(). If you can't understand when evacuation
will occur, use RARRAY_CONST_PTR().
(re-commit of r65444)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65449 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* transient_heap.c, transient_heap.h: implement TransientHeap (theap).
theap is designed for Ruby's object system. theap is like Eden heap
on generational GC terminology. theap allocation is very fast because
it only needs to bump up pointer and deallocation is also fast because
we don't do anything. However we need to evacuate (Copy GC terminology)
if theap memory is long-lived. Evacuation logic is needed for each type.
See [Bug #14858] for details.
* array.c: Now, theap for T_ARRAY is supported.
ary_heap_alloc() tries to allocate memory area from theap. If this trial
sccesses, this array has theap ptr and RARRAY_TRANSIENT_FLAG is turned on.
We don't need to free theap ptr.
* ruby.h: RARRAY_CONST_PTR() returns malloc'ed memory area. It menas that
if ary is allocated at theap, force evacuation to malloc'ed memory.
It makes programs slow, but very compatible with current code because
theap memory can be evacuated (theap memory will be recycled).
If you want to get transient heap ptr, use RARRAY_CONST_PTR_TRANSIENT()
instead of RARRAY_CONST_PTR(). If you can't understand when evacuation
will occur, use RARRAY_CONST_PTR().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65444 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because it's not supported by this file. Also, shared `def_iseq_ptr`
instead of copying the main definition of it.
vm_core.h: moved `def_iseq_ptr` to this place. added `inline` to avoid
compiler warnings since it's not used in some files including vm_core.h.
vm_insnhelper.c: moved `def_iseq_ptr` to vm_core.h.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65440 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
The instructions were used only for branch coverage.
Instead, it now uses a trace framework [Feature #14104].
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65225 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
We have several options to ensure there's no race condition between main
thread and MJIT thead about IC reference:
1) Give up caching ivar for multiple classes (or multiple versions of the
same class) in the same getinstancevariable (This commit's approach)
2) Allocate new inline cache every time
Other ideas we could think of couldn't eliminate possibilities of race
condition.
In 2, it's memory allocation would be slow and it may trigger JIT
cancellation frequently. So 1 would be fast for both VM and JIT
situations.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65213 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* vm_insnhelper.c (vm_push_frame): validate prev_frame because
prev_frame can be the end of frame.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65162 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
No major performance impact, but just in case for some platform
that matters.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65062 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
That optimization is already reverted and we're not retrying the
optimization soon. Let me simplify the code of vm_getivar.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65061 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
* debug_counter.h: add debug counters to count frame state transitions:
* frame_R2R: Ruby frame to Ruby frame
* frame_R2C: Ruby frame to C frame
* frame_C2C: C frame to C frame
* frame_C2R: C frame to Ruby frame
* vm_insnhelper.c (vm_push_frame): ditto.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
* debug_counter.h: add the following counters.
* frame_push: control frame counts (total counts).
* frame_push_*: control frame counts per every frame type.
* obj_*: add free'ed counts for each type.
* gc.c: ditto.
* vm_insnhelper.c (vm_push_frame): ditto.
* debug_counter.c (rb_debug_counter_show_results): widen counts field
to show >10G numbers.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64867 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
by sharing vm_call_iseq_setup_normal. This is a retry of r64280.
vm_insnhelper.c: Remove unused argument `ci` and pass `me` instead of
`cc` to share this with JIT. Declare this with ALWAYS_INLINE to make
sure this function is inlined in JIT.
tool/mk_call_iseq_optimized.rb: deal with the interface change of
vm_call_iseq_setup_normal.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64820 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
for CC_SET_FASTPATH condition. Just a cosmetic change to unify the
styling with other lines.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64775 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because it's actually setting fastpath to cc instead of ci since r51903.
vm_insnhelper.c: ditto
mjit_compile.c: ditto
tool/ruby_vm/views/_mjit_compile_send.erb: ditto
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64772 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
because cc->call is NULL by default and it is not overridden by
vm_search_super_method if OPT_CALL_FASTPATH is 0. So this macro is not
just a switch for optimization but now it's mandatory.
vm_insnhelper.c: cosmetic change. Use boolean-ish `TRUE` instead of 1 to
specify `enabled` flag.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64735 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Simply use DISPATCH_ORIGINAL_INSN instead of rb_funcall. This is,
when possible, overall performant because method dispatch results are
cached inside of CALL_CACHE. Should also be good for JIT.
----
trunk: ruby 2.6.0dev (2018-09-12 trunk 64689) [x86_64-darwin15]
ours: ruby 2.6.0dev (2018-09-12 leaf-insn 64688) [x86_64-darwin15]
last_commit=make opt_str_freeze leaf
Calculating -------------------------------------
trunk ours
vm2_freezestring 5.440M 31.411M i/s - 6.000M times in 1.102968s 0.191017s
Comparison:
vm2_freezestring
ours: 31410864.5 i/s
trunk: 5439865.4 i/s - 5.77x slower
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64690 b2dd03c8-39d4-4d8f-98ff-823fe69b080e