frozen T_OBJECT can be shareable.

If an T_OBJECT object is frozen and all ivars are shareable,
the object should be shareable.
This commit is contained in:
Koichi Sasada 2020-09-25 03:19:27 +09:00
Родитель fde136152e
Коммит 5286526346
2 изменённых файлов: 50 добавлений и 0 удалений

Просмотреть файл

@ -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{

Просмотреть файл

@ -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;
}