Commit graph

28 commits

Author SHA1 Message Date
Max Bernstein
ef95e5ba3d
ZJIT: Profile type+shape distributions (#13901)
ZJIT uses the interpreter to take type profiles of what objects pass through
the code. It stores a compressed record of the history per opcode for the
opcodes we select.

Before this change, we re-used the HIR Type data-structure, a shallow type
lattice, to store historical type information. This was quick for bringup but
is quite lossy as profiles go: we get one bit per built-in type seen, and if we
see a non-built-in type in addition, we end up with BasicObject. Not very
helpful. Additionally, it does not give us any notion of cardinality: how many
of each type did we see?

This change brings with it a much more interesting slice of type history: a
histogram. A Distribution holds a record of the top-N (where N is fixed at Ruby
compile-time) `(Class, ShapeId)` pairs and their counts. It also holds an
*other* count in case we see more than N pairs.

Using this distribution, we can make more informed decisions about when we
should use type information. We can determine if we are strictly monomorphic,
very nearly monomorphic, or something else. Maybe the call-site is polymorphic,
so we should have a polymorphic inline cache. Exciting stuff.

I also plumb this new distribution into the HIR part of the compilation
pipeline.
2025-08-05 16:56:04 -04:00
Takashi Kokubun
b22eb0e468
ZJIT: Add --zjit-stats (#14034) 2025-07-29 10:00:15 -07:00
Alan Wu
960fae438b
ZJIT: Add missing write barrier in profiling (GH-13922)
Fixes `TestZJIT::test_require_rubygems`. It was crashing locally due to
false collection of a live object. See
<https://alanwu.space/post/write-barrier/>.

Co-authored-by: Max Bernstein <max@bernsteinbear.com>
Co-authored-by: Takashi Kokubun <takashi.kokubun@shopify.com>
Co-authored-by: Stan Lo <stan.lo@shopify.com>
2025-07-16 23:25:37 +00:00
Takashi Kokubun
acc3172530
ZJIT: Profile each instruction at most num_profiles times (#13903)
* ZJIT: Profile each instruction at most num_profiles times

* Use saturating_add for num_profiles
2025-07-16 09:53:10 -07:00
Takashi Kokubun
f5085c70f2
ZJIT: Mark profiled objects when marking ISEQ (#13784) 2025-07-09 16:03:23 -07:00
Stan Lo
6af5398359
ZJIT: Support Regexp type (#13760) 2025-07-02 08:06:59 -04:00
Max Bernstein
665da05141 ZJIT: Pretty-print symbols in HIR dump
This lets us better see what is going on, for example in pattern
matching code, which has a bunch of dynamic method lookups and
`respond_to?` sends.
2025-06-30 19:21:42 -04:00
Stan Lo
dc1b55a387
ZJIT: Add new ZJIT types for Set (#13743) 2025-06-30 09:58:32 -07:00
Jean Boussier
e070d93573 Get rid of rb_shape_lookup 2025-06-12 17:08:22 +02:00
Alan Wu
677c36370f ZJIT: Fix insn arg index for defined, add tests 2025-06-06 22:30:17 +09:00
Max Bernstein
3246bbd325 ZJIT: Add codegen for uncached setinstancevariable 2025-06-06 16:17:54 +09:00
Stan Lo
111986f8b0
ZJIT: Add newrange support (#13505)
* Add newrange support to zjit

* Add RangeType enum for Range insn's flag

* Address other feedback
2025-06-04 18:51:53 -07:00
Jean Boussier
675f33508c Get rid of TOO_COMPLEX shape type
Instead it's now a `shape_id` flag.

This allows to check if an object is complex without having
to chase the `rb_shape_t` pointer.
2025-06-04 13:13:50 +02:00
Jean Boussier
e535f8248b Get rid of rb_shape_id(rb_shape_t *)
We should avoid conversions from `rb_shape_t *` into `shape_id_t`
outside of `shape.c` as the short term goal is to have `shape_id_t`
contain tags.
2025-05-27 12:45:24 +02:00
Alan Wu
92b218fbc3 YJIT: ZJIT: Allow both JITs in the same build
This commit allows building YJIT and ZJIT simultaneously, a "combo
build". Previously, `./configure --enable-yjit --enable-zjit` failed. At
runtime, though, only one of the two can be enabled at a time.

Add a root Cargo workspace that contains both the yjit and zjit crate.
The common Rust build integration mechanisms are factored out into
defs/jit.mk.

Combo YJIT+ZJIT dev builds are supported; if either JIT uses
`--enable-*=dev`, both of them are built in dev mode.

The combo build requires Cargo, but building one JIT at a time with only
rustc in release build remains supported.
2025-05-15 00:39:03 +09:00
Jean Boussier
ea77250847 Rename RB_OBJ_SHAPE -> rb_obj_shape
As well as `RB_OBJ_SHAPE_ID` -> `rb_obj_shape_id`
and `RSHAPE` is now a simple alias for `rb_shape_lookup`.

I tried to turn all these into `static inline` but I'm having
trouble with `RUBY_EXTERN rb_shape_tree_t *rb_shape_tree_ptr;`
not being exposed as I'd expect.
2025-05-09 10:22:51 +02:00
Jean Boussier
5782561fc1 Rename rb_shape_get_shape_id -> RB_OBJ_SHAPE_ID
And `rb_shape_get_shape` -> `RB_OBJ_SHAPE`.
2025-05-09 10:22:51 +02:00
Jean Boussier
c9b08882b7 Refactor rb_shape_get_next to return an ID
Also rename it, and change parameters to be consistent with
other transition functions.
2025-05-09 10:22:51 +02:00
Jean Boussier
3f7c0af051 Rename rb_shape_obj_too_complex -> rb_shape_obj_too_complex_p 2025-05-09 10:22:51 +02:00
Jean Boussier
334ebba221 Rename rb_shape_get_shape_by_id -> RSHAPE 2025-05-09 10:22:51 +02:00
Jean Boussier
6c9b3ac232 Refactor OBJ_TOO_COMPLEX_SHAPE_ID to not be referenced outside shape.h
Also refactor checks for `->type == SHAPE_OBJ_TOO_COMPLEX`.
2025-05-08 07:58:05 +02:00
Alan Wu
33909a1c69 YJIT: ZJIT: Share identical glue functions
Working towards having YJIT and ZJIT in the same build, we need to
deduplicate some glue code that would otherwise cause name collision.
Add jit.c for this and build it for YJIT and ZJIT builds. Update bindgen
to look at jit.c; some shuffling of functions in the output, but the set
of functions shouldn't have changed.
2025-05-02 23:47:57 +09:00
Max Bernstein
6052b12de4
ZJIT: Replace GetConstantPath with Const if the IC is not empty (#13183)
* Add rb_zjit_constcache_shareable

* Add rb_zjit_multi_ractor_p

* Replace GetConstantPath with Const if the IC is not empty
2025-04-28 12:10:26 -07:00
Alan Wu
3e57c4dceb Strength reduce to CCall for sends landing in simple C methods
A new optimization pass. Also:
- Printing for `Insn::CCall`
- Wrap `ID` and add convenience method for printing, replacing calls to rb_id2name()
2025-04-18 21:53:01 +09:00
Takashi Kokubun
8b72e07359 Disable ZJIT profiling at call-threshold (https://github.com/Shopify/zjit/pull/99)
* Disable ZJIT profiling at call-threshold

* Stop referencing ZJIT instructions in codegen
2025-04-18 21:53:01 +09:00
Takashi Kokubun
d488f74dee Resurrect icache invalidation for arm64 (https://github.com/Shopify/zjit/pull/68)
* Resurrect icache invalidation for arm64

* Get rid of cfg(not(test))
2025-04-18 21:53:00 +09:00
Takashi Kokubun
ae17323a65 Move a couple of bindgen targets to ZJIT bindgen
We filed https://github.com/Shopify/zjit/pull/65 and
https://github.com/Shopify/zjit/pull/64 concurrently.
2025-04-18 21:53:00 +09:00
Takashi Kokubun
5a35c47c82 Stop sharing yjit/bindgen with ZJIT (https://github.com/Shopify/zjit/pull/64)
* cp -r yjit/bindgen zjit/

* Rename YJIT variables

* Stop mentioning YJIT in zjit.c
2025-04-18 21:53:00 +09:00