object_id took the VM lock for every shareable object in multi-Ractor mode, even
when the object already had an id.
Kernel#hash reaches object_id through rb_obj_hash, so a shareable T_DATA such as
an Encoding, a Ractor or a Ractor::Port used as a Hash key serialised every
lookup across Ractors.
In this commit we make generic_field_set copy the fields of a shareable object
in multi-Ractor mode, and publish the new fields_obj of a T_DATA with an atomic
write.
```ruby
t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
ractors = 4.times.map do
Ractor.new do
h = { Encoding::UTF_8 => 1 }
1_000_000.times { h[Encoding::UTF_8] }
end
end
ractors.each(&:join)
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - t
puts "#{elapsed.round(2)}s"
```
I ran this 3 times before this patch and after and saw
before: 0.58s 0.61s 0.64s
after: 0.05s 0.05s 0.05s