summaryrefslogtreecommitdiff
path: root/yjit/src
AgeCommit message (Collapse)Author
2023-03-03YJIT: Fix a cargo test warning on x86_64 (#7428)Takashi Kokubun
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-03-02YJIT: shrink stack_size/sp_offet to u8/i8 (#7426)Maxime Chevalier-Boisvert
Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-03-02YJIT: Delete stale `frozen_bytes` related code (#7423)Alan Wu
The code and comments in there have been disabled by comments for a long time. The issues that the counter used to solve are now solved more comprehensively by "runningness" [tracking][1] introduced by Code GC and [delayed deallocation][2]. Having a single counter doesn't fit our current model where code pages that could be touched or not are interleaved, anyway. Just delete the code. [1]: e7c71c6c9271b0c29f210769159090e17128e740 [2]: a0b0365e905e1ac51998ace7e6fc723406a2f157 Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-03-02YJIT: Fix cfunc splatJimmy Miller
Follow-up for cb8a040b7906c09d9d3ac3d3fe853f633005024f. Notes: Merged: https://github.com/ruby/ruby/pull/7418 Merged-By: XrXr
2023-03-01YJIT: Properly deal with cfunc splat when no args needed (#7413)Jimmy Miller
Related to: https://github.com/ruby/ruby/pull/7377 Previously it was believed that there was a problem with a combination of cfuncs + splat + send, but it turns out the same issue happened without send. For example `Integer.sqrt(1, *[])`. The issue was happened not because of send, but because of setting the wrong argc when we don't need to splat any args. Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-03-01YJIT: reject large stacks so we can use i8/u8 stack_size and stack_offset ↵Maxime Chevalier-Boisvert
(#7412) * Reject large stacks so we can use i8/u8 stack_size and stack_offset * Add rejection test for iseq too long as well Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-03-01YJIT: Use a boxed slice for outgoing branches and cme dependencies (#7409)Takashi Kokubun
YJIT: Use a boxed slice for outgoing branches and cme dependencies Notes: Merged-By: maximecb <maximecb@ruby-lang.org>
2023-02-28YJIT: Compress BranchGenFn and BranchShape (#7401)Takashi Kokubun
* YJIT: Compress BranchGenFn and BranchShape * YJIT: Derive Debug for Branch * YJIT: Capitalize BranchGenFn names Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Co-authored-by: Alan Wu <alansi.xingwu@shopify.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-02-28YJIT: Use a boxed slice for gc_obj_offsets (#7397)Takashi Kokubun
* YJIT: Use a boxed slice for gc_obj_offsets * YJIT: Stop using Option * YJIT: s/add_counter/incr_counter_by/ Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2023-02-28Update Rust bindgenMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/7310
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-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-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>