summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-09-25 03:19:27 +0900
committerKoichi Sasada <ko1@atdot.net>2020-09-25 12:52:53 +0900
commit52865263467b48c0f5af6d9548972dd1f9e5bee1 (patch)
treee3f9292d6cdba7c2746f8eef9c69adb001d465b9
parentfde136152eacca454bfb978347abfa67bd73ac4d (diff)
frozen T_OBJECT can be shareable.
If an T_OBJECT object is frozen and all ivars are shareable, the object should be shareable.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3575
-rw-r--r--bootstraptest/test_ractor.rb27
-rw-r--r--ractor.c23
2 files changed, 50 insertions, 0 deletions
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index b6f00de515..c693a9c496 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -424,6 +424,33 @@ assert_equal "[[[1, true], [:sym, true], [:xyzzy, true], [\"frozen\", true], " \
[sr, ur].inspect
}
+# frozen Objects are shareable
+assert_equal [false, true, false].inspect, %q{
+ class C
+ def initialize freeze
+ @a = 1
+ @b = :sym
+ @c = 'frozen_str'
+ @c.freeze if freeze
+ @d = true
+ end
+ end
+
+ def check obj1
+ obj2 = Ractor.new obj1 do |obj|
+ obj
+ end.take
+
+ obj1.object_id == obj2.object_id
+ end
+
+ results = []
+ results << check(C.new(true)) # false
+ results << check(C.new(true).freeze) # true
+ results << check(C.new(false).freeze) # false
+}
+
+
# move example2: String
# touching moved object causes an error
assert_equal 'hello world', %q{
diff --git a/ractor.c b/ractor.c
index a7e588a9d8..fbc9192af8 100644
--- a/ractor.c
+++ b/ractor.c
@@ -1776,6 +1776,22 @@ rb_ractor_shareable_p_hash_i(VALUE key, VALUE value, VALUE arg)
return ST_CONTINUE;
}
+static bool
+ractor_obj_ivars_shareable_p(VALUE obj)
+{
+ uint32_t len = ROBJECT_NUMIV(obj);
+ VALUE *ptr = ROBJECT_IVPTR(obj);
+
+ for (uint32_t i=0; i<len; i++) {
+ VALUE val = ptr[i];
+ if (val != Qundef && !rb_ractor_shareable_p(ptr[i])) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
MJIT_FUNC_EXPORTED bool
rb_ractor_shareable_p_continue(VALUE obj)
{
@@ -1826,6 +1842,13 @@ rb_ractor_shareable_p_continue(VALUE obj)
return false;
}
}
+ case T_OBJECT:
+ if (RB_OBJ_FROZEN_RAW(obj) && ractor_obj_ivars_shareable_p(obj)) {
+ goto shareable;
+ }
+ else {
+ return false;
+ }
default:
return false;
}