summaryrefslogtreecommitdiff
path: root/shape.c
AgeCommit message (Collapse)Author
2025-12-03YJIT: Pass class and shape ID directly instead of objectMax Bernstein
2025-12-03Move imemo fields check out of shape_get_nextMax Bernstein
Not every caller (for example, YJIT) actually needs to pass the object. YJIT (and, in the future, ZJIT) only need to pass the class.
2025-12-03Remove spurious obj != klass check in shape_get_nextMax Bernstein
This should never be true. I added an `rb_bug` in case it was and it wasn't true in any of btest or test-all. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2025-12-03Handle NEWOBJ tracepoints settings fieldsJean Boussier
[Bug #21710] - struct.c: `struct_alloc` It is possible for a `NEWOBJ` tracepoint call back to write fields into a newly allocated object before `struct_alloc` had the time to set the `RSTRUCT_GEN_FIELDS` flags and such. Hence we can't blindly initialize the `fields_obj` reference to `0` we first need to check no fields were added yet. - object.c: `rb_class_allocate_instance` Similarly, if a `NEWOBJ` tracepoint tries to set fields on the object, the `shape_id` must already be set, as it's required on T_OBJECT to know where to write fields. `NEWOBJ_OF` had to be refactored to accept a `shape_id`.
2025-11-07renaming internal data structures and functions from namespace to boxSatoshi Tagomori
2025-08-28rb_ivar_delete: allow complex transitionJean Boussier
`rb_ivar_delete` would force a new shape to be created. And in the case of a shape exhaustion, it wouldn't handle T_CLASS/T_MODULE correctly.
2025-08-27Replace ROBJECT_EMBED by ROBJECT_HEAPJean Boussier
The embed layout is way more common than the heap one, especially since WVA. I think it makes for more readable code to inverse the flag.
2025-08-26Ensure T_OBJECT and T_IMEMO/fields have identical layoutJean Boussier
2025-08-21Remove unused SPECIAL_CONST_SHAPE_IDÉtienne Barrié
Its usage was removed in 306d50811dd060d876d1eb364a0d5e6106f5e4f1.
2025-08-18Don't allow looking at the shape ID of immediates (#14266)Max Bernstein
It only makes sense for heap objects.
2025-08-18Add missing writebarrier on complex obj dupJohn Hawthorn
When we dup a complex object we need to issue a writebarrier_remember on the new object. This was caught by wbcheck inside the rubygems test suite. Co-authored-by: Aaron Patterson <tenderlove@ruby-lang.org>
2025-08-13imemo_fields: store owner object in RBasic.klassJean Boussier
It is much more convenient than storing the klass, especially when dealing with `object_id` as it allows to update the id2ref table without having to dereference the owner, which may be garbage at that point.
2025-08-07Convert `VM/shape_tree` to use `rb_gc_mark_and_move`Jean Boussier
The `p->field = rb_gc_location(p->field)` isn't ideal because it means all references are rewritten on compaction, regardless of whether the referenced object has moved. This isn't good for caches nor for Copy-on-Write. `rb_gc_mark_and_move` avoid needless writes, and most of the time allow to have a single function for both marking and updating references.
2025-08-01Fix rb_shape_transition_object_id transition to TOO_COMPLEXJean Boussier
If `get_next_shape_internal` fail to return a shape, we must transitiont to a complex shape. `shape_transition_object_id` mistakenly didn't. Co-Authored-By: Peter Zhu <peter@peterzhu.ca>
2025-07-09Avoid concurrently overflowing of shape_idJohn Hawthorn
Previously it was possible for two atomic increments of next_shape_id running concurrently to overflow MAX_SHAPE_ID. For this reason we need to do the test atomically with the allocation in shape_alloc returning NULL. This avoids overflowing next_shape_id by repeatedly attempting a CAS. Alternatively we could have allowed incrementing past MAX_SHAPE_ID and then clamping in rb_shapes_count, but this seems simpler.
2025-07-09Always use atomics to get the shape countJohn Hawthorn
When sharing between threads we need both atomic reads and writes. We probably didn't need to use this in some cases (where we weren't running in multi-ractor mode) but I think it's best to be consistent.
2025-07-09Fix off-by-one in shape_tree_mark/shape_tree_compactJohn Hawthorn
This was using < so subtract one from the last shape id would have us miss the last inserted shape. I think this is unlikely to have caused issues because I don't think the newest shape will ever have edges. We do need to use `- 1` because otherwise RSHAPE wraps around and returns the root shape.
2025-07-04Remove unused src param from rb_shape_copy_fieldsJohn Hawthorn
2025-06-26variable.c: Refactor `generic_field_set` / `generic_ivar_set`Jean Boussier
These two functions are very similar, they can share most of their logic.
2025-06-25Move RUBY_ATOMIC_VALUE_LOAD to ruby_atomic.hPeter Zhu
Deduplicates RUBY_ATOMIC_VALUE_LOAD by moving it to ruby_atomic.h.
2025-06-24Cleanup and document `shape_id_t` layoutJean Boussier
2025-06-24Reduce exposure of FL_FREEZEJean Boussier
The `FL_FREEZE` flag is redundant with `SHAPE_ID_FL_FROZEN`, so ideally it should be eliminated in favor of the later. Doing so would eliminate the risk of desync between the two, but also solve the problem of the frozen status being global in namespace context (See Bug #21330).
2025-06-17Rename `imemo_class_fields` -> `imemo_fields`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13626
2025-06-15Fix typo in error message for shape_id verificationydah
Notes: Merged: https://github.com/ruby/ruby/pull/13621
2025-06-13Get rid of FL_EXIVARJean Boussier
Now that the shape_id gives us all the same information, it's no longer needed. Notes: Merged: https://github.com/ruby/ruby/pull/13612
2025-06-13Use the `shape_id` rather than `FL_EXIVAR`Jean Boussier
We still keep setting `FL_EXIVAR` so that `rb_shape_verify_consistency` can detect discrepancies. Notes: Merged: https://github.com/ruby/ruby/pull/13612
2025-06-13Enforce consistency between shape_id and FL_EXIVARJean Boussier
The FL_EXIVAR is a bit redundant with the shape_id. Now that the `shape_id` is embedded in all objects on all archs, we can cheaply check if an object has any fields with a simple bitmask. Notes: Merged: https://github.com/ruby/ruby/pull/13612
2025-06-13Suppress unused-variable warningNobuyoshi Nakada
2025-06-13Add SHAPE_ID_HAS_IVAR_MASK for quick ivar checkJean Boussier
This allow checking if an object has ivars with just a shape_id mask. Notes: Merged: https://github.com/ruby/ruby/pull/13606
2025-06-13Suppress unused-variable warningNobuyoshi Nakada
2025-06-13shape.c: cleanup unused IDsJean Boussier
id_frozen and id_t_object are no longer used. id_object_id no longer need to be exposed. Notes: Merged: https://github.com/ruby/ruby/pull/13605
2025-06-12Allocate `rb_shape_tree` staticallyJean Boussier
There is no point allocating it during init, it adds a useless indirection. Notes: Merged: https://github.com/ruby/ruby/pull/13596
2025-06-12Get rid of GET_SHAPE_TREE()Jean Boussier
It's a useless indirection. Notes: Merged: https://github.com/ruby/ruby/pull/13596
2025-06-12Get rid of `rb_shape_lookup`Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13596
2025-06-12shape.h: make RSHAPE static inlineJean Boussier
Since the shape_tree_ptr is `extern` it should be possible to fully inline `RSHAPE`. Notes: Merged: https://github.com/ruby/ruby/pull/13596
2025-06-12Fix class instance variable inside namespacesJean Boussier
Now that classes fields are delegated to an object with its own shape_id, we no longer need to mark all classes as TOO_COMPLEX. Notes: Merged: https://github.com/ruby/ruby/pull/13595
2025-06-12Turn `rb_classext_t.fields` into a T_IMEMO/class_fieldsJean Boussier
This behave almost exactly as a T_OBJECT, the layout is entirely compatible. This aims to solve two problems. First, it solves the problem of namspaced classes having a single `shape_id`. Now each namespaced classext has an object that can hold the namespace specific shape. Second, it open the door to later make class instance variable writes atomics, hence be able to read class variables without locking the VM. In the future, in multi-ractor mode, we can do the write on a copy of the `fields_obj` and then atomically swap it. Considerations: - Right now the `RClass` shape_id is always synchronized, but with namespace we should likely mark classes that have multiple namespace with a specific shape flag. Notes: Merged: https://github.com/ruby/ruby/pull/13411
2025-06-11Refactor the last references to `rb_shape_t`Jean Boussier
The type isn't opaque because Ruby isn't often compiled with LTO, so for optimization purpose it's better to allow as much inlining as possible. However ideally only `shape.c` and `shape.h` should deal with the actual struct, and everything else should just deal with opaque `shape_id_t`. Notes: Merged: https://github.com/ruby/ruby/pull/13586
2025-06-11shape.c: Fix rb_bug call to use correct format for size_tJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13583
2025-06-10Fix RubyVM::Shape.transition_treeÉtienne Barrié
Notes: Merged: https://github.com/ruby/ruby/pull/13578
2025-06-07Stop pinning shape edgesJean Boussier
Now that `rb_shape_traverse_from_new_root` has been eliminated there's no longer any reason to pin these objects, because we no longer need to traverse shapes downward during compaction. Notes: Merged: https://github.com/ruby/ruby/pull/13556
2025-06-07Simplify `rb_gc_rebuild_shape`Jean Boussier
Now that there no longer multiple shape roots, all we need to do when moving an object from one slot to the other is to update the `heap_index` part of the shape_id. Since this never need to create a shape transition, it will always work and never result in a complex shape. Notes: Merged: https://github.com/ruby/ruby/pull/13556
2025-06-07Get rid of rb_shape_t.heap_idJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13556
2025-06-07Get rid of SHAPE_T_OBJECTJean Boussier
Now that we have the `heap_index` in shape flags we no longer need `T_OBJECT` shapes. Notes: Merged: https://github.com/ruby/ruby/pull/13556
2025-06-07shape.c: assert we're not returning INVALID_SHAPE_ID.Jean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13556
2025-06-07shape.c: ensure heap_index is consistent for complex shapesJean Boussier
Notes: Merged: https://github.com/ruby/ruby/pull/13556
2025-06-07Replicate `heap_index` in shape_id flags.Jean Boussier
This is preparation to getting rid of `T_OBJECT` transitions. By first only replicating the information it's easier to ensure consistency. Notes: Merged: https://github.com/ruby/ruby/pull/13556
2025-06-06Add missing lock around `redblack_cache_ancestors`Jean Boussier
This used to be protected because all shape code was under a lock, but now that the shape tree is lock-free we still need to lock around the red-black cache. Co-Authored-By: Luke Gruber <luke.gruber@shopify.com> Notes: Merged: https://github.com/ruby/ruby/pull/13552
2025-06-06shape.c: match capacity growth with T_OBJECT embedded sizesJean Boussier
This helps with getting with of `SHAPE_T_OBJECT`, by ensuring that transitions will have capacities that match the next embed size. Notes: Merged: https://github.com/ruby/ruby/pull/13548
2025-06-06shape.c: Fix improperly named routineJean Boussier
Meant to be `transition_complex` not `transition_frozen`.