summaryrefslogtreecommitdiff
path: root/zjit.c
AgeCommit message (Collapse)Author
2025-12-16ZJIT: Use rb_zjit_writebarrier_check_immediate() instead of ↵Benoit Daloze
rb_gc_writebarrier() in gen_write_barrier() * To avoid calling rb_gc_writebarrier() with an immediate value in gen_write_barrier(), and avoid the LIR jump issue.
2025-12-10ZJIT: Remove unused includes from zjit.cAlan Wu
2025-12-09ZJIT: Prohibit ZJIT support with USE_FLONUM=0 (#15471)Takashi Kokubun
2025-12-10Add `NUM2PTR` and `PTR2NUM` macrosNobuyoshi Nakada
These macros have been defined here and there, so collect them.
2025-12-09ZJIT: Add dump to file for --zjit-stats (#15414)Aiden Fox Ivey
* ZJIT: Add dump to file for --zjit-stats * ZJIT: Rename --zjit-stats=quiet to --zjit-stats-quiet
2025-12-09Fixed by `misspell -w -error -source=text`Hiroshi SHIBATA
2025-12-05ZJIT: Avoid binding to `rb_iseq_constant_body`Alan Wu
Its definition changes depending on e.g. whether there is YJIT in the build.
2025-11-18ZJIT: add support for lazy `RubyVM::ZJIT.enable`Godfrey Chan
This implements Shopify#854: - Splits boot-time and enable-time initialization, tracks progress with `InitializationState` enum - Introduces `RubyVM::ZJIT.enable` Ruby method for enabling the JIT lazily, if not already enabled - Introduces `--zjit-disable` flag, which can be used alongside the other `--zjit-*` flags but prevents enabling the JIT at boot time - Adds ZJIT infra to support JIT hooks, but this is not currently exercised (Shopify/ruby#667) Left for future enhancements: - Support kwargs for overriding the CLI flags in `RubyVM::ZJIT.enable` Closes Shopify#854
2025-11-06ZJIT: Untag block handler (#15085)Max Bernstein
Storing the tagged block handler in profiles is not GC-safe (nice catch, Kokubun). Store the untagged block handler instead. Fix bug in https://github.com/ruby/ruby/pull/15051
2025-11-05ZJIT: Profile specific objects for invokeblock (#15051)Max Bernstein
I made a special kind of `ProfiledType` that looks at specific objects, not just their classes/shapes (https://github.com/ruby/ruby/pull/15051). Then I profiled some of our benchmarks. For lobsters: ``` Top-6 invokeblock handler (100.0% of total 1,064,155): megamorphic: 494,931 (46.5%) monomorphic_iseq: 337,171 (31.7%) polymorphic: 113,381 (10.7%) monomorphic_ifunc: 52,260 ( 4.9%) monomorphic_other: 38,970 ( 3.7%) no_profiles: 27,442 ( 2.6%) ``` For railsbench: ``` Top-6 invokeblock handler (100.0% of total 2,529,104): monomorphic_iseq: 834,452 (33.0%) megamorphic: 818,347 (32.4%) polymorphic: 632,273 (25.0%) monomorphic_ifunc: 224,243 ( 8.9%) monomorphic_other: 19,595 ( 0.8%) no_profiles: 194 ( 0.0%) ``` For shipit: ``` Top-6 invokeblock handler (100.0% of total 2,104,148): megamorphic: 1,269,889 (60.4%) polymorphic: 411,475 (19.6%) no_profiles: 173,367 ( 8.2%) monomorphic_other: 118,619 ( 5.6%) monomorphic_iseq: 84,891 ( 4.0%) monomorphic_ifunc: 45,907 ( 2.2%) ``` Seems like a monomorphic case for a specific ISEQ actually isn't a bad way of going about this, at least to start...
2025-10-21ZJIT: Fix binding to `INVALID_SHAPE_ID` under `-std=c99 -pedantic`Alan Wu
``` /src/jit.c:19:5: error: ISO C restricts enumerator values to range of 'int' (4294967295 is too large) [-Werror,-Wpedantic] 19 | RB_INVALID_SHAPE_ID = INVALID_SHAPE_ID, | ^ ~~~~~~~~~~~~~~~~ ```
2025-10-09ZJIT: Name enum for bindgen (#14802)Max Bernstein
Relying on having the same compiler version and behavior across platforms is brittle, as Kokubun points out. Instead, name the enum so we don't have to rely on gensym stability. Fix https://github.com/Shopify/ruby/issues/787
2025-09-30ZJIT: Add correction rb_zjit_exit_locations_dictAiden Fox Ivey
2025-09-30ZJIT: Add extra info to rb_zjit_add_frameAiden Fox Ivey
2025-09-30ZJIT: Add --zjit-trace-exits (#14640)Aiden Fox Ivey
Add side exit tracing functionality for ZJIT
2025-09-18ZJIT: Support variadic C calls (#14575)Stan Lo
* ZJIT: Support variadic C calls This reduces the `dynamic_send_count` in `liquid-render` by ~21% * ZJIT: Reuse gen_push_frame * ZJIT: Avoid optimizing variadic C call when tracing is enabled
2025-09-17ZJIT: Prevent custom allocator in ObjectAllocClassMax Bernstein
2025-09-17ZJIT: Const-fold IsMethodCfuncMax Bernstein
2025-09-16ZJIT: Print local names in FrameState (#14571)Max Bernstein
2025-09-12ZJIT: Share more code with YJIT in jit.c (#14520)Takashi Kokubun
* ZJIT: Share more code with YJIT in jit.c * Fix ZJIT references to JIT
2025-09-08ZJIT: Add RubyVM::ZJIT.reset_stats! method (GH-14479)Randy Stauner
This allows for more precise tracking of stats programmatically which is particularly useful for our nightly benchmarking suite. - Define rust function - Expose to C - Wrap with Ruby API - Add a test
2025-09-08ZJIT: Add --zjit-stats=quiet option to collect stats without printing (#14467)Randy Stauner
Similar to YJIT's --yjit-stats=quiet, this option allows ZJIT to collect statistics and make them available via the Ruby API without printing them at exit. This is useful for programmatic access to stats without the output noise. - Added print_stats field to Options struct - Modified option parsing to support --zjit-stats=quiet - Added rb_zjit_print_stats_p primitive to check if stats should be printed - Updated zjit.rb to only register at_exit handler when print_stats is true - Update the help text shown by `ruby --help` to indicate that --zjit-stats now accepts an optional =quiet parameter. - Added test for --zjit-stats=quiet option
2025-09-05ZJIT: Invalidate local variables on EP escape (#14448)Takashi Kokubun
2025-09-03ZJIT: Count exits coming from jit_exception (#14428)Takashi Kokubun
2025-08-29Add rb_jit_vm_unlock and share it in ZJIT and YJITStan Lo
2025-08-29Add rb_jit_vm_lock_then_barrier and share it in ZJIT and YJITStan Lo
2025-08-29Add rb_jit_multi_ractor_p and share it in ZJIT and YJITStan Lo
2025-08-29ZJIT: Specialize monomorphic GetIvar (#14388)Max Bernstein
Specialize monomorphic `GetIvar` into: * `GuardType(HeapObject)` * `GuardShape` * `LoadIvarEmbedded` or `LoadIvarExtended` This requires profiling self for `getinstancevariable` (it's not on the operand stack). This also optimizes `GetIvar`s that happen as a result of inlining `attr_reader` and `attr_accessor`. Also move some (newly) shared JIT helpers into jit.c.
2025-08-28ZJIT: Disable profiling in compile_iseq (#14385)Max Bernstein
This catches both the interpreter-JIT and JIT-JIT cases. Fixes https://github.com/Shopify/ruby/issues/719
2025-08-28ZJIT: Generate code for DefinedIvarMax Bernstein
2025-08-22ZJIT: Allow querying a single ZJIT stat (#14309)Takashi Kokubun
* ZJIT: Add RubyVM::ZJIT.stats_enabled? * ZJIT: Allow querying a single ZJIT stat
2025-08-21Remove unused SPECIAL_CONST_SHAPE_IDÉtienne Barrié
Its usage was removed in 306d50811dd060d876d1eb364a0d5e6106f5e4f1.
2025-08-05ZJIT: Profile type+shape distributions (#13901)Max Bernstein
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-07-29ZJIT: Add --zjit-stats (#14034)Takashi Kokubun
2025-07-16ZJIT: Profile each instruction at most num_profiles times (#13903)Takashi Kokubun
* ZJIT: Profile each instruction at most num_profiles times * Use saturating_add for num_profiles
2025-07-11Add Set C-APIJeremy Evans
This should be a minimal C-API needed to deal with Set objects. It supports creating the sets, checking whether an element is the set, adding and removing elements, iterating over the elements, clearing a set, and returning the size of the set. Co-authored-by: Nobuyoshi Nakada <nobu.nakada@gmail.com>
2025-07-09Fix whitespace on some RB_VM_LOCKING callsJohn Hawthorn
2025-06-30ZJIT: Add new ZJIT types for Set (#13743)Stan Lo
2025-06-04Get rid of TOO_COMPLEX shape typeJean Boussier
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. Notes: Merged: https://github.com/ruby/ruby/pull/13511
2025-05-26* remove trailing spaces. [ci skip]git
2025-05-25Use RB_VM_LOCKINGNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/13439
2025-05-15YJIT: ZJIT: Allow both JITs in the same buildAlan Wu
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. Notes: Merged: https://github.com/ruby/ruby/pull/13262
2025-05-02YJIT: ZJIT: Share identical glue functionsAlan Wu
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. Notes: Merged: https://github.com/ruby/ruby/pull/13229
2025-04-28ZJIT: Replace GetConstantPath with Const if the IC is not empty (#13183)Max Bernstein
* Add rb_zjit_constcache_shareable * Add rb_zjit_multi_ractor_p * Replace GetConstantPath with Const if the IC is not empty Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2025-04-28ZJIT: Drop trace_zjit_* instructions (#13189)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2025-04-18Disable ZJIT profiling at call-threshold ↵Takashi Kokubun
(https://github.com/Shopify/zjit/pull/99) * Disable ZJIT profiling at call-threshold * Stop referencing ZJIT instructions in codegen Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Resurrect icache invalidation for arm64 ↵Takashi Kokubun
(https://github.com/Shopify/zjit/pull/68) * Resurrect icache invalidation for arm64 * Get rid of cfg(not(test)) Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Stop sharing yjit/bindgen with ZJIT (https://github.com/Shopify/zjit/pull/64)Takashi Kokubun
* cp -r yjit/bindgen zjit/ * Rename YJIT variables * Stop mentioning YJIT in zjit.c Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Print Ruby exception in test utilsMax Bernstein
Notes: Merged: https://github.com/ruby/ruby/pull/13131
2025-04-18Assert everything is compiled in test_zjit ↵Takashi Kokubun
(https://github.com/Shopify/zjit/pull/40) * Assert everything is compiled in test_zjit * Update a comment on rb_zjit_assert_compiles Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> * Add a comment about assert_compiles * Actually use pipe_fd --------- Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Notes: Merged: https://github.com/ruby/ruby/pull/13131