summaryrefslogtreecommitdiff
path: root/object.c
AgeCommit message (Collapse)Author
2022-10-11Make inline cache reads / writes atomic with object shapesJemma Issroff
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>
2022-10-11Revert "Revert "This commit implements the Object Shapes technique in CRuby.""Jemma Issroff
This reverts commit 9a6803c90b817f70389cae10d60b50ad752da48f.
2022-10-10object.c: rb_eql returns int not VALUEJean Boussier
It works, but assumes `Qfalse == 0`, which is true today but might not be forever. Notes: Merged: https://github.com/ruby/ruby/pull/6508
2022-09-30Revert "This commit implements the Object Shapes technique in CRuby."Aaron Patterson
This reverts commit 68bc9e2e97d12f80df0d113e284864e225f771c2.
2022-09-28This commit implements the Object Shapes technique in CRuby.Jemma Issroff
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>
2022-09-26Revert this until we can figure out WB issues or remove shapes from GCAaron Patterson
Revert "* expand tabs. [ci skip]" This reverts commit 830b5b5c351c5c6efa5ad461ae4ec5085e5f0275. Revert "This commit implements the Object Shapes technique in CRuby." This reverts commit 9ddfd2ca004d1952be79cf1b84c52c79a55978f4.
2022-09-26This commit implements the Object Shapes technique in CRuby.Jemma Issroff
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> Notes: Merged: https://github.com/ruby/ruby/pull/6386
2022-09-08[DOC] non-positive `base` in `Kernel#Integer` and `String#to_i`Nobuyoshi Nakada
2022-08-20Reuse rb_class_new_instance_kw functionS-H-GAMELINKS
Notes: Merged: https://github.com/ruby/ruby/pull/6241
2022-07-27Adjust styles [ci skip]Nobuyoshi Nakada
2022-07-21Expand tabs [ci skip]Takashi Kokubun
[Misc #18891] Notes: Merged: https://github.com/ruby/ruby/pull/6094
2022-07-15Implement Objects on VWAPeter Zhu
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. Notes: Merged: https://github.com/ruby/ruby/pull/6117
2022-06-20Allow to just warn as bool expected, without an exceptionNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/6039
2022-06-10Add assertion for embedded to embedded ivar copyJemma Issroff
Notes: Merged: https://github.com/ruby/ruby/pull/6003
2022-06-06Add Module#undefined_instance_methodsJeremy Evans
Implements [Feature #12655] Co-authored-by: Nobuyoshi Nakada <nobu@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/5733 Merged-By: jeremyevans <code@jeremyevans.net>
2022-05-05Link from printf methods to format spec doc (#5886)Burdette Lamar
Notes: Merged-By: BurdetteLamar <BurdetteLamar@Yahoo.com>
2022-04-27[DOC] Enhanced RDoc for Kernel (#5847)Burdette Lamar
Treats #Integer; fixes an error in #String. Notes: Merged-By: BurdetteLamar <BurdetteLamar@Yahoo.com>
2022-04-26Faster rb_class_superclassJohn Hawthorn
This uses the RCLASS_SUPERCLASSES array to quickly find the next SUPERCLASS of klass which is a T_CLASS. Notes: Merged: https://github.com/ruby/ruby/pull/5850
2022-04-25[DOC] Enhanced RDoc for Kernel (#5846)Burdette Lamar
Treats: #Array #Hash #String Notes: Merged-By: BurdetteLamar <BurdetteLamar@Yahoo.com>
2022-04-14[DOC] Enhance documentation for `Module#<` & `Module#>`Akshay Birajdar
Notes: Merged: https://github.com/ruby/ruby/pull/5784
2022-04-14[DOC] Prefer RDOCLINK to the method nameNobuyoshi Nakada
2022-04-14[DOC] Now underscore methods can cross-referenceNobuyoshi Nakada
2022-03-30[DOC] Use simple references to operator methodsNobuyoshi Nakada
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.
2022-03-29[DOC] Repair format of What's Here sections in object.c (#5722)Burdette Lamar
* Repair format of What's Here sections in object.c Notes: Merged-By: BurdetteLamar <BurdetteLamar@Yahoo.com>
2022-03-17Revert "Faster rb_class_superclass"John Hawthorn
This reverts commit 29b68b89a0c0ea7de46c058fab746550398151f0. Notes: Merged: https://github.com/ruby/ruby/pull/5678
2022-03-17Faster rb_class_superclassJohn Hawthorn
This uses the RCLASS_SUPERCLASSES array to quickly find the next SUPERCLASS of klass which is a T_CLASS. Notes: Merged: https://github.com/ruby/ruby/pull/5662
2022-03-15Fast rb_class_inherited_pJohn Hawthorn
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. Notes: Merged: https://github.com/ruby/ruby/pull/5628
2022-03-11Fast object is iclass checksJohn Hawthorn
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. Notes: Merged: https://github.com/ruby/ruby/pull/5642
2022-03-10Revert "Fast object is iclass checks"John Hawthorn
This reverts commit 1b15756d24c11ed6bfddb5ae53402a071a20ea97. Notes: Merged: https://github.com/ruby/ruby/pull/5639
2022-03-10Fast object is iclass checksJohn Hawthorn
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. Notes: Merged: https://github.com/ruby/ruby/pull/5619
2022-02-23Constant time class to class ancestor lookupJohn Hawthorn
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. Notes: Merged: https://github.com/ruby/ruby/pull/5568
2022-02-23Never call kind_of with klass=0John Hawthorn
Notes: Merged: https://github.com/ruby/ruby/pull/5568
2022-02-18Enhanced RDoc concerning command injection (#5537)Burdette Lamar
Clarifies security vulnerabilities for commands. Treats: Kernel.system Kernel.` (backtick) IO.popen IO.read IO.write IO.binread IO.binwrite IO.readlines IO.foreach Notes: Merged-By: BurdetteLamar <BurdetteLamar@Yahoo.com>
2022-02-12[DOC] Simplify operator method referencesNobuyoshi Nakada
2022-02-07[DOC] Use RDoc link style for links in the same class/modulePeter Zhu
I used this regex: (?<=\[)#(?:class|module)-([A-Za-z]+)-label-([A-Za-z0-9\-\+]+) And performed a global find & replace for this: rdoc-ref:$1@$2 Notes: Merged: https://github.com/ruby/ruby/pull/5530
2022-02-07[DOC] Use RDoc link style for links to other classes/modulesPeter Zhu
I used this regex: ([A-Za-z]+)\.html#(?:class|module)-[A-Za-z]+-label-([A-Za-z0-9\-\+]+) And performed a global find & replace for this: rdoc-ref:$1@$2 Notes: Merged: https://github.com/ruby/ruby/pull/5530
2022-01-14Add a Module#const_added callbackJean Boussier
[Feature #17881] Works similarly to `method_added` but for constants. ```ruby Foo::BAR = 42 # call Foo.const_added(:FOO) class Foo::Baz; end # call Foo.const_added(:Baz) Foo.autoload(:Something, "path") # call Foo.const_added(:Something) ``` Notes: Merged: https://github.com/ruby/ruby/pull/4521
2022-01-06Allow include before calling Module#initializeJeremy Evans
This is to allow Module subclasses that include modules before calling super in the subclass's initialize. Remove rb_module_check_initializable from Module#initialize. Module#initialize only calls module_exec if a block is passed, it doesn't have other issues that would cause problems if called multiple times or with an already initialized module. Move initialization of super to Module#allocate, though I'm not sure it is required there. However, it's needed to be removed from Module#initialize for this to work. Fixes [Bug #18292] Notes: Merged: https://github.com/ruby/ruby/pull/5398
2022-01-03Kernel#=~: delete卜部昌平
Has been deprecated since ebff9dc10e6e72239c23e50acc7d3cbfdc659e7a.
2022-01-01Negative RBOOL usageNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/5385
2021-12-26Remove tainted and trusted featuresNobuyoshi Nakada
Already these had been announced to be removed in 3.2. Notes: Merged: https://github.com/ruby/ruby/pull/5348
2021-12-20Remove Class#descendantsJeremy Evans
Notes: Merged: https://github.com/ruby/ruby/pull/5309
2021-12-08Add `to_f` to predefined conversion method name to ID tableNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/5228
2021-11-23Add Class#subclassesJean Boussier
Implements [Feature #18273] Returns an array containing the receiver's direct subclasses without singleton classes. Notes: Merged: https://github.com/ruby/ruby/pull/5045
2021-11-18Optimize dynamic string interpolation for symbol/true/false/nil/0-9Jeremy Evans
This provides a significant speedup for symbol, true, false, nil, and 0-9, class/module, and a small speedup in most other cases. Speedups (using included benchmarks): :symbol :: 60% 0-9 :: 50% Class/Module :: 50% nil/true/false :: 20% integer :: 10% [] :: 10% "" :: 3% One reason this approach is faster is it reduces the number of VM instructions for each interpolated value. Initial idea, approach, and benchmarks from Eric Wong. I applied the same approach against the master branch, updating it to handle the significant internal changes since this was first proposed 4 years ago (such as CALL_INFO/CALL_CACHE -> CALL_DATA). I also expanded it to optimize true/false/nil/0-9/class/module, and added handling of missing methods, refined methods, and RUBY_DEBUG. This renames the tostring insn to anytostring, and adds an objtostring insn that implements the optimization. This requires making a few functions non-static, and adding some non-static functions. This disables 4 YJIT tests. Those tests should be reenabled after YJIT optimizes the new objtostring insn. Implements [Feature #13715] Co-authored-by: Eric Wong <e@80x24.org> Co-authored-by: Alan Wu <XrXr@users.noreply.github.com> Co-authored-by: Yusuke Endoh <mame@ruby-lang.org> Co-authored-by: Koichi Sasada <ko1@atdot.net> Notes: Merged: https://github.com/ruby/ruby/pull/5002 Merged-By: jeremyevans <code@jeremyevans.net>
2021-11-17Improve performance Kernel#Float with using Primitive.mandatory_only? method ↵S.H
[Feature #18344] (#5133) Notes: Merged-By: k0kubun <takashikkbn@gmail.com>
2021-10-26Add Class#descendantsJeremy Evans
Doesn't include receiver or singleton classes. Implements [Feature #14394] Co-authored-by: fatkodima <fatkodima123@gmail.com> Co-authored-by: Benoit Daloze <eregontp@gmail.com> Notes: Merged: https://github.com/ruby/ruby/pull/4974 Merged-By: jeremyevans <code@jeremyevans.net>
2021-10-21Deprecate include/prepend in refinements and add Refinement#import_methods ↵Shugo Maeda
instead Refinement#import_methods imports methods from modules. Unlike Module#include, it copies methods and adds them into the refinement, so the refinement is activated in the imported methods. [Bug #17429] [ruby-core:101639]
2021-10-20Add comments about special runtime routines YJIT callsAlan Wu
When YJIT make calls to routines without reconstructing interpreter state through jit_prepare_routine_call(), it relies on the routine to never allocate, raise, and push/pop control frames. Comment about this on the routines that YJTI calls. This is probably something we should dynamically verify on debug builds. It's hard to statically verify this as it requires verifying all functions in the call tree. Maybe something to look at in the future.
2021-09-19Fix a typo [Bug #17048]Nobuyoshi Nakada