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

464 Коммитов

Автор SHA1 Сообщение Дата
shyouhei 7d4ad74f22 also use sp_inc in vm core
Now that sp_inc attributes are officially provided as inline
functions. Why not use them directly from the vm core, not just
by the compiler. By doing so, it is now possible for us to
optimize stack manipulations. We can now know exactly how many
words of stack space an instruction consumes before it actually
does. This changeset deletes some lines from insns.def because
they are no longer needed.  As a result it reduces the size of
vm_exec_core function from 32,400 bytes to 32,352 bytes on my
machine.

It seems it does not affect performance:

-----------------------------------------------------------
benchmark results:
minimum results in each 3 measurements.
Execution time (sec)
name    before  after
loop_for         1.093  1.061
loop_generator   1.156  1.152
loop_times       0.982  0.974
loop_whileloop   0.549  0.587
loop_whileloop2  0.115  0.121

Speedup ratio: compare with the result of `before' (greater is better)
name    after
loop_for        1.030
loop_generator  1.003
loop_times      1.008
loop_whileloop  0.935
loop_whileloop2 0.949

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62087 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-29 06:56:56 +00:00
k0kubun 6cb0126773 insns.def: [DOC] update supported attributes [ci skip]
which are changed at r62051.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62074 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-27 13:50:28 +00:00
shyouhei 3234245ae3 move ADD_PC around to optimize PC manipluiations
This commit introduces new attribute handles_flame and if that is
_not_ the case, places ADD_PC right after INC_SP.  This improves
locality of PC manipulations to prevents unnecessary register spill-
outs. As a result, it reduces the size of vm_exec_core from 32,688
bytes to 32,384 bytes on my machine.

Speedup is very faint, but certain.

-----------------------------------------------------------
benchmark results:
minimum results in each 3 measurements.
Execution time (sec)
name    before  after
so_ackermann     0.476  0.464
so_array         0.742  0.728
so_binary_trees  5.493  5.466
so_concatenate   3.619  3.395
so_count_words   0.190  0.184
so_exception     0.249  0.239
so_fannkuch      0.994  0.953
so_fasta         1.369  1.374
so_k_nucleotide  1.111  1.111
so_lists         0.470  0.481
so_mandelbrot    2.059  2.050
so_matrix        0.466  0.465
so_meteor_contest        2.712  2.781
so_nbody         1.154  1.204
so_nested_loop   0.852  0.846
so_nsieve        1.636  1.623
so_nsieve_bits   2.073  2.039
so_object        0.616  0.584
so_partial_sums  1.464  1.481
so_pidigits      1.075  1.082
so_random        0.321  0.317
so_reverse_complement    0.555  0.558
so_sieve         0.495  0.490
so_spectralnorm  1.634  1.627

Speedup ratio: compare with the result of `before' (greater is better)
name    after
so_ackermann    1.025
so_array        1.019
so_binary_trees 1.005
so_concatenate  1.066
so_count_words  1.030
so_exception    1.040
so_fannkuch     1.043
so_fasta        0.996
so_k_nucleotide 1.000
so_lists        0.978
so_mandelbrot   1.004
so_matrix       1.001
so_meteor_contest       0.975
so_nbody        0.959
so_nested_loop  1.007
so_nsieve       1.008
so_nsieve_bits  1.017
so_object       1.056
so_partial_sums 0.989
so_pidigits     0.994
so_random       1.014
so_reverse_complement   0.996
so_sieve        1.010
so_spectralnorm 1.004

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62051 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-26 06:30:58 +00:00
shyouhei a1d6fba33b suppress warning for VC12
It says "warning C4146: unary minus operator applied
to unsigned type, result still unsigned"


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61794 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-12 13:25:03 +00:00
shyouhei 9456f88f00 [ci skip] add comments about file format (2nd try)
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61783 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-12 08:38:08 +00:00
shyouhei e2b7cb9d32 new insns.def format (2nd try)
- Gave up @j comments
- Room for sp_inc to be a proper grammer element

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61782 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-12 08:38:07 +00:00
shyouhei 5ad95486e6 merge revisions 61753:61750 61747:61740 61737:61728
Revert all the VM generator rewrites; requested by naruse


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61755 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-10 01:53:24 +00:00
kazu a3ecb0f82d Fix a typo [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61751 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-10 00:01:31 +00:00
shyouhei 310be7547d [ci skip] add comments about file format
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61730 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-09 13:30:29 +00:00
shyouhei 89df12d849 new insns.def format
- Gave up @j comments
- Room for sp_inc to be a proper grammer element

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61729 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-09 13:30:28 +00:00
ko1 7fd1183467 Speedup `block.call` [Feature #14330]
* 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
2018-01-07 19:18:49 +00:00
ko1 0d2346f9a1 Speedup `Proc#call` [Feature #14318]
* vm_insnhelper.c (vm_call_opt_call): do same process of `yield` instead of
  invoking `Proc`.

* vm_insnhelper.c (vm_invoke_block): invoke given block handler instead of
  using a block handler in the current frame.
  Also do not check blcok handler here (caller should check it).

* insns.def (invokeblock): catch up this fix.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61624 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-05 17:51:10 +00:00
ko1 0268c85e85 * insns.def (invokeblock): `calling->recv` is not used.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61606 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-01-05 07:25:55 +00:00
nobu e3f46b1dc5 insns.def: adjust type
* insns.def (checkkeyword): adjust argument type to
  vm_check_keyword as lindex_t.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61420 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-12-23 00:51:36 +00:00
mame c08e8886ba compile.c: add a RUBY_EVENT_COVERAGE_LINE event for line coverage
2.5's line coverage measurement was about two times slower than 2.4
because of two reasons; (1) vm_trace uses rb_iseq_event_flags (which
takes O(n) currently where n is the length of iseq) to get an event
type, and (2) RUBY_EVENT_LINE uses setjmp to call an event hook.

This change adds a special event for line coverage,
RUBY_EVENT_COVERAGE_LINE, and adds `tracecoverage` instructions where
the event occurs in iseq.
`tracecoverage` instruction calls an event hook without vm_trace.
And, RUBY_EVENT_COVERAGE_LINE is an internal event which does not
use setjmp.

This change also cancells lineno change due to the deletion of trace
instructions [Feature #14104].  So fixes [Bug #14191].

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61350 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-12-20 04:24:14 +00:00
mame c7e4f91246 insns.def (tracebranch): renamed from `trace2`
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61047 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-12-06 07:04:49 +00:00
ko1 2fb4c36c44 accepts `ec` as first parameter.
* vm_insnhelper.c (vm_check_match): accepts `ec` as first parameter.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60794 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-16 06:10:31 +00:00
ko1 665ba24b44 remove `trace` instruction. [Feature #14104]
* tool/instruction.rb: create `trace_` prefix instructions.

* compile.c (ADD_TRACE): do not add `trace` instructions but add
  TRACE link elements. TRACE elements will be unified with a next
  instruction as instruction information.

* vm_trace.c (update_global_event_hook): modify all ISeqs when
  hooks are enabled.

* iseq.c (rb_iseq_trace_set): added to toggle `trace_` instructions.

* vm_insnhelper.c (vm_trace): added.
  This function is a body of `trace_` prefix instructions.

* vm_insnhelper.h (JUMP): save PC to a control frame.

* insns.def (trace): removed.

* vm_exec.h (INSN_ENTRY_SIG): add debug output (disabled).


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60763 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-14 12:58:36 +00:00
ko1 0c2746a7bb th->ec: dtrace
* vm.c (ruby_th_dtrace_setup): rename to rb_dtrace_setup()
  and accept `ec`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60696 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-07 08:19:25 +00:00
ko1 8ea78d66a1 th->ec: vm_once_dispatch.
* vm_insnhelper.c (vm_once_dispatch): accepts `ec`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60693 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-07 06:14:00 +00:00
ko1 5dfdaa9299 move rb_thread_t::interrupt_flag and mask
to rb_execution_context_t.

* vm_core.h (rb_thread_t): move
  `rb_thread_t::interrupt_flag` and
  `rb_thread_t::interrupt_mask` to rb_execution_context_t.

  RUBY_VM_CHECK_INTS() accepts `ec` instead of `th`.

* cont.c (rb_fiber_terminate): to propagate interrupt information,
  add new parameter `need_interrupt`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60672 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-11-06 07:44:28 +00:00
ko1 a288b87c4c EXEC_EVENT_HOOK(ec, ...)
* vm_core.h (EXEC_EVENT_HOOK): accepts `ec` instead of `th`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60539 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-29 13:19:14 +00:00
ko1 7e9aca4071 catch up recent changes for call threaded code VM.
Fix compile errors for OPT_CALL_THREADED_CODE (in vm_opts.h).


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60493 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 19:16:51 +00:00
ko1 baa849443f `th` -> `ec` for `rb_insn_func_t`.
* vm_core.h (rb_insn_func_t): accepts `ec` instead of `th`.

* vm_insnhelper.c (rb_vm_opt_struct_aref): ditto.

* vm_insnhelper.c (rb_vm_opt_struct_aset): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60492 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 19:08:31 +00:00
ko1 04dc3a0ca6 vm_exec_core() accepts `ec` instead of `th`.
* vm_exec.c (vm_exec_core): accepts `ec` instead of `th`.

* vm_args.c (vm_caller_setup_arg_block): also accepts `ec`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60477 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 06:21:50 +00:00
ko1 88910e94a8 `th` -> `ec` for block related functions.
* vm.c: the following functions accept `ec` instead of `th`.
  * invoke_block
  * invoke_bmethod
  * invoke_iseq_block_from_c
  * invoke_block_from_c_bh
  * check_block_handler
  * vm_yield_with_cref
  * vm_yield
  * vm_yield_with_block
  * vm_yield_force_blockarg
  * invoke_block_from_c_proc
  * vm_invoke_proc
  * vm_invoke_bmethod
  * rb_vm_invoke_proc

* vm_insnhelper.c: ditto.
  * vm_yield_with_cfunc
  * vm_yield_with_symbol
  * vm_callee_setup_block_arg
  * vm_yield_setup_args
  * vm_invoke_iseq_block
  * vm_invoke_symbol_block
  * vm_invoke_ifunc_block
  * vm_invoke_block


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 06:06:31 +00:00
ko1 f37049ec05 `ec` -> `th`
* vm_exec.h (VM_SP_CNT): accepts `ec` instead of `th`.

* vm_insnhelper.c (vm_stack_consistency_error): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60474 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 05:33:33 +00:00
ko1 7267a79a7f vm_defined() accepts `ec` instead of `th`.
* vm_insnhelper.c (vm_defined): accepts `ec` instead of `th`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60473 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 05:30:05 +00:00
ko1 ac58719ab3 vm_search_super_method() accepts `ec` instead of `th`.
* vm_insnhelper.c (vm_search_super_method): accepts `ec` instead of `th`.
  Surprisingly, it doesn't use `th` (now `ec`) so this patch is for
  the future extension.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60471 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 05:22:24 +00:00
ko1 b5101cbb23 vm_get_ev_const() accepts `ec` instead of `th`.
* vm_insnhelper.c (vm_get_ev_const): accepts `ec` instead of `th`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60470 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 05:18:58 +00:00
ko1 2f4e6b6c4f vm_throw* accept `ec` instead of `th`.
* vm_insnhelper.c (vm_throw*): accept `ec` instead of `th`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60467 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 01:35:12 +00:00
ko1 84e6a3d31c ec->th for vm_cref_push() and constify.
* vm_insnhelper.c (vm_cref_push): accepts `ec` instead of `th`.

* vm_insnhelper.c: consitfy the first parameter (ec):
  * lep_svar
  * lep_svar_write
  * lep_svar_get
  * lep_svar_set
  * vm_getspecial
  and added vm_cref_push.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60466 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 01:31:15 +00:00
ko1 34ff953e37 Some functions accept `ec` instead of `th`.
* vm_insnhelper.c: The following functions accept `ec` instead of `th`.
  * lep_svar
  * lep_svar_write
  * lep_svar_get
  * lep_svar_set
  * vm_getspecial


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60465 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-27 01:22:01 +00:00
ko1 a8868b3fe5 rb_vm_bh_to_procval() accepts `ec` instead of `th`.
* vm_insnhelper.c (rb_vm_bh_to_procval): accepts `ec` instead of `th`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60460 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-26 23:33:59 +00:00
ko1 284d4c08d6 vm_pop_frame() accepts `ec` instead of `th`.
* vm_insnhelper.c (vm_pop_frame): accepts `ec` instead of `th`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60448 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-26 10:55:24 +00:00
ko1 9adf6064ce vm_push_frame() accepts `ec` instead of `th`.
* vm_insnhelper.c (vm_push_frame): accepts `ec` instead of `th`.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60447 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-26 10:53:42 +00:00
ko1 837fd5e494 Use rb_execution_context_t instead of rb_thread_t
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
2017-10-26 08:32:49 +00:00
ko1 5ee9513a71 Lazy Proc allocation for block parameters
[Feature #14045]

* insns.def (getblockparam, setblockparam): add special access
  instructions for block parameters.
  getblockparam checks VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM and
  if it is not set this instruction creates a Proc object from
  a given blcok and set VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM.
  setblockparam is similar to setlocal, but set
  VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM.

* compile.c: use get/setblockparm instead get/setlocal instructions.
  Note that they are used for method local block parameters (def m(&b)),
  not for block local method parameters (iter{|&b|).

* proc.c (get_local_variable_ptr): creates Proc object for
  Binding#local_variable_get/set.

* safe.c (safe_setter): we need to create Proc objects for postponed
  block parameters when $SAFE is changed.

* vm_args.c (args_setup_block_parameter): used only for block local blcok
  parameters.

* vm_args.c (vm_caller_setup_arg_block): if called with
  VM_CALL_ARGS_BLOCKARG_BLOCKPARAM flag then passed block values should be
  a block handler.

* test/ruby/test_optimization.rb: add tests.

* benchmark/bm_vm1_blockparam*: added.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60397 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-10-24 11:13:49 +00:00
nobu 5d988300b2 intern instruction
* insns.def (intern): new instruction to turn string into symbol.
  opt_call_c_function can not dump.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59951 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-09-18 05:16:37 +00:00
nobu b2da3824c5 refinements in string interpolation
* compile.c (iseq_compile_each0): insert to_s method call, so that
  refinements activated at the caller should take place.
  [Feature #13812]

* insns.def (tostring): fix up converted object to a string,
  infect and fallback.

* insns.def (branchiftype): new instruction for conversion.
  branches if TOS is an instance of the given type.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59950 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-09-18 02:27:13 +00:00
mame d1b290d5ba Add a new instruction `trace2` for hooking with custom data
This is needed for passing to the hook function the measuring target
type (line/branch/method) and the site of coverage event fired.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59871 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-09-14 01:55:30 +00:00
shyouhei 0eb7359cc7 add rb_hash_new_with_size()
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
2017-09-05 04:48:19 +00:00
yui-knk a70804da54 Remove not exist arguments from comments of insns
is_local argument was introduced on r11639 and removed on r11813.

* insns.def (getinstancevariable, setinstancevariable): Remove a not
  exist argument.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59600 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-08-15 13:12:39 +00:00
ko1 8dd9c12c58 move fields to ec.
* vm_core.h (rb_thread.h): move errinfo and trace_arg to
  rb_execution_context_t.

* cont.c (fiber_switch, rb_cont_call): do not restore "trace_arg" here.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59199 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-06-28 14:27:49 +00:00
nobu 02fa3456ce vm_insnhelper.c: vm_stack_consistency_error
* vm_insnhelper.c (vm_stack_consistency_error): extracted from
  insns.def for further info in the future.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59149 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-06-23 01:43:39 +00:00
ko1 cc50ed4a50 add debug counters for local variable (lavr) access.
* debug_counter.h: add the following counters:
  * lvar_get: counter for lvar get.
  * lvar_get_dynamic: counter for lvar get from upper frames.
  * lvar_set: coutner for lvar set.
  * lvar_set_dynamic: coutner for lvar set from upper frames.
  * lvar_set_slowpath: counter for lavr set using slowpath.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58977 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-31 06:46:57 +00:00
k0kubun a270c90e89 insns.def: [DOC] Fix description of tostring
rb_obj_as_string() calls not #to_str (idTo_str) but #to_s (idTo_s).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58887 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-25 11:41:45 +00:00
hsbt 15196f4c6d Translate missing rdoc comment for opt_send_without_block.
fix [GH-1608], Patch by @k0kubun

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58610 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-05-08 13:14:24 +00:00
shyouhei 29ca20de2d refactor newhash (revision 58463 another try) [fix GH-1600]
* st.c (rb_hash_bulk_insert): new API to bulk insert entries
	  into a hash. Given arguments are first inserted into the
	  table at once, then reindexed. This is faster than inserting
	  things using rb_hash_aset() one by one.

	  This arrangement (rb_ prefixed function placed in st.c) is
	  unavoidable because it both touches table internal and write
	  barrier at once.

	* internal.h: delcare the new function.

	* hash.c (rb_hash_s_create): use the new function.

	* vm.c (core_hash_merge): ditto.

	* insns.def (newhash): ditto.

	* test/ruby/test_hash.rb: more coverage on hash creation.

	* test/ruby/test_literal.rb: ditto.

-----------------------------------------------------------
benchmark results:
minimum results in each 7 measurements.
Execution time (sec)
name    before  after
loop_whileloop2  0.136  0.137
vm2_bighash*     1.249  0.623

Speedup ratio: compare with the result of `before' (greater is better)
name    after
loop_whileloop2 0.996
vm2_bighash*    2.004



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58492 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-27 04:21:04 +00:00
shyouhei a15fd1d9f2 revert newhash refactoring
We need to fix GC bug before merging this.  Revert revisions
58452, 58435, 58434, 58428, 58427 in this order.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58463 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-24 01:40:51 +00:00
shyouhei 4ee09d914d refactor hash literal
Same as rb_ary_tmp_new_from_values(), it reduces vm_exec_core binary
size from 26,176 bytes to 26,080 bytes.  But this time, also with a
bit of optimizations:

  - Because we are allocating a new hash and no back references are
    introduced at all, we can safely skip write barriers.

  - Also, the iteration never recurs.  We can avoid complicated
    function callbacks by using st_insert instead of st_update.

----

	* hash.c (rb_hash_new_from_values): refactor
          extract the bulk insert into a function.

	* hash.c (rb_hash_new_from_object): also refactor.

	* hash.c (rb_hash_s_create): use the new functions.

	* insns.def (newhash): ditto.

	* vm.c (core_hash_from_ary): ditto.

	* iternal.h: export the new function.

-----------------------------------------------------------
benchmark results:
minimum results in each 7 measurements.
Execution time (sec)
name    before  after
loop_whileloop2  0.135  0.134
vm2_bighash*     1.236  0.687

Speedup ratio: compare with the result of `before' (greater is better)
name    after
loop_whileloop2 1.008
vm2_bighash*    1.798


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58427 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-21 04:21:14 +00:00
shyouhei 5069122ab6 refactor torexp to use routine in array.c
Found a part where copy&paste can be eliminated.  Reduces vm_exec_core
from 26,228 bytes to 26,176 bytes in size on my machine. I believe it
does not affect any runtime performance.

----

	* array.c (rb_ary_tmp_new_from_values): extend existing
          rb_ary_new_from_values function so that it can take
          additional value for klass.
	* array.c (rb_ary_new_from_values): use the new function.
	* insns.def (toregexp): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58416 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-20 10:32:08 +00:00
shyouhei 93b1b04a20 typo fix (sorry!) [ci skip]
Surprisingly this was not a syntax error on my machine.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58396 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-18 13:05:38 +00:00
ko1 37d2f9724c fix compile error.
* insns.def (trace): use cast `flag` to pass compilation with clang on MacOSX.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58394 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-18 12:30:59 +00:00
shyouhei 4a8c235fed tabify (sorry!) [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58392 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-18 11:06:58 +00:00
shyouhei 4d21d1f04b split insns.def into functions
Contemporary C compilers are good at function inlining.  They fold
multiple functions into one.  However they are not yet smart enough to
unfold a function into several ones.  So generally speaking, it is
wiser for a C programmer to manually split C functions whenever
possible.  That should make rooms for compilers to optimize at will.

Before this changeset insns.def was converted into single HUGE
function called vm_exec_core().  By moving each instruction's core
into individual functions, generated C source code is reduced from
3,428 lines to 2,847 lines.  Looking at the generated assembly
however, it seems my compiler (gcc 6.2) is extraordinary smart so that
it inlines almost all functions I introduced in this changeset back
into that vm_exec_core.  On my machine compiled machine binary of the
function does not shrink very much in size (28,432 bytes to 26,816
bytes, according to nm(1)).

I believe this change is zero-cost.  Several benchmarks I exercised
showed no significant difference beyond error mergin.  For instance
3 repeated runs of optcarrot benchmark on my machine resulted in:

   before this: 28.330329285707490, 27.513378371065920, 29.40420215754537
   after  this: 27.107195867280414, 25.549324021385907, 30.31581919050884

in fps (greater==faster).

----

	* internal.h (rb_obj_not_equal): used from vm_insnhelper.c
	* insns.def: move vast majority of lines into vm_insnhelper.c
	* vm_insnhelper.c: moved here.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58390 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-04-18 10:58:49 +00:00
normal 669a55dfed fix redefinition optimization for -"literal string" (UMinus)
Unfortunately this enlarges insns.def by yet another
instruction.  However, it is much prettier than opt_str_freeze
in use, and maybe we can avoid having so many instructions in
the future.

[ruby-core:80368]

* insns.def (DEFINE_INSN): new instruction: opt_str_uminus (maybe temporary)
* compile.c (iseq_compile_each0): split instructions
* test/ruby/test_optimization.rb (test_string_uminus): new test
* vm.c (vm_init_redefined_flag): set redefinintion flag for uminus
* vm_core.h (enum ruby_basic_operators): add BOP_UMINUS

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58144 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-03-27 06:12:37 +00:00
shyouhei c56edb9a59 revert RB_FIXABLE related changesets [Bug #13288][Bug #13293][Bug #13294]
This commit is auto-generated using following command:

svn diff -r57807:57788 include internal.h bignum.c numeric.c compile.c insns.def object.c sprintf.c | patch -p0


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57818 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-03-09 02:31:23 +00:00
shyouhei 74cdd893eb optimize FIXABLE macro
Looking at the source code, FIXABLE tends to be just before LOING2FIX
to check applicability of that operation.  Why not try computing first
then check for overflow, which should be optimial.

I also tried the same thing for unsigned types but resulted in slower
execution.  It seems RB_POSFIXABLE() is fast enough on modern CPUs.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57789 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-03-06 11:14:05 +00:00
naruse 038ccbd112 Use carry flag to reduce instructions
NOTE:
(1) Fixnum's LSB is always 1.
    It means you can always run `x - 1` without overflow.
(2) Of course `z = x + (y-1)` may overflow.
    Now z's LSB is always 1, and the MSB of true result is also 1.
    You can get true result in long as `(1<<63)|(z>>1)`,
    and it equals to `(z<<63)|(z>>1)` == `ror(z)`.

GCC and Clang have __builtin_add_ovewflow:
* https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
* https://clang.llvm.org/docs/LanguageExtensions.html#checked-arithmetic-builtins

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57506 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-02-02 15:54:51 +00:00
nobu 5dc87d5ba3 insns.def: float comparison
* insns.def (opt_lt, opt_le, opt_gt, opt_ge): optimize flonum and
  on-heap float comparison.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57319 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-01-13 05:49:43 +00:00
nobu d59dfcdb04 adjust indent [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57279 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-01-07 11:54:10 +00:00
eregon ac9f8145f1 fix optimization for hash aset/aref with fstring
Patch by Eric Wong [ruby-core:78797].
I don't like the idea of making insns.def any bigger to support
a corner case, and "test_hash_aref_fstring_identity" shows
how contrived this is.

[ruby-core:78783] [Bug #12855]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@57278 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2017-01-07 11:31:53 +00:00
nobu bd2fd73196 insns.def: adjust index type
* insns.def (checkmatch): adjust type of the index variable, to
  get rid of (potential) overflow.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56911 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-11-28 03:48:34 +00:00
ktsj 9cbd6ee097 * vm_trace.c (tracepoint_attr_callee_id, rb_tracearg_callee_id):
add TracePoint#callee_id. [ruby-core:77241] [Feature #12747]

* cont.c, eval.c, gc.c, include/ruby/intern.h, insns.def, thread.c,
  vm.c, vm_backtrace.c, vm_core.h, vm_eval.c, vm_insnhelper.c, vm_trace.c: ditto.

* test/ruby/test_settracefunc.rb: tests for above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56593 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-11-05 13:15:27 +00:00
nobu f28caf31d1 insns.def: opt_case_dispatch trivial optimization
* insns.def (opt_case_dispatch): extract float value only if the
  Float method is not redefnined.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56511 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-10-28 07:05:05 +00:00
shugo bbd662c8bd * insns.def (setclassvariable, setconstant): warn when self is a
refinement.  [Bug #10103] [ruby-core:64143]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@56101 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-09-08 04:44:51 +00:00
ko1 9f60791a04 * vm_core.h: revisit the structure of frame, block and env.
[Bug #12628]

  This patch introduce many changes.

  * Introduce concept of "Block Handler (BH)" to represent
    passed blocks.

  * move rb_control_frame_t::flag to ep[0] (as a special local
    variable). This flags represents not only frame type, but also
    env flags such as escaped.

  * rename `rb_block_t` to `struct rb_block`.

  * Make Proc, Binding and RubyVM::Env objects wb-protected.

  Check [Bug #12628] for more details.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55766 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-28 11:02:30 +00:00
ko1 be5564a178 * vm_insnhelper.c: introduce rb_vm_pop_frame() and use it
instead of setting rb_thread_t::cfp directly.

* vm_insnhelper.c (vm_pop_frame): return the result of
  finish frame or not.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55755 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-26 10:28:21 +00:00
shyouhei 0af375124c * insns.def: tabify [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55699 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-07-17 08:40:53 +00:00
naruse 8fe1d91f62 * insns.def (opt_succ): optimize like r55515. (but this argument is
consntant)

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55536 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-06-29 06:23:38 +00:00
naruse 1e791f438b * insns.def (opt_plus): use `- 1` instead of `& (~1)` to allow
compilers to use x86 LEA instruction (3 operand).
  Even if 3 operand LEA's latency is 3 cycle after SandyBridge,
  it reduces code size and can be faster because of super scalar.

* insns.def (opt_plus): calculate and use rb_int2big.
  On positive Fixnum overflow, `recv - 1 + obj` doesn't carry
  because recv's msb and obj's msb are 0, and resulted msb is 1.
  Therefore simply rshift and cast as signed long works fine.
  On negative Fixnum overflow, it will carry because both arguments'
  msb are 1, and resulted msb is also 1.
  In this case it needs to restore carried sign bit after rshift.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55515 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-06-27 18:30:12 +00:00
akr f9727c12cc [Feature #12005] Unify Fixnum and Bignum into Integer
* [Feature #12005] Unify Fixnum and Bignum into Integer

* include/ruby/ruby.h (rb_class_of): Return rb_cInteger for fixnums.

* insns.def (INTEGER_REDEFINED_OP_FLAG): Unified from
  FIXNUM_REDEFINED_OP_FLAG and BIGNUM_REDEFINED_OP_FLAG.

* vm_core.h: Ditto.

* vm_insnhelper.c (opt_eq_func): Use INTEGER_REDEFINED_OP_FLAG instead
  of FIXNUM_REDEFINED_OP_FLAG.

* vm.c (vm_redefinition_check_flag): Use rb_cInteger instead of
  rb_cFixnum and rb_cBignum.
  (C): Use Integer instead of Fixnum and Bignum.

* numeric.c (fix_succ): Removed.
  (Init_Numeric): Define Fixnum as Integer.

* bignum.c (bignew): Use rb_cInteger instead of Rb_cBignum.
  (rb_int_coerce): replaced from rb_big_coerce and return fixnums
  as-is.
  (Init_Bignum): Define Bignum as Integer.
  Don't define ===.

* error.c (builtin_class_name): Return "Integer" for fixnums.

* sprintf.c (ruby__sfvextra): Use rb_cInteger instead of rb_cFixnum.

* ext/-test-/testutil: New directory to test.
  Currently it provides utilities for fixnum and bignum.

* ext/json/generator/generator.c: Define mInteger_to_json.

* lib/mathn.rb (Fixnum#/): Redefinition removed.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55024 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-17 06:53:48 +00:00
eregon 06dd20f7fe * insns.def (defineclass): Also raise an error when redeclaring the
superclass of a class as Object and it has another superclass.
  [Bug #12367] [ruby-core:75446]
* test/ruby/test_class.rb: test for above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54970 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-10 12:46:43 +00:00
naruse 28f5e12c24 * configure.in: check function attirbute const and pure,
and define CONSTFUNC and PUREFUNC if available.
  Note that I don't add those options as default because
  it still shows many false-positive (it seems not to consider
  longjmp).

* vm_eval.c (stack_check): get rb_thread_t* as an argument
  to avoid duplicate call of GET_THREAD().

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54952 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-05-08 17:44:51 +00:00
nobu a491508753 string.c: rb_str_concat_literals
* string.c (rb_str_concat_literals): concatenate literal string
  fragments.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54490 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-04-05 08:15:22 +00:00
naruse 51c4ffa45b * internal.h (rb_fix_divmod_fix): like r54213, use FIX2NUM only if
x == FIXNUM_MIN && y == -1. This must be a rare case and it is
  expected compiler to handle well.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54216 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-21 13:36:03 +00:00
naruse 148f1b9d57 * internal.h (DLONG): defined if long is 32bit (and LONG_LONG is 64bit;
but LONG_LONG is always defined as 64bit), or there's int128_t.

* internal.h (DL2NUM): defined if DLONG is defined.

* internal.h (rb_fix_mul_fix): defined for `Fixnum * Fixnum`.

* insns.def (opt_mul): use rb_fix_mul_fix().

* numeric.c (fix_mul): ditto.

* time.c (mul): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54203 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-20 11:10:43 +00:00
mame 3c7c983300 * compile.c (NODE_CALL): add optimization shortcut for Array#max/min.
Now `[x, y].max` is optimized so that a temporal array object is not
  created in some condition.

* insns.def (opt_newarray_max, opt_newarray_min): added.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54153 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-17 12:47:31 +00:00
naruse 1b49df0b3d * intern.h (rb_divmod): assume compilers `/` and `%` comply C99
and reduce branching. If a compiler doesn't comply, add #ifdefs.

* intern.h (rb_div): added for Ruby's behavior.

* intern.h (rb_mod): added for Ruby's behavior.

* insns.def (opt_div): use rb_div.

* insns.def (opt_mod): use rb_mod.

* numeric.c (fixdivmod): removed.

* numeric.c (fix_divide): use rb_div.

* numeric.c (fix_mod): use rb_mod.

* numeric.c (fix_divmod): use rb_divmod.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54029 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-08 09:15:18 +00:00
naruse 87adc59b21 * insns.def (opt_mod): show its method name on ZeroDivisionError.
[Bug #12158]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@54028 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-03-08 08:54:38 +00:00
naruse 2708fb6ba7 * insns.def (opt_plus): simply use LONG2NUM() instead of wrongly
complex overflow case.

* insns.def (opt_sub): ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53839 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-02-15 19:42:59 +00:00
naruse 016e6db57e improve r53741
* Remove branching by a==0 case

Before r53741:
% perf stat ./miniruby -e'a=100;i=0;while i<0xfffffff;i+=1;a=(a*557+2)%100000;end'

 Performance counter stats for './miniruby -vea=100;i=0;while
i<0xfffffff;i+=1;a=(a*557+2)%100000;end':

      16412.994492 task-clock (msec)         #    0.999 CPUs utilized
               195 context-switches          #    0.012 K/sec
                 2 cpu-migrations            #    0.000 K/sec
               876 page-faults               #    0.053 K/sec
       48488588328 cycles                    #    2.954 GHz
       18464835712 stalled-cycles-frontend   #   38.08% frontend cycles
idle
   <not supported> stalled-cycles-backend
       85665428518 instructions              #    1.77  insns per cycle
                                             #    0.22  stalled cycles
                                             #    per insn
       10207419707 branches                  #  621.911 M/sec
           6334713 branch-misses             #    0.06% of all branches

      16.426858699 seconds time elapsed

After this:
% perf stat ./miniruby -ve'a=100;i=0;while i<0xfffffff;i+=1;a=(a*557+2)%100000;end'

 Performance counter stats for './miniruby -vea=100;i=0;while i<0xfffffff;i+=1;a=(a*557+2)%100000;end':

      13363.540634 task-clock (msec)         #    0.999 CPUs utilized
               137 context-switches          #    0.010 K/sec
                 2 cpu-migrations            #    0.000 K/sec
               874 page-faults               #    0.065 K/sec
       39477429278 cycles                    #    2.954 GHz
       14615402375 stalled-cycles-frontend   #   37.02% frontend cycles idle
   <not supported> stalled-cycles-backend
       83514678452 instructions              #    2.12  insns per cycle
                                             #    0.18  stalled cycles per insn
        9401528135 branches                  #  703.521 M/sec
            432567 branch-misses             #    0.00% of all branches

      13.371484310 seconds time elapsed

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53744 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-02-05 06:52:41 +00:00
naruse 1f57a334da * insns.def (opt_mult): Use int128_t for overflow detection.
* bignum.c (rb_uint128t2big): added for opt_mult.

* bignum.c (rb_uint128t2big): added for rb_uint128t2big..

* configure.in: define int128_t, uint128_t and related MACROs.
  Initially introduced by r41379 but reverted by r50749.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53741 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-02-05 04:31:27 +00:00
nobu 645d23955f insns.def: description [ci skip]
* insns.def: [DOC] add missing English description.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53490 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-01-10 02:07:00 +00:00
yui-knk c48abea0c3 Move a comment to the appropriate position.
The position of `/* fall through */` was moved by r52931.

* insns.def (opt_case_dispatch): Move a comment to the
  appropriate position.
  [ci skip]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53423 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2016-01-03 23:14:43 +00:00
normal d65bc80d3f insns.def (opt_case_dispatch): avoid converting Infinity
Infinity cannot be written as an optimizable literal,
so it can never match a key in a CDHASH.
Avoid converting it to prevent FloatDomainError.

* insns.def (opt_case_dispatch): avoid converting Infinity
* test/ruby/test_optimization.rb (test_opt_case_dispatch_inf): new
  [ruby-dev:49423] [Bug #11804]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@53039 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-12-11 09:15:14 +00:00
ko1 3dbb390180 * introduce new ISeq binary format serializer/de-serializer
and a pre-compilation/runtime loader sample.
  [Feature #11788]

* iseq.c: add new methods:
  * RubyVM::InstructionSequence#to_binary_format(extra_data = nil)
  * RubyVM::InstructionSequence.from_binary_format(binary)
  * RubyVM::InstructionSequence.from_binary_format_extra_data(binary)

* compile.c: implement body of this new feature.

* load.c (rb_load_internal0), iseq.c (rb_iseq_load_iseq):
  call RubyVM::InstructionSequence.load_iseq(fname) with
  loading script name if this method is defined.

  We can return any ISeq object as a result value.
  Otherwise loading will be continue as usual.

  This interface is not matured and is not extensible.
  So that we don't guarantee the future compatibility of this method.
  Basically, you should'nt use this method.

* iseq.h: move ISEQ_MAJOR/MINOR_VERSION (and some definitions)
  from iseq.c.

* encoding.c (rb_data_is_encoding), internal.h: added.

* vm_core.h: add several supports for lazy load.
  * add USE_LAZY_LOAD macro to specify enable or disable of
    this feature.
  * add several fields to rb_iseq_t.
  * introduce new macro rb_iseq_check().

* insns.def: some check for lazy loading feature.

* vm_insnhelper.c: ditto.

* proc.c: ditto.

* vm.c: ditto.

* test/lib/iseq_loader_checker.rb: enabled iff suitable
  environment variables are provided.

* test/runner.rb: enable lib/iseq_loader_checker.rb.

* sample/iseq_loader.rb: add sample compiler and loader.

    $ ruby sample/iseq_loader.rb [dir]

  will compile all ruby scripts in [dir].
  With default setting, this compile creates *.rb.yarb files
  in same directory of target .rb scripts.

    $ ruby -r sample/iseq_loader.rb [app]

  will run with enable to load compiled binary data.




git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52949 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-12-08 13:58:50 +00:00
normal 4ebab10bf5 compile optimized case dispatch for nil/true/false
nil/true/false are special literals just like floats, integers,
literal strings, and symbols.  Optimize when statements with
them by using a jump table, too.

target 0: a (ruby 2.3.0dev (2015-12-08 trunk 52928) [x86_64-linux]) at "/home/ew/rrrr/b/ruby"
target 1: b (ruby 2.3.0dev (2015-12-08 master 52928) [x86_64-linux]) at "/home/ew/ruby/b/ruby"

benchmark results:
minimum results in each 5 measurements.
Execution time (sec)
name	a	b
loop_whileloop2	0.102	0.103
vm2_case_lit*	1.657	0.549

Speedup ratio: compare with the result of `a' (greater is better)
name	b
loop_whileloop2	0.988
vm2_case_lit*	3.017

* benchmark/bm_vm2_case_lit.rb: new benchmark
* compile.c (case_when_optimizable_literal): add nil/true/false
* insns.def (opt_case_dispatch): ditto
* vm.c (vm_redefinition_check_flag): ditto
* vm.c (vm_init_redefined_flag): ditto
* vm_core.h: ditto
* object.c (InitVM_Object): define === explicitly for nil/true/false
* test/ruby/test_case.rb (test_deoptimize_nil): new test
* test/ruby/test_optimization.rb (test_opt_case_dispatch): update
  (test_eqq): new test
  [ruby-core:71923] [Feature #11769]
  Original patch by Aaron Patterson <tenderlove@ruby-lang.org>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52931 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-12-08 01:46:45 +00:00
normal 4d2ce0cbff insns.def (opt_case_dispatch): check Float#=== redefinition
The missing check for Float#=== redefinition was noticed while
working on enhancing optimized case dispatch for nil/true/false
in [ruby-core:71818] https://bugs.ruby-lang.org/issues/11769

So no, I don't normally redefine core classes like this :P

* insns.def (opt_case_dispatch): check Float#=== redefinition
* test/ruby/test_optimization.rb (test_opt_case_dispatch): new
  [ruby-core:71920] [Bug #11784]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52928 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-12-07 23:56:57 +00:00
ko1 ba772af0a6 * compile.c (iseq_compile_each): add debug information to NODE_STR
strings as default.
  [Feature #11725]

* insns.def (freezestring): add new instruction to support adding
  debug information for dynamically constracted strings.

* compile.c (iseq_compile_each): support adding debug information
  for NODE_DSTR with freezestring instruction.

* error.c (rb_error_frozen): change the debug information ID name
  id_debug_created_info and this field should have a 2 element array
  containing path and line information.

* defs/id.def: ditto.

* test/ruby/test_rubyoptions.rb: catch up this fix.

* test/ruby/test_iseq.rb: now frozen strings are not same.




git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52688 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-20 23:49:31 +00:00
ko1 32a9647264 * refactoring CREF related code.
* eval_intern.h: remove unused setter functions.
  CREF_CLASS_SET()
  CREF_NEXT_SET()
  CREF_SCOPE_VISI_COPY()

* eval_intern.h: rename flags:
  * NODE_FL_CREF_PUSHED_BY_EVAL_ -> CREF_FL_PUSHED_BY_EVAL
  * NODE_FL_CREF_OMOD_SHARED_ -> CREF_FL_OMOD_SHARED
  and use IMEMO_FL_USER1/2.

* vm.c (vm_cref_new): accept push_by_eval parameter.

* vm.c (vm_cref_new_use_prev): added for rb_vm_rewrite_cref().

* vm_insnhelper.c (vm_cref_push): accept pushed_by_eval parameter.

* vm_insnhelper.h: remove unused macros:
  COPY_CREF_OMOD() and COPY_CREF().

* vm_eval.c, insns.def: catch up this fix.




git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52564 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-11-13 20:02:19 +00:00
ko1 f363bbdf10 * insns.def (getinlinecache/setinlinecache): compare ic->ic_cref and
current cref only when cached CREF list includes singleton class.

  Singleton classes have own namespaces, so that we need to check
  cref as a key (#10943).

  However, if current CREF list does not include singleton class,
  no need to check CREF beacuse it should be same name space.

* vm_insnhelper.c (vm_get_const_key_cref): add a function returns
  CREF only when it includes singleton class.

* vm_core.h: constify iseq_inline_cache_entry::ic_cref.




git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52371 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-10-29 22:43:45 +00:00
ko1 648aa500d6 * insns.def: nobody set ic->ic_value.value to Qundef.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52368 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-10-29 21:21:13 +00:00
nobu 645116ff25 RUBY_DTRACE_CREATE_HOOK
* internal.h (RUBY_DTRACE_CREATE_HOOK): macro to call hook at
  object creation.

* vm.c (rb_source_location, rb_source_loc): retrieve source path
  and line number at once.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52340 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-10-29 05:32:57 +00:00
nobu a356fe1c35 Safe navigation operator
* compile.c (iseq_peephole_optimize): peephole optimization for
  branchnil jumps.
* compile.c (iseq_compile_each): generate save navigation operator
  code.
* insns.def (branchnil): new opcode to pop the tos and branch if
  it is nil.
* parse.y (NEW_QCALL, call_op, parser_yylex): parse token '.?'.
  [Feature #11537]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52214 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-10-22 06:30:12 +00:00
nobu a7f64368ae revert r51991
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51993 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-10-01 10:50:49 +00:00
nobu 32289fbed4 vm_args.c: GC guard
* vm_args.c (vm_caller_setup_arg_block): prevent newly created
  ifunc object from GC.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51991 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-10-01 02:57:43 +00:00
nobu ed8b452e37 compile.c: fix performance of strconcat
* compile.c (compile_dstr_fragments): fix performance by omitting
  the first empty string only for keeping literal encoding if
  other literals are too.  [ruby-core:70930] [Bug #11556]
* string.c (rb_str_append_literal): append but keep encoding non
  US-ASCII.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51970 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-09-29 07:37:40 +00:00
ko1 d5ec9ec308 * vm_core.h: split rb_call_info_t into several structs.
* rb_call_info (ci) has compiled fixed information.
  * if ci->flag & VM_CALL_KWARG, then rb_call_info is
    also rb_call_info_with_kwarg. This technique reduce one word
    for major rb_call_info data.
  * rb_calling_info has temporary data (argc, blockptr, recv).
    for each method dispatch. This data is allocated only on
    machine stack.
  * rb_call_cache is for inline method cache.
  Before this patch, only rb_call_info_t data is passed.
  After this patch, above three structs are passed.
  This patch improves:
  * data locarity (rb_call_info is now read-only data).
  * reduce memory consumption (rb_call_info_with_kwarg,
    rb_calling_info).
* compile.c: use above data.
* insns.def: ditto.
* iseq.c: ditto.
* vm_args.c: ditto.
* vm_eval.c: ditto.
* vm_insnhelper.c: ditto.
* vm_insnhelper.h: ditto.
* iseq.h: add iseq_compile_data::ci_index and
  iseq_compile_data::ci_kw_indx.
* tool/instruction.rb: introduce TS_CALLCACHE operand type.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51903 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-09-19 17:59:58 +00:00
ko1 eec17b718a * vm_core.h: remove rb_call_info_t::blockiseq.
* insns.def (send, invokesuper): pass blockiseq explicitly.
* compile.c: catch up this fix.
* iseq.c: ditto.
* vm_args.c: ditto.
* iseq.c (ISEQ_MINOR_VERSION): 2->3 because instruction spec was
  changed.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51794 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-09-08 08:21:07 +00:00
nobu db45ec9845 insns.def: redundant call
* insns.def (leave): remove redundant function call.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51490 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-08-05 05:43:58 +00:00
ko1 e4198a73d4 * make rb_iseq_t T_IMEMO object (type is imemo_iseq).
All contents of previous rb_iseq_t is in rb_iseq_t::body.
  Remove rb_iseq_t::self because rb_iseq_t is an object.
  RubyVM::InstructionSequence is wrapper object points T_IMEMO/iseq.
  So RubyVM::ISeq.of(something) method returns different wrapper
  objects but they point the same T_IMEMO/iseq object.
  This patch is big, but most of difference is replacement of
  iseq->xxx to iseq->body->xxx.
  (previous) rb_iseq_t::compile_data is also located to
  rb_iseq_t::compile_data.
  It was moved from rb_iseq_body::compile_data.
  Now rb_iseq_t has empty two pointers.
  I will split rb_iseq_body data into static data and dynamic data.
* compile.c: rename some functions/macros.
  Now, we don't need to separate iseq and iseqval (only VALUE).
* eval.c (ruby_exec_internal): `n' is rb_iseq_t (T_IMEMO/iseq).
* ext/objspace/objspace.c (count_imemo_objects): count T_IMEMO/iseq.
* gc.c: check T_IMEMO/iseq.
* internal.h: add imemo_type::imemo_iseq.
* iseq.c: define RubyVM::InstructionSequnce as T_OBJECT.
  Methods are implemented by functions named iseqw_....
* load.c (rb_load_internal0): rb_iseq_new_top() returns
  rb_iseq_t (T_IMEMO/iesq).
* method.h (rb_add_method_iseq): accept rb_iseq_t (T_IMEMO/iseq).
* vm_core.h (GetISeqPtr): removed because it is not T_DATA now.
* vm_core.h (struct rb_iseq_body): remove padding for
  [Bug #10037][ruby-core:63721].



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51327 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-21 22:52:59 +00:00
ko1 5e8a147480 * method.h: introduce rb_callable_method_entry_t to remove
rb_control_frame_t::klass.
  [Bug #11278], [Bug #11279]
  rb_method_entry_t data belong to modules/classes.
  rb_method_entry_t::owner points defined module or class.
    module M
      def foo; end
    end
  In this case, owner is M.
  rb_callable_method_entry_t data belong to only classes.
  For modules, MRI creates corresponding T_ICLASS internally.
  rb_callable_method_entry_t can also belong to T_ICLASS.
  rb_callable_method_entry_t::defined_class points T_CLASS or
  T_ICLASS.
  rb_method_entry_t data for classes (not for modules) are also
  rb_callable_method_entry_t data because it is completely same data.
  In this case, rb_method_entry_t::owner == rb_method_entry_t::defined_class.
  For example, there are classes C and D, and incldues M,
    class C; include M; end
    class D; include M; end
  then, two T_ICLASS objects for C's super class and D's super class
  will be created.
  When C.new.foo is called, then M#foo is searcheed and
  rb_callable_method_t data is used by VM to invoke M#foo.
  rb_method_entry_t data is only one for M#foo.
  However, rb_callable_method_entry_t data are two (and can be more).
  It is proportional to the number of including (and prepending)
  classes (the number of T_ICLASS which point to the module).
  Now, created rb_callable_method_entry_t are collected when
  the original module M was modified. We can think it is a cache.
  We need to select what kind of method entry data is needed.
  To operate definition, then you need to use rb_method_entry_t.
  You can access them by the following functions.
  * rb_method_entry(VALUE klass, ID id);
  * rb_method_entry_with_refinements(VALUE klass, ID id);
  * rb_method_entry_without_refinements(VALUE klass, ID id);
  * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
  To invoke methods, then you need to use rb_callable_method_entry_t
  which you can get by the following APIs corresponding to the
  above listed functions.
  * rb_callable_method_entry(VALUE klass, ID id);
  * rb_callable_method_entry_with_refinements(VALUE klass, ID id);
  * rb_callable_method_entry_without_refinements(VALUE klass, ID id);
  * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
  VM pushes rb_callable_method_entry_t, so that rb_vm_frame_method_entry()
  returns rb_callable_method_entry_t.
  You can check a super class of current method by
  rb_callable_method_entry_t::defined_class.
* method.h: renamed from rb_method_entry_t::klass to
  rb_method_entry_t::owner.
* internal.h: add rb_classext_struct::callable_m_tbl to cache
  rb_callable_method_entry_t data.
  We need to consider abotu this field again because it is only
  active for T_ICLASS.
* class.c (method_entry_i): ditto.
* class.c (rb_define_attr): rb_method_entry() does not takes
  defiend_class_ptr.
* gc.c (mark_method_entry): mark RCLASS_CALLABLE_M_TBL() for T_ICLASS.
* cont.c (fiber_init): rb_control_frame_t::klass is removed.
* proc.c: fix `struct METHOD' data structure because
  rb_callable_method_t has all information.
* vm_core.h: remove several fields.
  * rb_control_frame_t::klass.
  * rb_block_t::klass.
  And catch up changes.
* eval.c: catch up changes.
* gc.c: ditto.
* insns.def: ditto.
* vm.c: ditto.
* vm_args.c: ditto.
* vm_backtrace.c: ditto.
* vm_dump.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@51126 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-07-03 11:24:50 +00:00
nobu 1a3e7ca11f insns.def: no quoting
* insns.def (defineclass): do not quote unprintable characters at
  raising an exception.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51062 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-29 08:38:04 +00:00
nobu 548b97e70c insns.def: preserve encoding
* insns.def (defineclass): preserve encoding of name in error
  messages for super class mismatch.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51055 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-28 17:10:26 +00:00
nobu b90a5f9334 insns.def: preserve encoding
* insns.def (defineclass): preserve encoding of name in error
  messages for non-class super.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51054 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-28 17:10:00 +00:00
nobu 491ace2dbe insns.def: preserve encoding
* insns.def (defineclass): preserve encoding of name in error
  messages when already defined but type mismatch.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@51053 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-28 17:06:59 +00:00
ko1 18bbd05709 * method.h: split rb_method_definition_t::flag to several flags.
`flag' contains several categories of attributes and it makes us
  confusion (at least, I had confused).
  * rb_method_visibility_t (flags::visi)
    * NOEX_UNDEF     -> METHOD_VISI_UNDEF     = 0
    * NOEX_PUBLIC    -> METHOD_VISI_PUBLIC    = 1
    * NOEX_PRIVATE   -> METHOD_VISI_PRIVATE   = 2
    * NOEX_PROTECTED -> METHOD_VISI_PROTECTED = 3
  * NOEX_SAFE(flag)) -> safe (flags::safe, 2 bits)
  * NOEX_BASIC       -> basic (flags::basic, 1 bit)
  * NOEX_MODFUNC     -> rb_scope_visibility_t in CREF
  * NOEX_SUPER       -> MISSING_SUPER (enum missing_reason)
  * NOEX_VCALL       -> MISSING_VCALL (enum missing_reason)
  * NOEX_RESPONDS    -> BOUND_RESPONDS (macro)
  Now, NOEX_NOREDEF is not supported (I'm not sure it is needed).
  Background:
    I did not know what "NOEX" stands for.
    I asked Matz (who made this name) and his answer was "Nothing".
    "At first, it meant NO EXport (private), but the original
    meaning was gone."
    This is why I remove the mysterious word "NOEX" from MRI.
* vm_core.h: introduce `enum missing_reason' to represent
  method_missing (NoMethodError) reason.
* eval_intern.h: introduce rb_scope_visibility_t to represent
  scope visibility.
  It has 3 method visibilities (public/private/protected)
  and `module_function`.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50743 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-03 01:39:16 +00:00
ko1 15164bf33c * insns.def (defined), vm_insnhelper.c (vm_defined):
move instruction body to the vm_defined() function.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50736 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-02 19:15:29 +00:00
ko1 57b817f4c5 * method.h: make rb_method_entry_t a VALUE.
Motivation and new data structure are described in [Bug #11203].
  This patch also solve the following issues.
  * [Bug #11200] Memory leak of method entries
  * [Bug #11046] __callee__ returns incorrect method name in orphan
                 proc
* test/ruby/test_method.rb: add a test for [Bug #11046].
* vm_core.h: remvoe rb_control_frame_t::me. me is located at value
  stack.
* vm_core.h, gc.c, vm_method.c: remove unlinked_method... codes
  because method entries are simple VALUEs.
* method.h:  Now, all method entries has own independent method
  definititons. Strictly speaking, this change is not essential,
  but for future changes.
  * rb_method_entry_t::flag is move to rb_method_definition_t::flag.
  * rb_method_definition_t::alias_count is now
    rb_method_definition_t::alias_count_ptr, a pointer to the counter.
* vm_core.h, vm_insnhelper.c (rb_vm_frame_method_entry) added to
  search the current method entry from value stack.
* vm_insnhelper.c (VM_CHECK_MODE): introduced to enable/disable
  assertions.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50728 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-06-02 04:20:30 +00:00
ko1 8dced4d2c0 * internal.h: define rb_cref_t and change to use it.
rb_cref_t is data type of CREF. Now, the body is still NODE.
  It is easy to understand what is CREF and what is pure NODE.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49897 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-08 21:22:43 +00:00
ko1 d84f9b1694 * fix namespace issue on singleton class expressions. [Bug #10943]
* vm_core.h, method.h: remove rb_iseq_t::cref_stack. CREF is stored
  to rb_method_definition_t::body.iseq_body.cref.
* vm_insnhelper.c: modify SVAR usage.
  When calling ISEQ type method, push CREF information onto method
  frame, SVAR located place. Before this fix, SVAR is simply nil.
  After this patch, CREF (or NULL == Qfalse for not iseq methods)
  is stored at the method invocation.
  When SVAR is requierd, then put NODE_IF onto SVAR location,
  and NDOE_IF::nd_reserved points CREF itself.
* vm.c (vm_cref_new, vm_cref_dump, vm_cref_new_toplevel): added.
* vm_insnhelper.c (vm_push_frame): accept CREF.
* method.h, vm_method.c (rb_add_method_iseq): added. This function
  accepts iseq and CREF.
* class.c (clone_method): use rb_add_method_iseq().
* gc.c (mark_method_entry): mark method_entry::body.iseq_body.cref.
* iseq.c: remove CREF related codes.
* insns.def (getinlinecache/setinlinecache): CREF should be cache key
  because a different CREF has a different namespace.
* node.c (rb_gc_mark_node): mark NODE_IF::nd_reserved for SVAR.
* proc.c: catch up changes.
* struct.c: ditto.
* insns.def: ditto.
* vm_args.c (raise_argument_error): ditto.
* vm_eval.c: ditto.
* test/ruby/test_class.rb: add a test.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-03-06 12:24:58 +00:00
nobu 5ac58b272d insns.def: reverse
* insns.def (reverse): add new instruction for massign.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49731 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-02-25 00:20:39 +00:00
nobu ec0c0e3da2 insns.def: typo
* insns.def (adjuststack): fix a typo, "empty".

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49615 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2015-02-16 14:44:01 +00:00
normal 6c0a375c58 insns.def (opt_succ): remove Time#succ optimization
Time#succ is a deprecated method and not frequently used, so this wastes
icache in vm_exec_core.  Using bloat-o-meter in the Linux kernel source
to shows a small reduction on my x86-64 system:

$ ~/linux/scripts/bloat-o-meter ruby.before ruby.after
add/remove: 0/0 grow/shrink: 0/1 up/down: 0/-57 (-57)
function                                     old     new   delta
vm_exec_core                               24216   24159     -57

[Feature #10501]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48415 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-11-13 21:55:28 +00:00
ko1 fbebd502f9 * rewrite method/block parameter fitting logic to optimize
keyword arguments/parameters and a splat argument.
  [Feature #10440] (Details are described in this ticket)
  Most of complex part is moved to vm_args.c.
  Now, ISeq#to_a does not catch up new instruction format.
* vm_core.h: change iseq data structures.
  * introduce rb_call_info_kw_arg_t to represent keyword arguments.
  * add rb_call_info_t::kw_arg.
  * rename rb_iseq_t::arg_post_len to rb_iseq_t::arg_post_num.
  * rename rb_iseq_t::arg_keywords to arg_keyword_num.
  * rename rb_iseq_t::arg_keyword to rb_iseq_t::arg_keyword_bits.
    to represent keyword bitmap parameter index.
    This bitmap parameter shows that which keyword parameters are given
    or not given (0 for given).
    It is refered by `checkkeyword' instruction described bellow.
  * rename rb_iseq_t::arg_keyword_check to rb_iseq_t::arg_keyword_rest
    to represent keyword rest parameter index.
  * add rb_iseq_t::arg_keyword_default_values to represent default
    keyword values.
  * rename VM_CALL_ARGS_SKIP_SETUP to VM_CALL_ARGS_SIMPLE
    to represent
      (ci->flag & (SPLAT|BLOCKARG)) &&
      ci->blockiseq == NULL &&
      ci->kw_arg == NULL.
* vm_insnhelper.c, vm_args.c: rewrite with refactoring.
  * rewrite splat argument code.
  * rewrite keyword arguments/parameters code.
  * merge method and block parameter fitting code into one code base.
* vm.c, vm_eval.c: catch up these changes.
* compile.c (new_callinfo): callinfo requires kw_arg parameter.
* compile.c (compile_array_): check the last argument Hash object or
  not. If Hash object and all keys are Symbol literals, they are
  compiled to keyword arguments.
* insns.def (checkkeyword): add new instruction.
  This instruction check the availability of corresponding keyword.
  For example, a method "def foo k1: 'v1'; end" is cimpiled to the
  following instructions.
    0000 checkkeyword     2, 0  # check k1 is given.
    0003 branchif         9     # if given, jump to address #9
    0005 putstring        "v1"
    0007 setlocal_OP__WC__0 3   # k1 = 'v1'
    0009 trace            8
    0011 putnil
    0012 trace            16
    0014 leave
* insns.def (opt_send_simple): removed and add new instruction
  "opt_send_without_block".
* parse.y (new_args_tail_gen): reorder variables.
  Before this patch, a method "def foo(k1: 1, kr1:, k2: 2, **krest, &b)"
  has parameter variables "k1, kr1, k2, &b, internal_id, krest",
  but this patch reorders to "kr1, k1, k2, internal_id, krest, &b".
  (locate a block variable at last)
* parse.y (vtable_pop): added.
  This function remove latest `n' variables from vtable.
* iseq.c: catch up iseq data changes.
* proc.c: ditto.
* class.c (keyword_error): export as rb_keyword_error().
* common.mk: depend vm_args.c for vm.o.
* hash.c (rb_hash_has_key): export.
* internal.h: ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48239 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-11-02 18:02:55 +00:00
normal e1062b23b4 insns.def: add comments to def/opt_operand.def
* insns.def (getlocal,setlocal): add comment to def/opt_operand.def

I spent some time thinking about the same optimization before
realizing it was already done.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48106 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-10-23 01:50:45 +00:00
normal f0c968a778 iseq_inline_storage_entry: 24=>16 bytes on 64-bit
We may tag the running_thread pointer to avoid making the "once" struct
bigger than "struct iseq_inline_cache_entry".

This only saves a small amount with "valgrind ruby -e exit"
before:
  total heap usage: 48,122 allocs, 19,248 frees, 8,110,149 bytes allocated
after:
  total heap usage: 48,122 allocs, 19,253 frees, 8,099,197 bytes allocated

* insns.def (once): define and use fake RUNNING_THREAD_ONCE_DONE
  pointer to indicate is->once.running_thread is done.

* vm_core.h (iseq_inline_storage_entry): remove done field,
  allowing the union to be reduced from 24=>16 bytes on 64-bit

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47542 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-09-11 19:25:32 +00:00
nobu 7d9b37cc53 insns.def: avoid type-punned pointer cast
* insns.def (once), vm_insnhelper.c (vm_once_exec): turn the
  parameter into a VALUE to get rid of type-punned pointer cast.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46478 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-06-20 06:59:28 +00:00
nobu b90450d37c insns.def: fix typo
* insns.def (defineclass): fix typo in the instruction comment.
  [fix GH-618]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@46149 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-05-26 15:00:23 +00:00
normal 4101a5690e insns.def (opt_regexpmatch2): respect redefined match op
* insns.def (opt_regexpmatch2): respect redefined match op
  Thanks to Sam Rawlins for the fix.
* test/ruby/test_string.rb: test based on Tsuyoshi Sawada's report
  [Bug #9581]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@45318 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-03-11 22:28:33 +00:00
nobu 1f502d9661 insns.def: adjust style
* insns.def (opt_mod, opt_aset_with, opt_aref_with, opt_regexpmatch1):
  adjust style, do not cuddle else up.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44703 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-01-25 03:15:30 +00:00
tmm1 58f800a278 insns.def: add opt path for Hash#[] and Hash#[]= used with str literal keys
* insns.def (opt_aref_with): new instruction to optimize Hash#[],
  removing any allocation overhead when used with a string literal
  key. Patch by normalperson (Eric Wong). [ruby-core:59640] [Bug #9382]
* insns.def (opt_aset_with): new instruction to optimize Hash#[]=
* compile.c (iseq_compile_each): compiler shortcuts for new
  instructions
* hash.c (static VALUE rb_hash_compare_by_id_p): fix documentation for
  Hash#compare_by_identity to reflect frozen string sharing
* test/ruby/test_hash.rb (class TestHash): test for new behavior

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44551 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2014-01-10 04:54:08 +00:00
marcandre af4e6084d0 * insns.def: Fix optimization bug of Float#/ [Bug #9238]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44127 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-12-10 18:18:31 +00:00
charliesome 7df9798126 * compile.c, insns.def, test/ruby/test_rubyvm.rb, vm.c, vm_core.h,
vm_insnhelper.c, vm_insnhelper.h, vm_method.c: Rename method_serial
  to global_method_state and constant_serial to global_constant_state
  after discussion with ko1.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44097 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-12-09 10:51:02 +00:00
charliesome 07ac58747f * compile.c (iseq_compile_each): emit opt_str_freeze if the #freeze
method is called on a static string literal with no arguments.

* defs/id.def (firstline): add freeze so idFreeze is available

* insns.def (opt_str_freeze): add opt_str_freeze instruction which
  pushes a frozen string literal without allocating a new object if
  String#freeze is not overriden

* string.c (Init_String): define String#freeze

* vm.c (vm_init_redefined_flag): define BOP_FREEZE on String class as
  a basic operation

* vm_insnhelper.h: ditto

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43627 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-11-09 21:17:06 +00:00
charliesome 1546fb6c00 * insns.def: unify ic_constant_serial and ic_class_serial into one field
ic_serial. This is possible because these fields are only ever used
  exclusively with each other.

* insns.def: ditto
* vm_core.h: ditto
* vm_insnhelper.c: ditto

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43596 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-11-09 03:46:48 +00:00
charliesome 8b0771b014 * class.c: unify names of vm state version counters to 'serial'.
This includes renaming 'vm_state_version_t' to 'rb_serial_t',
  'method_state' to 'method_serial', 'seq' to 'class_serial',
  'vmstat' to 'constant_serial', etc.

* insns.def: ditto
* internal.h: ditto
* vm.c: ditto
* vm_core.h: ditto
* vm_insnhelper.c: ditto
* vm_insnhelper.h: ditto
* vm_method.c: ditto

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43595 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-11-09 03:34:49 +00:00
charliesome 7fafa8f376 * insns.def, vm.c, vm_insnhelper.c, vm_insnhelper.h, vm_method.c: split
ruby_vm_global_state_version into two separate counters - one for the
  global method state and one for the global constant state. This means
  changes to constants do not affect method caches, and changes to
  methods do not affect constant caches. In particular, this means
  inclusions of modules containing constants no longer globally
  invalidate the method cache.

* class.c, eval.c, include/ruby/intern.h, insns.def, vm.c, vm_method.c:
  rename rb_clear_cache_by_class to rb_clear_method_cache_by_class

* class.c, include/ruby/intern.h, variable.c, vm_method.c: add
  rb_clear_constant_cache

* compile.c, vm_core.h, vm_insnhelper.c: rename vmstat field in
  rb_call_info_struct to method_state

* vm_method.c: rename vmstat field in struct cache_entry to method_state

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-10-29 00:52:38 +00:00
sorah c4b4e77c72 * insns.def (opt_regexpmatch2): Check String#=~ hasn't overridden
before calling rb_reg_match().

* test/ruby/test_string.rb: Test for above.

* vm.c (vm_init_redefined_flag): Add BOP flag for String#=~

[ruby-core:57385] [Bug #8953]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43052 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-09-26 07:58:28 +00:00
charliesome b18151cf53 * insns.def (opt_regexpmatch1): check Regexp#=~ is not defined before
calling rb_reg_match()

* test/ruby/test_regexp.rb: add test

* vm.c (ruby_vm_redefined_flag): change type to short[]

* vm.c (vm_redefinition_check_flag): return REGEXP_REDEFINED_OP_FLAG if
  klass == rb_cRegexp

* vm.c (vm_init_redefined_flag): setup BOP flag for Regexp#=~

* vm_insnhelper.h: add REGEXP_REDEFINED_OP_FLAG

[ruby-core:57385] [Bug #8953]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43050 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-09-26 07:39:48 +00:00
charliesome 2f522b9cc6 * class.c, compile.c, eval.c, gc.h, insns.def, internal.h, method.h,
variable.c, vm.c, vm_core.c, vm_insnhelper.c, vm_insnhelper.h,
  vm_method.c: Implement class hierarchy method cache invalidation.

  [ruby-core:55053] [Feature #8426] [GH-387]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42822 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-09-04 05:25:06 +00:00
charliesome d0d63cff8a * compile.c (NODE_MATCH3): pass CALL_INFO to opt_regexpmatch2
* insns.def (opt_regexpmatch2): use CALL_SIMPLE_METHOD to call =~ if
  the receiver is not a T_STRING [Bug #8847] [ruby-core:56916]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42742 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-31 06:07:21 +00:00
nobu b3392daaad vm_insnhelper.h: RBASIC_CLASS
* vm_insnhelper.c (opt_eq_func): use RBASIC_CLASS() instead of HEAP_CLASS_OF().
* insns.def (opt_plus, opt_minus, opt_mult, opt_div, opt_mod, opt_lt),
  (opt_gt, opt_ltlt, opt_aref, opt_aset, opt_length, opt_size),
  (opt_empty_p, opt_succ): ditto.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42702 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-27 07:11:10 +00:00
nobu 922467238e insns.def: refine comments
* insns.def (getinlinecache, once, opt_case_dispatch): refine some
  English version comments.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42638 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-21 06:51:51 +00:00
ko1 30b1947df2 * insns.def: fix regexp's once option behavior.
fix [ruby-trunk - Bug #6701]
* insns.def: remove `onceinlinecache' and introduce `once' instruction.
  `once' doesn't use `setinlinecache' insn any more.
* vm_core.h: `union iseq_inline_storage_entry' to store once data.
* compile.c: catch up above changes.
* iseq.c: ditto.
* vm.c, vm_insnhelper.c: ditto. fix `m_core_set_postexe()' which
  is depend on `onceinlinecache' insn.
* test/ruby/test_regexp.rb: add tests.
* iseq.c: ISEQ_MINOR_VERSION to 1 (should increment major?)



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42637 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-20 17:41:13 +00:00
ko1 22468a4f92 * vm_insnhelper.c (vm_push_frame): fix stack overflow check codes.
Stack overflow check should be done *after* pushing a stack frame.
  However, some stack overflow checking codes checked *before*
  pushing a stack frame with iseq->stack_max.
  To solve this problem, add a new parameter `stack_max' to specify
  a possible consuming stack size.
* vm_core.h (CHECK_VM_STACK_OVERFLOW0): add to share the stack overflow
  checking code.
* insns.def: catch up this change.
* vm.c, vm_eval.c: ditto.
* test/ruby/test_exception.rb: add a stack overflow test.
  This code is reported by nobu.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42398 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-08-06 08:33:05 +00:00
ko1 c4c821a7d7 * hash.c (rb_hash_tbl_raw), internal.h: added.
Returns st_table without shading hash.
* array.c: use rb_hash_tbl_raw() for read-only purpose.
* compile.c (iseq_compile_each): ditto.
* gc.c (count_objects): ditto.
* insns.def: ditto.
* process.c: ditto.
* thread.c (clear_coverage): ditto.
* vm_insnhelper.c: ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40937 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-26 16:19:04 +00:00
ko1 aacd771046 * *.c, parse.y, insns.def: use RARRAY_AREF/ASET macro
instead of using RARRAY_PTR().



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40690 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-13 09:56:22 +00:00
nobu babae04960 insns.def: refactor by wanabe
* insns.def (defined): use vm_search_superclass() like as normal super
  call.  based on a patch <https://gist.github.com/wanabe/5520026> by
  wanabe.
* vm_insnhelper.c (vm_search_superclass): return error but not raise
  exceptions.
* vm_insnhelper.c (vm_search_super_method): check the result of
  vm_search_superclass and raise execptions on error.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40584 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-05 09:57:02 +00:00
nobu 08fbd2cee2 insns.def: method entry from method frame
* insns.def (defined): get method entry from the method top level
  frame, not block frame.  [ruby-core:54769] [Bug #8367]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40583 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-05-05 07:29:44 +00:00
charliesome 4f683e1678 * insns.def (opt_mod): Use % operator if both operands are positive for
a significant performance improvement. Thanks to @samsaffron.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40410 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-04-22 13:57:21 +00:00
tmm1 cbd8b09920 iseq: reduce array allocations for simple sequences
* compile.c (iseq_add_mark_object): Use new rb_iseq_add_mark_object().

* insns.def (setinlinecache): Ditto.

* iseq.c (rb_iseq_add_mark_object): New function to allocate
  iseq->mark_ary on demand. [Bug #8142]

* iseq.h (rb_iseq_add_mark_object): Ditto.

* iseq.c (prepare_iseq_build): Avoid allocating mark_ary until needed.

* iseq.c (rb_iseq_build_for_ruby2cext): Ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40336 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-04-17 11:20:23 +00:00
akr 712c7168bf * internal.h (MUL_OVERFLOW_SIGNED_INTEGER_P): New macro.
(MUL_OVERFLOW_FIXNUM_P): Ditto.
  (MUL_OVERFLOW_LONG_P): Ditto.

* array.c (rb_ary_product): Don't overflow on signed integer
  multiplication.

* numeric.c (fix_mul): Ditto.
  (int_pow): Ditto.

* rational.c (f_imul): Ditto.

* insns.def (opt_mult): Ditto.

* thread.c (sleep_timeval): Don't overflow on signed integer addition.

* bignum.c (rb_int2big): Don't overflow on signed integer negation.
  (rb_big2ulong): Ditto.
  (rb_big2long): Ditto.
  (rb_big2ull): Ditto.
  (rb_big2ll): Ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40208 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-04-09 11:39:53 +00:00
takano32 8f73480c3d * insns.def: fix condition.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@39733 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-03-12 08:02:17 +00:00
shugo bb54d0ae4c * insns.def (defineclass): private constants should not be accessed
by scoped module definitions.  The bug was introduced in r38495.

* test/ruby/test_module.rb: related test.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38772 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-01-11 00:58:08 +00:00
nobu a00b29a67f insns.def: adjust indent
* insns.def (getlocal, defined): adjust indent.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38740 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2013-01-08 05:57:42 +00:00
shugo ea01ffa569 * vm_core.h (rb_vm_defineclass_type_t),
compile.c (iseq_compile_each), insns.def (defineclass): change the
  meaning of the third operand of defineclass as follows:
    lower 3bits: the type of the defineclass
                   0 = class, 1 = singleton class, 2 = module
    4th bit: a flag represents whether the defineclass is scoped
               0 = not scoped (e.g., class Foo)
	       1 = scoped (e.g., class Bar::Baz)
    5th bit: a flag represents whether the superclass is specified
               0 = not specified (e.g., class Foo)
               1 = specified (e.g., class Bar < Foo)
  If the superclass is specified and is not a class, a TypeError
  should be raised.  [ruby-dev:46747] [Bug #7572]

* test/ruby/test_class.rb: related test.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38495 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-12-20 08:13:53 +00:00
nobu c9b4b78085 compile.c, vm_insnhelper.c: flip-flop without hidden string key
* compile.c (iseq_compile_each): count flip-flop state in local iseq
  not in each iseqs, so that the keys can be other than hidden
  strings.  [ruby-core:47253] [Bug #6899]
* vm_insnhelper.c (lep_svar_get, lep_svar_set, vm_getspecial): store
  flip-flop states in an array instead of a hash.
* iseq.c (set_relation): main iseq also can has local scope.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38292 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2012-12-10 06:11:16 +00:00