Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2279,7 +2279,7 @@ private InvokeQuickNode quickenInvoke(int top, int curBCI, int opcode, int state
public int reQuickenInvoke(VirtualFrame frame, int top, int opcode, int curBCI, int statementIndex) {
CompilerAsserts.neverPartOfCompilation();
assert Bytecodes.isInvoke(opcode);
BaseQuickNode invoke = generifyInlinedMethodNode(top, opcode, curBCI, statementIndex);
BaseQuickNode invoke = generifyInlinedMethodNode(top, opcode, curBCI, statementIndex, null);
// Perform the call outside of the lock.
return invoke.execute(frame, false);
}
Expand Down Expand Up @@ -2314,9 +2314,16 @@ private BaseQuickNode replaceQuickAt(int opcode, int curBCI, BaseQuickNode old,
* Reverts Bytecode-level method inlining at the current bci, in case instrumentation starts
* happening on this node.
*/
public BaseQuickNode generifyInlinedMethodNode(int top, int opcode, int curBCI, int statementIndex) {
public BaseQuickNode generifyInlinedMethodNode(int top, int opcode, int curBCI, int statementIndex, ResolvedCall<Klass, Method, Field> resolvedCall) {
CompilerAsserts.neverPartOfCompilation();
ResolvedInvoke resolvedInvoke = getResolvedInvoke(opcode, readOriginalCPI(curBCI));
ResolvedInvoke resolvedInvoke;
if (resolvedCall == null) {
resolvedInvoke = getResolvedInvoke(opcode, readOriginalCPI(curBCI));
} else {
assert !resolvedCall.getResolvedMethod().isInvokeIntrinsic() : "An inlined method may never be an invokeGeneric.";
resolvedInvoke = new ResolvedInvoke(resolvedCall, null);
}

return atomic(() -> {
assert bs.currentBC(curBCI) == QUICK;
char nodeIndex = readCPI(curBCI);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public interface Recipes {
private final InlinedMethodPredicate condition;

public ConditionalInlinedMethodNode(ResolvedCall<Klass, Method, Field> resolvedCall, int top, int opcode, int callerBCI, int statementIndex, Recipes recipes, InlinedMethodPredicate condition) {
super(resolvedCall.getResolvedMethod().getMethodVersion(), top, opcode, callerBCI, statementIndex, null);
super(resolvedCall, top, opcode, callerBCI, statementIndex, null);
this.fallbackNode = getFallback(resolvedCall, top, callerBCI);
this.condition = condition;
this.recipes = recipes;
Expand All @@ -59,23 +59,22 @@ public final int execute(VirtualFrame frame, boolean isContinuationResume) {
preludeChecks(frame);
if (condition.isValid(getContext(), method, frame, this)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
InlinedMethodNode replacement = getDefinitiveNode(recipes, inlinedMethod(), top, opcode, getCallerBCI(), statementIndex);
InlinedMethodNode replacement = getDefinitiveNode(recipes, getResolvedCall(), top, opcode, getCallerBCI(), statementIndex);
return getBytecodeNode().replaceQuickAt(frame, opcode, getCallerBCI(), this,
replacement);
} else {
return fallbackNode.execute(frame, false);
}
}

public static InlinedMethodNode getDefinitiveNode(Recipes recipes,
Method.MethodVersion inlinedMethod, int top, int opcode, int callerBci, int statementIndex) {
public static InlinedMethodNode getDefinitiveNode(Recipes recipes, ResolvedCall<Klass, Method, Field> inlinedCall, int top, int opcode, int callerBci, int statementIndex) {
BodyNode newBody = recipes.cookBody();
InlinedMethodPredicate guard = recipes.cookGuard();
InlinedMethodNode replacement;
if (guard == null) {
replacement = new InlinedMethodNode(inlinedMethod, top, opcode, callerBci, statementIndex, newBody);
replacement = new InlinedMethodNode(inlinedCall, top, opcode, callerBci, statementIndex, newBody);
} else {
replacement = new GuardedInlinedMethodNode(inlinedMethod, top, opcode, callerBci, statementIndex, newBody, guard);
replacement = new GuardedInlinedMethodNode(inlinedCall, top, opcode, callerBci, statementIndex, newBody, guard);
}
return replacement;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public final class GuardedConditionalInlinedMethodNode extends InlinedMethodNode
public GuardedConditionalInlinedMethodNode(ResolvedCall<Klass, Method, Field> resolvedCall, int top, int opcode, int callerBCI, int statementIndex,
ConditionalInlinedMethodNode.Recipes recipes,
InlinedMethodPredicate condition, InlinedMethodPredicate guard) {
super(resolvedCall.getResolvedMethod().getMethodVersion(), top, opcode, callerBCI, statementIndex, null);
super(resolvedCall, top, opcode, callerBCI, statementIndex, null);
this.fallbackNode = insert(getFallback(resolvedCall, top, callerBCI));
this.condition = condition;
this.guard = guard;
Expand All @@ -55,7 +55,7 @@ public int execute(VirtualFrame frame, boolean isContinuationResume) {
if (guard.isValid(getContext(), method, frame, this)) {
if (condition.isValid(getContext(), method, frame, this)) {
CompilerDirectives.transferToInterpreterAndInvalidate();
InlinedMethodNode replacement = getDefinitiveNode(recipes, guard, inlinedMethod(), top, opcode, getCallerBCI(), statementIndex);
InlinedMethodNode replacement = getDefinitiveNode(recipes, guard, getResolvedCall(), top, opcode, getCallerBCI(), statementIndex);
return getBytecodeNode().replaceQuickAt(frame, opcode, getCallerBCI(), this,
replacement);
} else {
Expand All @@ -68,14 +68,14 @@ public int execute(VirtualFrame frame, boolean isContinuationResume) {
}

public static InlinedMethodNode getDefinitiveNode(ConditionalInlinedMethodNode.Recipes recipes, InlinedMethodPredicate oldGuard,
Method.MethodVersion method, int top, int opcode, int callerBci, int statementIndex) {
ResolvedCall<Klass, Method, Field> inlinedCall, int top, int opcode, int callerBci, int statementIndex) {
BodyNode newBody = recipes.cookBody();
InlinedMethodPredicate cookedGuard = recipes.cookGuard();
InlinedMethodPredicate newGuard = cookedGuard == null
? oldGuard
: (ctx, m, f, node) -> cookedGuard.isValid(ctx, m, f, node) && oldGuard.isValid(ctx, m, f, node);
InlinedMethodNode replacement;
replacement = new GuardedInlinedMethodNode(method, top, opcode, callerBci, statementIndex, newBody, newGuard);
replacement = new GuardedInlinedMethodNode(inlinedCall, top, opcode, callerBci, statementIndex, newBody, newGuard);
return replacement;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,16 @@

import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.espresso.impl.Field;
import com.oracle.truffle.espresso.impl.Klass;
import com.oracle.truffle.espresso.impl.Method;
import com.oracle.truffle.espresso.shared.resolver.ResolvedCall;

public final class GuardedInlinedMethodNode extends InlinedMethodNode {
private final InlinedMethodPredicate guard;

public GuardedInlinedMethodNode(Method inlinedMethod, int top, int opcode, int callerBCI, int statementIndex, BodyNode body, InlinedMethodPredicate guard) {
this(inlinedMethod.getMethodVersion(), top, opcode, callerBCI, statementIndex, body, guard);
}

public GuardedInlinedMethodNode(Method.MethodVersion inlinedMethod, int top, int opcode, int callerBCI, int statementIndex, BodyNode body, InlinedMethodPredicate guard) {
super(inlinedMethod, top, opcode, callerBCI, statementIndex, body);
public GuardedInlinedMethodNode(ResolvedCall<Klass, Method, Field> inlinedCall, int top, int opcode, int callerBCI, int statementIndex, BodyNode body, InlinedMethodPredicate guard) {
super(inlinedCall, top, opcode, callerBCI, statementIndex, body);
this.guard = guard;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public SourceSection getSourceSection() {
}

// Data needed to revert to the generic case.
protected final CallKind callKind;
protected final int opcode;
protected final int statementIndex;

Expand All @@ -124,14 +125,15 @@ public static InlinedMethodNode createFor(ResolvedCall<Klass, Method, Field> res
// Try to inline trivial substitutions.
JavaSubstitution.Factory factory = Substitutions.lookupSubstitution(resolutionSeed);
if (factory != null && factory.inlineInBytecode()) {
return InlinedSubstitutionBodyNode.create(resolutionSeed, top, opcode, curBCI, statementIndex, factory);
return InlinedSubstitutionBodyNode.create(resolvedCall, top, opcode, curBCI, statementIndex, factory);
}
}
return null;
}

public InlinedMethodNode(Method.MethodVersion inlinedMethod, int top, int opcode, int callerBCI, int statementIndex, BodyNode body) {
super(inlinedMethod, top, callerBCI);
public InlinedMethodNode(ResolvedCall<Klass, Method, Field> inlinedCall, int top, int opcode, int callerBCI, int statementIndex, BodyNode body) {
super(inlinedCall.getResolvedMethod(), top, callerBCI);
this.callKind = inlinedCall.getCallKind();
this.opcode = opcode;
this.statementIndex = statementIndex;
this.body = body;
Expand Down Expand Up @@ -188,7 +190,11 @@ private void initCheck() {
}

public final BaseQuickNode revertToGeneric(BytecodeNode parent) {
return parent.generifyInlinedMethodNode(top, opcode, getCallerBCI(), statementIndex);
return parent.generifyInlinedMethodNode(top, opcode, getCallerBCI(), statementIndex, getResolvedCall());
}

protected ResolvedCall<Klass, Method, Field> getResolvedCall() {
return new ResolvedCall<>(callKind, inlinedMethod().getMethod());
}

public static boolean isInlineCandidate(ResolvedCall<Klass, Method, Field> resolvedCall) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,10 @@ private static InlinedMethodNode create(ResolvedCall<Klass, Method, Field> resol
boolean isDefinitive = isResolutionSuccessAt(inlinedMethod, fieldCpi);
if (isDefinitive) {
if (isUnconditionalInlineCandidate(resolvedCall)) {
return ConditionalInlinedMethodNode.getDefinitiveNode(recipes, inlinedMethod, top, opCode, curBCI, statementIndex);
return ConditionalInlinedMethodNode.getDefinitiveNode(recipes, resolvedCall, top, opCode, curBCI, statementIndex);
} else {
return GuardedConditionalInlinedMethodNode.getDefinitiveNode(recipes, InlinedMethodPredicate.LEAF_ASSUMPTION_CHECK,
inlinedMethod, top, opCode, curBCI, statementIndex);
resolvedCall, top, opCode, curBCI, statementIndex);
}
}
InlinedMethodPredicate condition = (context, version, frame, node) -> isResolutionSuccessAt(version, fieldCpi);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,13 @@
package com.oracle.truffle.espresso.nodes.quick.invoke.inline.bodies;

import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.espresso.impl.Field;
import com.oracle.truffle.espresso.impl.Klass;
import com.oracle.truffle.espresso.impl.Method;
import com.oracle.truffle.espresso.nodes.quick.invoke.inline.GuardedInlinedMethodNode;
import com.oracle.truffle.espresso.nodes.quick.invoke.inline.InlinedFrameAccess;
import com.oracle.truffle.espresso.nodes.quick.invoke.inline.InlinedMethodNode;
import com.oracle.truffle.espresso.shared.resolver.ResolvedCall;
import com.oracle.truffle.espresso.substitutions.JavaSubstitution;

public final class InlinedSubstitutionBodyNode extends InlinedMethodNode.BodyNode {
Expand All @@ -37,13 +40,13 @@ public final class InlinedSubstitutionBodyNode extends InlinedMethodNode.BodyNod
this.substitution = insert(substitution);
}

public static InlinedMethodNode create(Method inlinedMethod, int top, int opcode, int callerBCI, int statementIndex, JavaSubstitution.Factory factory) {
Method.MethodVersion methodVersion = inlinedMethod.getMethodVersion();
public static InlinedMethodNode create(ResolvedCall<Klass, Method, Field> inlinedCall, int top, int opcode, int callerBCI, int statementIndex, JavaSubstitution.Factory factory) {
Method.MethodVersion methodVersion = inlinedCall.getResolvedMethod().getMethodVersion();
InlinedSubstitutionBodyNode bodyNode = new InlinedSubstitutionBodyNode(methodVersion, factory.create());
if (factory.guard() != null) {
return new GuardedInlinedMethodNode(methodVersion, top, opcode, callerBCI, statementIndex, bodyNode, factory.guard());
return new GuardedInlinedMethodNode(inlinedCall, top, opcode, callerBCI, statementIndex, bodyNode, factory.guard());
} else {
return new InlinedMethodNode(methodVersion, top, opcode, callerBCI, statementIndex, bodyNode);
return new InlinedMethodNode(inlinedCall, top, opcode, callerBCI, statementIndex, bodyNode);
}
}

Expand Down