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

818 Коммитов

Автор SHA1 Сообщение Дата
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
Jimmy Miller 8286544dc5
YJIT: Use starting context for status === CantCompile (#7583) 2023-03-23 13:11:46 -04:00
Ole Friis Østergaard e950781880
Use shape information in YJIT's definedivar implementation (#7579)
* Use shape information in YJIT's definedivar implementation

* Handle complex shape for definedivar
2023-03-23 11:04:30 -04:00
Alan Wu aa54082d70
YJIT: Fix large ISeq rejection (#7576)
We crashed in some edge cases due to the recent change to not compile
encoded iseqs that are larger than `u16::MAX`.

- Match the C signature of rb_yjit_constant_ic_update() and clamp down
  to `IseqIdx` size
- Return failure instead of panicking with `unwrap()` in codegen when
  the iseq is too large

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Noah Gibbs <noah.gibbs@shopify.com>
2023-03-21 14:24:17 -04:00
Jimmy Miller 5de26bc031
YJIT: Fix incorrect exit in splat (#7575)
So by itself, this shouldn't have been a correctness issue, but we
also pop the stack for block_args. Doing stack manipulation like that
and then side-exiting causes issues. So, while this fixes the
immediate failure, we have a bigger issue with block_args popping and
then exiting that we need to deal with.
2023-03-21 12:57:26 -04:00
Peter Zhu 30e7561d1d Revert "YJIT: Rest and block_arg support (#7557)"
This reverts commit 5d0a1ffafa.

This commit is causing sequel in yjit-bench to raise with this stack trace:

```
sequel-5.64.0/lib/sequel/dataset/sql.rb:266:in `literal': wrong argument type Array (expected Proc) (TypeError)
	from sequel-5.64.0/lib/sequel/database/misc.rb:269:in `literal'
	from sequel-5.64.0/lib/sequel/adapters/shared/sqlite.rb:314:in `column_definition_default_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:564:in `block in column_definition_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:564:in `each'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:564:in `column_definition_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:634:in `block in column_list_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:634:in `map'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:634:in `column_list_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:753:in `create_table_sql'
	from sequel-5.64.0/lib/sequel/adapters/shared/sqlite.rb:348:in `create_table_sql'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:702:in `create_table_from_generator'
	from sequel-5.64.0/lib/sequel/database/schema_methods.rb:203:in `create_table'
	from benchmarks/sequel/benchmark.rb:19:in `<main>'
```
2023-03-21 10:51:35 -04:00
Takashi Kokubun 7f696b8859 Remove a warning in bootstraptest/runner.rb
../bootstraptest/runner.rb:121: warning: assigned but unused variable - e
2023-03-19 21:02:21 -07:00
Jimmy Miller 5d0a1ffafa
YJIT: Rest and block_arg support (#7557)
* YJIT: Rest and block_arg support

* Update bootstraptest/test_yjit.rb

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2023-03-17 16:11:30 -04:00
Takashi Kokubun c62cf60d18 Skip a flaky test that might not work 2023-03-17 09:06:52 -07:00
Jimmy Miller 5825d7d4a1
YJIT: Remove exit for rest and send combo (#7546) 2023-03-16 17:40:36 -04:00
Nobuyoshi Nakada ce47ee00ae Fix indirect counter increment
`*pcnt++` just dereferences `pcnt` then increments the local variable,
but has no side effect.
2023-03-15 13:59:11 +09:00
Takashi Kokubun 973cb64b1c RJIT: Skip a flaky test_thread test for now
and unskip a ractor test that was actually running
2023-03-10 23:24:18 -08:00
Jimmy Miller 719a7726d1
YJIT: Handle special case of splat and rest lining up (#7422)
If you have a method that takes rest arguments and a splat call that
happens to line up perfectly with that rest, you can just dupe the
array rather than move anything around. We still have to dupe, because
people could have a custom to_a method or something like that which
means it is hard to guarantee we have exclusive access to that array.

Example:

```ruby
def foo(a, b, *rest)
end

foo(1, 2, *[3, 4])
```
2023-03-07 12:29:59 -05:00
Takashi Kokubun 23ec248e48 s/mjit/rjit/ 2023-03-06 23:44:01 -08:00
Takashi Kokubun 2e875549a9 s/MJIT/RJIT/ 2023-03-06 23:44:01 -08:00
Takashi Kokubun eaccdc1941 Rename MJIT filenames to RJIT 2023-03-06 23:44:01 -08:00
Takashi Kokubun 3034553e8d Add more GC guards 2023-03-05 23:28:59 -08:00
Takashi Kokubun e6354d5e9b Deal with too slow test 2023-03-05 22:41:18 -08:00
Takashi Kokubun 6be4e065eb Support SP motion in all insns 2023-03-05 22:11:20 -08:00
Takashi Kokubun a8dec34961 Implement initial opt_lt 2023-03-05 22:11:20 -08:00
Takashi Kokubun 4eb6f1dbb9 Put nil on an appropriate index 2023-03-05 22:11:20 -08:00
Koichi Sasada 883871d722 add a test for Ractor
Ractor should take care method cache invalidation.
Added test will miss method cache on each method call.
2023-03-06 13:30:54 +09:00
Takashi Kokubun 4782bb352e Another attempt to skip test_ractor on ci.rvm.jp
This reverts commit 8d31a60f47.
2023-03-03 20:39:38 -08:00
Takashi Kokubun 8d31a60f47 Fix a YJIT enablement check
This should be enough for `make test` and `make btest-ruby` while it
doesn't work for `make btest`.
2023-03-03 17:03:26 -08:00
Maxime Chevalier-Boisvert 4d59d01621
YJIT: fix CI issue reported by Koichi caused by small stack patch (#7442)
Includes small reproduction produced by Kokubun.

http://ci.rvm.jp/results/trunk-yjit@ruby-sp2-docker
2023-03-03 15:02:52 -08:00
Takashi Kokubun 533c8c0c44 Re-skip an unstable Ractor test
https://github.com/ruby/ruby/actions/runs/4316423442/jobs/7532190115
http://ci.rvm.jp/results/trunk-yjit@ruby-sp2-docker/4466770
2023-03-02 09:47:07 -08:00
Takashi Kokubun fac92cd050 Revert "Revert "Re-enable test_ractor for YJIT""
This reverts commit 9792d9e40f.

Ractor implementation has been rewritten. Let's see if it works now.
2023-03-02 09:11:24 -08:00
Jimmy Miller ce476cdfb7
YJIT: Fix cfunc splat
Follow-up for cb8a040b79.
2023-03-02 10:57:19 -05:00
Koichi Sasada 5875fce6ce `Ractor::Selector#empty?`
It returns the waiting set is empty or not.

Also add Ractor::Selector's tests.
2023-03-03 00:08:02 +09:00
Koichi Sasada 6207a3f588 Enable flaky ractor test
I hope a4421bd73c will solve the issue...
2023-03-02 16:14:49 +09:00
Koichi Sasada a4421bd73c Rewrite Ractor synchronization mechanism
This patch rewrites Ractor synchronization mechanism, send/receive
and take/yield.

* API
  * Ractor::Selector is introduced for lightweight waiting
    for many ractors.
* Data structure
  * remove `struct rb_ractor_waiting_list` and use
    `struct rb_ractor_queue takers_queue` to manage takers.
  * remove `rb_ractor_t::yield_atexit` and use
    `rb_ractor_t::sync::will_basket::type` to check the will.
  * add `rb_ractor_basket::p.take` to represent a taking ractor.
* Synchronization protocol
  * For the Ractor local GC, `take` can not make a copy object
    directly so ask to generate the copy from the yielding ractor.
  * The following steps shows what `r1.take` does on `r0`.
    * step1: (r0) register `r0` into `r1`'s takers.
    * step2: (r0) check `r1`'s status and wakeup r0 if `r1` is waiting
             for yielding a value.
    * step3: (r0) sleep until `r1` wakes up `r0`.
  * The following steps shows what `Ractor.yield(v)` on `r1`.
    * step1: (r1) check first takers of `r1` and if there is (`r0`),
             make a copy object of `v` and pass it to `r0` and
             wakes up `r0`.
    * step2: (r1) if there is no taker ractors, sleep until
             another ractor try to take.
2023-03-02 14:31:54 +09:00
Jimmy Miller cb8a040b79
YJIT: Properly deal with cfunc splat when no args needed (#7413)
Related to:
https://github.com/ruby/ruby/pull/7377

Previously it was believed that there was a problem with a combination
of cfuncs + splat + send, but it turns out the same issue happened
without send. For example `Integer.sqrt(1, *[])`. The issue was
happened not because of send, but because of setting the wrong argc
when we don't need to splat any args.
2023-03-01 16:33:16 -05:00
Alan Wu 55a24f9b08 YJIT: Reject __send__ with splat to cfunc for now
`make test-spec` revealed this issue after applying an unrelated bug
fix. A crashing case is included, though I suspect there are other
scenarios where it misbehaves. Don't compile for now.

Note that this is *not* an issue on the 3.2.x series; it has
`send_args_splat_non_iseq` which already rejects all splats to cfuncs,
including sends with splats.
2023-02-27 11:12:22 -05:00
Jimmy Miller 8943b0d411
YJIT: `Kernel#{is_a?,instance_of?}` fast paths (GH-7297)
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2023-02-15 14:05:42 -05:00
Takashi Kokubun 6c5582815d
YJIT: Check correct BOP on gen_fixnum_cmp (#7303) 2023-02-14 12:54:50 -08:00
Maple Ong 381bdee118
YJIT: Support invokesuper in a block (#7264)
Support invokesuper in a block on YJIT

invokesuper previously side exited when it is in a block. To make sure we're compiling the correct method in super, we now use the local environment pointer (LEP) to get the method, which will work in a block.

Co-authored-by: John Hawthorn <john@hawthorn.email>
2023-02-09 10:41:29 -05:00
Jimmy Miller 762a3d80f7
Implement splat for cfuncs. Split exit exit cases to better capture where we are exiting (#6929)
YJIT: Implement splat for cfuncs. Split exit cases

This also implements a new check for ruby2keywords as the last
argument of a splat. This does mean that we generate more code, but in
actual benchmarks where we gained speed from this (binarytrees) I
don't see any significant slow down. I did have to struggle here with
the register allocator to find code that didn't allocate too many
registers. It's a bit hard when everything is implicit. But I think I
got to the minimal amount of copying and stuff given our current
allocation strategy.
2023-01-19 13:42:49 -05:00
Benoit Daloze 6abe20e87b Remove Encoding#replicate 2023-01-11 13:41:41 +01:00
Takashi Kokubun 9792d9e40f Revert "Re-enable test_ractor for YJIT"
This reverts commit 650a20a3e1.

Now that 3.2.0 is released, let's disable flaky tests. Koichi said he'll
rework Ractor implementation for this, and it has not been done yet.
2023-01-09 17:43:47 -08:00
Takashi Kokubun b9332ac8e7
MJIT: Cancel all on disastrous situations (#7019)
I noticed this while running test_yjit with --mjit-call-threshold=1, 
which redefines `Integer#<`. When Ruby is monkey-patched, 
MJIT itself could be broken.

Similarly, Ruby scripts could break MJIT in many different ways. I
prepared the same set of hooks as YJIT so that we could possibly
override it and disable it on those moments. Every constant under
RubyVM::MJIT is private and thus it's an unsupported behavior though.
2022-12-24 01:13:40 -08:00
Takashi Kokubun 67ef3cd3cc
Skip a flaky Ractor test for mswin 2022-12-21 16:56:41 -08:00
Takashi Kokubun 650a20a3e1
Re-enable test_ractor for YJIT
This would be still flaky, but we want to make sure there's no
YJIT-specific issue when Ruby 3.2 is released. We might skip it again
after the release.
2022-12-19 13:59:36 -08:00
Koichi Sasada ae19ac5b5b fixed encoding table
This reduces global lock acquiring for reading.
https://bugs.ruby-lang.org/issues/18949
2022-12-16 10:04:37 +09:00
Takashi Kokubun 307d2e0e91
Skip yet another flaky Ractor test 2022-12-13 22:40:13 -08:00
Takashi Kokubun 7b38853bc3
Skip another flaky Ractor test for YJIT 2022-12-02 10:26:54 -08:00
Takashi Kokubun 85f041c0c5
Skip a couple of Ractor tests
Koichi plans to rework Ractor implementation to address these failures.
He agreed to skip flaky Ractor tests for now.
2022-12-02 10:18:50 -08:00
Alan Wu eb2b717a8b
YJIT: Make case-when optimization respect === redefinition (#6846)
* YJIT: Make case-when optimization respect === redefinition

Even when a fixnum key is in the dispatch hash, if there is a case such
that its basic operations for === is redefined, we need to fall back to
checking each case like the interpreter. Semantically we're always
checking each case by calling === in order, it's just that this is not
observable when basic operations are intact.

When all the keys are fixnums, though, we can do the optimization we're
doing right now. Check for this condition.

* Update yjit/src/cruby_bindings.inc.rs

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

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2022-12-02 11:40:16 -05:00
Alan Wu a0b0365e90 YJIT: Deallocate `struct Block` to plug memory leaks
Previously we essentially never freed block even after invalidation.
Their reference count never reached zero for a couple of reasons:
1. `Branch::block` formed a cycle with the block holding the branch
2. Strong count on a branch that has ever contained a stub never
   reached 0 because we increment the `.clone()` call for
   `BranchRef::into_raw()` didn't have a matching decrement.

It's not safe to immediately deallocate blocks during
invalidation since `branch_stub_hit()` can end up
running with a branch pointer from an invalidated branch.
To plug the leaks, we wait until code GC or global invalidation and
deallocate the blocks for iseqs that are definitely not running.
2022-11-30 12:23:50 -05:00
Jimmy Miller 98e9165b0a
Fix bug involving .send and overwritten methods. (#6752)
@casperisfine reporting a bug in this gist https://gist.github.com/casperisfine/d59e297fba38eb3905a3d7152b9e9350

After investigating I found it was caused by a combination of send and a c_func that we have overwritten in the JIT. For send calls, we need to do some stack manipulation before making the call. Because of the way exits works, we need to do that stack manipulation at the last possible moment. In this case, we weren't doing that stack manipulation at all. Unfortunately, with how the code is structured there isn't a great place to do that stack manipulation for our overridden C funcs.

Each overridden C func can return a boolean stating that it shouldn't be used. We would need to do the stack manipulation after all of those checks are done. We could pass a lambda(?) or separate out the logic for "can I run this override" from "now generate the code for it". Since we are coming up on a release, I went with the path of least resistence and just decided to not use these overrides if we are in a send call.

We definitely should revist this in the future.
2022-11-17 23:17:40 -05:00