summaryrefslogtreecommitdiff
path: root/yjit
AgeCommit message (Collapse)Author
2023-02-28YJIT: add defer_empty_count statMaxime Chevalier-Boisvert
Count how often we defer from a block that is empty Notes: Merged: https://github.com/ruby/ruby/pull/7396
2023-02-27Update YJIT-bindgenMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/7330
2023-02-27Merge internal/intern/gc.h into internal/gc.hMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/7330
2023-02-27YJIT: Detect and reject `send(:alias_for_send, :foo)`Alan Wu
Previously, YJIT failed to put the stack into the correct shape when `BasicObject#send` calls an alias method for the send method itself. This can manifest as strange `NoMethodError`s in the final non-send receiver, as [seen][1] with the kt-paperclip gem. I also found a case where it makes YJIT fail the stack size assertion while compiling `leave`. YJIT's `BasicObject#__send__` implementation already rejects sends to `send`, but didn't detect sends to aliases of `send`. Adjust the detection and reject these cases. Fixes [Bug #19464] [1]: https://github.com/Shopify/yjit/issues/306 Notes: Merged: https://github.com/ruby/ruby/pull/7377
2023-02-27YJIT: Reject __send__ with splat to cfunc for nowAlan Wu
`make test-spec` revealed this issue after applying an unrelated bug fix. A crashing case is included, though I suspect there are other scenarios where it misbehaves. Don't compile for now. Note that this is *not* an issue on the 3.2.x series; it has `send_args_splat_non_iseq` which already rejects all splats to cfuncs, including sends with splats. Notes: Merged: https://github.com/ruby/ruby/pull/7377
2023-02-24YJIT: Generate Block::entry_exit with block entry PCAlan Wu
Previously, when Block::entry_exit is requested from any instruction that is not the first one in the block, we generated the exit with an incorrect PC. We should always be using the PC for the entry of the block for Block::entry_exit. It was a simple typo. The bug was [introduced][1] while we were refactoring to use the current backend. Later, we had a chance to spot this issue while [preparing][2] to enable unused variable warnings, but didn't spot the issue. Fixes [Bug #19463] [1]: 27fcab995e6dde19deb91dc6e291bdb72100af68 [2]: 31461c7e0eab4963ccc8649ea8ebf27979132c0c Notes: Merged: https://github.com/ruby/ruby/pull/7374 Merged-By: XrXr
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-24YJIT: Use enum for expressing type diff (#7370)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-24YJIT: Compress TempMapping (#7368)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-23YJIT: Trivial fixes in codegen.rsTakashi Kokubun
2023-02-23YJIT: Skip type checks on splat args and expandarray if possible (#7363)Takashi Kokubun
YJIT: Skip type checks on splat args and expandarray if possible Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-02-23YJIT: Add `make yjit-smoke-test` [ci skip]Alan Wu
I have this as a shell command and Maxime told me that she finds it useful, too. I tested this on a release build and a dev build. Note I intentional didn't put `$(Q)` in front of everything so `make` echos the command it runs. Notes: Merged: https://github.com/ruby/ruby/pull/7365
2023-02-22YJIT: Introduce Opnd::Stack (#7352)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-21Call rb_ivar_set instead of exiting for many ivarseileencodes
Previously, when we have a lot of ivars defined, we would exit via `jit_chain_guard` for megamorphic ivars. Now if we have more than the max depth of ivars we can call `rb_ivar_set` instead of exiting. Using the following script: ```ruby class A def initialize @a = 1 end def a @a end end N = 30 N.times do |i| eval <<-eorb class A#{i} < A def initialize @a#{i} = 1 super end end eorb end klasses = N.times.map { Object.const_get(:"A#{_1}") } 1000.times do klasses.each do |k| k.new.a end end ``` Exits before this change show exits for `setinstancevariable`: ``` ***YJIT: Printing YJIT statistics on exit*** method call exit reasons: klass_megamorphic: 24,975 (100.0%) invokeblock exit reasons: (all relevant counters are zero) invokesuper exit reasons: (all relevant counters are zero) leave exit reasons: interp_return: 26,948 (100.0%) se_interrupt: 1 ( 0.0%) getblockparamproxy exit reasons: (all relevant counters are zero) getinstancevariable exit reasons: megamorphic: 13,986 (100.0%) setinstancevariable exit reasons: megamorphic: 19,980 (100.0%) opt_aref exit reasons: (all relevant counters are zero) expandarray exit reasons: (all relevant counters are zero) opt_getinlinecache exit reasons: (all relevant counters are zero) invalidation reasons: (all relevant counters are zero) num_send: 155,823 num_send_known_class: 0 ( 0.0%) num_send_polymorphic: 119,880 (76.9%) bindings_allocations: 0 bindings_set: 0 compiled_iseq_count: 36 compiled_block_count: 158 compiled_branch_count: 240 block_next_count: 10 defer_count: 70 freed_iseq_count: 0 invalidation_count: 0 constant_state_bumps: 0 inline_code_size: 29,216 outlined_code_size: 27,948 freed_code_size: 0 code_region_size: 65,536 live_context_size: 8,322 live_context_count: 219 live_page_count: 4 freed_page_count: 0 code_gc_count: 0 num_gc_obj_refs: 130 object_shape_count: 295 side_exit_count: 58,942 total_exit_count: 85,890 yjit_insns_count: 1,023,581 avg_len_in_yjit: 11.2 Top-4 most frequent exit ops (100.0% of exits): opt_send_without_block: 24,975 (42.4%) setinstancevariable: 19,980 (33.9%) getinstancevariable: 13,986 (23.7%) leave: 1 ( 0.0%) ``` Exits after this change show we have no exits for `setinstancevariable`. ``` ***YJIT: Printing YJIT statistics on exit*** method call exit reasons: klass_megamorphic: 24,975 (100.0%) invokeblock exit reasons: (all relevant counters are zero) invokesuper exit reasons: (all relevant counters are zero) leave exit reasons: interp_return: 60,912 (100.0%) se_interrupt: 3 ( 0.0%) getblockparamproxy exit reasons: (all relevant counters are zero) getinstancevariable exit reasons: (all relevant counters are zero) setinstancevariable exit reasons: (all relevant counters are zero) opt_aref exit reasons: (all relevant counters are zero) expandarray exit reasons: (all relevant counters are zero) opt_getinlinecache exit reasons: (all relevant counters are zero) invalidation reasons: (all relevant counters are zero) num_send: 155,823 num_send_known_class: 0 ( 0.0%) num_send_polymorphic: 119,880 (76.9%) bindings_allocations: 0 bindings_set: 0 compiled_iseq_count: 36 compiled_block_count: 179 compiled_branch_count: 240 block_next_count: 11 defer_count: 70 freed_iseq_count: 0 invalidation_count: 0 constant_state_bumps: 0 inline_code_size: 31,032 outlined_code_size: 29,708 freed_code_size: 0 code_region_size: 65,536 live_context_size: 8,360 live_context_count: 220 live_page_count: 4 freed_page_count: 0 code_gc_count: 0 num_gc_obj_refs: 130 object_shape_count: 295 side_exit_count: 24,978 total_exit_count: 85,890 yjit_insns_count: 1,076,966 avg_len_in_yjit: 12.2 Top-2 most frequent exit ops (100.0% of exits): opt_send_without_block: 24,975 (100.0%) leave: 3 ( 0.0%) ``` Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/7335
2023-02-21YJIT: Fastpath for Module#=== (#7351)Alan Wu
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Jimmy Miller <jimmy.miller@shopify.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-21YJIT: Avoid checking symbol ID twice on send (#7350)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-21YJIT: Fix clippy issues and remove unused params (#7348)Jimmy Miller
* YJIT: Fix clippy issues and remove unused params * Remove an unnecessary whitespace --------- Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-20YJIT: Fix assertion for partially mapped last pages (#7337)Takashi Kokubun
Follows up [Bug #19400] Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-02-17YJIT: Consolidate jit methods in JITState impl (#7336)Jimmy Miller
These jit_* methods don't jit code, but instead check things on the JITState. We had other methods that did the same thing that were just added on the impl JITState. For consistency I added these methods there. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-17YJIT: Use rb_ivar_get at the end of ivar chains (#7334)Takashi Kokubun
* YJIT: Use rb_ivar_get at the end of ivar chains * Rename the counter to get_ivar_max_depth Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-02-17Add asm comment to YJIT's rb_str_empty_pMaxime Chevalier-Boisvert
2023-02-16YJIT: Fix false assumption that String#+@ => ::StringAlan Wu
Could return a subclass. [Bug #19444] Notes: Merged: https://github.com/ruby/ruby/pull/7328
2023-02-16YJIT: jit_prepare_routine_call() for String#+@ missingAlan Wu
We saw SEGVs due to this when running with StackProf, which needs a correct PC for RUBY_INTERNAL_EVENT_NEWOBJ, the same event used for ObjectSpace allocation tracing. [Bug #19444] Notes: Merged: https://github.com/ruby/ruby/pull/7328
2023-02-16YJIT: Show Context stats on exit (#7327)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-02-16YJIT: Refactor getlocal and setlocal insns (#7320)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-16YJIT: Initial support for rest args (#7311)Jimmy Miller
* YJIT: Initial support for rest args * Update yjit/src/codegen.rs --------- Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-16Move `attached_object` into `rb_classext_struct`Jean Boussier
Given that signleton classes don't have an allocator, we can re-use these bytes to store the attached object in `rb_classext_struct` without making it larger. Notes: Merged: https://github.com/ruby/ruby/pull/7309
2023-02-15YJIT: `Kernel#{is_a?,instance_of?}` fast paths (GH-7297)Jimmy Miller
Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Notes: Merged: https://github.com/ruby/ruby/pull/7297 Merged-By: XrXr
2023-02-15Encapsulate RCLASS_ATTACHED_OBJECTJean Boussier
Right now the attached object is stored as an instance variable and all the call sites that either get or set it have to know how it's stored. It's preferable to hide this implementation detail behind accessors so that it is easier to change how it's stored. Notes: Merged: https://github.com/ruby/ruby/pull/7308
2023-02-14YJIT: Optimize != for Integers and Strings (#7301)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-14YJIT: Check correct BOP on gen_fixnum_cmp (#7303)Takashi Kokubun
Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
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-10use correct svar even if env is escapedKoichi Sasada
This patch is follo-up of 0a82bfe. Without this patch, if env is escaped (Proc'ed), strange svar can be touched. This patch tracks escaped env and use it. Notes: Merged: https://github.com/ruby/ruby/pull/7282
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-09Merge gc.h and internal/gc.hMatt Valentine-House
[Feature #19425] Notes: Merged: https://github.com/ruby/ruby/pull/7273
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: Crash with rb_bug() when panickingAlan Wu
Helps with getting good bug reports in the wild. Intended to be backported to the 3.2.x series. Notes: Merged: https://github.com/ruby/ruby/pull/7232
2023-02-02YJIT: ARM64: Fix long jumps to labelsAlan Wu
Previously, with Code GC, YJIT panicked while trying to emit a B.cond instruction with an offset that is not encodable in 19 bits. This only happens when the code in an assembler instance straddles two pages. To fix this, when we detect that a jump to a label can land on a different page, we switch to a fresh new page and regenerate all the code in the assembler there. We still assume that no one assembler has so much code that it wouldn't fit inside a fresh new page. [Bug #19385] Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Notes: Merged: https://github.com/ruby/ruby/pull/7227
2023-02-02YJIT: ARM64: Move functions out of arm64_emit()Alan Wu
Notes: Merged: https://github.com/ruby/ruby/pull/7227