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

1054 Коммитов

Автор SHA1 Сообщение Дата
卜部昌平 15e977349e more on NULL versus functions
Function pointers are not void*.  See also
115fec062c
ce4ea956d2
8427fca49b
2020-05-11 16:47:25 +09:00
卜部昌平 9e41a75255 sed -i 's|ruby/impl|ruby/internal|'
To fix build failures.
2020-05-11 09:24:08 +09:00
卜部昌平 d7f4d732c1 sed -i s|ruby/3|ruby/impl|g
This shall fix compile errors.
2020-05-11 09:24:08 +09:00
Nobuyoshi Nakada cfe0e660f4
Disable -Wswitch warning when VM_CHECK_MODE 2020-05-03 00:15:56 +09:00
Takashi Kokubun 79f3403be0
Invalidate fastpath when calling attr_reader by super
The same bug as 8355a99883 existed in attr_reader too.
2020-04-14 23:49:29 -07:00
Takashi Kokubun 8355a99883
Invalidate fastpath when calling attr_writer by super
We started to use fastpath on invokesuper when a method is not refinements
since 5c27681813, but we shouldn't have used fastpath for attr_writer either.

`cc->aux_.attr_index` is for an actual receiver class, while we store
its superclass in `cc->klass` and therefore there's no way to properly
invalidate attr_writer's inline cache when it's called by super.

[Bug #16785]

I suspect the same bug also exists in attr_reader. I'll address that in
another commit.
2020-04-14 23:32:13 -07:00
Takashi Kokubun 310ef9f40b
Make vm_call_cfunc_with_frame a fastpath (#3027)
when there's no need to call CALLER_SETUP_ARG and CALLER_REMOVE_EMPTY_KW_SPLAT
(i.e. !rb_splat_or_kwargs_p(ci) && !calling->kw_splat).

Micro benchmark:
```
$ benchmark-driver -v --rbenv 'before;after' benchmark/vm_send_cfunc.yml --repeat-count=4
before: ruby 2.8.0dev (2020-04-13T23:45:05Z master b9d3ceee8f) [x86_64-linux]
after: ruby 2.8.0dev (2020-04-14T00:48:52Z no-splat-fastpath 418d363722) [x86_64-linux]
Calculating -------------------------------------
                         before       after
       vm_send_cfunc    69.585M     88.724M i/s -    100.000M times in 1.437097s 1.127096s

Comparison:
                    vm_send_cfunc
               after:  88723605.2 i/s
              before:  69584737.1 i/s - 1.28x  slower
```

Optcarrot:
```
$ benchmark-driver -v --rbenv 'before;after' benchmark.yml --repeat-count=12 --output=all
before: ruby 2.8.0dev (2020-04-13T23:45:05Z master b9d3ceee8f) [x86_64-linux]
after: ruby 2.8.0dev (2020-04-14T00:48:52Z no-splat-fastpath 418d363722) [x86_64-linux]
Calculating -------------------------------------
                                       before                 after
Optcarrot Lan_Master.nes    50.76119601545175     42.73858236484051 fps
                            50.76388649761503     51.04211379912850
                            50.80930672252514     51.39455790755538
                            50.90236000778749     51.75656936556145
                            51.01744746340430     51.86875277356489
                            51.06495279015112     51.88692482485558
                            51.07785337168974     51.93429603190578
                            51.20163525187862     51.95768145071314
                            51.34671771913112     52.45577266040274
                            51.35918340835583     52.53163888762858
                            51.46641337418146     52.62172484121034
                            51.50835463462257     52.85064021113239
```
2020-04-13 20:32:59 -07:00
Takashi Kokubun 5c27681813
Enable fastpath on invokesuper (#3021)
Fastpath has not been used for invokesuper since it has set vm_call_super_method on every invocation.
Because it seems to be blocked only by refinements, try enabling fastpath on invokesuper when cme is not for refinements.

While this patch itself should be helpful for VM performance, a part of this patch's motivation is to unblock inlining invokesuper on JIT. 

$ benchmark-driver -v --rbenv 'before;after' benchmark/vm2_super.yml --repeat-count=4
before: ruby 2.8.0dev (2020-04-11T15:19:58Z master a01bda5949) [x86_64-linux]
after: ruby 2.8.0dev (2020-04-12T02:00:08Z invokesuper-fastpath c171984ee3) [x86_64-linux]
Calculating -------------------------------------
                         before       after
           vm2_super    20.031M     32.860M i/s -      6.000M times in 0.299534s 0.182593s

Comparison:
                        vm2_super
               after:  32859885.2 i/s
              before:  20031097.3 i/s - 1.64x  slower
2020-04-11 20:45:22 -07:00
Jeremy Evans 900e83b501 Turn class variable warnings into exceptions
This changes the following warnings:

* warning: class variable access from toplevel
* warning: class variable @foo of D is overtaken by C

into RuntimeErrors.  Handle defined?(@@foo) at toplevel
by returning nil instead of raising an exception (the previous
behavior warned before returning nil when defined? was used).

Refactor the specs to avoid the warnings even in older versions.
The specs were checking for the warnings, but the purpose of
the related specs as evidenced from their description is to
test for behavior, not for warnings.

Fixes [Bug #14541]
2020-04-10 00:29:05 -07:00
卜部昌平 9e6e39c351
Merge pull request #2991 from shyouhei/ruby.h
Split ruby.h
2020-04-08 13:28:13 +09:00
Jeremy Evans d2c41b1bff Reduce allocations for keyword argument hashes
Previously, passing a keyword splat to a method always allocated
a hash on the caller side, and accepting arbitrary keywords in
a method allocated a separate hash on the callee side.  Passing
explicit keywords to a method that accepted a keyword splat
did not allocate a hash on the caller side, but resulted in two
hashes allocated on the callee side.

This commit makes passing a single keyword splat to a method not
allocate a hash on the caller side.  Passing multiple keyword
splats or a mix of explicit keywords and a keyword splat still
generates a hash on the caller side.  On the callee side,
if arbitrary keywords are not accepted, it does not allocate a
hash.  If arbitrary keywords are accepted, it will allocate a
hash, but this commit uses a callinfo flag to indicate whether
the caller already allocated a hash, and if so, the callee can
use the passed hash without duplicating it.  So this commit
should make it so that a maximum of a single hash is allocated
during method calls.

To set the callinfo flag appropriately, method call argument
compilation checks if only a single keyword splat is given.
If only one keyword splat is given, the VM_CALL_KW_SPLAT_MUT
callinfo flag is not set, since in that case the keyword
splat is passed directly and not mutable.  If more than one
splat is used, a new hash needs to be generated on the caller
side, and in that case the callinfo flag is set, indicating
the keyword splat is mutable by the callee.

In compile_hash, used for both hash and keyword argument
compilation, if compiling keyword arguments and only a
single keyword splat is used, pass the argument directly.

On the caller side, in vm_args.c, the callinfo flag needs to
be recognized and handled.  Because the keyword splat
argument may not be a hash, it needs to be converted to a
hash first if not.  Then, unless the callinfo flag is set,
the hash needs to be duplicated.  The temporary copy of the
callinfo flag, kw_flag, is updated if a hash was duplicated,
to prevent the need to duplicate it again.  If we are
converting to a hash or duplicating a hash, we need to update
the argument array, which can including duplicating the
positional splat array if one was passed.  CALLER_SETUP_ARG
and a couple other places needs to be modified to handle
similar issues for other types of calls.

This includes fairly comprehensive tests for different ways
keywords are handled internally, checking that you get equal
results but that keyword splats on the caller side result in
distinct objects for keyword rest parameters.

Included are benchmarks for keyword argument calls.
Brief results when compiled without optimization:

  def kw(a: 1) a end
  def kws(**kw) kw end
  h = {a: 1}

  kw(a: 1)       # about same
  kw(**h)        # 2.37x faster
  kws(a: 1)      # 1.30x faster
  kws(**h)       # 2.19x faster
  kw(a: 1, **h)  # 1.03x slower
  kw(**h, **h)   # about same
  kws(a: 1, **h) # 1.16x faster
  kws(**h, **h)  # 1.14x faster
2020-03-17 12:09:43 -07:00
卜部昌平 f12b9a3338 %p is for void *
See also
35eb12c063
6f5eb28507
687308cf0d
b6a2d63eb3
2020-03-04 12:30:42 +09:00
Koichi Sasada 91de0daaa2 method_missing_reason should be set.
send() has special method launcher in VM and it has special
method_missing caller. This path doesn't set
ec->method_missing_reason which is used at exception creation,
so setup this information. Without this setting, NoMethodError
exception becomes NameError.

This patch will fix:
http://ci.rvm.jp/results/trunk-random1@phosphorus-docker/2761643
2020-03-03 02:44:02 +09:00
Koichi Sasada 18674aef0d check imemo_type
check imemo_type to debug
http://ci.rvm.jp/results/trunk-vm-asserts@silicon-docker/2744755
2020-02-27 10:50:20 +09:00
Koichi Sasada b9007b6c54 Introduce disposable call-cache.
This patch contains several ideas:

(1) Disposable inline method cache (IMC) for race-free inline method cache
    * Making call-cache (CC) as a RVALUE (GC target object) and allocate new
      CC on cache miss.
    * This technique allows race-free access from parallel processing
      elements like RCU.
(2) Introduce per-Class method cache (pCMC)
    * Instead of fixed-size global method cache (GMC), pCMC allows flexible
      cache size.
    * Caching CCs reduces CC allocation and allow sharing CC's fast-path
      between same call-info (CI) call-sites.
(3) Invalidate an inline method cache by invalidating corresponding method
    entries (MEs)
    * Instead of using class serials, we set "invalidated" flag for method
      entry itself to represent cache invalidation.
    * Compare with using class serials, the impact of method modification
      (add/overwrite/delete) is small.
    * Updating class serials invalidate all method caches of the class and
      sub-classes.
    * Proposed approach only invalidate the method cache of only one ME.

See [Feature #16614] for more details.
2020-02-22 09:58:59 +09:00
Koichi Sasada f2286925f0 VALUE size packed callinfo (ci).
Now, rb_call_info contains how to call the method with tuple of
(mid, orig_argc, flags, kwarg). Most of cases, kwarg == NULL and
mid+argc+flags only requires 64bits. So this patch packed
rb_call_info to VALUE (1 word) on such cases. If we can not
represent it in VALUE, then use imemo_callinfo which contains
conventional callinfo (rb_callinfo, renamed from rb_call_info).

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

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

struct rb_call_info_kw_arg is renamed to rb_callinfo_kwarg.

rb_funcallv_with_cc() and rb_method_basic_definition_p_with_cc()
is temporary removed because cd->ci should be marked.
2020-02-22 09:58:59 +09:00
Nobuyoshi Nakada 0b4500d982
Adjusted indent [ci skip] 2020-02-22 00:17:31 +09:00
Koichi Sasada 99a8742067 should be compared with called_id
me->called_id and me->def->original_id can be different sometimes
so we should compare with called_id, which is mtbl's key.
(fix GH-PR #2869)
2020-02-13 03:30:22 +09:00
John Hawthorn ed7b46b66b Use inline cache for super calls 2020-02-13 00:14:55 +09:00
Koichi Sasada a635c93fde support MJIT with debug option.
VM_CHECK_MODE > 0 with optflags=-O0 can not run JIT tests because
of link problems. This patch fix them.
2020-02-03 16:57:41 +09:00
Jeremy Evans beae6cbf0f Fully separate positional arguments and keyword arguments
This removes the warnings added in 2.7, and changes the behavior
so that a final positional hash is not treated as keywords or
vice-versa.

To handle the arg_setup_block splat case correctly with keyword
arguments, we need to check if we are taking a keyword hash.
That case didn't have a test, but it affects real-world code,
so add a test for it.

This removes rb_empty_keyword_given_p() and related code, as
that is not needed in Ruby 3.  The empty keyword case is the
same as the no keyword case in Ruby 3.

This changes rb_scan_args to implement keyword argument
separation for C functions when the : character is used.
For backwards compatibility, it returns a duped hash.
This is a bad idea for performance, but not duping the hash
breaks at least Enumerator::ArithmeticSequence#inspect.

Instead of having RB_PASS_CALLED_KEYWORDS be a number,
simplify the code by just making it be rb_keyword_given_p().
2020-01-02 18:40:45 -08:00
卜部昌平 5e22f873ed decouple internal.h headers
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead.  This would significantly
speed up incremental builds.

We take the following inclusion order in this changeset:

1.  "ruby/config.h", where _GNU_SOURCE is defined (must be the very
    first thing among everything).
2.  RUBY_EXTCONF_H if any.
3.  Standard C headers, sorted alphabetically.
4.  Other system headers, maybe guarded by #ifdef
5.  Everything else, sorted alphabetically.

Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
2019-12-26 20:45:12 +09:00
卜部昌平 0958e19ffb add several __has_something macro
With these macros implemented we can write codes just like we can assume
the compiler being clang.  MSC_VERSION_SINCE is defined to implement
those macros, but turned out to be handy for other places.  The -fdeclspec
compiler flag is necessary for clang to properly handle __has_declspec().
2019-12-26 20:45:12 +09:00
Nobuyoshi Nakada db16629008
Fixed misspellings
Fixed misspellings reported at [Bug #16437], only in ruby and rubyspec.
2019-12-20 09:32:42 +09:00
卜部昌平 f054f11a38 per-method serial number
Methods and their definitions can be allocated/deallocated on-the-fly.
One pathological situation is when a method is deallocated then another
one is allocated immediately after that.  Address of those old/new method
entries/definitions can be the same then, depending on underlying
malloc/free implementation.

So pointer comparison is insufficient.  We have to check the contents.
To do so we introduce def->method_serial, which is an integer unique to
that specific method definition.

PS: Note that method_serial being uintptr_t rather than rb_serial_t is
intentional.  This is because rb_serial_t can be bigger than a pointer
on a 32bit system (rb_serial_t is at least 64bit).  In order to preserve
old packing of struct rb_call_cache, rb_serial_t is inappropriate.
2019-12-18 12:52:28 +09:00
Koichi Sasada fbe229906b add debug counter to count `call` reusing cases. 2019-12-17 13:15:38 +09:00
卜部昌平 ba11a74745 ensure cc->def == cc->me->def
The equation shall hold for every call cache.  However prior to this
changeset cc->me could be updated without also updating cc->def.  Let's
make it sure by introducing new macro named CC_SET_ME which sets cc->me
and cc->def at once.
2019-12-16 17:52:18 +09:00
Jeremy Evans 55b7ba3686 Make super in instance_eval in method in module raise TypeError
This makes behavior the same as super in instance_eval in method
in class.  The reason this wasn't implemented before is that
there is a check to determine if the self in the current context
is of the expected class, and a module itself can be included
in multiple classes, so it doesn't have an expected class.

Implementing this requires giving iclasses knowledge of which
class created them, so that super call in the module method
knows the expected class for super calls.  This reference
is called includer, and should only be set for iclasses.

Note that the approach Ruby uses in this check is not robust. If
you instance_eval another object of the same class and call super,
instead of an TypeError, you get super called with the
instance_eval receiver instead of the method receiver.  Truly
fixing super would require keeping a reference to the super object
(method receiver) in each frame where scope has changed, and using
that instead of current self when calling super.

Fixes [Bug #11636]
2019-12-12 15:50:19 +09:00
Aaron Patterson 2c8d186c6e
Introduce an "Inline IVAR cache" struct
This commit introduces an "inline ivar cache" struct.  The reason we
need this is so compaction can differentiate from an ivar cache and a
regular inline cache.  Regular inline caches contain references to
`VALUE` and ivar caches just contain references to the ivar index.  With
this new struct we can easily update references for inline caches (but
not inline var caches as they just contain an int)
2019-12-05 13:37:02 -08:00
Koichi Sasada 36da0b3da1 check interrupts at each frame pop timing.
Asynchronous events such as signal trap, finalization timing,
thread switching and so on are managed by "interrupt_flag".
Ruby's threads check this flag periodically and if a thread
does not check this flag, above events doesn't happen.

This checking is CHECK_INTS() (related) macro and it is placed
at some places (laeve instruction and so on). However, at the end
of C methods, C blocks (IMEMO_IFUNC) etc there are no checking
and it can introduce uninterruptible thread.

To modify this situation, we decide to place CHECK_INTS() at
vm_pop_frame(). It increases interrupt checking points.
[Bug #16366]

This patch can introduce unexpected events...
2019-11-29 17:47:02 +09:00
Yusuke Endoh 191ce5344e Reduce duplicated warnings for the change of Ruby 3 keyword arguments
By this change, the following code prints only one warning.

```
def foo(**opt); end
100.times { foo({kw:1}) }
```

A global variable `st_table *caller_to_callees` is a map from caller to
a set of callee methods.  It remembers that a warning is already printed
for each pair of caller and callee.

[Feature #16289]
2019-11-29 17:32:27 +09:00
Koichi Sasada f38b6d197f Revert "export for MJIT"
This reverts commit 2e6f1cf8b2.
2019-11-29 03:22:24 +09:00
Koichi Sasada e4e41840ad Revert "* remove trailing spaces. [ci skip]"
This reverts commit 27d0d7c0d3.
2019-11-29 03:22:13 +09:00
git 27d0d7c0d3 * remove trailing spaces. [ci skip] 2019-11-29 03:18:19 +09:00
Koichi Sasada 2e6f1cf8b2 export for MJIT 2019-11-29 03:17:52 +09:00
Koichi Sasada dd723771c1 fastpath for ivar read of FL_EXIVAR objects.
vm_getivar() provides fastpath for T_OBJECT by caching an index
of ivar. This patch also provides fastpath for FL_EXIVAR objects.
FL_EXIVAR objects have an each ivar array and index can be cached
as T_OBJECT. To access this ivar array, generic_iv_tbl is exposed
by rb_ivar_generic_ivtbl() (declared in variable.h which is newly
introduced).

Benchmark script:

Benchmark.driver(repeat_count: 3){|x|
  x.executable name: 'clean', command: %w'../clean/miniruby'
  x.executable name: 'trunk', command: %w'./miniruby'

  objs = [Object.new, 'str', {a: 1, b: 2}, [1, 2]]

  objs.each.with_index{|obj, i|
    rep = obj.inspect
    rep = 'Object.new' if /\#/ =~ rep
    x.prelude str = %Q{
      v#{i} = #{rep}
      def v#{i}.foo
        @iv # ivar access method (attr_reader)
      end
      v#{i}.instance_variable_set(:@iv, :iv)
    }
    puts str
    x.report %Q{
      v#{i}.foo
    }
  }
}

Result:

      v0.foo # T_OBJECT

               clean:  85387141.8 i/s
               trunk:  85249373.6 i/s - 1.00x  slower

      v1.foo # T_STRING

               trunk:  57894407.5 i/s
               clean:  39957178.6 i/s - 1.45x  slower

      v2.foo # T_HASH

               trunk:  56629413.2 i/s
               clean:  39227088.9 i/s - 1.44x  slower

      v3.foo # T_ARRAY

               trunk:  55797530.2 i/s
               clean:  38263572.9 i/s - 1.46x  slower
2019-11-29 03:11:04 +09:00
Kazuhiro NISHIYAMA 09e76e9828
Improve consistency of bool/true/false 2019-11-25 15:09:09 +09:00
Koichi Sasada e27acb6148 add fast path for argc==0.
If calling builtin functions with no arguments, we don't need to
calculate argv location.
2019-11-25 14:04:21 +09:00
卜部昌平 f6239ce0fc peep-hole optimize VM instructions
Some minor optimizations.

Calculating -------------------------------------
                           ours       trunk
          vm2_regexp     8.479M      8.346M i/s -      6.000M times in 0.707612s 0.718916s
   vm2_regexp_invert     8.605M      8.350M i/s -      6.000M times in 0.697298s 0.718576s

Comparison:
                       vm2_regexp
                ours:   8479223.3 i/s
               trunk:   8345893.8 i/s - 1.02x  slower

                vm2_regexp_invert
                ours:   8604647.4 i/s
               trunk:   8349852.8 i/s - 1.03x  slower

Calculating -------------------------------------
                           ours+jit   trunk+jit
Optcarrot Lan_Master.nes     68.603      64.167 fps

Comparison:
             Optcarrot Lan_Master.nes
                ours+jit:        68.6 fps
               trunk+jit:        64.2 fps - 1.07x  slower
2019-11-19 13:56:13 +09:00
Koichi Sasada 57cd4623cf should not use __func__ 2019-11-18 13:53:32 +09:00
Koichi Sasada 5e34ab5406 add casts.
add casts to avoid compile error.
http://ci.rvm.jp/results/trunk_clang_39@silicon-docker/2402215
2019-11-18 10:36:48 +09:00
Koichi Sasada 71fee9bc72 vm_invoke_builtin_delegate with start index.
opt_invokebuiltin_delegate and opt_invokebuiltin_delegate_leave
invokes builtin functions with same parameters of the method.
This technique eliminate stack push operations. However, delegation
parameters should be completely same as given parameters.
(e.g. `def foo(a, b, c) __builtin_foo(a, b, c)` is okay, but
__builtin_foo(b, c) is not allowed)

This patch relaxes this restriction. ISeq has a local variables
table which includes parameters. For example, the method defined
as `def foo(a, b, c) x=y=nil`, then local variables table contains
[a, b, c, x, y]. If calling builtin-function with arguments which
are sub-array of the lvar table, use opt_invokebuiltin_delegate
instruction with start index. For example, `__builtin_foo(b, c)`,
`__builtin_bar(c, x, y)` is okay, and so on.
2019-11-18 10:16:11 +09:00
Koichi Sasada 179062dd80 move rb_vm_lvar_exposed() correctly.
rb_vm_lvar_exposed() is prepared for __builtin_inline!(), needed for
mini_builtin.c and builtin.c. However, it's only on builtin.c.
So move it to make it as a part of VM.
2019-11-14 04:21:24 +09:00
Dylan Thacker-Smith ac112f2b5d Avoid top-level search for nested constant reference from nil in defined?
Fixes [Bug #16332]

Constant access was changed to no longer allow top-level constant access
through `nil`, but `defined?` wasn't changed at the same time to stay
consistent.

Use a separate defined type to distinguish between a constant
referenced from the current lexical scope and one referenced from
another namespace.
2019-11-13 15:36:58 +09:00
Koichi Sasada 9142f802f1 rewrite comment.
Pointed by nagachika-san.
https://ruby-trunk-changes.hatenablog.com/entry/ruby_trunk_changes_20191109
2019-11-11 16:47:50 +09:00
Koichi Sasada 43ceedecc0 use STACK_ADDR_FROM_TOP()
vm_invoke_builtin() accesses VM stack via cfp->sp. However, MJIT
can use their own stack. To access them appropriately, we need to
use STACK_ADDR_FROM_TOP().
2019-11-09 16:18:58 +09:00
Koichi Sasada 21f7cca2c6 initialize kw special local var.
A method which has keyword parameters has an implicit local variable
to specify which keywords are (un)specified.

vm_call_iseq_setup_kwparm_nokwarg() is special function to invoke
a ISeq method without any keyword arguments. However, it should
also initialize the special local var. Without this initialization,
the implicit lvar can points a freed (T_NONE) object.
2019-11-09 10:04:04 +09:00
卜部昌平 90fc555258 name the result of calccall
This is a pure refactoring for better understanding of what is
happening here.  Should change nothing but readability.
2019-11-08 12:09:01 +09:00
卜部昌平 a1a08ac9aa describe vm_cache_check_for_class_serial [ci skip]
Added comments describing what it is.  Requested by ko1.
2019-11-08 10:31:06 +09:00
Koichi Sasada 46acd0075d support builtin features with Ruby and C.
Support loading builtin features written in Ruby, which implement
with C builtin functions.
[Feature #16254]

Several features:

(1) Load .rb file at boottime with native binary.

Now, prelude.rb is loaded at boottime. However, this file is contained
into the interpreter as a text format and we need to compile it.
This patch contains a feature to load from binary format.

(2) __builtin_func() in Ruby call func() written in C.

In Ruby file, we can write `__builtin_func()` like method call.
However this is not a method call, but special syntax to call
a function `func()` written in C. C functions should be defined
in a file (same compile unit) which load this .rb file.

Functions (`func` in above example) should be defined with
  (a) 1st parameter: rb_execution_context_t *ec
  (b) rest parameters (0 to 15).
  (c) VALUE return type.
This is very similar requirements for functions used by
rb_define_method(), however `rb_execution_context_t *ec`
is new requirement.

(3) automatic C code generation from .rb files.

tool/mk_builtin_loader.rb creates a C code to load .rb files
needed by miniruby and ruby command. This script is run by
BASERUBY, so *.rb should be written in BASERUBY compatbile
syntax. This script load a .rb file and find all of __builtin_
prefix method calls, and generate a part of C code to export
functions.

tool/mk_builtin_binary.rb creates a C code which contains
binary compiled Ruby files needed by ruby command.
2019-11-08 09:09:29 +09:00
卜部昌平 d45a013a1a extend rb_call_cache
Prior to this changeset, majority of inline cache mishits resulted
into the same method entry when rb_callable_method_entry() resolves
a method search.  Let's not call the function at the first place on
such situations.

In doing so we extend the struct rb_call_cache from 44 bytes (in
case of 64 bit machine) to 64 bytes, and fill the gap with
secondary class serial(s).  Call cache's class serials now behavies
as a LRU cache.

Calculating -------------------------------------
                           ours         2.7         2.6
vm2_poly_same_method     2.339M      1.744M      1.369M i/s - 6.000M times in 2.565086s 3.441329s 4.381386s

Comparison:
             vm2_poly_same_method
                ours:   2339103.0 i/s
                 2.7:   1743512.3 i/s - 1.34x  slower
                 2.6:   1369429.8 i/s - 1.71x  slower
2019-11-07 17:41:30 +09:00
卜部昌平 6ff1250739 rb_method_basic_definition_p with CC
Noticed that rb_method_basic_definition_p is frequently called.
Its callers include vm_caller_setup_args_block(),
rb_hash_default_value(), rb_num_neative_int_p(), and a lot more.

It seems worth caching the method resolution part.  Majority of
rb_method_basic_definion_p() usages take fixed class and fixed
method id combinations.

Calculating -------------------------------------
                           ours       trunk
           so_matrix      2.379       2.115 i/s -       1.000 times in 0.420409s 0.472879s

Comparison:
                        so_matrix
                ours:         2.4 i/s
               trunk:         2.1 i/s - 1.12x  slower
2019-11-05 11:39:35 +09:00
卜部昌平 cc5580f175 fix bug in keyword + protected combination
Test included for the situation formerly was not working.
2019-10-28 14:38:05 +09:00
卜部昌平 356e203a3a more on struct rb_call_data
Replacing adjacent struct rb_call_info and struct rb_call_cache
into a struct rb_call_data.
2019-10-25 12:24:22 +09:00
wanabe 4ff2c58f91 retry tailcall optimization (#2529)
Sorry, f62f90367f is push miss.
2019-10-25 04:40:39 +09:00
Jeremy Evans d6a2507e49 Duplicate hash when converting keyword hash to keywords
This mirrors the behavior when manually splatting a hash.  This
mirrors the changes made in setup_parameters_complex in
6081ddd6e6, so that splatting to a
non-iseq method works the same as splatting to an iseq method.
2019-10-24 12:35:04 -07:00
Alan Wu 89e7997622 Combine call info and cache to speed up method invocation
To perform a regular method call, the VM needs two structs,
`rb_call_info` and `rb_call_cache`. At the moment, we allocate these two
structures in separate buffers. In the worst case, the CPU needs to read
4 cache lines to complete a method call. Putting the two structures
together reduces the maximum number of cache line reads to 2.

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

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

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

[Misc #16258]
2019-10-24 18:03:42 +09:00
Nobuyoshi Nakada 42edb05626
extracted declare_under 2019-10-10 01:08:42 +09:00
Koichi Sasada ddf5020e4f Revert "tailcall optimization again (#2528)"
This reverts commit f62f90367f.
2019-10-06 17:01:00 +09:00
wanabe f62f90367f tailcall optimization again (#2528)
This is follow up of r67315.
2019-10-06 16:52:09 +09:00
卜部昌平 3ffd98c5cd add debug counters for vm_search_method_slowpath()
Implemented fine-grained inspection of cache misshits.  Handy for
counting the reasons why an inline method cache was evicted.
2019-10-03 15:24:09 +09:00
卜部昌平 eb92159d72 Revert https://github.com/ruby/ruby/pull/2486
This reverts commits: 10d6a3aca7 8ba48c1b85 fba8627dc1 dd883de5ba
6c6a25feca 167e6b48f1 7cb96d41a5 3207979278 595b3c4fdd 1521f7cf89
c11c5e69ac cf33608203 3632a812c0 f56506be0d 86427a3219 .

The reason for the revert is that we observe ABA problem around
inline method cache.  When a cache misshits, we search for a
method entry.  And if the entry is identical to what was cached
before, we reuse the cache.  But the commits we are reverting here
introduced situations where a method entry is freed, then the
identical memory region is used for another method entry.  An
inline method cache cannot detect that ABA.

Here is a code that reproduce such situation:

```ruby
require 'prime'

class << Integer
  alias org_sqrt sqrt
  def sqrt(n)
    raise
  end

  GC.stress = true
  Prime.each(7*37){} rescue nil # <- Here we populate CC
  class << Object.new; end

  # These adjacent remove-then-alias maneuver
  # frees a method entry, then immediately
  # reuses it for another.
  remove_method :sqrt
  alias sqrt org_sqrt
end

Prime.each(7*37).to_a # <- SEGV
```
2019-10-03 12:45:24 +09:00
Jeremy Evans ef697388be
Treat return in block in class/module as LocalJumpError (#2511)
return directly in class/module is an error, so return in
proc in class/module should also be an error.  I believe the
previous behavior was an unintentional oversight during the
addition of top-level return in 2.4.
2019-10-02 07:56:28 -07:00
Nobuyoshi Nakada 10d6a3aca7
Fix assertion
callable_method_entry_p is for rb_callable_method_entry_t.
2019-09-30 17:43:11 +09:00
卜部昌平 fba8627dc1 delete unnecessary branch
At last, not only myself but also your compiler are fully confident
that the method entries pointed from call caches are immutable.  We
don't have to worry about silent updates.  Just delete the branch
that is now always false.

Calculating -------------------------------------
                           ours       trunk
vm2_poly_same_method     2.142M      2.070M i/s -      6.000M times in 2.801148s 2.898994s

Comparison:
             vm2_poly_same_method
                ours:   2141979.2 i/s
               trunk:   2069683.8 i/s - 1.03x  slower
2019-09-30 10:26:38 +09:00
卜部昌平 dd883de5ba refactor constify most of rb_method_entry_t
Now that we have eliminated most destructive operations over the
rb_method_entry_t / rb_callable_method_entry_t, let's make them
mostly immutabe and mark them const.

One exception is rb_export_method(), which destructively modifies
visibilities of method entries.  I have left that operation as is
because I suspect that destructiveness is the nature of that
function.
2019-09-30 10:26:38 +09:00
卜部昌平 6c6a25feca refactor add rb_method_entry_from_template
Tired of rb_method_entry_create(..., rb_method_definition_create(
..., &(rb_method_foo_t) {...})) maneuver.  Provide a function that
does the thing to reduce copy&paste.
2019-09-30 10:26:38 +09:00
卜部昌平 7cb96d41a5 refactor delete rb_method_entry_copy
The deleted function was to destructively overwrite existing method
entries, which is now considered to be a bad idea.  Delete it, and
assign a newly created method entry instead.
2019-09-30 10:26:38 +09:00
卜部昌平 3207979278 refactor delete rb_method_definition_set
Instead of destructively write fields of method entries, create a
new entry and let it overwrite its owner.
2019-09-30 10:26:38 +09:00
卜部昌平 595b3c4fdd refactor rb_method_definition_create take opts
Before this changeset rb_method_definition_create only allocated a
memory region and we had to destructively initialize it later.
That is not a good design so we change the API to return a complete
struct instead.
2019-09-30 10:26:38 +09:00
卜部昌平 cf33608203 refactor constify most of rb_method_definition_t
Most (if not all) of the fields of rb_method_definition_t are never
meant to be modified once after they are stored.  Marking them const
makes it possible for compilers to warn on unintended modifications.
2019-09-30 10:26:38 +09:00
Jeremy Evans 6fdd701472 Remove VM_NO_KEYWORDS, replace with RB_NO_KEYWORDS
VM_NO_KEYWORDS was introduced first in vm_core.h, but it is best
to only use a single definition for this.
2019-09-29 16:41:00 -07:00
Jeremy Evans 7814b6c657 Correctly issue ArgumentError when calling method that accepts no keywords
If a method accepts no keywords and was called with a keyword, an
ArgumentError was not always issued previously.  Force methods that
accept no keywords to go through setup_parameters_complex so that
an ArgumentError is raised if keywords are provided.
2019-09-27 11:21:50 -07:00
Nobuyoshi Nakada 8d0ff88727
Adjusted spaces [ci skip] 2019-09-27 14:06:07 +09:00
Nobuyoshi Nakada 0c6f36668a
Adjusted spaces [ci skip] 2019-09-27 10:20:56 +09:00
Jeremy Evans 3b302ea8c9 Add Module#ruby2_keywords for passing keywords through regular argument splats
This approach uses a flag bit on the final hash object in the regular splat,
as opposed to a previous approach that used a VM frame flag.  The hash flag
approach is less invasive, and handles some cases that the VM frame flag
approach does not, such as saving the argument splat array and splatting it
later:

  ruby2_keywords def foo(*args)
    @args = args
    bar
  end
  def bar
    baz(*@args)
  end
  def baz(*args, **kw)
    [args, kw]
  end
  foo(a:1)    #=> [[], {a: 1}]
  foo({a: 1}, **{}) #=> [[{a: 1}], {}]

  foo({a: 1}) #=> 2.7: [[], {a: 1}] # and warning
  foo({a: 1}) #=> 3.0: [[{a: 1}], {}]

It doesn't handle some cases that the VM frame flag handles, such as when
the final hash object is replaced using Hash#merge, but those cases are
probably less common and are unlikely to properly support keyword
argument separation.

Use ruby2_keywords to handle argument delegation in the delegate library.
2019-09-25 12:33:52 -07:00
Takashi Kokubun 6e0dd3e7c1
Use RUBY_VM_NEXT_CONTROL_FRAME macro
in vm_push_frame and limit scope of i.
Just a minor maintainability improvement.
2019-09-20 21:06:08 +09:00
卜部昌平 fcfe36b733 fix spec failure
See also https://travis-ci.org/ruby/ruby/jobs/586452224
2019-09-19 15:18:10 +09:00
卜部昌平 d74fa8e55c reuse cc->call
I noticed that in case of cache misshit, re-calculated cc->me can
be the same method entry than the pevious one.  That is an okay
situation but can't we partially reuse the cache, because cc->call
should still be valid then?

One thing that has to be special-cased is when the method entry
gets amended by some refinements.  That happens behind-the-scene
of call cache mechanism.  We have to check if cc->me->def points to
the previously saved one.

Calculating -------------------------------------
                          trunk        ours
vm2_poly_same_method     1.534M      2.025M i/s -      6.000M times in 3.910203s 2.962752s

Comparison:
             vm2_poly_same_method
                ours:   2025143.9 i/s
               trunk:   1534447.2 i/s - 1.32x  slower
2019-09-19 15:18:10 +09:00
卜部昌平 bcd5f2e9d3 delete unused variable 2019-09-18 11:06:24 +09:00
Jeremy Evans 775365cbd2 Fix keyword argument separation issues with sym procs when using refinements
Make sure that vm_yield_with_cfunc can correctly set the empty keyword
flag by passing 2 as the kw_splat value when calling it in
vm_invoke_ifunc_block.  Make sure calling.kw_splat is set to 1 and not
128 in vm_sendish, so we can safely check for different kw_splat values.

vm_args.c needs to call add_empty_keyword, and to make JIT happy, the
function needs to be exported.  Rename the function to
rb_adjust_argv_kw_splat to more accurately reflect what it does, and
mark it as MJIT exported.
2019-09-17 16:22:44 -07:00
Jeremy Evans 37a2c660aa Convert keyword argument to required positional hash argument for Class#new, Method#call, UnboundMethod#bind_call
Also add keyword argument separation warnings for Class#new and Method#call.

To allow for keyword argument to required positional hash converstion in
cfuncs, add a vm frame flag indicating the cfunc was called with an empty
keyword hash (which was removed before calling the cfunc).  The cfunc can
check this frame flag and add back an empty hash if it is passing its
arguments to another Ruby method.  Add rb_empty_keyword_given_p function
for checking if called with an empty keyword hash, and
rb_add_empty_keyword for adding back an empty hash to argv.

All of this empty keyword argument support is only for 2.7.  It will be
removed in 3.0 as Ruby 3 will not convert empty keyword arguments to
required positional hash arguments.  Comment all of the relevent code
to make it obvious this is expected to be removed.

Add rb_funcallv_kw as an public C-API function, just like rb_funcallv
but with a keyword flag.  This is used by rb_obj_call_init (internals
of Class#new).  This also required expected call_type enum with
CALL_FCALL_KW, similar to the recent addition of CALL_PUBLIC_KW.

Add rb_vm_call_kw as a internal function, used by call_method_data
(internals of Method#call and UnboundMethod#bind_call). Add tests
for UnboundMethod#bind_call keyword handling.
2019-09-06 19:41:23 -07:00
git dd81af7b6a * remove trailing spaces. [ci skip] 2019-09-06 09:50:59 +09:00
Jeremy Evans d3cf0eb214 Mark rb_warn_keyword_to_last_hash as static inline
mame pointed out that vm_args.c is included in vm_insnhelper.c.
2019-09-05 17:47:12 -07:00
Jeremy Evans 729de9ee68 Convert empty keyword hash to required positional argument and warn for method_missing
This is the same as the bmethod, sym proc, and send cases,
where we don't remove the keyword splat, so later code can
move it to a required positional parameter and warn.
2019-09-05 17:47:12 -07:00
Jeremy Evans e220b467ef Convert empty keyword hash to required positional argument and warn for sym procs
This is the same as the bmethod and send cases, where we don't
remove the keyword splat, so later code can move it to to a
a required positional parameter and warn.
2019-09-05 17:47:12 -07:00
Jeremy Evans e2878a96f7 Convert empty keyword hash to required positional argument and warn for lambda and bmethod
The lambda case is similar to the attr_writer case, except we have
to determine the number of required parameters from the iseq
instead of being able to assume a single required parameter.

This fixes a lot of lambda tests which were switched to require
warnings for all usage of keyword arguments.  Similar to method
handling, we do not warn when passing keyword arguments to
lambdas that do not accept keyword arguments, the argument is
just passed as a positional hash in that case, unless it is empty.
If it is empty and not the final required parameter, then we
ignore it.  If it is empty and the final required parameter, then
we pass it for backwards compatibility and emit a warning, as in
Ruby 3 we will not pass it.

The bmethod case is similar to the send case, in that we do not
want to remove empty keyword splats in vm_call_bmethod, as that
prevents later call handling from moving them to required
positional arguments and warning.
2019-09-05 17:47:12 -07:00
Jeremy Evans e7274a8ec4 Convert empty keyword hash to required positional argument and warn
In general, we want to ignore empty keyword hashes.  The only case
where we want to allow them for backwards compatibility is when
they are necessary to satify the final required positional argument.
In that case, we want to not ignore them, but we do want to warn,
as that will be going away in Ruby 3.

This commit implements this support for regular methods and
attr_writer methods.

In order to allow send to forward arguments correctly, send no
longer removes empty keyword hashes.  It is the responsibility of
the final method to remove the empty keyword hashes now.  This
change was necessary as otherwise send could remove the empty
keyword hashes before the regular or attr_writer methods could
move them to required positional arguments.

For completeness, add tests for keyword handling regular
methods calls.

This makes rb_warn_keyword_to_last_hash non-static in vm_args.c
so it can be reused in vm_insnhelper.c, and also moves declarations
before statements in the rb_warn_* functions in vm_args.c.
2019-09-05 17:47:12 -07:00
Jeremy Evans d1ef73b59c Always remove empty keyword hashes when calling methods
While doing so is not backwards compatible with Ruby 2.6, it is
necessary for generic argument forwarding to work for all methods:

```ruby
def foo(*args, **kw, &block)
  bar(*args, **kw, &block)
end
```

If you do not remove empty keyword hashes, and bar does not accept
keyword arguments, then a call to foo without keyword arguments
calls bar with an extra positional empty hash argument.
2019-09-05 17:47:12 -07:00
Yusuke Endoh 55b96c5d2d Add a keyword-to-last-hash warning for some case of define_method method
and lambda.

When define_method is a simple iseq (`define_method(:m) {|x| ... }`),
passing keywords to it (`m(**kw)`) didn't print a warning.
2019-09-05 17:47:12 -07:00
Yusuke Endoh dd83f7bf98 define_method should not drop the empty keyword hash
Similar to 38e9c1bc35d5549575fbb263afff560e97db068e
2019-09-05 17:47:12 -07:00
Yusuke Endoh 70f2780892 vm_call_bmethod should not drop the empty keyword hash
Similar to 38e9c1bc35d5549575fbb263afff560e97db068e
2019-09-05 17:47:12 -07:00
Yusuke Endoh 252e299009 vm_call_opt_send should not drop the empty keyword hash
Now the mechanism that conveys kw_splat flag is gradually established,
so the hack to drop the empty keyword hash is not needed for
vm_call_opt_send.
2019-09-05 17:47:12 -07:00
Yusuke Endoh acee630241 vm_insnhelper.c: Do not read `ci->flag` after CALLER_SETUP_ARG
Actually, the following call is wrongly warned without this change.

```
class C
  def method_missing(x, *args, **opt)
  end
end
C.new.foo(k: 1)
  # warning: The last argument is used as the keyword parameter
  # warning: for `method_missing' defined here
```
2019-09-05 17:47:12 -07:00
Yusuke Endoh eda8dcea16 Add a comment that some ci->flag is inconsistent after CALLER_SETUP_ARG 2019-09-05 17:47:12 -07:00
Yusuke Endoh 0bfe3bf4d1 Ignore an empty keyword splat for attr_reader/writer methods 2019-09-05 17:47:12 -07:00
Yusuke Endoh 437ff40879 C method should accept a keyword hash (for compatibility with 2.6) 2019-09-05 17:47:12 -07:00
Yusuke Endoh c5555e2eb8 CALLER_SETUP_ARG removes an empty keyword hash from argv
...only when a "remove_empty_keyword_hash" flag is specified.

After CALLER_SETUP_ARG is called, `ci->flag & VM_CALL_KW_SPLAT` must not
be used.  Instead. use `calling->kw_splat`.  This is because
CALLER_SETUP_ARG may modify argv and update `calling->kw_splat`, and
`ci->flag & VM_CALL_KW_SPLAT` may be inconsistent with the result.
2019-09-05 17:47:12 -07:00
Yusuke Endoh a23ddf7ff5 vm_argc.c (vm_caller_setup_arg_kw): "cfunc" argument is no longer used 2019-09-05 17:47:12 -07:00
Yusuke Endoh 030b8e5edf Set calling->kw_splat = 1 in vm_caller_setup_arg_kw
There are two styles that argv contains keyword arguments: one is
VM_CALL_KWARG which contains value elements in argv (to avoid a hash
object creation if possible), and the other is VM_CALL_KW_SPLAT which
contains one last hash in argv.

vm_caller_setup_arg_kw translates argv from the VM_CALL_KWARG style to
the VM_CALL_KW_SPLAT style.
`calling->kw_splat` means that argv is the VM_CALL_KW_SPLAT style.

So, instead of setting `calling->kw_splat` at many places, it would be
better to do so when vm_caller_setup_arg_kw is called.
2019-09-05 17:47:12 -07:00
Jeremy Evans 1fffd33189 Fix passing keywords without splats to sym procs, define_method, and method_missing 2019-09-05 17:47:12 -07:00
Jeremy Evans 6f9b86616a Make Symbol#to_proc calls handle keyword arguments
Make rb_sym_proc_call take a flag for whether a keyword argument
is used, and use the new rb_funcall_with_block_kw function to
pass that information.
2019-09-05 17:47:12 -07:00
Jeremy Evans 38dae1d510 If removing an empty keyword splat hash, unset the kw_splat flag
Otherwise the last positional hash could be considered as the
keyword arguments.
2019-09-05 17:47:12 -07:00
Jeremy Evans 7fc874bf4c Add rb_funcall_with_block_kw
This is needed for C functions to call methods with keyword arguments.
This is a copy of rb_funcall_with_block with an extra argument for
the keyword flag.

There isn't a clean way to implement this that doesn't involve
changing a lot of function signatures, because rb_call doesn't
support a way to mark that the call has keyword arguments.  So hack
this in using a CALL_PUBLIC_KW call_type, which we switch for
CALL_PUBLIC later in the call stack.

We do need to modify rm_vm_call0 to take an argument for whether
keyword arguments are used, since the call_type is no longer
available at that point.  Use the passed in value to set the
appropriate keyword flag in both calling and ci_entry.
2019-09-05 17:47:12 -07:00
Jeremy Evans e3cb3e11af Set VM_FRAME_FLAG_CFRAME_KW if kw_splat set in vm_yield_with_cfunc 2019-09-05 17:47:12 -07:00
Yusuke Endoh ce04392d8d Propagate kw_splat information
The kw_splat flag is whether the original call passes keyword or not.
Some types of methods (e.g., bmethod and sym_proc) drops the
information.  This change tries to propagate the flag to the final
callee, as far as I can.
2019-09-05 17:47:12 -07:00
Jeremy Evans 39c3252cd1
Merge pull request #2422 from jeremyevans/rb_keyword_given_p
Add rb_keyword_given_p to the C-API
2019-09-03 11:32:02 -07:00
Urabe, Shyouhei 79e3d6bb9e fix shortcut condition
rb_reg_match expects its first argument to be a Regexp instance.
Should check that.
2019-09-02 13:56:40 +09:00
Urabe, Shyouhei ec80d5c4f3 delete unused function 2019-09-02 13:56:40 +09:00
Urabe, Shyouhei 8ad7fafcdd opt_regexpmatch1 is actually making things slower.
----

trunk: ruby 2.6.0dev (2018-09-18 trunk 64767) [x86_64-darwin15]
ours: ruby 2.6.0dev (2018-09-18 opt_regexpmatch 64775) [x86_64-darwin15]
last_commit=opt_regexpmatch1 is actually making things slower.
Calculating -------------------------------------
                              trunk        ours
Optcarrot Lan_Master.nes     33.877      35.282 fps

Comparison:
             Optcarrot Lan_Master.nes
                    ours:        35.3 fps
                   trunk:        33.9 fps - 1.04x  slower
2019-09-02 13:56:40 +09:00
Jeremy Evans f58db5a6f5 Simplify setting of VM_CALL_KW_SPLAT in vm_call_method_missing
Pointed out by ko1.
2019-09-01 19:46:19 -07:00
Jeremy Evans 3fde9ef937 Fix keyword argument separation warning in method_missing
vm_call_method_missing was dropping VM_CALL_KW_SPLAT, so this just
makes it not drop it, to get the same behavior as calling the method
directly.
2019-09-01 16:08:42 -07:00
Jeremy Evans d646a292cd Fix keyword argument separation warning when using send
vm_call_opt_send was dropping VM_CALL_KW_SPLAT, so this just makes
it not drop it, to get the same behavior as calling the method
directly.
2019-08-31 23:06:49 -07:00
Jeremy Evans 15757390ff Don't pass an empty keyword hash when double splatting empty hash when calling cfunc
This mirrors earlier changes in keyword argument separation for
calling Ruby methods and calling procs/lambdas, so that behavior
is kept the same.
2019-08-31 21:54:06 -07:00
Jeremy Evans 1f18b578ce Don't pass an empty keyword hash when double splatting empty hash 2019-08-30 23:50:50 -07:00
Yusuke Endoh 16c6984bb9 Separate keyword arguments from positional arguments
And, allow non-symbol keys as a keyword arugment
2019-08-30 12:39:31 -07:00
Nobuyoshi Nakada 761346a960
Show the previous definition location,
when reopened class/module redefinition mismatched the previous
definition.  [Feature #11460]
2019-08-29 13:24:00 +09:00
卜部昌平 b8fd2e83e7 decouple compile.c usage of imemo_ifunc
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct.  This commit deletes ANYARGS from
struct vm_ifunc, but in doing so we also have to decouple the usage
of this struct in compile.c, which (I think) is an abuse of ANYARGS.
2019-08-27 15:52:26 +09:00
Nobuyoshi Nakada dc020b06ff
Hoisted out search_refined_method
[Bug #16107]
2019-08-17 12:32:34 +09:00
Nobuyoshi Nakada 11a9f7ab94 Search refinement module along nested usings
[Bug #16107]
2019-08-17 12:30:38 +09:00
git d053a57014 * expand tabs. [ci skip] 2019-08-15 01:51:19 +09:00
Jeremy Evans fbcd065294 Remove support for nil::Constant
This was an intentional bug added in 1.9.

The approach taken here is to add a second operand to the
getconstant instruction for whether nil should be allowed and
treated as current scope.

Fixes [Bug #11718]
2019-08-14 09:50:14 -07:00
git 4e9382a827 * expand tabs. 2019-08-09 11:11:18 +09:00
Koichi Sasada 71efad1ed3 introduce RCLASS_CLONED flag for inline cache.
Methods on duplicated class/module refer same constant inline
cache (IC). Constant access lookup should be done for cloned
class/modules but inline cache doesn't check it.
To check it, this patch introduce new RCLASS_CLONED flag which
are set when if class/module is cloned (both orig and dst).
[Bug #15877]
2019-08-09 11:05:11 +09:00
git 3e6b9926b7 * expand tabs. 2019-08-06 20:59:41 +09:00
卜部昌平 b5146e375a
leafify opt_plus
Inspired by 346aa557b3

Closes: https://github.com/ruby/ruby/pull/2321
2019-08-06 20:59:19 +09:00
Takashi Kokubun 346aa557b3
Make opt_eq and opt_neq insns leaf
# Benchmark zero?

```
require 'benchmark/ips'

Numeric.class_eval do
  def ruby_zero?
    self == 0
  end
end

Benchmark.ips do |x|
  x.report('0.zero?') { 0.ruby_zero? }
  x.report('1.zero?') { 1.ruby_zero? }
  x.compare!
end
```

## VM
No significant impact for VM.

### before
ruby 2.7.0dev (2019-08-04T02:56:02Z master 2d8c037e97) [x86_64-linux]

  0.zero?: 21855445.5 i/s
  1.zero?: 21770817.3 i/s - same-ish: difference falls within error

### after
ruby 2.7.0dev (2019-08-04T11:17:10Z opt-eq-leaf 6404bebd6a) [x86_64-linux]

  1.zero?: 21958912.3 i/s
  0.zero?: 21881625.9 i/s - same-ish: difference falls within error

## JIT
The performance improves about 1.23x.

### before
ruby 2.7.0dev (2019-08-04T02:56:02Z master 2d8c037e97) +JIT [x86_64-linux]

  0.zero?: 36343111.6 i/s
  1.zero?: 36295153.3 i/s - same-ish: difference falls within error

### after
ruby 2.7.0dev (2019-08-04T11:17:10Z opt-eq-leaf 6404bebd6a) +JIT [x86_64-linux]

  0.zero?: 44740467.2 i/s
  1.zero?: 44363616.1 i/s - same-ish: difference falls within error

# Benchmark str == str / str != str

```
# frozen_string_literal: true
require 'benchmark/ips'

Benchmark.ips do |x|
  x.report('a == a') { 'a' == 'a' }
  x.report('a == b') { 'a' == 'b' }
  x.report('a != a') { 'a' != 'a' }
  x.report('a != b') { 'a' != 'b' }
  x.compare!
end
```

## VM
No significant impact for VM.

### before
ruby 2.7.0dev (2019-08-04T02:56:02Z master 2d8c037e97) [x86_64-linux]

  a == a: 27286219.0 i/s
  a != a: 24892389.5 i/s - 1.10x  slower
  a == b: 23623635.8 i/s - 1.16x  slower
  a != b: 21800958.0 i/s - 1.25x  slower

### after
ruby 2.7.0dev (2019-08-04T11:17:10Z opt-eq-leaf 6404bebd6a) [x86_64-linux]

  a == a: 27224016.2 i/s
  a != a: 24490109.5 i/s - 1.11x  slower
  a == b: 23391052.4 i/s - 1.16x  slower
  a != b: 21811321.7 i/s - 1.25x  slower

## JIT
The performance improves on JIT a little.

### before
ruby 2.7.0dev (2019-08-04T02:56:02Z master 2d8c037e97) +JIT [x86_64-linux]

  a == a: 42010674.7 i/s
  a != a: 38920311.2 i/s - same-ish: difference falls within error
  a == b: 32574262.2 i/s - 1.29x  slower
  a != b: 32099790.3 i/s - 1.31x  slower

### after
ruby 2.7.0dev (2019-08-04T11:17:10Z opt-eq-leaf 6404bebd6a) +JIT [x86_64-linux]

  a == a: 46902738.8 i/s
  a != a: 43097258.6 i/s - 1.09x  slower
  a == b: 35822018.4 i/s - 1.31x  slower
  a != b: 33377257.8 i/s - 1.41x  slower

This is needed towards Bug#15589.
Closes: https://github.com/ruby/ruby/pull/2318
2019-08-04 22:20:12 +09:00
Yusuke Endoh 086ffe72c7 Revert "Revert "Add a specialized instruction for `.nil?` calls""
This reverts commit a0980f2446.

Retry for macOS Mojave.
2019-08-02 23:25:38 +09:00
Yusuke Endoh a0980f2446 Revert "Add a specialized instruction for `.nil?` calls"
This reverts commit 9faef3113f.

It seemed to cause a failure on macOS Mojave, though I'm unsure how.
https://rubyci.org/logs/rubyci.s3.amazonaws.com/osx1014/ruby-master/log/20190802T034503Z.fail.html.gz

This tentative revert is to check if the issue is actually caused by the
change or not.
2019-08-02 15:03:34 +09:00
Aaron Patterson 9faef3113f
Add a specialized instruction for `.nil?` calls
This commit adds a specialized instruction for called to `.nil?`.  It is
about 27% faster than master in the case where the object is nil or not
nil.  In the case where an object implements `nil?`, I think it may be
slightly slower.  Here is a benchmark:

```ruby
require "benchmark/ips"

class Niller
  def nil?; true; end
end

not_nil = Object.new
xnil = nil
niller = Niller.new

Benchmark.ips do |x|
  x.report("nil?")    { xnil.nil? }
  x.report("not nil") { not_nil.nil? }
  x.report("niller")   { niller.nil? }
end
```

On Ruby master:

```
[aaron@TC ~/g/ruby (master)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   429.195k i/100ms
             not nil   437.889k i/100ms
              niller   437.935k i/100ms
Calculating -------------------------------------
                nil?     20.166M (± 8.1%) i/s -    100.002M in   5.002794s
             not nil     20.046M (± 7.6%) i/s -     99.839M in   5.020086s
              niller     22.467M (± 6.1%) i/s -    112.111M in   5.013817s
[aaron@TC ~/g/ruby (master)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   449.660k i/100ms
             not nil   433.836k i/100ms
              niller   443.073k i/100ms
Calculating -------------------------------------
                nil?     19.997M (± 8.8%) i/s -     99.375M in   5.020458s
             not nil     20.529M (± 7.0%) i/s -    102.385M in   5.020689s
              niller     21.796M (± 8.0%) i/s -    108.110M in   5.002300s
[aaron@TC ~/g/ruby (master)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   402.119k i/100ms
             not nil   438.968k i/100ms
              niller   398.226k i/100ms
Calculating -------------------------------------
                nil?     20.050M (±12.2%) i/s -     98.519M in   5.008817s
             not nil     20.614M (± 8.0%) i/s -    102.280M in   5.004531s
              niller     22.223M (± 8.8%) i/s -    110.309M in   5.013106s

```

On this branch:

```
[aaron@TC ~/g/ruby (specialized-nilp)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   468.371k i/100ms
             not nil   456.517k i/100ms
              niller   454.981k i/100ms
Calculating -------------------------------------
                nil?     27.849M (± 7.8%) i/s -    138.169M in   5.001730s
             not nil     26.417M (± 8.7%) i/s -    131.020M in   5.011674s
              niller     21.561M (± 7.5%) i/s -    107.376M in   5.018113s
[aaron@TC ~/g/ruby (specialized-nilp)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   477.259k i/100ms
             not nil   428.712k i/100ms
              niller   446.109k i/100ms
Calculating -------------------------------------
                nil?     28.071M (± 7.3%) i/s -    139.837M in   5.016590s
             not nil     25.789M (±12.9%) i/s -    126.470M in   5.011144s
              niller     20.002M (±12.2%) i/s -     98.144M in   5.001737s
[aaron@TC ~/g/ruby (specialized-nilp)]$ ./ruby compil.rb
Warming up --------------------------------------
                nil?   467.676k i/100ms
             not nil   445.791k i/100ms
              niller   415.024k i/100ms
Calculating -------------------------------------
                nil?     26.907M (± 8.0%) i/s -    133.755M in   5.013915s
             not nil     25.319M (± 7.9%) i/s -    125.713M in   5.007758s
              niller     19.569M (±11.8%) i/s -     96.286M in   5.008533s
```

Co-Authored-By: Ashe Connor <kivikakk@github.com>
2019-07-31 16:21:25 -07:00
Samuel Williams 9dda0a03cc
Remove `rb_vm_push_frame` as it is no longer used. 2019-07-19 11:10:01 +12:00
Yusuke Endoh 49362ddac6 Add a /* fall through */ comment 2019-07-14 22:21:10 +09:00
Jeremy Evans 5e018214e7 Fix SystemStackError when calling a method in an unused refinement
Fixes [Bug #15720]
2019-06-11 09:43:38 -07:00
git b487b39b85 * expand tabs. 2019-06-01 13:34:55 +09:00
Yusuke Endoh 65e63af377 Make opt_aref instruction support Integer#[]
only when its receiver and the argument are both Integers.

Since 6bedbf4625, Integer#[] has supported a range extraction.
This means that Integer#[] now accepts multiple arguments, which made
the method very slow unfortunately.

This change fixes the performance issue by adding a special handling for
its traditional use case: `num[idx]` where both `num` and `idx` are
Integers.
2019-06-01 13:15:43 +09:00
Nobuyoshi Nakada b1aecef873
Use UNALIGNED_MEMBER_PTR
* internal.h (UNALIGNED_MEMBER_ACCESS, UNALIGNED_MEMBER_PTR):
  moved from eval_intern.h.

* compile.c iseq.c, vm.c: use UNALIGNED_MEMBER_PTR for `entries`
  in `struct iseq_catch_table`.

* vm_eval.c, vm_insnhelper.c: use UNALIGNED_MEMBER_PTR for `body`
  in `rb_method_definition_t`.
2019-05-31 16:04:16 +09:00
Urabe, Shyouhei 2a863d4bab avoid buffer overflow in vm_check_canary
ec->cfp->iseq might not exist at the very beginning of a thread.

=================================================================
==82954==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7fc86f334810 at pc 0x55ceaf013125 bp 0x7ffe2eddbbf0 sp 0x7ffe2eddbbe8
READ of size 8 at 0x7fc86f334810 thread T0
    #0 0x55ceaf013124 in vm_check_canary vm_insnhelper.c:217:24
    #1 0x55ceaefb4796 in vm_push_frame vm_insnhelper.c:276:5
    #2 0x55ceaf0124bd in th_init vm.c:2661:5
    #3 0x55ceaf00d5eb in ruby_thread_init vm.c:2690:5
    #4 0x55ceaf00d4b1 in rb_thread_alloc vm.c:2703:5
    #5 0x55ceaef0038b in thread_s_new thread.c:872:20
    #6 0x55ceaf04d8c1 in call_cfunc_m1 vm_insnhelper.c:2041:12
    #7 0x55ceaf03118d in vm_call_cfunc_with_frame vm_insnhelper.c:2207:11
    #8 0x55ceaf017985 in vm_call_cfunc vm_insnhelper.c:2225:12
    #9 0x55ceaf01548b in vm_call_method_each_type vm_insnhelper.c:2560:9
    #10 0x55ceaf014c96 in vm_call_method vm_insnhelper.c:2686:13
    #11 0x55ceaefb5de4 in vm_call_general vm_insnhelper.c:2730:12
    #12 0x55ceaf03c868 in vm_sendish vm_insnhelper.c:3623:11
    #13 0x55ceaefc95bb in vm_exec_core insns.def:771:11
    #14 0x55ceaf006700 in rb_vm_exec vm.c:1892:22
    #15 0x55ceaf00acbf in rb_iseq_eval_main vm.c:2151:11
    #16 0x55ceaea250ca in ruby_exec_internal eval.c:262:2
    #17 0x55ceaea2498b in ruby_exec_node eval.c:326:12
    #18 0x55ceaea247d0 in ruby_run_node eval.c:318:25
    #19 0x55ceae88c486 in main main.c:42:9
    #20 0x7fc874330b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310
    #21 0x55ceae7e5289 in _start (miniruby+0x15f289)

0x7fc86f334810 is located 16 bytes to the right of 1048576-byte region [0x7fc86f234800,0x7fc86f334800)
allocated by thread T0 here:
    #0 0x55ceae85d56d in malloc (miniruby+0x1d756d)
    #1 0x55ceaea71d12 in objspace_xmalloc0 gc.c:9416:5
    #2 0x55ceaea71cd2 in ruby_xmalloc2_body gc.c:9623:12
    #3 0x55ceaea7d09c in ruby_xmalloc2 gc.c:11479:12
    #4 0x55ceaf00c3b7 in rb_thread_recycle_stack vm.c:2462:12
    #5 0x55ceaf012256 in th_init vm.c:2656:29
    #6 0x55ceaf00d5eb in ruby_thread_init vm.c:2690:5
    #7 0x55ceaf00d4b1 in rb_thread_alloc vm.c:2703:5
    #8 0x55ceaef0038b in thread_s_new thread.c:872:20
    #9 0x55ceaf04d8c1 in call_cfunc_m1 vm_insnhelper.c:2041:12
    #10 0x55ceaf03118d in vm_call_cfunc_with_frame vm_insnhelper.c:2207:11
    #11 0x55ceaf017985 in vm_call_cfunc vm_insnhelper.c:2225:12
    #12 0x55ceaf01548b in vm_call_method_each_type vm_insnhelper.c:2560:9
    #13 0x55ceaf014c96 in vm_call_method vm_insnhelper.c:2686:13
    #14 0x55ceaefb5de4 in vm_call_general vm_insnhelper.c:2730:12
    #15 0x55ceaf03c868 in vm_sendish vm_insnhelper.c:3623:11
    #16 0x55ceaefc95bb in vm_exec_core insns.def:771:11
    #17 0x55ceaf006700 in rb_vm_exec vm.c:1892:22
    #18 0x55ceaf00acbf in rb_iseq_eval_main vm.c:2151:11
    #19 0x55ceaea250ca in ruby_exec_internal eval.c:262:2
    #20 0x55ceaea2498b in ruby_exec_node eval.c:326:12
    #21 0x55ceaea247d0 in ruby_run_node eval.c:318:25
    #22 0x55ceae88c486 in main main.c:42:9
    #23 0x7fc874330b96 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:310

SUMMARY: AddressSanitizer: heap-buffer-overflow vm_insnhelper.c:217:24 in vm_check_canary
Shadow bytes around the buggy address:
  0x0ff98de5e8b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ff98de5e8c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ff98de5e8d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ff98de5e8e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ff98de5e8f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0ff98de5e900: fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff98de5e910: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff98de5e920: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff98de5e930: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff98de5e940: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0ff98de5e950: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==82954==ABORTING
2019-04-26 15:59:40 +09:00
Urabe, Shyouhei 171a6ad1c1 print the disasm
It seems to be my fault to leave the variable disasm unused.
2019-04-26 15:59:40 +09:00
Urabe, Shyouhei b6ebbee5d6 suppress warning [ci skip] 2019-04-26 15:59:40 +09:00
k0kubun 088df9c8c2 Revert "GET_CFP and ec->cfp are different"
This reverts commit 30f71f4768.

I've also overlooked we're doing RESTORE_REGS()...

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67523 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-13 06:55:35 +00:00
k0kubun 30f71f4768 GET_CFP and ec->cfp are different
When reviewing r66565, I overlooked that `GET_ISEQ()` and `GET_EP()` are
NOT `ec->cfp->iseq` and `ec->cfp->ep` but `reg_cfp->iseq` and
`reg_cfp->ep`.

`vm_push_frame` updates `ec->cfp` and in this case we want to check the
callee's cfp and so `ec->cfp` should be checked instead.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67522 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-13 06:27:52 +00:00
svn 4b53f84326 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67443 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-05 08:15:21 +00:00
ko1 2b5bb8a087 add definemethod/definesmethod insn.
* insns.def: add definemethod and definesmethod (singleton method)
  instructions. Old YARV contains these instructions, but it is moved
  to methods of FrozenCore class because remove number of instructions
  can improve performance for some techniques (static stack caching
  and so on). However, we don't employ these technique and it is hard
  to optimize/analysis definition sequence. So I decide to introduce
  them (and remove definition methods). `putiseq` insn is also removed.

* vm_method.c (rb_scope_visibility_get): renamed to
  `vm_scope_visibility_get()` and make it accept `ec`.
  Same for `vm_scope_module_func_check()`.
  These fixes are result of refactoring `vm_define_method`.

* vm_insnhelper.c (rb_vm_get_cref): renamed to `vm_get_cref`
  because of consistency with other functions.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67442 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-05 08:15:11 +00:00
svn e590173547 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67432 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-04 01:34:56 +00:00
k0kubun 22fd30e605 Revert "Introduce inline cache for invokesuper"
This reverts commit d147ad6231.

because failing on CI:
http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1916925

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67431 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-04 01:34:53 +00:00
k0kubun d147ad6231 Introduce inline cache for invokesuper
Looks good in micro benchmark:
```
$ benchmark-driver benchmark/vm2_super.yml -v --rbenv 'before;after'
before: ruby 2.7.0dev (2019-04-03 trunk 67428) [x86_64-linux]
after: ruby 2.7.0dev (2019-04-03 trunk 67428) [x86_64-linux]
last_commit=Introduce inline cache for invokesuper
Calculating -------------------------------------
                         before       after
           vm2_super    19.265M     31.280M i/s -      6.000M times in 0.311447s 0.191813s

Comparison:
                        vm2_super
               after:  31280464.2 i/s
              before:  19264906.2 i/s - 1.62x  slower
```

No significant impact to Optcarrot:
```
$ benchmark-driver benchmark.yml --rbenv='before;after' -v --output=all --repeat-count=12
before: ruby 2.7.0dev (2019-04-03 trunk 67428) [x86_64-linux]
after: ruby 2.7.0dev (2019-04-03 trunk 67428) [x86_64-linux]
last_commit=Introduce inline cache for invokesuper
Calculating -------------------------------------
                                       before                 after
Optcarrot Lan_Master.nes    48.41126024010233     47.28027196127746 fps
                            49.49212664510990     48.75072555488074
                            49.51485564376117     49.20650895701073
                            49.58351773328487     49.24563592659139
                            49.64022392458479     49.26292753046641
                            49.92566235019630     49.44496216868009
                            50.18022198879376     49.45467429762771
                            50.33038373991723     49.52003367348857
                            50.43202877523305     49.69190055704068
                            50.61368587766504     49.79856204866324
                            50.77975014460643     50.27764769510704
                            50.89807360753746     50.35785776505005
```

A little improvement to k0kubun/railsbench?:
```
$ rbenv shell before; RUBYOPT="-v" WARMUP=1 BENCHMARK=30000 bin/bench
ruby 2.7.0dev (2019-04-03 trunk 67428) [x86_64-linux]
Warmup: 1 requests
Benchmark: 30000 requests

Request per second: 897.1 [#/s] (mean)

Percentage of the requests served within a certain time (ms)
  50%    1.01
  66%    1.02
  75%    1.03
  80%    1.04
  90%    1.08
  95%    1.23
  98%    2.10
  99%    5.52
 100%   13.26

$ rbenv shell after; RUBYOPT="-v" WARMUP=1 BENCHMARK=30000 bin/bench
ruby 2.7.0dev (2019-04-03 trunk 67428) [x86_64-linux]
last_commit=Introduce inline cache for invokesuper
Warmup: 1 requests
Benchmark: 30000 requests

Request per second: 913.0 [#/s] (mean)

Percentage of the requests served within a certain time (ms)
  50%    0.99
  66%    1.00
  75%    1.01
  80%    1.02
  90%    1.06
  95%    1.20
  98%    2.12
  99%    5.57
 100%   12.39
```

No significant impact to discourse:
```
* before
categories_admin:
  50: 54
  75: 60
  90: 70
  99: 86
home_admin:
  50: 56
  75: 65
  90: 71
  99: 122
topic_admin:
  50: 64
  75: 73
  90: 79
  99: 117
categories:
  50: 32
  75: 33
  90: 46
  99: 61
home:
  50: 34
  75: 36
  90: 48
  99: 56
topic:
  50: 40
  75: 42
  90: 55
  99: 83

* after
categories_admin:
  50: 59
  75: 66
  90: 80
  99: 149
home_admin:
  50: 54
  75: 58
  90: 70
  99: 96
topic_admin:
  50: 63
  75: 66
  90: 79
  99: 115
categories:
  50: 31
  75: 32
  90: 45
  99: 65
home:
  50: 34
  75: 35
  90: 49
  99: 58
topic:
  50: 40
  75: 42
  90: 55
  99: 78
```

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67429 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-04-03 16:06:03 +00:00
k0kubun c92c0a5935 Prefer using vm_base_ptr rather than cfp->bp
in MJIT implementation.

This allows us to drop cfp->bp by just modifying vm_base_ptr in the
future.

No performance impact:

$ benchmark-driver benchmark.yml --rbenv='before::before --disable-gems --jit;bp_::after --disable-gems --jit;vm_env_ptr::ruby-svn --disable-gems --jit' -v --output=all --repeat-count=12
before: ruby 2.7.0dev (2019-03-24 trunk 67341) +JIT [x86_64-linux]
bp_: ruby 2.7.0dev (2019-03-24 trunk 67342) +JIT [x86_64-linux]
vm_env_ptr: ruby 2.7.0dev (2019-03-25 trunk 67343) +JIT [x86_64-linux]
last_commit=Prefer using vm_base_ptr rather than cfp->bp
Calculating -------------------------------------
                                       before                   bp_            vm_env_ptr
Optcarrot Lan_Master.nes    77.15059205092646     70.18873044267853     69.62171387083328 fps
                            78.75767783870441     77.49867689173411     75.43496867709587
                            79.60102690369321     77.78037687683523     79.36688927929428
                            80.25144236638835     78.74729849101701     80.42363742291455
                            82.22375417165489     80.44265482494045     80.90287243299306
                            82.29166786292619     80.51740049420938     81.81153053252902
                            83.35386925305345     80.91054205210609     81.93562989125176
                            83.39770634366975     81.34550754145043     82.24544621470430
                            83.88523450309972     81.60698516017347     82.76801860263230
                            84.17553130135879     82.69615943446324     83.02530407910871
                            84.42132328119858     83.00969158037691     83.19968539409922
                            84.60731429793329     83.32703363300098     83.81352746019631

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67344 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-25 14:26:11 +00:00
ko1 8dd0fb9039 use cfp->bp more.
cfp->bp was (re-)introduced by Kokubun san, but VM doesn't use it
because I (ko1) want to remove it in a future. But using it make
leave instruction fast because of sp consisntency check.
So now VM uses cfp->bp.

To use cfp->bp, I checked the value and I found that it is not a
"initial value of sp" but a "initial value of ep". Fix this problem
and fix all bp references (this is why bp is renamed to bp_).


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67342 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-25 06:58:50 +00:00
ko1 c671f836b4 add debug counters to count call cache fastpath.
Add counters to count ccf (call cache fastpath) usage.
These counters will help which kind of method dispatch
is important to optimize.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67336 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-22 07:57:26 +00:00
svn a433f2c51b * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67334 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-22 00:21:43 +00:00
ko1 79ddbe9dee optimize method dispatch for lead/kw params.
similar idea to r67315, provide the following optimization
for method dispatch with lead and kw parameters.

(1) add a special branch to check passing kw arguments to
    a method which has lead and kw parameters.
    ex) def foo(x, k:1); end; foo(0, k:1)
(2) add a special branch to check passing no-kw arguments to
    a method which has lead and kw parameters.
    ex) def foo(x, k:1); end; foo(0)

For (1) and (2) cases, provide special dispatchers. For (2) case,
this patch only use the special dispatcher if all default
kw parameters are literal values (nil, 1, and so on. In other case,
kw->default_values does not contains Qundef) (and no required kw
parameters becaseu they don't pass any keyword parameters).

Passing keyword arguments with a hash object is not a scope of
this patch.

Without this patch, (1) and (2) cases use `setup_parameters_complex()`.
Especially, (2) seems frequent case for methods which extend a normal
usecase with keyword parameters (like: `exception: true`).

We can measure the performance with benchmark-driver:
  With methods: def kw k1:1, k2:2; end
                def m; end
  With the following binaries:
    clean-miniruby: unmodified trunk.
    opt_miniruby1: use special branches for lead/kw parameters.
    opt_miniruby2: use special dispatchers for lead/kw parameters.
    opt_cc_miniruby: apply step (2).
  Result with benchmark-driver:

                              m
     opt_miniruby2:  75222278.0 i/s
    clean-miniruby:  73177896.5 i/s - 1.03x  slower
     opt_miniruby1:  62466783.3 i/s - 1.20x  slower

                             kw
     opt_miniruby2:  52044504.4 i/s
     opt_miniruby1:  29142025.7 i/s - 1.79x  slower
    clean-miniruby:  20515235.4 i/s - 2.54x  slower

                      kw k1: 10
     opt_miniruby2:  26492219.5 i/s
     opt_miniruby1:  25409484.9 i/s - 1.04x  slower
    clean-miniruby:  20235113.7 i/s - 1.31x  slower

              kw k1: 10, k2: 20
     opt_miniruby1:  24159534.0 i/s
     opt_miniruby2:  23470527.5 i/s - 1.03x  slower
    clean-miniruby:  17822621.5 i/s - 1.36x  slower


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67333 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-22 00:21:41 +00:00
k0kubun 52bd8f6f68 Share vm_call_iseq_optimizable_p to reduce copy-paste
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67329 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-21 06:25:09 +00:00
k0kubun a8695d5022 Make rb_iseq_only_optparam_p static
because it's not used outside vm*.c, and also having non-static function
without MJIT_STATIC is harmful for mswin JIT system.

I hope this fix mswin test failure starting from r67315.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67328 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-21 05:59:57 +00:00
ko1 e8e1f72d8f remove redundant check.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67319 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-20 20:37:03 +00:00
ko1 df2af1147f fix a type error with a cast for clang.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67318 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-20 20:26:21 +00:00
svn 5c439ebfb0 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67316 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-20 19:57:43 +00:00
ko1 24e03d7e26 optimize method dispatch for lead/opt params.
There is a special optimization for "only lead parameters"
method dispatch using specialized dispatcher functions
`vm_call_iseq_setup_normal_0start...`.
Other cases (opt, rest, post, ...) we don't use specialized
dispatcher and call with `setup_parameters_complex` to
satisfy Ruby's complex parameter specification.

This commit introduce a specialize dispatcher for
methods which use only lead and optional parameters.

Two step improvements:
(1) prepare "lead/opt" only check pass.
    It is to skip the `setup_parameters_complex` function.
(2) introduce specialized dispatcher for only "lead/opt"
    parameters methods (vm_call_iseq_setup_normal_opt_start).

With these improvements, we achieved good micro-benchmark
results:
  With a method: `def opt2 a, b=nil; end`
  With the following binaries:
    clean-miniruby: unmodified trunk.
    opt_miniruby: apply step (1).
    opt_cc_miniruby: apply step (2).
  Result with benchmark-driver:

                        opt2(1)
   opt_cc_miniruby:  42269409.1 i/s
      opt_miniruby:  36304428.3 i/s - 1.16x  slower
    clean-miniruby:  25897409.5 i/s - 1.63x  slower

                     opt2(1, 2)
   opt_cc_miniruby:  45935145.7 i/s
      opt_miniruby:  40513196.9 i/s - 1.13x  slower
    clean-miniruby:  29976057.6 i/s - 1.53x  slower

This improvement may be trivial (difficult to improve practical
cases). However, this is enough small patch so I decide to
introduce it.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67315 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-03-20 19:57:39 +00:00
ko1 b1c1ee7183 change `cfunc->invoker` type for opt.
* vm_insnhelper.c: change `call_cfunc_*` parameters order
  and specify a function type for the passed func ptr.
  This fix reduce the number of asm instructions, such as:
    # before this patch
    0000000000000110 <call_cfunc_0>:
     110:       48 89 fa                mov    %rdi,%rdx
     113:       31 c0                   xor    %eax,%eax
     115:       48 89 f7                mov    %rsi,%rdi
     118:       ff e2                   jmpq   *%rdx
     11a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

    # after this patch
    0000000000000110 <call_cfunc_0>:
     110:       ff e1                   jmpq   *%rcx

  However, this kind of instruction reduction doesn't affect
  any performance because of great CPU architectures :p


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67122 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-02-22 07:25:51 +00:00
shyouhei 232f31ca12 on-smash canary detection
In addition to detect dead canary, we try to detect the very moment
when we smash the stack top.  Requested by k0kubun:
https://twitter.com/k0kubun/status/1085180749899194368


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66981 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-02-01 07:26:39 +00:00
k0kubun 4840771afb vm_insnhelper.c: make VM helpers inline
In r66597, both VM and JIT seem to be made slower:

```
$ benchmark-driver benchmark.yml --rbenv 'r66596::before --disable-gems;r66597::after --disable-gems;r66596+JIT::before --disable-gems --jit;r66597+JIT::after --disable-gems --jit' -v --repeat-count 24
r66596: ruby 2.7.0dev (2018-12-28 trunk 66596) [x86_64-linux]
r66597: ruby 2.7.0dev (2018-12-28 trunk 66597) [x86_64-linux]
r66596+JIT: ruby 2.7.0dev (2018-12-28 trunk 66596) +JIT [x86_64-linux]
r66597+JIT: ruby 2.7.0dev (2018-12-28 trunk 66597) +JIT [x86_64-linux]
Calculating -------------------------------------
                             r66596      r66597  r66596+JIT  r66597+JIT
Optcarrot Lan_Master.nes     55.174      54.620      88.011      85.326 fps

Comparison:
             Optcarrot Lan_Master.nes
              r66596+JIT:        88.0 fps
              r66597+JIT:        85.3 fps - 1.03x  slower
                  r66596:        55.2 fps - 1.60x  slower
                  r66597:        54.6 fps - 1.61x  slower
```

This commit makes JIT's situation a little better. But in 2.7 we seem to
have some other regressions after that, and this can't still resurrect the
2.6.0's performance.

```
$ benchmark-driver benchmark.yml --rbenv 'before::before --disable-gems;after::after --disable-gems;before+JIT::before --disable-gems --jit;after+JIT::after --disable-gems --jit' -v --repeat-count 24
before: ruby 2.7.0dev (2019-01-13 trunk 66808) [x86_64-linux]
after: ruby 2.7.0dev (2019-01-13 trunk 66808) [x86_64-linux]
last_commit=vm_insnhelper.c: make VM helpers inline
before+JIT: ruby 2.7.0dev (2019-01-13 trunk 66808) +JIT [x86_64-linux]
after+JIT: ruby 2.7.0dev (2019-01-13 trunk 66808) +JIT [x86_64-linux]
last_commit=vm_insnhelper.c: make VM helpers inline
Calculating -------------------------------------
                             before       after  before+JIT   after+JIT
Optcarrot Lan_Master.nes     51.710      51.535      83.629      85.486 fps

Comparison:
             Optcarrot Lan_Master.nes
               after+JIT:        85.5 fps
              before+JIT:        83.6 fps - 1.02x  slower
                  before:        51.7 fps - 1.65x  slower
                   after:        51.5 fps - 1.66x  slower
```

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66809 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-14 04:49:28 +00:00
k0kubun 56bf732aaf mjit.c: use boolean type for boolean variables
and functions to clarify the intention and make sure it's not used in a
surprising way (like using 2, 3, ... other than 0, 1 even while it seems
to be a boolean).

This is a retry of r66775. It included some typos...

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66778 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-10 14:31:18 +00:00
k0kubun efd99b5331 Revert "mjit.c: use boolean type for boolean variables"
This reverts commit bb1a1aeab0.

We hit something on ci.rvm.jp, reverting until investigation is done.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66776 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-10 13:29:29 +00:00
k0kubun bb1a1aeab0 mjit.c: use boolean type for boolean variables
and functions to clarify the intention and make sure it's not used in a
surprising way (like using 2, 3, ... other than 0, 1 even while it seems
to be a boolean).

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66775 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2019-01-10 13:21:58 +00:00
shyouhei 91dfdf840b vm_insnhelper.c: USE_FLONUM is always defined
This changeset should fix the 32bit failures.
See also: https://travis-ci.org/ruby/ruby/jobs/472855470


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66601 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-28 03:42:11 +00:00
shyouhei 24b1b433c5 vm_insnhelper.c: delete unused macros
- FIXNUM_2_P: moved to vm_insnhelper.c because that is the only
  place this macro is used.

- FLONUM_2_P: ditto.

- FLOAT_HEAP_P: not used anywhere.

- FLOAT_INSTANCE_P: ditto.

- GET_TOS: ditto.

- USE_IC_FOR_SPECIALIZED_METHOD: ditto.

- rb_obj_hidden_p: ditto.

- REG_A: ditto.

- REG_B: ditto.

- GET_CONST_INLINE_CACHE: ditto.

- vm_regan_regtype: moved inside of VM_COLLECT_USAGE_DETAILS
  because that os the only place this enum is used.

- vm_regan_acttype: ditto.

- GET_GLOBAL: used only once.  Removed with replacing that usage.

- SET_GLOBAL: ditto.

- rb_method_definition_create: declaration moved to
  vm_insnhelper.c because that is the only place this declaration
  makes sense.

- rb_method_definition_set: ditto.

- rb_method_definition_eq: ditto.

- rb_make_no_method_exception: ditto.



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66597 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-28 01:06:04 +00:00
svn 70398311d0 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66566 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-26 00:59:40 +00:00
shyouhei d46ab95376 insns.def: refactor to avoid CALL_METHOD macro
These send and its variant instructions are the most frequently called
paths in the entire process.  Reducing macro expansions to make them
dedicated function called vm_sendish() is the main goal of this
changeset.  It reduces the size of vm_exec_coref from 25,552 bytes to
23,728 bytes on my machine.

I see no significant slowdown.

Fix: [GH-2056]

vanilla: ruby 2.6.0dev (2018-12-19 trunk 66449) [x86_64-darwin15]
ours: ruby 2.6.0dev (2018-12-19 refactor-send 66449) [x86_64-darwin15]
last_commit=insns.def: refactor to avoid CALL_METHOD macro
Calculating -------------------------------------
                         vanilla        ours
   vm2_defined_method     2.645M      2.823M i/s -      6.000M times in 5.109888s 4.783254s
           vm2_method     8.553M      8.873M i/s -      6.000M times in 1.579892s 1.524026s
   vm2_method_missing     3.772M      3.858M i/s -      6.000M times in 3.579482s 3.499220s
vm2_method_with_block     8.494M      8.944M i/s -      6.000M times in 1.589774s 1.509463s
      vm2_poly_method      0.571       0.607 i/s -       1.000 times in 3.947570s 3.733528s
   vm2_poly_method_ov      5.514       5.168 i/s -       1.000 times in 0.408156s 0.436169s
 vm3_clearmethodcache      2.875       2.837 i/s -       1.000 times in 0.783018s 0.793493s

Comparison:
                vm2_defined_method
                 ours:   2822555.4 i/s
              vanilla:   2644878.1 i/s - 1.07x  slower

                        vm2_method
                 ours:   8872947.8 i/s
              vanilla:   8553433.1 i/s - 1.04x  slower

                vm2_method_missing
                 ours:   3858192.3 i/s
              vanilla:   3772296.3 i/s - 1.02x  slower

             vm2_method_with_block
                 ours:   8943825.1 i/s
              vanilla:   8493955.0 i/s - 1.05x  slower

                   vm2_poly_method
                 ours:         0.6 i/s
              vanilla:         0.6 i/s - 1.06x  slower

                vm2_poly_method_ov
              vanilla:         5.5 i/s
                 ours:         5.2 i/s - 1.07x  slower

              vm3_clearmethodcache
              vanilla:         2.9 i/s
                 ours:         2.8 i/s - 1.01x  slower



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66565 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-26 00:59:37 +00:00
shyouhei bfcf0fe787 vm_insnhelper.c: use COLDFUNC
COLDFUNC is introduced in r66228.  Use it for pre-existing
__attribute__((__cold__)) usages.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66538 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-25 03:15:22 +00:00
svn 47127762e7 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66437 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-18 08:33:23 +00:00
ko1 2103333e78 should use defined_class.
* vm_insnhelper.c (vm_call_method_each_type): we should use me->defined_class
  instead of me->owner because me->owner doesn't has correct ancestors list.
  [Bug #15427]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66436 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-18 08:33:20 +00:00
ko1 d3aad15922 Return same ISeq object for one src.
* iseq.c: before this patch, RubyVM::InstructionSequence.of(src) (ISeq in
  short) returns different ISeq (wrapper) objects point to one ISeq internal
  object. This patch changes this behavior to cache created ISeq (wrapper)
  objects and return same ISeq object for an internal ISeq object.

* iseq.h (ISEQ_EXECUTABLE_P): introduced to check executable ISeq objects.

* iseq.h (ISEQ_COMPILE_DATA_ALLOC): reordr setting flag line to avoid
  ISEQ_USE_COMPILE_DATA but compiled_data == NULL case.

* vm_core.h (rb_iseq_t): introduce `rb_iseq_t::wrapper` and
  `rb_iseq_t::aux::exec`.  Move `rb_iseq_t::local_hooks` to
  `rb_iseq_t::aux::exec::local_hooks`.

* test/ruby/test_iseq.rb: add ISeq.of() tests.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66246 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-12-06 10:52:27 +00:00
svn 61c8247d55 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66004 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-26 18:16:54 +00:00
ko1 96990203b7 Support targetting TracePoint [Feature #15289]
* 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
2018-11-26 18:16:39 +00:00
shyouhei b3b827664e vm_insnhelper.c: fix indent [ci skip]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65830 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-20 05:58:12 +00:00
shyouhei 0deee5c0aa vm_insnhelper.c: recv -1 + 3 overflows
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
2018-11-20 04:51:09 +00:00
shyouhei 7f6691ae77 suppress integer overflow warnings
* random.c: annotate rb_hash_start with NO_SANITIZE (seed.key.hash + h
  overflows and that seems intentional)
* bignum.c: avoid (size_t)--
* cont.c: ditto
* util.c: ditto
* vm_insnhelper.c: ditto



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65688 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-13 00:40:52 +00:00
shyouhei 3208db7fb3 vm_insnhelper.c: avoid nevative sp
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
2018-11-12 08:14:09 +00:00
svn 75521b8c1d * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65679 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-12 03:26:44 +00:00
shyouhei 00b8b11858 vm_insnhelper.c: avoid division by zero
same as r65642.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65678 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-12 03:26:39 +00:00
svn f67c0e5671 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65640 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-11-09 01:13:22 +00:00
ko1 191108a6d0 There is a path to use bmethod with ifunc.
* 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
2018-11-09 01:13:20 +00:00
ko1 3cb6952f12 fix passing wrong `passed_bmethod_me`.
* 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
2018-11-09 01:02:13 +00:00
svn d4f1187d31 * remove trailing spaces, expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65455 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30 22:12:12 +00:00
ko1 8f675cdd00 support theap for T_HASH. [Feature #14989]
* 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
2018-10-30 22:11:51 +00:00
svn 437392232a * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65450 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30 21:54:13 +00:00
ko1 312b105d0e introduce TransientHeap. [Bug #14858]
* 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
2018-10-30 21:53:56 +00:00
svn 69b8ffcd5b * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65448 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30 21:02:12 +00:00
ko1 7d359f9b69 revert r65444 and r65446 because of commit miss
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65447 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30 21:01:55 +00:00
svn f926f799e9 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-30 20:46:47 +00:00
ko1 90ac549fa6 introduce TransientHeap. [Bug #14858]
* 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
2018-10-30 20:46:24 +00:00
k0kubun 51a0f04e6b _mjit_compile_send.erb: do not inline tailcall ISeq
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
2018-10-30 14:57:03 +00:00
svn b5425ad780 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65226 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-20 10:45:55 +00:00
mame 6c9a705032 Remove tracecoverage instructions
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
2018-10-20 10:45:48 +00:00
svn 26f53214a8 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65223 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-20 10:20:53 +00:00
k0kubun 00ecff9f78 revert r65213 and r65215
as we didn't agree on the actual implementation yet

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65222 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-20 10:20:49 +00:00
k0kubun 9f43a64c86 vm_insnhelper.c: never cache setinstancevariable twice
same as r65213

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65215 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-20 07:54:34 +00:00
k0kubun 8449f4992b vm_insnhelper.c: never cache getinstancevariable twice
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
2018-10-20 07:43:50 +00:00
ko1 2d4a268cd3 check before access.
* 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
2018-10-19 05:26:35 +00:00
svn 61634b6768 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65108 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-17 07:16:58 +00:00
mame e88fd0606b Remove the level information from throw instruction
It is no longer used.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65107 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-17 07:16:50 +00:00
k0kubun 589d80e7e3 vm_opts.h: share USE_IC_FOR_IVAR as OPT_IC_FOR_IVAR
with mjit_compile.c (tool/ruby_vm/views/_mjit_compile_getivar.erb).

mjit_compile.c: ditto
tool/ruby_vm/views/_mjit_compile_getivar.erb: ditto
vm_opts.h: ditto

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65074 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 11:25:36 +00:00
k0kubun 7bf86ecd70 vm_insnhelper.c: remove obsoleted comment [ci skip]
see also: r65061

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65072 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-10-14 05:50:06 +00:00
k0kubun 0614a6e5d0 vm_insinhelper.c: prefer using inlinable function
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
2018-10-13 14:49:41 +00:00
k0kubun e4eb6e3342 vm_insnhelper.c: finish reverting r63333
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
2018-10-13 14:03:48 +00:00
k0kubun 950d100700 mjit.h: introduce MJIT_STATIC for full mswin JIT support
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
2018-10-07 13:11:27 +00:00
ko1 f0eecb15a3 remove old VM profile counters.
* 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
2018-10-01 06:22:20 +00:00
ko1 aa1023edc4 add debug counters more.
* 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
2018-09-28 03:35:15 +00:00
ko1 df5ec4107d add debug counters more.
* 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
2018-09-28 01:10:43 +00:00
k0kubun 6e62e59eec revert r64847, r64846 and r64839
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
2018-09-26 02:38:45 +00:00
k0kubun e08f418230 revert r64838 and r64839
because some build failures persisted

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64846 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-26 01:11:20 +00:00
k0kubun 08c9f030f6 Revert "Revert r64824 to fix build failure on AppVeyor"
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
2018-09-25 17:19:51 +00:00
k0kubun f00bf24272 Revert r64824 to fix build failure on AppVeyor
AppVeyor msys2/MinGW build started to fail like:
https://ci.appveyor.com/project/ruby/ruby/build/9722/job/b94kixi004klmye3

Until I can investigate that, I revert this for now.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64829 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-25 04:03:35 +00:00
k0kubun fb80f6c7ba insns.def: optimize & and | of Integer [experimental]
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
2018-09-24 12:40:28 +00:00
k0kubun 36265861b9 _mjit_compile_send.erb: refactor code to setup iseq
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
2018-09-24 06:09:55 +00:00
svn 2def52500f * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64807 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-21 10:19:14 +00:00
nobu 7e9ee35fb8 Remove -Wno-parentheses flag.
[Fix GH-1958]

From: Jun Aruga <jaruga@redhat.com>

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64806 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-21 10:19:10 +00:00
svn a4675d9d80 * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64776 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-18 13:52:08 +00:00
k0kubun e7db9df982 vm_insnhelper.c: always use bool-ish value
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
2018-09-18 13:52:06 +00:00
svn 36850b789c * expand tabs.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64773 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-18 12:48:31 +00:00
k0kubun 62327bb6ff vm_insnhelper.h: rename CI_SET_FASTPATH to CC_SET_FASTPATH
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
2018-09-18 12:48:28 +00:00
k0kubun 519c62fdc2 vm_insnhelper.h: drop OPT_CALL_FASTPATH macro support
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
2018-09-13 12:29:57 +00:00
shyouhei 02b52b2733 make opt_str_freeze leaf
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
2018-09-12 03:39:36 +00:00
shyouhei 33c8171c65 make opt_case_dispatch leaf
This instruction can be written without rb_funcall. It not only boosts
performance of case statements, but also makes room of future JIT
improvements.  Because opt_case_dispatch is about optimization this
should not be a bad thing to have.

----

trunk: ruby 2.6.0dev (2018-09-05 trunk 64634) [x86_64-darwin15]
ours: ruby 2.6.0dev (2018-09-12 leaf-insn 64688) [x86_64-darwin15]
last_commit=make opt_case_dispatch leaf
Calculating -------------------------------------
                          trunk        ours
        vm2_case_lit      1.366       2.012 i/s -       1.000 times in 0.731839s 0.497008s

Comparison:
                     vm2_case_lit
                ours:         2.0 i/s
               trunk:         1.4 i/s - 1.47x  slower



git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64689 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-12 01:55:00 +00:00
k0kubun 24e30ef76e transform_mjit_header.rb: add static to Init_*
as well, to make CI succeed with VM_CHECK_MODE > 1.

vm_insnhelper.c: drop unnecessary MJIT_HEADER ifdef. This is intended to
be ignored by having `static inline`. Removing that by macro would be
helpful for minimizing compilation time, but the impact is not so big
and having many MJIT_HEADER check would be bad for maintainability.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64682 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-11 11:26:15 +00:00
nobu 6f7fafbf00 random.c: prefixed fill_random_bytes
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64680 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-11 11:05:20 +00:00
k0kubun db40f67849 vm_insnhelper.c: stop unnecessarily using rb_sprintf
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64679 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-11 11:01:18 +00:00
k0kubun 30011cbb7a vm_insnhelper.c: fix -Wformat-security on rb_bug
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64678 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-11 10:58:33 +00:00
shyouhei c2bfb4e93c add new instruction attribute called leaf
An instruction is leaf if it has no rb_funcall inside.  In order to
check this property, we introduce stack canary which is a random
number collected at runtime.  Stack top is always filled with this
number and checked for stack smashing operations, when VM_CHECK_MODE.
[GH-1947]


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64677 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-09-11 09:48:58 +00:00
mame 100bf27574 compile.c: remove tracecoverage instruction for line coverage
Line coverage was based on special instruction "tracecoverage".
Now, instead, it uses the mechanism of trace hook [Feature #14104].

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64509 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-22 11:09:47 +00:00
k0kubun 8076928003 vm_insnhelper.c: revert r64280
This commit caused test-all failure with --jit-wait.
I don't know the reason yet, but let me revert it to normalize CI.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64314 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-12 00:30:04 +00:00
k0kubun c3b2546411 vm_insnhelper.c: drop duplicated inline
to resolve warning:
c:\projects\ruby\vm_insnhelper.c(1661) : warning C4141: 'inline' : used more than once

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64312 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-11 23:40:12 +00:00
k0kubun b4b012c529 _mjit_compile_send.erb: refactor to share vm_call_iseq_setup_normal
implementation. This had no major performance impact by effort to keep
them inlined.

vm_insnhelper.c: ditto

mjit_compile.c: just update the comment about opt_pc=0 assumption

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64280 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-11 03:38:38 +00:00
mame 2138f24c70 insns.def (invokesuper): remove a dummy receiever flag hack for ZSUPER
This is just a refactoring.

The receiver of "invokesuper" was a boolean to represent if it is ZSUPER
or not.  This was used in vm_search_super_method to prohibit ZSUPER call
in define_method. (It is currently prohibited because of the limitation
of the implementation.)

This change removes the hack by introducing an explicit flag,
VM_CALL_SUPER, to signal the information.  Now, the implementation of
"invokesuper" is consistent with "send" instruction.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64268 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-08-10 07:45:16 +00:00
k0kubun ba8413c27c vm.c: simplify the implementation of r64031
because such inconsistency may result in the regression fixed in r64034.

vm_exec is not touched since renaming it may be controversial...

vm_args.c: ditto.
vm_eval.c: ditto.
vm_insnhelper.c: ditto.
vm_method.c: ditto.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64035 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-24 15:17:08 +00:00
k0kubun c86fc2bba5 mjit_compile.c: reduce sp motion on JIT
This retries r62655, which was reverted at r63863 for r63763.

tool/ruby_vm/views/_mjit_compile_insn.erb: revert the revert.
tool/ruby_vm/views/_mjit_compile_insn_body.erb: ditto.
tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb: ditto.
tool/ruby_vm/views/_mjit_compile_send.erb: ditto.
tool/ruby_vm/views/mjit_compile.inc.erb: ditto.

tool/ruby_vm/views/_insn_entry.erb: revert half of r63763. The commit
  was originally reverted since changing pc motion was bad for tracing,
  but changing sp motion was totally fine. For JIT, I wanna resurrect
  the sp motion change in r62051.
tool/ruby_vm/models/bare_instructions.rb: ditto.
insns.def: ditto.
vm_insnhelper.c: ditto.
vm_insnhelper.h: ditto.

* benchmark

$ benchmark-driver benchmark.yml --rbenv 'before;after;before --jit;after --jit' --repeat-count 12 -v
before: ruby 2.6.0dev (2018-07-19 trunk 63998) [x86_64-linux]
after: ruby 2.6.0dev (2018-07-19 add-sp 63998) [x86_64-linux]
last_commit=mjit_compile.c: reduce sp motion on JIT
before --jit: ruby 2.6.0dev (2018-07-19 trunk 63998) +JIT [x86_64-linux]
after --jit: ruby 2.6.0dev (2018-07-19 add-sp 63998) +JIT [x86_64-linux]
last_commit=mjit_compile.c: reduce sp motion on JIT
Calculating -------------------------------------
                             before       after  before --jit  after --jit
Optcarrot Lan_Master.nes     51.354      50.238        70.010       72.139 fps

Comparison:
             Optcarrot Lan_Master.nes
             after --jit:        72.1 fps
            before --jit:        70.0 fps - 1.03x  slower
                  before:        51.4 fps - 1.40x  slower
                   after:        50.2 fps - 1.44x  slower

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63999 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-19 13:25:22 +00:00
k0kubun 80dac806cc revert r63988
Due to trunk-mjit CI failures:
http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1130097
http://ci.rvm.jp/results/trunk-mjit@silicon-docker/1130196

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63991 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-17 16:20:15 +00:00
k0kubun 6a4bb345df mjit_compile.c: resurrect local variable stack
This optimization was reverted on r63863, but this commit resurrects the
optimization to skip some sp motions on JIT execution.

tool/ruby_vm/views/_mjit_compile_insn_body.erb: ditto
tool/ruby_vm/views/_mjit_compile_insn.erb: ditto

insns.def: resurrect handles_frame as handles_stack, which was deleted
on r63763.
tool/ruby_vm/models/bare_instructions.rb: ditto

vm_insnhelper.c: prevent moving sp outside insns.def to allow modifying
it by JIT.

* Optcarrot benchmark

$ benchmark-driver benchmark.yml --rbenv 'before --jit;after --jit' --repeat-count 12 -v
before --jit: ruby 2.6.0dev (2018-07-17 trunk 63987) +JIT [x86_64-linux]
after --jit: ruby 2.6.0dev (2018-07-17 local-stack 63987) +JIT [x86_64-linux]
last_commit=mjit_compile.c: resurrect local variable stack
Calculating -------------------------------------
                         before --jit  after --jit
Optcarrot Lan_Master.nes       70.518       72.144 fps

Comparison:
             Optcarrot Lan_Master.nes
             after --jit:        72.1 fps
            before --jit:        70.5 fps - 1.02x  slower

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63988 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-07-17 15:09:41 +00:00
shyouhei 6b534134a7 give up insn attr handles_frame
I introduced this mechanism in r62051 to speed things up. Later it
was reported that the change causes problems.  I searched for
workarounds but nothing seemed appropriate.  I hereby officially
give it up.  The idea to move ADD_PC around was a mistake.

Fixes [Bug #14809] and [Bug #14834].

Signed-off-by: Urabe, Shyouhei <shyouhei@ruby-lang.org>


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63763 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-06-27 09:28:09 +00:00
shyouhei 529af9c821 refactor move logics out of insns.def
This is a pure refactoring.  I see no difference in this change.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63756 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-06-27 01:10:02 +00:00
ko1 331f46a250 add assertion to vm_search_method()
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63706 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-06-20 18:10:09 +00:00
k0kubun 6dd4657fc2 _mjit_compile_send.erb: retry inlining attr_reader
This reverts r63249 (revert r63212) and fixes a bug in it. The test to
prevent the bug is added as well.

vm_insnhelper.c: add `index` argument to vm_getivar. The argument is
created so that MJIT can pass the value of `cc->aux.index` on compilation
time.  The cache invalidation in _mjit_compile_send_guard.erb is only
working for the cache value on compilation time.
Note: As `index` is always passed as constant and it's force-inlined,
the performance of `vm_getivar` won't be degraded in VM.

_mjit_compile_send_guard.erb: New. Used to invalidate inlined values of cc.
common.mk: update dependencies for _mjit_compile_send_guard.erb

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@63333 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-05-03 08:47:32 +00:00
tenderlove 9e26858e8c Reverting r62775, this should fix i686 builds
We need to mark default values for kwarg methods.  This also fixes
Bootsnap.  IBF iseq loading needed to mark iseqs as "having markable
objects".

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62851 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-19 18:21:54 +00:00
naruse 94c40622f5 Revert "Add direct marking on iseq operands"
This reverts commit r62706.

It causes SEGV on i686-linux (debian) and armv7l-linux-eabihf:
http://www.rubyist.net/~akr/chkbuild/debian/ruby-trunk/log/20180309T204300Z.diff.html.gz
http://rubyci.s3.amazonaws.com/scw-9d6766/ruby-trunk/log/20180309T211706Z.diff.html.gz

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62775 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-16 07:59:10 +00:00
tenderlove 8952964976 Add direct marking on iseq operands
Directly marking iseq operands allows us to eliminate the "mark array"
stored on ISEQ objects, which will reduce the amount of memory ISEQ
objects consume.  This patch changes the iseq mark function to:

* Directly marks ISEQ operands
* Iterate over and mark child ISEQs

It also introduces two flags on the ISEQ object.  In order to mark
instruction operands, we have to disassemble the instructions and find
the instruction parameters and types.  Instructions may also be
translated to jump addresses.  Instruction sequences may get marked by
the GC *while* they're mid flight (being compiled).  The
`ISEQ_TRANSLATED` flag is used to indicate whether or not the
instructions have been translated to jump addresses so that when we
decode the instructions we know whether or not we need to go from jump
location back to original instruction or not.

Not all ISEQ objects have any markable objects embedded in their
instructions.  We can detect whether or not an ISEQ has markable objects
in the instructions at compile time.  If the instructions contain
markable objects, we set a flag `ISEQ_MARKABLE_ISEQ` on the ISEQ object.
This means that during the mark phase, we can skip decompilation if the
flag is *not* set.  In other words, we can avoid decompilation of we
know in advance there is nothing to mark.

`once` instructions have an operand that contains the result of a
one-time compilation of a regex.  Before this patch, that operand was
called an "inline cache", even though the struct was actually an "inline
storage".  This patch changes the operand to be an "inline storage" so
that we can differentiate between caches that need marking (the inline
storage) and caches that don't need marking (inline cache).

[ruby-core:84909]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62706 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-09 20:11:45 +00:00
nobu 51c6022040 vm_insnhelper.c: blockparamproxy in rescue
* vm_insnhelper.c (vm_call_opt_block_call): get block handler from
  the method local frame.  fix segfault at calling the proxy in
  rescue.  http://twitter.com/wannabe53/status/970955247626567680

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62680 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-06 15:14:22 +00:00
k0kubun 8a15857a7f mjit_compile.c: use local variables for stack
if catch_except_p is FALSE. If catch_except_p is TRUE, stack values
should be on VM's stack when exception is thrown and the JIT-ed frame
is re-executed by VM's exception handler. If it's FALSE, the JIT-ed
frame won't be re-executed and don't need to keep values on VM's stack.

Using local variables allows us to reduce cfp->sp motion. Moving cfp->sp
is needed only for insns whose handles_frame? is false. So it improves
performance.

_mjit_compile_insn.erb: Prepare `stack_size` variable for GET_SP,
STACK_ADDR_FROM_TOP, TOPN macros. Share pc and sp motion partial view.
Use cancel handler created in mjit_compile.c.

_mjit_compile_send.erb: ditto. Also, when iseq->body->catch_except_p is
TRUE, this stops to call mjit_exec directly. I described the reason in
vm_insnhelper.h's comment for EXEC_EC_CFP.

_mjit_compile_pc_and_sp.erb: Shared logic for moving sp and pc. As you
can see from thsi file, when status->local_stack_p is TRUE and
insn.handles_frame? is false, moving sp is skipped. But if
insn.handles_frame? is true, values should be rolled back to VM's stack.
common.mk: add dependency for the file

_mjit_compile_insn_body.erb: Set sp value before canceling JIT on
DISPATCH_ORIGINAL_INSN. Replace GET_SP, STACK_ADDR_FROM_TOP, TOPN macros
for the case ocal_stack_p is TRUE and insn.handles_frame? is false.
In that case, values are not available on VM's stack and those macros
should be replaced.

mjit_compile.inc.erb: updated comments of macros which are supported by
JIT compiler. All references to `cfp->sp` should be replaced and thus
INC_SP, SET_SV, PUSH are no longer supported for now, because they are
not used now.

vm_exec.h: moved EXEC_EC_CFP definition to vm_insnhelper.h because it's
tighly coupled to CALL_METHOD.

vm_insnhelper.h: Have revised EXEC_EC_CFP definition moved from vm_exec.h.
Now it triggers mjit_exec for VM, and has the guard for catch_except_p
on JIT-ed code. See comments for details. CALL_METHOD delegates
triggering mjit_exec to EXEC_EC_CFP.

insns.def: Stopped using EXEC_EC_CFP for the case we don't want to
trigger mjit_exec. Those insns (defineclass, opt_call_c_function) are
not supported by JIT and it's safe to use RESTORE_REGS(), NEXT_INSN().
expandarray is changed to pass GET_SP() to replace the macro in
_mjit_compile_insn_body.erb.

vm_insnhelper.c: change to take sp for the above reason.

[close https://github.com/ruby/ruby/pull/1828]

This patch resurrects the performance which was attached in
[Feature #14235].

* Benchmark

Optcarrot (with configuration for benchmark_driver.gem)
https://github.com/benchmark-driver/optcarrot

$ benchmark-driver benchmark.yml --verbose 1 --rbenv 'before;before+JIT::before,--jit;after;after+JIT::after,--jit' --repeat-count 10
before: ruby 2.6.0dev (2018-03-04 trunk 62652) [x86_64-linux]
before+JIT: ruby 2.6.0dev (2018-03-04 trunk 62652) +JIT [x86_64-linux]
after: ruby 2.6.0dev (2018-03-04 local-variable.. 62652) [x86_64-linux]
last_commit=mjit_compile.c: use local variables for stack
after+JIT: ruby 2.6.0dev (2018-03-04 local-variable.. 62652) +JIT [x86_64-linux]
last_commit=mjit_compile.c: use local variables for stack
Calculating -------------------------------------
                         before  before+JIT       after   after+JIT
           optcarrot     53.552      59.680      53.697      63.358 fps

Comparison:
                        optcarrot
           after+JIT:        63.4 fps
          before+JIT:        59.7 fps - 1.06x  slower
               after:        53.7 fps - 1.18x  slower
              before:        53.6 fps - 1.18x  slower

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62655 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-03-04 07:04:40 +00:00
nobu ef04d43fbb vm_insnhelper.c: no insns_info in jit
* vm_insnhelper.c: instructions info are not used in jit source
  code.  resolved a warning by transform_mjit_header.rb.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62505 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-21 00:55:22 +00:00
nobu 49f52937bd vm.c: disable dtrace in jit source
* vm.c: include dummy dtrace probes header in jit header.

* vm_insnhelper.c: probes headers are included by vm.c.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62489 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-20 03:15:33 +00:00
nobu def3714be2 prefixed functions exported for mjit
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62445 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-17 01:30:05 +00:00
nobu 8cdac548c5 vm_insnhelper.c: rb_autoloading_value flag
* vm_insnhelper.c (vm_get_ev_const): add flag argument of
  `rb_autoloading_value`.

* constant.h (rb_autoloading_value): moved the declaration from
  vm_core.h for `rb_const_flag_t`.  [ruby-core:85516] [Bug #14469]

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62394 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2018-02-13 09:34:43 +00:00