summaryrefslogtreecommitdiff
path: root/yjit.c
AgeCommit message (Collapse)Author
2023-06-06Unify length field for embedded and heap strings (#7908)Peter Zhu
* Unify length field for embedded and heap strings The length field is of the same type and position in RString for both embedded and heap allocated strings, so we can unify it. * Remove RSTRING_EMBED_LEN Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-05-20`rb_bug` prints a newline after the messageNobuyoshi Nakada
2023-04-18YJIT: Fix raw sample stack lengths in exit traces (#7728)John Hawthorn
yjit-trace-exits appends a synthetic sample for the instruction being exited, but we didn't increment the size of the stack. Fixing this count correctly lets us successfully generate a flamegraph from the exits. I also replaced the line number for instructions with 0, as I don't think the previous value had meaning. Co-authored-by: Adam Hess <HParker@github.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-04-06Pull the shape tree out of the vm objectMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/7393
2023-04-05YJIT: Add codegen for Integer methods (#7665)Takashi Kokubun
* YJIT: Add codegen for Integer methods * YJIT: Update dependencies * YJIT: Fix Integer#[] for argc=2 Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-04-01Remove an unneeded function copyTakashi Kokubun
2023-03-28YJIT: Add `--yjit-pause` and `RubyVM::YJIT.resume` (#7609)Maxime Chevalier-Boisvert
* YJIT: Add --yjit-pause and RubyVM::YJIT.resume This allows booting YJIT in a suspended state. We chose to add a new command line option as opposed to simply allowing YJIT.resume to work without any command line option because it allows for combining with YJIT tuning command line options. It also simpifies implementation. Paired with Kokubun and Maxime. * Update yjit.rb Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> --------- Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-03-24YJIT: Constify EC to avoid an `as` pointer cast (#7591)Alan Wu
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-03-18RJIT: Optimize String#bytesizeTakashi Kokubun
2023-03-17YJIT: Support entry for multiple PCs per ISEQ (GH-7535)Takashi Kokubun
Notes: Merged: https://github.com/ruby/ruby/pull/7535 Merged-By: k0kubun <takashikkbn@gmail.com>
2023-03-16Refactor jit_func_t and jit_execTakashi Kokubun
I closed https://github.com/ruby/ruby/pull/7543, but part of the diff seems useful regardless, so I extracted it.
2023-03-15YJIT: Assert that we have the VM lock while markingAlan Wu
Somewhat important because having the lock is a key part of the soundness reasoning for the `unsafe` usage here. Notes: Merged: https://github.com/ruby/ruby/pull/7530
2023-03-14YJIT: Introduce no_gc attribute (#7511)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-03-13YJIT: Handle rest+splat where non-splat < required (#7499)Jimmy Miller
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-03-11Rename builtin attr :inline to :leafTakashi Kokubun
2023-03-11Support multiple attributes with Primitive.attr!Takashi Kokubun
2023-03-07YJIT: Handle splat+rest for args pass greater than required (#7468)Jimmy Miller
For example: ```ruby def my_func(x, y, *rest) p [x, y, rest] end my_func(1, 2, 3, *[4, 5]) ``` Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-26Adjust `else` style to be consistent in each files [ci skip]Nobuyoshi Nakada
2023-02-24Fix incorrect line numbers in GC hookPeter Zhu
If the previous instruction is not a leaf instruction, then the PC was incremented before the instruction was ran (meaning the currently executing instruction is actually the previous instruction), so we should not increment the PC otherwise we will calculate the source line for the next instruction. This bug can be reproduced in the following script: ``` require "objspace" ObjectSpace.trace_object_allocations_start a = 1.0 / 0.0 p [ObjectSpace.allocation_sourceline(a), ObjectSpace.allocation_sourcefile(a)] ``` Which outputs: [4, "test.rb"] This is incorrect because the object was allocated on line 10 and not line 4. The behaviour is correct when we use a leaf instruction (e.g. if we replaced `1.0 / 0.0` with `"hello"`), then the output is: [10, "test.rb"]. [Bug #19456] Notes: Merged: https://github.com/ruby/ruby/pull/7357
2023-02-16YJIT: Show Context stats on exit (#7327)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-02-14YJIT: Optimize != for Integers and Strings (#7301)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-09Merge gc.h and internal/gc.hMatt Valentine-House
[Feature #19425] Notes: Merged: https://github.com/ruby/ruby/pull/7273
2023-01-31YJIT: Handle splat with opt more fully (#7209)Jimmy Miller
* YJIT: Handle splat with opt more fully * Update yjit/src/codegen.rs --------- Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-18YJIT: implement codegen for `String#empty?` (#7148)Maxime Chevalier-Boisvert
YJIT: implement codegen for String#empty? Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-11-17YJIT: Add object shape count to stats (#6754)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-11-08Implement optimize call (#6691)Jimmy Miller
This dispatches to a c func for doing the dynamic lookup. I experimented with chain on the proc but wasn't able to detect which call sites would be monomorphic vs polymorphic. There is definitely room for optimization here, but it does reduce exits. 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: don't show a full crash report if mmap is only out of memory (#6659)Noah Gibbs
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-10-31YJIT: Add RubyVM::YJIT.code_gc (#6644)Takashi Kokubun
* YJIT: Add RubyVM::YJIT.code_gc * Rename compiled_page_count to live_page_count Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
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-18Allow passing a Rust closure to rb_iseq_callback (#6575)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-10-17Make mjit_cont sharable with YJIT (#6556)Takashi Kokubun
* Make mjit_cont sharable with YJIT * Update dependencies * Update YJIT binding Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-10-17YJIT: Do not call `mprotect` when `mem_size` is zero (#6563)Tatsuya Kawano
This allows x86_64 based YJIT to run on Docker Desktop on Apple silicon (arm64) Mac because it will avoid a subtle behavior difference in `mprotect` system call between the Linux kernel and `qemu-x86_64` user space emulator. 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-04YJIT: add support for calling bmethods (#6489)Alan Wu
* YJIT: fix a parameter name * YJIT: add support for calling bmethods This commit adds support for the VM_METHOD_TYPE_BMETHOD method type in YJIT. You can get these type of methods from facilities like Kernel#define_singleton_method and Module#define_method. Even though the body of these methods are blocks, the parameter setup for them is exactly the same as VM_METHOD_TYPE_ISEQ, so we can reuse the same logic in gen_send_iseq(). You can see this from how vm_call_bmethod() eventually calls setup_parameters_complex() with arg_setup_method. Bmethods do need their frame environment to be setup differently. We handle this by allowing callers of gen_send_iseq() to control the iseq, the frame flag, and the prev_ep. The `prev_ep` goes into the same location as the block handler would go into in an iseq method frame. 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-09-15YJIT should die if we compile on Aarch64 with no instruction cache clear ↵Noah Gibbs
available (#6380) YJIT should die if we compile on ARM64 with no icache clear available Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-09-14YJIT: Implement specialized respond_to? (#6363)John Hawthorn
* Add rb_callable_method_entry_or_negative * YJIT: Implement specialized respond_to? This implements a specialized respond_to? in YJIT. * Update yjit/src/codegen.rs Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-09-14Initial support for VM_CALL_ARGS_SPLAT (#6341)Jimmy Miller
* Initial support for VM_CALL_ARGS_SPLAT This implements support for calls with splat (*) for some methods. In benchmarks this made very little difference for most benchmarks, but a large difference for binarytrees. Looking at side exits, many benchmarks now don't exit for splat, but exit for some other reason. Binarytrees however had a number of calls that used splat args that are now much faster. In my non-scientific benchmarking this made splat args performance on par with not using splat args at all. * Fix wording and whitespace Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> * Get rid of side_effect reassignment Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-08-29A64: Only clear icache when writing out new code ↵Alan Wu
(https://github.com/Shopify/ruby/pull/442) Previously we cleared the cache for all the code in the system when we flip memory protection, which was prohibitively expensive since the operation is not constant time. Instead, only clear the cache for the memory region of newly written code when we write out new code. This brings the runtime for the 30k_if_else test down to about 6 seconds from the previous 45 seconds on my laptop. Notes: Merged: https://github.com/ruby/ruby/pull/6289
2022-08-29Use bindgen for old manual extern declarations ↵Alan Wu
(https://github.com/Shopify/ruby/pull/404) We have a large extern block in cruby.rs leftover from the port. We can use bindgen for it now and reserve the manual declaration for just a handful of vm_insnhelper.c functions. Fixup a few minor discrepencies bindgen found between the C declaration and the manual declaration. Mostly missing `const` on the C side.
2022-08-29Add ifdef to clear cacheMaxime Chevalier-Boisvert
2022-08-29Clear the icache on armMaxime 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-07-28YJIT: Teach getblockparamproxy to handle the no-block case without exiting ↵Matthew Draper
(#6191) Teach getblockparamproxy to handle the no-block case without exiting 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-07-27Adjust styles [ci skip]Nobuyoshi Nakada
2022-07-12Speed up --yjit-trace-exits code (#6106)Eileen M. Uchitelle
In a small script the speed of this feature isn't really noticeable but on Rails it's very noticeable how slow this can be. This PR aims to speed up two parts of the functionality. 1) The Rust exit recording code Instead of adding all samples as we see them to the yjit_raw_samples and yjit_line_samples, we can increment the counter on the ones we've seen before. This will be faster on traces where we are hitting the same stack often. In a crude measurement of booting just the active record base test (`test/cases/base_test.rb`) we found that this improved the speed by 1 second. This also results in a smaller marshal dump file which sped up the test boot time by 4 seconds with trace exits on. 2) The Ruby parsing code Previously we were allocating new arrays using `shift` and `each_with_index`. This change avoids allocating new arrays by using an index. This change saves us the most amount of time, gaining 11 seconds. Before this change the test boot time took 62 seconds, after it took 47 seconds. This is still too long but it's a step closer to faster functionality. Next we're going to tackle allowing you to collect trace exits for a specific instruction. There is also some potential slowness in the GC code that I'd like to take a second look at. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org> Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-06-30YJIT: Refactor gen_opt_mod (#6078)Dave Schwantes
Refactor gen_opt_mod in YJIT Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-06-17YJIT: Update note about symbol prefixes [ci skip]Alan Wu
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>