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

1072 Коммитов

Автор SHA1 Сообщение Дата
Koichi Sasada 31748e69c8 CI can be NULL.
Unused CI (introduced from peephole optimization, etc) can be NULL
so introduce NULL check.
2020-02-22 10:27:44 +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 56d33b3ea8
Fixed missing `return`
Get rid of double writing.
2020-02-20 13:39:27 +09:00
卜部昌平 7aa3f1fe69 printf can be a macro
Namely glibc has this macro on -DFORTIFY_SOURCE.  We have to prevent
macro redefinition with different macro body.
2020-02-20 11:46:54 +09:00
Nobuyoshi Nakada 0bfa479c52
Split the optimizable range item conditions 2020-02-16 13:47:18 +09:00
Masataka Pocke Kuwabara 5278294230 Reduce begin-less/end-less range allocation
```
$ cat test.yaml
prelude: |
    def endless
      1..
    end

    def beginless
      ..1
    end

    def endless_substr(str)
      str[1..]
    end

benchmark:
    endless: endless
    beginless: beginless
    endless_substr: "endless_substr('foo')"

$ RBENV_VERSION=trunk ruby -v
ruby 2.8.0dev (2020-02-15T12:52:03Z master 961630126b) [x86_64-linux]
$ RBENV_VERSION=patched ruby -v
ruby 2.8.0dev (2020-02-15T12:52:03Z origin/master 961630126b) [x86_64-linux]

$ benchmark-driver test.yaml --rbenv 'patched;trunk'
Warming up --------------------------------------
             endless    45.948M i/s -     46.076M times in 1.002782s (21.76ns/i, 26clocks/i)
           beginless    49.986M i/s -     50.237M times in 1.005037s (20.01ns/i, 24clocks/i)
      endless_substr     8.067M i/s -      8.187M times in 1.014936s (123.96ns/i, 148clocks/i)
Calculating -------------------------------------
                        patched       trunk
             endless   115.679M     21.500M i/s -    137.843M times in 1.191597s 6.411398s
           beginless   112.599M     22.060M i/s -    149.957M times in 1.331778s 6.797768s
      endless_substr     8.888M      6.760M i/s -     24.201M times in 2.722995s 3.580038s

Comparison:
                          endless
             patched: 115679391.9 i/s
               trunk:  21499711.2 i/s - 5.38x  slower

                        beginless
             patched: 112598731.5 i/s
               trunk:  22059673.0 i/s - 5.10x  slower

                   endless_substr
             patched:   8887513.1 i/s
               trunk:   6759886.2 i/s - 1.31x  slower
```
2020-02-16 02:37:12 +09:00
Jeremy Evans 7a288df7b8 Make yield in singleton class definitions in methods a SyntaxError
This behavior was deprecated in 2.7 and scheduled to be removed
in 3.0.

Calling yield in a class definition outside a method is now a
SyntaxError instead of a LocalJumpError, as well.
2020-02-11 12:44:23 -08:00
NagayamaRyoga a2845adb49 compile.c: Drop obj_list from ibf_dump
[Feature #16505]
2020-02-09 11:33:38 -05:00
NagayamaRyoga e443f23576 compile.c: Drop iseq_list from ibf_dump
[Feature #16505]
2020-02-09 11:33:38 -05:00
NagayamaRyoga 6e5e6a40c4 Deduplicate objects efficiently when dumping iseq to binary
We were inefficient in cases where there are a lot of duplicates due to
the use of linear search. Use a hash table instead.

These cases are not that rare in the wild.

[Feature #16505]
2020-02-09 11:33:38 -05:00
Seiei Miyagi 11963da9e8 Check type of empty keyword [Bug #16603]
Co-authored-by: Yusuke Endoh <mame@ruby-lang.org>
2020-02-03 17:54:44 +09:00
Yusuke Endoh fac4385f01 compile.c: remove a unused variable 2020-02-01 00:04:45 +09:00
Nobuyoshi Nakada 3893a8dd42
Optimized branches in pattern matching 2020-01-30 17:47:09 +09:00
Koichi Sasada 9f460e017b move internal/debug.h definitions to internal.h
Debug utilities should be accessible from any internal code.
2020-01-03 04:46:51 +09: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
Koichi Sasada 9808e01090 export a function for MJIT.
rb_iseq_complete() can be used by MJIT.
2019-12-25 14:37:53 +09:00
Koichi Sasada d9bf9c572f take care of USE_LAZY_LOAD=1.
On USE_LAZY_LOAD=1, the iseq should be loaded. So rb_iseq_check()
is needed. Furthermore, now lazy loading with builtin_function_table
is not supported, so it should cancel lazy loading.
2019-12-25 14:12:33 +09:00
Nobuyoshi Nakada d2ac6d4d9f
Manage deprecation warning by the flag 2019-12-22 14:45:42 +09:00
Yusuke Endoh 75acbd5f00 compile.c: avoid newarraykwsplat for arguments
`foo(*rest, post, **empty_kw)` is compiled like
`foo(*rest + [post, **empty_kw])`, and `**empty_kw` is removed by
"newarraykwsplat" instruction.
However, the method call still has a flag of KW_SPLAT, so "post" is
considered as a keyword hash, which caused a segfault.
Note that the flag cannot be removed if "empty_kw" is not always empty.

This change fixes the issue by compiling arguments with "newarray"
instead of "newarraykwsplat".

[Bug #16442]
2019-12-22 03:35:29 +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
Koichi Sasada 97a17a51b8 readable function names for inline functions.
Now, C functions written by __builtin_cexpr!(code) and others are
named as "__builtin_inline#{n}". However, it is difficult to know
what the function is. This patch rename them into
"__builtin_foo_#{lineno}" when cexpr! is in 'foo' method.
2019-12-13 17:55:45 +09:00
卜部昌平 35eb12c063 add casts
%p is for void *.  Becuase fprintf is a function with variadic arguments
automatic cast from any pointer to void * does not work.  We have to be
explicit.
2019-12-12 14:19:36 +09:00
Yusuke Endoh 156fb72d70 vm_args.c (rb_warn_check): Use iseq_unique_id instead of its pointer
(This is the second try of 036bc1da6c6c9b0fa9b7f5968d897a9554dd770e.)

If iseq is GC'ed, the pointer of iseq may be reused, which may hide a
deprecation warning of keyword argument change.

http://ci.rvm.jp/results/trunk-test1@phosphorus-docker/2474221

```
1) Failure:
TestKeywordArguments#test_explicit_super_kwsplat [/tmp/ruby/v2/src/trunk-test1/test/ruby/test_keyword.rb:549]:
--- expected
+++ actual
@@ -1 +1 @@
-/The keyword argument is passed as the last hash parameter.* for `m'/m
+""
```

This change ad-hocly adds iseq_unique_id for each iseq, and use it
instead of iseq pointer.  This covers the case where caller is GC'ed.
Still, the case where callee is GC'ed, is not covered.

But anyway, it is very rare that iseq is GC'ed.  Even when it occurs, it
just hides some warnings.  It's no big deal.
2019-12-09 15:22:48 +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
Yusuke Endoh f9e5c74cd2 compile.c: stop wrong peephole optimization when covearge is enabled
jump-jump optimization ignores the event flags of the jump instruction
being skipped, which leads to overlook of line events.

This changeset stops the wrong optimization when coverage measurement is
neabled and when the jump instruction has any event flag.

Note that this issue is not only for coverage but also for TracePoint,
and this change does not fix TracePoint.
However, fixing it fundamentally is tough (which requires revamp of
the compiler).  This issue is critical in terms of coverage measurement,
but minor for TracePoint (ko1 said), so we here choose a stopgap
measurement.

[Bug #15980] [Bug #16397]

Note for backporters: this changeset can be viewed by `git diff -w`.
2019-12-04 10:40:54 +09:00
Yusuke Endoh f9754f0ea0 compile.c: trivial refactoring
Use `for` instead of `while` to make it explicit that it is a traverse
of bytecode.
2019-12-04 08:22:48 +09:00
Koichi Sasada a3e6f52c17 rename __builtin_inline!(code) and introduce others.
rename __builtin_inline!(code) to __builtin_cstmt(code).
Also this commit introduce the following inlining C code features.

* __builtin_cstmt!(STMT)

(renamed from __builtin_inline!)

Define a function which run STMT implicitly and call this function at
evatuation time. Note that you need to return some value in STMT.
If there is a local variables (includes method parameters), you can
read these values.

  static VALUE func(ec, self) {
    VALUE x = ...;
    STMT
  }

Usage:
  def double a
    # a is readable from C code.
    __builtin_cstmt! 'return INT2FIX(FIX2INT(a) * 2);'
  end

* __builtin_cexpr!(EXPR)

Define a function which invoke EXPR implicitly like `__builtin_cstmt!`.
Different from cstmt!, which compiled with `return EXPR;`.
(`return` and `;` are added implicitly)

  static VALUE func(ec, self) {
    VALUE x = ...;
    return EXPPR;
  }

Usage:
  def double a
    __builtin_cexpr! 'INT2FIX(FIX2INT(a) * 2)'
  end

* __builtin_cconst!(EXPR)

Define a function which invoke EXPR implicitly like cexpr!.
However, the function is called once at compile time, not evaluated time.
Any local variables are not accessible (because there is no local variable
at compile time).

Usage:
  GCC = __builtin_cconst! '__GNUC__'

* __builtin_cinit!(STMT)

STMT are writtein in auto-generated code.
This code does not return any value.

Usage:

  __builtin_cinit! '#include <zlib.h>'
  def no_compression?
    __builtin_cconst! 'Z_NO_COMPRESSION ? Qtrue : Qfalse'
  end
2019-11-27 03:55:28 +09:00
卜部昌平 0e8219f591 make functions static
These functions are used from within a compilation unit so we can
make them static, for better binary size.  This changeset reduces
the size of generated ruby binary from 26,590,128 bytes to
26,584,472 bytes on my macihne.
2019-11-19 12:36:19 +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
Jeremy Evans ab42e5a486 More fixes for $SAFE/taint post merging 2019-11-18 01:00:25 +02: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
Nobuyoshi Nakada fb6a489af2
Revert "Method reference operator"
This reverts commit 67c5747369.
[Feature #16275]
2019-11-12 17:24:48 +09:00
Nobuyoshi Nakada 2de3feab44
Get rid of `__` prefix which is presereved by C standard 2019-11-12 16:09:36 +09:00
Koichi Sasada 3141642380 __builtin_inline!
Add an experimental `__builtin_inline!(c_expression)` special intrinsic
which run a C code snippet.
In `c_expression`, you can access the following variables:
  * ec (rb_execution_context_t *)
  * self (const VALUE)
  * local variables (const VALUE)
Not that you can read these variables, but you can not write them.
You need to return from this expression and return value will be a
result of __builtin_inline!().

Examples:
  `def foo(x) __builtin_inline!('return rb_p(x);'); end` calls `p(x)`.
  `def double(x) __builtin_inline!('return INT2NUM(NUM2INT(x) * 2);')`
  returns x*2.
2019-11-11 16:47:50 +09:00
Nobuyoshi Nakada 11e21f1982
Make prefix static 2019-11-08 23:00:36 +09:00
Koichi Sasada 83c563cfa4 cstr -> bytes
rb_iseq_ibf_load_cstr() accepts bytes, but not NUL-terminate
C string. To make it clear, rename it to _bytes.
2019-11-08 16:16:25 +09:00
卜部昌平 7661150109 revival of __func__
dad2abc69f deleted __func__ but ruby
already use this feature under RUBY_FUNCTION_NAME_STRING macro.
Use it.
2019-11-08 11:12:01 +09:00
Koichi Sasada dad2abc69f do not use __func__.
Microsoft Visual Studio 12.0 doesn't support it.
2019-11-08 10:03:19 +09:00
Koichi Sasada 46b9ca6c54 fix type 2019-11-08 09:26:16 +09:00
git 4c00b9e8eb * remove trailing spaces. [ci skip] 2019-11-08 09:09:47 +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
Lourens Naudé 65744fb19e Right size the iseq coverage branches tmp array - initializes with 5 elements 2019-10-29 11:30:49 +09:00
Aaron Patterson 339a891c7d
Pin keys of this st_table 2019-10-28 11:47:09 -07:00
Koichi Sasada 58b363bf0d respect `param.flags.ruby2_keywords` at to_binary.
`param.flags.ruby2_keywords` is not store/load correctly at to_binary
so restore this flag correctly.
2019-10-25 04:39:22 +09:00
Nobuyoshi Nakada b609bdeb53
Define arguments forwarding as `ruby2_keywords` style
Get rid of these redundant and useless warnings.

```
$ ruby -e 'def bar(a) a; end; def foo(...) bar(...) end; foo({})'
-e:1: warning: The last argument is used as the keyword parameter
-e:1: warning: for `foo' defined here
-e:1: warning: The keyword argument is passed as the last hash parameter
-e:1: warning: for `bar' defined here
```
2019-10-25 01:16:05 +09:00
Alan Wu f1de438380 Use CPDEBUG for debug code 2019-10-24 18:03:42 +09: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 afab8122c3
Fix the exception when CPDEBUG 2019-10-23 02:04:36 +09:00
Alan Wu 9c553139ae Fix build for CPDEBUG=1
The declarations went out-of-sync in dcfb7f6.
2019-10-22 12:21:02 +09:00