Skip to content
Browse files

A fix for that pesky on-again, off-again failure in test_cache_map_le…

…ak. It now will hold a reference to the transient "self" until the class definition is complete.

git-svn-id: http://svn.codehaus.org/jruby/trunk/jruby@5471 961051c9-f516-0410-bf72-c9f7e237a7b7
  • Loading branch information...
1 parent 2a54be5 commit ebc0f386d44003960a538a7f43aa321a370dc66e @headius headius committed Jan 3, 2008
Showing with 33 additions and 2 deletions.
  1. +12 −2 src/org/jruby/compiler/impl/StandardASMCompiler.java
  2. +21 −0 test/test_singleton_with_transient.rb
View
14 src/org/jruby/compiler/impl/StandardASMCompiler.java
@@ -2063,7 +2063,7 @@ public void call(MethodCompiler context) {
} else {
methodCompiler.loadRuntime();
- receiverCallback.call(methodCompiler);
+ methodCompiler.loadSelf();
methodCompiler.invokeUtilityMethod("getSingletonClass", cg.sig(RubyClass.class, cg.params(Ruby.class, IRubyObject.class)));
}
@@ -2088,6 +2088,9 @@ public void call(MethodCompiler context) {
Label after = new Label();
Label noException = new Label();
methodCompiler.method.trycatch(start, end, after, null);
+
+ // save a reference to self, for singleton 'attached' to prevent GC
+ methodCompiler.loadSelf();
methodCompiler.beginClass(bodyPrep, staticScope);
@@ -2099,6 +2102,9 @@ public void call(MethodCompiler context) {
methodCompiler.loadThreadContext();
methodCompiler.invokeThreadContext("postCompiledClass", cg.sig(Void.TYPE, cg.params()));
+ // pop extra self
+ methodCompiler.method.pop();
+
methodCompiler.method.go_to(noException);
methodCompiler.method.label(after);
@@ -2114,7 +2120,11 @@ public void call(MethodCompiler context) {
// prepare to call class definition method
method.aload(THIS);
loadThreadContext();
- loadSelf();
+ if (receiverCallback == null) {
+ loadSelf();
+ } else {
+ receiverCallback.call(this);
+ }
method.getstatic(cg.p(IRubyObject.class), "NULL_ARRAY", cg.ci(IRubyObject[].class));
method.getstatic(cg.p(Block.class), "NULL_BLOCK", cg.ci(Block.class));
View
21 test/test_singleton_with_transient.rb
@@ -0,0 +1,21 @@
+require 'test/unit'
+
+# In rare cases where a singleton is constructed out of an immediate,
+# the object can be GCed before the class is completely defined since
+# 'attached' is now a weakref. This test causes that to happen in
+# most runs, and should ensure we don't regress.
+class TestSingletonWithTransient < Test::Unit::TestCase
+ def test_transient
+ assert_nothing_raised do
+ class << 'foo'
+ x = 0
+ while x < 10
+ GC.start
+ def foo; end
+ x += 1
+ end
+ end
+ end
+ end
+end
+

0 comments on commit ebc0f38

Please sign in to comment.
Something went wrong with that request. Please try again.