Skip to content
Permalink
Browse files
Merge branch 'master' into truffle-head
  • Loading branch information
chrisseaton committed Nov 17, 2014
2 parents f19ed28 + d227756 commit 251748938b16a9f86d077d165515eed46d311c45
Show file tree
Hide file tree
Showing 18 changed files with 200 additions and 162 deletions.
@@ -10,11 +10,10 @@
import org.jruby.ast.executable.Script;
import org.jruby.ast.executable.ScriptAndCode;
import org.jruby.compiler.NotCompilableException;
import org.jruby.exceptions.JumpException;
import org.jruby.exceptions.RaiseException;
import org.jruby.ir.targets.JVMVisitor;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.Block;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
@@ -88,11 +87,18 @@ public IRubyObject __file__(ThreadContext context, IRubyObject self, IRubyObject

@Override
public IRubyObject load(ThreadContext context, IRubyObject self, boolean wrap) {
Helpers.preLoadCommon(context, staticScope, false);
DynamicScope tlbScope = scope.getToplevelScope();
if (tlbScope == null) {
context.preMethodScopeOnly(staticScope);
} else {
context.preScopedBody(tlbScope);
tlbScope.growIfNeeded();
}

try {
return __file__(context, self, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK);
} finally {
Helpers.postLoad(context);
context.popScope();
}
}
};
@@ -12,23 +12,23 @@
public class IRScriptBody extends IRScope {
private List<IRClosure> beginBlocks;
private List<IRClosure> endBlocks;
private DynamicScope tlbScope;
private DynamicScope toplevelScope;

public IRScriptBody(IRManager manager, String sourceName, StaticScope staticScope) {
super(manager, null, sourceName, sourceName, 0, staticScope);
this.tlbScope = null;
this.toplevelScope = null;
if (!getManager().isDryRun() && staticScope != null) {
staticScope.setIRScope(this);
staticScope.setScopeType(this.getScopeType());
}
}

public DynamicScope getTopLevelBindingScope() {
return tlbScope;
public DynamicScope getToplevelScope() {
return toplevelScope;
}

public void setTopLevelBindingScope(DynamicScope tlbScope) {
this.tlbScope = tlbScope;
this.toplevelScope = tlbScope;
}

@Override
@@ -3,6 +3,7 @@
import org.jruby.ir.IRVisitor;
import org.jruby.ir.Operation;
import org.jruby.ir.operands.Operand;
import org.jruby.ir.runtime.IRRuntimeHelpers;
import org.jruby.ir.transformations.inlining.CloneInfo;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.DynamicScope;
@@ -19,6 +20,10 @@ public RaiseRequiredKeywordArgumentError(String name) {
this.name = name;
}

public String getName() {
return name;
}

@Override
public Operand[] getOperands() {
return new Operand[0];
@@ -31,7 +36,7 @@ public Instr clone(CloneInfo ii) {

@Override
public Object interpret(ThreadContext context, StaticScope currScope, DynamicScope currDynScope, IRubyObject self, Object[] temp) {
throw context.runtime.newArgumentError("missing keyword: " + name);
throw IRRuntimeHelpers.newRequiredKeywordArgumentError(context, name);
}

@Override
@@ -1,7 +1,6 @@
package org.jruby.ir.interpreter;

import org.jruby.*;
import org.jruby.ast.Node;
import org.jruby.ast.RootNode;
import org.jruby.common.IRubyWarnings.ID;
import org.jruby.exceptions.RaiseException;
@@ -149,7 +148,7 @@ protected IRubyObject execute(Ruby runtime, IRScriptBody irScope, IRubyObject se
}

scope.setModule(currModule);
DynamicScope tlbScope = irScope.getTopLevelBindingScope();
DynamicScope tlbScope = irScope.getToplevelScope();
if (tlbScope == null) {
context.preMethodScopeOnly(scope);
} else {
@@ -381,11 +380,14 @@ private static void processCall(ThreadContext context, Instr instr, Operation op

private static void processBookKeepingOp(ThreadContext context, Instr instr, Operation operation,
String name, IRubyObject[] args, IRubyObject self, Block block,
RubyModule implClass, Visibility visibility) {
RubyModule implClass) {
switch(operation) {
case PUSH_FRAME:
context.preMethodFrameOnly(implClass, name, self, block);
context.setCurrentVisibility(visibility);
// Only the top-level script scope has PRIVATE visibility.
// This is already handled as part of Interpreter.execute above.
// Everything else is PUBLIC by default.
context.setCurrentVisibility(Visibility.PUBLIC);
break;
case POP_FRAME:
context.popFrame();
@@ -549,7 +551,7 @@ private static void processOtherOp(ThreadContext context, Instr instr, Operation
}

private static IRubyObject interpret(ThreadContext context, IRubyObject self,
InterpreterContext interpreterContext, Visibility visibility, RubyModule implClass,
InterpreterContext interpreterContext, RubyModule implClass,
String name, IRubyObject[] args, Block block, Block.Type blockType) {
Instr[] instrs = interpreterContext.getInstructions();
Object[] temp = interpreterContext.allocateTemporaryVariables();
@@ -561,12 +563,13 @@ private static IRubyObject interpret(ThreadContext context, IRubyObject self,
Object exception = null;
DynamicScope currDynScope = context.getCurrentScope();
StaticScope currScope = interpreterContext.getStaticScope();
IRScope scope = currScope.getIRScope();
boolean acceptsKeywordArgument = interpreterContext.receivesKeywordArguments();

// Init profiling this scope
boolean debug = IRRuntimeHelpers.isDebug();
boolean profile = IRRuntimeHelpers.inProfileMode();
//Integer scopeVersion = profile ? Profiler.initProfiling(scope) : 0;
boolean acceptsKeywordArgument = interpreterContext.receivesKeywordArguments();
Integer scopeVersion = profile ? Profiler.initProfiling(scope) : 0;

// Enter the looooop!
while (ipc < n) {
@@ -593,7 +596,7 @@ private static IRubyObject interpret(ThreadContext context, IRubyObject self,
receiveArg(context, instr, operation, args, acceptsKeywordArgument, currDynScope, temp, exception, block);
break;
case CALL_OP:
//if (profile) Profiler.updateCallSite(instr, scope, scopeVersion);
if (profile) Profiler.updateCallSite(instr, scope, scopeVersion);
processCall(context, instr, operation, currDynScope, currScope, temp, self);
break;
case RET_OP:
@@ -612,7 +615,7 @@ private static IRubyObject interpret(ThreadContext context, IRubyObject self,
currDynScope = interpreterContext.newDynamicScope(context);
context.pushScope(currDynScope);
} else {
processBookKeepingOp(context, instr, operation, name, args, self, block, implClass, visibility);
processBookKeepingOp(context, instr, operation, name, args, self, block, implClass);
}
break;
case OTHER_OP:
@@ -661,7 +664,7 @@ public static IRubyObject INTERPRET_ROOT(ThreadContext context, IRubyObject self
InterpreterContext ic, RubyModule clazz, String name) {
try {
ThreadContext.pushBacktrace(context, name, ic.getFileName(), context.getLine());
return interpret(context, self, ic, null, clazz, name, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK, null);
return interpret(context, self, ic, clazz, name, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK, null);
} finally {
ThreadContext.popBacktrace(context);
}
@@ -671,7 +674,7 @@ public static IRubyObject INTERPRET_EVAL(ThreadContext context, IRubyObject self
InterpreterContext ic, RubyModule clazz, IRubyObject[] args, String name, Block block, Block.Type blockType) {
try {
ThreadContext.pushBacktrace(context, name, ic.getFileName(), context.getLine());
return interpret(context, self, ic, null, clazz, name, args, block, blockType);
return interpret(context, self, ic, clazz, name, args, block, blockType);
} finally {
ThreadContext.popBacktrace(context);
}
@@ -681,7 +684,7 @@ public static IRubyObject INTERPRET_BLOCK(ThreadContext context, IRubyObject sel
InterpreterContext ic, IRubyObject[] args, String name, Block block, Block.Type blockType) {
try {
ThreadContext.pushBacktrace(context, name, ic.getFileName(), context.getLine());
return interpret(context, self, ic, null, null, name, args, block, blockType);
return interpret(context, self, ic, null, name, args, block, blockType);
} finally {
ThreadContext.popBacktrace(context);
}
@@ -696,7 +699,7 @@ public static IRubyObject INTERPRET_METHOD(ThreadContext context, InterpretedIRM
try {
if (!isSynthetic) ThreadContext.pushBacktrace(context, name, ic.getFileName(), context.getLine());

return interpret(context, self, ic, method.getVisibility(), method.getImplementationClass().getMethodLocation(), name, args, block, null);
return interpret(context, self, ic, method.getImplementationClass().getMethodLocation(), name, args, block, null);
} finally {
if (!isSynthetic) ThreadContext.popBacktrace(context);
}
@@ -21,7 +21,7 @@ private static class IRCallSite {
long count;
InterpretedIRMethod tgtM;

public IRCallSite() { }
public IRCallSite() {}

public IRCallSite(IRCallSite cs) {
this.s = cs.s;
@@ -86,7 +86,7 @@ private static void analyzeProfile() {
IRCallSite cs = csp.cs;

if (cs.v != scopeVersionMap.get(cs.s).intValue()) {
// System.out.println("Skipping callsite: <" + cs.s + "," + cs.v + "> with compiled version: " + scopeVersionMap.get(cs.s));
System.out.println("Skipping callsite: <" + cs.s + "," + cs.v + "> with compiled version: " + scopeVersionMap.get(cs.s));
continue;
}

@@ -149,8 +149,8 @@ public int compare(IRCallSite a, IRCallSite b) {
// This check is arbitrary
if (i == 100 || freq > 99.0) break;

// System.out.println("Considering: " + ircs.call + " with id: " + ircs.call.callSiteId +
// " in scope " + ircs.s + " with count " + ircs.count + "; contrib " + contrib + "; freq: " + freq);
System.out.println("Considering: " + ircs.call + " with id: " + ircs.call.callSiteId +
" in scope " + ircs.s + " with count " + ircs.count + "; contrib " + contrib + "; freq: " + freq);

// Now inline here!
CallBase call = ircs.call;
@@ -166,8 +166,8 @@ public int compare(IRCallSite a, IRCallSite b) {
// Dont inline large methods -- 500 is arbitrary
// Can be null if a previously inlined method hasn't been rebuilt
if ((instrs == null) || instrs.length > 500) {
// if (instrs == null) System.out.println("no instrs!");
// else System.out.println("large method with " + instrs.length + " instrs. skipping!");
if (instrs == null) System.out.println("no instrs!");
else System.out.println("large method with " + instrs.length + " instrs. skipping!");
continue;
}

@@ -179,7 +179,7 @@ public int compare(IRCallSite a, IRCallSite b) {
Operand clArg = call.getClosureArg(null);
inlineCall = (clArg instanceof WrappedIRClosure) && (((WrappedIRClosure)clArg).getClosure() == hc);
}

/*
if (inlineCall) {
noInlining = false;
long start = new java.util.Date().getTime();
@@ -194,6 +194,7 @@ public int compare(IRCallSite a, IRCallSite b) {
} else {
//System.out.println("--no inlining--");
}
*/
}

for (IRScope x: inlinedScopes) {
@@ -277,6 +278,8 @@ public int compare(IRScope a, IRScope b) {
}

public static Integer initProfiling(IRScope scope) {
if (scope == null) return null;

/* SSS: Not being used currently
tpCount = scopeThreadPollCounts.get(scope);
if (tpCount == null) {
@@ -311,6 +314,8 @@ public static Integer initProfiling(IRScope scope) {
}

public static void updateCallSite(Instr instr, IRScope scope, Integer scopeVersion) {
if (scope == null) return;

if (instr instanceof CallBase) {
callerSite.s = scope;
callerSite.v = scopeVersion;
@@ -319,8 +324,7 @@ public static void updateCallSite(Instr instr, IRScope scope, Integer scopeVersi
}

public static void clockTick() {
// SSS: Not being used currently
// tpCount.count++;
// tpCount.count++; // SSS: Not being used currently
globalThreadPollCount++;

// 20K is arbitrary
@@ -92,7 +92,7 @@ public Object retrieve(ThreadContext context, IRubyObject self, StaticScope curr

if (isKWArgsHash && pairs.get(0).getKey() == Symbol.KW_REST_ARG_DUMMY) {
// Dup the rest args hash and use that as the basis for inserting the non-rest args
hash = (RubyHash)((RubyHash) pairs.get(0).getValue().retrieve(context, self, currScope, currDynScope, temp)).dup(context);
hash = ((RubyHash) pairs.get(0).getValue().retrieve(context, self, currScope, currDynScope, temp)).dupFast(context);
// Skip the first pair
it.next();
} else {
@@ -984,6 +984,16 @@ public static RubyHash constructHashFromArray(Ruby runtime, IRubyObject[] pairs)
return hash;
}

// Used by JIT
public static RubyHash dupKwargsHashAndPopulateFromArray(ThreadContext context, RubyHash dupHash, IRubyObject[] pairs) {
Ruby runtime = context.runtime;
RubyHash hash = dupHash.dupFast(context);
for (int i = 0; i < pairs.length;) {
hash.fastASet(runtime, pairs[i++], pairs[i++], true);
}
return hash;
}

// Used by JIT
public static IRubyObject searchConst(ThreadContext context, StaticScope staticScope, String constName, boolean noPrivateConsts) {
Ruby runtime = context.getRuntime();
@@ -1268,4 +1278,9 @@ public static IRubyObject irReqdArgMultipleAsgn(ThreadContext context, RubyArray
public static IRubyObject irNot(ThreadContext context, IRubyObject obj) {
return context.runtime.newBoolean(!(obj.isTrue()));
}

@JIT
public static RaiseException newRequiredKeywordArgumentError(ThreadContext context, String name) {
return context.runtime.newArgumentError("missing keyword: " + name);
}
}
@@ -85,13 +85,22 @@ public static CallSite array(Lookup lookup, String name, MethodType type) {

public static CallSite hash(Lookup lookup, String name, MethodType type) {
MethodHandle handle = Binder
.from(type)
.from(lookup, type)
.collect(1, IRubyObject[].class)
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "hash");
CallSite site = new ConstantCallSite(handle);
return site;
}

public static CallSite kwargsHash(Lookup lookup, String name, MethodType type) {
MethodHandle handle = Binder
.from(lookup, type)
.collect(2, IRubyObject[].class)
.invokeStaticQuiet(LOOKUP, Bootstrap.class, "kwargsHash");
CallSite site = new ConstantCallSite(handle);
return site;
}

public static CallSite ivar(Lookup lookup, String name, MethodType type) throws Throwable {
String[] names = name.split(":");
String operation = names[0];
@@ -139,6 +148,10 @@ public static Handle hash() {
return new Handle(Opcodes.H_INVOKESTATIC, p(Bootstrap.class), "hash", sig(CallSite.class, Lookup.class, String.class, MethodType.class));
}

public static Handle kwargsHash() {
return new Handle(Opcodes.H_INVOKESTATIC, p(Bootstrap.class), "kwargsHash", sig(CallSite.class, Lookup.class, String.class, MethodType.class));
}

public static Handle invokeSuper() {
return SuperInvokeSite.BOOTSTRAP;
}
@@ -264,6 +277,10 @@ public static IRubyObject hash(ThreadContext context, IRubyObject[] pairs) {
return hash;
}

public static IRubyObject kwargsHash(ThreadContext context, RubyHash hash, IRubyObject[] pairs) {
return IRRuntimeHelpers.dupKwargsHashAndPopulateFromArray(context, hash, pairs);
}

static MethodHandle buildGenericHandle(InvokeSite site, DynamicMethod method, RubyClass dispatchClass) {
SmartBinder binder;

@@ -85,5 +85,6 @@ public void popmethod() {
public AtomicInteger callSiteCount = new AtomicInteger(0);
public Set<Integer> arrayMethodsDefined = new HashSet();
public Set<Integer> hashMethodsDefined = new HashSet();
public Set<Integer> kwargsHashMethodsDefined = new HashSet();
public Set<Integer> dregexpMethodsDefined = new HashSet();
}

0 comments on commit 2517489

Please sign in to comment.