use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class GraphKit method inline.
/**
* Inlines a given invocation to a method. The graph of the inlined method is processed in the
* same manner as for snippets and method substitutions.
*/
public void inline(InvokeNode invoke) {
ResolvedJavaMethod method = ((MethodCallTargetNode) invoke.callTarget()).targetMethod();
MetaAccessProvider metaAccess = providers.getMetaAccess();
Plugins plugins = new Plugins(graphBuilderPlugins);
GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(plugins);
StructuredGraph calleeGraph = new StructuredGraph.Builder(invoke.getOptions(), invoke.getDebug()).method(method).build();
if (invoke.graph().trackNodeSourcePosition()) {
calleeGraph.setTrackNodeSourcePosition();
}
IntrinsicContext initialReplacementContext = new IntrinsicContext(method, method, providers.getReplacements().getDefaultReplacementBytecodeProvider(), INLINE_AFTER_PARSING);
GraphBuilderPhase.Instance instance = new GraphBuilderPhase.Instance(metaAccess, providers.getStampProvider(), providers.getConstantReflection(), providers.getConstantFieldProvider(), config, OptimisticOptimizations.NONE, initialReplacementContext);
instance.apply(calleeGraph);
// Remove all frame states from inlinee
calleeGraph.clearAllStateAfter();
new DeadCodeEliminationPhase(Optionality.Required).apply(calleeGraph);
InliningUtil.inline(invoke, calleeGraph, false, method);
}
use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class VerifyUpdateUsages method verify.
@Override
protected boolean verify(StructuredGraph graph, PhaseContext context) {
if (graph.method().isConstructor()) {
return true;
}
/*
* There are only two acceptable patterns for methods which update Node inputs, either a
* single StoreField node and invoke of updateUsages or updateUsagesInterface, or 2
* StoreFields that come from LoadFields on the same object. Other patterns can be added as
* needed but it would be best to keep things simple so that verification can be simple.
*/
List<StoreFieldNode> stores = graph.getNodes().filter(StoreFieldNode.class).snapshot();
ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
ResolvedJavaType nodeInputList = context.getMetaAccess().lookupJavaType(NodeInputList.class);
StoreFieldNode storeField1 = null;
StoreFieldNode storeField2 = null;
for (StoreFieldNode store : stores) {
if (isNodeInput(store.field(), declaringClass, nodeInputList)) {
if (storeField1 == null) {
storeField1 = store;
} else if (storeField2 == null) {
storeField2 = store;
} else {
return false;
}
}
}
if (storeField1 == null) {
return true;
}
if (storeField2 == null) {
// Single input field update so just check for updateUsages or updateUsagesInterface
// call
ResolvedJavaType node = context.getMetaAccess().lookupJavaType(Node.class);
for (MethodCallTargetNode call : graph.getNodes().filter(MethodCallTargetNode.class)) {
ResolvedJavaMethod callee = call.targetMethod();
if (callee.getDeclaringClass().equals(node) && (callee.getName().equals("updateUsages") || callee.getName().equals("updateUsagesInterface"))) {
return true;
}
}
} else {
if (storeField1.value() instanceof LoadFieldNode && storeField2.value() instanceof LoadFieldNode) {
LoadFieldNode load1 = (LoadFieldNode) storeField1.value();
LoadFieldNode load2 = (LoadFieldNode) storeField2.value();
// Check for swapping values within the same object
if (load1.object() == storeField1.object() && load2.object() == storeField2.object() && storeField1.object() == storeField2.object() && load1.field().equals(storeField2.field()) && load2.field().equals(storeField1.field())) {
return true;
}
}
}
return false;
}
use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class VerifyBailoutUsage method verify.
@Override
protected boolean verify(StructuredGraph graph, PhaseContext context) {
final ResolvedJavaType bailoutType = context.getMetaAccess().lookupJavaType(BailoutException.class);
ResolvedJavaMethod caller = graph.method();
String holderQualified = caller.format("%H");
String holderUnqualified = caller.format("%h");
String packageName = holderQualified.substring(0, holderQualified.length() - holderUnqualified.length() - 1);
if (!matchesPrefix(packageName)) {
for (MethodCallTargetNode t : graph.getNodes(MethodCallTargetNode.TYPE)) {
ResolvedJavaMethod callee = t.targetMethod();
if (callee.getDeclaringClass().equals(bailoutType)) {
// we only allow the getter
if (!callee.getName().equals("isPermanent")) {
throw new VerificationError("Call to %s at callsite %s is prohibited. Consider using %s for permanent bailouts or %s for retryables.", callee.format("%H.%n(%p)"), caller.format("%H.%n(%p)"), PermanentBailoutException.class.getName(), RetryableBailoutException.class.getName());
}
}
}
}
return true;
}
use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class VerifyDebugUsage method verifyParameters.
private void verifyParameters(StructuredGraph callerGraph, MethodCallTargetNode debugCallTarget, List<? extends ValueNode> args, ResolvedJavaType stringType, int startArgIdx, int varArgsIndex) {
ResolvedJavaMethod verifiedCallee = debugCallTarget.targetMethod();
Integer dumpLevel = null;
int argIdx = startArgIdx;
int varArgsElementIndex = 0;
boolean reportVarArgs = false;
for (int i = 0; i < args.size(); i++) {
ValueNode arg = args.get(i);
if (arg instanceof Invoke) {
reportVarArgs = varArgsIndex >= 0 && argIdx >= varArgsIndex;
Invoke invoke = (Invoke) arg;
CallTargetNode callTarget = invoke.callTarget();
if (callTarget instanceof MethodCallTargetNode) {
ResolvedJavaMethod m = ((MethodCallTargetNode) callTarget).targetMethod();
if (m.getName().equals("toString")) {
int bci = invoke.bci();
int nonVarArgIdx = reportVarArgs ? argIdx - varArgsElementIndex : argIdx;
verifyStringConcat(callerGraph, verifiedCallee, bci, nonVarArgIdx, reportVarArgs ? varArgsElementIndex : -1, m);
verifyToStringCall(callerGraph, verifiedCallee, stringType, m, bci, nonVarArgIdx, reportVarArgs ? varArgsElementIndex : -1);
} else if (m.getName().equals("format")) {
int bci = invoke.bci();
int nonVarArgIdx = reportVarArgs ? argIdx - varArgsElementIndex : argIdx;
verifyFormatCall(callerGraph, verifiedCallee, stringType, m, bci, nonVarArgIdx, reportVarArgs ? varArgsElementIndex : -1);
}
}
}
if (i == 1) {
if (verifiedCallee.getName().equals("dump")) {
dumpLevel = verifyDumpLevelParameter(callerGraph, debugCallTarget, verifiedCallee, arg);
}
} else if (i == 2) {
if (dumpLevel != null) {
verifyDumpObjectParameter(callerGraph, debugCallTarget, arg, verifiedCallee, dumpLevel);
}
}
if (varArgsIndex >= 0 && i >= varArgsIndex) {
varArgsElementIndex++;
}
argIdx++;
}
}
use of org.graalvm.compiler.nodes.java.MethodCallTargetNode in project graal by oracle.
the class VerifyDebugUsage method verifyParameters.
private void verifyParameters(MethodCallTargetNode callTarget, StructuredGraph callerGraph, NodeInputList<? extends ValueNode> args, ResolvedJavaType stringType, int startArgIdx) {
if (callTarget.targetMethod().isVarArgs() && args.get(args.count() - 1) instanceof NewArrayNode) {
// unpack the arguments to the var args
List<ValueNode> unpacked = new ArrayList<>(args.snapshot());
NewArrayNode varArgParameter = (NewArrayNode) unpacked.remove(unpacked.size() - 1);
int firstVarArg = unpacked.size();
for (Node usage : varArgParameter.usages()) {
if (usage instanceof StoreIndexedNode) {
StoreIndexedNode si = (StoreIndexedNode) usage;
unpacked.add(si.value());
}
}
verifyParameters(callerGraph, callTarget, unpacked, stringType, startArgIdx, firstVarArg);
} else {
verifyParameters(callerGraph, callTarget, args, stringType, startArgIdx, -1);
}
}
Aggregations