summaryrefslogtreecommitdiff
path: root/class.c
AgeCommit message (Collapse)Author
2021-03-10Refactor `rb_class_ivar_set`eileencodes
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`. Notes: Merged: https://github.com/ruby/ruby/pull/4254
2021-02-22Check for cyclic prepend before making originAlan Wu
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]. Notes: Merged: https://github.com/ruby/ruby/pull/4181
2021-02-11Make a cyclic prepend not modify ancestors for the receiverJeremy Evans
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. Notes: Merged: https://github.com/ruby/ruby/pull/4165
2021-02-01Add RCLASS_SUBCLASSES MacroMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/4124
2021-02-01Add RCLASS_ALLOCATOR MacroMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/4124
2021-02-01Add PARENT_MODULE_SUBCLASSES MacroMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/4124
2021-02-01Add RCLASS_PARENT_SUBMODULES MacroMatt Valentine-House
Notes: Merged: https://github.com/ruby/ruby/pull/4124
2021-01-26Add compaction notes for class/module creation C APIsAlan Wu
Notes: Merged: https://github.com/ruby/ruby/pull/3885
2021-01-26Make rb_define_module_id_under() pin existing modulesAlan Wu
Just like rb_define_class_id_under(). Also makes rb_define_module_under() consistent with rb_define_class_under() in the same regard. Notes: Merged: https://github.com/ruby/ruby/pull/3885
2021-01-14Make Module#prepend affect ancestor chain even if argument already included ↵Jeremy Evans
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] Notes: Merged: https://github.com/ruby/ruby/pull/4072
2020-12-22reset cache before iteratingKoichi Sasada
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] Notes: Merged: https://github.com/ruby/ruby/pull/3964
2020-12-21Fixed indefinite articles before "Integer" [ci skip]Nobuyoshi Nakada
2020-12-19fix refinements/prepend bugKoichi Sasada
replaced method entry should be invalidated. [Bug #17386]
2020-11-25Prefer rb_module_new() over rb_define_module_id()Alan Wu
rb_define_module_id() doesn't do anything with its parameter so it's a bit confusing.
2020-11-20Do not allow Module#include to insert modules before the origin in the ↵Jeremy Evans
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] Notes: Merged: https://github.com/ruby/ruby/pull/3796
2020-11-16Fix singleton class cloningAlan Wu
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> Notes: Merged: https://github.com/ruby/ruby/pull/3761
2020-11-13Use rb_attr_get() for hidden ivarAlan Wu
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. Notes: Merged: https://github.com/ruby/ruby/pull/3763
2020-11-13Improve error message when subclassing non-ClassJeremy Evans
Fixes [Bug #14726] Notes: Merged: https://github.com/ruby/ruby/pull/3330
2020-11-09Fix excessive GC rootingAlan Wu
rb_vm_add_root_module() is enough to make sure the object become a GC root. Notes: Merged: https://github.com/ruby/ruby/pull/3741
2020-11-09rb_vm_add_root_module(): Remove unused parameterAlan Wu
Notes: Merged: https://github.com/ruby/ruby/pull/3741
2020-08-27include/ruby/backward/2/rmodule.h: deprecate卜部昌平
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. Notes: Merged: https://github.com/ruby/ruby/pull/3347
2020-08-17Remove write barrier exemption for T_ICLASSAlan Wu
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] Notes: Merged: https://github.com/ruby/ruby/pull/3410
2020-07-30Set cloned flag after checked if copiableNobuyoshi Nakada
2020-07-22Lazily insert origins on prepend to save memoryAlan Wu
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. Notes: Merged: https://github.com/ruby/ruby/pull/3331
2020-06-29singleton_class_of: do not goto into a branch卜部昌平
I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor. Notes: Merged: https://github.com/ruby/ruby/pull/3247
2020-06-29SPECIAL_SINGLETON: no longer used卜部昌平
This macro does not improve any readability and/or runtime performance. Notes: Merged: https://github.com/ruby/ruby/pull/3247
2020-06-18Make Module#prepend affect the iclasses of the moduleJeremy Evans
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] Notes: Merged: https://github.com/ruby/ruby/pull/3181
2020-06-16Assert iclass property and remove dead codeAlan Wu
Iclass objects are never made from other iclass objects. Notes: Merged: https://github.com/ruby/ruby/pull/3218 Merged-By: XrXr
2020-06-03Ensure origins for all included, prepended, and refined modulesJeremy Evans
This fixes various issues when a module is included in or prepended to a module or class, and then refined, or refined and then included or prepended to a module or class. Implement by renaming ensure_origin to rb_ensure_origin, making it non-static, and calling it when refining a module. Fix Module#initialize_copy to handle origins correctly. Previously, Module#initialize_copy did not handle origins correctly. For example, this code: ```ruby module B; end class A def b; 2 end prepend B end a = A.dup.new class A def b; 1 end end p a.b ``` Printed 1 instead of 2. This is because the super chain for a.singleton_class was: ``` a.singleton_class A.dup B(iclass) B(iclass origin) A(origin) # not A.dup(origin) ``` The B iclasses would not be modified, so the includer entry would be still be set to A and not A.dup. This modifies things so that if the class/module has an origin, all iclasses between the class/module and the origin are duplicated and have the correct includer entry set, and the correct origin is created. This requires other changes to make sure all tests still pass: * rb_undef_methods_from doesn't automatically handle classes with origins, so pass it the origin for Comparable when undefing methods in Complex. This fixed a failure in the Complex tests. * When adding a method, the method cache was not cleared correctly if klass has an origin. Clear the method cache for the klass before switching to the origin of klass. This fixed failures in the autoload tests related to overridding require, without breaking the optimization tests. Also clear the method cache for both the module and origin when removing a method. * Module#include? is fixed to skip origin iclasses. * Refinements are fixed to use the origin class of the module that has an origin. * RCLASS_REFINED_BY_ANY is removed as it was only used in a single place and is no longer needed. * Marshal#dump is fixed to skip iclass origins. * rb_method_entry_make is fixed to handled overridden optimized methods for modules that have origins. Fixes [Bug #16852] Notes: Merged: https://github.com/ruby/ruby/pull/3140
2020-05-22Fix origin iclass pointer for modulesJeremy Evans
If a module has an origin, and that module is included in another module or class, previously the iclass created for the module had an origin pointer to the module's origin instead of the iclass's origin. Setting the origin pointer correctly requires using a stack, since the origin iclass is not created until after the iclass itself. Use a hidden ruby array to implement that stack. Correctly assigning the origin pointers in the iclass caused a use-after-free in GC. If a module with an origin is included in a class, the iclass shares a method table with the module and the iclass origin shares a method table with module origin. Mark iclass origin with a flag that notes that even though the iclass is an origin, it shares a method table, so the method table should not be garbage collected. The shared method table will be garbage collected when the module origin is garbage collected. I've tested that this does not introduce a memory leak. This change caused a VM assertion failure, which was traced to callable method entries using the incorrect defined_class. Update rb_vm_check_redefinition_opt_method and find_defined_class_by_owner to treat iclass origins different than class origins to avoid this issue. This also includes a fix for Module#included_modules to skip iclasses with origins. Fixes [Bug #16736] Notes: Merged: https://github.com/ruby/ruby/pull/3136
2020-05-22Revert "Fix origin iclass pointer for modules"Jeremy Evans
This reverts commit c745a60634260ba2080d35af6fdeaaae86fe5193. This triggers a VM assertion. Reverting until the issue can be debugged.
2020-05-22Fix origin iclass pointer for modulesJeremy Evans
If a module has an origin, and that module is included in another module or class, previously the iclass created for the module had an origin pointer to the module's origin instead of the iclass's origin. Setting the origin pointer correctly requires using a stack, since the origin iclass is not created until after the iclass itself. Use a hidden ruby array to implement that stack. Correctly assigning the origin pointers in the iclass caused a use-after-free in GC. If a module with an origin is included in a class, the iclass shares a method table with the module and the iclass origin shares a method table with module origin. Mark iclass origin with a flag that notes that even though the iclass is an origin, it shares a method table, so the method table should not be garbage collected. The shared method table will be garbage collected when the module origin is garbage collected. I've tested that this does not introduce a memory leak. This also includes a fix for Module#included_modules to skip iclasses with origins. Fixes [Bug #16736] Notes: Merged: https://github.com/ruby/ruby/pull/2978
2020-05-21Synchronized non-inline version rb_scan_args with the inline versionNobuyoshi Nakada
2020-05-11sed -i 's|ruby/impl|ruby/internal|'卜部昌平
To fix build failures. Notes: Merged: https://github.com/ruby/ruby/pull/3079
2020-05-11sed -i s|ruby/3|ruby/impl|g卜部昌平
This shall fix compile errors. Notes: Merged: https://github.com/ruby/ruby/pull/3079
2020-04-12Make rb_scan_args implementations sameNobuyoshi Nakada
between rb_scan_args_set and rb_scan_args_assign + rb_scan_args_result.
2020-04-08Suppress -Wswitch warningsNobuyoshi Nakada
2020-04-08Merge pull request #2991 from shyouhei/ruby.h卜部昌平
Split ruby.h Notes: Merged-By: shyouhei <shyouhei@ruby-lang.org>
2020-02-27Make Module#include affect the iclasses of the moduleJeremy Evans
When calling Module#include, if the receiver is a module, walk the subclasses list and include the argument module in each iclass. This does not affect Module#prepend, as fixing that is significantly more involved. Fixes [Bug #9573] Notes: Merged: https://github.com/ruby/ruby/pull/2936
2020-02-22Introduce disposable call-cache.Koichi Sasada
This patch contains several ideas: (1) Disposable inline method cache (IMC) for race-free inline method cache * Making call-cache (CC) as a RVALUE (GC target object) and allocate new CC on cache miss. * This technique allows race-free access from parallel processing elements like RCU. (2) Introduce per-Class method cache (pCMC) * Instead of fixed-size global method cache (GMC), pCMC allows flexible cache size. * Caching CCs reduces CC allocation and allow sharing CC's fast-path between same call-info (CI) call-sites. (3) Invalidate an inline method cache by invalidating corresponding method entries (MEs) * Instead of using class serials, we set "invalidated" flag for method entry itself to represent cache invalidation. * Compare with using class serials, the impact of method modification (add/overwrite/delete) is small. * Updating class serials invalidate all method caches of the class and sub-classes. * Proposed approach only invalidate the method cache of only one ME. See [Feature #16614] for more details. Notes: Merged: https://github.com/ruby/ruby/pull/2888
2020-02-14Hoisted out `rb_scan_args_result`Nobuyoshi Nakada
2020-02-03Make `rb_scan_args_kw` inline tooNobuyoshi Nakada
2020-02-03Moved runtime assignemntsNobuyoshi Nakada
Separate assignemnts of dynamically given runtime values in `rb_scan_args_assign` from parsing statically given format in `rb_scan_args_parse`.
2020-02-03`struct rb_scan_args_t::vargs` is never usedNobuyoshi Nakada
2020-02-02Removed no longer used variable `last_hash`Nobuyoshi Nakada
1. By substituting `n_var` with its initializer, `0 < n_var` is equivalent to `argc > argi + n_trail`. 2. As `argi` is non-negative, so `argi + n_trail >= n_trail`, and the above expression is equivalent to `argc > n_trail`. 3. Therefore, `f_last` is always false, and `last_hash` is no longer used. Notes: Merged: https://github.com/ruby/ruby/pull/2873 Merged-By: nobu <nobu@ruby-lang.org>
2020-01-16Clarify documentation for Module#included_modules and Module#included?Marc-Andre Lafortune
[DOC] [ci skip] [Bug #8841]
2020-01-05Remove unused tmp_buffer in class.cKazuhiro NISHIYAMA
ref 44a164c26f5371519636585d8ba7aa59f489442e and beae6cbf0fd8b6619e5212552de98022d4c4d4d4
2020-01-05Remove unused last_idx in class.cKazuhiro NISHIYAMA
ref c7f01d889becbeffc4254e1b0b7faecb80ea3f3e and beae6cbf0fd8b6619e5212552de98022d4c4d4d4
2020-01-03Fix unused warningsKazuhiro NISHIYAMA
http://ci.rvm.jp/results/trunk_gcc7@silicon-docker/2539622 ``` /tmp/ruby/v2/src/trunk_gcc7/class.c: In function 'rb_scan_args_parse': /tmp/ruby/v2/src/trunk_gcc7/class.c:1971:12: warning: unused variable 'tmp_buffer' [-Wunused-variable] VALUE *tmp_buffer = arg->tmp_buffer; ^~~~~~~~~~ ``` ``` In file included from /tmp/ruby/v2/src/trunk_gcc7/vm_insnhelper.c:1895:0, from /tmp/ruby/v2/src/trunk_gcc7/vm.c:349: /tmp/ruby/v2/src/trunk_gcc7/vm_args.c:212:1: warning: 'args_stored_kw_argv_to_hash' defined but not used [-Wunused-function] args_stored_kw_argv_to_hash(struct args_info *args) ^~~~~~~~~~~~~~~~~~~~~~~~~~~ ```
2020-01-02Fully separate positional arguments and keyword argumentsJeremy Evans
This removes the warnings added in 2.7, and changes the behavior so that a final positional hash is not treated as keywords or vice-versa. To handle the arg_setup_block splat case correctly with keyword arguments, we need to check if we are taking a keyword hash. That case didn't have a test, but it affects real-world code, so add a test for it. This removes rb_empty_keyword_given_p() and related code, as that is not needed in Ruby 3. The empty keyword case is the same as the no keyword case in Ruby 3. This changes rb_scan_args to implement keyword argument separation for C functions when the : character is used. For backwards compatibility, it returns a duped hash. This is a bad idea for performance, but not duping the hash breaks at least Enumerator::ArithmeticSequence#inspect. Instead of having RB_PASS_CALLED_KEYWORDS be a number, simplify the code by just making it be rb_keyword_given_p(). Notes: Merged: https://github.com/ruby/ruby/pull/2794