summaryrefslogtreecommitdiff
path: root/yjit/src/codegen.rs
AgeCommit message (Collapse)Author
2023-02-14YJIT: Don't side-exit on too-complex shapes (#7298)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-13YJIT: Fix a typo in a counter nameTakashi Kokubun
I added `invokeblock_iseq_arg0_args_splat` counter but it wasn't used because of a typo. Related to https://github.com/ruby/ruby/pull/7234
2023-02-10YJIT: add counters for polymorphic send and send with known class (#7288)Maxime Chevalier-Boisvert
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-09YJIT: optimized codegen for `rb_ary_empty_p` (WIP) (#7242)Maxime Chevalier-Boisvert
* YJIT: add specialized implementation of rb_ary_empty_p() * Update yjit/src/codegen.rs Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> --------- Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-09YJIT: Support invokesuper in a block (#7264)Maple Ong
Support invokesuper in a block on YJIT invokesuper previously side exited when it is in a block. To make sure we're compiling the correct method in super, we now use the local environment pointer (LEP) to get the method, which will work in a block. Co-authored-by: John Hawthorn <john@hawthorn.email> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-09YJIT: Add counter for megamorphic send (#7274)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-09YJIT: Use the system page size when the code page size is too small (#7267)Alan Wu
Previously on ARM64 Linux systems that use 64 KiB pages (`CONFIG_ARM64_64K_PAGES=y`), YJIT was panicking on boot due to a failed assertion. The assertion was making sure that code GC can free the last code page that YJIT manages without freeing unrelated memory. YJIT prefers picking 16 KiB as the granularity at which to free code memory, but when the system can only free at 64 KiB granularity, that is not possible. The fix is to use the system page size as the code page size when the system page size is 64 KiB. Continue to use 16 KiB as the code page size on common systems that use 16/4 KiB pages. Add asserts to code_gc() and free_page() about code GC's assumptions. Fixes [Bug #19400] Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-09YJIT: Add counters for ivar exits (#7266)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-06YJIT: Support arg0 splat on invokeblock (#7234)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-06YJIT: Check interrupts on frame pop (#7248)Takashi Kokubun
YJIT: Skip gen_check_ints on ISEQ send On the interpreter, vm_push_frame doesn't check interrupts. Only vm_pop_frame does. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-03YJIT: Make Block::start_addr non-optionalAlan Wu
We set the block address as soon as we make the block, so there is no point in making it `Option<CodePtr>`. No memory saving, unfortunately, as `mem::size_of::<Block>() = 176` before and after this change. Still a simplification for the logic, though. Notes: Merged: https://github.com/ruby/ruby/pull/7243
2023-02-03YJIT: Support ifunc on invokeblock (#7233)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-02YJIT: log the names of methods we call to in disasm (#7231)Maxime Chevalier-Boisvert
* YJIT: log the names of methods we call to in disasm * Assert that pointer is not null * Handle case where UTF8 conversion not possible Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-02Fix typos in YJIT [ci skip]Alan Wu
2023-02-02YJIT: Move CodegenGlobals::freed_pages into an RcAlan Wu
This allows for supplying a freed_pages vec in Rust tests. We need it so we can test scenarios that occur after code GC. Notes: Merged: https://github.com/ruby/ruby/pull/7227
2023-02-01Remove whitespaceMaxime Chevalier-Boisvert
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-31YJIT: Group unimplemented method types togetherAlan Wu
Grouping these together helps with finding all of the unimplemented method types. It was interleaved with some other match arm long and short previously. Notes: Merged: https://github.com/ruby/ruby/pull/7210
2023-01-31YJIT: Implement codegen for Kernel#block_given? (#7202)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-30YJIT: Add splat optimized_send (#7167)Jimmy Miller
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-30YJIT: Initial implementation of splat with optional params (#7166)Jimmy Miller
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-30YJIT: Skip defer_compilation for fixnums if possible (#7168)Takashi Kokubun
* YJIT: Skip defer_compilation for fixnums if possible * YJIT: It should be Some(false) * YJIT: Define two_fixnums_on_stack on Context Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-30YJIT: Inline return address callback (#7198)Alan Wu
This makes it so that the generator and the output code read in the same order. I think it reads better this way. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-20YJIT: get rid of unneeded `.into()`Jimmy Miller
Notes: Merged: https://github.com/ruby/ruby/pull/7158 Merged-By: XrXr
2023-01-19YJIT: Refactor side_exitsJimmy Miller
Notes: Merged: https://github.com/ruby/ruby/pull/7155
2023-01-19Implement splat for cfuncs. Split exit exit cases to better capture where we ↵Jimmy Miller
are exiting (#6929) YJIT: Implement splat for cfuncs. Split exit cases This also implements a new check for ruby2keywords as the last argument of a splat. This does mean that we generate more code, but in actual benchmarks where we gained speed from this (binarytrees) I don't see any significant slow down. I did have to struggle here with the register allocator to find code that didn't allocate too many registers. It's a bit hard when everything is implicit. But I think I got to the minimal amount of copying and stuff given our current allocation strategy. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-18YJIT: Use .as_side_exit() for jumps to counted exitsAlan Wu
Fewer cycles running nops when these jumps are not taken. Fixing all these so when they get copy pasted in the future we save on padding. Notes: Merged: https://github.com/ruby/ruby/pull/7150
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>
2023-01-13YJIT: Use SIZEOF_VALUE_I32 instead of `... as i32`Alan Wu
Shorter, and easier to parse without parentheses. Notes: Merged: https://github.com/ruby/ruby/pull/7121
2023-01-13YJIT: Factor out VALUE_BITS = (8 * SIZE_OF_VALUE as u8)Alan Wu
Using a constant shows intention better and is less noisy. It always took me a second to parse the long expression. Notes: Merged: https://github.com/ruby/ruby/pull/7121
2023-01-12Enable `clippy` checks for yjit in CI (#7093)Ian Ker-Seymer
* Add job to check clippy lints in CI * Address all remaining clippy lints * Check lints on arm64 as well * Apply latest clippy lints * Do not exit 0 on clippy warnings Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-11YJIT: Add a few asm comments (#7105)Takashi Kokubun
* YJIT: Add a few asm comments * YJIT: Clarify exiting insns * YJIT: Fix cargo test Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-01-10Differentiate T_ARRAY and array subclasses (#7091)Aaron Patterson
* Differentiate T_ARRAY and array subclasses This commit teaches the YJIT context the difference between Arrays (objects with type T_ARRAY and class rb_cArray) vs Array subclasses (objects with type T_ARRAY but _not_ class rb_cArray). It uses this information to reduce the number of guards emitted when using `jit_guard_known_klass` with rb_cArray, notably opt_aref * Update yjit/src/core.rs Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-10YJIT: Save PC and SP before calling leaf builtins (#7090)Alan Wu
Previously, we did not update `cfp->sp` before calling the C function of ISEQs marked with `Primitive.attr! "inline"` (leaf builtins). This caused the GC to miss temporary values on the stack in case the function allocates and triggers a GC run. Right now, there is only a few leaf builtins in numeric.rb on Integer methods such as `Integer#~`. Since these methods only allocate when operating on big numbers, we missed this issue. Fix by saving PC and SP before calling the functions -- our usual protocol for calling C functions that may allocate on the GC heap. [Bug #19316] Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-01-06YJIT: Make iseq_get_location consistent with iseq.c (#7074)Takashi Kokubun
* YJIT: Make iseq_get_location consistent with iseq.c * YJIT: Call it "YJIT entry point" Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-01-05Use a different name for megamorphic setivar exitsAaron Patterson
We should differentiate between set and get for megamorphic exits. This patch fixes the megamorphic exit name in gen_setinstancevariable so that we can tell the difference between megamorphic get / set sites Notes: Merged: https://github.com/ruby/ruby/pull/7072
2023-01-03YJIT: Fix `yield` into block with >=30 locals on ARMAlan Wu
It's a register spill issue. Fix by moving the Qnil fill snippet to after registers are released. [Bug #19299] Notes: Merged: https://github.com/ruby/ruby/pull/7059
2022-12-15YJIT: Fix `obj.send(:call)`Alan Wu
All the method call types need to handle argument shifting in case they're called by `.send`, and we weren't handling that in `OPTIMIZED_METHOD_TYPE_CALL`. Lack of shifting caused the stack size assertion in gen_leave() to fail. Discovered by Rails CI: https://buildkite.com/rails/rails/builds/91705#018516c4-f8f8-469e-bc2d-ddeb25ca8317/1920-2067 Diagnosed with help from `@eileencodes` and `@k0kubun`. Notes: Merged: https://github.com/ruby/ruby/pull/6943 Merged-By: XrXr
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-15Transition complex objects to "too complex" shapeJemma Issroff
When an object becomes "too complex" (in other words it has too many variations in the shape tree), we transition it to use a "too complex" shape and use a hash for storing instance variables. Without this patch, there were rare cases where shape tree growth could "explode" and cause performance degradation on what would otherwise have been cached fast paths. This patch puts a limit on shape tree growth, and gracefully degrades in the rare case where there could be a factorial growth in the shape tree. For example: ```ruby class NG; end HUGE_NUMBER.times do NG.new.instance_variable_set(:"@unique_ivar_#{_1}", 1) end ``` We consider objects to be "too complex" when the object's class has more than SHAPE_MAX_VARIATIONS (currently 8) leaf nodes in the shape tree and the object introduces a new variation (a new leaf node) associated with that class. For example, new variations on instances of the following class would be considered "too complex" because those instances create more than 8 leaves in the shape tree: ```ruby class Foo; end 9.times { Foo.new.instance_variable_set(":@uniq_#{_1}", 1) } ``` However, the following class is *not* too complex because it only has one leaf in the shape tree: ```ruby class Foo def initialize @a = @b = @c = @d = @e = @f = @g = @h = @i = nil end end 9.times { Foo.new } `` This case is rare, so we don't expect this change to impact performance of most applications, but it needs to be handled. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/6931
2022-12-14YJIT: Remove duplicate call to jit_prepare_routine_call()Alan Wu
It's idempotent. Notes: Merged: https://github.com/ruby/ruby/pull/6930
2022-12-12YJIT: Implement opt_newarray_max instruction (#6893)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-12-09YJIT: Split send_iseq_complex_callee exit reasons (#6895)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-12-09YJIT: implement `getconstant` YARV instruction (#6884)Maxime Chevalier-Boisvert
* YJIT: implement getconstant YARV instruction * Constant id is not a pointer * Stack operands must be read after jit_prepare_routine_call Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-12-08YJIT: Drop Copy trait from Context (#6889)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-12-08YJIT: implement opt_newarray_min YARV instruction (#6888)Maxime Chevalier-Boisvert
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-12-05YJIT: Remove --yjit-code-page-size (#6865)Alan Wu
Certain code page sizes don't work and can cause crashes, so having this value available as a command-line option is a bit dangerous. Remove it and turn it into a constant instead. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2022-12-05YJIT: Extract SHAPE_ID_NUM_BITS into a constant (#6863)Jemma Issroff
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2022-12-02Extracted rb_shape_id_offsetJemma Issroff
Notes: Merged: https://github.com/ruby/ruby/pull/6767
2022-12-02Update yjit/src/codegen.rsMaxime Chevalier-Boisvert
Notes: Merged: https://github.com/ruby/ruby/pull/6767