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

866 Коммитов

Автор SHA1 Сообщение Дата
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
Takashi Kokubun d15d1c01c2
Rename --mjit-min-calls to --mjit-call-threshold (#6731)
for consistency with YJIT
2022-11-14 23:38:52 -08:00
Alan Wu bc8ba244b8
YJIT: Fix invalidation for c_call and c_return (#6719)
Follow-up for 2b8191bdad. Since that
commit, we stopped doing code invalidation the second time the call and
return events are enabled. We need to do it every time these events are
enabled because we might have generated code while these events are
disabled.

Also rename locals and edit comments to make it more clear that the iseq
rewrite code path only happens the first time a particular iseq trace
event is enabled.
2022-11-13 12:51:19 -05:00
Nobuyoshi Nakada b02b8e7756
Let other test runners follow the change of GNU make 4.4 jobserver 2022-11-07 10:08:30 +09:00
Matthew Draper c746f380f2
YJIT: Support nil and blockparamproxy as blockarg in send (#6492)
Co-authored-by: John Hawthorn <john@hawthorn.email>

Co-authored-by: John Hawthorn <john@hawthorn.email>
2022-10-26 15:27:59 -04:00
Nobuyoshi Nakada 131c31a920
[Bug #19081] Show the caller location in warning for Ractor
The internal location in ractor.rb is not usefull at all.
```
$ ruby -e 'Ractor.new {}'
<internal:ractor>:267: warning: Ractor is experimental, ...
```
2022-10-26 19:43:14 +09:00
Jemma Issroff 9a5684bf7f Add test for ractor race condition on ivar sets 2022-10-14 11:59:36 -07:00
Jemma Issroff ad63b668e2
Revert "Revert "This commit implements the Object Shapes technique in CRuby.""
This reverts commit 9a6803c90b.
2022-10-11 08:40:56 -07:00
Alan Wu 7293bfe1bf
YJIT: add support for calling bmethods (#6489)
* YJIT: fix a parameter name

* YJIT: add support for calling bmethods

This commit adds support for the VM_METHOD_TYPE_BMETHOD method type in
YJIT. You can get these type of methods from facilities like
Kernel#define_singleton_method and Module#define_method.

Even though the body of these methods are blocks, the parameter setup
for them is exactly the same as VM_METHOD_TYPE_ISEQ, so we can reuse
the same logic in gen_send_iseq(). You can see this from how
vm_call_bmethod() eventually calls setup_parameters_complex() with
arg_setup_method.

Bmethods do need their frame environment to be setup differently. We
handle this by allowing callers of gen_send_iseq() to control the iseq,
the frame flag, and the prev_ep. The `prev_ep` goes into the same
location as the block handler would go into in an iseq method frame.

Co-authored-by: John Hawthorn <john@hawthorn.email>

Co-authored-by: John Hawthorn <john@hawthorn.email>
2022-10-04 22:48:05 -04:00
Nobuyoshi Nakada 88c12a2937
Indent folded bootstraptest dots 2022-10-01 18:53:41 +09:00
Aaron Patterson 9a6803c90b
Revert "This commit implements the Object Shapes technique in CRuby."
This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
2022-09-30 16:01:50 -07:00
Nobuyoshi Nakada 942066713b
bootstraptest/runner: run in parallel if in parallel build 2022-09-29 14:09:25 +09:00
Jemma Issroff d594a5a8bd
This commit implements the Object Shapes technique in CRuby.
Object Shapes is used for accessing instance variables and representing the
"frozenness" of objects.  Object instances have a "shape" and the shape
represents some attributes of the object (currently which instance variables are
set and the "frozenness").  Shapes form a tree data structure, and when a new
instance variable is set on an object, that object "transitions" to a new shape
in the shape tree.  Each shape has an ID that is used for caching. The shape
structure is independent of class, so objects of different types can have the
same shape.

For example:

```ruby
class Foo
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

class Bar
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

foo = Foo.new # `foo` has shape id 2
bar = Bar.new # `bar` has shape id 2
```

Both `foo` and `bar` instances have the same shape because they both set
instance variables of the same name in the same order.

This technique can help to improve inline cache hits as well as generate more
efficient machine code in JIT compilers.

This commit also adds some methods for debugging shapes on objects.  See
`RubyVM::Shape` for more details.

For more context on Object Shapes, see [Feature: #18776]

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com>
Co-Authored-By: John Hawthorn <john@hawthorn.email>
2022-09-28 08:26:21 -07:00
Nobuyoshi Nakada 09bce061af bootstraptest/runner: manage sub processes with the job server 2022-09-28 23:18:55 +09:00
Nobuyoshi Nakada fc54dbe8b4 bootstraptest/runner: fold dots by window size 2022-09-28 23:18:55 +09:00
Aaron Patterson 06abfa5be6
Revert this until we can figure out WB issues or remove shapes from GC
Revert "* expand tabs. [ci skip]"

This reverts commit 830b5b5c35.

Revert "This commit implements the Object Shapes technique in CRuby."

This reverts commit 9ddfd2ca00.
2022-09-26 16:10:11 -07:00
Jemma Issroff 9ddfd2ca00 This commit implements the Object Shapes technique in CRuby.
Object Shapes is used for accessing instance variables and representing the
"frozenness" of objects.  Object instances have a "shape" and the shape
represents some attributes of the object (currently which instance variables are
set and the "frozenness").  Shapes form a tree data structure, and when a new
instance variable is set on an object, that object "transitions" to a new shape
in the shape tree.  Each shape has an ID that is used for caching. The shape
structure is independent of class, so objects of different types can have the
same shape.

For example:

```ruby
class Foo
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

class Bar
  def initialize
    # Starts with shape id 0
    @a = 1 # transitions to shape id 1
    @b = 1 # transitions to shape id 2
  end
end

foo = Foo.new # `foo` has shape id 2
bar = Bar.new # `bar` has shape id 2
```

Both `foo` and `bar` instances have the same shape because they both set
instance variables of the same name in the same order.

This technique can help to improve inline cache hits as well as generate more
efficient machine code in JIT compilers.

This commit also adds some methods for debugging shapes on objects.  See
`RubyVM::Shape` for more details.

For more context on Object Shapes, see [Feature: #18776]

Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com>
Co-Authored-By: John Hawthorn <john@hawthorn.email>
2022-09-26 09:21:30 -07:00
Nobuyoshi Nakada 12e5e5b573
Fix the option name in the error message [ci skip] 2022-09-19 14:15:13 +09:00
John Hawthorn f98d6d3f38
YJIT: Implement specialized respond_to? (#6363)
* Add rb_callable_method_entry_or_negative

* YJIT: Implement specialized respond_to?

This implements a specialized respond_to? in YJIT.

* Update yjit/src/codegen.rs

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2022-09-14 16:15:55 -04:00
Hiroshi SHIBATA 29bc3e0daf
omit random failure in bootstraptest with freebsd
http://rubyci.s3.amazonaws.com/freebsd13/ruby-master/log/20220902T063002Z.fail.html.gz
2022-09-06 16:27:12 +09:00
Maple Ong 5a76a15a0f
YJIT: Implement concatarray in yjit (https://github.com/Shopify/ruby/pull/405)
* Create code generation func

* Make rb_vm_concat_array available to use in Rust

* Map opcode to code gen func

* Implement code gen for concatarray

* Add test for concatarray

* Use new asm backend

* Add comment to C func wrapper
2022-08-29 08:47:11 -07:00
Alan Wu 4d811d7a2b
Fix code invalidation while OOM and OOM simulation (https://github.com/Shopify/ruby/pull/395)
`YJIT.simulate_oom!` used to leave one byte of space in the code block,
so our test didn't expose a problem with asserting that the write
position is in bounds in `CodeBlock::set_pos`. We do the following when
patching code:
  1. save current write position
  2. seek to middle of the code block and patch
  3. restore old write position
The bounds check fails on (3) when the code block is already filled up.

Leaving one byte of space also meant that when we write that byte, we
need to fill the entire code region with trapping instruction in
`VirtualMem`, which made the OOM tests unnecessarily slow.

Remove the incorrect bounds check and stop leaving space in the code
block when simulating OOM.
2022-08-29 08:47:10 -07:00
Takashi Kokubun df84832c75
Port getblockparamproxy and getblockparam (https://github.com/Shopify/ruby/pull/394) 2022-08-29 08:47:10 -07:00
Takashi Kokubun ca2afba4a7
Port the remaining method types in opt_send_without_block (https://github.com/Shopify/ruby/pull/390) 2022-08-29 08:47:09 -07:00
Takashi Kokubun 668b99b43b
Port gen_send_iseq to the new backend IR (https://github.com/Shopify/ruby/pull/381)
* Port gen_send_iseq to the new backend IR

* Replace occurrences of 8 by SIZEOF_VALUE

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2022-08-29 08:47:09 -07:00
Takashi Kokubun 726a451955
Port invokebuiltin* insns to the new backend IR (https://github.com/Shopify/ruby/pull/375)
* Port invokebuiltin* insns to the new backend IR

* Fix the C_ARG_OPNDS check boundary
2022-08-29 08:47:08 -07:00
Takashi Kokubun 2b85295d28
Port objtostring to the new backend (https://github.com/Shopify/ruby/pull/369) 2022-08-29 08:47:07 -07:00
Takashi Kokubun 4539c21367
Port gen_send_cfunc to the new backend (https://github.com/Shopify/ruby/pull/357)
* Port gen_send_cfunc to the new backend

* Remove an obsoleted test

* Add more cfunc tests

* Use csel_e instead and more into()

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>

* Add a missing lea for build_kwargs

* Split cfunc test cases

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2022-08-29 08:47:06 -07:00
Zack Deveau dea4238544
Port gen_concatstring to new backend IR (https://github.com/Shopify/ruby/pull/350)
* Port gen_concatstring to new backend IR

* Update yjit/src/codegen.rs

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2022-08-29 08:47:05 -07:00
Takashi Kokubun 330c9e9850
Port anytostring, intern, and toregexp (https://github.com/Shopify/ruby/pull/348)
* Port anytostring, intern, and toregexp

* Port getspecial to the new backend (#349)

PR: https://github.com/Shopify/ruby/pull/349
2022-08-29 08:47:05 -07:00
Takashi Kokubun 16307adf8f
Port only ATTRSET of opt_send_without_block (https://github.com/Shopify/ruby/pull/351) 2022-08-29 08:47:05 -07:00
Zack Deveau 6ab71a8598
Port gen_checktype to the new IR assembler backend (https://github.com/Shopify/ruby/pull/343) 2022-08-29 08:47:05 -07:00
Matthew Draper ab08a43ec5
YJIT: Teach getblockparamproxy to handle the no-block case without exiting (#6191)
Teach getblockparamproxy to handle the no-block case without exiting

Co-authored-by: John Hawthorn <john@hawthorn.email>

Co-authored-by: John Hawthorn <john@hawthorn.email>
2022-07-28 11:38:07 -04:00
Hiroshi SHIBATA 98e01c9914
Also skip the failing test similar with a343952d19 2022-07-28 19:10:24 +09:00
Matt Valentine-House 6423d32e3b Replace use of double_heap in tests with expand_heap 2022-07-11 09:00:03 -04:00
Noah Gibbs (and/or Benchmark CI) 5da31b62b0 Make sure string-operation assertions happen inside a method to be sure YJIT will JIT them. 2022-06-27 09:26:18 -07:00
Alan Wu 333754ace8 YJIT: Add regression test for local type tracking
The test in [1] was removed because it stopped working when we limited
the power of Kernel#binding in [2]. However, the underlying issue could
still be reproduced using blocks. Add back a regression test.

I tested the test by commenting out the fix from [1].

[1]: 54c91042ed
[2]: 343ea9967e
2022-06-23 20:27:02 -04:00
Nobuyoshi Nakada a343952d19
On FreeBSD omit the test to close a pipe while reading [ci skip] 2022-06-21 09:41:29 +09:00
Noah Gibbs 9ed9cc9852
Add tests for a variety of string-subclass operations (#5999)
This way YJIT has to match CRuby for each of them.
Remove unused string_p() Rust function
2022-06-10 13:52:43 -04:00
Noah Gibbs 1598c9458a
Add special-case code for the String unary plus operator (#5982) 2022-06-07 11:20:57 -04:00
Noah Gibbs 9d18661e1d
Revert incorrect string-guard optimisation. (#5969)
Also add jhawthorn's test to for this bug.
Fix String#to_s invalidation test
2022-06-01 10:22:08 -04:00
Noah Gibbs 50bad7159a
Special-case jit_guard_known_class for strings. This can remove (#5920)
runtime guard-checks for String#to_s, making some blocks too
short to invalidate later. Add NOPs in those cases to reserve space.
2022-05-20 19:39:37 -04:00
Alan Wu f90549cd38 Rust YJIT
In December 2021, we opened an [issue] to solicit feedback regarding the
porting of the YJIT codebase from C99 to Rust. There were some
reservations, but this project was given the go ahead by Ruby core
developers and Matz. Since then, we have successfully completed the port
of YJIT to Rust.

The new Rust version of YJIT has reached parity with the C version, in
that it passes all the CRuby tests, is able to run all of the YJIT
benchmarks, and performs similarly to the C version (because it works
the same way and largely generates the same machine code). We've even
incorporated some design improvements, such as a more fine-grained
constant invalidation mechanism which we expect will make a big
difference in Ruby on Rails applications.

Because we want to be careful, YJIT is guarded behind a configure
option:

```shell
./configure --enable-yjit # Build YJIT in release mode
./configure --enable-yjit=dev # Build YJIT in dev/debug mode
```

By default, YJIT does not get compiled and cargo/rustc is not required.
If YJIT is built in dev mode, then `cargo` is used to fetch development
dependencies, but when building in release, `cargo` is not required,
only `rustc`. At the moment YJIT requires Rust 1.60.0 or newer.

The YJIT command-line options remain mostly unchanged, and more details
about the build process are documented in `doc/yjit/yjit.md`.

The CI tests have been updated and do not take any more resources than
before.

The development history of the Rust port is available at the following
commit for interested parties:
1fd9573d8b

Our hope is that Rust YJIT will be compiled and included as a part of
system packages and compiled binaries of the Ruby 3.2 release. We do not
anticipate any major problems as Rust is well supported on every
platform which YJIT supports, but to make sure that this process works
smoothly, we would like to reach out to those who take care of building
systems packages before the 3.2 release is shipped and resolve any
issues that may come up.

[issue]: https://bugs.ruby-lang.org/issues/18481

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
Co-authored-by: Noah Gibbs <the.codefolio.guy@gmail.com>
Co-authored-by: Kevin Newton <kddnewton@gmail.com>
2022-04-27 11:00:22 -04:00
Jeremy Evans 0b091fdac6
Raise RuntimeError if Kernel#binding is called from a non-Ruby frame
Check whether the current or previous frame is a Ruby frame in
call_trace_func and rb_tracearg_binding before attempting to
create a binding for the frame.

Fixes [Bug #18487]

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2022-04-06 19:14:03 -07:00
Kevin Newton 6068da8937 Finer-grained constant cache invalidation (take 2)
This commit reintroduces finer-grained constant cache invalidation.
After 8008fb7 got merged, it was causing issues on token-threaded
builds (such as on Windows).

The issue was that when you're iterating through instruction sequences
and using the translator functions to get back the instruction structs,
you're either using `rb_vm_insn_null_translator` or
`rb_vm_insn_addr2insn2` depending if it's a direct-threading build.
`rb_vm_insn_addr2insn2` does some normalization to always return to
you the non-trace version of whatever instruction you're looking at.
`rb_vm_insn_null_translator` does not do that normalization.

This means that when you're looping through the instructions if you're
trying to do an opcode comparison, it can change depending on the type
of threading that you're using. This can be very confusing. So, this
commit creates a new translator function
`rb_vm_insn_normalizing_translator` to always return the non-trace
version so that opcode comparisons don't have to worry about different
configurations.

[Feature #18589]
2022-04-01 14:48:22 -04:00
Jeremy Evans d1d48cb690 Revert "Raise RuntimeError if Kernel#binding is called from a non-Ruby frame"
This reverts commit 343ea9967e.

This causes an assertion failure with -DRUBY_DEBUG=1 -DRGENGC_CHECK_MODE=2
2022-04-01 07:22:49 -07:00
Nobuyoshi Nakada 69967ee64e
Revert "Finer-grained inline constant cache invalidation"
This reverts commits for [Feature #18589]:
* 8008fb7352
  "Update formatting per feedback"
* 8f6eaca2e1
  "Delete ID from constant cache table if it becomes empty on ISEQ free"
* 629908586b
  "Finer-grained inline constant cache invalidation"

MSWin builds on AppVeyor have been crashing since the merger.
2022-03-25 20:29:09 +09:00
Jeremy Evans 343ea9967e Raise RuntimeError if Kernel#binding is called from a non-Ruby frame
Check whether the current or previous frame is a Ruby frame in
call_trace_func before attempting to create a binding for the frame.

Fixes [Bug #18487]

Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2022-03-24 12:31:07 -07:00
Kevin Newton 629908586b Finer-grained inline constant cache invalidation
Current behavior - caches depend on a global counter. All constant mutations cause caches to be invalidated.

```ruby
class A
  B = 1
end

def foo
  A::B # inline cache depends on global counter
end

foo # populate inline cache
foo # hit inline cache

C = 1 # global counter increments, all caches are invalidated

foo # misses inline cache due to `C = 1`
```

Proposed behavior - caches depend on name components. Only constant mutations with corresponding names will invalidate the cache.

```ruby
class A
  B = 1
end

def foo
  A::B # inline cache depends constants named "A" and "B"
end

foo # populate inline cache
foo # hit inline cache

C = 1 # caches that depend on the name "C" are invalidated

foo # hits inline cache because IC only depends on "A" and "B"
```

Examples of breaking the new cache:

```ruby
module C
  # Breaks `foo` cache because "A" constant is set and the cache in foo depends
  # on "A" and "B"
  class A; end
end

B = 1
```

We expect the new cache scheme to be invalidated less often because names aren't frequently reused. With the cache being invalidated less, we can rely on its stability more to keep our constant references fast and reduce the need to throw away generated code in YJIT.
2022-03-24 09:14:38 -07:00
Nobuyoshi Nakada c8b414b334
Reuse `-v` option result as `target_platform`
Backticks method invokes `/bin/sh` when the command contains
quotes, and `sh` clears some environment variables set in
runruby.rb to search the built shared library.
2022-02-17 20:12:38 +09:00
Koichi Sasada fdf0f8d814 btest-ruby OPTS=-v should disable quiet
`make btest-ruby` is run with -q (quiet) option and -v should
remove -q option.
2022-02-17 18:58:37 +09:00
Koichi Sasada 8e0899919b extend timeout for mjit
1 seconeds is not enough on an specific (busy) machine w/ mjit.
http://ci.rvm.jp/results/trunk-mjit@phosphorus-docker/3830178
2022-02-14 14:52:12 +09:00
Koichi Sasada 603ab70961 support concurrent btest execution
* `-j` option for concurrent test with threads
  * `-jN` uses N threads
  * `-j` uses nproc/2 threads
* Introduce `BT` struct to manage configurations
* Introduce `Assertion` to manage all assertions
* Remove all toplevel instance variables
* Show elapsed seconds at last

```
$ time make btest
...
real    0m37.319s
user    0m26.221s
sys     0m16.534s

$ time make btest TESTOPTS=-j
...
real    0m11.812s
user    0m36.667s
sys     0m21.872s
```
2022-02-06 03:05:47 +09:00