<feed xmlns='http://www.w3.org/2005/Atom'>
<title>ruby.git/test/ruby/test_call.rb, branch v3_3_11</title>
<subtitle>The Ruby Programming Language</subtitle>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/'/>
<entry>
<title>merge revision(s) a3562c2a0abf1c2bdd1d50377b4f929580782594: [Backport #20701]</title>
<updated>2024-09-02T10:19:13+00:00</updated>
<author>
<name>Takashi Kokubun</name>
<email>takashikkbn@gmail.com</email>
</author>
<published>2024-09-02T10:19:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=cf9a6c2b63e6337a3f6ce76527446739e5aceb67'/>
<id>cf9a6c2b63e6337a3f6ce76527446739e5aceb67</id>
<content type='text'>
	Remove incorrect setting of KW_SPLAT_MUT flag

	Fixes [Bug #20701]

	Co-authored-by: Pablo Herrero &lt;pablodherrero@gmail.com&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
	Remove incorrect setting of KW_SPLAT_MUT flag

	Fixes [Bug #20701]

	Co-authored-by: Pablo Herrero &lt;pablodherrero@gmail.com&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>Remove unused variables in test_call_op_asgn_keywords_mutable</title>
<updated>2023-12-15T02:44:13+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2023-12-15T02:44:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=29e99c84ae8059cd308cf1c06be05f62c55cd68d'/>
<id>29e99c84ae8059cd308cf1c06be05f62c55cd68d</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix op asgn method calls passing mutable keyword splats</title>
<updated>2023-12-14T16:13:43+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2023-12-13T00:48:26+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a18819e65fa2dd3135909df81534937dadafb6ab'/>
<id>a18819e65fa2dd3135909df81534937dadafb6ab</id>
<content type='text'>
When passing the keyword splat to [], it cannot be mutable, because
mutating the keyword splat inside [] would result in changes to the
keyword splat passed to []=.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
When passing the keyword splat to [], it cannot be mutable, because
mutating the keyword splat inside [] would result in changes to the
keyword splat passed to []=.
</pre>
</div>
</content>
</entry>
<entry>
<title>Fix op asgn calls with keywords</title>
<updated>2023-12-12T15:34:53+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2023-12-12T15:34:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=2f1d6da8c45590bf3461ed4bf051a4e1009eaf85'/>
<id>2f1d6da8c45590bf3461ed4bf051a4e1009eaf85</id>
<content type='text'>
Examples of such calls:

```ruby
obj[kw: 1] += fo
obj[**kw] &amp;&amp;= bar
```

Before this patch, literal keywords would segfault in the compiler,
and keyword splat usage would result in TypeError.

This handles all cases I can think of:

* literal keywords
* keyword splats
* combined with positional arguments
* combined with regular splats
* both with and without blocks
* both popped and non-popped cases

This also makes sure that to_hash is only called once on the keyword
splat argument, instead of twice, and make sure it is called before
calling to_proc on a passed block.

Fixes [Bug #20051]

Co-authored-by: Nobuyoshi Nakada &lt;nobu@ruby-lang.org&gt;</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Examples of such calls:

```ruby
obj[kw: 1] += fo
obj[**kw] &amp;&amp;= bar
```

Before this patch, literal keywords would segfault in the compiler,
and keyword splat usage would result in TypeError.

This handles all cases I can think of:

* literal keywords
* keyword splats
* combined with positional arguments
* combined with regular splats
* both with and without blocks
* both popped and non-popped cases

This also makes sure that to_hash is only called once on the keyword
splat argument, instead of twice, and make sure it is called before
calling to_proc on a passed block.

Fixes [Bug #20051]

Co-authored-by: Nobuyoshi Nakada &lt;nobu@ruby-lang.org&gt;</pre>
</div>
</content>
</entry>
<entry>
<title>Ensure super(**kw, &amp;block) calls kw.to_hash before block.to_proc</title>
<updated>2023-12-09T21:15:47+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2023-12-07T20:16:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f64357540eabad0f1bfaa6be60710d153325b064'/>
<id>f64357540eabad0f1bfaa6be60710d153325b064</id>
<content type='text'>
Similar as previous commit, but handles the super case with
explicit arguments.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Similar as previous commit, but handles the super case with
explicit arguments.
</pre>
</div>
</content>
</entry>
<entry>
<title>Ensure f(**kw, &amp;block) calls kw.to_hash before block.to_proc</title>
<updated>2023-12-09T21:15:47+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2023-11-08T23:56:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=a950f230788d51e13d16596e37cb77e4cc6e2311'/>
<id>a950f230788d51e13d16596e37cb77e4cc6e2311</id>
<content type='text'>
Previously, block.to_proc was called first, by vm_caller_setup_arg_block.
kw.to_hash was called later inside CALLER_SETUP_ARG or setup_parameters_complex.

This adds a splatkw instruction that is inserted before sends with
ARGS_BLOCKARG and KW_SPLAT and without KW_SPLAT_MUT. This is not needed in the
KW_SPLAT_MUT case, because then you know the value is a hash, and you don't
need to call to_hash on it.

The splatkw instruction checks whether the second to top block is a hash,
and if not, replaces it with the value of calling to_hash on it (using
rb_to_hash_type).  As it is always before a send with ARGS_BLOCKARG and
KW_SPLAT, second to top is the keyword splat, and top is the passed block.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Previously, block.to_proc was called first, by vm_caller_setup_arg_block.
kw.to_hash was called later inside CALLER_SETUP_ARG or setup_parameters_complex.

This adds a splatkw instruction that is inserted before sends with
ARGS_BLOCKARG and KW_SPLAT and without KW_SPLAT_MUT. This is not needed in the
KW_SPLAT_MUT case, because then you know the value is a hash, and you don't
need to call to_hash on it.

The splatkw instruction checks whether the second to top block is a hash,
and if not, replaces it with the value of calling to_hash on it (using
rb_to_hash_type).  As it is always before a send with ARGS_BLOCKARG and
KW_SPLAT, second to top is the keyword splat, and top is the passed block.
</pre>
</div>
</content>
</entry>
<entry>
<title>Prevent modification of splat array inside setup_parameters_complex</title>
<updated>2023-12-07T19:27:55+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2023-11-21T17:02:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=13cd963500106b366c8df9eec5c1b6815e93f07f'/>
<id>13cd963500106b366c8df9eec5c1b6815e93f07f</id>
<content type='text'>
For the following:

```
def f(*a); a end
p f(*a, kw: 3)
```

`setup_parameters_complex` pushes `{kw: 3}` onto `a`.  This worked fine
back when `concatarray true` was used and `a` was already a copy. It
does not work correctly with the optimization to switch to
`concatarray false`.  This duplicates the array on the callee side
in such a case.

This affects cases when passing a regular splat and a keyword splat
(or literal keywords) in a method call, where the method does not
accept keywords.

This allocation could probably be avoided, but doing so would
make `setup_parameters_complex` more complicated.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
For the following:

```
def f(*a); a end
p f(*a, kw: 3)
```

`setup_parameters_complex` pushes `{kw: 3}` onto `a`.  This worked fine
back when `concatarray true` was used and `a` was already a copy. It
does not work correctly with the optimization to switch to
`concatarray false`.  This duplicates the array on the callee side
in such a case.

This affects cases when passing a regular splat and a keyword splat
(or literal keywords) in a method call, where the method does not
accept keywords.

This allocation could probably be avoided, but doing so would
make `setup_parameters_complex` more complicated.
</pre>
</div>
</content>
</entry>
<entry>
<title>Ensure keyword splat method argument is hash</title>
<updated>2023-11-18T17:44:42+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2023-10-30T18:52:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=ae48d4ad2ef7abbf116ff28b2cd3748d4c654d80'/>
<id>ae48d4ad2ef7abbf116ff28b2cd3748d4c654d80</id>
<content type='text'>
Commit e87d0882910001ef3b0c2ccd43bf00cee8c34a0c introduced a
regression where the keyword splat object passed by the caller
would be directly used by callee as keyword splat parameters,
if it implemented #to_hash.  The return value of #to_hash would be
ignored in this case.
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Commit e87d0882910001ef3b0c2ccd43bf00cee8c34a0c introduced a
regression where the keyword splat object passed by the caller
would be directly used by callee as keyword splat parameters,
if it implemented #to_hash.  The return value of #to_hash would be
ignored in this case.
</pre>
</div>
</content>
</entry>
<entry>
<title>Split the bmethod proc test to avoid redefinition</title>
<updated>2023-06-17T03:29:28+00:00</updated>
<author>
<name>Nobuyoshi Nakada</name>
<email>nobu@ruby-lang.org</email>
</author>
<published>2023-06-17T03:29:28+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=7b3a531fffcac5ba09edd050feccd9149205cd7e'/>
<id>7b3a531fffcac5ba09edd050feccd9149205cd7e</id>
<content type='text'>
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
</pre>
</div>
</content>
</entry>
<entry>
<title>Speed up calling iseq bmethods</title>
<updated>2023-04-25T15:06:16+00:00</updated>
<author>
<name>Jeremy Evans</name>
<email>code@jeremyevans.net</email>
</author>
<published>2023-03-23T21:39:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.ruby-lang.org/ruby.git/commit/?id=f6254f77f7a7c4d1f11180b3b382680868bd9ee4'/>
<id>f6254f77f7a7c4d1f11180b3b382680868bd9ee4</id>
<content type='text'>
Currently, bmethod arguments are copied from the VM stack to the
C stack in vm_call_bmethod, then copied from the C stack to the VM
stack later in invoke_iseq_block_from_c.  This is inefficient.

This adds vm_call_iseq_bmethod and vm_call_noniseq_bmethod.
vm_call_iseq_bmethod is an optimized method that skips stack
copies (though there is one copy to remove the receiver from
the stack), and avoids calling vm_call_bmethod_body,
rb_vm_invoke_bmethod, invoke_block_from_c_proc,
invoke_iseq_block_from_c, and vm_yield_setup_args.

Th vm_call_iseq_bmethod argument handling is similar to the
way normal iseq methods are called, and allows for similar
performance optimizations when using splats or keywords.
However, even in the no argument case it's still significantly
faster.

A benchmark is added for bmethod calling.  In my environment,
it improves bmethod calling performance by 38-59% for simple
bmethod calls, and up to 180% for bmethod calls passing
literal keywords on both sides.

```

./miniruby-iseq-bmethod:  18159792.6 i/s
          ./miniruby-m:  13174419.1 i/s - 1.38x  slower

                   bmethod_simple_1
./miniruby-iseq-bmethod:  15890745.4 i/s
          ./miniruby-m:  10008972.7 i/s - 1.59x  slower

             bmethod_simple_0_splat
./miniruby-iseq-bmethod:  13142804.3 i/s
          ./miniruby-m:  11168595.2 i/s - 1.18x  slower

             bmethod_simple_1_splat
./miniruby-iseq-bmethod:  12375791.0 i/s
          ./miniruby-m:   8491140.1 i/s - 1.46x  slower

                   bmethod_no_splat
./miniruby-iseq-bmethod:  10151258.8 i/s
          ./miniruby-m:   8716664.1 i/s - 1.16x  slower

                    bmethod_0_splat
./miniruby-iseq-bmethod:   8138802.5 i/s
          ./miniruby-m:   7515600.2 i/s - 1.08x  slower

                    bmethod_1_splat
./miniruby-iseq-bmethod:   8028372.7 i/s
          ./miniruby-m:   5947658.6 i/s - 1.35x  slower

                   bmethod_10_splat
./miniruby-iseq-bmethod:   6953514.1 i/s
          ./miniruby-m:   4840132.9 i/s - 1.44x  slower

                  bmethod_100_splat
./miniruby-iseq-bmethod:   5287288.4 i/s
          ./miniruby-m:   2243218.4 i/s - 2.36x  slower

                         bmethod_kw
./miniruby-iseq-bmethod:   8931358.2 i/s
          ./miniruby-m:   3185818.6 i/s - 2.80x  slower

                      bmethod_no_kw
./miniruby-iseq-bmethod:  12281287.4 i/s
          ./miniruby-m:  10041727.9 i/s - 1.22x  slower

                   bmethod_kw_splat
./miniruby-iseq-bmethod:   5618956.8 i/s
          ./miniruby-m:   3657549.5 i/s - 1.54x  slower
```
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
Currently, bmethod arguments are copied from the VM stack to the
C stack in vm_call_bmethod, then copied from the C stack to the VM
stack later in invoke_iseq_block_from_c.  This is inefficient.

This adds vm_call_iseq_bmethod and vm_call_noniseq_bmethod.
vm_call_iseq_bmethod is an optimized method that skips stack
copies (though there is one copy to remove the receiver from
the stack), and avoids calling vm_call_bmethod_body,
rb_vm_invoke_bmethod, invoke_block_from_c_proc,
invoke_iseq_block_from_c, and vm_yield_setup_args.

Th vm_call_iseq_bmethod argument handling is similar to the
way normal iseq methods are called, and allows for similar
performance optimizations when using splats or keywords.
However, even in the no argument case it's still significantly
faster.

A benchmark is added for bmethod calling.  In my environment,
it improves bmethod calling performance by 38-59% for simple
bmethod calls, and up to 180% for bmethod calls passing
literal keywords on both sides.

```

./miniruby-iseq-bmethod:  18159792.6 i/s
          ./miniruby-m:  13174419.1 i/s - 1.38x  slower

                   bmethod_simple_1
./miniruby-iseq-bmethod:  15890745.4 i/s
          ./miniruby-m:  10008972.7 i/s - 1.59x  slower

             bmethod_simple_0_splat
./miniruby-iseq-bmethod:  13142804.3 i/s
          ./miniruby-m:  11168595.2 i/s - 1.18x  slower

             bmethod_simple_1_splat
./miniruby-iseq-bmethod:  12375791.0 i/s
          ./miniruby-m:   8491140.1 i/s - 1.46x  slower

                   bmethod_no_splat
./miniruby-iseq-bmethod:  10151258.8 i/s
          ./miniruby-m:   8716664.1 i/s - 1.16x  slower

                    bmethod_0_splat
./miniruby-iseq-bmethod:   8138802.5 i/s
          ./miniruby-m:   7515600.2 i/s - 1.08x  slower

                    bmethod_1_splat
./miniruby-iseq-bmethod:   8028372.7 i/s
          ./miniruby-m:   5947658.6 i/s - 1.35x  slower

                   bmethod_10_splat
./miniruby-iseq-bmethod:   6953514.1 i/s
          ./miniruby-m:   4840132.9 i/s - 1.44x  slower

                  bmethod_100_splat
./miniruby-iseq-bmethod:   5287288.4 i/s
          ./miniruby-m:   2243218.4 i/s - 2.36x  slower

                         bmethod_kw
./miniruby-iseq-bmethod:   8931358.2 i/s
          ./miniruby-m:   3185818.6 i/s - 2.80x  slower

                      bmethod_no_kw
./miniruby-iseq-bmethod:  12281287.4 i/s
          ./miniruby-m:  10041727.9 i/s - 1.22x  slower

                   bmethod_kw_splat
./miniruby-iseq-bmethod:   5618956.8 i/s
          ./miniruby-m:   3657549.5 i/s - 1.54x  slower
```
</pre>
</div>
</content>
</entry>
</feed>
