diff options
| author | Jean Boussier <jean.boussier@gmail.com> | 2025-05-19 12:38:49 +0200 |
|---|---|---|
| committer | Jean Boussier <jean.boussier@gmail.com> | 2025-06-02 17:49:53 +0200 |
| commit | e9fd44dd724b165a7ea1dd9822fdb65d80907c06 (patch) | |
| tree | cec80ab6e7dca86e3bcd603daf7300756a9266d0 /shape.h | |
| parent | cbd49ecbbe870c934b2186e3896dd43033313332 (diff) | |
shape.c: Implement a lock-free version of get_next_shape_internal
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
Notes:
Merged: https://github.com/ruby/ruby/pull/13441
Diffstat (limited to 'shape.h')
| -rw-r--r-- | shape.h | 4 |
1 files changed, 2 insertions, 2 deletions
@@ -42,7 +42,7 @@ extern ID ruby_internal_object_id; typedef struct redblack_node redblack_node_t; struct rb_shape { - struct rb_id_table *edges; // id_table from ID (ivar) to next shape + VALUE edges; // id_table from ID (ivar) to next shape ID edge_name; // ID (ivar) for transition from parent to rb_shape attr_index_t next_field_index; // Fields are either ivars or internal properties like `object_id` attr_index_t capacity; // Total capacity of the object with this shape @@ -75,7 +75,7 @@ typedef struct { /* object shapes */ rb_shape_t *shape_list; rb_shape_t *root_shape; - shape_id_t next_shape_id; + rb_atomic_t next_shape_id; redblack_node_t *shape_cache; unsigned int cache_size; |
