summaryrefslogtreecommitdiff
path: root/yjit/src/core.rs
AgeCommit message (Collapse)Author
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>
2022-06-27Separate Type::String into Type::CString and Type::TString.Noah Gibbs (and/or Benchmark CI)
Also slightly broaden the cases where << on two strings will generate specialised code rather than a plain method call. Notes: Merged: https://github.com/ruby/ruby/pull/6022
2022-06-14YJIT: On-demand executable memory allocation; faster boot (#5944)Alan Wu
This commit makes YJIT allocate memory for generated code gradually as needed. Previously, YJIT allocates all the memory it needs on boot in one go, leading to higher than necessary resident set size (RSS) and time spent on boot initializing the memory with a large memset(). Users should no longer need to search for a magic number to pass to `--yjit-exec-mem` since physical memory consumption should now more accurately reflect the requirement of the workload. YJIT now reserves a range of addresses on boot. This region start out with no access permission at all so buggy attempts to jump to the region crashes like before this change. To get this hardening at finer granularity than the page size, we fill each page with trapping instructions when we first allocate physical memory for the page. Most of the time applications don't need 256 MiB of executable code, so allocating on-demand ends up doing less total work than before. Case in point, a simple `ruby --yjit-call-threshold=1 -eitself` takes about half as long after this change. In terms of memory consumption, here is a table to give a rough summary of the impact: | Peak RSS in MiB | -eitself example | railsbench once | | :-------------: | ---------------: | --------------: | | before | 265 | 377 | | after | 11 | 143 | | no YJIT | 10 | 101 | A new module is introduced to handle allocation bookkeeping. `CodePtr` is moved into the module since it has a close relationship with the new `VirtualMemory` struct. This new interface has a slightly smaller surface than before in that marking a region as writable is no longer a public operation. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-04-29YJIT: Enable default rustc lints (warnings) (#5864)Alan Wu
`rustc` performs in depth dead code analysis and issues warning even for things like unused struct fields and unconstructed enum variants. This was annoying for us during the port but hopefully they are less of an issue now. This patch enables all the unused warnings we disabled and address all the warnings we previously ignored. Generally, the approach I've taken is to use `cfg!` instead of using the `cfg` attribute and to delete code where it makes sense. I've put `#[allow(unused)]` on things we intentionally keep around for printf style debugging and on items that are too annoying to keep warning-free in all build configs. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-04-29YJIT: Adopt Clippy suggestions we likeAlan Wu
This adopts most suggestions that rust-clippy is confident enough to auto apply. The manual changes mostly fix manual if-lets and take opportunities to use the `Default` trait on standard collections. Co-authored-by: Kevin Newton <kddnewton@gmail.com> Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Notes: Merged: https://github.com/ruby/ruby/pull/5853
2022-04-28YJIT: replace BLOCKID_NULL with Option<BlockId>, more idiomatic (#5858)Maxime Chevalier-Boisvert
* YJIT: replace BLOCKID_NULL with Option<BlockId>, more idiomatic * Update yjit/src/core.rs Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> * Update yjit/src/core.rs Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-04-27Rust YJITAlan Wu
In December 2021, we opened an [issue] to solicit feedback regarding the porting of the YJIT codebase from C99 to Rust. There were some reservations, but this project was given the go ahead by Ruby core developers and Matz. Since then, we have successfully completed the port of YJIT to Rust. The new Rust version of YJIT has reached parity with the C version, in that it passes all the CRuby tests, is able to run all of the YJIT benchmarks, and performs similarly to the C version (because it works the same way and largely generates the same machine code). We've even incorporated some design improvements, such as a more fine-grained constant invalidation mechanism which we expect will make a big difference in Ruby on Rails applications. Because we want to be careful, YJIT is guarded behind a configure option: ```shell ./configure --enable-yjit # Build YJIT in release mode ./configure --enable-yjit=dev # Build YJIT in dev/debug mode ``` By default, YJIT does not get compiled and cargo/rustc is not required. If YJIT is built in dev mode, then `cargo` is used to fetch development dependencies, but when building in release, `cargo` is not required, only `rustc`. At the moment YJIT requires Rust 1.60.0 or newer. The YJIT command-line options remain mostly unchanged, and more details about the build process are documented in `doc/yjit/yjit.md`. The CI tests have been updated and do not take any more resources than before. The development history of the Rust port is available at the following commit for interested parties: https://github.com/Shopify/ruby/commit/1fd9573d8b4b65219f1c2407f30a0a60e537f8be Our hope is that Rust YJIT will be compiled and included as a part of system packages and compiled binaries of the Ruby 3.2 release. We do not anticipate any major problems as Rust is well supported on every platform which YJIT supports, but to make sure that this process works smoothly, we would like to reach out to those who take care of building systems packages before the 3.2 release is shipped and resolve any issues that may come up. [issue]: https://bugs.ruby-lang.org/issues/18481 Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Co-authored-by: Noah Gibbs <the.codefolio.guy@gmail.com> Co-authored-by: Kevin Newton <kddnewton@gmail.com> Notes: Merged: https://github.com/ruby/ruby/pull/5826