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: 786eef56d432
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 67820f827103
Choose a head ref
  • 3 commits
  • 7 files changed
  • 1 contributor

Commits on Jun 13, 2017

  1. Copy the full SHA
    8b8add6 View commit details
  2. Reinstate a non-indy const lookup path for Android.

    This is not a straight reversion of the caching commit below,
    since there were modifications to how constants bound after that
    change.
    
    Note that we still need to restore constant caching for non-indy
    paths, or otherwise make it easier to say that Java 7+ JRuby will
    use indy for some things without compile.invokedynamic, but
    disable those features on platforms that don't support indy.
    
    Revert "Always use invokeynamic to lookup and cache constants."
    
    This reverts commit e03c4f1.
    headius committed Jun 13, 2017
    Copy the full SHA
    a45cbe9 View commit details
  3. Provide a non-indy global var path again.

    This is a completely unoptimized path, and can't be shipped, but
    it should continue to allow things to work on Android without
    breaking the non-indy JIT for JRuby proper.
    headius committed Jun 13, 2017
    Copy the full SHA
    67820f8 View commit details
14 changes: 14 additions & 0 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Original file line number Diff line number Diff line change
@@ -38,6 +38,8 @@
import org.jruby.runtime.callsite.RefinedCachingCallSite;
import org.jruby.runtime.callsite.VariableCachingCallSite;
import org.jruby.runtime.ivars.VariableAccessor;
import org.jruby.runtime.opto.ConstantCache;
import org.jruby.runtime.opto.Invalidator;
import org.jruby.util.ArraySupport;
import org.jruby.util.ByteList;
import org.jruby.util.RegexpOptions;
@@ -1183,6 +1185,18 @@ public static IRubyObject searchConst(ThreadContext context, StaticScope staticS
return constant;
}

@JIT
public static IRubyObject searchModuleForConst(ThreadContext context, IRubyObject cmVal, String constName, boolean noPrivateConsts) {
if (!(cmVal instanceof RubyModule)) throw context.runtime.newTypeError(cmVal + " is not a type/class");

RubyModule module = (RubyModule) cmVal;
IRubyObject constant = noPrivateConsts ? module.getConstantFromNoConstMissing(constName, false) : module.getConstantNoConstMissing(constName);

if (constant != null) return constant;

return module.callMethod(context, "const_missing", context.runtime.fastNewSymbol(constName));
}

@JIT
public static IRubyObject inheritedSearchConst(ThreadContext context, IRubyObject cmVal, String constName, boolean noPrivateConsts) {
RubyModule module;
3 changes: 2 additions & 1 deletion core/src/main/java/org/jruby/ir/targets/Bootstrap.java
Original file line number Diff line number Diff line change
@@ -1020,8 +1020,9 @@ public static Block constructBlock(Binding binding, CompiledIRBlockBody body) th
/* Not the best place for this but better than tying Ruby to indy. */
public static Object createNullToNilHandle(Ruby runtime) {
IRubyObject nilObject = runtime.getNil();
MethodHandle nullToNil = Binder.from(IRubyObject.class, IRubyObject.class)
MethodHandle nullToNil = Binder.from(IRubyObject.class, Object.class)
.append(nilObject)
.cast(IRubyObject.class, IRubyObject.class, IRubyObject.class)
.invokeStaticQuiet(lookup(), Helpers.class, "nullToNil");

return nullToNil;
12 changes: 3 additions & 9 deletions core/src/main/java/org/jruby/ir/targets/ConstantLookupSite.java
Original file line number Diff line number Diff line change
@@ -8,22 +8,16 @@
import org.jruby.parser.StaticScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.CodegenUtils;
import org.jruby.util.cli.Options;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Opcodes;

import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.MutableCallSite;
import java.lang.invoke.SwitchPoint;
import java.lang.invoke.*;

import static java.lang.invoke.MethodHandles.guardWithTest;
import static org.jruby.util.CodegenUtils.p;
import static org.jruby.util.CodegenUtils.sig;

/**
* Created by headius on 1/31/16.
@@ -37,7 +31,7 @@ public class ConstantLookupSite extends MutableCallSite {

private final SiteTracker tracker = new SiteTracker();

public static final Handle BOOTSTRAP = new Handle(Opcodes.H_INVOKESTATIC, p(ConstantLookupSite.class), "constLookup", sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, int.class));
public static final Handle BOOTSTRAP = new Handle(Opcodes.H_INVOKESTATIC, CodegenUtils.p(ConstantLookupSite.class), "constLookup", CodegenUtils.sig(CallSite.class, MethodHandles.Lookup.class, String.class, MethodType.class, String.class, int.class));

public ConstantLookupSite(MethodType type, String name, boolean publicOnly) {
super(type);
35 changes: 18 additions & 17 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter6.java
Original file line number Diff line number Diff line change
@@ -740,20 +740,26 @@ private void performSuper(String file, int line, String name, int arity, boolean
}

public void searchConst(String name, boolean noPrivateConsts) {
adapter.invokedynamic("searchConst", sig(JVM.OBJECT, params(ThreadContext.class, StaticScope.class)), ConstantLookupSite.BOOTSTRAP, name, noPrivateConsts ? 1 : 0);
adapter.ldc(name);
adapter.ldc(noPrivateConsts);
invokeIRHelper("searchConst", sig(IRubyObject.class, ThreadContext.class, StaticScope.class, String.class, boolean.class));
}

public void searchModuleForConst(String name, boolean noPrivateConsts) {
adapter.invokedynamic("searchModuleForConst", sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class)), ConstantLookupSite.BOOTSTRAP, name, noPrivateConsts ? 1 : 0);
adapter.ldc(name);
adapter.ldc(noPrivateConsts);
invokeIRHelper("searchModuleForConst", sig(IRubyObject.class, ThreadContext.class, IRubyObject.class, String.class, boolean.class));
}

public void inheritanceSearchConst(String name, boolean noPrivateConsts) {
adapter.invokedynamic("inheritanceSearchConst", sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class)), ConstantLookupSite.BOOTSTRAP, name, noPrivateConsts ? 1 : 0);
adapter.ldc(name);
adapter.ldc(noPrivateConsts);
invokeIRHelper("inheritedSearchConst", sig(IRubyObject.class, ThreadContext.class, IRubyObject.class, String.class, boolean.class));
}

public void lexicalSearchConst(String name) {
adapter.invokedynamic("lexicalSearchConst", sig(JVM.OBJECT, params(ThreadContext.class, StaticScope.class)), ConstantLookupSite.BOOTSTRAP, name, 0);
}
adapter.ldc(name);
invokeIRHelper("lexicalSearchConst", sig(IRubyObject.class, ThreadContext.class, StaticScope.class, String.class));}

public void pushNil() {
loadContext();
@@ -955,22 +961,17 @@ public void checkpoint() {

@Override
public void getGlobalVariable(String name, String file, int line) {
loadContext();
adapter.invokedynamic(
"get:" + JavaNameMangler.mangleMethodName(name),
sig(IRubyObject.class, ThreadContext.class),
Bootstrap.global(),
file, line);
loadRuntime();
adapter.ldc(name);
invokeHelper("getGlobalVariable", sig(IRubyObject.class, Ruby.class, String.class));
}

@Override
public void setGlobalVariable(String name, String file, int line) {
loadContext();
adapter.invokedynamic(
"set:" + JavaNameMangler.mangleMethodName(name),
sig(void.class, IRubyObject.class, ThreadContext.class),
Bootstrap.global(),
file, line);
loadRuntime();
adapter.ldc(name);
invokeHelper("setGlobalVariable", sig(IRubyObject.class, IRubyObject.class, Ruby.class, String.class));
adapter.pop();
}

@Override
40 changes: 40 additions & 0 deletions core/src/main/java/org/jruby/ir/targets/IRBytecodeAdapter7.java
Original file line number Diff line number Diff line change
@@ -17,8 +17,11 @@
import org.jruby.compiler.impl.SkinnyMethodAdapter;
import org.jruby.ir.IRScope;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
import org.jruby.runtime.BlockBody;
import org.jruby.runtime.CallType;
import org.jruby.runtime.CompiledIRBlockBody;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.MethodIndex;
import org.jruby.runtime.ThreadContext;
@@ -34,6 +37,7 @@
import java.math.BigInteger;

import static org.jruby.util.CodegenUtils.ci;
import static org.jruby.util.CodegenUtils.p;
import static org.jruby.util.CodegenUtils.params;
import static org.jruby.util.CodegenUtils.sig;

@@ -265,6 +269,22 @@ public void invokeZSuper(String file, int line, String name, int arity, boolean
}
}

public void searchConst(String name, boolean noPrivateConsts) {
adapter.invokedynamic("searchConst", sig(JVM.OBJECT, params(ThreadContext.class, StaticScope.class)), ConstantLookupSite.BOOTSTRAP, name, noPrivateConsts ? 1 : 0);
}

public void searchModuleForConst(String name, boolean noPrivateConsts) {
adapter.invokedynamic("searchModuleForConst", sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class)), ConstantLookupSite.BOOTSTRAP, name, noPrivateConsts ? 1 : 0);
}

public void inheritanceSearchConst(String name, boolean noPrivateConsts) {
adapter.invokedynamic("inheritanceSearchConst", sig(JVM.OBJECT, params(ThreadContext.class, IRubyObject.class)), ConstantLookupSite.BOOTSTRAP, name, noPrivateConsts ? 1 : 0);
}

public void lexicalSearchConst(String name) {
adapter.invokedynamic("lexicalSearchConst", sig(JVM.OBJECT, params(ThreadContext.class, StaticScope.class)), ConstantLookupSite.BOOTSTRAP, name, 0);
}

public void pushNil() {
loadContext();
adapter.invokedynamic("nil", sig(IRubyObject.class, ThreadContext.class), Bootstrap.contextValue());
@@ -329,4 +349,24 @@ public void prepareBlock(Handle handle, org.jruby.runtime.Signature signature, S
long encodedSignature = signature.encode();
adapter.invokedynamic(handle.getName(), sig(Block.class, ThreadContext.class, IRubyObject.class, DynamicScope.class), Bootstrap.prepareBlock(), handle, scopeHandle, encodedSignature);
}

@Override
public void getGlobalVariable(String name, String file, int line) {
loadContext();
adapter.invokedynamic(
"get:" + JavaNameMangler.mangleMethodName(name),
sig(IRubyObject.class, ThreadContext.class),
Bootstrap.global(),
file, line);
}

@Override
public void setGlobalVariable(String name, String file, int line) {
loadContext();
adapter.invokedynamic(
"set:" + JavaNameMangler.mangleMethodName(name),
sig(void.class, IRubyObject.class, ThreadContext.class),
Bootstrap.global(),
file, line);
}
}
2 changes: 2 additions & 0 deletions core/src/main/java/org/jruby/runtime/Helpers.java
Original file line number Diff line number Diff line change
@@ -2001,10 +2001,12 @@ public static RubyModule checkIsModule(IRubyObject maybeModule) {
throw maybeModule.getRuntime().newTypeError(maybeModule + " is not a class/module");
}

@JIT
public static IRubyObject getGlobalVariable(Ruby runtime, String name) {
return runtime.getGlobalVariables().get(name);
}

@JIT
public static IRubyObject setGlobalVariable(IRubyObject value, Ruby runtime, String name) {
return runtime.getGlobalVariables().set(name, value);
}
14 changes: 10 additions & 4 deletions core/src/main/java/org/jruby/runtime/opto/OptoFactory.java
Original file line number Diff line number Diff line change
@@ -49,11 +49,17 @@ public static final Object newConstantWrapper(Class type, Object object) {
}

public static Invalidator newConstantInvalidator() {
if (indyEnabled()) {
return new SwitchPointInvalidator();
} else {
return new ObjectIdentityInvalidator();
if (indyEnabled() && indyConstants()) {
try {
return new SwitchPointInvalidator();
} catch (Error e) {
disableIndy();
throw e;
} catch (Throwable t) {
disableIndy();
}
}
return new ObjectIdentityInvalidator();
}

private static Boolean indyEnabled() {