summaryrefslogtreecommitdiff
path: root/iseq.c
Commit message (Collapse)AuthorAgeFilesLines
* Rename rb_ary_tmp_new to rb_ary_hidden_newPeter Zhu2022-07-261-2/+2
| | | | | | rb_ary_tmp_new suggests that the array is temporary in some way, but that's not true, it just creates an array that's hidden and not on the transient heap. This commit renames it to rb_ary_hidden_new.
* Add "rb_" prefixes to toplevel enum definitionsYusuke Endoh2022-07-221-10/+10
| | | | ... as per ko1's request.
* Expand tabs [ci skip]Takashi Kokubun2022-07-211-757/+757
| | | | [Misc #18891]
* Separate TS_IVC and TS_ICVARC in is_entries buffersJemma Issroff2022-07-181-4/+15
| | | | This allows us to treat cvar caches differently than ivar caches.
* Simplify BLSR codeNobuyoshi Nakada2022-07-081-1/+1
| | | | And suppress unary minus operator to unsigned type warnings by VC.
* Remove ISEQ_MARKABLE_ISEQ flagAaron Patterson2022-07-071-41/+41
| | | | | We don't need this flag anymore. We have all the info we need via the bitmap and the is_entries list.
* Use iseq bitmap when updating referencesAaron Patterson2022-06-291-88/+12
| | | | | This allows us to delete the disassembly code path for reference updating.
* Move function to `static inline` so we don't have leaked globalsAaron Patterson2022-06-291-20/+0
| | | | | This function shouldn't leak and is only needed during instruction assembly
* Fix ISeq dump / load in array casesAaron Patterson2022-06-291-2/+24
| | | | | | | | | | | We need to dump relative offsets for inline storage entries so that loading iseqs as an array works as well. This commit also has some minor refactoring to make computing relative ISE information easier. This should fix the iseq dump / load as array tests we're seeing fail in CI. Co-Authored-By: John Hawthorn <john@hawthorn.email>
* iseq.c: Use ntz_intptr for faster bitmap scanJean Boussier2022-06-251-16/+12
|
* Free bitmap buffer if it's not usedAaron Patterson2022-06-231-4/+6
| | | | | If the iseqs don't have any objects in them that need marking, then immediately free the bitmap buffer
* Flatten bitmap when there is only one elementAaron Patterson2022-06-231-18/+29
| | | | | We can avoid allocating a bitmap when the number of elements in the iseq is fewer than the size of an iseq_bits_t
* Speed up ISeq by marking via bitmaps and IC rearrangingAaron Patterson2022-06-231-9/+61
| | | | | | | | | | | | | | | | This commit adds a bitfield to the iseq body that stores offsets inside the iseq buffer that contain values we need to mark. We can use this bitfield to mark objects instead of disassembling the instructions. This commit also groups inline storage entries and adds a counter for each entry. This allows us to iterate and mark each entry without disassembling instructions Since we have a bitfield and grouped inline caches, we can mark all VALUE objects associated with instructions without actually disassembling the instructions at mark time. [Feature #18875] [ruby-core:109042]
* Reuse an interned stringNobuyoshi Nakada2022-06-171-3/+2
| | | | | | Repeating to intern the same string is just redundant, as interned strings for the same content are always the same object until it gets collected.
* Rust YJITAlan Wu2022-04-271-3/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In December 2021, we opened an [issue] to solicit feedback regarding the porting of the YJIT codebase from C99 to Rust. There were some reservations, but this project was given the go ahead by Ruby core developers and Matz. Since then, we have successfully completed the port of YJIT to Rust. The new Rust version of YJIT has reached parity with the C version, in that it passes all the CRuby tests, is able to run all of the YJIT benchmarks, and performs similarly to the C version (because it works the same way and largely generates the same machine code). We've even incorporated some design improvements, such as a more fine-grained constant invalidation mechanism which we expect will make a big difference in Ruby on Rails applications. Because we want to be careful, YJIT is guarded behind a configure option: ```shell ./configure --enable-yjit # Build YJIT in release mode ./configure --enable-yjit=dev # Build YJIT in dev/debug mode ``` By default, YJIT does not get compiled and cargo/rustc is not required. If YJIT is built in dev mode, then `cargo` is used to fetch development dependencies, but when building in release, `cargo` is not required, only `rustc`. At the moment YJIT requires Rust 1.60.0 or newer. The YJIT command-line options remain mostly unchanged, and more details about the build process are documented in `doc/yjit/yjit.md`. The CI tests have been updated and do not take any more resources than before. The development history of the Rust port is available at the following commit for interested parties: https://github.com/Shopify/ruby/commit/1fd9573d8b4b65219f1c2407f30a0a60e537f8be Our hope is that Rust YJIT will be compiled and included as a part of system packages and compiled binaries of the Ruby 3.2 release. We do not anticipate any major problems as Rust is well supported on every platform which YJIT supports, but to make sure that this process works smoothly, we would like to reach out to those who take care of building systems packages before the 3.2 release is shipped and resolve any issues that may come up. [issue]: https://bugs.ruby-lang.org/issues/18481 Co-authored-by: Maxime Chevalier-Boisvert <maximechevalierb@gmail.com> Co-authored-by: Noah Gibbs <the.codefolio.guy@gmail.com> Co-authored-by: Kevin Newton <kddnewton@gmail.com>
* Adjust indent [ci skip]Nobuyoshi Nakada2022-04-021-29/+29
|
* Finer-grained constant cache invalidation (take 2)Kevin Newton2022-04-011-0/+114
| | | | | | | | | | | | | | | | | | | | | | | | This commit reintroduces finer-grained constant cache invalidation. After 8008fb7 got merged, it was causing issues on token-threaded builds (such as on Windows). The issue was that when you're iterating through instruction sequences and using the translator functions to get back the instruction structs, you're either using `rb_vm_insn_null_translator` or `rb_vm_insn_addr2insn2` depending if it's a direct-threading build. `rb_vm_insn_addr2insn2` does some normalization to always return to you the non-trace version of whatever instruction you're looking at. `rb_vm_insn_null_translator` does not do that normalization. This means that when you're looping through the instructions if you're trying to do an opcode comparison, it can change depending on the type of threading that you're using. This can be very confusing. So, this commit creates a new translator function `rb_vm_insn_normalizing_translator` to always return the non-trace version so that opcode comparisons don't have to worry about different configurations. [Feature #18589]
* Revert "Finer-grained inline constant cache invalidation"Nobuyoshi Nakada2022-03-251-90/+0
| | | | | | | | | | | | This reverts commits for [Feature #18589]: * 8008fb7352abc6fba433b99bf20763cf0d4adb38 "Update formatting per feedback" * 8f6eaca2e19828e92ecdb28b0fe693d606a03f96 "Delete ID from constant cache table if it becomes empty on ISEQ free" * 629908586b4bead1103267652f8b96b1083573a8 "Finer-grained inline constant cache invalidation" MSWin builds on AppVeyor have been crashing since the merger.
* Delete ID from constant cache table if it becomes empty on ISEQ freeKevin Newton2022-03-241-0/+5
| | | | Co-authored-by: John Hawthorn <john@hawthorn.email>
* Finer-grained inline constant cache invalidationKevin Newton2022-03-241-0/+85
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Current behavior - caches depend on a global counter. All constant mutations cause caches to be invalidated. ```ruby class A B = 1 end def foo A::B # inline cache depends on global counter end foo # populate inline cache foo # hit inline cache C = 1 # global counter increments, all caches are invalidated foo # misses inline cache due to `C = 1` ``` Proposed behavior - caches depend on name components. Only constant mutations with corresponding names will invalidate the cache. ```ruby class A B = 1 end def foo A::B # inline cache depends constants named "A" and "B" end foo # populate inline cache foo # hit inline cache C = 1 # caches that depend on the name "C" are invalidated foo # hits inline cache because IC only depends on "A" and "B" ``` Examples of breaking the new cache: ```ruby module C # Breaks `foo` cache because "A" constant is set and the cache in foo depends # on "A" and "B" class A; end end B = 1 ``` We expect the new cache scheme to be invalidated less often because names aren't frequently reused. With the cache being invalidated less, we can rely on its stability more to keep our constant references fast and reduce the need to throw away generated code in YJIT.
* Add ISEQ_BODY macroPeter Zhu2022-03-241-52/+52
| | | | | | Use ISEQ_BODY macro to get the rb_iseq_constant_body of the ISeq. Using this macro will make it easier for us to change the allocation strategy of rb_iseq_constant_body when using Variable Width Allocation.
* Fix indents [ci skip]Nobuyoshi Nakada2022-02-031-1/+1
|
* Treat TS_ICVARC cache as separate from TS_IVC cacheJemma Issroff2022-02-021-0/+3
|
* `rb_iseq_update_references()` cares `script_lines`Koichi Sasada2021-12-191-0/+1
| | | | | and it fixes compaction issue: http://rubyci.s3.amazonaws.com/freebsd12/ruby-master/log/20211218T203001Z.fail.html.gz
* `iseq_type_sym()` -> `iseq_type_id()`Koichi Sasada2021-12-191-40/+40
| | | | | `iseq_type_sym()` returns `ID` (surprisingly!) so rename it to `iseq_type_id()`.
* add `rb_iseq_type()` to return iseq type in SymbolKoichi Sasada2021-12-191-36/+53
| | | | It is shorthand `ISeq#to_a[9]`.
* fix local TP memory leakKoichi Sasada2021-12-151-3/+2
| | | | | | | It free `rb_hook_list_t` itself if needed. To recognize the need, this patch introduced `rb_hook_list_t::is_local` flag. This patch is succession of https://github.com/ruby/ruby/pull/4652
* Introduce an option "--dump=insns_without_opt" for debugging purposesYusuke Endoh2021-12-131-2/+2
|
* Rework tracing for blocks running as methodsAlan Wu2021-12-011-2/+23
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The main impetus for this change is to fix [Bug #13392]. Previously, we fired the "return" TracePoint event after popping the stack frame for the block running as method (BMETHOD). This gave undesirable source location outputs as the return event normally fires right before the frame going away. The iseq for each block can run both as a block and as a method. To accommodate that, this commit makes vm_trace() fire call/return events for instructions that have b_call/b_return events attached when the iseq is running as a BMETHOD. The logic for rewriting to "trace_*" instruction is tweaked so that when the user listens to call/return events, instructions with b_call/b_return become trace variants. To continue to provide the return value for non-local returns done using the "return" or "break" keyword inside BMETHODs, the stack unwinding code is tweaked. b_return events now provide the same return value as return events for these non-local cases. A pre-existing test deemed not providing a return value for these b_return events as a limitation. This commit removes the checks for call/return TracePoint events that happen when calling into BMETHODs when no TracePoints are active. Technically, migrating just the return event is enough to fix the bug, but migrating both call and return removes our reliance on `VM_FRAME_FLAG_FINISH` and re-entering the interpreter when the caller is already in the interpreter.
* add `VM_CALLCACHE_ON_STACK`Koichi Sasada2021-11-171-6/+11
| | | | check if iseq refers to on stack CC (it shouldn't).
* `Primitive.mandatory_only?` for fast pathKoichi Sasada2021-11-151-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Compare with the C methods, A built-in methods written in Ruby is slower if only mandatory parameters are given because it needs to check the argumens and fill default values for optional and keyword parameters (C methods can check the number of parameters with `argc`, so there are no overhead). Passing mandatory arguments are common (optional arguments are exceptional, in many cases) so it is important to provide the fast path for such common cases. `Primitive.mandatory_only?` is a special builtin function used with `if` expression like that: ```ruby def self.at(time, subsec = false, unit = :microsecond, in: nil) if Primitive.mandatory_only? Primitive.time_s_at1(time) else Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in)) end end ``` and it makes two ISeq, ``` def self.at(time, subsec = false, unit = :microsecond, in: nil) Primitive.time_s_at(time, subsec, unit, Primitive.arg!(:in)) end def self.at(time) Primitive.time_s_at1(time) end ``` and (2) is pointed by (1). Note that `Primitive.mandatory_only?` should be used only in a condition of an `if` statement and the `if` statement should be equal to the methdo body (you can not put any expression before and after the `if` statement). A method entry with `mandatory_only?` (`Time.at` on the above case) is marked as `iseq_overload`. When the method will be dispatch only with mandatory arguments (`Time.at(0)` for example), make another method entry with ISeq (2) as mandatory only method entry and it will be cached in an inline method cache. The idea is similar discussed in https://bugs.ruby-lang.org/issues/16254 but it only checks mandatory parameters or more, because many cases only mandatory parameters are given. If we find other cases (optional or keyword parameters are used frequently and it hurts performance), we can extend the feature.
* need to mark script_linesKoichi Sasada2021-10-291-0/+1
|
* freeze (make shareable) script_linesKoichi Sasada2021-10-211-2/+7
|
* `RubyVM.keep_script_lines`Koichi Sasada2021-10-211-4/+40
| | | | | | | | | | | | | | `RubyVM.keep_script_lines` enables to keep script lines for each ISeq and AST. This feature is for debugger/REPL support. ```ruby RubyVM.keep_script_lines = true RubyVM::keep_script_lines = true eval("def foo = nil\ndef bar = nil") pp RubyVM::InstructionSequence.of(method(:foo)).script_lines ```
* Cleanup iseq.c minimize diff with upstreamAlan Wu2021-10-201-21/+8
| | | | | Most of these are vestiges of our old setup where we hack into the interpreter loop.
* TracePoint supportAlan Wu2021-10-201-16/+0
| | | | | | | | | | | | | | | | | | | | | | This change fixes some cases where YJIT fails to fire tracing events. Most of the situations YJIT did not handle correctly involves enabling tracing while running inside generated code. A new operation to invalidate all generated code is added, which uses patching to make generated code exit at the next VM instruction boundary. A new routine called `jit_prepare_routine_call()` is introduced to facilitate this and should be used when generating code that could allocate, or could otherwise use `RB_VM_LOCK_ENTER()`. The `c_return` event is fired in the middle of an instruction as opposed to at an instruction boundary, so it requires special handling. C method call return points are patched to go to a fucntion which does everything the interpreter does, including firing the `c_return` event. The generated code for C method calls normally does not fire the event. Invalided code should not change after patching so the exits are not clobbered. A new variable is introduced to track the region of code that should not change.
* Clear JIT code when tracepoints get enabledAaron Patterson2021-10-201-0/+11
| | | | | Clear out any JIT code on iseqs when tracepoints get enabled. We can't handle tracepoints right now, so we'll just try to recompile later.
* Yet Another Ruby JIT!Jose Narvaez2021-10-201-6/+6
| | | | Renaming uJIT to YJIT. AKA s/ujit/yjit/g.
* Should fix builds without mjit supportAlan Wu2021-10-201-0/+1
|
* Tie lifetime of uJIT blocks to iseqsAlan Wu2021-10-201-0/+3
| | | | | | | | | | | | | | | | | | | | * Tie lifetime of uJIT blocks to iseqs Blocks weren't being freed when iseqs are collected. * Add rb_dary. Use it for method dependency table * Keep track of blocks per iseq Remove global version_tbl * Block version bookkeeping fix * dary -> darray * free ujit_blocks * comment about size of ujit_blocks
* Restore interpreter regs in ujit hook. Implement leave bytecode.Maxime Chevalier-Boisvert2021-10-201-11/+2
|
* Add to the MicroJIT scraper an example that passes ecAlan Wu2021-10-201-0/+7
|
* MicroJIT: Don't compile trace instructionsAlan Wu2021-10-201-0/+19
|
* Small build fixesAlan Wu2021-10-201-0/+2
|
* Try to fix Windows buildAlan Wu2021-10-201-1/+0
|
* Avoid triggering GC while translating threaded codeAlan Wu2021-10-201-0/+1
|
* Remove PC argument from ujit instructionsMaxime Chevalier-Boisvert2021-10-201-1/+1
|
* Removed native_pop_code, ported call with labelMaxime Chevalier-Boisvert2021-10-201-61/+0
|
* Generate multiple copies of native code for `pop`Alan Wu2021-10-201-6/+6
| | | | | | Insert generated addresses into st_table for mapping native code addresses back to info about VM instructions. Export `encoded_insn_data` to do this. Also some style fixes.
* Reimplement Alan's pop instruction with the new assemblerMaxime Chevalier-Boisvert2021-10-201-0/+26
|