Skip to content

Commit

Permalink
Fix #1980: Do not attempt to reuse IRReturnJump/IRBreakJump
Browse files Browse the repository at this point in the history
* Removed dump opt from b26a85e.
* Added a regression spec.
  • Loading branch information
subbuss committed Sep 17, 2014
1 parent e3d3037 commit 57222ee
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 30 deletions.
16 changes: 1 addition & 15 deletions core/src/main/java/org/jruby/ir/runtime/IRBreakJump.java
Expand Up @@ -4,9 +4,6 @@
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.builtin.IRubyObject;

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;

public class IRBreakJump extends RuntimeException implements Unrescuable {
public DynamicScope scopeToReturnTo;
public IRubyObject breakValue;
Expand All @@ -15,19 +12,8 @@ public class IRBreakJump extends RuntimeException implements Unrescuable {

private IRBreakJump() {}

// See https://jira.codehaus.org/browse/JRUBY-6523
// Dont use static threadlocals because they leak classloaders.
// Instead, use soft/weak references so that GC can collect these.

private static ThreadLocal<Reference<IRBreakJump>> threadLocalBJ = new ThreadLocal<Reference<IRBreakJump>>();

public static IRBreakJump create(DynamicScope scopeToReturnTo, IRubyObject rv) {
IRBreakJump bj;
Reference<IRBreakJump> bjRef = threadLocalBJ.get();
if (bjRef == null || (bj = bjRef.get()) == null) {
bj = new IRBreakJump();
threadLocalBJ.set(new SoftReference<IRBreakJump>(bj));
}
IRBreakJump bj = new IRBreakJump();
bj.scopeToReturnTo = scopeToReturnTo;
bj.breakValue = rv;
bj.caughtByLambda = false;
Expand Down
16 changes: 1 addition & 15 deletions core/src/main/java/org/jruby/ir/runtime/IRReturnJump.java
Expand Up @@ -3,28 +3,14 @@
import org.jruby.exceptions.Unrescuable;
import org.jruby.runtime.DynamicScope;

import java.lang.ref.Reference;
import java.lang.ref.SoftReference;

public class IRReturnJump extends RuntimeException implements Unrescuable {
public DynamicScope methodToReturnFrom;
public Object returnValue;

private IRReturnJump() {}

// See https://jira.codehaus.org/browse/JRUBY-6523
// Dont use static threadlocals because they leak classloaders.
// Instead, use soft/weak references so that GC can collect these.

private static ThreadLocal<Reference<IRReturnJump>> threadLocalRJ = new ThreadLocal<Reference<IRReturnJump>>();

public static IRReturnJump create(DynamicScope scope, Object rv) {
IRReturnJump rj;
Reference<IRReturnJump> rjRef = threadLocalRJ.get();
if (rjRef == null || (rj = rjRef.get()) == null) {
rj = new IRReturnJump();
threadLocalRJ.set(new SoftReference<IRReturnJump>(rj));
}
IRReturnJump rj = new IRReturnJump();
rj.methodToReturnFrom = scope;
rj.returnValue = rv;
return rj;
Expand Down
16 changes: 16 additions & 0 deletions spec/regression/GH-1980_multiple_nonlocal_returns_in_flight.rb
@@ -0,0 +1,16 @@
# https://github.com/jruby/jruby/issues/1980

describe 'Multiple non-local returns in-flight' do
it 'should not collide' do
o = Object.new
def o.bar; yield; end
def o.baz; bar { return 5 }; end
def o.foo
bar { return 10 }
ensure
baz
end

expect(foo).to eq(10)
end
end

0 comments on commit 57222ee

Please sign in to comment.