Skip to content

Commit 4c5c563

Browse files
committed
Only load the IR compiler if it will be needed
1 parent 4da5af7 commit 4c5c563

20 files changed

+104
-88
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package org.jruby;
2+
3+
import org.jruby.ast.Node;
4+
import org.jruby.ast.executable.Script;
5+
import org.jruby.ast.executable.ScriptAndCode;
6+
import org.jruby.util.ClassDefiningClassLoader;
7+
8+
/**
9+
* Created by uwe on 20/5/15.
10+
*/
11+
public interface Compiler {
12+
Script tryCompile(Node scriptNode);
13+
14+
ScriptAndCode tryCompile(Node scriptNode, ClassDefiningClassLoader classDefiningClassLoader);
15+
}

core/src/main/java/org/jruby/compiler/Constantizable.java renamed to core/src/main/java/org/jruby/Constantizable.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package org.jruby.compiler;
1+
package org.jruby;
22

33
/**
44
* Represents an object that can produce a JIT-optimizable "constant" version of itself. Currently this is only used

core/src/main/java/org/jruby/Ruby.java

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,12 @@
4848
import org.jruby.ast.GlobalVarNode;
4949
import org.jruby.ast.VCallNode;
5050
import org.jruby.ast.WhileNode;
51-
import org.jruby.compiler.Constantizable;
52-
import org.jruby.compiler.NotCompilableException;
5351
import org.jruby.ext.thread.ThreadLibrary;
5452
import org.jruby.ir.IRScriptBody;
5553
import org.jruby.javasupport.JavaSupport;
5654
import org.jruby.javasupport.JavaSupportImpl;
5755
import org.jruby.lexer.yacc.ISourcePosition;
5856
import org.jruby.parser.StaticScope;
59-
import org.jruby.util.ClassDefiningClassLoader;
6057
import org.objectweb.asm.util.TraceClassVisitor;
6158

6259
import jnr.constants.Constant;
@@ -75,7 +72,6 @@
7572
import org.jruby.ast.executable.ScriptAndCode;
7673
import org.jruby.common.IRubyWarnings.ID;
7774
import org.jruby.common.RubyWarnings;
78-
import org.jruby.compiler.JITCompiler;
7975
import org.jruby.embed.Extension;
8076
import org.jruby.exceptions.JumpException;
8177
import org.jruby.exceptions.MainExitException;
@@ -94,7 +90,6 @@
9490
import org.jruby.internal.runtime.methods.CallConfiguration;
9591
import org.jruby.internal.runtime.methods.DynamicMethod;
9692
import org.jruby.internal.runtime.methods.JavaMethod;
97-
import org.jruby.ir.Compiler;
9893
import org.jruby.ir.IRManager;
9994
import org.jruby.ir.interpreter.Interpreter;
10095
import org.jruby.ir.persistence.IRReader;
@@ -104,6 +99,7 @@
10499
import org.jruby.management.BeanManager;
105100
import org.jruby.management.BeanManagerFactory;
106101
import org.jruby.management.Config;
102+
import org.jruby.management.JITCompiler;
107103
import org.jruby.management.ParserStats;
108104
import org.jruby.parser.Parser;
109105
import org.jruby.parser.ParserConfiguration;
@@ -280,9 +276,36 @@ private Ruby(RubyInstanceConfig config) {
280276
objectSpacer = DISABLED_OBJECTSPACE;
281277
}
282278

279+
this.interpreter = new Interpreter(this);
280+
281+
if (getInstanceConfig().getCompileMode().shouldJIT()) {
282+
final Class<?> clazz;
283+
284+
try {
285+
clazz = getJRubyClassLoader().loadClass("org.jruby.ir.Compiler");
286+
} catch (Exception e) {
287+
throw new RuntimeException("Compiler not available", e);
288+
}
289+
290+
try {
291+
Constructor<?> con = clazz.getConstructor(Ruby.class);
292+
compiler = (org.jruby.Compiler) con.newInstance(this);
293+
} catch (Exception e) {
294+
throw new RuntimeException("Error while calling the constructor of IR Compiler", e);
295+
}
296+
} else {
297+
compiler = null;
298+
}
299+
283300
reinitialize(false);
284301
}
285302

303+
private final org.jruby.Compiler compiler;
304+
305+
public Compiler getCompiler() {
306+
return compiler;
307+
}
308+
286309
public void registerMBeans() {
287310
this.beanManager.register(jitCompiler);
288311
this.beanManager.register(configBean);
@@ -471,7 +494,7 @@ public IRubyObject evalScriptlet(String script, DynamicScope scope) {
471494
context.preEvalScriptlet(scope);
472495

473496
try {
474-
return Interpreter.getInstance().execute(this, rootNode, context.getFrameSelf());
497+
return interpreter.execute(this, rootNode, context.getFrameSelf());
475498
} finally {
476499
context.postEvalScriptlet();
477500
}
@@ -651,7 +674,7 @@ public IRubyObject runWithGetsLoop(Node scriptNode, boolean printing, boolean pr
651674
boolean compile = getInstanceConfig().getCompileMode().shouldPrecompileCLI();
652675
if (compile) {
653676
try {
654-
script = tryCompile(scriptNode);
677+
script = compiler.tryCompile(scriptNode);
655678
if (Options.JIT_LOGGING.load()) {
656679
LOG.info("Successfully compiled: " + scriptNode.getPosition().getFile());
657680
}
@@ -764,7 +787,7 @@ private ScriptAndCode precompileCLI(Node scriptNode) {
764787
// IR JIT does not handle all scripts yet, so let those that fail run in interpreter instead
765788
// FIXME: restore error once JIT should handle everything
766789
try {
767-
scriptAndCode = tryCompile(scriptNode, new ClassDefiningJRubyClassLoader(getJRubyClassLoader()));
790+
scriptAndCode = compiler.tryCompile(scriptNode, new ClassDefiningJRubyClassLoader(getJRubyClassLoader()));
768791
if (scriptAndCode != null && Options.JIT_LOGGING.load()) {
769792
LOG.info("done compiling target script: " + scriptNode.getPosition().getFile());
770793
}
@@ -779,18 +802,6 @@ private ScriptAndCode precompileCLI(Node scriptNode) {
779802
return scriptAndCode;
780803
}
781804

782-
/**
783-
* Try to compile the code associated with the given Node, returning an
784-
* instance of the successfully-compiled Script or null if the script could
785-
* not be compiled.
786-
*
787-
* @param node The node to attempt to compiled
788-
* @return an instance of the successfully-compiled Script, or null.
789-
*/
790-
public Script tryCompile(Node node) {
791-
return tryCompile(node, new ClassDefiningJRubyClassLoader(getJRubyClassLoader())).script();
792-
}
793-
794805
private void failForcedCompile(Node scriptNode) throws RaiseException {
795806
if (config.getCompileMode().shouldPrecompileAll()) {
796807
throw newRuntimeError("could not compile and compile mode is 'force': " + scriptNode.getPosition().getFile());
@@ -804,20 +815,6 @@ private void handeCompileError(Node node, Throwable t) {
804815
}
805816
}
806817

807-
private ScriptAndCode tryCompile(Node node, ClassDefiningClassLoader classLoader) {
808-
try {
809-
return Compiler.getInstance().execute(this, node, classLoader);
810-
} catch (NotCompilableException e) {
811-
if (Options.JIT_LOGGING.load()) {
812-
LOG.error("failed to compile target script " + node.getPosition().getFile() + ": " + e.getLocalizedMessage());
813-
if (Options.JIT_LOGGING_VERBOSE.load()) {
814-
LOG.error(e);
815-
}
816-
}
817-
return null;
818-
}
819-
}
820-
821818
public IRubyObject runScript(Script script) {
822819
return runScript(script, false);
823820
}
@@ -856,7 +853,7 @@ public IRubyObject runInterpreter(ThreadContext context, ParseResult parseResult
856853
}
857854

858855
try {
859-
return Interpreter.getInstance().execute(this, parseResult, self);
856+
return interpreter.execute(this, parseResult, self);
860857
} catch (JumpException.ReturnJump rj) {
861858
return (IRubyObject) rj.getValue();
862859
}
@@ -874,7 +871,7 @@ public IRubyObject runInterpreter(ThreadContext context, Node rootNode, IRubyObj
874871
try {
875872

876873
// FIXME: retrieve from IRManager unless lifus does it later
877-
return Interpreter.getInstance().execute(this, rootNode, self);
874+
return interpreter.execute(this, rootNode, self);
878875
} catch (JumpException.ReturnJump rj) {
879876
return (IRubyObject) rj.getValue();
880877
}
@@ -2981,7 +2978,7 @@ public void compileAndLoadFile(String filename, InputStream in, boolean wrap) {
29812978
// script was not found in cache above, so proceed to compile
29822979
Node scriptNode = parseFile(readStream, filename, null);
29832980
if (script == null) {
2984-
scriptAndCode = tryCompile(scriptNode, new ClassDefiningJRubyClassLoader(jrubyClassLoader));
2981+
scriptAndCode = compiler.tryCompile(scriptNode, new ClassDefiningJRubyClassLoader(jrubyClassLoader));
29852982
if (scriptAndCode != null) script = scriptAndCode.script();
29862983
}
29872984

@@ -3058,6 +3055,8 @@ public JavaProxyClassFactory getJavaProxyClassFactory() {
30583055
return javaProxyClassFactory;
30593056
}
30603057

3058+
private final Interpreter interpreter;
3059+
30613060
public class CallTraceFuncHook extends EventHook {
30623061
private RubyProc traceFunc;
30633062
private EnumSet<RubyEvent> interest =
@@ -4775,7 +4774,7 @@ private void setNetworkStack() {
47754774
}
47764775

47774776
/**
4778-
* @see org.jruby.compiler.Constantizable
4777+
* @see Constantizable
47794778
*/
47804779
@Override
47814780
public Object constant() {

core/src/main/java/org/jruby/RubyBoolean.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434

3535
import org.jruby.anno.JRubyClass;
3636
import org.jruby.anno.JRubyMethod;
37-
import org.jruby.compiler.Constantizable;
3837
import org.jruby.runtime.ClassIndex;
3938
import org.jruby.runtime.ObjectAllocator;
4039
import org.jruby.runtime.ThreadContext;
@@ -91,7 +90,7 @@ public Class<?> getJavaClass() {
9190
}
9291

9392
/**
94-
* @see org.jruby.compiler.Constantizable
93+
* @see Constantizable
9594
*/
9695
@Override
9796
public Object constant() {

core/src/main/java/org/jruby/RubyEncoding.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.jcodings.util.Hash.HashEntryIterator;
4242
import org.jruby.anno.JRubyClass;
4343
import org.jruby.anno.JRubyMethod;
44-
import org.jruby.compiler.Constantizable;
4544
import org.jruby.runtime.ClassIndex;
4645
import org.jruby.runtime.ObjectAllocator;
4746
import org.jruby.runtime.ThreadContext;
@@ -101,7 +100,7 @@ private RubyEncoding(Ruby runtime, ByteList name, Encoding encoding, boolean isD
101100
}
102101

103102
/**
104-
* @see org.jruby.compiler.Constantizable
103+
* @see Constantizable
105104
*/
106105
@Override
107106
public Object constant() {

core/src/main/java/org/jruby/RubyFixnum.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@
3939
import org.jcodings.specific.USASCIIEncoding;
4040
import org.jruby.anno.JRubyClass;
4141
import org.jruby.anno.JRubyMethod;
42-
import org.jruby.compiler.Constantizable;
4342
import org.jruby.runtime.Block;
44-
import org.jruby.runtime.BlockBody;
4543
import org.jruby.runtime.ClassIndex;
4644
import org.jruby.runtime.Helpers;
4745
import org.jruby.runtime.ObjectAllocator;
@@ -133,7 +131,7 @@ public ClassIndex getNativeClassIndex() {
133131
}
134132

135133
/**
136-
* @see org.jruby.compiler.Constantizable
134+
* @see Constantizable
137135
*/
138136
@Override
139137
public Object constant() {

core/src/main/java/org/jruby/RubyNil.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434

3535
import org.jruby.anno.JRubyMethod;
3636
import org.jruby.anno.JRubyClass;
37-
import org.jruby.compiler.Constantizable;
3837
import org.jruby.runtime.ClassIndex;
3938
import org.jruby.runtime.ObjectAllocator;
4039
import org.jruby.runtime.ThreadContext;
@@ -110,7 +109,7 @@ public Class<?> getJavaClass() {
110109
}
111110

112111
/**
113-
* @see org.jruby.compiler.Constantizable
112+
* @see Constantizable
114113
*/
115114
@Override
116115
public Object constant() {

core/src/main/java/org/jruby/RubySymbol.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,7 @@
4141
import org.jruby.anno.JRubyClass;
4242
import org.jruby.anno.JRubyMethod;
4343
import org.jruby.ast.util.ArgsUtil;
44-
import org.jruby.compiler.Constantizable;
4544
import org.jruby.parser.StaticScope;
46-
import org.jruby.runtime.Arity;
4745
import org.jruby.runtime.Binding;
4846
import org.jruby.runtime.Block;
4947
import org.jruby.runtime.Block.Type;
@@ -207,7 +205,7 @@ public static RubySymbol newSymbol(Ruby runtime, String name, Encoding encoding)
207205
}
208206

209207
/**
210-
* @see org.jruby.compiler.Constantizable
208+
* @see Constantizable
211209
*/
212210
@Override
213211
public Object constant() {

core/src/main/java/org/jruby/compiler/util/HandleFactory.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
import java.io.IOException;
3434
import java.lang.reflect.Method;
3535
import java.lang.reflect.Modifier;
36-
import org.jruby.compiler.JITCompiler;
3736
import org.jruby.compiler.impl.SkinnyMethodAdapter;
37+
import org.jruby.management.JITCompiler;
3838
import org.jruby.util.ClassDefiningClassLoader;
3939
import org.jruby.util.ClassDefiningJRubyClassLoader;
4040
import org.objectweb.asm.ClassVisitor;

core/src/main/java/org/jruby/embed/internal/EmbedRubyRuntimeAdapterImpl.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import java.io.InputStream;
3737
import java.io.Reader;
3838
import java.io.StringReader;
39-
import java.io.Writer;
4039
import java.net.URL;
4140

4241
import org.jruby.Ruby;
@@ -192,7 +191,7 @@ private EmbedEvalUnit runParser(Object input, String filename, int... lines) {
192191
CompileMode compileMode = runtime.getInstanceConfig().getCompileMode();
193192
if (compileMode == CompileMode.FORCE) {
194193
// CON FIXME: We may need to force heap variables here so the compiled script uses our provided scope
195-
Script script = runtime.tryCompile(node);
194+
Script script = runtime.getCompiler().tryCompile(node);
196195
if (script != null) {
197196
return new EmbedEvalUnitImpl(container, node, scope, script);
198197
} else {

core/src/main/java/org/jruby/ir/Compiler.java

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import org.jruby.Ruby;
88
import org.jruby.RubyModule;
9+
import org.jruby.ast.Node;
910
import org.jruby.ast.executable.AbstractScript;
1011
import org.jruby.ast.executable.Script;
1112
import org.jruby.ast.executable.ScriptAndCode;
@@ -22,27 +23,51 @@
2223
import org.jruby.runtime.Visibility;
2324
import org.jruby.runtime.builtin.IRubyObject;
2425
import org.jruby.util.ClassDefiningClassLoader;
26+
import org.jruby.util.ClassDefiningJRubyClassLoader;
27+
import org.jruby.util.cli.Options;
28+
import org.jruby.util.log.Logger;
29+
import org.jruby.util.log.LoggerFactory;
2530

2631
import java.lang.invoke.MethodHandle;
2732
import java.lang.invoke.MethodHandles;
2833
import java.lang.reflect.Method;
2934

30-
public class Compiler extends IRTranslator<ScriptAndCode, ClassDefiningClassLoader> {
35+
public class Compiler extends IRTranslator<ScriptAndCode, ClassDefiningClassLoader> implements org.jruby.Compiler {
36+
private static final Logger LOG = LoggerFactory.getLogger("Compiler");
37+
private final Ruby ruby;
3138

32-
// Compiler is singleton
33-
private Compiler() {}
39+
public Compiler(Ruby ruby) {
40+
this.ruby = ruby;
41+
}
3442

35-
private static class CompilerHolder {
36-
// FIXME: Remove as singleton unless lifus does later
37-
public static final Compiler instance = new Compiler();
43+
/**
44+
* Try to compile the code associated with the given Node, returning an
45+
* instance of the successfully-compiled Script or null if the script could
46+
* not be compiled.
47+
*
48+
* @param node The node to attempt to compiled
49+
* @return an instance of the successfully-compiled Script, or null.
50+
*/
51+
public Script tryCompile(Node node) {
52+
return tryCompile(node, new ClassDefiningJRubyClassLoader(ruby.getJRubyClassLoader())).script();
3853
}
3954

40-
public static Compiler getInstance() {
41-
return CompilerHolder.instance;
55+
public ScriptAndCode tryCompile(Node node, ClassDefiningClassLoader classLoader) {
56+
try {
57+
return execute(ruby, node, classLoader);
58+
} catch (NotCompilableException e) {
59+
if (Options.JIT_LOGGING.load()) {
60+
LOG.error("failed to compile target script " + node.getPosition().getFile() + ": " + e.getLocalizedMessage());
61+
if (Options.JIT_LOGGING_VERBOSE.load()) {
62+
LOG.error(e);
63+
}
64+
}
65+
return null;
66+
}
4267
}
4368

4469
@Override
45-
protected ScriptAndCode execute(final Ruby runtime, final IRScriptBody scope, ClassDefiningClassLoader classLoader) {
70+
protected ScriptAndCode execute(final IRScriptBody scope, ClassDefiningClassLoader classLoader) {
4671
JVMVisitor visitor;
4772
byte[] bytecode;
4873
Class compiled;

0 commit comments

Comments
 (0)