Use pure-Ruby Fiber-based Enumerator#next #5672
This code has been passed around multiple implementations as a
There are a few caveats to this migration:
This code is modified from TruffleRuby's copy of Rubinius's code,
I am proposing this for 9.2.7 because it seems like mostly a lateral move, although there were some tag changes. There are at least two todos before release:
The text was updated successfully, but these errors were encountered:
This code has been passed around multiple implementations as a pure-Ruby version of Enumerator#next that just uses fibers. We have had many issues with the separate fiber-like impl we used for Enumerator#next, and the logical path forward is to unify that with Fiber via this code. There are a few caveats to this migration: * Three new introduced failures appear to be shared with other impls using this logic (rbx, truffleruby). * This commit breaks the fast-path Array logic for Enumerator#next so it's always going through a thread. However the protocol here would allow us to implement #to_generator on any object, which should make it possible to short-circuit more easily (in Ruby!). * I have not measured performance. However the logic surrounding the Fiber calls should not be particularly heavy. * I have not vetted the cleanup side of this, except to confirm that this implementation seems about as good at jruby#5671 in that it does appear to GC, but for a high-churn benchmark it eventually collapses without explicit GCs. So...no worse? This code is modified from TruffleRuby's copy of Rubinius's code, with Rubinius's license being very liberal and TruffleRuby's being identical to JRuby's.
The original implementation was based on Enumerator code from Rubinius. However in Rubinius, the Fiber thread does not root objects any deeper than to the Fiber object itself. In order to make this not leak threads, all state shared between the Fiber and the Enumerator is passed in a separate State object. This also includes minor tweaks, like fixing the to_generator logic (needed for efficient non-fiber generators), and using the Fiber.yield method directly as the body of the iteration, so no intermediate block state is necessary. This last change should reduce the cost of the iteration loop close to what it was in the Java-based Enumerator#next.