Commit graph

1114 commits

Author SHA1 Message Date
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: 2208671415
See: 2203596331
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.

2178009528 (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
Aaron Patterson
a93f4e3d1a byteslice can return nil so we have to push an "unknown" value 2024-02-13 10:10:19 -08:00
Alan Wu
fdaef7a72e YJIT: Fixup kwrest stack base
I was a little rushed and didn't notice that it was still using the
final stack size even though we don't grow the stack before kwrest
handling anymore. Oh well, we got a new test out of it.

Fix: cbdabd5890
2024-02-13 12:16:36 -05:00
Aaron Patterson
c35fea8509
Specialize String#byteslice(a, b) (#9939)
* Specialize String#byteslice(a, b)

This adds a specialization for String#byteslice when there are two
parameters.

This makes our protobuf parser go from 5.84x slower to 5.33x slower

```
Comparison:
decode upstream (53738 bytes):     7228.5 i/s
decode protobuff (53738 bytes):     1236.8 i/s - 5.84x  slower

Comparison:
decode upstream (53738 bytes):     7024.8 i/s
decode protobuff (53738 bytes):     1318.5 i/s - 5.33x  slower
```

* Update yjit/src/codegen.rs

---------

Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com>
2024-02-13 16:20:27 +00:00