Koichi Sasada, a Ruby core developer, shares slides and papers on the Ruby VM, garbage collection, and concurrency.
HN links it for his talks on Guilds (later Ractors), the Ruby 3 concurrency design, and Ruby VM and memory work.
> Your example is just showing that the extended module only appears in the instance's singleton class, this has nothing to do with method cache. It's how the method cache is implemented that matters.
The method cache works by invalidating anything below the class(es) whose methods have changed on the ancestor chain.
You're right that it can't be seen from user code, but if you take the implementers at their word about how it works, then this should be a perfectly convincing demonstration.
Or, if you don't believe me, read the source yourself:
https://github.com/ruby/ruby/blob/ba6b0acdb6c371f9f7150bed6f555c7f34fe3781/vm_insnhelper.c#L823-L841
https://github.com/ruby/ruby/blob/1aa54bebaf274bc08e72f9ad3854c7ad592c344a/vm_method.c#L78-L94
The part that clears the class hierarchy is here:
https://github.com/ruby/ruby/blob/1aa54bebaf274bc08e72f9ad3854c7ad592c344a/vm_method.c#L56-L61
Alternatively, see Koichi's presentation at RubyKaiga:
http://www.atdot.net/~ko1/activities/RubyKaigi2013-ko1.pdf
And the big caveat to this simple modification is that, if done naively, previously marked objects may become the sole referencers of non-garbage without being re-enumerated - potentially leading to the garbage-collection of non-garbage, which would be a serious bug.
To fix this, you might have the live code that runs in-between the partial mark+sweeps mark objects to be re-swept as it runs. This adds overhead and complexity, of course. This code is apparently called write barriers by Ruby's GC:
https://jemma.dev/blog/gc-incremental
https://blog.peterzhu.ca/notes-on-ruby-gc/
http://www.atdot.net/~ko1/activities/rgengc_ismm.pdf
I'm left wondering what the overhead of such greylisting / write barriers are, compared to the reference counting overhead mentioned by shwestrick in the "Reference count, don't garbage collect" thread:
https://news.ycombinator.com/item?id=32277088
If anyone is interested in digging a bit deeper into this.
"Progress report of 'Ruby 3 Concurrency'" (2018)
http://atdot.net/~ko1/activities/2018_RubyElixirConfTaiwan.pdf
"Parallel programming in Ruby3 with Guild" (2018)
http://atdot.net/~ko1/activities/2018_rubyconf2018.pdf
"Ruby 3 Concurrency" (2016)
http://atdot.net/~ko1/activities/2016_rubyconf.pdf
A bit off-topic but still interesting, it talks about the goal of reaching over 100k threads to support a massive network of concurrent connections.
"MaNy Project" (2022)
http://atdot.net/~ko1/activities/2022_rubykaigi2022.pdf
That’s the plan with Guilds: http://www.atdot.net/~ko1/activities/2018_rubyconf2018.pdf
These are the slides for Koichi Sasada’s RubyConf 2018 (last week) talk updating the community on his progress in the design and implementation of Guilds.
Surprising that the author isn’t aware of this planned CRuby feature announced in 2016. I wrote about it then: https://olivierlacan.com/posts/concurrency-in-ruby-3-with-guilds/
Take this with a grain of salt of course because the design has clearly changed since then and I need to upgrade my post or do a follow-up.
On the "Ruby Kaigi" presentation (http://www.atdot.net/~ko1/activities/2015_RubyKaigi2015.pdf), Koichi Sasada states that Matz doesn't like the automatic compilation of source files a la Python, which automatically generates .pyc files.
Why is this? I understand the inconvenience of having lots of compiled files in your deployment structure but I guess having a static compile phase would be worse. Any opinions on this?
I think there was a miscommunication in the interview. He meant load/parse/compile time. See http://www.atdot.net/~ko1/activities/2016_railsconf_pub.pdf