Commit graph

65 commits

Author SHA1 Message Date
Takashi Kokubun
478e0fc710
YJIT: Replace Array#each only when YJIT is enabled (#11955)
* YJIT: Replace Array#each only when YJIT is enabled

* Add comments about BUILTIN_ATTR_C_TRACE

* Make Ruby Array#each available with --yjit as well

* Fix all paths that expect a C location

* Use method_basic_definition_p to detect patches

* Copy a comment about C_TRACE flag to compilers

* Rephrase a comment about add_yjit_hook

* Give METHOD_ENTRY_BASIC flag to Array#each

* Add --yjit-c-builtin option

* Allow inconsistent source_location in test-spec

* Refactor a check of BUILTIN_ATTR_C_TRACE

* Set METHOD_ENTRY_BASIC without touching vm->running
2024-11-04 11:14:28 -05:00
Nobuyoshi Nakada
0283b5ddb4 Check syntax warnings in built-in scripts 2024-09-25 11:18:41 +09:00
Nobuyoshi Nakada
b61e3a6218 Write rbinc files at once
Unexpected error can make empty files which result in unclear
compilation errors.
2024-07-18 19:34:10 +09:00
Koichi Sasada
9180e33ca3 show warning for unused block
With verbopse mode (-w), the interpreter shows a warning if
a block is passed to a method which does not use the given block.

Warning on:

* the invoked method is written in C
* the invoked method is not `initialize`
* not invoked with `super`
* the first time on the call-site with the invoked method
  (`obj.foo{}` will be warned once if `foo` is same method)

[Feature #15554]

`Primitive.attr! :use_block` is introduced to declare that primitive
functions (written in C) will use passed block.

For minitest, test needs some tweak, so use
ea9caafc07
for `test-bundled-gems`.
2024-04-15 12:08:07 +09:00
Takashi Kokubun
c84237f953
Rewrite Array#each in Ruby using Primitive (#9533) 2024-01-23 20:09:57 +00:00
Takashi Kokubun
27c1dd8634
YJIT: Allow inlining ISEQ calls with a block (#9622)
* YJIT: Allow inlining ISEQ calls with a block

* Leave a TODO comment about u16 inline_block
2024-01-23 19:36:23 +00:00
Nobuyoshi Nakada
127b19ab56 Use line numbers as builtin-index
The order of iseq may differ from the order of tokens, typically
`while`/`until` conditions are put after the body.

These orders can match by using line numbers as builtin-indexes, but
at the same time, it introduces the restriction that multiple `cexpr!`
and `cstmt!` cannot appear in the same line.

Another possible idea is to use `RubyVM::AbstractSyntaxTree` and
`node_id` instead of ripper, with making BASERUBY 3.1 or later.
2024-01-22 19:39:34 +09:00
Takashi Kokubun
e37a37e696 Drop obsoleted BUILTIN_ATTR_NO_GC attribute
The thing that has used this in the past was very buggy, and we've never
revisied it. Let's remove it until we need it again.
2024-01-16 17:27:53 -08:00
John Hawthorn
18573b8d05 Avoid reading unused lvars in Primitive.cexpr
Previously on builds with optimizations disabled, this could result in
an out of bounds read. When we had all of:
* built with -O0
* Leaf builtin
* Primitive.mandatory_only
* "no args builtin", called by vm_call_single_noarg_inline_builti
* The stack is escaped to the heap via binding or a proc

This is because mk_builtin_loader generated reads for all locals
regardless of whether they were used and in the case we generated a
mandatory_only iseq that would include more variables than were actually
available.

On optimized builds, the invalid accesses would be optimized away, and
this also was often unnoticed as the invalid access would just hit
another part of the stack unless it had been escaped to the heap.

The fix here is imperfect, as this could have false positives, but since
Primitive.cexpr! is only available within the cruby codebase itself
that's probably fine as a proper fix would be much more challenging (the
only false positives we found were in rjit.rb).

Fixes [Bug #20178]

Co-authored-by: Adam Hess <HParker@github.com>
2024-01-11 16:53:20 -08:00
Takashi Kokubun
70ba310212
YJIT: Introduce no_gc attribute (#7511) 2023-03-14 15:38:58 -07:00
Takashi Kokubun
50c5f94ed7 RJIT: Introduce constants under RubyVM::RJIT::C 2023-03-11 21:48:28 -08:00
Takashi Kokubun
94da5f7c36 Rename builtin attr :inline to :leaf 2023-03-11 14:25:12 -08:00
Takashi Kokubun
0c0c88d383 Support multiple attributes with Primitive.attr! 2023-03-11 14:19:46 -08:00
Takashi Kokubun
3a02c7818c
Change the syntax of Primitive.attr! to Symbol (#7501) 2023-03-10 23:40:57 -08:00
Takashi Kokubun
e93e780f3d Remove MJIT's builtin function compiler 2023-03-07 23:16:24 -08:00
Takashi Kokubun
23ec248e48 s/mjit/rjit/ 2023-03-06 23:44:01 -08:00
Nobuyoshi Nakada
d752cf7601 Use class methods of File over Kernel.open and IO.read 2022-12-01 02:28:49 +09:00
Takashi Kokubun
6844bcc6b4 MJIT: Use a String buffer in builtin compilers
instead of FILE*.

Using C.fprintf is slower than String manipulation on memory. I'm going
to change the way MJIT writes files, and this is a prerequisite for it.
2022-11-27 21:11:33 -08:00
Takashi Kokubun
b4546d26f2
Fix the trailing comma comment for builtin [ci skip]
so that it's clear why not args.last but args[1]
2022-09-20 09:43:50 +09:00
Takashi Kokubun
76a0e81f40
Support trailing commas in builtin
`foo(Primitive.cexpr!('Qnil'),)` causes SEGV without this change.
2022-09-20 07:38:58 +09:00
Nobuyoshi Nakada
9faa9ced96 Support sub-library in builtin-loader
Previously, it was supported in prelude.c, but has not followed up the
builtin-loader system.
2022-09-09 15:47:24 +09:00
Peter Zhu
5f10bd634f Add ISEQ_BODY macro
Use ISEQ_BODY macro to get the rb_iseq_constant_body of the ISeq. Using
this macro will make it easier for us to change the allocation strategy
of rb_iseq_constant_body when using Variable Width Allocation.
2022-03-24 10:03:51 -04:00
Koichi Sasada
b1b73936c1 Primitive.mandatory_only? for fast path
Compare with the C methods, A built-in methods written in Ruby is
slower if only mandatory parameters are given because it needs to
check the argumens and fill default values for optional and keyword
parameters (C methods can check the number of parameters with `argc`,
so there are no overhead). Passing mandatory arguments are common
(optional arguments are exceptional, in many cases) so it is important
to provide the fast path for such common cases.

`Primitive.mandatory_only?` is a special builtin function used with
`if` expression like that:

```ruby
  def self.at(time, subsec = false, unit = :microsecond, in: nil)
    if Primitive.mandatory_only?
      Primitive.time_s_at1(time)
    else
      Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
    end
  end
```

and it makes two ISeq,

```
  def self.at(time, subsec = false, unit = :microsecond, in: nil)
    Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in))
  end

  def self.at(time)
    Primitive.time_s_at1(time)
  end
```

and (2) is pointed by (1). Note that `Primitive.mandatory_only?`
should be used only in a condition of an `if` statement and the
`if` statement should be equal to the methdo body (you can not
put any expression before and after the `if` statement).

A method entry with `mandatory_only?` (`Time.at` on the above case)
is marked as `iseq_overload`. When the method will be dispatch only
with mandatory arguments (`Time.at(0)` for example), make another
method entry with ISeq (2) as mandatory only method entry and it
will be cached in an inline method cache.

The idea is similar discussed in https://bugs.ruby-lang.org/issues/16254
but it only checks mandatory parameters or more, because many cases
only mandatory parameters are given. If we find other cases (optional
or keyword parameters are used frequently and it hurts performance),
we can extend the feature.
2021-11-15 15:58:56 +09:00
Nobuyoshi Nakada
54199a3f5f
Use VALUE instead of intptr_t
On emscripten `intptr_t`, `uintptr_t`, `ptrdiff_t` and so on are
defined as `long`, but `PRIdPTR` and so on defined as `int`.
2021-08-16 15:36:37 +09:00
Benoit Daloze
68d6bd0873 Fix trivial -Wundef warnings
* See [Feature #17752]

Co-authored-by: xtkoba (Tee KOBAYASHI) <xtkoba+ruby@gmail.com>
2021-05-04 14:56:55 +02:00
Nobuyoshi Nakada
37e2a67a74
Method ID of call and fcall can be const not only ident 2021-01-01 00:54:38 +09:00
Nobuyoshi Nakada
0fbf4d0374
Access to reserved word parameter like as __builtin.arg!(:if) 2020-12-31 15:11:38 +09:00
Yusuke Endoh
248f1ef282 tool/mk_builtin_loader.rb: prevent "assigned but unused variable" 2020-12-12 23:09:11 +09:00
卜部昌平
1fb4e28002 skip inlining cexpr! that are not attr! inline
Requested by ko1.
2020-07-16 11:49:09 +09:00
卜部昌平
927fe2422f mk_builtin_loader.rb: STACK_ADDR_FROM_TOP unusable
Stacks are emulated in MJIT, must not touch the original VM stack.

See also http://ci.rvm.jp/results/trunk-mjit-wait@silicon-docker/3061353
2020-07-13 12:30:43 +09:00
卜部昌平
4506f6119a %p is not portable accross platforms
This commit fixes compiler error on MSVC.  %p on that platform is not
suitable to represent a compile-time constant.

34017163/job/vj2a8uk3gwv9yxak (L24381)
2020-07-13 08:56:18 +09:00
卜部昌平
2363a16e9a add comments 2020-07-13 08:56:18 +09:00
卜部昌平
5783d84a17 fix typo 2020-07-13 08:56:18 +09:00
卜部昌平
9721f477c7 inline Primitive.cexpr!
We can obtain the verbatim source code of Primitive.cexpr!.  Why not
paste that content into the JITed program.
2020-07-13 08:56:18 +09:00
卜部昌平
f66e0212ef precalc invokebuiltin destinations
Noticed that struct rb_builtin_function is a purely compile-time
constant.  MJIT can eliminate some runtime calculations by statically
generate dedicated C code generator for each builtin functions.
2020-07-13 08:56:18 +09:00
Koichi Sasada
95f5fd9a55 fix up Primitive.cinit! code
Recent changes break Primitive.cinit!(c_code) so fix it.
2020-07-05 10:44:36 +09:00
Koichi Sasada
74e1bca79d support all locals for cexpr!, cstmt!
Primitve.cexpr! and .cstmt! can access Ruby's parameter and
*local variables* (note that local parameters are also local
variables). However recent changes only allow to access
parameters. This patch fix it.

For example, the following code can work:

def foo a, b, k: :kw, **kwrest
  c = a + b
  d = k
  e = kwrest
  p Primitive.cstmt!(%q(rb_p(rb_ary_new_from_args(5, a, b, c, d, e));
                        return Qnil;))
end
2020-07-04 17:28:23 +09:00
Nobuyoshi Nakada
09b936d89c
Calculate header line count instead of hardcoding 2020-06-28 14:14:29 +09:00
Nobuyoshi Nakada
1020f7e3aa
Replace separators in input file name in header too 2020-06-28 14:12:26 +09:00
Nobuyoshi Nakada
44a659ad97
Replace ALT_SEPARATOR with SEPARATOR also in output file name
To suppress warnings by Visual C.
```
./integer.rb(5) : warning C4129: 'i' : unrecognized character escape sequence
./kernel.rb(21) : warning C4129: 'k' : unrecognized character escape sequence
```
2020-06-28 13:20:40 +09:00
Takashi Kokubun
7561db8c00
Introduce Primitive.attr! to annotate 'inline' (#3242)
[Feature #15589]
2020-06-20 17:13:03 -07:00
Nobuyoshi Nakada
49f0fd21e4 [Feature #16254] Allow Primitive.func style 2020-06-19 18:46:55 +09:00
Nobuyoshi Nakada
c8703a17ce [Feature #16254] Allow __builtin.func style 2020-06-19 18:46:55 +09:00
Nobuyoshi Nakada
d23917dd85
Support arguments of singleton method 2020-06-14 16:09:00 +09:00
Nobuyoshi Nakada
b22bfdaa9a
Fixed up rest, keywords, keyword rest and block arguments 2020-06-14 16:08:33 +09:00
Takashi Kokubun
997133d595
Make __builtin_cexpr! and __builtin_cstmt! work again
with Ripper.

a3e6f52c17 introduced __builtin_cexpr! and
__builtin_cstmt!, but nobody has used them and then they broke on
79292b3088 by undefined `params`.

This patch fixes the undefined `params`, but still we're not using them
yet.
2020-06-13 23:48:34 -07:00
Nobuyoshi Nakada
79292b3088
Make builtin loader sources by Ripper 2020-05-19 12:54:51 +09:00
Nobuyoshi Nakada
11fa1dcc23
Also scan rescue clauses 2020-04-04 12:38:00 +09:00
Nobuyoshi Nakada
d7bef803ac Separate builtin initialization calls 2019-12-29 12:34:55 +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