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

866 Коммитов

Автор SHA1 Сообщение Дата
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
Luke Gruber 32c4b0125f Set Ractor moved object's shape to original object's shape
Fixes [Bug #19409]
2024-01-02 08:10:59 +09:00
Hiroshi SHIBATA 863ded45a1
Typofix under bootstraptest, spec and yjit directories 2023-12-25 13:50:23 +09:00
John Hawthorn c18edc5b5d Avoid underflow of rb_yjit_live_iseq_count
This value is only incremented when rb_iseq_translate_threaded_code is
called, which doesn't happen for iseqs which result in a syntax error.

This is easy to hit by running a debug build with RUBY_FREE_AT_EXIT=1,
but any build and options could underflow this value by running enough
evals.
2023-12-21 20:43:01 -08:00
Takashi Kokubun 68bcca4c2b RJIT: Fix unwanted shadowing in set_local_type
local_idx should not be overwritten.
2023-12-21 15:48:37 -08:00
Takashi Kokubun 78b27ce62a RJIT: Streamline RJIT enablement check
in bootstrap tests so that `make btest-bruby` skips the right tests.
2023-12-21 14:32:03 -08:00
Koichi Sasada 054f56fd3e moved object should not have a shape ID
fix [Bug #19917]
2023-12-20 07:04:32 +09:00
Koichi Sasada c9a9b8036c remove `Ractor::Selector` from Ruby level
`Ractor::Selector` is not approved by Matz so remove it from
Ruby-level.

The implementation is used by `Ractor.select` so most of implementation
was remaind and calling `rb_init_ractor_selector()`, `Ractor::Selector`
will be defined. I will provide `ractor-selector` gem to try it.
2023-12-16 01:00:01 +09:00
Koichi Sasada 9b4cb69a88 support `skip` in bootstraptest 2023-12-16 01:00:01 +09:00
Alan Wu d4bbee7475
YJIT: Fix off-by-one in Kernel#send type handling (#9212)
Previously, if the method ID argument happens to be on one below the top
of the stack, we didn't overwrite the type of the stack slot, which
leaves an incorrect type for the stack slot. The included script tripped
asserts both with and without --yjit-verify-ctx.
2023-12-12 22:10:14 +00:00
Alan Wu 4eca329d29 Skip a YJIT test on RJIT 2023-12-11 19:21:08 -05:00
Alan Wu 9cb0ad863c YJIT: Fix missing arity check for splat calls to methods with optionals
Previously, for splat callsites that land in methods with optional
parameters, we didn't reject the case where the caller supplies too many
arguments. Accepting those calls previously caused YJIT to construct
corrupted control frames, which leads to crashes if the callee uses
certain stack walking methods such as Kernel#raise and String#gsub (for
setting up the frame-local `$~`).

Example crash in a debug build:

    Assertion Failed: ../vm_core.h:1375:VM_ENV_FLAGS:FIXNUM_P(flags)
2023-12-11 19:21:08 -05:00
Takashi Kokubun a439fc2f17
YJIT: Avoid register allocation conflict with a higher stack_idx (#9143)
YJIT: Avoid register allocation conflict

with a higher stack_idx
2023-12-06 15:19:43 -05:00
Alan Wu b5a62eb9ab
YJIT: Mark and update stubs in invalidated blocks (#9104)
Like in the example given in delayed_deallocation(), stubs can be hit
even if the block housing it is invalidated. Mark them so we don't
work with invalidate ISeqs when hitting these stubs.
2023-12-04 10:13:40 -05:00
Takashi Kokubun 926bfc3bc0
YJIT: Avoid a register spill on arm64 (#9014) 2023-11-22 15:13:32 -08:00
Maxime Chevalier-Boisvert 7a93bee4f8
YJIT: add an extra btest for shape too complex (#9013)
Following Jean Boussier's comment that some shape bugs were not
caught by our tests, I'm trying to improve our test coverage a
tiny bit.
2023-11-22 19:06:37 +00:00
Takashi Kokubun 9877f3ada8
YJIT: Inline basic Ruby methods (#8855)
* YJIT: Inline basic Ruby methods

* YJIT: Fix "InsnOut operand made it past register allocation"

checktype should not generate a useless instruction.
2023-11-07 10:54:33 -05:00
Alan Wu 0bf1749e9f
YJIT: Fix argument clobbering in some block_arg+rest_param calls (#8647)
Previously, for block argument callsites with some specific argument
count and callee local variable count combinations, YJIT ended up
writing over arguments that are supposed to be collected into a rest
parameter array unmodified.

Detect when clobbering would happen and avoid it. Also, place the block
handler after the stack overflow check, since it writes to new stack
space.

Reported-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-10-13 10:41:53 -04:00
Koichi Sasada be1bbd5b7d M:N thread scheduler for Ractors
This patch introduce M:N thread scheduler for Ractor system.

In general, M:N thread scheduler employs N native threads (OS threads)
to manage M user-level threads (Ruby threads in this case).
On the Ruby interpreter, 1 native thread is provided for 1 Ractor
and all Ruby threads are managed by the native thread.

From Ruby 1.9, the interpreter uses 1:1 thread scheduler which means
1 Ruby thread has 1 native thread. M:N scheduler change this strategy.

Because of compatibility issue (and stableness issue of the implementation)
main Ractor doesn't use M:N scheduler on default. On the other words,
threads on the main Ractor will be managed with 1:1 thread scheduler.

There are additional settings by environment variables:

`RUBY_MN_THREADS=1` enables M:N thread scheduler on the main ractor.
Note that non-main ractors use the M:N scheduler without this
configuration. With this configuration, single ractor applications
run threads on M:1 thread scheduler (green threads, user-level threads).

`RUBY_MAX_CPU=n` specifies maximum number of native threads for
M:N scheduler (default: 8).

This patch will be reverted soon if non-easy issues are found.

[Bug #19842]
2023-10-12 14:47:01 +09:00
Takashi Kokubun 0b67e3fd3e
YJIT: Chain-guard opt_mult overflow (#8554)
* YJIT: Chain-guard opt_mult overflow

* YJIT: Support regenerating Jo after Mul
2023-09-29 21:55:48 -04:00
Alan Wu 7cec7d14c3
YJIT: Fix object movement bug in iseq guard for invokeblock
Since the compile-time iseq used in the guard was not marked and updated
during compaction, a runtime value reusing the address could falsely pass
the guard.

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-15 19:03:48 -04:00
Nobuyoshi Nakada 89802078f9
[Bug #19882] Reject tokens invalid as symbols 2023-09-15 17:27:36 +09:00
Ian Candy 78233e8352
Add `String#getbyte` YJIT implementation (#8397)
* Add getbyte JIT implementation

Adds an implementation for String#getbyte for YJIT, along with a
bootstrap test. This should be helpful for pure Ruby implementations
and to avoid unneeded allocations.

Co-authored-by: John Hawthorn <jhawthorn@github.com>

* Skip the getbyte test for RJIT for now

---------

Co-authored-by: John Hawthorn <jhawthorn@github.com>
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-09-07 23:15:24 -04:00
Alan Wu 23c83d172c YJIT: Remove Type::CArray and limit use of Type::CString
These types are essentially claims about what `RBASIC_CLASS(obj)`
returns. The field changes with singleton class creation, but we didn't
consider so previously and elided guards where we actually needed them.

Found running ruby/spec with --yjit-verify-ctx. The assertion interface
makes extensive use of singleton classes.
2023-08-28 17:14:33 -04:00
Alan Wu 4524aeba2f YJIT: Fix return type of Integer#/ with T_FIXNUM inputs
Issue found by running ruby/spec with `--yjit-verify-ctx`. Thanks!
2023-08-18 12:17:37 -04:00
Maxime Chevalier-Boisvert 314eed8a5e
YJIT: implement fast path for integer multiplication in opt_mult (#8204)
* YJIT: implement fast path for integer multiplication in opt_mult

* Update yjit/src/codegen.rs

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>

* Implement mul with overflow checking on arm64

* Fix missing semicolon

* Add arm splitting for lshift, rshift, urshift

---------

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-08-18 10:05:32 -04:00
Alan Wu 5d48825d55 YJIT: Fix String#<< return type
We previously falsely asserted that String#<< always returns a ::String
instance. Issue was discovered on CI with `--yjit-verify-ctx`.

https://github.com/ruby/ruby/actions/runs/5893760435/job/15986002531
2023-08-17 17:17:31 -04:00
Alan Wu 9acc73d7c5
YJIT: Optional parameter rework and bugfix (#8220)
* YJIT: Fix splatting empty array with rest param

* YJIT: Rework optional parameter handling to fix corner case

The old code had a few unintuitive parts. The starting PC of the callee
was set in different places; `num_param`, which one would assume to be
static for a particular callee seemingly tallied to different amounts
depending on the what the caller passed; `opts_filled_with_splat` was
greater than zero even when the opts were not filled by items in the
splat array. Functionally, the bits that lets the callee know which
keyword parameters are unspecified were not passed properly when there
are optional parameters and a rest parameter, and then optional
parameters are all filled.

Make `num_param` non-mut and use parameter information in the callee
iseq as-is. Move local variable nil fill and placing of the rest array
out of `gen_push_frame()` as they are only ever relevant for iseq calls.
Always place the rest array at `lead_num + opt_num` to fix the
previously buggy situation.

* YJIT: Compile splat calls to iseqs with rest params

Test interactions with optional parameters.
2023-08-15 10:08:48 -04:00
Takashi Kokubun 02e5095108
YJIT: Implement GET_BLOCK_HANDLER() for invokesuper (#8206) 2023-08-11 13:07:16 -07:00
Takashi Kokubun cd8d20cd1f
YJIT: Compile exception handlers (#8171)
Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-08-08 16:06:22 -07:00
Maxime Chevalier-Boisvert 98b4256aa7
YJIT: handle expandarray_rhs_too_small case (#8161)
* YJIT: handle expandarray_rhs_too_small case

YJIT: fix csel bug in x86 backend, add test

Remove commented out lines

Refactor expandarray to use chain guards

Propagate Type::Nil when known

Update yjit/src/codegen.rs

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>

* Add missing counter, use get_array_ptr() in expandarray

* Make change suggested by Kokubun to reuse loop

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2023-08-03 16:09:18 -04:00
ywenc 8ca399d640
Implement `opt_aref_with` instruction (#8118)
Implement gen_opt_aref_with

Vm opt_aref_with is available

Test opt_aref_with

Stats for opt_aref_with

Co-authored-by: jhawthorn <jhawthorn@github.com>
2023-07-26 10:38:59 -04:00
Nobuyoshi Nakada d3bcff0158
Fix a typo [ci skip] 2023-07-17 00:15:05 +09:00
Takashi Kokubun 503f987ead Skip a flaky test for RJIT 2023-07-11 14:39:32 -07:00
Takashi Kokubun a1d4dada6b
YJIT: Break register cycles for C arguments (take 2) (#8018)
* Revert "Revert "YJIT: Break register cycles for C arguments (#7918)""

This reverts commit 78ca085785.

* Use shfited_live_ranges for the last-insn check
2023-07-04 15:57:32 -04:00
Alan Wu 296782ab60
YJIT: Fix autosplat miscomp for blocks with optionals (#8006)
* YJIT: Fix autosplat miscomp for blocks with optionals

When passing an array as the sole argument to `yield`, and the yieldee
takes more than 1 optional parameter, the array is expanded similar
to `*array` splat calls. This is called "autosplat" in
`setup_parameters_complex()`.

Previously, YJIT did not detect this autosplat condition. It passed the
array without expanding it, deviating from interpreter behavior.
Detect this conditon and refuse to compile it.

Fixes: Shopify/yjit#313

* RJIT: Fix autosplat miscomp for blocks with optionals

This is mirrors the same issue as YJIT. See previous commit.
2023-07-04 10:45:29 -04:00
Takashi Kokubun cbfb5fbb25 RJIT: Fix unspecified_bits with locals 2023-04-26 18:12:53 -07:00
Jeremy Evans 99c6d19e50 Generalize cfunc large array splat fix to fix many additional cases raising SystemStackError
Originally, when 2e7bceb34e fixed cfuncs to no
longer use the VM stack for large array splats, it was thought to have fully
fixed Bug #4040, since the issue was fixed for methods defined in Ruby (iseqs)
back in Ruby 2.2.

After additional research, I determined that same issue affects almost all
types of method calls, not just iseq and cfunc calls.  There were two main
types of remaining issues, important cases (where large array splat should
work) and pedantic cases (where large array splat raised SystemStackError
instead of ArgumentError).

Important cases:

```ruby
define_method(:a){|*a|}
a(*1380888.times)

def b(*a); end
send(:b, *1380888.times)

:b.to_proc.call(self, *1380888.times)

def d; yield(*1380888.times) end
d(&method(:b))

def self.method_missing(*a); end
not_a_method(*1380888.times)

```

Pedantic cases:

```ruby
def a; end
a(*1380888.times)
def b(_); end
b(*1380888.times)
def c(_=nil); end
c(*1380888.times)

c = Class.new do
  attr_accessor :a
  alias b a=
end.new
c.a(*1380888.times)
c.b(*1380888.times)

c = Struct.new(:a) do
  alias b a=
end.new
c.a(*1380888.times)
c.b(*1380888.times)
```

This patch fixes all usage of CALLER_SETUP_ARG with splatting a large
number of arguments, and required similar fixes to use a temporary
hidden array in three other cases where the VM would use the VM stack
for handling a large number of arguments.  However, it is possible
there may be additional cases where splatting a large number
of arguments still causes a SystemStackError.

This has a measurable performance impact, as it requires additional
checks for a large number of arguments in many additional cases.

This change is fairly invasive, as there were many different VM
functions that needed to be modified to support this. To avoid
too much API change, I modified struct rb_calling_info to add a
heap_argv member for storing the array, so I would not have to
thread it through many functions.  This struct is always stack
allocated, which helps ensure sure GC doesn't collect it early.

Because of how invasive the changes are, and how rarely large
arrays are actually splatted in Ruby code, the existing test/spec
suites are not great at testing for correct behavior.  To try to
find and fix all issues, I tested this in CI with
VM_ARGC_STACK_MAX to -1, ensuring that a temporary array is used
for all array splat method calls.  This was very helpful in
finding breaking cases, especially ones involving flagged keyword
hashes.

Fixes [Bug #4040]

Co-authored-by: Jimmy Miller <jimmy.miller@shopify.com>
2023-04-25 08:06:16 -07:00
Aaron Patterson c5fc1ce975 Emit special instruction for array literal + .(hash|min|max)
This commit introduces a new instruction `opt_newarray_send` which is
used when there is an array literal followed by either the `hash`,
`min`, or `max` method.

```
[a, b, c].hash
```

Will emit an `opt_newarray_send` instruction.  This instruction falls
back to a method call if the "interested" method has been monkey
patched.

Here are some examples of the instructions generated:

```
$ ./miniruby --dump=insns -e '[@a, @b].max'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 getinstancevariable                    :@a, <is:0>               (   1)[Li]
0003 getinstancevariable                    :@b, <is:1>
0006 opt_newarray_send                      2, :max
0009 leave
$ ./miniruby --dump=insns -e '[@a, @b].min'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,12)> (catch: FALSE)
0000 getinstancevariable                    :@a, <is:0>               (   1)[Li]
0003 getinstancevariable                    :@b, <is:1>
0006 opt_newarray_send                      2, :min
0009 leave
$ ./miniruby --dump=insns -e '[@a, @b].hash'
== disasm: #<ISeq:<main>@-e:1 (1,0)-(1,13)> (catch: FALSE)
0000 getinstancevariable                    :@a, <is:0>               (   1)[Li]
0003 getinstancevariable                    :@b, <is:1>
0006 opt_newarray_send                      2, :hash
0009 leave
```

[Feature #18897] [ruby-core:109147]

Co-authored-by: John Hawthorn <jhawthorn@github.com>
2023-04-18 17:16:22 -07:00
Jimmy Miller 293913905e
YJIT: Fixes failure reported by rails for opt+splat+rest (#7727) 2023-04-17 17:58:04 -04:00
Alan Wu 87c7de55e0 RJIT: Skip a YJIT test
Despite applying a fix to RJIT similar to the YJIT fix, this test still
crashes RJIT.
2023-04-14 18:01:14 -04:00
Alan Wu 31e67a476f YJIT: Fix false object collection when setting ivar
Previously, setinstancevariable could generate code that calls
`rb_ensure_iv_list_size()` without first updating `cfp->sp`. This means
in the event that a GC start from within said routine the top few
objects would not be marked, causing them to be falsly collected.

Call `jit_prepare_routine_call()` first.

[Bug #19601]
2023-04-14 18:01:14 -04:00
Jimmy Miller 08413f982c
YJIT: Add support for rest with option and splat args (#7698) 2023-04-13 16:21:02 -07:00
John Hawthorn 0ce2bdc76d YJIT: Fix missing argc check in known cfuncs
Previously we were missing a compile-time check that the known cfuncs
receive the correct number of arguments.

We noticied this because in particular when using ARGS_SPLAT, which also
wasn't checked, YJIT would crash on code which was otherwise correct
(didn't raise exceptions in the VM).

This still supports vararg (argc == -1) cfuncs. I added an additional
assertion that when we use the specialized codegen for one of these
known functions that the argc are popped off the stack correctly, which
should help ensure they're implemented correctly (previously the crash
was usually observed on a future `leave` insn).

[Bug #19595]
2023-04-12 17:48:34 -07:00
Takashi Kokubun 1ff14a855a
YJIT: Avoid using a register for unspecified_bits (#7685)
Fix [Bug #19586]
2023-04-10 16:35:48 -07:00
Takashi Kokubun 1587494b0b
YJIT: Add codegen for Integer methods (#7665)
* YJIT: Add codegen for Integer methods

* YJIT: Update dependencies

* YJIT: Fix Integer#[] for argc=2
2023-04-05 13:19:31 -07:00
Takashi Kokubun 6ab86e4626 RJIT: Fix arguments for shift_stack 2023-04-03 21:26:40 -07:00
Jimmy Miller a8782c454c YJIT: Test more kw and rest cases and change exit name 2023-03-30 18:01:26 -04:00
Jimmy Miller a8c6ba23a6
YJIT: Rest and keyword (non-supplying) (#7608)
* YJIT: Rest and keyword (non-supplying)

* Update yjit/src/codegen.rs

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-03-29 12:31:41 -04:00
Jimmy Miller 59c3fac6c4
YJIT: Rest and block_arg support (#7584) 2023-03-24 17:01:59 -04:00