Skip to content

Commit

Permalink
Clean up more refactored JIT code and unused logic.
Browse files Browse the repository at this point in the history
  • Loading branch information
headius committed Sep 18, 2014
1 parent 03e5101 commit 41de7c6
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 153 deletions.
7 changes: 5 additions & 2 deletions core/src/main/java/org/jruby/Ruby.java
Expand Up @@ -720,8 +720,11 @@ public IRubyObject runNormally(Node scriptNode) {
try {
script = tryCompile(scriptNode, new JRubyClassLoader(getJRubyClassLoader()));
} catch (Exception e) {
if (Options.JIT_LOGGING_VERBOSE.load()) {
e.printStackTrace();
if (Options.JIT_LOGGING.load()) {
LOG.error("failed to compile target script '" + scriptNode.getPosition().getFile() + "'");
if (Options.JIT_LOGGING_VERBOSE.load()) {
e.printStackTrace();
}
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/java/org/jruby/ast/util/SexpMaker.java
Expand Up @@ -6,6 +6,7 @@
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicLong;

import org.jruby.ast.AliasNode;
import org.jruby.ast.ArgumentNode;
Expand Down Expand Up @@ -51,6 +52,7 @@
import org.jruby.util.ConvertBytes;

public class SexpMaker {
private static final AtomicLong JITTED_METHOD_NUMBER = new AtomicLong();
private interface Builder {
public Builder append(String str);
public Builder append(char ch);
Expand Down Expand Up @@ -192,7 +194,8 @@ public static String sha1(IRScope scope) {

db.append(scope.getName());
db.append('\n');
db.append(scope.toStringInstrs());
// CON FIXME: We need a better way to uniquely identify this...right?
db.append(JITTED_METHOD_NUMBER.getAndIncrement());

byte[] digest = db.d.digest();

Expand Down
45 changes: 5 additions & 40 deletions core/src/main/java/org/jruby/compiler/JITCompiler.java
Expand Up @@ -153,8 +153,6 @@ public void tearDown() {
public void jitThresholdReached(final InterpretedIRMethod method, final RubyInstanceConfig config, ThreadContext context, final String className, final String methodName) {
// Disable any other jit tasks from entering queue
method.setCallCount(-1);

final Ruby runtime = context.runtime;

Runnable jitTask = new JITTask(className, method, methodName);

Expand Down Expand Up @@ -259,11 +257,11 @@ public void run() {

return;
} catch (Throwable t) {
if (runtime.getDebug().isTrue()) {
t.printStackTrace();
}
if (config.isJitLoggingVerbose()) {
if (config.isJitLogging()) {
log(method, className + "." + methodName, "could not compile", t.getMessage());
if (config.isJitLoggingVerbose()) {
t.printStackTrace();
}
}

counts.failCount.incrementAndGet();
Expand All @@ -290,37 +288,6 @@ public static String getHashForBytes(byte[] bytes) {
throw new RuntimeException(nsae);
}
}

public static void saveToCodeCache(Ruby ruby, byte[] bytecode, String packageName, File cachedClassFile) {
String codeCache = RubyInstanceConfig.JIT_CODE_CACHE;
File codeCacheDir = new File(codeCache);
if (!codeCacheDir.exists()) {
ruby.getWarnings().warn("jruby.jit.codeCache directory " + codeCacheDir + " does not exist");
} else if (!codeCacheDir.isDirectory()) {
ruby.getWarnings().warn("jruby.jit.codeCache directory " + codeCacheDir + " is not a directory");
} else if (!codeCacheDir.canWrite()) {
ruby.getWarnings().warn("jruby.jit.codeCache directory " + codeCacheDir + " is not writable");
} else {
if (!new File(codeCache, packageName).isDirectory()) {
boolean createdDirs = new File(codeCache, packageName).mkdirs();
if (!createdDirs) {
ruby.getWarnings().warn("could not create JIT cache dir: " + new File(codeCache, packageName));
}
}
// write to bytecode cache
FileOutputStream fos = null;
try {
if (RubyInstanceConfig.JIT_LOADING_DEBUG) LOG.info("writing jitted bytecode to to " + cachedClassFile);
fos = new FileOutputStream(cachedClassFile);
fos.write(bytecode);
} catch (Exception e) {
e.printStackTrace();
// ignore
} finally {
try {fos.close();} catch (Exception e) {}
}
}
}

public static class JITClassGenerator {
public JITClassGenerator(String className, String methodName, String key, Ruby ruby, InterpretedIRMethod method, JITCounts counts) {
Expand Down Expand Up @@ -357,9 +324,7 @@ protected void compile() {

method.ensureInstrsReady();

if (config.isJitLogging()) {
LOG.info("done jitting: " + method);
}
bytecode = JVMVisitor.compileToBytecode(method.getIRMethod());

counts.compiledCount.incrementAndGet();
counts.compileTime.addAndGet(System.nanoTime() - start);
Expand Down
38 changes: 0 additions & 38 deletions core/src/main/java/org/jruby/environment/OSEnvironment.java

This file was deleted.

@@ -1,32 +1,24 @@
package org.jruby.internal.runtime.methods;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import org.jruby.MetaClass;
import org.jruby.Ruby;
import org.jruby.RubyInstanceConfig;
import org.jruby.RubyClass;
import org.jruby.RubyModule;
import org.jruby.compiler.JITCompiler;
import org.jruby.ir.*;
import org.jruby.ir.representations.CFG;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.ir.targets.JVMVisitor;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Arity;
import org.jruby.runtime.Block;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.PositionAware;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.OneShotClassLoader;
import org.jruby.util.cli.Options;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;
Expand All @@ -41,30 +33,28 @@ public class InterpretedIRMethod extends DynamicMethod implements IRMethodArgs,
protected final IRScope method;

private static class DynamicMethodBox {
public CompiledIRMethod actualMethod;
public DynamicMethod actualMethod;
public int callCount = 0;
}

private DynamicMethodBox box = new DynamicMethodBox();

public InterpretedIRMethod(IRScope method, Visibility visibility, RubyModule implementationClass) {
super(implementationClass, visibility, CallConfiguration.FrameNoneScopeNone);
super(implementationClass, visibility, CallConfiguration.FrameNoneScopeNone, method.getName());
this.method = method;
this.method.getStaticScope().determineModule();
this.arity = calculateArity();
this.pushScope = true;
}

// We can probably use IRMethod callArgs for something (at least arity)
public InterpretedIRMethod(IRScope method, RubyModule implementationClass) {
this(method, Visibility.PRIVATE, implementationClass);
if (!implementationClass.getRuntime().getInstanceConfig().getCompileMode().shouldJIT()) {
this.box.callCount = -1;
}
}

public IRScope getIRMethod() {
return method;
}

public CompiledIRMethod getCompiledIRMethod() {
public DynamicMethod getActualMethod() {
return box.actualMethod;
}

Expand Down Expand Up @@ -94,7 +84,10 @@ public Arity getArity() {

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
if (tryCompile(context)) return callJitted(context, self, clazz, name, args, block);
DynamicMethodBox box = this.box;
if (box.callCount >= 0) tryJit(context, box);
DynamicMethod actualMethod = box.actualMethod;
if (actualMethod != null) return actualMethod.call(context, self, clazz, name, args, block);

ensureInstrsReady();

Expand Down Expand Up @@ -171,60 +164,33 @@ public void switchToJitted(CompiledIRMethod newMethod) {
}


private boolean tryCompile(ThreadContext context) {
if (box.actualMethod != null) {
return true;
}

context.runtime.getJITCompiler().jitThresholdReached(this, context.runtime.getInstanceConfig(), context, getImplementationClass().getName(), getName());
private void tryJit(ThreadContext context, DynamicMethodBox box) {
Ruby runtime = context.runtime;

// don't JIT during runtime boot
if (context.runtime.isBooting()) return false;
if (runtime.isBooting()) return;

String className;
if (implementationClass.isSingleton()) {
MetaClass metaClass = (MetaClass)implementationClass;
RubyClass realClass = metaClass.getRealClass();
// if real class is Class
if (realClass == context.runtime.getClassClass()) {
// use the attached class's name
className = ((RubyClass)metaClass.getAttached()).getName();
} else {
// use the real class name
className = realClass.getName();
}
} else {
// use the class name
className = implementationClass.getName();
}

if (box.callCount == -1) return false;

if (box.callCount++ >= Options.JIT_THRESHOLD.load()) {

box.callCount = -1; // disable...we get one shot
Ruby runtime = context.runtime;
RubyInstanceConfig config = runtime.getInstanceConfig();

if (config.getCompileMode().shouldJIT()) {

ensureInstrsReady();

try {
Class compiled = JVMVisitor.compile(method, new OneShotClassLoader(context.runtime.getJRubyClassLoader()));
Method scriptMethod = compiled.getMethod(
"__script__",
ThreadContext.class,
StaticScope.class,
IRubyObject.class,
IRubyObject[].class,
Block.class,
RubyModule.class);
MethodHandle handle = MethodHandles.publicLookup().unreflect(scriptMethod);
box.actualMethod = new CompiledIRMethod(handle, getName(), getFile(), getLine(), method.getStaticScope(), getVisibility(), getImplementationClass(), Helpers.encodeParameterList(getParameterList()), method.hasExplicitCallProtocol());

if (config.isJitLogging()) {
LOG.info("done jitting: " + method);
}

return true;
} catch (Throwable e) {
if (config.isJitLogging()) {
LOG.info("failed to jit (" + e.getMessage() + "): " + method);
if (config.isJitLoggingVerbose()) {
StringWriter trace = new StringWriter();
PrintWriter writer = new PrintWriter(trace);
e.printStackTrace(writer);
LOG.info(trace.toString());
}
}
}
}
context.runtime.getJITCompiler().jitThresholdReached(this, context.runtime.getInstanceConfig(), context, className, name);
}
return false;
}

public void setActualMethod(CompiledIRMethod method) {
Expand Down
Expand Up @@ -8,7 +8,6 @@
import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.ScopeModule;
import org.jruby.ir.operands.UndefinedValue;
import org.jruby.ir.operands.Variable;
import org.jruby.ir.transformations.inlining.InlinerInfo;
Expand Down
Expand Up @@ -9,7 +9,6 @@
import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.ScopeModule;
import org.jruby.ir.transformations.inlining.InlinerInfo;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.DynamicScope;
Expand Down
Expand Up @@ -6,7 +6,6 @@
import org.jruby.internal.runtime.methods.InterpretedIRMethod;
import org.jruby.ir.*;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.ScopeModule;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.ir.transformations.inlining.InlinerInfo;
import org.jruby.parser.StaticScope;
Expand Down
Expand Up @@ -6,7 +6,6 @@
import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.operands.ScopeModule;
import org.jruby.ir.operands.Variable;
import org.jruby.ir.transformations.inlining.InlinerInfo;
import org.jruby.parser.StaticScope;
Expand Down
5 changes: 4 additions & 1 deletion core/src/main/java/org/jruby/ir/targets/Bootstrap.java
Expand Up @@ -814,7 +814,10 @@ private static MethodHandle getHandle(RubyClass selfClass, String fallbackName,
if (method instanceof CompiledIRMethod) {
compiledIRMethod = (CompiledIRMethod)method;
} else if (method instanceof InterpretedIRMethod) {
compiledIRMethod = ((InterpretedIRMethod)method).getCompiledIRMethod();
DynamicMethod actualMethod = ((InterpretedIRMethod)method).getActualMethod();
if (actualMethod instanceof CompiledIRMethod) {
compiledIRMethod = (CompiledIRMethod)actualMethod;
}
}

if (compiledIRMethod != null) {
Expand Down

0 comments on commit 41de7c6

Please sign in to comment.