summaryrefslogtreecommitdiff
path: root/zjit
AgeCommit message (Collapse)Author
2025-08-13ZJIT: Don't eliminate NewHash with operandsMax Bernstein
Hashing and checking operands for equality is re-entrant. We could later optimize this to check for hash/eq methods on operands and eliminate if they don't have side effects, but this is fine for now.
2025-08-13ZJIT: Only validate HIR in debug modeMax Bernstein
2025-08-12ZJIT: Prepare non-leaf calls for SetGlobal (#14197)Stan Lo
When trace_var is used, setting a global variable can cause exceptions to be raised. We need to prepare for that.
2025-08-12ZJIT: Avoid compiling failed ISEQs repeatedly (#14195)Takashi Kokubun
2025-08-12ZJIT: Add flag to disable the HIR optimizer (#14181)Max Bernstein
Also add a check in the bisect script that can assign blame to the HIR optimizer.
2025-08-12ZJIT: Avoid splitting add_into/sub_into for x86_64 (#14177)Takashi Kokubun
* ZJIT: Avoid splitting add_into/sub_into * Require add_into/sub_into to take a Reg
2025-08-11CI: Surface Rust warnings on PRs that touch any Rust codeAlan Wu
Rust PRs will have a failed CI step if they trigger any warnings. This helps us stay on top of warnings from new Rust releases and also ones we accidentally write. Fix a typo for demo, since this only runs when Rust files are changed.
2025-08-11ZJIT: Add --zjit-exec-mem-size (#14175)Takashi Kokubun
* ZJIT: Add --zjit-exec-mem-size * Add a comment about the limit
2025-08-11ZJIT: Implement `concatstrings` insn (#14154)Stan Lo
Co-authored-by: Alexander Momchilov <alexander.momchilov@shopify.com>
2025-08-11ZJIT: Add compile/profile/GC/invalidation time stats (#14158)Takashi Kokubun
Co-authored-by: Stan Lo <stan001212@gmail.com>
2025-08-11ZJIT: Fix `mismatched_lifetime_syntaxes`, new in Rust 1.89.0Alan Wu
2025-08-08ZJIT: Avoid compiling and direct sends to forwardable ISEQsAlan Wu
These `...` ISEQs have a special calling convention in the interpreter and our stubs and JIT calling convention don't deal well. Reject for now. Debugged with help from `@tekknolagi` and `tool/zjit_bisect.rb`. Merely avoiding direct sends is enough to pass the attached test, but also avoid compiling ISEQs with `...` parameter to limit exposure for now. `SendWithoutBlock`, which does dynamic dispatch using interpreter code, seems to handle calling into forwardable ISEQs correctly, so they are fine -- we can't predict where these dynamic sends land anyways.
2025-08-08ZJIT: Fix "memory operand with non-register base" (#14153)Takashi Kokubun
2025-08-08ZJIT: Add a graphviz dumper for HIR (#14117)Max Bernstein
This is moderately useful just in stdout (copy and paste into a renderer) but potentially more useful alongside a tool that parses stdout looking for `digraph G { ... }` and renders those automatically.
2025-08-07ZJIT: Remove the need for unwrap() on with_num_bits() (#14144)Takashi Kokubun
* ZJIT: Remove the need for unwrap() on with_num_bits() * Fix arm64 tests * Track the caller of with_num_bits Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> --------- Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2025-08-07ZJIT: Implement `defined?` codegen for non-yield calls (#14101)Stan Lo
2025-08-07ZJIT: Optimize class guards by directly reading klass field (#14136)Stan Lo
Replace `rb_yarv_class_of` call with: - a constant check for special constants (nil, fixnums, symbols, etc) - a check for false - direct memory read at offset 8 for regular heap objects for the class check
2025-08-07ZJIT: Remove GC offsets overwritten by invalidation (#14102)Takashi Kokubun
ZJIT: Remove GC offsts overwritten by invalidation
2025-08-07ZJIT: Create HeapObject Type (#14140)Max Bernstein
This is a counterpoint to the Immediate type and it represents all BasicObject subclasses except for the several immediate objects. If we know something is a HeapObject, we know we can treat it as an RBasic pointer.
2025-08-07ZJIT: Set PC before StringCopy (#14141)Max Bernstein
ZJIT: Set PC before StringCopy This function allocates.
2025-08-06ZJIT: Inline attr_reader/attr_accessor (#14126)Max Bernstein
We can rewrite SendWithoutBlock to GetIvar.
2025-08-06ZJIT: Implement SingleRactorMode invalidation (#14121)Stan Lo
* ZJIT: Implement SingleRactorMode invalidation * ZJIT: Add macro for compiling jumps * ZJIT: Fix typo in comment * YJIT: Fix typo in comment * ZJIT: Avoid using unexported types in zjit.h `enum ruby_vminsn_type` is declared in `insns.inc` and is not exported. Using it in `zjit.h` would cause build errors when the file including it doesn't include `insns.inc`.
2025-08-06ZJIT: x86: split: Fix live ranges index-out-of-range panicAlan Wu
Previously we crashed panicked due to index bounds check running test_fixnum.rb. On ARM and in other places in the x86 backend, this isn't a problem because they inspect the output of instructions which is never replaced.
2025-08-06ZJIT: Fix "immediate value too large" on cmp for x86_64 (#14125)Takashi Kokubun
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com>
2025-08-05ZJIT: Fix `Kernel#Float`'s annotation (#14123)Stan Lo
As pointed out in https://github.com/ruby/ruby/pull/14078#discussion_r2255427676, the return type should be `Float` instead.
2025-08-05ZJIT: Avoid matching built-in iseq's HIR line numbers in tests (#14124)Stan Lo
ZJIT: Avoid matching built-in ISEQs' HIR line numbers in tests Co-authored-by: Author: Takashi Kokubun <takashi.kokubun@shopify.com>
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-08-04ZJIT: Add helpers to prepare for C calls (#14100)Takashi Kokubun
2025-08-01ZJIT: Reject builtin annotation if its iseq has multiple invokebuiltin insnsStan Lo
2025-08-01ZJIT: Annotate Kernel#classStan Lo
2025-08-01ZJIT: Improve builtin function annotation collectionStan Lo
2025-08-01ZJIT: Support annotating builtin functionsStan Lo
This allows us to annotate builtin functions with their return type.
2025-08-01ZJIT: Enable IncrCounter for arm64 (#14086)Takashi Kokubun
2025-08-01ZJIT: Refer to scratch registers in operandsAlan Wu
Co-authored-by: Takashi Kokubun <takashi.kokubun@shopify.com>
2025-08-01ZJIT: Fix side-exit panicking when there's too many localsAlan Wu
Previously, ARM64 panicked due to compiled_side_exits() when the memory displacement got large enough to exceed the 9 bits limit. Usually, we split these kind of memory operands, but compiled_side_exits() runs after split. Using scratch registers, implement `Insn::Store` on ARM such that it can handle large displacements without split(). Do this for x86 as well, and remove arch specific code from compiled_side_exits(). We can now run `TestKeywordArguments`. Since `Insn::Store` doesn't need splitting now, users enjoy lower register pressure. Downside is, using `Assembler::SCRATCH_REG` as a base register is now sometimes an error, depending on whether `Insn::Store` also needs to use the register. It seems a fair trade off since `SCRATCH_REG` is not often used, and we don't put it as a base register anywhere at the moment.
2025-08-01ZJIT: A64: Use MOVN for small negative immediatesAlan Wu
Save a couple instructions to load a small negative constant into a register. In fact MOVN is speced to alias as `mov` in the official disassembly.
2025-07-31ZJIT: Add the ISEQ name to Block asm comments (#14070)Takashi Kokubun
2025-07-31ZJIT: Stub JIT-to-JIT calls (#14052)Takashi Kokubun
2025-07-31ZJIT: A64: Fix splitting for large memory displacementsAlan Wu
On the ruby side, this fixes a crash for methods with 39 or more parameters. We used to miscomp those entry points due to Insn::Lea picking ADDS which cannot reference SP: # set method params: 40 mov x0, #0xfee8 movk x0, #0xffff, lsl #16 movk x0, #0xffff, lsl #32 movk x0, #0xffff, lsl #48 adds x0, xzr, x0 Have Lea work for all i32 displacements and avoid involving the split pass. Previously, direct use of Insn::Lea directly from the user (as opposed to generated by the split pass for some memory operations) wasn't split, so being able to handle the whole range in arm64_emit() was implicitly required. Also, not going through split reduces register pressure.
2025-07-31ZJIT: Remove false comment [ci skip]Alan Wu
2025-07-31ZJIT: Only build the assembler for `target_arch`Alan Wu
Fixes test error from running the ARM assembler on x86, but then trying to disassemble it as x86.
2025-07-31ZJIT: A64: Add add_extended() which can add a register to spAlan Wu
2025-07-30ZJIT: Don't create owned Cow/String when printingMax Bernstein
2025-07-30ZJIT: Don't make unnecessary CowMax Bernstein
2025-07-30ZJIT: Don't write to StringMax Bernstein
2025-07-30ZJIT: Get rid of CallInfoMax Bernstein
2025-07-30ZJIT: Deref struct in find()Max Bernstein
2025-07-30ZJIT: Remove catch-all case to make it clearer what's unimplementedMax Bernstein
2025-07-30ZJIT: Remove unused ArraySet instructionMax Bernstein
2025-07-30ZJIT: Prepare for sharing JIT hooks with ZJIT (#14044)Takashi Kokubun