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: f048d4f5987e
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 88bab9990347
Choose a head ref

Commits on Mar 3, 2015

  1. Copy the full SHA
    54bcd35 View commit details
  2. Things we are minimally building and interpreting will now be more ob…

    …vious BEGIN/END/eval
    enebo committed Mar 3, 2015
    Copy the full SHA
    6a494f9 View commit details
  3. Copy the full SHA
    d823301 View commit details
  4. Copy the full SHA
    d6ebbb3 View commit details
  5. Copy the full SHA
    cba0983 View commit details
  6. Copy the full SHA
    8bf22fa View commit details
  7. Copy the full SHA
    b1f9c42 View commit details
  8. Copy the full SHA
    f9b3bfe View commit details
  9. Copy the full SHA
    8c6a32c View commit details
  10. Copy the full SHA
    ac3bc8a View commit details
  11. CFG can use Instr[] to build

    enebo committed Mar 3, 2015
    Copy the full SHA
    5ad4c5c View commit details
  12. 2
    Copy the full SHA
    dee6c77 View commit details
  13. Copy the full SHA
    675a0eb View commit details
  14. Copy the full SHA
    3c73e40 View commit details
  15. Copy the full SHA
    4462b99 View commit details
  16. Copy the full SHA
    9854e78 View commit details
  17. Copy the full SHA
    c1990ca View commit details
  18. Copy the full SHA
    766a91e View commit details
  19. lots of rearrangement and state added to fullinterpretercontext and s…

    …ome basic outline of flow in prepareFullBuild
    enebo committed Mar 3, 2015
    Copy the full SHA
    e2964e5 View commit details
  20. Copy the full SHA
    16def94 View commit details
  21. Copy the full SHA
    8355e22 View commit details
  22. Copy the full SHA
    5168e0e View commit details
  23. Copy the full SHA
    70539bb View commit details
  24. Copy the full SHA
    a6f82b8 View commit details
  25. Copy the full SHA
    e1d1877 View commit details
  26. Whoops added errant println

    enebo committed Mar 3, 2015
    Copy the full SHA
    d8f0060 View commit details
  27. Copy the full SHA
    112b450 View commit details
  28. Last sloppy commit. CFGBuilder removed from compilerpasses. JIT/Full …

    …build race problem finally solved
    enebo committed Mar 3, 2015
    Copy the full SHA
    63c8149 View commit details
  29. Unbreak the JI code so specs run again and comment out flip specs sin…

    …ce they test flip migrating through eval (which is currently broken and is amazing it ever worked
    enebo committed Mar 3, 2015
    Copy the full SHA
    8c13270 View commit details
  30. Enable OptimizeTempVarsPass again

    * Fix use of the incorrect instruction list
    subbuss committed Mar 3, 2015
    Copy the full SHA
    8e1e2f8 View commit details
  31. Fix incorrect CFG fetch in LocalOptimizationPass

    * Now -X-C runs with all passes again.
    subbuss committed Mar 3, 2015
    Copy the full SHA
    6ec9f98 View commit details
  32. Add LocalOptimizationPass to default JIT passes

    * Also renamed DEFAULT_COMPILER_PASSES to DEFAULT_BUILD_PASSES
      to clarify that these are passes that run for interpreter.
    subbuss committed Mar 3, 2015
    Copy the full SHA
    107f4c0 View commit details
  33. OptimizeTempVarsPass doesn't need to run on child scopes upfront

    * Let this run on child scopes on demand so that it follows the
      new lifecycle.
    
    * Eliminates crashers when run on closures from parent scopes.
    subbuss committed Mar 3, 2015
    Copy the full SHA
    03bc9c6 View commit details

Commits on Mar 4, 2015

  1. CFG.toStringInstrs: Don't dump CFG of nested scopes

    * This can be extremely distracting in debugging output.
    * Users of CFG debug output that need output from nested scopes
      should explicitly do it where required.
    subbuss committed Mar 4, 2015
    Copy the full SHA
    2e4c5f9 View commit details
  2. Build full interpreter contexts for closures on demand

    * No need to build full ICs for closures eagerly.
    
    * Had to add some null checks for access to ICs in a couple
      places when I experimented turning off passes on nested scopes
      (LocalOptimizationPass, AddLocalVarLoadStoreInstructionsPass).
      Keeps that code more robust and usable in different lifecycles.
    subbuss committed Mar 4, 2015
    Copy the full SHA
    6a8701b View commit details
  3. Make LVA dependent on OptimizeDynScopesPass

    * If LVA is to run independently on closures (without parent scopes),
      it needs info about whether dyn scopes have been eliminated or not
      (see access to IRFlags.DYNSCOPE_ELIMINATED in the code).
      So, making that dependency explicit.
    subbuss committed Mar 4, 2015
    Copy the full SHA
    0dbe1b2 View commit details
  4. OptimizeTempVarsPass is now just a collection of static methods and n…

    …ot inheriting from CompilerPass.
    
    clonedInstrs is no longer a field in IRScope and is a local in prepareFullBuildCommon.
    enebo committed Mar 4, 2015
    Copy the full SHA
    88eeb49 View commit details
  5. Copy the full SHA
    9fd5d46 View commit details
  6. Add new test:mri:int_full which is jit.threshold=0 to force full buil…

    …d tests for full interpreter.
    enebo committed Mar 4, 2015
    Copy the full SHA
    43f0463 View commit details
  7. Remove special fic check in getCFG. Partially brittle because I only …

    …guard in LOP pass for closures
    enebo committed Mar 4, 2015
    Copy the full SHA
    974016f View commit details

Commits on Mar 5, 2015

  1. Fix bug in LVA + simplify it

    * LVA was attempting to analyze closures in the context of their
      parent scope's LVA context. The code was general enough that if
      we knew more information about specific call sites, it would have
      done better.
    
      However, in reality, given that we don't know too much about
      call sites, (a) all that code was extra complexity (b) it was
      really doing anything in terms of not being conservative (because
      all calls are being treated as dataflow barriers right now)
      (c) in the only case where it would not have been conservative,
      it was actually making an incorrect assumption that the closure
      will execute at the call site where it is defined and hence
      incorrectly marking a variable dead when it wasn't.
    
    * The fix was to simply eliminate the analysis of closures in the
      context of the parent's scope. We already had support for
      independent LVA of closures which takes care of scenario (c) above
      by marking all dirtied vars live on "entry" (which in the case of
      LVA, which is a backwards pass, is the control flow exit).
    
      This now fixes the failing snippet (see below) and should also
      eliminate the remaining test:mri:jit failures.
    [subbu@earth ir] jruby -Xjit.threshold=0 -e "z = 5; x = Hash.new {|h,kk| z = kk }; z=0; x[22]; p z"
    22
    
    Conflicts:
    	core/src/main/java/org/jruby/ir/dataflow/analyses/LiveVariableNode.java
    	core/src/main/java/org/jruby/ir/passes/LiveVariableAnalysis.java
    subbuss committed Mar 5, 2015
    Copy the full SHA
    f48c871 View commit details
  2. Copy the full SHA
    699c833 View commit details
  3. Fix NPEs in full builds

    subbuss committed Mar 5, 2015
    Copy the full SHA
    566a3b6 View commit details
  4. Change LVA.previouslyRun check to return null if it has never made a …

    …CFG before vs making on demand.
    
      The basic mechanics of CompilerPass on a null return will naturally run the pass on it which will
      generate the CFG on demand along with the data.
    Add comment in getCFG explaining when fic will be null.
    Comment out child closure passing from LOP because we don't want it but left it comments out because
      it exposes some lifecycle problems.  Once we stabilize hypernugget and merge back to master we
      will dig into this problem more.
    enebo committed Mar 5, 2015
    Copy the full SHA
    0c83a8c View commit details
  5. Copy the full SHA
    7789ebe View commit details
  6. Make IRScope.getLiveVariablesProblem add convenience cast to LiveVari…

    …ablesProblem.
    
    Remove DataFlowConstants since it was already mostly dead.
    Hook up more LVP getters to reduce externalized use of FIC.
    enebo committed Mar 5, 2015
    Copy the full SHA
    0b65fe8 View commit details
  7. Copy the full SHA
    cd796d0 View commit details
  8. Copy the full SHA
    a5e6a7b View commit details
  9. New IRScope.{get,put}StoreLocalVarPlacementProblem. fic is only refer…

    …ences in IRScope now.
    enebo committed Mar 5, 2015
    Copy the full SHA
    2be82aa View commit details
  10. Copy the full SHA
    27504e2 View commit details
Showing with 1,779 additions and 1,362 deletions.
  1. +1 −1 core/src/main/java/org/jruby/Ruby.java
  2. +19 −0 core/src/main/java/org/jruby/compiler/FullBuildSource.java
  3. +68 −19 core/src/main/java/org/jruby/compiler/JITCompiler.java
  4. +22 −8 core/src/main/java/org/jruby/ext/jruby/JRubyLibrary.java
  5. +1 −1 core/src/main/java/org/jruby/internal/runtime/methods/IRMethodArgs.java
  6. +7 −9 core/src/main/java/org/jruby/internal/runtime/methods/InterpretedIRBodyMethod.java
  7. +0 −13 core/src/main/java/org/jruby/internal/runtime/methods/InterpretedIRMetaClassBody.java
  8. +58 −144 core/src/main/java/org/jruby/internal/runtime/methods/InterpretedIRMethod.java
  9. +369 −0 core/src/main/java/org/jruby/internal/runtime/methods/MixedModeIRMethod.java
  10. +1 −1 core/src/main/java/org/jruby/ir/IRBindingEvalScript.java
  11. +180 −47 core/src/main/java/org/jruby/ir/IRBuilder.java
  12. +24 −49 core/src/main/java/org/jruby/ir/IRClosure.java
  13. +4 −2 core/src/main/java/org/jruby/ir/IREvalScript.java
  14. +4 −4 core/src/main/java/org/jruby/ir/IRFor.java
  15. +45 −4 core/src/main/java/org/jruby/ir/IRManager.java
  16. +21 −24 core/src/main/java/org/jruby/ir/IRMethod.java
  17. +197 −471 core/src/main/java/org/jruby/ir/IRScope.java
  18. +5 −3 core/src/main/java/org/jruby/ir/IRScriptBody.java
  19. +4 −1 core/src/main/java/org/jruby/ir/IRTranslator.java
  20. +0 −13 core/src/main/java/org/jruby/ir/dataflow/DataFlowConstants.java
  21. +9 −25 core/src/main/java/org/jruby/ir/dataflow/DataFlowProblem.java
  22. +1 −1 core/src/main/java/org/jruby/ir/dataflow/FlowGraphNode.java
  23. +0 −2 core/src/main/java/org/jruby/ir/dataflow/analyses/LiveVariableNode.java
  24. +1 −1 core/src/main/java/org/jruby/ir/dataflow/analyses/LiveVariablesProblem.java
  25. +1 −1 core/src/main/java/org/jruby/ir/dataflow/analyses/LoadLocalVarPlacementNode.java
  26. +4 −8 core/src/main/java/org/jruby/ir/dataflow/analyses/StoreLocalVarPlacementNode.java
  27. +2 −2 core/src/main/java/org/jruby/ir/dataflow/analyses/StoreLocalVarPlacementProblem.java
  28. +4 −5 core/src/main/java/org/jruby/ir/dataflow/analyses/UnboxableOpsAnalysisNode.java
  29. +0 −1 core/src/main/java/org/jruby/ir/instructions/ProcessModuleBodyInstr.java
  30. +2 −4 core/src/main/java/org/jruby/ir/interpreter/BeginEndInterpreterContext.java
  31. +3 −2 core/src/main/java/org/jruby/ir/interpreter/ClosureInterpreterContext.java
  32. +172 −0 core/src/main/java/org/jruby/ir/interpreter/FullInterpreterContext.java
  33. +3 −9 core/src/main/java/org/jruby/ir/interpreter/Interpreter.java
  34. +88 −83 core/src/main/java/org/jruby/ir/interpreter/InterpreterContext.java
  35. +17 −40 core/src/main/java/org/jruby/ir/interpreter/InterpreterEngine.java
  36. +4 −4 core/src/main/java/org/jruby/ir/interpreter/Profiler.java
  37. +177 −0 core/src/main/java/org/jruby/ir/interpreter/StartupInterpreterEngine.java
  38. +24 −8 core/src/main/java/org/jruby/ir/operands/ClosureLocalVariable.java
  39. +0 −2 core/src/main/java/org/jruby/ir/operands/WrappedIRClosure.java
  40. +2 −15 core/src/main/java/org/jruby/ir/passes/AddCallProtocolInstructions.java
  41. +4 −13 core/src/main/java/org/jruby/ir/passes/AddLocalVarLoadStoreInstructions.java
  42. +0 −35 core/src/main/java/org/jruby/ir/passes/CFGBuilder.java
  43. +0 −4 core/src/main/java/org/jruby/ir/passes/DeadCodeElimination.java
  44. +1 −7 core/src/main/java/org/jruby/ir/passes/DominatorTreeBuilder.java
  45. +0 −14 core/src/main/java/org/jruby/ir/passes/EnsureTempsAssigned.java
  46. +0 −34 core/src/main/java/org/jruby/ir/passes/LinearizeCFG.java
  47. +5 −15 core/src/main/java/org/jruby/ir/passes/LiveVariableAnalysis.java
  48. +0 −19 core/src/main/java/org/jruby/ir/passes/LocalOptimizationPass.java
  49. +13 −18 core/src/main/java/org/jruby/ir/passes/OptimizeDelegationPass.java
  50. +3 −4 core/src/main/java/org/jruby/ir/passes/OptimizeDynScopesPass.java
  51. +30 −37 core/src/main/java/org/jruby/ir/passes/OptimizeTempVarsPass.java
  52. +2 −2 core/src/main/java/org/jruby/ir/passes/UnboxingPass.java
  53. +4 −3 core/src/main/java/org/jruby/ir/persistence/IRReader.java
  54. +1 −4 core/src/main/java/org/jruby/ir/persistence/IRWriter.java
  55. +1 −1 core/src/main/java/org/jruby/ir/persistence/IRWriterFile.java
  56. +1 −1 core/src/main/java/org/jruby/ir/persistence/OperandEncoderMap.java
  57. +1 −1 core/src/main/java/org/jruby/ir/representations/BasicBlock.java
  58. +13 −30 core/src/main/java/org/jruby/ir/representations/CFG.java
  59. +1 −1 core/src/main/java/org/jruby/ir/representations/CFGLinearizer.java
  60. +17 −9 core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
  61. +2 −4 core/src/main/java/org/jruby/ir/targets/Bootstrap.java
  62. +7 −22 core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
  63. +0 −2 core/src/main/java/org/jruby/ir/transformations/inlining/CFGInliner.java
  64. +6 −4 core/src/main/java/org/jruby/runtime/Helpers.java
  65. +58 −13 core/src/main/java/org/jruby/runtime/InterpretedIRBlockBody.java
  66. +2 −0 core/src/main/java/org/jruby/runtime/backtrace/FrameType.java
  67. +1 −1 core/src/main/ruby/jruby/jruby.rb
  68. +3 −3 lib/ruby/stdlib/jruby/ext.rb
  69. +4 −0 rakelib/test.rake
  70. +38 −31 spec/compiler/general_spec.rb
  71. +12 −0 spec/tags/ruby/language/if_tags.txt
  72. +2 −1 test/jruby.index
  73. +1 −0 test/mri/excludes/TestFlip.rb
  74. +2 −2 test/pom.xml
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -1254,7 +1254,7 @@ private void init() {
initThreadStatuses();

// Create an IR manager and a top-level IR scope and bind it to the top-level static-scope object
irManager = new IRManager();
irManager = new IRManager(getInstanceConfig());
// FIXME: This registers itself into static scope as a side-effect. Let's make this
// relationship handled either more directly or through a descriptice method
// FIXME: We need a failing test case for this since removing it did not regress tests
19 changes: 19 additions & 0 deletions core/src/main/java/org/jruby/compiler/FullBuildSource.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package org.jruby.compiler;

import org.jruby.RubyModule;
import org.jruby.ir.IRScope;
import org.jruby.ir.interpreter.InterpreterContext;

/**
* Blocks and methods both share same full build mechanism so they implement this to be buildable.
*/
public interface FullBuildSource {
public void setCallCount(int count);
public void switchToFullBuild(InterpreterContext interpreterContext);
public IRScope getIRScope();
public InterpreterContext ensureInstrsReady();
public String getName();
public String getFile();
public int getLine();
public RubyModule getImplementationClass();
}
87 changes: 68 additions & 19 deletions core/src/main/java/org/jruby/compiler/JITCompiler.java
Original file line number Diff line number Diff line change
@@ -36,12 +36,9 @@
import org.jruby.RubyModule;
import org.jruby.ast.util.SexpMaker;
import org.jruby.internal.runtime.methods.CompiledIRMethod;
import org.jruby.internal.runtime.methods.InterpretedIRMethod;
import org.jruby.internal.runtime.methods.MixedModeIRMethod;
import org.jruby.ir.IRMethod;
import org.jruby.ir.targets.JVMVisitor;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.threading.DaemonThreadFactory;
@@ -52,10 +49,8 @@
import org.jruby.util.log.LoggerFactory;
import org.objectweb.asm.Opcodes;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Locale;
@@ -150,8 +145,31 @@ public void tearDown() {
}
}
}

public void fullBuildThresholdReached(final FullBuildSource method, final RubyInstanceConfig config) {
// Disable any other jit tasks from entering queue
method.setCallCount(-1);

Runnable jitTask = new FullBuildTask(method);

if (config.getJitThreshold() > 0) {
if (config.getJitBackground() && executor != null) {
try {
executor.submit(jitTask);
} catch (RejectedExecutionException ree) {
// failed to submit, just run it directly
jitTask.run();
}
} else {
// Because are non-asynchonously build if the JIT threshold happens to be 0 we will have no ic yet.
method.ensureInstrsReady();
// just run directly
jitTask.run();
}
}
}

public void jitThresholdReached(final InterpretedIRMethod method, final RubyInstanceConfig config, ThreadContext context, final String className, final String methodName) {
public void jitThresholdReached(final MixedModeIRMethod method, final RubyInstanceConfig config, ThreadContext context, final String className, final String methodName) {
// Disable any other jit tasks from entering queue
method.setCallCount(-1);

@@ -169,19 +187,48 @@ public void jitThresholdReached(final InterpretedIRMethod method, final RubyInst
jitTask.run();
}
} else {
// Because are non-asynchonously build if the JIT threshold happens to be 0 we will have no ic yet.
method.ensureInstrsReady();

// just run directly
jitTask.run();
}
}

private static final MethodHandles.Lookup PUBLIC_LOOKUP = MethodHandles.publicLookup().in(Ruby.class);

private class FullBuildTask implements Runnable {
private final FullBuildSource method;

public FullBuildTask(FullBuildSource method) {
this.method = method;
}

public void run() {
try {
method.switchToFullBuild(method.getIRScope().prepareFullBuild());

if (config.isJitLogging()) {
log(method.getImplementationClass(), method.getFile(), method.getLine(), method.getName(), "done building");
}
} catch (Throwable t) {
if (config.isJitLogging()) {
log(method.getImplementationClass(), method.getFile(), method.getLine(), method.getName(),
"Could not build; passes run: " + method.getIRScope().getExecutedPasses(), t.getMessage());
if (config.isJitLoggingVerbose()) {
t.printStackTrace();
}
}
}
}
}

private class JITTask implements Runnable {
private final String className;
private final InterpretedIRMethod method;
private final MixedModeIRMethod method;
private final String methodName;

public JITTask(String className, InterpretedIRMethod method, String methodName) {
public JITTask(String className, MixedModeIRMethod method, String methodName) {
this.className = className;
this.method = method;
this.methodName = methodName;
@@ -203,7 +250,7 @@ public void run() {
|| config.getExcludedMethods().contains(excludeModuleName + "#" + methodName)
|| config.getExcludedMethods().contains(methodName))) {
method.setCallCount(-1);
log(method, methodName, "skipping method: " + excludeModuleName + "#" + methodName);
log(method.getImplementationClass(), method.getFile(), method.getLine(), methodName, "skipping method: " + excludeModuleName + "#" + methodName);
return;
}
}
@@ -235,12 +282,12 @@ public void run() {
// logEvery n methods based on configuration
if (config.getJitLogEvery() > 0) {
if (methodCount % config.getJitLogEvery() == 0) {
log(method, methodName, "live compiled methods: " + methodCount);
log(method.getImplementationClass(), method.getFile(), method.getLine(), methodName, "live compiled methods: " + methodCount);
}
}

if (config.isJitLogging()) {
log(method, className + "." + methodName, "done jitting");
log(method.getImplementationClass(), method.getFile(), method.getLine(), className + "." + methodName, "done jitting");
}

Map<Integer, MethodType> signatures = ((IRMethod)method.getIRMethod()).getNativeSignatures();
@@ -273,7 +320,7 @@ public void run() {
return;
} catch (Throwable t) {
if (config.isJitLogging()) {
log(method, className + "." + methodName, "Could not compile; passes run: " + method.getIRMethod().getExecutedPasses(), t.getMessage());
log(method.getImplementationClass(), method.getFile(), method.getLine(), className + "." + methodName, "Could not compile; passes run: " + method.getIRMethod().getExecutedPasses(), t.getMessage());
if (config.isJitLoggingVerbose()) {
t.printStackTrace();
}
@@ -305,7 +352,7 @@ public static String getHashForBytes(byte[] bytes) {
}

public static class JITClassGenerator {
public JITClassGenerator(String className, String methodName, String key, Ruby ruby, InterpretedIRMethod method, JVMVisitor visitor) {
public JITClassGenerator(String className, String methodName, String key, Ruby ruby, MixedModeIRMethod method, JVMVisitor visitor) {
this.packageName = JITCompiler.RUBY_JIT_PREFIX;
if (RubyInstanceConfig.JAVA_VERSION == Opcodes.V1_7 || Options.COMPILE_INVOKEDYNAMIC.load() == true) {
// Some versions of Java 7 seems to have a bug that leaks definitions across cousin classloaders
@@ -378,20 +425,22 @@ public String toString() {
private final String className;
private final String methodName;
private final String digestString;
private final InterpretedIRMethod method;
private final MixedModeIRMethod method;
private final JVMVisitor visitor;

private byte[] bytecode;
private long compileTime;
private String name;
}

static void log(InterpretedIRMethod method, String name, String message, String... reason) {
String className = method.getImplementationClass().getBaseName();

static void log(RubyModule implementationClass, String file, int line, String name, String message, String... reason) {
boolean isBlock = implementationClass == null;
String className = isBlock ? "<block>" : implementationClass.getBaseName();
if (className == null) className = "<anon class>";

StringBuilder builder = new StringBuilder(message + ":" + className + "." + name + " at " + method.getIRMethod().getFileName() + ":" + method.getIRMethod().getLineNumber());
name = isBlock ? "" : "." + name;

StringBuilder builder = new StringBuilder(message + ":" + className + name + " at " + file + ":" + line);

if (reason.length > 0) {
builder.append(" because of: \"");
30 changes: 22 additions & 8 deletions core/src/main/java/org/jruby/ext/jruby/JRubyLibrary.java
Original file line number Diff line number Diff line change
@@ -222,10 +222,17 @@ public static IRubyObject methodArgs(IRubyObject recv) {
argsArray.append(RubyArray.newArray(runtime, block, getNameFrom(runtime, args.getBlock())));
}
} else if (method instanceof IRMethodArgs) {
for (String[] argParam: ((IRMethodArgs)method).getParameterList()) {
RubySymbol argType = runtime.newSymbol(argParam[0]);
if (argParam[1] == "") argsArray.append(RubyArray.newArray(runtime, argType));
else argsArray.append(RubyArray.newArray(runtime, argType, runtime.newSymbol(argParam[1])));
String[] argsDesc = ((IRMethodArgs) method).getParameterList();

for (int i = 0; i < argsDesc.length; i++) {
RubySymbol argType = runtime.newSymbol(argsDesc[i]);
i++;
String argName = argsDesc[i];
if (argName.isEmpty()) {
argsArray.append(RubyArray.newArray(runtime, argType));
} else {
argsArray.append(RubyArray.newArray(runtime, argType, runtime.newSymbol(argName)));
}
}
} else {
if (method.getArity() == Arity.OPTIONAL) {
@@ -287,10 +294,17 @@ public static String[] methodParameters(Ruby runtime, DynamicMethod method) {
argsArray.add("b" + getNameFrom(runtime, args.getBlock()));
}
} else if (method instanceof IRMethodArgs) {
for (String[] argParam: ((IRMethodArgs)method).getParameterList()) {
RubySymbol argType = runtime.newSymbol(argParam[0]);
if (argParam[1] == "") argsArray.add(argParam[0]);
else argsArray.add(argParam[0] + argParam[1]);
String[] argsDesc = ((IRMethodArgs) method).getParameterList();

for (int i = 0; i < argsDesc.length; i++) {
String argType = argsDesc[i];
i++;
String argName = argsDesc[i];
if (argName.isEmpty()) {
argsArray.add(argType);
} else {
argsArray.add(argType + argName);
}
}
} else {
if (method.getArity() == Arity.OPTIONAL) {
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@
import java.util.List;

public interface IRMethodArgs {
public List<String[]> getParameterList();
public String[] getParameterList();

public enum ArgType {
key, keyreq, keyrest, block, opt, rest, req
Original file line number Diff line number Diff line change
@@ -18,12 +18,12 @@ public class InterpretedIRBodyMethod extends InterpretedIRMethod {
public InterpretedIRBodyMethod(IRScope method, RubyModule implementationClass) {
super(method, Visibility.PUBLIC, implementationClass);

this.box.callCount = -1;
callCount = -1;
}

@Override
public List<String[]> getParameterList() {
return new ArrayList<String[]>();
public String[] getParameterList() {
return new String[0];
}

@Override
@@ -40,9 +40,9 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz

protected IRubyObject callInternal(ThreadContext context, IRubyObject self, RubyModule clazz, String name, Block block) {
InterpreterContext ic = ensureInstrsReady();
if (!ic.hasExplicitCallProtocol()) {
this.pre(ic, context, self, name, block, getImplementationClass());
}

if (!ic.hasExplicitCallProtocol()) this.pre(ic, context, self, name, block, getImplementationClass());

try {
switch (method.getScopeType()) {
case MODULE_BODY: return INTERPRET_MODULE(ic, context, self, clazz, method.getName(), block);
@@ -51,9 +51,7 @@ protected IRubyObject callInternal(ThreadContext context, IRubyObject self, Ruby
default: throw new RuntimeException("invalid body method type: " + method);
}
} finally {
if (!ic.hasExplicitCallProtocol()) {
this.post(ic, context);
}
if (!ic.hasExplicitCallProtocol()) this.post(ic, context);
}
}

Original file line number Diff line number Diff line change
@@ -38,21 +38,8 @@ protected void pre(InterpreterContext ic, ThreadContext context, IRubyObject sel

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, Block 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, block);

if (IRRuntimeHelpers.isDebug()) doDebug();

return callInternal(context, self, clazz, name, block);
}

@Override
public DynamicMethod dup() {
InterpretedIRMetaClassBody x = new InterpretedIRMetaClassBody(method, implementationClass);
x.dupBox(this);

return x;
}
}
Loading