Data#initialize copied the member list on every call to find the missing keywords, then cleared the given ones. A byte per member is enough to track what was given, and the member list is only needed to build the error message, so look i...shia (Sangyong Sim)
struct_ivar_get caches a member list found on a superclass into the subclass with rb_ivar_set. The ID has no "@", so it skips the Ractor ownership check, and a Ractor that does not own the class ends up writing class fields concurrently ...shia (Sangyong Sim)
3rd PR is here. [Track the given members of Data#initialize without copying them](https://github.com/ruby/ruby/pull/19581) Before digging into where to store the members, I'm going to look into the ISEQ approach first.shia (Sangyong Sim)
Data.new turned positional arguments into a keyword Hash and called initialize with it. When initialize is the default Data#initialize and every member is given, that call can only store the members and freeze the instance, so do that di...shia (Sangyong Sim)
Eregon, Thanks for your comments. I would like to go that way too if possible. But as you said, generating ISEQs needs a careful look at whether the code stays maintainable, and at other side effects. So for now, I will keep working on t...shia (Sangyong Sim)
struct_alloc() sizes an instance by the member count of its class, so the instance's own length can be used instead of looking the hidden __members__ ivar up on the class again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anth...shia (Sangyong Sim)
## Summary Struct and Data are slower to create and to operate on than a hand-written class that does the same job. Struct / Data are usually chosen because people expect them to be lightweight value objects, yet once they sit on a h...shia (Sangyong Sim)
ruby -v: ruby 4.0.6 (2026-07-14 revision 03b6d3f889) +PRISM [x86_64-linux] Also reproduced on 4.0.1 and on master (3600d410ad, 2026-09-04). Not reproduced on 3.4.9. ## Summary With YJIT or ZJIT enabled, this sequence crashes the p...shia (Sangyong Sim)