summaryrefslogtreecommitdiff
path: root/vm.c
Commit message (Collapse)AuthorAgeFilesLines
* `nt->serial` for `RUBY_DEBUG_LOG`Koichi Sasada2023-03-311-0/+3
| | | | | | Show native thread's serial on `RUBY_DEBUG_LOG`. `nt->serial` is also stored into `ruby_nt_serial` if the compiler supports `RB_THREAD_LOCAL_SPECIFIER`.
* YJIT: Leave cfp->pc uninitialized for VM_FRAME_MAGIC_CFUNCAlan Wu2023-03-291-1/+1
| | | | | | | | | C function frames don't need to use the VM-specific pc field to run properly. When pushing a control frame from output code, save one instruction by leaving the field uninitialized. Fix-up rb_vm_svar_lep(), which is used while setting local variables via Regexp#=~. Use cfp->iseq as a secondary signal so it can stop assuming that all CFUNC frames always have zero pc's.
* YJIT: Add `--yjit-pause` and `RubyVM::YJIT.resume` (#7609)Maxime Chevalier-Boisvert2023-03-281-1/+1
| | | | | | | | | | | | | | | | | | | * YJIT: Add --yjit-pause and RubyVM::YJIT.resume This allows booting YJIT in a suspended state. We chose to add a new command line option as opposed to simply allowing YJIT.resume to work without any command line option because it allows for combining with YJIT tuning command line options. It also simpifies implementation. Paired with Kokubun and Maxime. * Update yjit.rb Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com> --------- Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
* Fix shape allocation limitsAaron Patterson2023-03-221-2/+2
| | | | | | | | | | We can only allocate enough shapes to fit in the shape buffer. MAX_SHAPE_ID was based on the theoretical maximum number of shapes we could have, not on the amount of memory we can actually consume. This commit changes the MAX_SHAPE_ID to be based on the amount of memory we're allowed to consume. Co-Authored-By: Jemma Issroff <jemmaissroff@gmail.com>
* Fix the JIT-unsupported caseTakashi Kokubun2023-03-161-1/+1
|
* Refactor jit_func_t and jit_execTakashi Kokubun2023-03-161-2/+2
| | | | | I closed https://github.com/ruby/ruby/pull/7543, but part of the diff seems useful regardless, so I extracted it.
* Remove SIGCHLD `waidpid`. (#7527)Samuel Williams2023-03-151-4/+0
| | | | | | | * Remove `waitpid_lock` and related code. * Remove un-necessary test. * Remove `rb_thread_sleep_interruptible` dead code.
* Remove unused jit_enable_p flagTakashi Kokubun2023-03-141-14/+9
| | | | This was used only by MJIT.
* YJIT: Implement throw instruction (#7491)Takashi Kokubun2023-03-141-24/+21
| | | | | | | * Break up jit_exec from vm_sendish * YJIT: Implement throw instruction * YJIT: Explain what rb_vm_throw does [ci skip]
* Revert SIGCHLD changes to diagnose CI failures. (#7517)Samuel Williams2023-03-141-0/+4
| | | | | | | | | | | | | | | * Revert "Remove special handling of `SIGCHLD`. (#7482)" This reverts commit 44a0711eab7fbc71ac2c8ff489d8c53e97a8fe75. * Revert "Remove prototypes for functions that are no longer used. (#7497)" This reverts commit 4dce12bead3bfd91fd80b5e7195f7f540ffffacb. * Revert "Remove SIGCHLD `waidpid`. (#7476)" This reverts commit 1658e7d96696a656d9bd0a0c84c82cde86914ba2. * Fix change to rjit variable name.
* Remove an unused VM optionTakashi Kokubun2023-03-131-3/+0
| | | | This seems to be used nowhere today.
* RJIT: Stop allowing leaked globals rjit_*Takashi Kokubun2023-03-081-3/+3
|
* Remove SIGCHLD `waidpid`. (#7476)Samuel Williams2023-03-091-4/+0
| | | | | | | * Remove `waitpid_lock` and related code. * Remove un-necessary test. * Remove `rb_thread_sleep_interruptible` dead code.
* Allow enabling YJIT and RJIT independently (#7474)Takashi Kokubun2023-03-071-1/+7
| | | | | We used to require MJIT is supported when YJIT is supported. However, now that RJIT dropped some platforms that YJIT supports, it no longer makes sense. We should be able to enable only YJIT, and vice versa.
* s/mjit/rjit/Takashi Kokubun2023-03-061-7/+7
|
* s/MJIT/RJIT/Takashi Kokubun2023-03-061-2/+2
|
* Remove obsoleted MJIT_HEADER macroTakashi Kokubun2023-03-061-14/+0
|
* Remove obsoleted MJIT_STATIC macroTakashi Kokubun2023-03-061-1/+1
|
* Stop exporting symbols for MJITTakashi Kokubun2023-03-061-18/+9
|
* Prepare for compiling an ISEQTakashi Kokubun2023-03-051-26/+0
|
* Prepare rb_mjit_compile hookTakashi Kokubun2023-03-051-3/+8
|
* Encapsulate RCLASS_ATTACHED_OBJECTJean Boussier2023-02-151-1/+2
| | | | | | | | | 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.
* use correct svar even if env is escapedKoichi Sasada2023-02-101-17/+39
| | | | | | | | 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.
* Merge gc.h and internal/gc.hMatt Valentine-House2023-02-091-1/+1
| | | | [Feature #19425]
* Remove unneeded repetitionsTakashi Kokubun2023-02-041-1/+1
|
* use correct svar (#7225)Koichi Sasada2023-02-011-5/+18
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | * use correct svar Without this patch, svar location is used "nearest Ruby frame". It is almost correct but it doesn't correct when the `each` method is written in Ruby. ```ruby class C include Enumerable def each %w(bar baz).each{|e| yield e} end end C.new.grep(/(b.)/){|e| p [$1, e]} ``` This patch fix this issue by traversing ifunc's cfp. Note that if cfp doesn't specify this Thread's cfp stack, reserved svar location (`ec->root_svar`) is used. * make yjit-bindgen --------- Co-authored-by: Takashi Kokubun <takashikkbn@gmail.com>
* Fix off-by-one error in rb_vm_each_stack_valuePeter Zhu2023-01-091-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Applying the following patch to test/erb/test_erb.rb and running that file will cause Ruby to crash on my machine (macOS 13.1 on M1 Pro): ``` --- a/test/erb/test_erb.rb +++ b/test/erb/test_erb.rb @@ -7,6 +7,12 @@ class TestERB < Test::Unit::TestCase class MyError < RuntimeError ; end + def setup + GC.auto_compact = true + GC.stress = true + GC.verify_compaction_references(expand_heap: true, toward: :empty) + end + ``` It crashes with the following log: ``` /Users/peter/src/ruby/lib/erb/compiler.rb:276: [BUG] Segmentation fault at 0x00000001083a8690 ... -- C level backtrace information ------------------------------------------- ... /Users/peter/src/ruby/build/ruby(rb_vm_each_stack_value+0xa8) [0x104cc3a44] ../vm.c:2737 /Users/peter/src/ruby/build/ruby(rb_vm_each_stack_value+0xa8) [0x104cc3a44] ../vm.c:2737 /Users/peter/src/ruby/build/ruby(check_stack_for_moved+0x2c) [0x104b272a4] ../gc.c:5512 /Users/peter/src/ruby/build/ruby(gc_compact_finish) ../gc.c:5534 /Users/peter/src/ruby/build/ruby(gc_sweep_compact) ../gc.c:8653 /Users/peter/src/ruby/build/ruby(gc_sweep) ../gc.c:6196 /Users/peter/src/ruby/build/ruby(has_sweeping_pages+0x0) [0x104b19c54] ../gc.c:9568 /Users/peter/src/ruby/build/ruby(gc_rest) ../gc.c:9570 ``` This crash happens because it's reading the VALUE at sp. But since sp points to the top of the stack, it's reading the VALUE above the top of the stack, which is causing this segfault. Fixes [Bug #19320]
* MJIT: Cancel all on disastrous situations (#7019)Takashi Kokubun2022-12-241-0/+1
| | | | | | | | | | I noticed this while running test_yjit with --mjit-call-threshold=1, which redefines `Integer#<`. When Ruby is monkey-patched, MJIT itself could be broken. Similarly, Ruby scripts could break MJIT in many different ways. I prepared the same set of hooks as YJIT so that we could possibly override it and disable it on those moments. Every constant under RubyVM::MJIT is private and thus it's an unsupported behavior though.
* Use a BOP for Hash#defaultJohn Hawthorn2022-12-171-0/+1
| | | | | | | | | | | | | | | | | | | | On a hash miss we need to call default if it is redefined in order to return the default value to be used. Previously we checked this with rb_method_basic_definition_p, which avoids the method call but requires a method lookup. This commit replaces the previous check with BASIC_OP_UNREDEFINED_P and a new BOP_DEFAULT. We still need to fall back to rb_method_basic_definition_p when called on a subclasss of hash. | |compare-ruby|built-ruby| |:---------------|-----------:|---------:| |hash_aref_miss | 2.692| 3.531| | | -| 1.31x| Co-authored-by: Daniel Colson <danieljamescolson@gmail.com> Co-authored-by: "Ian C. Anderson" <ian@iancanderson.com> Co-authored-by: Jack McCracken <me@jackmc.xyz>
* MJIT: Give a more appropriate name to the initial stateTakashi Kokubun2022-12-081-4/+4
|
* Add debug counters to RubyVM.stat (#6086)Chris Seaton2022-12-071-0/+19
| | | | | | | | | * Add debug counters to RubyVM.stat * Use SIZET2NUM Co-author: Nobuyoshi Nakada <nobu@ruby-lang.org> * Prefix debug_counter_names
* MJIT: Refactor the jit_func enum for MJITTakashi Kokubun2022-12-061-8/+7
| | | | | | All values should have a MJIT_ prefix. We could address the warning for the end mark if we just define the macro for the check next to the enum. It even simplifies some code for checking the enum.
* Introduce BOP_CMP for optimized comparisonDaniel Colson2022-12-061-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Prior to this commit the `OPTIMIZED_CMP` macro relied on a method lookup to determine whether `<=>` was overridden. The result of the lookup was cached, but only for the duration of the specific method that initialized the cmp_opt_data cache structure. With this method lookup, `[x,y].max` is slower than doing `x > y ? x : y` even though there's an optimized instruction for "new array max". (John noticed somebody a proposed micro-optimization based on this fact in https://github.com/mastodon/mastodon/pull/19903.) ```rb a, b = 1, 2 Benchmark.ips do |bm| bm.report('conditional') { a > b ? a : b } bm.report('method') { [a, b].max } bm.compare! end ``` Before: ``` Comparison: conditional: 22603733.2 i/s method: 19820412.7 i/s - 1.14x (± 0.00) slower ``` This commit replaces the method lookup with a new CMP basic op, which gives the examples above equivalent performance. After: ``` Comparison: method: 24022466.5 i/s conditional: 23851094.2 i/s - same-ish: difference falls within error ``` Relevant benchmarks show an improvement to Array#max and Array#min when not using the optimized newarray_max instruction as well. They are noticeably faster for small arrays with the relevant types, and the same or maybe a touch faster on larger arrays. ``` $ make benchmark COMPARE_RUBY=<master@5958c305> ITEM=array_min $ make benchmark COMPARE_RUBY=<master@5958c305> ITEM=array_max ``` The benchmarks added in this commit also look generally improved. Co-authored-by: John Hawthorn <jhawthorn@github.com>
* Move BOP macros to separate fileDaniel Colson2022-12-061-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit moves ruby_basic_operators and the unredefined macros out of vm_core.h and into basic_operators.h so that we can use them more broadly in places where we currently use a method look up via `rb_method_basic_definition_p` (e.g. object.c, numeric.c, complex.c, enum.c, but also in internal/compar.h after introducing BOP_CMP and elsewhere if we introduce more BOPs) The most controversial part of this change is probably moving redefined_flag out of rb_vm_t. [vm_opt_method_def_table and vm_opt_mid_table](https://github.com/ruby/ruby/blob/9da2a5204f32a4f2ce135fddde2abb6e07d647e9/vm.c) are not part of rb_vm_t either, and I think this fits well with those. But more significantly it seems to result in one fewer instruction. For example: Before: ``` (lldb) disassemble -n vm_opt_str_freeze miniruby`vm_exec_core: miniruby[0x10028233e] <+14558>: movq 0x11a86b(%rip), %rax ; ruby_current_vm_ptr miniruby[0x100282345] <+14565>: testb $0x4, 0x242c(%rax) ``` After: ``` (lldb) disassemble -n vm_opt_str_freeze ruby`vm_exec_core: ruby[0x100280ebe] <+14510>: testb $0x4, 0x120147(%rip) ; ruby_vm_redefined_flag + 43 ``` Co-authored-by: John Hawthorn <jhawthorn@github.com>
* Introduce `Fiber#storage` for inheritable fiber-scoped variables. (#6612)Samuel Williams2022-12-011-1/+7
|
* Fix autoload status of statically linked extensionsAlan Wu2022-11-251-0/+3
| | | | | | | | | | | | | | | | | | Previously, for statically-linked extensions, we used `vm->loading_table` to delay calling the init function until the extensions are required. This caused the extensions to look like they are in the middle of being loaded even before they're required. (`rb_feature_p()` returned true with a loading path output.) Combined with autoload, queries like `defined?(CONST)` and `Module#autoload?` were confused by this and returned nil incorrectly. RubyGems uses `defined?` to detect if OpenSSL is available and failed when OpenSSL was available in builds using `--with-static-linked-ext`. Use a dedicated table for the init functions instead of adding them to the loading table. This lets us remove some logic from non-EXTSTATIC builds. [Bug #19115]
* Add next_shape_id to vm statsAaron Patterson2022-11-231-1/+3
| | | | | | We need to track this number in CI. It's important to know how changes to the codebase impact the number of shapes in the system, so lets add the number to the VM stat hash
* Using UNDEF_P macroS-H-GAMELINKS2022-11-161-6/+6
|
* Rename --mjit-min-calls to --mjit-call-threshold (#6731)Takashi Kokubun2022-11-141-1/+1
| | | for consistency with YJIT
* Reduce the number of branches in jit_exec (#6722)Takashi Kokubun2022-11-131-30/+23
| | | | | | | * Reduce the number of branches in jit_exec * Address build failure in some configurations * Refactor yjit.h
* s/mjit_func_t/jit_func_t/Takashi Kokubun2022-11-131-1/+1
|
* Remove unused debug countersTakashi Kokubun2022-11-131-21/+1
| | | | | | The structure and readability of jit_exec is messed up right now. I'd like to help the current situation by this for now. I'll resurrect them when I need it again.
* Transition shape when object's capacity changesJemma Issroff2022-11-101-11/+0
| | | | | | | | | | | | | | | | This commit adds a `capacity` field to shapes, and adds shape transitions whenever an object's capacity changes. Objects which are allocated out of a bigger size pool will also make a transition from the root shape to the shape with the correct capacity for their size pool when they are allocated. This commit will allow us to remove numiv from objects completely, and will also mean we can guarantee that if two objects share shapes, their IVs are in the same positions (an embedded and extended object cannot share shapes). This will enable us to implement ivar sets in YJIT using object shapes. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
* 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>