Commit graph

781 commits

Author SHA1 Message Date
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
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