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: 1c56b3a258fc
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: d03d09e18769
Choose a head ref

Commits on Apr 23, 2015

  1. Use jnr-ffi 2.0.3 to gain ppc64le support.

    jnr/jnr-ffi#40 and related issues.
    headius committed Apr 23, 2015
    Copy the full SHA
    4752304 View commit details

Commits on Apr 24, 2015

  1. Copy the full SHA
    d77456d View commit details
  2. Copy the full SHA
    f7b8a8a View commit details
  3. Copy the full SHA
    ae2428c View commit details
  4. 1
    Copy the full SHA
    2bdfb5a View commit details
  5. remove more jruby.home properties from build

    [skip ci]
    mkristian committed Apr 24, 2015
    Copy the full SHA
    46f43bb View commit details
  6. Copy the full SHA
    e371995 View commit details
  7. Copy the full SHA
    f7d09d0 View commit details
  8. Use jnr-ffi 2.0.3 to gain ppc64le support.

    jnr/jnr-ffi#40 and related issues.
    headius committed Apr 24, 2015
    Copy the full SHA
    c815260 View commit details
  9. Merge remote-tracking branch 'origin/jruby-1_7'

    Conflicts:
    	core/src/main/java/org/jruby/javasupport/JavaSupport.java
    	core/src/main/java/org/jruby/javasupport/binding/Initializer.java
    	core/src/main/java/org/jruby/javasupport/binding/InterfaceInitializer.java
    headius committed Apr 24, 2015
    Copy the full SHA
    a1cb409 View commit details
  10. Revert "remove more jruby.home properties from build"

    This reverts commit 46f43bb.
    headius committed Apr 24, 2015
    Copy the full SHA
    6fb60a4 View commit details
  11. Copy the full SHA
    6550480 View commit details
  12. Copy the full SHA
    9f60295 View commit details
  13. Copy the full SHA
    7d07f90 View commit details

Commits on Apr 25, 2015

  1. Revert "deprecation warning when using the old __jsend! internal me…

    …thod (no longer in 9K)"
    
    This reverts commit f7b8a8a.
    
    Conflicts:
    	core/src/main/java/org/jruby/javasupport/binding/Initializer.java
    	test/test_higher_javasupport.rb
    mkristian committed Apr 25, 2015
    Copy the full SHA
    518471b View commit details
  2. Copy the full SHA
    6c23812 View commit details
  3. Copy the full SHA
    b0ee239 View commit details
  4. 3
    Copy the full SHA
    5fe5742 View commit details
  5. Copy the full SHA
    0e1fd4d View commit details
  6. 2
    Copy the full SHA
    28f9e82 View commit details
  7. Copy the full SHA
    6120ead View commit details
  8. Merge branch 'master' into truffle-head

    Conflicts:
    	truffle/src/main/java/org/jruby/truffle/nodes/RubyNode.java
    chrisseaton committed Apr 25, 2015
    Copy the full SHA
    d03d09e View commit details
Showing with 244 additions and 148 deletions.
  1. +53 −39 core/src/main/java/org/jruby/javasupport/Java.java
  2. +6 −2 core/src/main/java/org/jruby/javasupport/JavaSupport.java
  3. +46 −25 core/src/main/java/org/jruby/javasupport/JavaSupportImpl.java
  4. +0 −2 core/src/main/java/org/jruby/javasupport/binding/ClassInitializer.java
  5. +3 −0 core/src/main/java/org/jruby/javasupport/binding/Initializer.java
  6. +0 −2 core/src/main/java/org/jruby/javasupport/binding/InterfaceInitializer.java
  7. +0 −24 install/jruby.install4j
  8. +1 −5 lib/pom.rb
  9. +1 −1 lib/pom.xml
  10. +0 −4 maven/jruby-complete/pom.rb
  11. +0 −4 maven/jruby-dist/pom.rb
  12. +0 −4 maven/jruby/pom.rb
  13. +0 −4 pom.rb
  14. +0 −4 spec/truffle/tags/core/file/symlink_tags.txt
  15. +0 −12 spec/truffle/tags/core/kernel/test_tags.txt
  16. +3 −0 spec/truffle/tags/core/signal/list_tags.txt
  17. +1 −0 test/mri/excludes_truffle/TestDelegateClass.rb
  18. +1 −0 test/mri/excludes_truffle/TestNotImplement.rb
  19. +2 −0 test/mri/excludes_truffle/TestRequire.rb
  20. +1 −0 test/mri/excludes_truffle/TestString.rb
  21. +1 −0 test/mri/excludes_truffle/TestString2.rb
  22. +1 −1 test/mri_truffle.index
  23. +1 −1 tool/jt.rb
  24. +14 −9 truffle/src/main/java/org/jruby/truffle/nodes/RubyNode.java
  25. +0 −2 truffle/src/main/java/org/jruby/truffle/nodes/core/HashNodes.java
  26. +0 −2 truffle/src/main/java/org/jruby/truffle/nodes/core/ThreadNodes.java
  27. +56 −0 truffle/src/main/java/org/jruby/truffle/nodes/rubinius/ByteArrayNodes.java
  28. +14 −0 truffle/src/main/java/org/jruby/truffle/nodes/rubinius/PosixNodes.java
  29. +1 −1 truffle/src/main/java/org/jruby/truffle/nodes/rubinius/StringPrimitiveNodes.java
  30. +7 −0 truffle/src/main/java/org/jruby/truffle/runtime/RubyContext.java
  31. +30 −0 truffle/src/main/ruby/core/rubinius/common/kernel.rb
  32. +1 −0 truffle/src/main/ruby/core/shims.rb
92 changes: 53 additions & 39 deletions core/src/main/java/org/jruby/javasupport/Java.java
Original file line number Diff line number Diff line change
@@ -439,50 +439,71 @@ public static RubyModule getProxyClass(Ruby runtime, JavaClass javaClass) {
}

public static RubyModule getProxyClass(final Ruby runtime, final Class<?> clazz) {
RubyModule unfinished = runtime.getJavaSupport().getUnfinishedProxyClassCache().get(clazz).get();
if (unfinished != null) return unfinished;
RubyModule proxy = runtime.getJavaSupport().getUnfinishedProxy(clazz);
if (proxy != null) return proxy;
return runtime.getJavaSupport().getProxyClassFromCache(clazz);
}

// Only used by proxy ClassValue calculator in JavaSupport
static RubyModule createProxyClassForClass(final Ruby runtime, final Class<?> clazz) {
final JavaSupport javaSupport = runtime.getJavaSupport();

if (clazz.isInterface()) return generateInterfaceProxy(runtime, clazz);

return generateClassProxy(runtime, clazz, javaSupport);
}
RubyModule proxy;
RubyClass superClass = null;
if (clazz.isInterface()) {
proxy = (RubyModule) runtime.getJavaSupport().getJavaInterfaceTemplate().dup();
} else {
if (clazz.isArray()) {
superClass = javaSupport.getArrayProxyClass();
} else if (clazz.isPrimitive()) {
superClass = javaSupport.getConcreteProxyClass();
} else if (clazz == Object.class) {
superClass = javaSupport.getConcreteProxyClass();
} else {
// other java proxy classes added under their superclass' java proxy
superClass = (RubyClass) getProxyClass(runtime, clazz.getSuperclass());
}
proxy = RubyClass.newClass(runtime, superClass);
}

private static RubyModule generateInterfaceProxy(final Ruby runtime, final Class javaClass) {
if (!javaClass.isInterface()) {
throw runtime.newArgumentError(javaClass.toString() + " is not an interface");
// ensure proxy is visible down-thread
javaSupport.beginProxy(clazz, proxy);
try {
if (clazz.isInterface()) {
generateInterfaceProxy(runtime, clazz, proxy);
} else {
generateClassProxy(runtime, clazz, (RubyClass)proxy, superClass, javaSupport);
}
} finally {
javaSupport.endProxy(clazz);
}

RubyModule proxyModule = (RubyModule) runtime.getJavaSupport().getJavaInterfaceTemplate().dup();
return proxy;
}

private static void generateInterfaceProxy(final Ruby runtime, final Class javaClass, final RubyModule proxy) {
assert javaClass.isInterface() : "not an interface: " + javaClass;

// include any interfaces we extend
final Class<?>[] extended = javaClass.getInterfaces();
for ( int i = extended.length; --i >= 0; ) {
for (int i = extended.length; --i >= 0; ) {
RubyModule extModule = getInterfaceModule(runtime, extended[i]);
proxyModule.includeModule(extModule);
proxy.includeModule(extModule);
}
Initializer.setupProxyModule(runtime, javaClass, proxyModule);
addToJavaPackageModule(proxyModule);

return proxyModule;
Initializer.setupProxyModule(runtime, javaClass, proxy);
addToJavaPackageModule(proxy);
}

private static RubyModule generateClassProxy(Ruby runtime, Class<?> clazz, JavaSupport javaSupport) {
RubyModule proxyClass;
private static void generateClassProxy(Ruby runtime, Class<?> clazz, RubyClass proxy, RubyClass superClass, JavaSupport javaSupport) {
if (clazz.isArray()) {
proxyClass = createProxyClass(runtime, javaSupport.getArrayProxyClass(), clazz, true);
createProxyClass(runtime, proxy, clazz, true);

// FIXME: Organizationally this might be nicer in a specialized class
if ( clazz.getComponentType() == byte.class ) {
final Encoding ascii8bit = runtime.getEncodingService().getAscii8bitEncoding();

// All bytes can be considered raw strings and forced to particular codings if not 8bitascii
proxyClass.addMethod("to_s", new JavaMethodZero(proxyClass, PUBLIC) {
proxy.addMethod("to_s", new JavaMethodZero(proxy, PUBLIC) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
ByteList bytes = new ByteList((byte[]) ((ArrayJavaProxy) self).getObject(), ascii8bit);
@@ -492,55 +513,48 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
}
}
else if ( clazz.isPrimitive() ) {
proxyClass = createProxyClass(runtime, javaSupport.getConcreteProxyClass(), clazz, true);
createProxyClass(runtime, proxy, clazz, true);
}
else if ( clazz == Object.class ) {
// java.lang.Object is added at root of java proxy classes
proxyClass = createProxyClass(runtime, javaSupport.getConcreteProxyClass(), clazz, true);
createProxyClass(runtime, proxy, clazz, true);
if (NEW_STYLE_EXTENSION) {
proxyClass.getMetaClass().defineAnnotatedMethods(NewStyleExtensionInherited.class);
proxy.getMetaClass().defineAnnotatedMethods(NewStyleExtensionInherited.class);
} else {
proxyClass.getMetaClass().defineAnnotatedMethods(OldStyleExtensionInherited.class);
proxy.getMetaClass().defineAnnotatedMethods(OldStyleExtensionInherited.class);
}
addToJavaPackageModule(proxyClass);
addToJavaPackageModule(proxy);
}
else {
// other java proxy classes added under their superclass' java proxy
RubyClass superProxyClass = (RubyClass) getProxyClass(runtime, clazz.getSuperclass());
proxyClass = createProxyClass(runtime, superProxyClass, clazz, false);
createProxyClass(runtime, proxy, clazz, false);
// include interface modules into the proxy class
final Class<?>[] interfaces = clazz.getInterfaces();
for ( int i = interfaces.length; --i >= 0; ) {
proxyClass.includeModule(getInterfaceModule(runtime, interfaces[i]));
proxy.includeModule(getInterfaceModule(runtime, interfaces[i]));
}
if ( Modifier.isPublic(clazz.getModifiers()) ) {
addToJavaPackageModule(proxyClass);
addToJavaPackageModule(proxy);
}
}

// JRUBY-1000, fail early when attempting to subclass a final Java class;
// solved here by adding an exception-throwing "inherited"
if ( Modifier.isFinal(clazz.getModifiers()) ) {
final String clazzName = clazz.getCanonicalName();
proxyClass.getMetaClass().addMethod("inherited", new org.jruby.internal.runtime.methods.JavaMethod(proxyClass, PUBLIC) {
proxy.getMetaClass().addMethod("inherited", new org.jruby.internal.runtime.methods.JavaMethod(proxy, PUBLIC) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
throw context.runtime.newTypeError("can not extend final Java class: " + clazzName);
}
});
}

return proxyClass;
}

private static RubyClass createProxyClass(final Ruby runtime,
final RubyClass baseType, final Class<?> javaClass, boolean invokeInherited) {
RubyClass proxyClass;
final RubyClass proxyClass, final Class<?> javaClass, boolean invokeInherited) {

// this needs to be split, since conditional calling #inherited doesn't fit standard ruby semantics
final RubyClass superClass = proxyClass.getSuperClass();

final RubyClass superClass = baseType;
proxyClass = RubyClass.newClass(runtime, superClass);
proxyClass.makeMetaClass( superClass.getMetaClass() );

if ( Map.class.isAssignableFrom( javaClass ) ) {
@@ -1457,6 +1471,6 @@ private static void addToJavaPackageModule(RubyModule proxyClass, JavaClass java
@Deprecated
private static RubyClass createProxyClass(final Ruby runtime,
final RubyClass baseType, final JavaClass javaClass, boolean invokeInherited) {
return createProxyClass(runtime, baseType, javaClass.javaClass(), invokeInherited);
return createProxyClass(runtime, RubyClass.newClass(runtime, baseType), javaClass, invokeInherited);
}
}
8 changes: 6 additions & 2 deletions core/src/main/java/org/jruby/javasupport/JavaSupport.java
Original file line number Diff line number Diff line change
@@ -107,9 +107,13 @@ public abstract class JavaSupport {

public abstract Map<Set<?>, JavaProxyClass> getJavaProxyClassCache();

public abstract ClassValue<ThreadLocal<RubyModule>> getUnfinishedProxyClassCache();

public abstract ClassValue<Map<String, AssignedName>> getStaticAssignedNames();

public abstract ClassValue<Map<String, AssignedName>> getInstanceAssignedNames();

public abstract void beginProxy(Class cls, RubyModule proxy);

public abstract void endProxy(Class cls);

public abstract RubyModule getUnfinishedProxy(Class cls);
}
71 changes: 46 additions & 25 deletions core/src/main/java/org/jruby/javasupport/JavaSupportImpl.java
Original file line number Diff line number Diff line change
@@ -33,45 +33,49 @@
***** END LICENSE BLOCK *****/
package org.jruby.javasupport;

import org.jruby.javasupport.binding.AssignedName;
import org.jruby.util.collections.MapBasedClassValue;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.exceptions.RaiseException;
import org.jruby.exceptions.Unrescuable;
import org.jruby.util.collections.ClassValue;
import org.jruby.javasupport.binding.AssignedName;
import org.jruby.javasupport.proxy.JavaProxyClass;
import org.jruby.javasupport.util.ObjectProxyCache;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.WeakIdentityHashMap;
import org.jruby.util.cli.Options;
import org.jruby.util.collections.ClassValueCalculator;

public class JavaSupportImpl extends JavaSupport {
private final Ruby runtime;

private final ObjectProxyCache<IRubyObject,RubyClass> objectProxyCache =
// TODO: specifying soft refs, may want to compare memory consumption,
// behavior with weak refs (specify WEAK in place of SOFT below)
new ObjectProxyCache<IRubyObject,RubyClass>(ObjectProxyCache.ReferenceType.WEAK) {
// TODO: specifying soft refs, may want to compare memory consumption,
// behavior with weak refs (specify WEAK in place of SOFT below)
new ObjectProxyCache<IRubyObject,RubyClass>(ObjectProxyCache.ReferenceType.WEAK) {

public IRubyObject allocateProxy(Object javaObject, RubyClass clazz) {
return Java.allocateProxy(javaObject, clazz);
}
};
public IRubyObject allocateProxy(Object javaObject, RubyClass clazz) {
return Java.allocateProxy(javaObject, clazz);
}
};

private final ClassValue<JavaClass> javaClassCache;
private final ClassValue<RubyModule> proxyClassCache;
private final ClassValue<ThreadLocal<RubyModule>> unfinishedProxyClassCache;
private class UnfinishedProxy extends ReentrantLock {
volatile RubyModule proxy;
UnfinishedProxy(RubyModule proxy) {
this.proxy = proxy;
}
}
private final Map<Class, UnfinishedProxy> unfinishedProxies;
private final ClassValue<Map<String, AssignedName>> staticAssignedNames;
private final ClassValue<Map<String, AssignedName>> instanceAssignedNames;

@@ -108,19 +112,20 @@ public JavaClass computeValue(Class<?> cls) {
return new JavaClass(runtime, cls);
}
});

this.proxyClassCache = ClassValue.newInstance(new ClassValueCalculator<RubyModule>() {
/**
* Because of the complexity of processing a given class and all its dependencies,
* we opt to synchronize this logic. Creation of all proxies goes through here,
* allowing us to skip some threading work downstream.
*/
@Override
public RubyModule computeValue(Class<?> cls) {
public synchronized RubyModule computeValue(Class<?> cls) {
return Java.createProxyClassForClass(runtime, cls);
}
});
this.unfinishedProxyClassCache = ClassValue.newInstance(new ClassValueCalculator<ThreadLocal<RubyModule>>() {
@Override
public ThreadLocal<RubyModule> computeValue(Class<?> cls) {
return new ThreadLocal<RubyModule>();
}
});
this.staticAssignedNames =ClassValue.newInstance(new ClassValueCalculator<Map<String, AssignedName>>() {

this.staticAssignedNames = ClassValue.newInstance(new ClassValueCalculator<Map<String, AssignedName>>() {
@Override
public Map<String, AssignedName> computeValue(Class<?> cls) {
return new HashMap<String, AssignedName>();
@@ -132,6 +137,9 @@ public Map<String, AssignedName> computeValue(Class<?> cls) {
return new HashMap<String, AssignedName>();
}
});

// Proxy creation is synchronized (see above) so a HashMap is fine for recursion detection.
this.unfinishedProxies = new ConcurrentHashMap<Class, UnfinishedProxy>(8, 0.75f, 1);
}

public Class loadJavaClass(String className) throws ClassNotFoundException {
@@ -331,10 +339,6 @@ public Map<Set<?>, JavaProxyClass> getJavaProxyClassCache() {
return this.javaProxyClassCache;
}

public ClassValue<ThreadLocal<RubyModule>> getUnfinishedProxyClassCache() {
return unfinishedProxyClassCache;
}

public ClassValue<Map<String, AssignedName>> getStaticAssignedNames() {
return staticAssignedNames;
}
@@ -343,6 +347,23 @@ public ClassValue<Map<String, AssignedName>> getInstanceAssignedNames() {
return instanceAssignedNames;
}

public void beginProxy(Class cls, RubyModule proxy) {
UnfinishedProxy up = new UnfinishedProxy(proxy);
up.lock();
unfinishedProxies.put(cls, up);
}

public void endProxy(Class cls) {
UnfinishedProxy up = unfinishedProxies.remove(cls);
up.unlock();
}

public RubyModule getUnfinishedProxy(Class cls) {
UnfinishedProxy up = unfinishedProxies.get(cls);
if (up != null && up.isHeldByCurrentThread()) return up.proxy;
return null;
}

@Deprecated
private volatile Map<Object, Object[]> javaObjectVariables;

Original file line number Diff line number Diff line change
@@ -30,8 +30,6 @@ public RubyModule initialize(RubyModule proxy) {

proxyClass.setReifiedClass(javaClass);

runtime.getJavaSupport().getUnfinishedProxyClassCache().get(javaClass).set(proxyClass);

if ( javaClass.isArray() || javaClass.isPrimitive() ) {
return proxy;
}
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@
import org.jruby.internal.runtime.methods.JavaMethod;
import org.jruby.javasupport.Java;
import org.jruby.javasupport.JavaClass;
import org.jruby.javasupport.JavaSupport;
import org.jruby.javasupport.JavaUtil;
import org.jruby.runtime.Block;
import org.jruby.runtime.Helpers;
@@ -34,6 +35,7 @@
*/
public abstract class Initializer {
protected final Ruby runtime;
protected final JavaSupport javaSupport;
protected final Class javaClass;

private static final Logger LOG = LoggerFactory.getLogger("Initializer");
@@ -68,6 +70,7 @@ public abstract class Initializer {

public Initializer(Ruby runtime, Class javaClass) {
this.runtime = runtime;
this.javaSupport = runtime.getJavaSupport();
this.javaClass = javaClass;
}

Original file line number Diff line number Diff line change
@@ -23,8 +23,6 @@ public InterfaceInitializer(Ruby runtime, Class<?> javaClass) {
public RubyModule initialize(RubyModule proxy) {
final State state = new State(runtime, null);

runtime.getJavaSupport().getUnfinishedProxyClassCache().get(javaClass).set(proxy);

Field[] fields = JavaClass.getDeclaredFields(javaClass);

for (int i = fields.length; --i >= 0; ) {
24 changes: 0 additions & 24 deletions install/jruby.install4j
Original file line number Diff line number Diff line change
@@ -683,30 +683,6 @@
</exclude>
<variables />
</win32>
<win32 name="Windows w/ JRE" id="21" mediaFileName="${compiler:sys.shortName}_${compiler:sys.platform}jre_${compiler:sys.version}" installDir="jruby-${compiler:sys.version}" overridePrincipalLanguage="false" requires64bit="false" jreBitType="32" runPostProcessor="false" postProcessor="" failOnPostProcessorError="false" includedJRE="windows-x86-1.7.0_51" manualJREEntry="false" bundleType="1" jreURL="" jreFtpURL="" jreShared="false" directDownload="false" customInstallBaseDir="c:" createUninstallIcon="true" contentFilesType="1" downloadURL="" runAsAdmin="false">
<excludedLaunchers />
<excludedComponents />
<excludedBeans>
<bean refId="26" />
</excludedBeans>
<overriddenPrincipalLanguage id="en" customLocalizationFile="" />
<exclude>
<entry location=".i4j_fileset_201" fileType="regular" />
</exclude>
<variables />
</win32>
<win32 name="Windows 64-bit w/ JRE" id="198" mediaFileName="${compiler:sys.shortName}_${compiler:sys.platform}_x64_jre_${compiler:sys.version}" installDir="jruby-${compiler:sys.version}" overridePrincipalLanguage="false" requires64bit="true" jreBitType="64" runPostProcessor="false" postProcessor="" failOnPostProcessorError="false" includedJRE="windows-amd64-1.7.0_51" manualJREEntry="false" bundleType="1" jreURL="" jreFtpURL="" jreShared="false" directDownload="false" customInstallBaseDir="c:" createUninstallIcon="true" contentFilesType="1" downloadURL="" runAsAdmin="false">
<excludedLaunchers />
<excludedComponents />
<excludedBeans>
<bean refId="26" />
</excludedBeans>
<overriddenPrincipalLanguage id="en" customLocalizationFile="" />
<exclude>
<entry location=".i4j_fileset_201" fileType="regular" />
</exclude>
<variables />
</win32>
<macosFolder name="Mac OS X Folder" id="22" mediaFileName="${compiler:sys.shortName}_${compiler:sys.platform}_${compiler:sys.version}" installDir="jruby-${compiler:sys.version}" overridePrincipalLanguage="false" requires64bit="false" jreBitType="all" runPostProcessor="false" postProcessor="" failOnPostProcessorError="false" customInstallBaseDir="" createUninstallIcon="true" contentFilesType="1" downloadURL="">
<excludedLaunchers>
<launcher id="320" />
Loading