summaryrefslogtreecommitdiff
path: root/class.c
Commit message (Collapse)AuthorAgeFilesLines
* Use the flag for uninitialized module [Bug #18185]Nobuyoshi Nakada2021-09-241-6/+9
| | | | Make `Module#ancestors` not to include `BasicObject`.
* Consider modified modules initialized [Bug #18185]Nobuyoshi Nakada2021-09-241-4/+10
|
* Allow to include uninitialized modules [Bug #18177]Nobuyoshi Nakada2021-09-201-1/+2
| | | | The module that is about to be included is considered initialized.
* Fix a typo [Bug #17048]Nobuyoshi Nakada2021-09-191-2/+2
|
* Already initialized modules cannot be replaced [Bug #17048]Nobuyoshi Nakada2021-09-171-1/+42
|
* include/ruby/internal/intern/class.h: add doxygen卜部昌平2021-09-101-67/+0
| | | | Must not be a bad idea to improve documents. [ci skip]
* include/ruby/internal/method.h: add doxygen卜部昌平2021-09-101-77/+1
| | | | | | | | Must not be a bad idea to improve documents. [ci skip] In fact many functions declared in the header file are already documented more or less. They were just copy & pasted, with applying some style updates.
* include/ruby/internal/module.h: add doxygen卜部昌平2021-09-101-51/+1
| | | | | | | | Must not be a bad idea to improve documents. [ci skip] In fact many functions declared in the header file are already documented more or less. They were just copy & pasted, with applying some style updates.
* include/ruby/internal/newobj.h: add doxygen卜部昌平2021-09-101-4/+0
| | | | Must not be a bad idea to improve documents. [ci skip]
* Assert not to be UNDEF visibilityNobuyoshi Nakada2021-09-011-0/+1
| | | | | Any defined methods, bound to any classes/modules and not being UNDEFINED_METHOD_ENTRY_P, should not be METHOD_VISI_UNDEF.
* [Feature #18045] Implement size classes for GCPeter Zhu2021-08-251-2/+1
| | | | | | | | | This commits implements size classes in the GC for the Variable Width Allocation feature. Unless `USE_RVARGC` compile flag is set, only a single size class is created, maintaining current behaviour. See the redmine ticket for more details. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Revert "[Feature #18045] Implement size classes for GC"Peter Zhu2021-08-231-1/+2
| | | | | | This reverts commits 48ff7a9f3e47bffb3e4d067a12ba9b936261caa0 and b2e2cf2dedd104acad8610721db5e4d341f135ef because it is causing crashes in SPARC solaris and i386 debian.
* [Feature #18045] Implement size classes for GCPeter Zhu2021-08-231-2/+1
| | | | | | | | | This commits implements size classes in the GC for the Variable Width Allocation feature. Unless `USE_RVARGC` compile flag is set, only a single size class is created, maintaining current behaviour. See the redmine ticket for more details. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Simplify repeated member access macrosNobuyoshi Nakada2021-08-201-14/+14
|
* Module#ancestors should not return superclasses of refinementsShugo Maeda2021-08-201-0/+5
| | | | | | [ruby-core:86949] [Bug #14744] Reported by Eregon (Benoit Daloze). Thanks!
* Remove old warning aged nearly 8 yearsNobuyoshi Nakada2021-08-191-6/+0
|
* Add a cache for class variableseileencodes2021-06-181-0/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Revert "Filling cache values on cvar write"Aaron Patterson2021-05-111-6/+0
| | | | | This reverts commit 08de37f9fa3469365e6b5c964689ae2bae0eb9f3. This reverts commit e8ae922b62adb00a80d3d4c49f7d7b0e6026eaba.
* Filling cache values on cvar writeeileencodes2021-05-111-0/+1
| | | | | | 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-0/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Method cache: fix refinement entry handlingAlan Wu2021-05-111-1/+3
| | | | | | | | | | | | | | | | | | | | To invalidate some callable method entries, we replace the entry in the class. Most types of method entries are on the method table of the origin class, but refinement entries without an orig_me are housed in the method table of the class itself. They are there because refinements take priority over prepended methods. By unconditionally inserting a copy of the refinement entry into the origin class, clearing the method cache created situations where there are refinement entry duplicates in the lookup chain, leading to infinite loops and other problems. Update the replacement logic to use the right class that houses the method entry. Also, be more selective about cache invalidation when moving refinement entries for prepend. This avoids calling clear_method_cache_by_id_in_class() before refinement entries are in the place it expects. [Bug #17806]
* Store rb_classext_t next to RClass slots on the heapMatt Valentine-House2021-05-061-1/+14
|
* Add ins_methods_type_i functionS.H2021-03-211-10/+10
|
* Refactor `rb_class_ivar_set`eileencodes2021-03-101-3/+0
| | | | | | 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`.
* Check for cyclic prepend before making originAlan Wu2021-02-221-21/+35
| | | | | | | | It's important to only make the origin when the prepend goes through, as the precense of the origin informs whether to do an origin backfill. This plus 2d877327e fix [Bug #17590].
* Make a cyclic prepend not modify ancestors for the receiverJeremy Evans2021-02-111-2/+12
| | | | | | Check for cyclic prepend before making any changes. This requires scanning the module ancestor chain twice, but in general modules do not have large numbers of ancestors.
* Add RCLASS_SUBCLASSES MacroMatt Valentine-House2021-02-011-10/+10
|
* Add RCLASS_ALLOCATOR MacroMatt Valentine-House2021-02-011-4/+4
|
* Add PARENT_MODULE_SUBCLASSES MacroMatt Valentine-House2021-02-011-8/+8
|
* Add RCLASS_PARENT_SUBMODULES MacroMatt Valentine-House2021-02-011-8/+8
|
* Add compaction notes for class/module creation C APIsAlan Wu2021-01-261-0/+8
|
* Make rb_define_module_id_under() pin existing modulesAlan Wu2021-01-261-0/+2
| | | | | | Just like rb_define_class_id_under(). Also makes rb_define_module_under() consistent with rb_define_class_under() in the same regard.
* Make Module#prepend affect ancestor chain even if argument already included ↵Jeremy Evans2021-01-141-22/+29
| | | | | | | | | | | | | | | in receiver Previously, if a class included a module and then prepended the same module, the prepend had no effect. This changes the behavior so that the prepend has an effect unless the module is already prepended the receiver. While here, rename the origin_seen variable in include_modules_at, since it is misleading. The variable tracks whether c has been seen, not whether the origin of klass has been. Fixes [Bug #17423]
* reset cache before iteratingKoichi Sasada2020-12-221-4/+17
| | | | | | | | cee02d754d76563635c1db90d2ab6c01f8492470 resets pCMC and `me` will be a invalidated and continuing the invalidated `me`, it will break the data structure. This patch tris to clear all methods of specified class before manipulating the `me`s. [Issue #17417]
* Fixed indefinite articles before "Integer" [ci skip]Nobuyoshi Nakada2020-12-211-1/+1
|
* fix refinements/prepend bugKoichi Sasada2020-12-191-1/+3
| | | | | replaced method entry should be invalidated. [Bug #17386]
* Prefer rb_module_new() over rb_define_module_id()Alan Wu2020-11-251-2/+3
| | | | | rb_define_module_id() doesn't do anything with its parameter so it's a bit confusing.
* Do not allow Module#include to insert modules before the origin in the ↵Jeremy Evans2020-11-201-1/+6
| | | | | | | | | | | | lookup chain Module#include should only be able to insert modules after the origin, otherwise it ends up working like Module#prepend. This fixes the case where one of the modules in the included module chain is included in a module that is already prepended to the receiver. Fixes [Bug #7844]
* Fix singleton class cloningAlan Wu2020-11-161-9/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Before this commit, `clone` gave different results depending on whether the original object had an attached singleton class or not. Consider the following setup: ``` class Foo; end Foo.singleton_class.define_method(:foo) {} obj = Foo.new obj.singleton_class if $call_singleton clone = obj.clone ``` When `$call_singleton = false`, neither `obj.singleton_class.singleton_class` nor `clone.singleton_class.singleton_class` own any methods. However, when `$call_singleton = true`, `clone.singleton_class.singleton_class` would own a copy of `foo` from `Foo.singleton_class`, even though `obj.singleton_class.singleton_class` does not. The latter case is unexpected and results in a visibly different clone, depending on if the original object had an attached class or not. Co-authored-by: Ufuk Kayserilioglu <ufuk.kayserilioglu@shopify.com>
* Use rb_attr_get() for hidden ivarAlan Wu2020-11-131-2/+2
| | | | | rb_ivar_get() can issue an uninitialized ivar warning. We never want to issue warnings about hidden ivars as they are not actionable for users.
* Improve error message when subclassing non-ClassJeremy Evans2020-11-131-1/+1
| | | | Fixes [Bug #14726]
* Fix excessive GC rootingAlan Wu2020-11-091-2/+0
| | | | | rb_vm_add_root_module() is enough to make sure the object become a GC root.
* rb_vm_add_root_module(): Remove unused parameterAlan Wu2020-11-091-7/+7
|
* include/ruby/backward/2/rmodule.h: deprecate卜部昌平2020-08-271-3/+3
| | | | | Only one function in only one file uses contents of this public header. That is not a wise idea. Let's just free the header's soul.
* Remove write barrier exemption for T_ICLASSAlan Wu2020-08-171-6/+3
| | | | | | | | | | | | | | | | | | | Before this commit, iclasses were "shady", or not protected by write barriers. Because of that, the GC needs to spend more time marking these objects than otherwise. Applications that make heavy use of modules should see reduction in GC time as they have a significant number of live iclasses on the heap. - Put logic for iclass method table ownership into a function - Remove calls to WB_UNPROTECT and insert write barriers for iclasses This commit relies on the following invariant: for any non oirigin iclass `I`, `RCLASS_M_TBL(I) == RCLASS_M_TBL(RBasic(I)->klass)`. This invariant did not hold prior to 98286e9 for classes and modules that have prepended modules. [Feature #16984]
* Set cloned flag after checked if copiableNobuyoshi Nakada2020-07-301-4/+5
|
* Lazily insert origins on prepend to save memoryAlan Wu2020-07-221-6/+20
| | | | | | | | | | | | | | | | 98286e9850936e27e8ae5e4f20858cc9c13d2dde made it so that `Module#include` allocates an origin iclass on each use. Since `include` is widely used, the extra allocation can contribute significantly to memory usage. Instead of always allocating in anticipation of prepend, this change takes a different approach. The new setup inserts a origin iclass into the super chains of all the children of the module when prepend happens for the first time. rb_ensure_origin is made static again since now that adding an origin now means walking over all usages, we want to limit the number of places where we do it.
* singleton_class_of: do not goto into a branch卜部昌平2020-06-291-15/+14
| | | | | I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
* SPECIAL_SINGLETON: no longer used卜部昌平2020-06-291-10/+6
| | | | This macro does not improve any readability and/or runtime performance.
* Make Module#prepend affect the iclasses of the moduleJeremy Evans2020-06-181-0/+7
| | | | | | | | | | | | 3556a834a2847e52162d1d3302d4c64390df1694 added support for Module#include to affect the iclasses of the module. It didn't add support for Module#prepend because there were bugs in the object model and GC at the time that prevented it. Those problems have been addressed in ad729a1d11c6c57efd2e92803b4e937db0f75252 and 98286e9850936e27e8ae5e4f20858cc9c13d2dde, and now adding support for it is straightforward and does not break any tests or specs. Fixes [Bug #9573]