summaryrefslogtreecommitdiff
path: root/object.c
Commit message (Collapse)AuthorAgeFilesLines
* Encapsulate RCLASS_ATTACHED_OBJECTJean Boussier2023-02-151-1/+1
| | | | | | | | | 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.
* YJIT: Implement codegen for Kernel#block_given? (#7202)Takashi Kokubun2023-01-311-6/+0
|
* Adjust braces [ci skip]Nobuyoshi Nakada2023-01-221-6/+4
|
* [DOC] Move the internal document for `Init_class_hierarchy`Nobuyoshi Nakada2023-01-041-21/+0
| | | | It has hidden the document for `Object` class.
* Transition complex objects to "too complex" shapeJemma Issroff2022-12-151-1/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When an object becomes "too complex" (in other words it has too many variations in the shape tree), we transition it to use a "too complex" shape and use a hash for storing instance variables. Without this patch, there were rare cases where shape tree growth could "explode" and cause performance degradation on what would otherwise have been cached fast paths. This patch puts a limit on shape tree growth, and gracefully degrades in the rare case where there could be a factorial growth in the shape tree. For example: ```ruby class NG; end HUGE_NUMBER.times do NG.new.instance_variable_set(:"@unique_ivar_#{_1}", 1) end ``` We consider objects to be "too complex" when the object's class has more than SHAPE_MAX_VARIATIONS (currently 8) leaf nodes in the shape tree and the object introduces a new variation (a new leaf node) associated with that class. For example, new variations on instances of the following class would be considered "too complex" because those instances create more than 8 leaves in the shape tree: ```ruby class Foo; end 9.times { Foo.new.instance_variable_set(":@uniq_#{_1}", 1) } ``` However, the following class is *not* too complex because it only has one leaf in the shape tree: ```ruby class Foo def initialize @a = @b = @c = @d = @e = @f = @g = @h = @i = nil end end 9.times { Foo.new } `` This case is rare, so we don't expect this change to impact performance of most applications, but it needs to be handled. Co-Authored-By: Aaron Patterson <tenderlove@ruby-lang.org>
* Use rb_inspect instead of +PRIsVALUE for Object.inspectMatt Valentine-House2022-12-091-2/+2
| | | | | In order to preserve the values when TrueClass, FalseClass or NilClass are stored in ivars
* Remove dead code in rb_obj_copy_ivarPeter Zhu2022-11-221-14/+0
| | | | The removed code is a duplicate of the code above.
* Refactor obj_ivar_set and vm_setivarPeter Zhu2022-11-211-2/+2
| | | | | | | obj_ivar_set and vm_setivar_slowpath is essentially doing the same thing, but the code is duplicated and not quite implemented in the same way, which could cause bugs. This commit refactors vm_setivar_slowpath to use obj_ivar_set.
* Update assertionAaron Patterson2022-11-181-1/+1
| | | | New T_OBJECT objects will have a T_OBJECT shape
* Differentiate T_OBJECT shapes from other objectsAaron Patterson2022-11-181-1/+1
| | | | | | | We would like to differentiate types of objects via their shape. This commit adds a special T_OBJECT shape when we allocate an instance of T_OBJECT. This allows us to avoid testing whether an object is an instance of a T_OBJECT or not, we can just check the shape.
* Using UNDEF_P macroS-H-GAMELINKS2022-11-161-5/+5
|
* Extract `rb_shape_get_parent` helperJemma Issroff2022-11-101-1/+1
| | | | | Extract an `rb_shape_get_parent` method instead of continually calling `rb_shape_get_shape_by_id(shape->parent_id)`
* Remove numiv from RObjectJemma Issroff2022-11-101-1/+0
| | | | | | | Since object shapes store the capacity of an object, we no longer need the numiv field on RObjects. This gives us one extra slot which we can use to give embedded objects one more instance variable (for a total of 3 ivs). This commit removes the concept of numiv from RObject.
* Transition shape when object's capacity changesJemma Issroff2022-11-101-23/+54
| | | | | | | | | | | | | | | | 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>
* Ivar copy needs to happen _before_ setting the shapeAaron Patterson2022-11-011-4/+4
| | | | | | | | When we copy instance variables, it is possible for the GC to be kicked off. The GC looks at the shape to determine what slots to mark inside the object. If the shape is set too soon, the GC could think that there are more instance variables on the object than there actually are at that moment.
* Implement object shapes for T_CLASS and T_MODULE (#6637)John Hawthorn2022-10-311-8/+10
| | | | | | | | * 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
* In init_copy, set shape after copying ivarsJemma Issroff2022-10-211-3/+3
| | | | | | | GC uses shapes to determine IV buffer width. Since allocation can trigger GC, we need to ensure we only set the shape once we've fully allocated new memory for the IV buffer, otherwise the GC can end up trying to mark invalid memory.
* Add Class#attached_objectUfuk Kayserilioglu2022-10-201-0/+1
| | | | | | | 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.
* [Bug #18998] Honor `#to_str` next to `#to_int` in `Kernel#Integer`Nobuyoshi Nakada2022-10-201-0/+3
|
* Simplified rb_obj_copy_ivar implementationJemma Issroff2022-10-171-24/+8
|
* Make inline cache reads / writes atomic with object shapesJemma Issroff2022-10-111-1/+1
| | | | | | | | | | | | | | 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-2/+44
| | | | This reverts commit 9a6803c90b817f70389cae10d60b50ad752da48f.
* object.c: rb_eql returns int not VALUEJean Boussier2022-10-101-2/+2
| | | | | It works, but assumes `Qfalse == 0`, which is true today but might not be forever.
* Revert "This commit implements the Object Shapes technique in CRuby."Aaron Patterson2022-09-301-44/+2
| | | | This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
* This commit implements the Object Shapes technique in CRuby.Jemma Issroff2022-09-281-2/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Revert this until we can figure out WB issues or remove shapes from GCAaron Patterson2022-09-261-44/+2
| | | | | | | | | | Revert "* expand tabs. [ci skip]" This reverts commit 830b5b5c351c5c6efa5ad461ae4ec5085e5f0275. Revert "This commit implements the Object Shapes technique in CRuby." This reverts commit 9ddfd2ca004d1952be79cf1b84c52c79a55978f4.
* This commit implements the Object Shapes technique in CRuby.Jemma Issroff2022-09-261-2/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* [DOC] non-positive `base` in `Kernel#Integer` and `String#to_i`Nobuyoshi Nakada2022-09-081-4/+27
|
* Reuse rb_class_new_instance_kw functionS-H-GAMELINKS2022-08-201-7/+1
|
* Adjust styles [ci skip]Nobuyoshi Nakada2022-07-271-4/+8
|
* Expand tabs [ci skip]Takashi Kokubun2022-07-211-358/+358
| | | | [Misc #18891]
* Implement Objects on VWAPeter Zhu2022-07-151-27/+6
| | | | | | This commit implements Objects on Variable Width Allocation. This allows Objects with more ivars to be embedded (i.e. contents directly follow the object header) which improves performance through better cache locality.
* Allow to just warn as bool expected, without an exceptionNobuyoshi Nakada2022-06-201-9/+15
|
* Add assertion for embedded to embedded ivar copyJemma Issroff2022-06-101-0/+1
|
* Add Module#undefined_instance_methodsJeremy Evans2022-06-061-0/+2
| | | | | Implements [Feature #12655] Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org>
* Link from printf methods to format spec doc (#5886)Burdette Lamar2022-05-051-253/+6
|
* [DOC] Enhanced RDoc for Kernel (#5847)Burdette Lamar2022-04-271-30/+61
| | | Treats #Integer; fixes an error in #String.
* Faster rb_class_superclassJohn Hawthorn2022-04-261-7/+6
| | | | | This uses the RCLASS_SUPERCLASSES array to quickly find the next SUPERCLASS of klass which is a T_CLASS.
* [DOC] Enhanced RDoc for Kernel (#5846)Burdette Lamar2022-04-251-26/+37
| | | | | | | Treats: #Array #Hash #String
* [DOC] Enhance documentation for `Module#<` & `Module#>`Akshay Birajdar2022-04-141-2/+6
|
* [DOC] Prefer RDOCLINK to the method nameNobuyoshi Nakada2022-04-141-1/+2
|
* [DOC] Now underscore methods can cross-referenceNobuyoshi Nakada2022-04-141-8/+6
|
* [DOC] Use simple references to operator methodsNobuyoshi Nakada2022-03-301-4/+4
| | | | | | | Method references is not only able to be marked up as code, also reflects `--show-hash` option. The bug that prevented the old rdoc from correctly parsing these methods was fixed last month.
* [DOC] Repair format of What's Here sections in object.c (#5722)Burdette Lamar2022-03-291-155/+147
| | | | | * Repair format of What's Here sections in object.c
* Revert "Faster rb_class_superclass"John Hawthorn2022-03-171-6/+7
| | | | This reverts commit 29b68b89a0c0ea7de46c058fab746550398151f0.
* Faster rb_class_superclassJohn Hawthorn2022-03-171-7/+6
| | | | | This uses the RCLASS_SUPERCLASSES array to quickly find the next SUPERCLASS of klass which is a T_CLASS.
* Fast rb_class_inherited_pJohn Hawthorn2022-03-151-10/+31
| | | | | | | | | This uses the superclass table recently introduced to implement fast inheritance checking between classes (ex. Foo < Bar). This is almost identical to what we do in class_search_class_ancestor (as called by rb_obj_is_kind_of) except that we are checking both directions: ie. both whether Foo < Bar and whether Bar < Foo.
* Fast object is iclass checksJohn Hawthorn2022-03-111-9/+29
| | | | | | | | | | | | | | | Calling rb_obj_is_kind_of with an ICLASS returns the same result as calling it with the ICLASS's original Module. Most of the time we encounter an ICLASS here checking the validity of a protected method or super call, which we expect to return true (or raise a slow exception anyways). We can take advantage of this by performing a fast class inheritance check on the ICLASS's "includer" in hopes that it returns true. If the includer class check returns false we still have to fallback to the full inheritance chain scan for the module's inclusion, but this should be less common.
* Revert "Fast object is iclass checks"John Hawthorn2022-03-101-23/+9
| | | | This reverts commit 1b15756d24c11ed6bfddb5ae53402a071a20ea97.
* Fast object is iclass checksJohn Hawthorn2022-03-101-9/+23
| | | | | | | | | | | | | | | Calling rb_obj_is_kind_of with an ICLASS returns the same result as calling it with the ICLASS's original Module. Most of the time we encounter an ICLASS here checking the validity of a protected method or super call, which we expect to return true (or raise a slow exception anyways). We can take advantage of this by performing a fast class inheritance check on the ICLASS's "includer" in hopes that it returns true. If the includer class check returns false we still have to fallback to the full inheritance chain scan for the module's inclusion, but this should be less common.