summaryrefslogtreecommitdiff
path: root/include/ruby/internal/core
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2025-05-19 12:38:49 +0200
committerJean Boussier <[email protected]>2025-06-02 17:49:53 +0200
commite9fd44dd724b165a7ea1dd9822fdb65d80907c06 (patch)
treecec80ab6e7dca86e3bcd603daf7300756a9266d0 /include/ruby/internal/core
parentcbd49ecbbe870c934b2186e3896dd43033313332 (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é <[email protected]>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/13441
Diffstat (limited to 'include/ruby/internal/core')
-rw-r--r--include/ruby/internal/core/rtypeddata.h3
1 files changed, 1 insertions, 2 deletions
diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h
index b576be779f..edf482267a 100644
--- a/include/ruby/internal/core/rtypeddata.h
+++ b/include/ruby/internal/core/rtypeddata.h
@@ -471,8 +471,7 @@ RBIMPL_SYMBOL_EXPORT_END()
/**
* Identical to #TypedData_Wrap_Struct, except it allocates a new data region
* internally instead of taking an existing one. The allocation is done using
- * ruby_calloc(). Hence it makes no sense for `data_type->function.dfree` to
- * be anything other than ::RUBY_TYPED_DEFAULT_FREE.
+ * ruby_calloc().
*
* @param klass Ruby level class of the object.
* @param type Type name of the C struct.