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

917 Коммитов

Автор SHA1 Сообщение Дата
Alan Wu f3c35749fe YJIT: Optimize putobject+opt_ltlt for integers
In `jit_rb_int_lshift()`, we guard against the right hand side changing
since we want to avoid generating variable length shifts. When control
reaches a `putobject` and `opt_ltlt` pair, though, we know that the right
hand side never changes.

This commit detects this situation and substitutes an implementation
that does not guard against the right hand side changing, saving that
work.

Deleted some `putobject` Rust tests since they aren't that valuable and
cause linking issues.

Nice boost to `optcarrot` and `protoboeuf`:

```
----------  ------------------
bench       yjit-pre/yjit-post
optcarrot   1.09
protoboeuf  1.12
----------  ------------------
```
2024-03-28 17:41:01 -04:00
Maxime Chevalier-Boisvert bb3cbdfe2f
YJIT: add iseq_alloc_count to stats (#10398)
* YJIT: add iseq_alloc_count to stats

* Remove an empty line

---------

Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2024-03-28 15:21:09 -04:00
Alan Wu de742b425f YJIT: Inline simple getlocal+leave iseqs
This mainly targets things like `T.unsafe()` from Sorbet, which is just an
identity function at runtime and only a hint for the static checker.
Only deal with simple caller and callees (no keywords and splat etc.).

Co-authored-by: Takashi Kokubun (k0kubun) <takashikkbn@gmail.com>
2024-03-25 17:50:40 -04:00
Takashi Kokubun 46bf6ae886
YJIT: Propagate Array, Hash, and String classes (#10323) 2024-03-25 12:06:47 -04:00
Nobuyoshi Nakada 78e12beb6d
Propagate jobserver FDs to `cargo` and `rustc` [ci skip]
https://doc.rust-lang.org/cargo/reference/build-scripts.html#jobserver
> Cargo and `rustc` use the jobserver protocol, developed for GNU
> make, to coordinate concurrency across processes.

Older GNU make used FDs to connect to the jobserver, and needs an
explicit use of `$(MAKE)` variable or `+` prefix to pass the FDs.
2024-03-22 22:05:58 +09:00
Takashi Kokubun 4238615432
YJIT: Get rid of Type::TProc (#10287) 2024-03-20 11:29:27 -04:00
Étienne Barrié 12be40ae6b Implement chilled strings
[Feature #20205]

As a path toward enabling frozen string literals by default in the future,
this commit introduce "chilled strings". From a user perspective chilled
strings pretend to be frozen, but on the first attempt to mutate them,
they lose their frozen status and emit a warning rather than to raise a
`FrozenError`.

Implementation wise, `rb_compile_option_struct.frozen_string_literal` is
no longer a boolean but a tri-state of `enabled/disabled/unset`.

When code is compiled with frozen string literals neither explictly enabled
or disabled, string literals are compiled with a new `putchilledstring`
instruction. This instruction is identical to `putstring` except it marks
the String with the `STR_CHILLED (FL_USER3)` and `FL_FREEZE` flags.

Chilled strings have the `FL_FREEZE` flag as to minimize the need to check
for chilled strings across the codebase, and to improve compatibility with
C extensions.

Notes:
  - `String#freeze`: clears the chilled flag.
  - `String#-@`: acts as if the string was mutable.
  - `String#+@`: acts as if the string was mutable.
  - `String#clone`: copies the chilled flag.

Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
2024-03-19 09:26:49 +01:00
Alan Wu 802e857ae6
YJIT: Support arity=-2 cfuncs (#10268)
This type of cfuncs shows up as consume a lot of cycles in profiles of
the lobsters benchmark, even though in the stats they don't happen that
frequently. Might be a bug in the profiling, but these calls are not
too bad to support, so might as well do it.

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2024-03-18 16:02:22 +00:00
Takashi Kokubun 207b002392
YJIT: Fallback cfunc varg splat for ruby2_keywords (#10226) 2024-03-13 12:22:35 -04:00
Peter Zhu 88373fe2e8 Update cruby_bindings.inc.rs 2024-03-13 09:55:52 -04:00
Takashi Kokubun 22708be0d7 Revisions for #10198
This fixes some inconsistencies introduced by that PR.
2024-03-12 13:44:48 -07:00
Maxime Chevalier-Boisvert 38a4b5c1fa
YJIT: String#getbyte codegen (#10188)
* WIP getbyte implementation

* WIP String#getbyte implementation

* Fix whitespace in stats.rs

* fix?

* Fix whitespace, add comment

---------

Co-authored-by: Aaron Patterson <aaron.patterson@shopify.com>
2024-03-06 20:56:30 +00:00
Jean Boussier b4a69351ec Move FL_SINGLETON to FL_USER1
This frees FL_USER0 on both T_MODULE and T_CLASS.

Note: prior to this, FL_SINGLETON was never set on T_MODULE,
so checking for `FL_SINGLETON` without first checking that
`FL_TYPE` was `T_CLASS` was valid. That's no longer the case.
2024-03-06 13:11:41 -05:00
cui fliter 226a889dc7
[DOC] fix some comments
Signed-off-by: cui fliter <imcusg@gmail.com>
2024-03-05 18:50:47 +09:00
Takashi Kokubun 317163c79c Update bindgen for YJIT and RJIT 2024-03-01 15:07:41 -08:00
Jeremy Evans 99384bac28 Correctly set anon_kwrest flag for def f(b: 1, **)
In cases where a method accepts both keywords and an anonymous
keyword splat, the method was not marked as taking an anonymous
keyword splat.  Fix that in the compiler.

Doing that broke handling of nil keyword splats in yjit, so
update yjit to handle that.

Add a test to check that calling a method that accepts both
a keyword argument and an anonymous keyword splat does not
modify a passed keyword splat hash.

Move the anon_kwrest check from setup_parameters_complex to
ignore_keyword_hash_p, and only use it if the keyword hash
is already a hash. This should speed things up slightly as
it avoids a check previously used for all callers of
setup_parameters_complex.

Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
2024-03-01 12:36:19 -08:00
Alan Wu 88050ec179 YJIT: No need to set cfp->sp when setting escaped locals
While writing to the env object can add it to the remember set,
it shouldn't trigger a GC run.
2024-03-01 12:54:34 -05:00
Takashi Kokubun 5891c70b38
YJIT: Support inlining putself (#10137) 2024-02-29 11:08:57 -05:00
Alan Wu f05ad373d8 YJIT: Squash canary before falling back
Recent flaky canary-related CI failures have all happened while trying
to fall back. It's unclear what is leaving the canary on the stack and
causing gen_send_dynamic() to falsely assume that it should be leaf,
and this patch isn't going to help us find the source. One source I
found is Array#<< with a frozen array, but it's unclear if that's what's
causing the CI failures. I'm somewhat afraid to add a canary check to
rb_longjmp() since that might introduce more flaky failures, and maybe
ones unrelated to YJIT.

See: https://github.com/ruby/ruby/actions/runs/8083502532/job/22086714152
See: https://github.com/ruby/ruby/actions/runs/8066858522/job/22035963315
2024-02-28 18:00:22 -05:00
Alan Wu 558b58d330 YJIT: Reject keywords hash in -1 arity cfunc splat support
`test_keyword.rb` caught this issue. Just need to run with `threshold=1`
2024-02-28 15:00:26 -05:00
Alan Wu 11f121364a
YJIT: Support splat with C methods with -1 arity
Usually we deal with splats by speculating that they're of a specific
size. In this case, the C method takes a pointer and a length, so
we can support changing sizes just fine.
2024-02-27 17:50:38 +00:00
dependabot[bot] 616b414621
Bump capstone from 0.11.0 to 0.12.0 in /yjit (#10094)
Bumps [capstone](https://github.com/capstone-rust/capstone-rs) from 0.11.0 to 0.12.0.
- [Release notes](https://github.com/capstone-rust/capstone-rs/releases)
- [Changelog](https://github.com/capstone-rust/capstone-rs/blob/master/CHANGELOG.md)
- [Commits](https://github.com/capstone-rust/capstone-rs/compare/capstone-v0.11.0...capstone-v0.12.0)

---
updated-dependencies:
- dependency-name: capstone
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-25 19:02:00 -08:00
Takashi Kokubun e9e752c7ef Assert running_iseq before using it
When running_iseq happens to be 0, it's better to fail on the assertion
rather than referencing the null pointer.
2024-02-23 20:19:37 -08:00
Takashi Kokubun e439419baa [DOC] Fix a typo 2024-02-23 16:21:36 -08:00
Takashi Kokubun 8a6740c70e
YJIT: Lazily push a frame for specialized C funcs (#10080)
* YJIT: Lazily push a frame for specialized C funcs

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>

* Fix a comment on pc_to_cfunc

* Rename rb_yjit_check_pc to rb_yjit_lazy_push_frame

* Rename it to jit_prepare_lazy_frame_call

* Fix a typo

* Optimize String#getbyte as well

* Optimize String#byteslice as well

---------

Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
2024-02-23 19:08:09 +00:00
Takashi Kokubun a16fefcff5
YJIT: Optimize attr_writer (#9986)
* YJIT: Optimize attr_writer

* Comment about StackOpnd vs SelfOpnd
2024-02-22 13:33:42 -05:00
Takashi Kokubun 35f68e7dff
YJIT: Assert Opnd::Stack's SP expectation (#10061) 2024-02-21 23:09:17 +00:00
Alan Wu 0be09967fe
YJIT: Grab stack operands after SP change in String#byteslice (#10060)
Previously, `StackOperand`s caching `sp_offset` was held across a
jit_prepare_call_with_gc(), which invalidates the offsets. With the
right register allocation state, the canary overlapped with the old
address of the receiver and YJIT clobbered the receiver writing the
canary.
2024-02-21 14:42:23 -08:00
Takashi Kokubun 577d07cfc6
YJIT: Allow non-leaf calls on opt_* insns (#10033)
* YJIT: Allow non-leaf calls on opt_* insns

* s/on_send_insn/is_sendish/

* Repeat known_cfunc_codegen
2024-02-21 20:24:18 +00:00
Takashi Kokubun ce4142bcb7
YJIT: rb_str_concat_literals is not leaf (#10035) 2024-02-20 17:23:08 -08:00
Alan Wu 8e1090487e YJIT: Fix calling leaf builtins with empty splat and kw_splat
These don't pass anything and just need to be popped off the stack.

https://github.com/ruby/ruby/actions/runs/7977363890/job/21780095289#step:13:104
2024-02-20 16:53:36 -05:00
Takashi Kokubun 9216a2ac43
YJIT: Verify the assumption of leaf C calls (#10002) 2024-02-20 13:42:29 -08:00
Jeremy Evans 77c1233f79 Add pushtoarraykwsplat instruction to avoid unnecessary array allocation
This is designed to replace the newarraykwsplat instruction, which is
no longer used in the parse.y compiler after this commit.  This avoids
an unnecessary array allocation in the case where ARGSCAT is followed
by LIST with keyword:

```ruby
a = []
kw = {}
[*a, 1, **kw]
```

Previous Instructions:

```
0000 newarray                               0                         (   1)[Li]
0002 setlocal_WC_0                          a@0
0004 newhash                                0                         (   2)[Li]
0006 setlocal_WC_0                          kw@1
0008 getlocal_WC_0                          a@0                       (   3)[Li]
0010 splatarray                             true
0012 putobject_INT2FIX_1_
0013 putspecialobject                       1
0015 newhash                                0
0017 getlocal_WC_0                          kw@1
0019 opt_send_without_block                 <calldata!mid:core#hash_merge_kwd, argc:2, ARGS_SIMPLE>
0021 newarraykwsplat                        2
0023 concattoarray
0024 leave
```

New Instructions:

```
0000 newarray                               0                         (   1)[Li]
0002 setlocal_WC_0                          a@0
0004 newhash                                0                         (   2)[Li]
0006 setlocal_WC_0                          kw@1
0008 getlocal_WC_0                          a@0                       (   3)[Li]
0010 splatarray                             true
0012 putobject_INT2FIX_1_
0013 pushtoarray                            1
0015 putspecialobject                       1
0017 newhash                                0
0019 getlocal_WC_0                          kw@1
0021 opt_send_without_block                 <calldata!mid:core#hash_merge_kwd, argc:2, ARGS_SIMPLE>
0023 pushtoarraykwsplat
0024 leave
```

pushtoarraykwsplat is designed to be simpler than newarraykwsplat.
It does not take a variable number of arguments from the stack, it
pops the top of the stack, and appends it to the second from the top,
unless the top of the stack is an empty hash.

During this work, I found the ARGSPUSH followed by HASH with keyword
did not compile correctly, as it pushed the generated hash to the
array even if the hash was empty.  This fixes the behavior, to use
pushtoarraykwsplat instead of pushtoarray in that case:

```ruby
a = []
kw = {}
[*a, **kw]

[{}] # Before

[] # After
```

This does not remove the newarraykwsplat instruction, as it is still
referenced in the prism compiler (which should be updated similar
to this), YJIT (only in the bindings, it does not appear to be
implemented), and RJIT (in a couple comments).  After those are
updated, the newarraykwsplat instruction should be removed.
2024-02-20 10:47:44 -08:00
Alan Wu 2e2e3d89af
YJIT: Support `**nil` for cfuncs
Similar to the iseq call support. Fairly straight forward.
2024-02-20 18:29:02 +00:00
Alan Wu 075b6ac8ae YJIT: Remove unused counters 2024-02-16 18:16:13 -05:00
Alan Wu b4327c1158 YJIT: Support empty splat
Previously we rejected empty splat calls to methods with no parameters
as `iseq_arity_error` which didn't work well with delegated calls.
2024-02-16 15:27:49 -05:00
Alan Wu c4e30d2865 YJIT: Support `**nil`
This adds YJIT support for VM_CALL_KW_SPLAT with nil, specifically for
when we already know from the context that it's done with a nil. This is
enough to support forwarding with `...` when there no keyword arguments
are present.

Amend the kw_rest support to propagate the type of the parameter to help
with this. Test interactions with splat, since the splat array sits
lower on the stack when a kw_splat argument is present.
2024-02-16 15:27:49 -05:00
Takashi Kokubun 9d81741f27 Pop the operand at the end 2024-02-15 16:38:21 -08:00
Takashi Kokubun cdc07236a4 Update a comment on spill_temps() 2024-02-15 16:38:21 -08:00
Takashi Kokubun bda4192e02 Remove duplicated spill_temps() 2024-02-15 16:38:21 -08:00
Aaron Patterson cfe77db00d Spill fewer temps on iv writes
Not all IV writes require calling a C function. If we don't need to
execute a write barrier (IOW the written value is an immediate), and we
don't need to expand the object to accommodate a new IV, we won't need
to make a C call and we can avoid spilling temps.
2024-02-15 16:38:21 -08:00
Alan Wu da7b9478d3
YJIT: Pass nil to anonymous kwrest when empty (#9972)
This is the same optimization as e4272fd29 ("Avoid allocation when
passing no keywords to anonymous kwrest methods") but for YJIT. For
anonymous kwrest parameters, nil is just as good as an empty hash.

On the usage side, update `splatkw` to handle `nil` with a leaner path.
2024-02-15 11:59:37 -05:00
Takashi Kokubun beeee54880
YJIT: Replace perf_fn! with a simpler macro (#9971) 2024-02-14 15:57:24 -08:00
Alan Wu 6f9ca7f453
YJIT: Use i32 over isize for ctx.sp_opnd() (#9968)
It eventually casts it to i32 anyways, and a lot of callers already have
an i32, so using isize was just adding unnecessary casts.
2024-02-14 21:50:58 +00:00
Alan Wu 72f8883a2f YJIT: Extract keyword handling to make gen_send_iseq() shorter
This should make it easier to grok the order of operations.
2024-02-14 16:09:11 -05:00
Aaron Patterson c9ed59c2e2 Update yjit/src/codegen.rs
Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
2024-02-14 12:49:36 -08:00
Aaron Patterson 7943cb22f6 Consider rb_str_getbyte as leaf sometimes
If YJIT knows the parameter to rb_str_getbyte is a fixnum, then I think
we can consider the function to be a leaf
2024-02-14 12:49:36 -08:00
Peter Zhu 1d3b306753 Move rb_class_allocate_instance from gc.c to object.c 2024-02-14 13:43:02 -05:00
Takashi Kokubun 7177731282
YJIT: Add --yjit-perf=codegen option (#9957) 2024-02-14 09:09:14 -08:00
Alan Wu ee3b4bec0e
YJIT: Simplify Kernel#send guards and admit more cases (#9956)
Previously, our compile time check rejected dynamic symbols (e.g. what
String#to_sym could return) even though we could handle them just fine.
The runtime guards for the type of method name was also overly
restrictive and didn't accept dynamic symbols.

Fold the type check into the rb_get_symbol_id() and take advantage of
the guard already checking for 0. This also avoids generating the same
call twice in case the same method name is presented as different
types.
2024-02-14 11:19:04 -05:00