At first glance this seems too simple. Compare it to JavaScript JITs, which IIRC can compile hot spots even in functions that are only called a few times (e.g. those that contain heavy loops) via on-stack replacement. (Although I’ve also heard on-stack replacement called a “party trick” - more useful for optimising benchmark scores than for real code.)
But on the other hand, Ruby’s language design might help here. Idiomatic Ruby uses blocks for loop bodies - so can Ruby JITs optimise long-running loops by treating the loop body as just another function?