Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Load the compiler reflectively.
Browse files Browse the repository at this point in the history
First step in making packaging the copiler optional.
donv committed May 24, 2015
1 parent 8a9f17c commit 213c2c7
Showing 3 changed files with 64 additions and 24 deletions.
51 changes: 29 additions & 22 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -48,15 +48,14 @@
import org.jruby.ast.GlobalVarNode;
import org.jruby.ast.VCallNode;
import org.jruby.ast.WhileNode;
import org.jruby.compiler.Compiler;
import org.jruby.compiler.Constantizable;
import org.jruby.compiler.NotCompilableException;
import org.jruby.ext.thread.ThreadLibrary;
import org.jruby.ir.IRScriptBody;
import org.jruby.javasupport.JavaSupport;
import org.jruby.javasupport.JavaSupportImpl;
import org.jruby.lexer.yacc.ISourcePosition;
import org.jruby.parser.StaticScope;
import org.jruby.util.ClassDefiningClassLoader;
import org.objectweb.asm.util.TraceClassVisitor;

import jnr.constants.Constant;
@@ -94,7 +93,6 @@
import org.jruby.internal.runtime.methods.CallConfiguration;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.internal.runtime.methods.JavaMethod;
import org.jruby.ir.Compiler;
import org.jruby.ir.IRManager;
import org.jruby.ir.interpreter.Interpreter;
import org.jruby.ir.persistence.IRReader;
@@ -217,6 +215,7 @@ public final class Ruby implements Constantizable {
* The logger used to log relevant bits.
*/
private static final Logger LOG = LoggerFactory.getLogger("Ruby");
private final Compiler compiler;

/**
* Create and initialize a new JRuby runtime. The properties of the
@@ -244,7 +243,6 @@ private Ruby(RubyInstanceConfig config) {

this.staticScopeFactory = new StaticScopeFactory(this);
this.beanManager = BeanManagerFactory.create(this, config.isManagementEnabled());
this.jitCompiler = new JITCompiler(this);
this.parserStats = new ParserStats(this);

Random myRandom;
@@ -280,11 +278,34 @@ private Ruby(RubyInstanceConfig config) {
objectSpacer = DISABLED_OBJECTSPACE;
}

if (config.getCompileMode().shouldJIT()) {
final Class<?> clazz;

try {
clazz = getJRubyClassLoader().loadClass("org.jruby.ir.Compiler");
} catch (Exception e) {
throw new RuntimeException("Compiler not available", e);
}

try {
Constructor<?> con = clazz.getConstructor();
compiler = (Compiler) con.newInstance();
} catch (Exception e) {
throw new RuntimeException("Error while calling the constructor of the IR compiler", e);
}
jitCompiler = new JITCompiler(this);
} else {
compiler = null;
jitCompiler = null;
}

reinitialize(false);
}

public void registerMBeans() {
this.beanManager.register(jitCompiler);
if (jitCompiler != null) {
this.beanManager.register(jitCompiler);
}
this.beanManager.register(configBean);
this.beanManager.register(parserStats);
this.beanManager.register(runtimeBean);
@@ -764,7 +785,7 @@ private ScriptAndCode precompileCLI(Node scriptNode) {
// IR JIT does not handle all scripts yet, so let those that fail run in interpreter instead
// FIXME: restore error once JIT should handle everything
try {
scriptAndCode = tryCompile(scriptNode, new ClassDefiningJRubyClassLoader(getJRubyClassLoader()));
scriptAndCode = compiler.tryCompile(scriptNode, new ClassDefiningJRubyClassLoader(getJRubyClassLoader()), this);
if (scriptAndCode != null && Options.JIT_LOGGING.load()) {
LOG.info("done compiling target script: " + scriptNode.getPosition().getFile());
}
@@ -788,7 +809,7 @@ private ScriptAndCode precompileCLI(Node scriptNode) {
* @return an instance of the successfully-compiled Script, or null.
*/
public Script tryCompile(Node node) {
return tryCompile(node, new ClassDefiningJRubyClassLoader(getJRubyClassLoader())).script();
return compiler.tryCompile(node, new ClassDefiningJRubyClassLoader(getJRubyClassLoader()), this).script();
}

private void failForcedCompile(Node scriptNode) throws RaiseException {
@@ -804,20 +825,6 @@ private void handeCompileError(Node node, Throwable t) {
}
}

private ScriptAndCode tryCompile(Node node, ClassDefiningClassLoader classLoader) {
try {
return Compiler.getInstance().execute(this, node, classLoader);
} catch (NotCompilableException e) {
if (Options.JIT_LOGGING.load()) {
LOG.error("failed to compile target script " + node.getPosition().getFile() + ": " + e.getLocalizedMessage());
if (Options.JIT_LOGGING_VERBOSE.load()) {
LOG.error(e);
}
}
return null;
}
}

public IRubyObject runScript(Script script) {
return runScript(script, false);
}
@@ -2981,7 +2988,7 @@ public void compileAndLoadFile(String filename, InputStream in, boolean wrap) {
// script was not found in cache above, so proceed to compile
Node scriptNode = parseFile(readStream, filename, null);
if (script == null) {
scriptAndCode = tryCompile(scriptNode, new ClassDefiningJRubyClassLoader(jrubyClassLoader));
scriptAndCode = compiler.tryCompile(scriptNode, new ClassDefiningJRubyClassLoader(jrubyClassLoader), this);
if (scriptAndCode != null) script = scriptAndCode.script();
}

13 changes: 13 additions & 0 deletions core/src/main/java/org/jruby/compiler/Compiler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.jruby.compiler;

import org.jruby.Ruby;
import org.jruby.ast.Node;
import org.jruby.ast.executable.ScriptAndCode;
import org.jruby.util.ClassDefiningClassLoader;

/**
* Created by uwe on 20/5/15.
*/
public interface Compiler {
ScriptAndCode tryCompile(Node node, ClassDefiningClassLoader classLoader, Ruby ruby);
}
24 changes: 22 additions & 2 deletions core/src/main/java/org/jruby/ir/Compiler.java
Original file line number Diff line number Diff line change
@@ -6,6 +6,7 @@

import org.jruby.Ruby;
import org.jruby.RubyModule;
import org.jruby.ast.Node;
import org.jruby.ast.executable.AbstractScript;
import org.jruby.ast.executable.Script;
import org.jruby.ast.executable.ScriptAndCode;
@@ -22,15 +23,34 @@
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.util.ClassDefiningClassLoader;
import org.jruby.util.cli.Options;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Method;

public class Compiler extends IRTranslator<ScriptAndCode, ClassDefiningClassLoader> {
public class Compiler extends IRTranslator<ScriptAndCode, ClassDefiningClassLoader> implements org.jruby.compiler.Compiler {
private static final Logger LOG = LoggerFactory.getLogger("Compiler");

// Compiler is singleton
private Compiler() {}
public Compiler() {}

@Override
public ScriptAndCode tryCompile(Node node, ClassDefiningClassLoader classLoader, Ruby ruby) {
try {
return getInstance().execute(ruby, node, classLoader);
} catch (NotCompilableException e) {
if (Options.JIT_LOGGING.load()) {
LOG.error("failed to compile target script " + node.getPosition().getFile() + ": " + e.getLocalizedMessage());
if (Options.JIT_LOGGING_VERBOSE.load()) {
LOG.error(e);
}
}
return null;
}
}

private static class CompilerHolder {
// FIXME: Remove as singleton unless lifus does later

0 comments on commit 213c2c7

Please sign in to comment.