Alex: I didn't realize your reduction actually included a very simple version...I should have read it more carefully.
Based on your reduction3, I have a trivial reduced case:
../jruby-1.4.0/bin/jruby -e "def foo(value, expected); Object; blah = value.send(:=~, expected); end; foo('foo', /foo/)"
The problem here is that the compiler optimization to eliminate local scopes does not do so for "send". Normally, it only detects methods known to set or get $, like the literal = method itself. When you call those methods via send, it does not see them, and therefore does not prepare a scope for them. It does not always fire because often the calling method does have a scope, and the backref ends up getting set there.
The constant lookup here is what triggers the error. A method that does not appear to set or get $~ but does access a constant gets a DummyDynamicScope just for constant-scoping purposes. This results in the method having a scope, but a scope that refuses to accept $~, so it errors out.
This is currently hard to fix without also causing a deoptimization for any methods doing .send, which is very heavily used for metaprogrammed code. I do have, in theory, a better way to handle backref logic; but I have not had spare cycles to try to put it in place.
The temporary fix is not great, because it masks two bugs: the first is the fact that we're not properly preparing for $~ when you use send, and the second is that we're potentially overwriting a previous call's $~ when no constant is present to trigger the error.
Not sure how to deal with this at the moment. $~ sucks.