summaryrefslogtreecommitdiff
path: root/variable.c
Commit message (Collapse)AuthorAgeFilesLines
* Remove autoload for constant if the autoload failsJeremy Evans2021-10-081-16/+22
| | | | | | | | | | | | | Previously, if an autoload failed (the file was loaded, but the constant was not defined by the autoloaded file). Ruby will try to autoload again if you delete the autoloaded file from $LOADED_FEATURES. With this change, the autoload and the constant itself are removed as soon as it fails. To handle cases where multiple threads are autoloading, when deleting an autoload, handle the case where another thread already deleted it. Fixes [Bug #15790]
* Merge if statementS-H-GAMELINKS2021-10-071-4/+1
|
* Return fstrings from `build_const_pathname`.Samuel Williams2021-09-251-2/+1
| | | | | | It's possible for `build_const_pathname` to be called when `rb_cString` is still NULL. There is a fix-up step when `rb_cString` is initialized, but it only applies to `fstring` instances.
* Refactor and Using RBOOL macroS.H2021-09-151-6/+2
|
* Use Module#ancestors order in recursive constant lookupAlan Wu2021-06-301-5/+19
| | | | | | | | | | | | | | | | | | | | | Before this commit, const_get with inherit=true and constant lookup expressions searched the ancestors of the starting point in an order different from `starting_point.ancestors`. Items in the ancestry list introduced through prepend were searched after searching the module they were prepended into. This oddity allowed for situations where constant lookups gave different results even though `starting_point.ancestors` is the same. Do the lookup in the same order as `starting_point.ancestors` by skipping classes and modules that have an origin iclass. The origin iclass is in the super chain after the prepended modules. Note that just like before this commit, the starting point of the constant lookup is always the first item that we search, regardless of the presence of any prepended modules. [Bug #17887]
* Get rid of pointer castingNobuyoshi Nakada2021-06-231-29/+34
|
* Refactor class variable cache functionsNobuyoshi Nakada2021-06-231-2/+5
| | | | | | | Extracted repeated code as update_classvariable_cache. When cvc table is not set in getclassvariable, an empty table was created but it has no id and would cause [BUG], so made the code same as setclassvariable.
* Add a cache for class variableseileencodes2021-06-181-8/+84
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Redo of 34a2acdac788602c14bf05fb616215187badd504 and 931138b00696419945dc03e10f033b1f53cd50f3 which were reverted. GitHub PR #4340. This change implements a cache for class variables. Previously there was no cache for cvars. Cvar access is slow due to needing to travel all the way up th ancestor tree before returning the cvar value. The deeper the ancestor tree the slower cvar access will be. The benefits of the cache are more visible with a higher number of included modules due to the way Ruby looks up class variables. The benchmark here includes 26 modules and shows with the cache, this branch is 6.5x faster when accessing class variables. ``` compare-ruby: ruby 3.1.0dev (2021-03-15T06:22:34Z master 9e5105c) [x86_64-darwin19] built-ruby: ruby 3.1.0dev (2021-03-15T12:12:44Z add-cache-for-clas.. c6be009) [x86_64-darwin19] | |compare-ruby|built-ruby| |:--------|-----------:|---------:| |vm_cvar | 5.681M| 36.980M| | | -| 6.51x| ``` Benchmark.ips calling `ActiveRecord::Base.logger` from within a Rails application. ActiveRecord::Base.logger has 71 ancestors. The more ancestors a tree has, the more clear the speed increase. IE if Base had only one ancestor we'd see no improvement. This benchmark is run on a vanilla Rails application. Benchmark code: ```ruby require "benchmark/ips" require_relative "config/environment" Benchmark.ips do |x| x.report "logger" do ActiveRecord::Base.logger end end ``` Ruby 3.0 master / Rails 6.1: ``` Warming up -------------------------------------- logger 155.251k i/100ms Calculating ------------------------------------- ``` Ruby 3.0 with cvar cache / Rails 6.1: ``` Warming up -------------------------------------- logger 1.546M i/100ms Calculating ------------------------------------- logger 14.857M (± 4.8%) i/s - 74.198M in 5.006202s ``` Lastly we ran a benchmark to demonstate the difference between master and our cache when the number of modules increases. This benchmark measures 1 ancestor, 30 ancestors, and 100 ancestors. Ruby 3.0 master: ``` Warming up -------------------------------------- 1 module 1.231M i/100ms 30 modules 432.020k i/100ms 100 modules 145.399k i/100ms Calculating ------------------------------------- 1 module 12.210M (± 2.1%) i/s - 61.553M in 5.043400s 30 modules 4.354M (± 2.7%) i/s - 22.033M in 5.063839s 100 modules 1.434M (± 2.9%) i/s - 7.270M in 5.072531s Comparison: 1 module: 12209958.3 i/s 30 modules: 4354217.8 i/s - 2.80x (± 0.00) slower 100 modules: 1434447.3 i/s - 8.51x (± 0.00) slower ``` Ruby 3.0 with cvar cache: ``` Warming up -------------------------------------- 1 module 1.641M i/100ms 30 modules 1.655M i/100ms 100 modules 1.620M i/100ms Calculating ------------------------------------- 1 module 16.279M (± 3.8%) i/s - 82.038M in 5.046923s 30 modules 15.891M (± 3.9%) i/s - 79.459M in 5.007958s 100 modules 16.087M (± 3.6%) i/s - 81.005M in 5.041931s Comparison: 1 module: 16279458.0 i/s 100 modules: 16087484.6 i/s - same-ish: difference falls within error 30 modules: 15891406.2 i/s - same-ish: difference falls within error ``` Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Adjust styles [ci skip]Nobuyoshi Nakada2021-06-171-1/+2
| | | | | | | | | * --braces-after-func-def-line * --dont-cuddle-else * --procnames-start-lines * --space-after-for * --space-after-if * --space-after-while
* Refactor rb_class_path_cached function (#4485)S.H2021-06-011-2/+1
|
* Refactor rb_define_class_variable function (#4492)S.H2021-06-011-2/+1
|
* Revert "Filling cache values on cvar write"Aaron Patterson2021-05-111-84/+8
| | | | | This reverts commit 08de37f9fa3469365e6b5c964689ae2bae0eb9f3. This reverts commit e8ae922b62adb00a80d3d4c49f7d7b0e6026eaba.
* Filling cache values on cvar writeeileencodes2021-05-111-0/+19
| | | | | | Instead of on read. Once it's in the inline cache we never have to make one again. We want to eventually put the value into the cache, and the best opportunity to do that is when you write the value.
* Add a cache for class variableseileencodes2021-05-111-8/+65
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This change implements a cache for class variables. Previously there was no cache for cvars. Cvar access is slow due to needing to travel all the way up th ancestor tree before returning the cvar value. The deeper the ancestor tree the slower cvar access will be. The benefits of the cache are more visible with a higher number of included modules due to the way Ruby looks up class variables. The benchmark here includes 26 modules and shows with the cache, this branch is 6.5x faster when accessing class variables. ``` compare-ruby: ruby 3.1.0dev (2021-03-15T06:22:34Z master 9e5105ca45) [x86_64-darwin19] built-ruby: ruby 3.1.0dev (2021-03-15T12:12:44Z add-cache-for-clas.. c6be0093ae) [x86_64-darwin19] | |compare-ruby|built-ruby| |:--------|-----------:|---------:| |vm_cvar | 5.681M| 36.980M| | | -| 6.51x| ``` Benchmark.ips calling `ActiveRecord::Base.logger` from within a Rails application. ActiveRecord::Base.logger has 71 ancestors. The more ancestors a tree has, the more clear the speed increase. IE if Base had only one ancestor we'd see no improvement. This benchmark is run on a vanilla Rails application. Benchmark code: ```ruby require "benchmark/ips" require_relative "config/environment" Benchmark.ips do |x| x.report "logger" do ActiveRecord::Base.logger end end ``` Ruby 3.0 master / Rails 6.1: ``` Warming up -------------------------------------- logger 155.251k i/100ms Calculating ------------------------------------- ``` Ruby 3.0 with cvar cache / Rails 6.1: ``` Warming up -------------------------------------- logger 1.546M i/100ms Calculating ------------------------------------- logger 14.857M (± 4.8%) i/s - 74.198M in 5.006202s ``` Lastly we ran a benchmark to demonstate the difference between master and our cache when the number of modules increases. This benchmark measures 1 ancestor, 30 ancestors, and 100 ancestors. Ruby 3.0 master: ``` Warming up -------------------------------------- 1 module 1.231M i/100ms 30 modules 432.020k i/100ms 100 modules 145.399k i/100ms Calculating ------------------------------------- 1 module 12.210M (± 2.1%) i/s - 61.553M in 5.043400s 30 modules 4.354M (± 2.7%) i/s - 22.033M in 5.063839s 100 modules 1.434M (± 2.9%) i/s - 7.270M in 5.072531s Comparison: 1 module: 12209958.3 i/s 30 modules: 4354217.8 i/s - 2.80x (± 0.00) slower 100 modules: 1434447.3 i/s - 8.51x (± 0.00) slower ``` Ruby 3.0 with cvar cache: ``` Warming up -------------------------------------- 1 module 1.641M i/100ms 30 modules 1.655M i/100ms 100 modules 1.620M i/100ms Calculating ------------------------------------- 1 module 16.279M (± 3.8%) i/s - 82.038M in 5.046923s 30 modules 15.891M (± 3.9%) i/s - 79.459M in 5.007958s 100 modules 16.087M (± 3.6%) i/s - 81.005M in 5.041931s Comparison: 1 module: 16279458.0 i/s 100 modules: 16087484.6 i/s - same-ish: difference falls within error 30 modules: 15891406.2 i/s - same-ish: difference falls within error ``` Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Refactor `rb_class_ivar_set`eileencodes2021-03-101-7/+4
| | | | | | In every caller of `rb_class_ivar_set` it checks for the `RCLASS_IV_TBL` and then creates it if it doesn't exist. Instead of repeating this in every caller, this can be done once in `rb_class_ivar_set`.
* Revert "Don't pin `val` passed in to `rb_define_const`."Aaron Patterson2021-02-031-0/+1
| | | | | | I think this is breaking something This reverts commit 1be84e53d76cff30ae371f0b397336dee934499d.
* Don't pin `val` passed in to `rb_define_const`.Aaron Patterson2021-02-031-1/+0
| | | | | The caller should be responsible for holding a pinned reference (if they need that)
* Skip freezing check on setting temporary class path [Bug #17563]Nobuyoshi Nakada2021-01-201-1/+1
| | | | Co-authored-by: ryannevell (Ryan Nevell) <ryan.nevell@gmail.com>
* Replace "iff" with "if and only if"Gannon McGibbon2021-01-191-1/+1
| | | | | | | iff means if and only if, but readers without that knowledge might assume this to be a spelling mistake. To me, this seems like exclusionary language that is unnecessary. Simply using "if and only if" instead should suffice.
* Introduce Ractor::IsolationErrorKoichi Sasada2020-12-211-9/+8
| | | | | | | | | | | Ractor has several restrictions to keep each ractor being isolated and some operation such as `CONST="foo"` in non-main ractor raises an exception. This kind of operation raises an error but there is confusion (some code raises RuntimeError and some code raises NameError). To make clear we introduce Ractor::IsolationError which is raised when the isolation between ractors is violated.
* sync RCLASS_CONST_TBL()Koichi Sasada2020-12-201-29/+62
| | | | | RCLASS_CONST_TBL() is shared resource so we need to sync with other ractors.
* Use category: :deprecated in warnings that are related to deprecationJeremy Evans2020-12-181-2/+2
| | | | | | | | | | | | | | | | | Also document that both :deprecated and :experimental are supported :category option values. The locations where warnings were marked as deprecation warnings was previously reviewed by shyouhei. Comment a couple locations where deprecation warnings should probably be used but are not currently used because deprecation warning enablement has not occurred at the time they are called (RUBY_FREE_MIN, RUBY_HEAP_MIN_SLOTS, -K). Add assert_deprecated_warn to test assertions. Use this to simplify some tests, and fix failing tests after marking some warnings with deprecated category.
* tuning ivar setKoichi Sasada2020-12-161-3/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * make rb_init_iv_list() simple * introduce vm_setivar_slowpath() for cache miss cases ../clean/miniruby is 647ee6f091. Calculating ------------------------------------- ./miniruby ../clean/miniruby ../ruby_2_7/miniruby vm_ivar_init 7.388M 6.814M 5.771M i/s - 30.000M times in 4.060420s 4.402534s 5.198781s vm_ivar_init_subclass 2.158M 2.147M 1.974M i/s - 3.000M times in 1.390328s 1.397587s 1.519951s vm_ivar_set 128.607M 97.931M 140.668M i/s - 30.000M times in 0.233269s 0.306338s 0.213268s vm_ivar 144.315M 151.722M 117.734M i/s - 30.000M times in 0.207879s 0.197730s 0.254811s Comparison: vm_ivar_init ./miniruby: 7388398.8 i/s ../clean/miniruby: 6814257.1 i/s - 1.08x slower ../ruby_2_7/miniruby: 5770583.9 i/s - 1.28x slower vm_ivar_init_subclass ./miniruby: 2157763.6 i/s ../clean/miniruby: 2146557.0 i/s - 1.01x slower ../ruby_2_7/miniruby: 1973747.9 i/s - 1.09x slower vm_ivar_set ../ruby_2_7/miniruby: 140668063.8 i/s ./miniruby: 128606912.1 i/s - 1.09x slower ../clean/miniruby: 97931027.8 i/s - 1.44x slower vm_ivar ../clean/miniruby: 151722121.9 i/s ./miniruby: 144314526.5 i/s - 1.05x slower ../ruby_2_7/miniruby: 117734305.5 i/s - 1.29x slower
* fix ivar with shareable objects issueKoichi Sasada2020-12-121-0/+17
| | | | | Instance variables of sharable objects are accessible only from main ractor, so we need to check it correctly.
* Remove the uninitialized instance variable verbose mode warningJeremy Evans2020-12-101-9/+1
| | | | | | | | | This speeds up all instance variable access, even when not in verbose mode. Uninitialized instance variable warnings were rarely helpful, and resulted in slower code if you wanted to avoid warnings when run in verbose mode. Implements [Feature #17055]
* fix public interfaceKoichi Sasada2020-11-181-1/+1
| | | | | | | | | | | | | | | | | | To make some kind of Ractor related extensions, some functions should be exposed. * include/ruby/thread_native.h * rb_native_mutex_* * rb_native_cond_* * include/ruby/ractor.h * RB_OBJ_SHAREABLE_P(obj) * rb_ractor_shareable_p(obj) * rb_ractor_std*() * rb_cRactor and rm ractor_pub.h and rename srcdir/ractor.h to srcdir/ractor_core.h (to avoid conflict with include/ruby/ractor.h)
* refactoring.Koichi Sasada2020-11-101-5/+5
| | | | | iv_index_tbl_newsize() usually returns iv_index_tbl->num_entries because ivup->iv_extended is usually false.
* eagerly initialize ivar table when index is small enoughAaron Patterson2020-11-091-18/+23
| | | | | | | | | | | | | When the inline cache is written, the iv table will contain an entry for the instance variable. If we get an inline cache hit, then we know the iv table must contain a value for the index written to the inline cache. If the index in the inline cache is larger than the list on the object, but *smaller* than the iv index table on the class, then we can just eagerly allocate the iv list to be the same size as the iv index table. This avoids duplicate work of checking frozen as well as looking up the index for the particular instance variable name.
* Simplify setting instance variablesAaron Patterson2020-11-041-24/+15
| | | | | | | | | Since T_OBJECT objects come to life as embedded objects, that means that ROBJECT_NUMIV will always return a _minimum_ of ROBJECT_EMBED_LEN_MAX. If ivup.index is *greater* than ROBJECT_NUMIV, then we know that the object *must not* be an embedded object. Thus we can skip the ROBJECT_EMBED_LEN_MAX check as well as initializing internals of embedded objects.
* suppport Ractor.send(move: true) for more detaKoichi Sasada2020-11-021-0/+21
| | | | This patch allows to move more data types.
* Fix bootstrap-test error in previous commitJeremy Evans2020-10-251-1/+1
|
* allow to access ivars of frozen shareable objectsKoichi Sasada2020-10-221-1/+2
| | | | | | Accessing a shareable object is prohibitted because it can cause race condition, but if the shareable object is frozen, there is no problem to access ivars.
* check main-ractor or not firstKoichi Sasada2020-10-211-2/+3
| | | | | On non-multi-ractor-mode, the cost of rb_ractor_main_p() is low so check it first.
* sync RClass::ext::iv_index_tblKoichi Sasada2020-10-171-122/+168
| | | | | | | | | | | | iv_index_tbl manages instance variable indexes (ID -> index). This data structure should be synchronized with other ractors so introduce some VM locks. This patch also introduced atomic ivar cache used by set/getinlinecache instructions. To make updating ivar cache (IVC), we changed iv_index_tbl data structure to manage (ID -> entry) and an entry points serial and index. IVC points to this entry so that cache update becomes atomically.
* sync generic_ivtblKoichi Sasada2020-10-141-14/+32
| | | | | | | | | generic_ivtbl is a process global table to maintain instance variables for non T_OBJECT/T_CLASS/... objects. So we need to protect them for multi-Ractor exection. Hint: we can make them Ractor local for unshareable objects, but now it is premature optimization.
* Introduce Ractor mechanism for parallel executionKoichi Sasada2020-09-031-43/+112
| | | | | | | | | | | | | | | | This commit introduces Ractor mechanism to run Ruby program in parallel. See doc/ractor.md for more details about Ractor. See ticket [Feature #17100] to see the implementation details and discussions. [Feature #17100] This commit does not complete the implementation. You can find many bugs on using Ractor. Also the specification will be changed so that this feature is experimental. You will see a warning when you make the first Ractor with `Ractor.new`. I hope this feature can help programmers from thread-safety issues.
* Don't call to_s in const_setAlan Wu2020-09-031-1/+2
| | | | | | | Follow up for 5e16857315bf55307c5fc887ca6f03bfa0630a93. Calling a method in the middle of const_set adds a way that it would fail. It also makes it inconsistent with declaring a constant using `::`, which doesn't call `to_s`.
* Fix constant names set using const_set on a singleton classMarc-Andre Lafortune2020-09-021-8/+9
| | | | Fixes [Bug #14895]
* ROBJECT_IV_INDEX_TBL: convert into an inline function卜部昌平2020-08-191-0/+1
| | | | | | | Former ROBJECT_IV_INDEX_TBL macro included RCLASS_IV_INDEX_TBL, which is not disclosed to extension libraies. The macro was kind of broken. Why not just deprecate it, and convert the internal use into an inline function.
* Ensure the shortcut cached in the classNobuyoshi Nakada2020-08-171-2/+2
| | | | | | As well as the other places using RCLASS_IV_INDEX_TBL. `IO#reopen` seems the only case that the class of an object can be changed.
* Improve docs for Module#remove_class_variable [ci skip]Alan Wu2020-08-021-5/+4
|
* Remove trailing spaces [ci skip]Nobuyoshi Nakada2020-07-201-1/+1
|
* Use ID instead of GENTRY for gvars. (#3278)Koichi Sasada2020-07-031-33/+48
| | | | | | | | | | | | Use ID instead of GENTRY for gvars. Global variables are compiled into GENTRY (a pointer to struct rb_global_entry). This patch replace this GENTRY to ID and make the code simple. We need to search GENTRY from ID every time (st_lookup), so additional overhead will be introduced. However, the performance of accessing global variables is not important now a day and this simplicity helps Ractor development.
* add UNREACHABLE_RETURN卜部昌平2020-06-291-0/+2
| | | | | | Not every compilers understand that rb_raise does not return. When a function does not end with a return statement, such compilers can issue warnings. We would better tell them about reachabilities.
* rb_mod_remove_cvar: do not goto into a branch卜部昌平2020-06-291-4/+4
| | | | | I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
* rb_copy_generic_ivar: do not goto into a branch卜部昌平2020-06-291-6/+8
| | | | | I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
* generic_ivar_update: do not goto into a branch卜部昌平2020-06-291-17/+10
| | | | | I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
* rb_path_to_class: do not goto into a branch卜部昌平2020-06-291-3/+5
| | | | | I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
* Raise RuntimeError for class variable overtaken in nonverbose modeJeremy Evans2020-06-181-1/+1
| | | | | | | | | | | | | | | | | | 900e83b50115afda3f79712310e4cb95e4508972 changed from a warning to an error in this case, but the warning was only issued in verbose mode, and therefore the error was only raised in verbose mode. That was not intentional, verbose mode should only change whether warnings are emitted, not other behavior. This issues the RuntimeError in all cases. This change broke a couple tests, as the tests actually issued the warning and therefore now raise an error. This wasn't caught earlier as test_variable suppressed the warning in this case, effectively setting $VERBOSE = false around the code that warned. basictest isn't run in verbose mode and therefore didn't expose the issue previously. Fix these tests. Fixes [Bug #14541]
* Prohibit setting class variable on frozen module through inheritanceAlan Wu2020-06-111-0/+3
| | | | | | | | Setting class varibles goes through the ancestor list which can contain iclasses. Iclasses share a lot of information with the module they are made from, but not the frozen status. Check the frozen status of the module instead of the iclass.