aboutsummaryrefslogtreecommitdiffstats
path: root/object.c
Commit message (Collapse)AuthorAgeFilesLines
* Refactor VM root modulesJean Boussier2024-03-061-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This `st_table` is used to both mark and pin classes defined from the C API. But `vm->mark_object_ary` already does both much more efficiently. Currently a Ruby process starts with 252 rooted classes, which uses `7224B` in an `st_table` or `2016B` in an `RArray`. So a baseline of 5kB saved, but since `mark_object_ary` is preallocated with `1024` slots but only use `405` of them, it's a net `7kB` save. `vm->mark_object_ary` is also being refactored. Prior to this changes, `mark_object_ary` was a regular `RArray`, but since this allows for references to be moved, it was marked a second time from `rb_vm_mark()` to pin these objects. This has the detrimental effect of marking these references on every minors even though it's a mostly append only list. But using a custom TypedData we can save from having to mark all the references on minor GC runs. Addtionally, immediate values are now ignored and not appended to `vm->mark_object_ary` as it's just wasted space.
* Move FL_SINGLETON to FL_USER1Jean Boussier2024-03-061-5/+5
| | | | | | | | This frees FL_USER0 on both T_MODULE and T_CLASS. Note: prior to this, FL_SINGLETON was never set on T_MODULE, so checking for `FL_SINGLETON` without first checking that `FL_TYPE` was `T_CLASS` was valid. That's no longer the case.
* YJIT: Lazily push a frame for specialized C funcs (#10080)Takashi Kokubun2024-02-231-0/+2
| | | | | | | | | | | | | | | | | | | | | * YJIT: Lazily push a frame for specialized C funcs Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com> * Fix a comment on pc_to_cfunc * Rename rb_yjit_check_pc to rb_yjit_lazy_push_frame * Rename it to jit_prepare_lazy_frame_call * Fix a typo * Optimize String#getbyte as well * Optimize String#byteslice as well --------- Co-authored-by: Maxime Chevalier-Boisvert <maxime.chevalierboisvert@shopify.com>
* Use `defined?(yield)` and `SIZED_ENUMERATOR`Nobuyoshi Nakada2024-02-171-0/+6
| | | | Prefer built-in features over method calls that may be overridden.
* Do not include a backtick in error messages and backtracesYusuke Endoh2024-02-151-3/+3
| | | | [Feature #16495]
* Move rb_class_allocate_instance from gc.c to object.cPeter Zhu2024-02-141-0/+31
|
* proc.c: get rid of `CLONESETUP`Jean Boussier2024-02-121-10/+20
| | | | | | | | | | | | | | | | | [Bug #20253] All the way down to Ruby 1.9, `Proc`, `Method`, `UnboundMethod` and `Binding` always had their own specific clone and dup routine. This caused various discrepancies with how other objects behave on `dup` and `clone. [Bug #20250], [Bug #20253]. This commit get rid of `CLONESETUP` and use the the same codepath as all other types, so ensure consistency. NB: It's still not accepting the `freeze` keyword argument on `clone`. Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com>
* rb_obj_setup: do not copy RUBY_FL_SEEN_OBJ_IDJean Boussier2024-02-091-1/+1
| | | | | | | [Bug #20250] We're seting up a new instance, so it never had an associated object_id.
* Fix memory leak when duplicating too complex objectPeter Zhu2024-01-101-2/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | [Bug #20162] Creating a ST table then calling st_replace leaks memory because the st_replace overwrites the ST table without freeing any of the existing memory. This commit changes it to use st_copy instead. For example: RubyVM::Shape.exhaust_shapes o = Object.new o.instance_variable_set(:@a, 0) 10.times do 100_000.times { o.dup } puts `ps -o rss= -p #{$$}` end Before: 23264 33600 42672 52160 61600 71728 81056 90528 100560 109840 After: 14752 14816 15584 15584 15664 15664 15664 15664 15664 15664
* Move internal ST functions to internal/st.hPeter Zhu2023-12-251-0/+1
| | | | | st_replace and st_init_existing_table_with_size are functions used internally in Ruby and should not be publicly visible.
* Don't copy RUBY_FL_PROMOTED flag in rb_obj_setupPeter Zhu2023-12-241-1/+2
| | | | | | | | | | RUBY_FL_PROMOTED is used by the garbage collector to track when an object becomes promoted to the old generation. rb_obj_setup must not copy that flag over because then it may become out-of-sync with the age of the object. This fixes a bug in Method#clone where the cloned Method object may get RUBY_FL_PROMOTED incorrectly set.
* Re-embed when removing Object instance variablesPeter Zhu2023-12-061-0/+6
| | | | | | | | | | | Objects with the same shape must always have the same "embeddedness" (either embedded or heap allocated) because YJIT assumes so. However, using remove_instance_variable, it's possible that some objects are embedded and some are heap allocated because it does not re-embed heap allocated objects. This commit changes remove_instance_variable to re-embed Object instance variables when it becomes small enough.
* Fix parameter types for rb_ivar_foreach() callbacksAlan Wu2023-12-051-3/+1
| | | | | | | | For this public API, the callback is declared to take `(ID, VALUE, st_data_t)`, but it so happens that using `(st_data_t, st_data_t, st_data_t)` also type checks, because the underlying type is identical. Use it as declared and get rid of some casts.
* Refactor rb_obj_evacuate_ivs_to_hash_tableJean Boussier2023-11-171-9/+5
| | | | | | | | | | | | | | | | | | That function is a bit too low level to called from multiple places. It's always used in tandem with `rb_shape_set_too_complex` and both have to know how the object is laid out to update the `iv_ptr`. So instead we can provide two higher level function: - `rb_obj_copy_ivs_to_hash_table` to prepare a `st_table` from an arbitrary oject. - `rb_obj_convert_to_too_complex` to assign the new `st_table` to the old object, and safely free the old `iv_ptr`. Unfortunately both can't be combined into one, because `rb_obj_copy_ivar` need `rb_obj_copy_ivs_to_hash_table` to copy from one object to another.
* rb_evict_ivars_to_hash: get rid of the sahpe paramaterJean Boussier2023-11-161-2/+2
| | | | | | | | | | It's only used to allocate the table with the right size, but in some case we were passing `rb_shape_get_shape_by_id(SHAPE_OBJ_TOO_COMPLEX)` which `next_iv_index` is a bit undefined. So overall we're better to just allocate a table the size of the existing object, it should be close enough in the vast majority of cases, and that's already a de-optimizaton path anyway.
* Handle running out of shapes in `Object#dup`Jean Boussier2023-10-311-1/+10
| | | | | | There is a handful of call sites where we may transition to OBJ_TOO_COMPLEX_SHAPE if we just ran out of shapes, but that weren't handling it properly.
* `get_next_shape_internal` should always return a shapeAaron Patterson2023-10-241-1/+1
| | | | | If it runs out of shapes, or new variations aren't allowed, it will return "too complex"
* geniv objects can become too complexAaron Patterson2023-10-241-2/+16
|
* [Bug #19349] Respect `#to_int` of `base` argumentNobuyoshi Nakada2023-08-311-114/+8
|
* [DOC] Improve doc guide compliance (#8221)Burdette Lamar2023-08-151-1/+1
|
* [Bug #19833] Fix index underflow at superclasses of `BasicObject`Nobuyoshi Nakada2023-08-081-0/+4
|
* Allow setting the name of a class or module. (#7483)Samuel Williams2023-06-211-0/+1
| | | | Introduce `Module#set_temporary_name` for setting identifiers for otherwise anonymous modules/classes.
* [DOC] Documentation for flags of RObjectPeter Zhu2023-04-111-0/+12
|
* Use an st table for "too complex" objectsAaron Patterson2023-03-201-1/+1
| | | | | | | | | | st tables will maintain insertion order so we can marshal dump / load objects with instance variables in the same order they were set on that particular instance [ruby-core:112926] [Bug #19535] Co-Authored-By: Jemma Issroff <jemmaissroff@gmail.com>
* [DOC] Enhanced RDoc for TrueClass (#7521)Burdette Lamar2023-03-161-22/+48
|
* [DOC] Enhanced RDoc for NilClass (#7500)Burdette Lamar2023-03-131-45/+101
|
* Stop exporting symbols for MJITTakashi Kokubun2023-03-061-10/+10
|
* Fix spelling (#7389)John Bampton2023-02-271-1/+1
|
* Remove (newly unneeded) remarks about aliasesBurdetteLamar2023-02-191-3/+0
|
* 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>