summaryrefslogtreecommitdiff
path: root/shape.c
AgeCommit message (Collapse)Author
2025-06-05Refactor raw accesses to rb_shape_t.capacityJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13524
2025-06-05Fix comment about debugging shapesÉtienne Barrié
This method was moved to RubyVM::Shape in 913979bede2a1b79109fa2072352882560d55fe0.
2025-06-05Get rid of `rb_shape_t.flags`Jean Boussier
Now all flags are only in the `shape_id_t`, and can all be checked without needing to dereference a pointer. Notes: Merged: https://github.com/ruby/ruby/pull/13515
2025-06-04Get rid of TOO_COMPLEX shape typeJean Boussier
Instead it's now a `shape_id` flag. This allows to check if an object is complex without having to chase the `rb_shape_t` pointer. Notes: Merged: https://github.com/ruby/ruby/pull/13511
2025-06-04shape.c: fix off by one error in `shape_tree_mark`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13289
2025-06-04Get rid of frozen shapes.Jean Boussier
Instead `shape_id_t` higher bits contain flags, and the first one tells whether the shape is frozen. This has multiple benefits: - Can check if a shape is frozen with a single bit check instead of dereferencing a pointer. - Guarantees it is always possible to transition to frozen. - This allow reclaiming `FL_FREEZE` (not done yet). The downside is you have to be careful to preserve these flags when transitioning. Notes: Merged: https://github.com/ruby/ruby/pull/13289
2025-06-02Pin shape->edgesJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13441
2025-06-02shape.c: Implement a lock-free version of get_next_shape_internalJean Boussier
Whenever we run into an inline cache miss when we try to set an ivar, we may need to take the global lock, just to be able to lookup inside `shape->edges`. To solve that, when we're in multi-ractor mode, we can treat the `shape->edges` as immutable. When we need to add a new edge, we first copy the table, and then replace it with CAS. This increases memory allocations, however we expect that creating new transitions becomes increasingly rare over time. ```ruby class A def initialize(bool) @a = 1 if bool @b = 2 else @c = 3 end end def test @d = 4 end end def bench(iterations) i = iterations while i > 0 A.new(true).test A.new(false).test i -= 1 end end if ARGV.first == "ractor" ractors = 8.times.map do Ractor.new do bench(20_000_000 / 8) end end ractors.each(&:take) else bench(20_000_000) end ``` The above benchmark takes 27 seconds in Ractor mode on Ruby 3.4, and only 1.7s with this branch. Co-Authored-By: Étienne Barrié <etienne.barrie@gmail.com> Notes: Merged: https://github.com/ruby/ruby/pull/13441
2025-05-27Rename `rb_shape_frozen_shape_p` -> `shape_frozen_p`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13450
2025-05-27Refactor `rb_shape_too_complex_p` to take a `shape_id_t`.Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13450
2025-05-27Refactor `rb_shape_has_object_id`Jean Boussier
Now takes a `shape_id_t` and the version that takes a `rb_shape_t *` is private. Notes: Merged: https://github.com/ruby/ruby/pull/13450
2025-05-27Refactor `rb_obj_shape` out.Jean Boussier
It still exists but only in `shape.c`. Notes: Merged: https://github.com/ruby/ruby/pull/13450
2025-05-27Get rid of rb_shape_set_shapeJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13450
2025-05-27Refactor `rb_shape_get_iv_index` to take a `shape_id_t`Jean Boussier
Further reduce exposure of `rb_shape_t`. Notes: Merged: https://github.com/ruby/ruby/pull/13450
2025-05-27Get rid of `rb_shape_id(rb_shape_t *)`Jean Boussier
We should avoid conversions from `rb_shape_t *` into `shape_id_t` outside of `shape.c` as the short term goal is to have `shape_id_t` contain tags. Notes: Merged: https://github.com/ruby/ruby/pull/13448
2025-05-27Refactor `rb_shape_rebuild_shape` to stop exposing `rb_shape_t`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13448
2025-05-26Add shape_id to RBasic under 32 bitJohn Hawthorn
This makes `RBobject` `4B` larger on 32 bit systems but simplifies the implementation a lot. [Feature #21353] Co-authored-by: Jean Boussier <byroot@ruby-lang.org> Notes: Merged: https://github.com/ruby/ruby/pull/13341
2025-05-25Use RB_VM_LOCKINGNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/13439
2025-05-23Refactor `rb_shape_transition_remove_ivar`Jean Boussier
Move the fields management logic in `rb_ivar_delete`, and keep shape managment logic in `rb_shape_transition_remove_ivar`. Notes: Merged: https://github.com/ruby/ruby/pull/13426
2025-05-13variable.c: Refactor rb_obj_field_* to take shape_id_tJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13314
2025-05-11Allow T_CLASS and generic types to be too_complexJean Boussier
The intial complex shape implementation never allowed objects other than T_OBJECT to become too complex, unless we run out of shapes. I don't see any reason to prevent that. Ref: https://github.com/ruby/ruby/pull/6931 Notes: Merged: https://github.com/ruby/ruby/pull/13301
2025-05-11namespace on readSatoshi Tagomori
2025-05-09Refactor `FIRST_T_OBJECT_SHAPE_ID` to not be used outside `shape.c`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13291
2025-05-09Rename `RB_OBJ_SHAPE` -> `rb_obj_shape`Jean Boussier
As well as `RB_OBJ_SHAPE_ID` -> `rb_obj_shape_id` and `RSHAPE` is now a simple alias for `rb_shape_lookup`. I tried to turn all these into `static inline` but I'm having trouble with `RUBY_EXTERN rb_shape_tree_t *rb_shape_tree_ptr;` not being exposed as I'd expect. Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Stop exposing rb_shape_frozen_shape_pJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Get rid of `rb_shape_get_parent`.Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Rename `rb_shape_get_shape_id` -> `RB_OBJ_SHAPE_ID`Jean Boussier
And `rb_shape_get_shape` -> `RB_OBJ_SHAPE`. Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Remove unused `rb_shape_object_id_index`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Refactor `rb_shape_get_next` to return an IDJean Boussier
Also rename it, and change parameters to be consistent with other transition functions. Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Refactor `rb_shape_transition_shape_remove_ivar` to not take a shape pointerJean Boussier
It's more consistent with other transition functions. Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Rename `rb_shape_obj_too_complex` -> `rb_shape_obj_too_complex_p`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Refactor `rb_shape_transition_too_complex` to return an ID.Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Refactor `rb_shape_transition_frozen` to return a `shape_id`.Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Rename `rb_shape_get_shape_by_id` -> `RSHAPE`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Refactor `rb_shape_get_next_iv_shape` to take and return ids.Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Refactor `rb_shape_depth` to take an ID rather than a pointer.Jean Boussier
As well as `rb_shape_edges_count` and `rb_shape_memsize`. Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Refactor `rb_shape_traverse_from_new_root` to not expose `rb_shape_t`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-09Extract `rb_shape_free_all`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13283
2025-05-08Fix `remove_instance_variable` on complex objectsJean Boussier
Introduced in: https://github.com/ruby/ruby/pull/13159 Now that there is no longer a unique TOO_COMPLEX shape with no children, checking `shape->type == TOO_COMPLEX` is incorrect. Notes: Merged: https://github.com/ruby/ruby/pull/13280
2025-05-08Move `object_id` in object fields.Jean Boussier
And get rid of the `obj_to_id_tbl` It's no longer needed, the `object_id` is now stored inline in the object alongside instance variables. We still need the inverse table in case `_id2ref` is invoked, but we lazily build it by walking the heap if that happens. The `object_id` concern is also no longer a GC implementation concern, but a generic implementation. Co-Authored-By: Matt Valentine-House <matt@eightbitraptor.com> Notes: Merged: https://github.com/ruby/ruby/pull/13159
2025-05-08shape.c: refactor frozen shape to no longer be finalJean Boussier
This opens the door to store more informations in shapes, such as the `object_id` or object address in case it has been observed and the object has to be moved. Notes: Merged: https://github.com/ruby/ruby/pull/13159
2025-05-08Refactor OBJ_TOO_COMPLEX_SHAPE_ID to not be referenced outside shape.hJean Boussier
Also refactor checks for `->type == SHAPE_OBJ_TOO_COMPLEX`. Notes: Merged: https://github.com/ruby/ruby/pull/13159
2025-05-08Rename `ivptr` -> `fields`, `next_iv_index` -> `next_field_index`Jean Boussier
Ivars will longer be the only thing stored inline via shapes, so keeping the `iv_index` and `ivptr` names would be confusing. Instance variables won't be the only thing stored inline via shapes, so keeping the `ivptr` name would be confusing. `field` encompass anything that can be stored in a VALUE array. Similarly, `gen_ivtbl` becomes `gen_fields_tbl`. Notes: Merged: https://github.com/ruby/ruby/pull/13159
2025-05-05Improve style consistency of `rb_shape_t *`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13257
2025-04-30get_next_shape_internal: Skip VM lock for single child caseJean Boussier
If the shape has only one child, we check it lock-free without compromising thread safety. I haven't computed hard data as to how often that it the case, but we can assume that it's not too rare for shapes to have a single child that is often requested, typically when freezing and object. Notes: Merged: https://github.com/ruby/ruby/pull/13191
2025-04-30Improve syntax style consistency in shape.c and shape.hJean Boussier
Most of this code use the `type * name` style, while the overwhemling majority of the rest of ruby use the `type *name` style. This is a cosmetic change, but helps with readability.
2024-12-24[DOC] Hide `RubyVM::Shape` that is for debug from RDoc totallyNobuyoshi Nakada
2024-11-21Annotate anonymous mmapKunshan Wang
Use PR_SET_VMA_ANON_NAME to set human-readable names for anonymous virtual memory areas mapped by `mmap()` when compiled and run on Linux 5.17 or higher. This makes it convenient for developers to debug mmap. Notes: Merged: https://github.com/ruby/ruby/pull/12119
2024-10-03Rename size_pool -> heapMatt Valentine-House
Now that we've inlined the eden_heap into the size_pool, we should rename the size_pool to heap. So that Ruby contains multiple heaps, with different sized objects. The term heap as a collection of memory pages is more in memory management nomenclature, whereas size_pool was a name chosen out of necessity during the development of the Variable Width Allocation features of Ruby. The concept of size pools was introduced in order to facilitate different sized objects (other than the default 40 bytes). They wrapped the eden heap and the tomb heap, and some related state, and provided a reasonably simple way of duplicating all related concerns, to provide multiple pools that all shared the same structure but held different objects. Since then various changes have happend in Ruby's memory layout: * The concept of tomb heaps has been replaced by a global free pages list, with each page having it's slot size reconfigured at the point when it is resurrected * the eden heap has been inlined into the size pool itself, so that now the size pool directly controls the free_pages list, the sweeping page, the compaction cursor and the other state that was previously being managed by the eden heap. Now that there is no need for a heap wrapper, we should refer to the collection of pages containing Ruby objects as a heap again rather than a size pool Notes: Merged: https://github.com/ruby/ruby/pull/11771
2024-08-16Parenthesize macro argumentsNobuyoshi Nakada
Notes: Merged: https://github.com/ruby/ruby/pull/11389