summaryrefslogtreecommitdiff
path: root/yjit
AgeCommit message (Collapse)Author
2024-11-25YJIT: fix small typo in command line options help (#12167)Maxime Chevalier-Boisvert
Notes: Merged-By: maximecb <[email protected]>
2024-11-20YJIT: Make compilation_failure a default stat (#12128)Alan Wu
It's good to monitor compilation failures. Notes: Merged-By: maximecb <[email protected]>
2024-11-20YJIT: Refactor to forward jump_to_next_insn() return valueAlan Wu
It's more concise this way and since `return Some(EndBlock)` is the only correct answer, no point repeating it everywhere. Notes: Merged: https://github.com/ruby/ruby/pull/12124
2024-11-20YJIT: Abandon block when gen_outlined_exit() failsAlan Wu
When CodeBlock::set_page fails (part of next_page(), see their docs for exact conditions), it can cause gen_outlined_exit() to fail while there is still plenty of memory available. Previously, this can have YJIT running incomplete code due to taking the early return in end_block_with_jump() that manifested as crashes with SIGILL. Add and use a wrapper with error handling. Notes: Merged: https://github.com/ruby/ruby/pull/12124
2024-11-14YJIT: Specialize String#dup (#12090)Takashi Kokubun
Notes: Merged-By: maximecb <[email protected]>
2024-11-14YJIT: Specialize Integer#pred (#12082)Takashi Kokubun
Notes: Merged-By: maximecb <[email protected]>
2024-11-13YJIT: Add inline_block_count stat (#12081)Takashi Kokubun
Notes: Merged-By: maximecb <[email protected]>
2024-11-13YJIT: Specialize `String#[]` (`String#slice`) with fixnum arguments (#12069)Randy Stauner
* YJIT: Specialize `String#[]` (`String#slice`) with fixnum arguments String#[] is in the top few C calls of several YJIT benchmarks: liquid-compile rubocop mail sudoku This speeds up these benchmarks by 1-2%. * YJIT: Try harder to get type info for `String#[]` In the large generated code of the mail gem the context doesn't have the type info. In that case if we peek at the stack and add a guard we can still apply the specialization and it speeds up the mail benchmark by 5%. Co-authored-by: Maxime Chevalier-Boisvert <[email protected]> Co-authored-by: Takashi Kokubun (k0kubun) <[email protected]> --------- Co-authored-by: Maxime Chevalier-Boisvert <[email protected]> Co-authored-by: Takashi Kokubun (k0kubun) <[email protected]> Notes: Merged-By: maximecb <[email protected]>
2024-11-13Mark strings returned by Symbol#to_s as chilled (#12065)Jean byroot Boussier
* Use FL_USER0 for ELTS_SHARED This makes space in RString for two bits for chilled strings. * Mark strings returned by `Symbol#to_s` as chilled [Feature #20350] `STR_CHILLED` now spans on two user flags. If one bit is set it marks a chilled string literal, if it's the other it marks a `Symbol#to_s` chilled string. Since it's not possible, and doesn't make much sense to include debug info when `--debug-frozen-string-literal` is set, we can't include allocation source, but we can safely include the symbol name in the warning message, making it much easier to find the source of the issue. Co-Authored-By: Étienne Barrié <[email protected]> --------- Co-authored-by: Étienne Barrié <[email protected]> Co-authored-by: Jean Boussier <[email protected]>
2024-11-11Fix false-positive memory leak using Valgrind in YJIT (#12057)Peter Zhu
When we run with RUBY_FREE_AT_EXIT, there's a false-positive memory leak reported in YJIT because the METHOD_CODEGEN_TABLE is never freed. This commit adds rb_yjit_free_at_exit that is called at shutdown when RUBY_FREE_AT_EXIT is set. Reported memory leak: ==699816== 1,104 bytes in 1 blocks are possibly lost in loss record 1 of 1 ==699816== at 0x484680F: malloc (vg_replace_malloc.c:446) ==699816== by 0x155B3E: UnknownInlinedFun (unix.rs:14) ==699816== by 0x155B3E: UnknownInlinedFun (stats.rs:36) ==699816== by 0x155B3E: UnknownInlinedFun (stats.rs:27) ==699816== by 0x155B3E: alloc (alloc.rs:98) ==699816== by 0x155B3E: alloc_impl (alloc.rs:181) ==699816== by 0x155B3E: allocate (alloc.rs:241) ==699816== by 0x155B3E: do_alloc<alloc::alloc::Global> (alloc.rs:15) ==699816== by 0x155B3E: new_uninitialized<alloc::alloc::Global> (mod.rs:1750) ==699816== by 0x155B3E: fallible_with_capacity<alloc::alloc::Global> (mod.rs:1788) ==699816== by 0x155B3E: prepare_resize<alloc::alloc::Global> (mod.rs:2864) ==699816== by 0x155B3E: resize_inner<alloc::alloc::Global> (mod.rs:3060) ==699816== by 0x155B3E: reserve_rehash_inner<alloc::alloc::Global> (mod.rs:2950) ==699816== by 0x155B3E: hashbrown::raw::RawTable<T,A>::reserve_rehash (mod.rs:1231) ==699816== by 0x5BC39F: UnknownInlinedFun (mod.rs:1179) ==699816== by 0x5BC39F: find_or_find_insert_slot<(usize, fn(&mut yjit::codegen::JITState, &mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option<yjit::codegen::BlockHandler>, i32, core::option::Option<yjit::cruby::VALUE>) -> bool), alloc::alloc::Global, hashbrown::map::equivalent_key::{closure_env#0}<usize, usize, fn(&mut yjit::codegen::JITState, &mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option<yjit::codegen::BlockHandler>, i32, core::option::Option<yjit::cruby::VALUE>) -> bool>, hashbrown::map::make_hasher::{closure_env#0}<usize, fn(&mut yjit::codegen::JITState, &mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option<yjit::codegen::BlockHandler>, i32, core::option::Option<yjit::cruby::VALUE>) -> bool, std::hash::random::RandomState>> (mod.rs:1413) ==699816== by 0x5BC39F: hashbrown::map::HashMap<K,V,S,A>::insert (map.rs:1754) ==699816== by 0x57C5C6: insert<usize, fn(&mut yjit::codegen::JITState, &mut yjit::backend::ir::Assembler, *const yjit::cruby::autogened::rb_callinfo, *const yjit::cruby::autogened::rb_callable_method_entry_struct, core::option::Option<yjit::codegen::BlockHandler>, i32, core::option::Option<yjit::cruby::VALUE>) -> bool, std::hash::random::RandomState> (map.rs:1104) ==699816== by 0x57C5C6: yjit::codegen::reg_method_codegen (codegen.rs:10521) ==699816== by 0x57C295: yjit::codegen::yjit_reg_method_codegen_fns (codegen.rs:10464) ==699816== by 0x5C6B07: rb_yjit_init (yjit.rs:40) ==699816== by 0x393723: ruby_opt_init (ruby.c:1820) ==699816== by 0x393723: ruby_opt_init (ruby.c:1767) ==699816== by 0x3957D4: prism_script (ruby.c:2215) ==699816== by 0x3957D4: process_options (ruby.c:2538) ==699816== by 0x396065: ruby_process_options (ruby.c:3166) ==699816== by 0x236E56: ruby_options (eval.c:117) ==699816== by 0x15BAED: rb_main (main.c:43) ==699816== by 0x15BAED: main (main.c:62) After this patch, there are no more memory leaks reported when running RUBY_FREE_AT_EXIT with Valgrind on an empty Ruby script: $ RUBY_FREE_AT_EXIT=1 valgrind --leak-check=full ruby -e "" ... ==700357== HEAP SUMMARY: ==700357== in use at exit: 0 bytes in 0 blocks ==700357== total heap usage: 36,559 allocs, 36,559 frees, 6,064,783 bytes allocated ==700357== ==700357== All heap blocks were freed -- no leaks are possible Notes: Merged-By: maximecb <[email protected]>
2024-11-08YJIT: Always abandon the block when gen_branch() or defer_compilation() failsAlan Wu
In [1], we started checking for gen_branch failures, but I made two crucial mistakes. One, defer_compilation() had the same issue as gen_branch() but wasn't checked. Two, returning None from a codegen function does not throw away the block. Checking how gen_single_block() handles codegen functions, you can see that None terminates the block with an exit, but does not overall return an Err. This handling is fine for unimplemented instructions, for example, but incorrect in case gen_branch() fails. The missing branch essentially corrupts the block; adding more code after a missing branch doesn't correct the code. Always abandon the block when defer_compilation() or gen_branch() fails. [1]: cb661d7d82984cdb54485ea3f4af01ac21960882 Fixup: [1] Notes: Merged: https://github.com/ruby/ruby/pull/12035 Merged-By: XrXr
2024-11-08YJIT: Pass panic message to rb_bug()Alan Wu
So that the Rust panic message is forwarded to the RUBY_CRASH_REPORT system, instead of only the static "YJIT panicked" message done so previously. This helps with triaging crashes since it's easier than trying to parse stderr output. Sample: <internal:yjit_hook>:2: [BUG] YJIT: panicked at src/codegen.rs:1197:5: explicit panic ... Notes: Merged: https://github.com/ruby/ruby/pull/12027
2024-11-06Ignore return value of `into_raw_fd`Nobuyoshi Nakada
Fix as the compiler orders: ``` warning: unused return value of `into_raw_fd` that must be used --> ../src/yjit/src/disasm.rs:123:21 | 123 | file.into_raw_fd(); // keep the fd open | ^^^^^^^^^^^^^^^^^^ | = note: losing the raw file descriptor may leak resources = note: `#[warn(unused_must_use)]` on by default help: use `let _ = ...` to ignore the resulting value | 123 | let _ = file.into_raw_fd(); // keep the fd open | +++++++ warning: unused return value of `into_raw_fd` that must be used --> ../src/yjit/src/log.rs:84:21 | 84 | file.into_raw_fd(); // keep the fd open | ^^^^^^^^^^^^^^^^^^ | = note: losing the raw file descriptor may leak resources help: use `let _ = ...` to ignore the resulting value | 84 | let _ = file.into_raw_fd(); // keep the fd open | +++++++ ``` Notes: Merged: https://github.com/ruby/ruby/pull/12009
2024-11-04YJIT: Replace Array#each only when YJIT is enabled (#11955)Takashi Kokubun
* YJIT: Replace Array#each only when YJIT is enabled * Add comments about BUILTIN_ATTR_C_TRACE * Make Ruby Array#each available with --yjit as well * Fix all paths that expect a C location * Use method_basic_definition_p to detect patches * Copy a comment about C_TRACE flag to compilers * Rephrase a comment about add_yjit_hook * Give METHOD_ENTRY_BASIC flag to Array#each * Add --yjit-c-builtin option * Allow inconsistent source_location in test-spec * Refactor a check of BUILTIN_ATTR_C_TRACE * Set METHOD_ENTRY_BASIC without touching vm->running Notes: Merged-By: maximecb <[email protected]>
2024-10-23YJIT: Make PendingBranch::set_target `must_use` [ci skip]Alan Wu
2024-10-23YJIT: Check when gen_branch() failsAlan Wu
We got some core dumps in the wild where a PendingBranch had everything as None, leading to a panic unwrapping in PendingBranch::into_branch(). This happened while compiling a `branchif`. It seems that the only way this can happen is when core::gen_branch() fails, but not due to OOM. We wouldn't have reach into_branch() when OOM, and the only way to not leave markers that would've set the branch's start_addr to some value in gen_branch() is for set_target() to fail, causing an early return. Unfortunately, it's hard to tell the exact sequence of events that led to this situation, but regardless, the dumps show us that we should check for errors in gen_branch(). Because gen_branch() is used deep in the stack during compilation (e.g. guard_known_class() -> jit_chain_guard() -> gen_branch()), it'd be bad for compile speed to propagate the error everywhere, not to mention the massive patch required. Opt for a flag checked near the end of compilation. Notes: Merged: https://github.com/ruby/ruby/pull/11938 Merged-By: XrXr
2024-10-23YJIT: Count compiled_branch_count when branch is finalized [ci skip]Alan Wu
2024-10-22Rewrite Numeric#dup and Numeric#+@ in Ruby (#11933)Takashi Kokubun
Notes: Merged-By: k0kubun <[email protected]>
2024-10-22YJIT: Implement specialization for no-op `{Kernel,Numeric}#dup`Alan Wu
Type information in the context for no additional work! This is the `if (special_object_p(obj)) return obj;` path in rb_obj_dup() and for Numeric#dup, it's always the identity function. Notes: Merged: https://github.com/ruby/ruby/pull/11926
2024-10-21YJIT: Rename method substitution functions and improve docs (+1) (#11919)Alan Wu
* YJIT: Fill in commented-out assertion * YJIT: Rename yjit_reg_method() and add links in docs Notes: Merged-By: maximecb <[email protected]>
2024-10-18YJIT: Allow shareable consts in multi-ractor mode (#11917)John Hawthorn
* Update yjit-bindgen deps * YJIT: Allow shareable consts in multi-ractor mode * Update yjit/src/codegen.rs Co-authored-by: Alan Wu <[email protected]> --------- Co-authored-by: Alan Wu <[email protected]> Notes: Merged-By: maximecb <[email protected]>
2024-10-17YJIT: In stats, group by resolved C method nameAlan Wu
Previously, in the "Top-N most frequent C calls" section of --yjit-stats output, we printed the class name of the receiver, not the method owner. This meant that calls on subclass instances that land on the same method showed up as different entires. Similarly, method called using an alias showed up as different entries from other aliases. Group by the resolved method instead. Test program: 1.itself; [].itself; true.inspect; true.to_s Before: Top-4 most frequent C calls (80.0% of C calls): 1 (20.0%): Integer#itself 1 (20.0%): TrueClass#to_s 1 (20.0%): TrueClass#inspect 1 (20.0%): Array#itself After: Top-2 most frequent C calls (80.0% of C calls): 2 (40.0%): Kernel#itself 2 (40.0%): TrueClass#to_s Notes: Merged: https://github.com/ruby/ruby/pull/11913
2024-10-17YJIT: Add compilation log (#11818)Kevin Menard
* YJIT: Add `--yjit-compilation-log` flag to print out the compilation log at exit. * YJIT: Add an option to enable the compilation log at runtime. * YJIT: Fix a typo in the `IseqPayload` docs. * YJIT: Add stubs for getting the YJIT compilation log in memory. * YJIT: Add a compilation log based on a circular buffer to cap the log size. * YJIT: Allow specifying either a file or directory name for the YJIT compilation log. The compilation log will be populated as compilation events occur. If a directory is supplied, then a filename based on the PID will be used as the write target. If a file name is supplied instead, the log will be written to that file. * YJIT: Add JIT compilation of C function substitutions to the compilation log. * YJIT: Add compilation events to the circular buffer even if output is sent to a file. Previously, the two modes were treated as being exclusive of one another. However, it could be beneficial to log all events to a file while also allowing for direct access of the last N events via `RubyVM::YJIT.compilation_log`. * YJIT: Make timestamps the first element in the YJIT compilation log tuple. * YJIT: Stream log to stderr if `--yjit-compilation-log` is supplied without an argument. * YJIT: Eagerly compute compilation log messages to avoid hanging on to references that may GC. * YJIT: Log all compiled blocks, not just the method entry points. * YJIT: Remove all compilation events other than block compilation to slim down the log. * YJIT: Replace circular buffer iterator with a consuming loop. * YJIT: Support `--yjit-compilation-log=quiet` as a way to activate the in-memory log without printing it. Co-authored-by: Randy Stauner <[email protected]> * YJIT: Promote the compilation log to being the one YJIT log. Co-authored-by: Randy Stauner <[email protected]> * Update doc/yjit/yjit.md * Update doc/yjit/yjit.md --------- Co-authored-by: Randy Stauner <[email protected]> Co-authored-by: Maxime Chevalier-Boisvert <[email protected]> Notes: Merged-By: maximecb <[email protected]>
2024-10-11Fix spellingJohn Bampton
Notes: Merged: https://github.com/ruby/ruby/pull/11882 Merged-By: XrXr
2024-10-08YJIT: Fastpath for Module#name (#11819)Alan Wu
Module#name shows up as a top C method callee in lobsters so probably common enough. It's also easy to substitute thanks to rb_mod_name() already having no GC yield points. klass = BasicObject 50_000_000.times { klass.name } Benchmark 1: /.rubies/post/bin/ruby --yjit mod_name.rb Time (mean ± σ): 1.433 s ± 0.010 s [User: 1.410 s, System: 0.010 s] Range (min … max): 1.421 s … 1.449 s 10 runs Benchmark 2: /.rubies/mstr/bin/ruby --yjit mod_name.rb Time (mean ± σ): 1.491 s ± 0.012 s [User: 1.468 s, System: 0.010 s] Range (min … max): 1.470 s … 1.511 s 10 runs Summary /.rubies/post/bin/ruby --yjit mod_name.rb ran 1.04 ± 0.01 times faster than /.rubies/mstr/bin/ruby --yjit mod_name.rb
2024-10-07YJIT: Add --yjit-mem-size option (#11810)Takashi Kokubun
* YJIT: Add --yjit-mem-size option * Improve --help * s/the region/this virtual memory region/ Co-authored-by: Maxime Chevalier-Boisvert <[email protected]> --------- Co-authored-by: Maxime Chevalier-Boisvert <[email protected]> Notes: Merged-By: maximecb <[email protected]>
2024-10-03Rename size_pool -> heapMatt Valentine-House
Now that we've inlined the eden_heap into the size_pool, we should rename the size_pool to heap. So that Ruby contains multiple heaps, with different sized objects. The term heap as a collection of memory pages is more in memory management nomenclature, whereas size_pool was a name chosen out of necessity during the development of the Variable Width Allocation features of Ruby. The concept of size pools was introduced in order to facilitate different sized objects (other than the default 40 bytes). They wrapped the eden heap and the tomb heap, and some related state, and provided a reasonably simple way of duplicating all related concerns, to provide multiple pools that all shared the same structure but held different objects. Since then various changes have happend in Ruby's memory layout: * The concept of tomb heaps has been replaced by a global free pages list, with each page having it's slot size reconfigured at the point when it is resurrected * the eden heap has been inlined into the size pool itself, so that now the size pool directly controls the free_pages list, the sweeping page, the compaction cursor and the other state that was previously being managed by the eden heap. Now that there is no need for a heap wrapper, we should refer to the collection of pages containing Ruby objects as a heap again rather than a size pool Notes: Merged: https://github.com/ruby/ruby/pull/11771
2024-10-02YJIT: Merge `impl VALUE` blocks [ci skip]Alan Wu
Reported by Kevin Menard.
2024-09-30Return an Iterator Instead of a Vector in `addrs_to_pages` Method (#11725)whtsht
* Returning an iterator instead of a vec * Avoid changing the meaning of end_page --------- Co-authored-by: Takashi Kokubun <[email protected]> Notes: Merged-By: k0kubun <[email protected]>
2024-09-25YJIT: Cache Context decoding (#11680)Takashi Kokubun
Notes: Merged-By: maximecb <[email protected]>
2024-09-23Fix a typoTakashi Kokubun
2024-09-17YJIT: Accept key for runtime_stats to return only that stat (#11536)Randy Stauner
Notes: Merged-By: maximecb <[email protected]>
2024-09-05YJIT: Speed up block_assumptions_free (#11556)Takashi Kokubun
Notes: Merged-By: k0kubun <[email protected]>
2024-09-05Optimized instruction for Hash#freezeÉtienne Barrié
If a Hash which is empty or only using literals is frozen, we detect this as a peephole optimization and change the instructions to be `opt_hash_freeze`. [Feature #20684] Co-authored-by: Jean Boussier <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/11406
2024-09-05Optimized instruction for Array#freezeÉtienne Barrié
If an Array which is empty or only using literals is frozen, we detect this as a peephole optimization and change the instructions to be `opt_ary_freeze`. [Feature #20684] Co-authored-by: Jean Boussier <[email protected]> Notes: Merged: https://github.com/ruby/ruby/pull/11406
2024-08-27YJIT: Encode doubles to VALUE objects and move stat generation to rust (#11388)Randy Stauner
* YJIT: Encode doubles to VALUE objects and move stat generation to rust Stats that can now be generated from rust have been moved there. * Move object_shape_count call for runtime_stats to rust This reduces the ruby method to a single primitive. * Change hash_aset_usize from macro to function Notes: Merged-By: maximecb <[email protected]>
2024-08-27YJIT: Pass method arguments using registers (#11280)Takashi Kokubun
* YJIT: Pass method arguments using registers * s/at_current_insn/at_compile_target/ * Implement register shuffle Notes: Merged-By: k0kubun <[email protected]>
2024-08-13Delete newarraykwsplatAlan Wu
The pushtoarraykwsplat instruction was designed to replace newarraykwsplat, and we now meet the condition for deletion mentioned in 77c1233f79a0f96a081b70da533fbbde4f3037fa. Notes: Merged: https://github.com/ruby/ruby/pull/11371 Merged-By: XrXr
2024-08-08YJIT: Allow tracing fallback counters (#11347)Takashi Kokubun
* YJIT: Allow tracing fallback counters * Update yjit.md about --yjit-trace-exits=counter Notes: Merged-By: k0kubun <[email protected]>
2024-08-08Make YJIT a GC root rather than an object (#11343)Peter Zhu
YJIT currently uses the YJIT root object to mark objects during GC and update references during compaction. This object otherwise serves no purpose. This commit changes it YJIT to be step when marking the GC root. This saves some memory from being allocated from the system and the GC. Notes: Merged-By: maximecb <[email protected]>
2024-08-02YJIT: Enhance the `String#<<` method substitution to handle integer ↵Kevin Menard
codepoint values. (#11032) * Document why we need to explicitly spill registers. * Simplify passing a byte value to `str_buf_cat`. * YJIT: Enhance the `String#<<` method substitution to handle integer codepoint values. * YJIT: Move runtime type check into YJIT. Performing the check in YJIT means we can make assumptions about the type. It also improves correctness of stack traces in cases where the codepoint argument is not a String or a Fixnum. Notes: Merged-By: maximecb <[email protected]>
2024-07-31YJIT: Decouple Context from encoding details (#11283)Takashi Kokubun
Notes: Merged-By: maximecb <[email protected]>
2024-07-29Expand opt_newarray_send to support Array#pack with buffer keyword argRandy Stauner
Use an enum for the method arg instead of needing to add an id that doesn't map to an actual method name. $ ruby --dump=insns -e 'b = "x"; [v].pack("E*", buffer: b)' before: ``` == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,34)> local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] b@0 0000 putchilledstring "x" ( 1)[Li] 0002 setlocal_WC_0 b@0 0004 putself 0005 opt_send_without_block <calldata!mid:v, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0007 newarray 1 0009 putchilledstring "E*" 0011 getlocal_WC_0 b@0 0013 opt_send_without_block <calldata!mid:pack, argc:2, kw:[#<Symbol:0x000000000023110c>], KWARG> 0015 leave ``` after: ``` == disasm: #<ISeq:<main>@-e:1 (1,0)-(1,34)> local table (size: 1, argc: 0 [opts: 0, rest: -1, post: 0, block: -1, kw: -1@-1, kwrest: -1]) [ 1] b@0 0000 putchilledstring "x" ( 1)[Li] 0002 setlocal_WC_0 b@0 0004 putself 0005 opt_send_without_block <calldata!mid:v, argc:0, FCALL|VCALL|ARGS_SIMPLE> 0007 putchilledstring "E*" 0009 getlocal b@0, 0 0012 opt_newarray_send 3, 5 0015 leave ``` Notes: Merged: https://github.com/ruby/ruby/pull/11249
2024-07-18YJIT: Tweak a comment a little [ci skip]Takashi Kokubun
2024-07-18YJIT: Allow dev_nodebug to disasm release-mode code (#11198)Takashi Kokubun
* YJIT: Allow dev_nodebug to disasm release-mode code * Revert "YJIT: Squash canary before falling back" This reverts commit f05ad373d84909da7541bd6d6ace38b48eaf24a1. The stray canary issue should have been solved by def7023ee4a3fc6eeba9d3a34c31a5bcff315fac, alleviating this codegen accommodation. * s/runtime_assertions/runtime_checks/ --------- Co-authored-by: Alan Wu <[email protected]> Notes: Merged-By: k0kubun <[email protected]>
2024-07-15YJIT: split chain_depth and flag booleans in context (#11169)Maxime Chevalier-Boisvert
Split these values to avoid using a bit mask in the context Use variable length encoding to save a few bits on chain depth
2024-07-15YJIT: Local variable register allocation (#11157)Takashi Kokubun
* YJIT: Local variable register allocation * locals are not stack temps * Rename RegTemps to RegMappings * Rename RegMapping to RegOpnd * Rename local_size to num_locals * s/stack value/operand/ * Rename spill_temps() to spill_regs() * Clarify when num_locals becomes None * Mention that InsnOut uses different registers * Rename get_reg_mapping to get_reg_opnd * Resurrect --yjit-temp-regs capability * Use MAX_CTX_TEMPS and MAX_CTX_LOCALS
2024-07-11YJIT: increase context cache size to 1024 redux (#11140)Maxime Chevalier-Boisvert
* YJIT: increase context cache size to 1024 redux * Move context hashing code outside of unsafe block * Avoid allocating large table on the stack, which would cause a stack overflow Co-authored by Alan Wu @XrXr
2024-07-10YJIT: increase context cache size to 1024 (#10983)Maxime Chevalier-Boisvert
* YJIT: increase context cache size to 1024 The other day I ran into a mysterious bug while increasing the cache size to 1024. I was not able to reproduce this locally. Opening this PR for testing/debugging. * Add extra debug assertions * Add more comments to context code * Update yjit/src/core.rs Co-authored-by: Alan Wu <[email protected]> * Update yjit/src/core.rs * Comment out potentially problematic assertion * Revert cache size to 512 so we can merge other changes --------- Co-authored-by: Alan Wu <[email protected]>
2024-07-08YJIT: `dump-disasm`: Print comments and bytes in release buildsAlan Wu
This change implements a fallback mode for the `--yjit-dump-disasm` development command-line option to make it usable in release builds. Previously, using the option with release builds of YJIT yielded only a warning asking the user to build with `--enable-yjit=dev`. While builds that use the `disasm` feature still give the best output, just having the comments is useful enough for many kinds of debugging. Having it usable in release builds is nice for new hackers, too, since this allows for tinkering without having to learn how to build YJIT in development mode. Sample output on A64: ``` # regenerate_branch # Insn: 0001 opt_send_without_block (stack_size: 1) # guard known object with singleton class 0x11f7e0034: 4b 00 00 58 03 00 00 14 08 ce 9c 04 01 00 00 0x11f7e0043: 00 3f 00 0b eb 81 06 01 54 1f 20 03 d5 # RUBY_VM_CHECK_INTS(ec) 0x11f7e0050: 8b 02 42 b8 cb 07 01 35 # stack overflow check 0x11f7e0058: ab 62 02 91 7f 02 0b eb 69 07 01 54 # save PC to CFP 0x11f7e0064: 0b 3b 9a d2 2b 2f a0 f2 0b 00 cc f2 6b 02 00 0x11f7e0073: f8 ab 82 00 91 ``` To ensure this feature doesn't incur too much cost when running without the `--yjit-dump-disasm` option, I checked that there is no significant impact to compile time and memory usage with the `compile_time_ns` and `yjit_alloc_size` entry in `RubyVM::YJIT.runtime_stats`. For each sample, I ran 3 iterations of the `lobsters` YJIT benchmark. The statistics summary and done with the `summary` function in R. Compile time, sample size of 60, lower is better: ``` Before After Min. :2.054e+09 Min. :2.028e+09 1st Qu.:2.069e+09 1st Qu.:2.044e+09 Median :2.081e+09 Median :2.060e+09 Mean :2.089e+09 Mean :2.066e+09 3rd Qu.:2.109e+09 3rd Qu.:2.085e+09 Max. :2.146e+09 Max. :2.144e+09 ``` Allocation size, sample size of 20, lower is better: ``` Before After Min. :21804742 Min. :21794082 1st Qu.:21826682 1st Qu.:21816282 Median :21844042 Median :21826814 Mean :21960664 Mean :22026291 3rd Qu.:21861228 3rd Qu.:22040439 Max. :22587426 Max. :22930614 ``` The `yjit_alloc_size` samples are noisy, but since the average increased by only 0.3%, and the median is lower, I feel safe saying that there is no significant change.