summaryrefslogtreecommitdiff
path: root/yjit/src/core.rs
AgeCommit message (Collapse)Author
2023-09-16[For ruby_3_2] Fix unused_mut Rust warnings (#8435)Alan Wu
Fix unused_mut Rust warnings Rust version 1.71.0 and up issue these warnings. On GitHub CI, the warnings were previously seen in -DYJIT_FORCE_ENABLE runs.
2022-12-15YJIT: Fix code GC freeing stubs with a trampoline (#6937)Alan Wu
Stubs we generate for invalidation don't necessarily co-locate with the code that jump to the stub. Since we rely on co-location to keep stubs alive as they are in the outlined code block, it used to be possible for code GC inside branch_stub_hit() to free the stub that's its direct caller, leading us to return to freed code after. Stubs used to look like: ``` mov arg0, branch_ptr mov arg1, target_idx mov arg2, ec call branch_stub_hit jmp return_reg ``` Since the call and the jump after the call is the same for all stubs, we can extract them and use a static trampoline for them. That makes branch_stub_hit() always return to static code. Stubs now look like: ``` mov arg0, branch_ptr mov arg1, target_idx jmp trampoline ``` Where the trampoline is: ``` mov arg2, ec call branch_stub_hit jmp return_reg ``` Code GC can now free stubs without problems since we'll always return to the trampoline, which we generate once on boot and lives forever. This might save a small bit of memory due to factoring out the static part of stubs, but it's probably minor. [Bug #19234] Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-12-08YJIT: Drop Copy trait from Context (#6889)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-30YJIT: add new counters for deferred compilation and queued blocks (#6837)Maxime Chevalier-Boisvert
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-30YJIT: Deallocate `struct Block` to plug memory leaksAlan Wu
Previously we essentially never freed block even after invalidation. Their reference count never reached zero for a couple of reasons: 1. `Branch::block` formed a cycle with the block holding the branch 2. Strong count on a branch that has ever contained a stub never reached 0 because we increment the `.clone()` call for `BranchRef::into_raw()` didn't have a matching decrement. It's not safe to immediately deallocate blocks during invalidation since `branch_stub_hit()` can end up running with a branch pointer from an invalidated branch. To plug the leaks, we wait until code GC or global invalidation and deallocate the blocks for iseqs that are definitely not running. Notes: Merged: https://github.com/ruby/ruby/pull/6833
2022-11-24YJIT: rename `InsnOpnd` => `YARVOpnd` (#6801)Maxime Chevalier-Boisvert
Rename InsnOpnd => YARVOpnd Make it more clear this refers to YARV insn/vm operands rather than backend IR, x86 or ARM insn operands. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-23YJIT: Use a Box for branch targets to save memoryAlan Wu
We frequently make branches that only have one target but we used to always allocate space for two branch targets. This patch moves all the information a branch target has into a struct and refer to them using Option<Box<BranchTarget>>, this way when the second branch target is not present it only takes 8 bytes. Retained heap size on railsbench went from 16.17 MiB to 14.57 MiB, a ratio of about 1.1. Notes: Merged: https://github.com/ruby/ruby/pull/6799
2022-11-22YJIT: Skip padding jumps to side exits on Arm (#6790)Takashi Kokubun
YJIT: Skip padding jumps to side exits Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-18YJIT: Improve the failure message on enlarging a branch (#6769)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-11-16YJIT: Shrink version lists after mutation (#6749)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-11-16YJIT: Pack BlockId and CodePtr (#6748)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-11-16YJIT: Add compiled_branch_count stats (#6746)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-11-16YJIT: Stop wrapping CmePtr with CmeDependency (#6747)Takashi Kokubun
* YJIT: Stop wrapping CmePtr with CmeDependency * YJIT: Fix an outdated comment [ci skip] Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-11-16YJIT: Shrink the vectors of Block after mutation (#6739)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-11-15YJIT: Invalidate redefined methods only through cme (#6734)Takashi Kokubun
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-11-13YJIT: Remove unused src_ctx from Block (#6714)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-08YJIT: Reset dropped_bytes when patching codeAlan Wu
We switch to a new page when we detect dropped_bytes flipping from false to true. Previously, when we patch code for invalidation during code gc, we start with the flag being set to true, so we failed to apply patches that straddle pages. We would write out jumps half way and then stop, which left the code corrupted. Reset the flag before patching so we patch across pages properly. Notes: Merged: https://github.com/ruby/ruby/pull/6686
2022-11-03YJIT: Fix a wrong type reference (#6661)Takashi Kokubun
* YJIT: Fix a wrong type reference * YJIT: Just remove CapturedSelfOpnd for now Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-02YJIT: Support invokeblock (#6640)Takashi Kokubun
* YJIT: Support invokeblock * Update yjit/src/backend/arm64/mod.rs * Update yjit/src/codegen.rs Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-02YJIT: Avoid accumulating freed pages in the payload (#6657)Takashi Kokubun
Co-Authored-By: Alan Wu <alansi.xingwu@shopify.com> Co-Authored-By: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-01YJIT: Add an assert to help with Context changesAlan Wu
While experimenting I found that it's easy to change Context and forget to also change the copying operation in limit_block_versions(). Add an assert to make sure we substitute a compatible generic context when limiting the number of versions. Notes: Merged: https://github.com/ruby/ruby/pull/6656
2022-11-01YJIT: Delete redundant ways to make ContextAlan Wu
Context::new() is the same as Context::default() and Context::new_with_stack_size() was only used in tests. Notes: Merged: https://github.com/ruby/ruby/pull/6656
2022-10-26YJIT: Support nil and blockparamproxy as blockarg in send (#6492)Matthew Draper
Co-authored-by: John Hawthorn <john@hawthorn.email> Co-authored-by: John Hawthorn <john@hawthorn.email> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-10-25YJIT: GC and recompile all code pages (#6406)Takashi Kokubun
when it fails to allocate a new page. Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-10-19YJIT: Respect writable_addrs on --yjit-dump-iseq-disasm as well (#6596)Takashi Kokubun
YJIT: Respect writable_addrs on --yjit-dump-iseq-disasm as well Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-10-18Fixes remaining issues and turns back on dead code and unused (#6584)Jimmy Miller
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-10-18Allow passing a Rust closure to rb_iseq_callback (#6575)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-10-17YJIT: Interleave inline and outlined code blocks (#6460)Takashi Kokubun
Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-10-17YJIT: call free_block to cleanup block when out of memoryAlan Wu
The commented out instance of free_block() is left over from the port. The addition in gen_single_block() was a place we missed. The new block is allocated in the same function and could have invariants associated with it even though there is no space to hold all the code. Notes: Merged: https://github.com/ruby/ruby/pull/6551
2022-10-14YJIT: Avoid creating payloads for non-JITed ISEQs (#6549)Takashi Kokubun
* YJIT: Count freed ISEQs * YJIT: Avoid creating payloads for non-JITed ISEQs Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-10-13fixes more clippy warnings (#6543)Jimmy Miller
* fixes more clippy warnings * Fix x86 c_callable to have doc_strings Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-10-11Implement optimize send in yjit (#6488)Jimmy Miller
* Implement optimize send in yjit This successfully makes all our benchmarks exit way less for optimize send reasons. It makes some benchmarks faster, but not by as much as I'd like. I think this implementation works, but there are definitely more optimial arrangements. For example, what if we compiled send to a jump table? That seems like perhaps the most optimal we could do, but not obvious (to me) how to implement give our current setup. Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> * Attempt at fixing the issues raised by @XrXr * fix allowlist * returns 0 instead of nil when not found * remove comment about encoding exception * Fix up c changes * Update assert Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> * get rid of unneeded code and fix the flags * Apply suggestions from code review Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> * rename and fix typo Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-10-06YJIT: add an assert for branch_stub_hit() (#6505)Alan Wu
We set the PC in branch_stub_hit(), which only makes sense if we're running with the intended iseq for the stub. We ran into an issue caught by this while tweaking code layout. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-09-09YJIT: Branch directly when nil? is known from typesJohn Hawthorn
Notes: Merged: https://github.com/ruby/ruby/pull/6350
2022-09-01Let --yjit-dump-disasm=all dump ocb code as well (#6309)Takashi Kokubun
* Let --yjit-dump-disasm=all dump ocb code as well * Use an enum instead * Add a None Option to DumpDisasm (#444) * Add a None Option to DumpDisasm * Update yjit/src/asm/mod.rs Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> * Fix a build failure * Use only a single name * Only None will be a disabled case * Fix cargo test * Fix --yjit-dump-disasm=all to print outlined cb Co-authored-by: Jimmy Miller <jimmyhmiller@gmail.com> Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-08-29Add --yjit-dump-disasm to dump every compiled code ↵Takashi Kokubun
(https://github.com/Shopify/ruby/pull/430) * Add --yjit-dump-disasm to dump every compiled code * Just use get_option * Carve out disasm_from_addr * Avoid push_str with format! * Share the logic through asm.compile * This seems to negatively impact the compilation speed Notes: Merged: https://github.com/ruby/ruby/pull/6289
2022-08-29Fix a bus error on regenerate_branch (https://github.com/Shopify/ruby/pull/408)Takashi Kokubun
* Fix a bus error on regenerate_branch * Fix pad_size Notes: Merged: https://github.com/ruby/ruby/pull/6289
2022-08-29Port jit_rb_str_concat to new backend, re-enable cfunc lookup ↵Noah Gibbs (and/or Benchmark CI)
(https://github.com/Shopify/ruby/pull/402)
2022-08-29Fix block invalidation with new backend. Enable more btests on x86 ↵Maxime Chevalier-Boisvert
(https://github.com/Shopify/ruby/pull/359)
2022-08-29Minor cleanups (https://github.com/Shopify/ruby/pull/345)Alan Wu
* Move allocation into Assembler::pos_marker We wanted to do this to begin with but didn't because we were confused about the lifetime parameter. It's actually talking about the lifetime of the references that the closure captures. Since all of our usages capture no references (they use `move`), it's fine to put a `+ 'static` here. * Use optional token syntax for calling convention macro * Explicitly request C ABI on ARM It looks like the Rust calling convention for functions are the same as the C ABI for now and it's unlikely to change, but it's easy for us to be explicit here. I also tried saying `extern "aapcs"` but that unfortunately doesn't work.
2022-08-29Refactor YJIT branches to use PosMarker ↵Maxime Chevalier-Boisvert
(https://github.com/Shopify/ruby/pull/333) * Refactor defer_compilation to use PosMarker * Port gen_direct_jump() to use PosMarker * Port gen_branch, branchunless * Port over gen_jump() * Port over branchif and branchnil * Fix use od record_boundary_patch_point in jump_to_next_insn
2022-08-29Implement PosMarker instruction (https://github.com/Shopify/ruby/pull/328)Maxime Chevalier-Boisvert
* Implement PosMarker instruction * Implement PosMarker in the arm backend * Make bindgen run only for clang image * Fix if-else in cirrus CI file * Add missing semicolon * Try removing trailing semicolon * Try to fix shell/YAML syntax Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
2022-08-29Fix compile errors on arm on the CI (https://github.com/Shopify/ruby/pull/313)Maxime Chevalier-Boisvert
* Fix compile errors on arm on the CI * Fix typo
2022-08-29Get codegen for deferred compilation workingMaxime Chevalier-Boisvert
2022-08-29Port over get_branch_target()Maxime Chevalier-Boisvert
2022-08-29Have Assembler::compile() return a list of GC offsetsMaxime Chevalier-Boisvert
2022-08-29Remove x86_64 dependency in core.rsMaxime Chevalier-Boisvert
2022-08-29Implement gc offset logicMaxime Chevalier-Boisvert
2022-08-24add --yjit-dump-iseqs param (https://github.com/Shopify/ruby/pull/332)Noah Gibbs
Notes: Merged: https://github.com/ruby/ruby/pull/6278
2022-08-04YJIT: Add known_* helpers for Type (#6208)John Hawthorn
* YJIT: Add known_* helpers for Type This adds a few helpers to Type which all return Options representing what is known, from a Ruby perspective, about the type. This includes: * known_class_of: If known, the class represented by this type * known_value_type: If known, the T_ value type * known_exact_value: If known, the exact VALUE represented by this type (currently this is only available for true/false/nil) * known_truthy: If known, whether or not this value evaluates as true (not false or nil) The goal of this is to abstract away the specifics of the mappings between types wherever possible from the codegen. For example previously by introducing Type::CString as a more specific version of Type::TString, uses of Type::TString in codegen needed to be updated to check either case. Now by using known_value_type, at least in theory we can introduce new types with minimal (if any) codegen changes. I think rust's Option type allows us to represent this uncertainty fairly well, and should help avoid mistakes, and the matching using this turned out pretty cleanly. * YJIT: Use known_value_type for checktype * YJIT: Use known_value_type for T_STRING check * YJIT: Use known_class_of in guard_known_klass * YJIT: Use known truthyness in jit_rb_obj_not * YJIT: Rename known_class_of => known_class Notes: Merged-By: maximecb <maximecb@ruby-lang.org>