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

Commits on Aug 6, 2015

  1. Copy the full SHA
    afe18b2 View commit details
  2. Copy the full SHA
    5cd9230 View commit details
  3. Copy the full SHA
    ae01731 View commit details
  4. Copy the full SHA
    a2c7d6e View commit details
  5. Back off original context idea since it is at odds with needing n IRC…

    …losure contexts to be able to compile with obvious mechanism for how to access a context from within the visitor. For Methods it seems to work so I renamed it to JVMVisitorMethodContext.
    enebo committed Aug 6, 2015
    Copy the full SHA
    ca3b0c1 View commit details
25 changes: 13 additions & 12 deletions core/src/main/java/org/jruby/compiler/JITCompiler.java
Original file line number Diff line number Diff line change
@@ -37,9 +37,9 @@
import org.jruby.ast.util.SexpMaker;
import org.jruby.internal.runtime.methods.CompiledIRMethod;
import org.jruby.internal.runtime.methods.MixedModeIRMethod;
import org.jruby.ir.IRMethod;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.targets.JVMVisitor;
import org.jruby.ir.targets.JVMVisitorMethodContext;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.threading.DaemonThreadFactory;
@@ -243,7 +243,8 @@ public void run() {
JVMVisitor visitor = new JVMVisitor();
JITClassGenerator generator = new JITClassGenerator(className, methodName, key, runtime, method, visitor);

generator.compile();
JVMVisitorMethodContext context = new JVMVisitorMethodContext();
generator.compile(context);

// FIXME: reinstate active bytecode size check
// At this point we still need to reinstate the bytecode size check, to ensure we're not loading code
@@ -274,8 +275,8 @@ public void run() {
log(method.getImplementationClass(), method.getFile(), method.getLine(), className + "." + methodName, "done jitting");
}

Map<Integer, MethodType> signatures = ((IRMethod)method.getIRScope()).getNativeSignatures();
String jittedName = ((IRMethod)method.getIRScope()).getJittedName();
Map<Integer, MethodType> signatures = context.getNativeSignatures();
String jittedName = context.getJittedName();
if (signatures.size() == 1) {
// only variable-arity
method.completeBuild(
@@ -324,10 +325,9 @@ public static String getHashForBytes(byte[] bytes) {
try {
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
sha1.update(bytes);
byte[] digest = sha1.digest();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < digest.length; i++) {
builder.append(Integer.toString( ( digest[i] & 0xff ) + 0x100, 16).substring( 1 ));
for (byte aByte : sha1.digest()) {
builder.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
}
return builder.toString().toUpperCase(Locale.ENGLISH);
} catch (NoSuchAlgorithmException nsae) {
@@ -358,7 +358,7 @@ public JITClassGenerator(String className, String methodName, String key, Ruby r
}

@SuppressWarnings("unchecked")
protected void compile() {
protected void compile(JVMVisitorMethodContext context) {
if (bytecode != null) return;

// Time the compilation
@@ -374,7 +374,7 @@ protected void compile() {

// This may not be ok since we'll end up running passes specific to JIT
// CON FIXME: Really should clone scope before passes in any case
bytecode = visitor.compileToBytecode(method.getIRScope());
bytecode = visitor.compileToBytecode(method.getIRScope(), context);

compileTime = System.nanoTime() - start;
}
@@ -392,8 +392,9 @@ void updateCounters(JITCounts counts) {
}
}

// FIXME: Does anything call this? If so we should document it.
public void generate() {
compile();
compile(new JVMVisitorMethodContext());
}

public byte[] bytecode() {
@@ -432,8 +433,8 @@ static void log(RubyModule implementationClass, String file, int line, String na

if (reason.length > 0) {
builder.append(" because of: \"");
for (int i = 0; i < reason.length; i++) {
builder.append(reason[i]);
for (String aReason : reason) {
builder.append(aReason);
}
builder.append('"');
}
Original file line number Diff line number Diff line change
@@ -60,7 +60,7 @@ public StaticScope getStaticScope() {

public ArgumentDescriptor[] getArgumentDescriptors() {
ensureInstrsReady(); // Make sure method is minimally built before returning this info
return method.getArgumentDescriptors();
return ((IRMethod) method).getArgumentDescriptors();
}

public Signature getSignature() {
12 changes: 6 additions & 6 deletions core/src/main/java/org/jruby/ir/Compiler.java
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@
import org.jruby.ir.operands.IRException;
import org.jruby.ir.runtime.IRBreakJump;
import org.jruby.ir.targets.JVMVisitor;
import org.jruby.ir.targets.JVMVisitorMethodContext;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
import org.jruby.runtime.DynamicScope;
@@ -43,15 +44,14 @@ public static Compiler getInstance() {

@Override
protected ScriptAndCode execute(final Ruby runtime, final IRScriptBody scope, ClassDefiningClassLoader classLoader) {
JVMVisitor visitor;
byte[] bytecode;
Class compiled;

MethodHandle _compiledHandle;

try {
visitor = new JVMVisitor();
bytecode = visitor.compileToBytecode(scope);
compiled = visitor.defineFromBytecode(scope, bytecode, classLoader);
JVMVisitor visitor = new JVMVisitor();
JVMVisitorMethodContext context = new JVMVisitorMethodContext();
bytecode = visitor.compileToBytecode(scope, context);
Class compiled = visitor.defineFromBytecode(scope, bytecode, classLoader);

Method compiledMethod = compiled.getMethod("RUBY$script", ThreadContext.class,
StaticScope.class, IRubyObject.class, IRubyObject[].class, Block.class, RubyModule.class, String.class);
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/ir/IRBuilder.java
Original file line number Diff line number Diff line change
@@ -2109,7 +2109,7 @@ public void receiveMethodArgs(final ArgsNode argsNode) {
public void receiveBlockArgs(final IterNode node) {
Node args = node.getVarNode();
if (args instanceof ArgsNode) { // regular blocks
scope.setArgumentDescriptors(Helpers.argsNodeToArgumentDescriptors(((ArgsNode) args)));
((IRClosure) scope).setArgumentDescriptors(Helpers.argsNodeToArgumentDescriptors(((ArgsNode) args)));
receiveArgs((ArgsNode)args);
} else {
// for loops -- reuse code in IRBuilder:buildBlockArgsAssignment
16 changes: 16 additions & 0 deletions core/src/main/java/org/jruby/ir/IRClosure.java
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@
import org.jruby.ir.transformations.inlining.CloneInfo;
import org.jruby.ir.transformations.inlining.SimpleCloneInfo;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.runtime.BlockBody;
import org.jruby.runtime.IRBlockBody;
import org.jruby.runtime.InterpretedIRBlockBody;
@@ -28,6 +29,9 @@ public class IRClosure extends IRScope {

private Signature signature;

// Argument description
protected ArgumentDescriptor[] argDesc = ArgumentDescriptor.EMPTY_ARRAY;

/** Added for interp/JIT purposes */
private IRBlockBody body;

@@ -290,4 +294,16 @@ public void setHandle(Handle handle) {
public Handle getHandle() {
return handle;
}

public ArgumentDescriptor[] getArgumentDescriptors() {
return argDesc;
}


/**
* Set upon completion of IRBuild of this IRClosure.
*/
public void setArgumentDescriptors(ArgumentDescriptor[] argDesc) {
this.argDesc = argDesc;
}
}
32 changes: 10 additions & 22 deletions core/src/main/java/org/jruby/ir/IRMethod.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,17 @@
package org.jruby.ir;

import java.lang.invoke.MethodType;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.jruby.ast.MethodDefNode;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.ir.operands.LocalVariable;
import org.jruby.ir.representations.BasicBlock;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.ArgumentDescriptor;

public class IRMethod extends IRScope {
public final boolean isInstanceMethod;

// Signatures to the jitted versions of this method
private Map<Integer, MethodType> signatures;

// Method name in the jitted version of this method
private String jittedName;
// Argument description
protected ArgumentDescriptor[] argDesc = ArgumentDescriptor.EMPTY_ARRAY;

private MethodDefNode defn;

@@ -27,7 +21,6 @@ public IRMethod(IRManager manager, IRScope lexicalParent, MethodDefNode defn, St

this.defn = defn;
this.isInstanceMethod = isInstanceMethod;
this.signatures = null;

if (!getManager().isDryRun() && staticScope != null) {
staticScope.setIRScope(this);
@@ -73,20 +66,15 @@ public LocalVariable getLocalVariable(String name, int scopeDepth) {
return lvar;
}

public void addNativeSignature(int arity, MethodType signature) {
if (signatures == null) signatures = new HashMap<>(1);
signatures.put(arity, signature);
}

public Map<Integer, MethodType> getNativeSignatures() {
return Collections.unmodifiableMap(signatures);
public ArgumentDescriptor[] getArgumentDescriptors() {
return argDesc;
}

public String getJittedName() {
return jittedName;
}

public void setJittedName(String jittedName) {
this.jittedName = jittedName;
/**
* Set upon completion of IRBuild of this IRMethod.
*/
public void setArgumentDescriptors(ArgumentDescriptor[] argDesc) {
this.argDesc = argDesc;
}
}
15 changes: 0 additions & 15 deletions core/src/main/java/org/jruby/ir/IRScope.java
Original file line number Diff line number Diff line change
@@ -22,7 +22,6 @@
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;

import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;

@@ -63,8 +62,6 @@ public abstract class IRScope implements ParseResult {
private static final Collection<IRClosure> NO_CLOSURES = Collections.unmodifiableCollection(new ArrayList<IRClosure>(0));

private static AtomicInteger globalScopeCount = new AtomicInteger();
// Argument description
protected ArgumentDescriptor[] argDesc = ArgumentDescriptor.EMPTY_ARRAY;

/** Unique global scope id */
private int scopeId;
@@ -189,7 +186,6 @@ public IRScope(IRManager manager, IRScope lexicalParent, String name,
this.scopeId = globalScopeCount.getAndIncrement();

setupLexicalContainment();
this.argDesc = null;
}

private void setupLexicalContainment() {
@@ -780,17 +776,6 @@ public LocalVariable lookupExistingLVar(String name) {
return localVars.get(name);
}

public ArgumentDescriptor[] getArgumentDescriptors() {
return argDesc;
}

/**
* Set upon completion of IRBuild of this IRMethod.
*/
public void setArgumentDescriptors(ArgumentDescriptor[] argDesc) {
this.argDesc = argDesc;
}

protected LocalVariable findExistingLocalVariable(String name, int depth) {
return localVars.get(name);
}
45 changes: 24 additions & 21 deletions core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
Original file line number Diff line number Diff line change
@@ -66,11 +66,12 @@ public JVMVisitor() {
}

public Class compile(IRScope scope, ClassDefiningClassLoader jrubyClassLoader) {
return defineFromBytecode(scope, compileToBytecode(scope), jrubyClassLoader);
JVMVisitorMethodContext context = new JVMVisitorMethodContext();
return defineFromBytecode(scope, compileToBytecode(scope, context), jrubyClassLoader);
}

public byte[] compileToBytecode(IRScope scope) {
codegenScope(scope);
public byte[] compileToBytecode(IRScope scope, JVMVisitorMethodContext context) {
codegenScope(scope, context);

// try {
// FileOutputStream fos = new FileOutputStream("tmp.class");
@@ -101,11 +102,11 @@ public byte[] code() {
return jvm.code();
}

public void codegenScope(IRScope scope) {
public void codegenScope(IRScope scope, JVMVisitorMethodContext context) {
if (scope instanceof IRScriptBody) {
codegenScriptBody((IRScriptBody)scope);
} else if (scope instanceof IRMethod) {
emitMethodJIT((IRMethod)scope);
emitMethodJIT((IRMethod)scope, context);
} else if (scope instanceof IRModuleBody) {
emitModuleBodyJIT((IRModuleBody)scope);
} else {
@@ -237,34 +238,34 @@ public void emitScriptBody(IRScriptBody script) {
jvm.popclass();
}

public void emitMethod(IRMethod method) {
public void emitMethod(IRMethod method, JVMVisitorMethodContext context) {
String name = JavaNameMangler.encodeScopeForBacktrace(method) + "$" + methodIndex++;

emitWithSignatures(method, name);
emitWithSignatures(method, context, name);
}

public void emitMethodJIT(IRMethod method) {
public void emitMethodJIT(IRMethod method, JVMVisitorMethodContext context) {
String clsName = jvm.scriptToClass(method.getFileName());
String name = JavaNameMangler.encodeScopeForBacktrace(method) + "$" + methodIndex++;
jvm.pushscript(clsName, method.getFileName());

emitWithSignatures(method, name);
emitWithSignatures(method, context, name);

jvm.cls().visitEnd();
jvm.popclass();
}

private void emitWithSignatures(IRMethod method, String name) {
method.setJittedName(name);
private void emitWithSignatures(IRMethod method, JVMVisitorMethodContext context, String name) {
context.setJittedName(name);

Signature signature = signatureFor(method, false);
emitScope(method, name, signature, false);
method.addNativeSignature(-1, signature.type());
context.addNativeSignature(-1, signature.type());

Signature specificSig = signatureFor(method, true);
if (specificSig != null) {
emitScope(method, name, specificSig, true);
method.addNativeSignature(method.getStaticScope().getSignature().required(), specificSig.type());
context.addNativeSignature(method.getStaticScope().getSignature().required(), specificSig.type());
}
}

@@ -928,20 +929,21 @@ public void DefineClassMethodInstr(DefineClassMethodInstr defineclassmethodinstr

jvmMethod().loadContext();

emitMethod(method);
JVMVisitorMethodContext context = new JVMVisitorMethodContext();
emitMethod(method, context);

Map<Integer, MethodType> signatures = method.getNativeSignatures();
Map<Integer, MethodType> signatures = context.getNativeSignatures();

MethodType signature = signatures.get(-1);

String defSignature = pushHandlesForDef(
method.getJittedName(),
context.getJittedName(),
signatures,
signature,
sig(void.class, ThreadContext.class, java.lang.invoke.MethodHandle.class, IRScope.class, IRubyObject.class),
sig(void.class, ThreadContext.class, java.lang.invoke.MethodHandle.class, java.lang.invoke.MethodHandle.class, int.class, IRScope.class, IRubyObject.class));

jvmAdapter().getstatic(jvm.clsData().clsName, method.getJittedName() + "_IRScope", ci(IRScope.class));
jvmAdapter().getstatic(jvm.clsData().clsName, context.getJittedName() + "_IRScope", ci(IRScope.class));
visit(defineclassmethodinstr.getContainer());

// add method
@@ -952,25 +954,26 @@ public void DefineClassMethodInstr(DefineClassMethodInstr defineclassmethodinstr
@Override
public void DefineInstanceMethodInstr(DefineInstanceMethodInstr defineinstancemethodinstr) {
IRMethod method = defineinstancemethodinstr.getMethod();
JVMVisitorMethodContext context = new JVMVisitorMethodContext();

IRBytecodeAdapter m = jvmMethod();
SkinnyMethodAdapter a = m.adapter;

m.loadContext();

emitMethod(method);
Map<Integer, MethodType> signatures = method.getNativeSignatures();
emitMethod(method, context);
Map<Integer, MethodType> signatures = context.getNativeSignatures();

MethodType variable = signatures.get(-1); // always a variable arity handle

String defSignature = pushHandlesForDef(
method.getJittedName(),
context.getJittedName(),
signatures,
variable,
sig(void.class, ThreadContext.class, java.lang.invoke.MethodHandle.class, IRScope.class, DynamicScope.class, IRubyObject.class),
sig(void.class, ThreadContext.class, java.lang.invoke.MethodHandle.class, java.lang.invoke.MethodHandle.class, int.class, IRScope.class, DynamicScope.class, IRubyObject.class));

a.getstatic(jvm.clsData().clsName, method.getJittedName() + "_IRScope", ci(IRScope.class));
a.getstatic(jvm.clsData().clsName, context.getJittedName() + "_IRScope", ci(IRScope.class));
jvmLoadLocal(DYNAMIC_SCOPE);
jvmMethod().loadSelf();

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.jruby.ir.targets;

import java.lang.invoke.MethodType;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
* Context for JITing methods. Temporary data.
*/
public class JVMVisitorMethodContext {
// Method name in the jitted version of this method
private String jittedName;

// Signatures to the jitted versions of this method
private Map<Integer, MethodType> signatures;

public void setJittedName(String jittedName) {
this.jittedName = jittedName;
}

public String getJittedName() {
return jittedName;
}


public void addNativeSignature(int arity, MethodType signature) {
if (signatures == null) signatures = new HashMap<>(1);
signatures.put(arity, signature);
}

public Map<Integer, MethodType> getNativeSignatures() {
return Collections.unmodifiableMap(signatures);
}
}
5 changes: 3 additions & 2 deletions core/src/main/java/org/jruby/runtime/IRBlockBody.java
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@

import org.jruby.EvalType;
import org.jruby.RubyArray;
import org.jruby.ir.IRClosure;
import org.jruby.ir.IRScope;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.runtime.Block.Type;
@@ -10,12 +11,12 @@
public abstract class IRBlockBody extends ContextAwareBlockBody {
protected final String fileName;
protected final int lineNumber;
protected final IRScope closure;
protected final IRClosure closure;
protected ThreadLocal<EvalType> evalType;

public IRBlockBody(IRScope closure, Signature signature) {
super(closure.getStaticScope(), signature);
this.closure = closure;
this.closure = (IRClosure) closure;
this.fileName = closure.getFileName();
this.lineNumber = closure.getLineNumber();
this.evalType = new ThreadLocal();