aboutsummaryrefslogtreecommitdiffstats
path: root/class.c
Commit message (Collapse)AuthorAgeFilesLines
* [Bug #19901]Adam Hess2023-09-231-0/+1
| | | | | | fix leak in module clone Co-authored-by: Peter Zhu <peter@peterzhu.ca>
* Stop exposing FrozenCore in headersNobuyoshi Nakada2023-09-191-8/+2
| | | | | Revert commit "Directly allocate FrozenCore as an ICLASS", 813a5f4fc46a24ca1695d23c159250b9e1080ac7.
* Store object age in a bitmapMatt Valentine-House2023-07-131-1/+0
| | | | | | | | | | | | | | | | | | Closes [Feature #19729] Previously 2 bits of the flags on each RVALUE are reserved to store the number of GC cycles that each object has survived. This commit introduces a new bit array on the heap page, called age_bits, to store that information instead. This patch still reserves one of the age bits in the flags (the old FL_PROMOTED0 bit, now renamed FL_PROMOTED). This is set to 0 for young objects and 1 for old objects, and is used as a performance optimisation for the write barrier. Fetching the age_bits from the heap page and doing the required math to calculate if the object was old or not would slow down the write barrier. So we keep this bit synced in the flags for fast access.
* Prefer `0` over `NULL` as function pointersNobuyoshi Nakada2023-06-231-1/+1
| | | SunC warns use of `NULL`, pointer to data as function pointers.
* Directly allocate FrozenCore as an ICLASSPeter Zhu2023-06-141-2/+8
| | | | | It's a bad idea to overwrite the flags as the garbage collector may have set other flags.
* Revert "Revert "Fix cvar caching when class is cloned""eileencodes2023-06-051-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This reverts commit 10621f7cb9a0c70e568f89cce47a02e878af6778. This was reverted because the gc integrity build started failing. We have figured out a fix so I'm reopening the PR. Original commit message: Fix cvar caching when class is cloned The class variable cache that was added in ruby#4544 changed the behavior of class variables on cloned classes. As reported when a class is cloned AND a class variable was set, and the class variable was read from the original class, reading a class variable from the cloned class would return the value from the original class. This was happening because the IC (inline cache) is stored on the ISEQ which is shared between the original and cloned class, therefore they share the cache too. To fix this we are now storing the `cref` in the cache so that we can check if it's equal to the current `cref`. If it's different we don't want to read from the cache. If it's the same we do. Cloned classes don't share the same cref with their original class. This will need to be backported to 3.1 in addition to 3.2 since the bug exists in both versions. We also added a marking function which was missing. Fixes [Bug #19379] Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* Revert "Fix cvar caching when class is cloned"Aaron Patterson2023-06-011-3/+0
| | | | This reverts commit 77d1b082470790c17c24a2f406b4fec5d522636b.
* Fix cvar caching when class is clonedeileencodes2023-06-011-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | The class variable cache that was added in https://github.com/ruby/ruby/pull/4544 changed the behavior of class variables on cloned classes. As reported when a class is cloned AND a class variable was set, and the class variable was read from the original class, reading a class variable from the cloned class would return the value from the original class. This was happening because the IC (inline cache) is stored on the ISEQ which is shared between the original and cloned class, therefore they share the cache too. To fix this we are now storing the `cref` in the cache so that we can check if it's equal to the current `cref`. If it's different we don't want to read from the cache. If it's the same we do. Cloned classes don't share the same cref with their original class. This will need to be backported to 3.1 in addition to 3.2 since the bug exists in both versions. We also added a marking function which was missing. Fixes [Bug #19379] Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* [DOC] Documentation for flags of RClassPeter Zhu2023-04-201-0/+36
|
* Make classes embedded on 32 bitPeter Zhu2023-04-161-9/+1
| | | | | Classes are now exactly 80 bytes when embedded, which perfectly fits the 3rd size pool on 32 bit systems.
* Change RMODULE_ALLOCATED_BUT_NOT_INITIALIZEDPeter Zhu2023-04-161-1/+1
| | | | | RCLASS_CLONED no longer uses FL_USER1, so we can make RMODULE_ALLOCATED_BUT_NOT_INITIALIZED use FL_USER1.
* Move RCLASS_CLONED to rb_classext_structPeter Zhu2023-04-161-2/+2
| | | | | This commit moves RCLASS_CLONED from the flags to the rb_classext_struct. This frees the FL_USER1 bit.
* [Feature #19474] Refactor NEWOBJ macrosMatt Valentine-House2023-04-061-1/+1
| | | | NEWOBJ_OF is now our canonical newobj macro. It takes an optional ec
* Adjust styles [ci skip]Nobuyoshi Nakada2023-03-081-1/+2
|
* Stop exporting symbols for MJITTakashi Kokubun2023-03-061-2/+2
|
* Move `attached_object` into `rb_classext_struct`Jean Boussier2023-02-161-4/+3
| | | | | | Given that signleton classes don't have an allocator, we can re-use these bytes to store the attached object in `rb_classext_struct` without making it larger.
* Encapsulate RCLASS_ATTACHED_OBJECTJean Boussier2023-02-151-9/+7
| | | | | | | | | 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.
* Copy cvar table on cloneeileencodes2023-02-091-0/+31
| | | | | | | | | | | | When a class with a class variable is cloned we need to also copy the cvar cache table from the original table to the clone. I found this bug while working on fixing [Bug #19379]. While this does not fix that bug directly it is still a required change to fix another bug revealed by the fix in https://github.com/ruby/ruby/pull/7265 This needs to be backported to 3.2.x and 3.1.x. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
* [DOC] Move the internal document for `Init_class_hierarchy`Nobuyoshi Nakada2023-01-041-0/+21
| | | | It has hidden the document for `Object` class.
* [DOC] Clarify Class#subclases behavior quirkszverok2022-12-111-0/+21
| | | | | As per discussion in [Feature #18273], explain the non-deterministic nature of the method.
* Freeze singleton class, not its originAlan Wu2022-12-081-1/+1
| | | | | | | | | | | | | Previously, when we froze an object, we froze `RCLASS_ORIGIN(object.singleton_class)`, which didn't freeze `object.singleton_class` when it has some prepended modules. Origin iclass are internal objects and users can't interact with them through Kernel#freeze?, Kernel#freeze, or any mutation method that checks the frozen status. So we shouldn't touch the origin iclasses when the frozen status should be visible. [Bug #19169]
* Inherit max_iv_count from superclassJohn Hawthorn2022-12-011-1/+7
| | | | | | | | In 274870bd5434ab64ac3a3c9db9aa27d262c1d6d6 we gained the ability to make an educated guess at the max_iv_count of a class based on its initialize method. This commit makes subclasses inherit their super's max_iv_count, which makes the estimate work in cases that the subclass does not have an initialize method.
* Using UNDEF_P macroS-H-GAMELINKS2022-11-161-3/+3
|
* Transition shape when object's capacity changesJemma Issroff2022-11-101-2/+2
| | | | | | | | | | | | | | | | 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>
* Implement object shapes for T_CLASS and T_MODULE (#6637)John Hawthorn2022-10-311-16/+5
| | | | | | | | * Avoid RCLASS_IV_TBL in marshal.c * Avoid RCLASS_IV_TBL for class names * Avoid RCLASS_IV_TBL for autoload * Avoid RCLASS_IV_TBL for class variables * Avoid copying RCLASS_IV_TBL onto ICLASSes * Use object shapes for Class and Module IVs
* Remove unused class serialJemma Issroff2022-10-211-6/+0
| | | | | | | | 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>
* Add Class#attached_objectUfuk Kayserilioglu2022-10-201-0/+27
| | | | | | | Implements [Feature #12084] Returns the object for which the receiver is the singleton class, or raises TypeError if the receiver is not a singleton class.
* Reuse ins_methods_type_i functionS-H-GAMELINKS2022-10-141-4/+1
|
* Remove reference to __classid__John Hawthorn2022-09-231-2/+0
| | | | | This used to be used for module names but its uses were removed in b00f280d4b9569e7153365d7e1c522b3d6b3c6cf.
* Update Module#instance_methods documentation for visibility changes/aliasesJeremy Evans2022-08-241-0/+9
| | | | Requested by matz in comment on #18435.
* Rename rb_ary_tmp_new to rb_ary_hidden_newPeter Zhu2022-07-261-3/+3
| | | | | | 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.
* Expand tabs [ci skip]Takashi Kokubun2022-07-211-265/+265
| | | | [Misc #18891]
* Add Module#undefined_instance_methodsJeremy Evans2022-06-061-0/+24
| | | | | Implements [Feature #12655] Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
* Remove unused RMODULE_INCLUDED_INTO_REFINEMENT flagJemma Issroff2022-05-261-1/+0
|
* Remove unnecessary module flag, add module assertions to other module flagsJemma Issroff2022-05-231-2/+3
|
* Fix potential GC issue while iterating over weak refsAlan Wu2022-05-051-8/+9
| | | | | | | | | | | | While walking over the list of subclasses for `include` and friends, we check whether the subclass is a garbage object. After the check, we allocate objects which might trigger GC and make the subclass garbage, even though before the allocation the subclass was not garbage. This is a sort of time-of-check-time-of-use issue. Fix this by saving the weak reference to a local variable, upgrading it to a strong reference while we do the allocation. It makes the code look slightly nicer even if it doesn't fix any runtime issues.
* Fix class ancestry checks for duped classesJohn Hawthorn2022-04-161-0/+2
| | | | | | | | | | | | | | | Previously in some when classes were duped (specifically those with a prepended module), they would not correctly have their "superclasses" array or depth filled in. This could cause ancestry checks (like is_a? and Module comparisons) to return incorrect results. This happened because rb_mod_init_copy builds origin classes in an order that doesn't have the super linked list fully connected until it's finished. This commit fixes the previous issue by calling rb_class_update_superclasses before returning the cloned class. This is similar to what's already done in make_metaclass.
* Finer-grained constant cache invalidation (take 2)Kevin Newton2022-04-011-4/+12
| | | | | | | | | | | | | | | | | | | | | | | | 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 "Finer-grained inline constant cache invalidation"Nobuyoshi Nakada2022-03-251-12/+4
| | | | | | | | | | | | 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.
* Update formatting per feedbackKevin Newton2022-03-241-1/+1
| | | Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
* Finer-grained inline constant cache invalidationKevin Newton2022-03-241-4/+12
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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.
* [Bug #18627] Fix crash when including modulePeter Zhu2022-03-181-18/+30
| | | | | | | During lazy sweeping, the iclass could be a dead object that has not yet been swept. However, the chain of superclasses of the iclass could already have been swept (and become a new object), which would cause a crash when trying to read the object.
* Assume that klass of dummy head is NULLPeter Zhu2022-03-161-1/+2
| | | | klass of the dummy head of the subclass entries should always be NULL.
* Always skip dummy head of subclass in rb_prepend_modulePeter Zhu2022-03-161-1/+1
| | | | | The first node of the subclass linked list of always a dummy head, so it should be skipped.
* Dedup superclass array in leaf sibling classesJohn Hawthorn2022-03-031-19/+14
| | | | | | | | | | | | | | | | Previously, we would build a new `superclasses` array for each class, even though for all immediate subclasses of a class, the array is identical. This avoids duplicating the arrays on leaf classes (those without subclasses) by calculating and storing a "superclasses including self" array on a class when it's first inherited and sharing that among all superclasses. An additional trick used is that the "superclass array including self" is valid as "self"'s superclass array. It just has it's own class at the end. We can use this to avoid an extra pointer of storage and can use one bit of a flag to track that we've "upgraded" the array.
* Constant time class to class ancestor lookupJohn Hawthorn2022-02-231-0/+60
| | | | | | | | | | | | | | | | | | | | | | | | | Previously when checking ancestors, we would walk all the way up the ancestry chain checking each parent for a matching class or module. I believe this was especially unfriendly to CPU cache since for each step we need to check two cache lines (the class and class ext). This check is used quite often in: * case statements * rescue statements * Calling protected methods * Class#is_a? * Module#=== * Module#<=> I believe it's most common to check a class against a parent class, to this commit aims to improve that (unfortunately does not help checking for an included Module). This is done by storing on each class the number and an array of all parent classes, in order (BasicObject is at index 0). Using this we can check whether a class is a subclass of another in constant time since we know the location to expect it in the hierarchy.
* Replace and Using METACLASS_OF macroS-H-GAMELINKS2022-02-191-15/+15
|
* Fix the placeholder subclass entry skipping [Bug #18489]Nobuyoshi Nakada2022-01-171-2/+1
|
* Separately allocate class_serial on 32-bit systemsPeter Zhu2022-01-141-0/+3
| | | | | | | | On 32-bit systems, VWA causes class_serial to not be aligned (it only guarantees 4 byte alignment but class_serial is 8 bytes and requires 8 byte alignment). This commit uses a hack to allocate class_serial through malloc. Once VWA allocates with 8 byte alignment in the future, we will revert this commit.
* Remove unneeded lineJeremy Evans2022-01-061-1/+0
|