aboutsummaryrefslogtreecommitdiffstats
path: root/vm.c
Commit message (Collapse)AuthorAgeFilesLines
* Fix -Wundef warningsNobuyoshi Nakada2022-10-261-1/+1
|
* Remove unused class serialJemma Issroff2022-10-211-12/+1
| | | | | | | | Before object shapes, we were using class serial to invalidate inline caches. Now that we use shape_id for inline cache keys, the class serial is unnecessary. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
* push dummy frame for loading processKoichi Sasada2022-10-201-11/+14
| | | | | | | | | | | | | This patch pushes dummy frames when loading code for the profiling purpose. The following methods push a dummy frame: * `Kernel#require` * `Kernel#load` * `RubyVM::InstructionSequence.compile_file` * `RubyVM::InstructionSequence.load_from_binary` https://bugs.ruby-lang.org/issues/18559
* Make inline cache reads / writes atomic with object shapesJemma Issroff2022-10-111-2/+2
| | | | | | | | | | | | | | Prior to this commit, we were reading and writing ivar index and shape ID in inline caches in two separate instructions when getting and setting ivars. This meant there was a race condition with ractors and these caches where one ractor could change a value in the cache while another was still reading from it. This commit instead reads and writes shape ID and ivar index to inline caches atomically so there is no longer a race condition. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: John Hawthorn <john@hawthorn.email>
* Revert "Revert "This commit implements the Object Shapes technique in CRuby.""Jemma Issroff2022-10-111-0/+31
| | | | This reverts commit 9a6803c90b817f70389cae10d60b50ad752da48f.
* Revert "This commit implements the Object Shapes technique in CRuby."Aaron Patterson2022-09-301-31/+0
| | | | This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
* This commit implements the Object Shapes technique in CRuby.Jemma Issroff2022-09-281-0/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Object Shapes is used for accessing instance variables and representing the "frozenness" of objects. Object instances have a "shape" and the shape represents some attributes of the object (currently which instance variables are set and the "frozenness"). Shapes form a tree data structure, and when a new instance variable is set on an object, that object "transitions" to a new shape in the shape tree. Each shape has an ID that is used for caching. The shape structure is independent of class, so objects of different types can have the same shape. For example: ```ruby class Foo def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end class Bar def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end foo = Foo.new # `foo` has shape id 2 bar = Bar.new # `bar` has shape id 2 ``` Both `foo` and `bar` instances have the same shape because they both set instance variables of the same name in the same order. This technique can help to improve inline cache hits as well as generate more efficient machine code in JIT compilers. This commit also adds some methods for debugging shapes on objects. See `RubyVM::Shape` for more details. For more context on Object Shapes, see [Feature: #18776] Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
* Revert this until we can figure out WB issues or remove shapes from GCAaron Patterson2022-09-261-45/+0
| | | | | | | | | | Revert "* expand tabs. [ci skip]" This reverts commit 830b5b5c351c5c6efa5ad461ae4ec5085e5f0275. Revert "This commit implements the Object Shapes technique in CRuby." This reverts commit 9ddfd2ca004d1952be79cf1b84c52c79a55978f4.
* This commit implements the Object Shapes technique in CRuby.Jemma Issroff2022-09-261-0/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Object Shapes is used for accessing instance variables and representing the "frozenness" of objects. Object instances have a "shape" and the shape represents some attributes of the object (currently which instance variables are set and the "frozenness"). Shapes form a tree data structure, and when a new instance variable is set on an object, that object "transitions" to a new shape in the shape tree. Each shape has an ID that is used for caching. The shape structure is independent of class, so objects of different types can have the same shape. For example: ```ruby class Foo def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end class Bar def initialize # Starts with shape id 0 @a = 1 # transitions to shape id 1 @b = 1 # transitions to shape id 2 end end foo = Foo.new # `foo` has shape id 2 bar = Bar.new # `bar` has shape id 2 ``` Both `foo` and `bar` instances have the same shape because they both set instance variables of the same name in the same order. This technique can help to improve inline cache hits as well as generate more efficient machine code in JIT compilers. This commit also adds some methods for debugging shapes on objects. See `RubyVM::Shape` for more details. For more context on Object Shapes, see [Feature: #18776] Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org> Co-Authored-By: Eileen M. Uchitelle <eileencodes@gmail.com> Co-Authored-By: John Hawthorn <john@hawthorn.email>
* Do not fork the process on --mjit-waitTakashi Kokubun2022-09-061-2/+2
| | | | | fork is for parallel compilation, but --mjit-wait cancels it. It's more useful to not fork it for binding.irb, debugging, etc.
* Introduce `usage_analysis_clear`S.H2022-08-291-26/+23
|
* Rename mjit_exec to jit_exec (#6262)Takashi Kokubun2022-08-191-14/+14
| | | | | | | * Rename mjit_exec to jit_exec * Rename mjit_exec_slowpath to mjit_check_iseq * Remove mjit_exec references from comments
* Move `mjit_exec` to vm.cNobuyoshi Nakada2022-08-171-0/+97
|
* Simplify around `USE_YJIT` macro (#6240)Nobuyoshi Nakada2022-08-151-1/+1
| | | | | | | | * Simplify around `USE_YJIT` macro - Use `USE_YJIT` macro only instead of `YJIT_BUILD`. - An intermediate macro `YJIT_SUPPORTED_P` is no longer used. * Bail out if YJIT is enabled on unsupported platforms
* Rename rb_ary_tmp_new to rb_ary_hidden_newPeter Zhu2022-07-261-1/+1
| | | | | | 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-1/+1
| | | | ... as per ko1's request.
* Expand tabs [ci skip]Takashi Kokubun2022-07-211-567/+567
| | | | [Misc #18891]
* Prevent the stack from being marked twiceAaron Patterson2022-07-201-2/+1
| | | | | | | This commit prevents the stack from being marked twice: once via the Fiber, and once via the Thread. It introduces an assertion to assert that the ec on the thread is the same as the ec on the Fiber being marked via the thread.
* Fix infinite loop when b_return TracePoint throwsAlan Wu2022-06-221-2/+2
| | | | | | | | | Previously, we didn't pop the frame that runs the TracePoint hook for b_return events for blocks running as methods (bmethods). In case the hook raises, that formed an infinite loop during stack unwinding in hook_before_rewind(). [Bug #18060]
* Move RubyVM::MJIT to builtin RubyTakashi Kokubun2022-06-151-39/+0
| | | | just less C code to maintain
* remove `NON_SCALAR_THREAD_ID` supportKoichi Sasada2022-05-241-4/+0
| | | | | | | | | `NON_SCALAR_THREAD_ID` shows `pthread_t` is non-scalar (non-pointer) and only s390x is known platform. However, the supporting code is very complex and it is only used for deubg print information. So this patch removes the support of `NON_SCALAR_THREAD_ID` and make the code simple.
* setup vm->main_ractor before `Init_native_thread()`Koichi Sasada2022-05-201-5/+6
|
* `rb_thread_t::serial` for debugKoichi Sasada2022-05-201-0/+5
| | | | | | | | | | | `rb_thread_t::serial` is auto-incremented serial number for threads and it can overflow, it means the serial is not a ID for each thread, it is only for debug print. `RUBY_DEBUG_LOG` shows this information. Also skip EC related information if EC is NULL. This patch enable to use `RUBY_DEBUG_LOG` without setup EC.
* Delete autoload data from global features after autoload has completed. (#5910)Samuel Williams2022-05-171-2/+2
| | | | | * Update naming of critical section assertions macros. * Improved locking for autoload.
* Fix various autoload race conditions. (#5898)Samuel Williams2022-05-151-0/+4
| | | | | | | | | | | * Add RUBY_VM_CRITICAL_SECTION for detecting unexpected context switch. * Prevent race between GC mark and autoload setup. * Protect race on autoload state. * Avoid potential race condition when allocating `autoload_featuremap`. * Add NEWS entry for autoload fixes.
* Rust YJITAlan Wu2022-04-271-1/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* introduce struct `rb_native_thread`Koichi Sasada2022-04-231-7/+6
| | | | | | | | | `rb_thread_t` contained `native_thread_data_t` to represent thread implementation dependent data. This patch separates them and rename it `rb_native_thread` and point it from `rb_thraed_t`. Now, 1 Ruby thread (`rb_thread_t`) has 1 native thread (`rb_native_thread`).
* refactoring thread inits in vm.cKoichi Sasada2022-04-231-30/+22
| | | | | | * `th_init` accepts vm and ractor. * remove `ruby_thread_init` because it is duplicated with `th_init`. * add some comments.
* Uncomment code to raise LocalJumpError for yield across thread through enumJeremy Evans2022-04-211-2/+0
| | | | | | | | Not sure if this is the correct fix. It does raise LocalJumpError in the yielding thread as you would expect, but the value yielded to the calling thread is still yielded without an exception. Fixes [Bug #18649]
* Raise RuntimeError if Kernel#binding is called from a non-Ruby frameJeremy Evans2022-04-061-7/+4
| | | | | | | | | Check whether the current or previous frame is a Ruby frame in call_trace_func and rb_tracearg_binding before attempting to create a binding for the frame. Fixes [Bug #18487] Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
* RubyVM.stat constant cache metrics (#5766)Kevin Newton2022-04-051-32/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | Before the new constant cache behavior, caches were invalidated by a single global variable. You could inspect the value of this variable with RubyVM.stat(:global_constant_state). This was mostly useful to verify the behavior of the VM or to test constant loading like in Rails. With the new constant cache behavior, we introduced RubyVM.stat(:constant_cache) which returned a hash with symbol keys and integer values that represented the number of live constant caches associated with the given symbol. Additionally, we removed the old RubyVM.stat(:global_constant_state). This was proven to be not very useful, so it doesn't help you diagnose constant loading issues. So, instead we added the global constant state back into the RubyVM output. However, that number can be misleading as now when you invalidate something like `Foo::Bar::Baz` you're actually invalidating 3 different lists of inline caches. This commit attempts to get the best of both worlds. We remove RubyVM.stat(:global_constant_state) like we did originally, as it doesn't have the same semantic meaning and it could be confusing going forward. Instead we add RubyVM.stat(:constant_cache_invalidations) and RubyVM.stat(:constant_cache_misses). These two metrics should provide enough information to diagnose any constant loading issues, as well as provide a replacement for the old global constant state.
* Bring back RubyVM.stat(:global_constant_state)Kevin Newton2022-04-041-1/+3
| | | | This was removed as part of [Feature #18589]. But some applications were relying on this behavior. So bringing this back to make it better for backward compatibility going forward.
* Finer-grained constant cache invalidation (take 2)Kevin Newton2022-04-011-9/+52
| | | | | | | | | | | | | | | | | | | | | | | | 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 "Raise RuntimeError if Kernel#binding is called from a non-Ruby frame"Jeremy Evans2022-04-011-4/+7
| | | | | | This reverts commit 343ea9967e4a6b279eed6bd8e81ad0bdc747f254. This causes an assertion failure with -DRUBY_DEBUG=1 -DRGENGC_CHECK_MODE=2
* Prefix ccan headers (#4568)Nobuyoshi Nakada2022-03-301-7/+7
| | | | | | | | | | | | | * Prefixed ccan headers * Remove unprefixed names in ccan/build_assert * Remove unprefixed names in ccan/check_type * Remove unprefixed names in ccan/container_of * Remove unprefixed names in ccan/list Co-authored-by: Samuel Williams <samuel.williams@oriontransfer.co.nz>
* Revert "Finer-grained inline constant cache invalidation"Nobuyoshi Nakada2022-03-251-52/+9
| | | | | | | | | | | | 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.
* Raise RuntimeError if Kernel#binding is called from a non-Ruby frameJeremy Evans2022-03-241-7/+4
| | | | | | | | | Check whether the current or previous frame is a Ruby frame in call_trace_func before attempting to create a binding for the frame. Fixes [Bug #18487] Co-authored-by: Alan Wu <XrXr@users.noreply.github.com>
* Finer-grained inline constant cache invalidationKevin Newton2022-03-241-9/+52
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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-40/+40
| | | | | | 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.
* [wasm] vm.c: stop unwinding to main for every vm_exec call by setjmpYuta Saito2022-02-181-0/+80
| | | | | | | | | | | | | | | | | | | | | | | | the original rb_wasm_setjmp implementation always unwinds to the root call frame to have setjmp compatible interface, and simulate sjlj's undefined behavior. Therefore, every vm_exec call unwinds to main, and a deep call stack makes setjmp call very expensive. The following snippet from optcarrot takes 5s even though it takes less than 0.3s on native. ``` [0x0, 0x4, 0x8, 0xc].map do |attr| (0..7).map do |j| (0...0x10000).map do |i| clr = i[15 - j] * 2 + i[7 - j] clr != 0 ? attr | clr : 0 end end end ``` This patch adds a WASI specialized vm_exec which uses lightweight try-catch API without unwinding to the root frame. After this patch, the above snippet takes only 0.5s.
* Fix error: old-style function definitionKazuhiro NISHIYAMA2022-01-221-1/+1
| | | | | | | | | | | https://rubyci.s3.amazonaws.com/debian-riscv64/ruby-master/log/20220122T050018Z.log.html.gz#miniruby ``` compiling vm_trace.c vm_trace.c: In function 'rb_vm_memsize_postponed_job_buffer': vm_trace.c:1599:1: error: old-style function definition [-Werror=old-style-definition] 1599 | rb_vm_memsize_postponed_job_buffer() | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ```
* Accurately report VM memsizeKevin Newton2022-01-211-4/+52
| | | | | | Currently the calculation only counts the size of the struct. This commit adds the size of the associated st tables, id tables, and linked lists. Still missing is the size of the ractors and (potentially) the size of the object space.
* T#dup (T < Proc) should return T's objectKoichi Sasada2022-01-131-1/+1
| | | | | T#dup (T < Proc) returns Proc object (not T) from Ruby 1.9. [Bug #17545]
* Show the target Proc on Ractor::IsolationErrorSutou Kouhei2021-12-221-1/+3
| | | | It's useful for debug.
* make `overloaded_cme_table` truly weak key mapKoichi Sasada2021-12-211-1/+5
| | | | | | | | | | | | | `overloaded_cme_table` keeps cme -> monly_cme pairs to manage corresponding `monly_cme` for `cme`. The lifetime of the `monly_cme` should be longer than `monly_cme`, but the previous patch losts the reference to the living `monly_cme`. Now `overloaded_cme_table` values are always root (keys are only weak reference), it means `monly_cme` does not freed until corresponding `cme` is invalidated. To make managing easy, move `overloaded_cme_table` to `rb_vm_t`.
* Remove RubyVM::JIT (#5275)Takashi Kokubun2021-12-151-3/+0
| | | [Feature #18349] reverts [Feature #17490]
* Don't invalidate BOPs when aliases redefinedJohn Hawthorn2021-12-141-3/+8
| | | | | | | | | | | | | Previously when redefining an alias of a BOP, we would unnecessarily invalidate the bop. For example: class String alias len length private :len end This commit avoids this by checking that the called_id on the method entry matches the original_id on the definition.
* YJIT: Avoid unnecessary BOP invalidationJohn Hawthorn2021-12-141-3/+5
| | | | | Previously we would invalidate BOPs in YJIT when the method registered as a BOP was redefined on a subclass.
* Prepare for removing RubyVM::JIT (#5262)Takashi Kokubun2021-12-131-12/+11
|
* `Ractor.make_shareable` checks proc's seflKoichi Sasada2021-12-091-0/+4
| | | | | | | `Ractor.make_shareable(proc_obj)` raises an `IsolationError` if the self of `proc_obj` is not a shareable object. [Bug #18243]