Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 2e141997725b
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 1e2282afcb44
Choose a head ref
  • 4 commits
  • 3 files changed
  • 2 contributors

Commits on Jan 4, 2016

  1. Add spec for #3576

    smellsblue committed Jan 4, 2016
    Copy the full SHA
    201d853 View commit details

Commits on Jan 6, 2016

  1. Move spec to new file and add additional related specs

    Revert changes to construction_spec.rb
    smellsblue committed Jan 6, 2016
    Copy the full SHA
    992fbc8 View commit details
  2. Copy the full SHA
    c32266c View commit details

Commits on Jan 11, 2016

  1. Merge pull request #3581 from smellsblue/cache-constructed-proxies

    Cache proxies of newly constructed Java objects
    kares committed Jan 11, 2016
    Copy the full SHA
    1e2282a View commit details
25 changes: 15 additions & 10 deletions core/src/main/java/org/jruby/java/invokers/ConstructorInvoker.java
Original file line number Diff line number Diff line change
@@ -55,7 +55,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
JavaConstructor constructor = (JavaConstructor) findCallable(self, name, args, args.length);

final Object[] convertedArgs = convertArguments(constructor, args);
proxy.setObject( constructor.newInstanceDirect(context, convertedArgs) );
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, convertedArgs));

return self;
}
@@ -66,7 +66,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
JavaProxy proxy = castJavaProxy(self);
JavaConstructor constructor = (JavaConstructor) findCallableArityZero(self, name);

proxy.setObject(constructor.newInstanceDirect(context));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context));

return self;
}
@@ -79,7 +79,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
final Class<?>[] paramTypes = constructor.getParameterTypes();
Object cArg0 = arg0.toJava(paramTypes[0]);

proxy.setObject(constructor.newInstanceDirect(context, cArg0));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, cArg0));

return self;
}
@@ -93,7 +93,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
Object cArg0 = arg0.toJava(paramTypes[0]);
Object cArg1 = arg1.toJava(paramTypes[1]);

proxy.setObject(constructor.newInstanceDirect(context, cArg0, cArg1));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, cArg0, cArg1));

return self;
}
@@ -108,7 +108,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
Object cArg1 = arg1.toJava(paramTypes[1]);
Object cArg2 = arg2.toJava(paramTypes[2]);

proxy.setObject(constructor.newInstanceDirect(context, cArg0, cArg1, cArg2));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, cArg0, cArg1, cArg2));

return self;
}
@@ -131,7 +131,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
convertedArgs[i] = intermediate[i].toJava(paramTypes[i]);
}

proxy.setObject(constructor.newInstanceDirect(context, convertedArgs));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, convertedArgs));

return self;
}
@@ -148,7 +148,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
final Class<?>[] paramTypes = constructor.getParameterTypes();
Object cArg0 = proc.toJava(paramTypes[0]);

proxy.setObject(constructor.newInstanceDirect(context, cArg0));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, cArg0));

return self;
}
@@ -166,7 +166,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
Object cArg0 = arg0.toJava(paramTypes[0]);
Object cArg1 = proc.toJava(paramTypes[1]);

proxy.setObject(constructor.newInstanceDirect(context, cArg0, cArg1));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, cArg0, cArg1));

return self;
}
@@ -185,7 +185,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
Object cArg1 = arg1.toJava(paramTypes[1]);
Object cArg2 = proc.toJava(paramTypes[2]);

proxy.setObject(constructor.newInstanceDirect(context, cArg0, cArg1, cArg2));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, cArg0, cArg1, cArg2));

return self;
}
@@ -205,10 +205,15 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
Object cArg2 = arg2.toJava(paramTypes[2]);
Object cArg3 = proc.toJava(paramTypes[3]);

proxy.setObject(constructor.newInstanceDirect(context, cArg0, cArg1, cArg2, cArg3));
setAndCacheProxyObject(context, proxy, constructor.newInstanceDirect(context, cArg0, cArg1, cArg2, cArg3));

return self;
}
return call(context, self, clazz, name, arg0, arg1, arg2);
}

private void setAndCacheProxyObject(ThreadContext context, JavaProxy proxy, Object object) {
proxy.setObject(object);
context.runtime.getJavaSupport().getObjectProxyCache().put(object, proxy);
}
}
21 changes: 21 additions & 0 deletions spec/java_integration/fixtures/CachedInJava.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package java_integration.fixtures;

public class CachedInJava {
private static final ThreadLocal<CachedInJava> lastInstance = new ThreadLocal<CachedInJava>();

public CachedInJava() {
lastInstance.set(this);
}

public CachedInJava newInstanceFromInstance() {
return new CachedInJava();
}

public static CachedInJava newInstanceFromStatic() {
return new CachedInJava();
}

public static CachedInJava getLastInstance() {
return lastInstance.get();
}
}
31 changes: 31 additions & 0 deletions spec/java_integration/object/singleton_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require File.dirname(__FILE__) + "/../spec_helper"

java_import "java_integration.fixtures.CachedInJava"

describe "A singleton method added to a Java object from Ruby" do
before(:all) { CachedInJava.__persistent__ = true }

it "caches the proxy when directly constructed" do
object = CachedInJava.new
def object.answer; 42; end
expect(object.answer).to eq(42)
expect(CachedInJava.last_instance).to eq(object)
expect(CachedInJava.last_instance.answer).to eq(42)
end

it "caches the proxy when retrieved from a Java instance method" do
object = CachedInJava.new.new_instance_from_instance
def object.answer; 42; end
expect(object.answer).to eq(42)
expect(CachedInJava.last_instance).to eq(object)
expect(CachedInJava.last_instance.answer).to eq(42)
end

it "caches the proxy when retrieved from a Java static method" do
object = CachedInJava.new_instance_from_static
def object.answer; 42; end
expect(object.answer).to eq(42)
expect(CachedInJava.last_instance).to eq(object)
expect(CachedInJava.last_instance.answer).to eq(42)
end
end