use of jdk.vm.ci.meta.JavaKind in project graal by oracle.
the class ForeignCallNode method intrinsify.
public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod targetMethod, @InjectedNodeParameter Stamp returnStamp, @InjectedNodeParameter ForeignCallsProvider foreignCalls, ForeignCallDescriptor descriptor, ValueNode... arguments) {
ForeignCallNode node = new ForeignCallNode(foreignCalls, descriptor, arguments);
node.setStamp(returnStamp);
assert verifyDescriptor(b, targetMethod, descriptor);
/*
* Need to update the BCI of a ForeignCallNode so that it gets the stateDuring in the case
* that the foreign call can deoptimize. As with all deoptimization, we need a state in a
* non-intrinsic method.
*/
GraphBuilderContext nonIntrinsicAncestor = b.getNonIntrinsicAncestor();
if (nonIntrinsicAncestor != null) {
node.setBci(nonIntrinsicAncestor.bci());
}
JavaKind returnKind = targetMethod.getSignature().getReturnKind();
if (returnKind == JavaKind.Void) {
b.add(node);
} else {
b.addPush(returnKind, node);
}
return true;
}
use of jdk.vm.ci.meta.JavaKind in project graal by oracle.
the class RawLoadNode method virtualize.
@Override
public void virtualize(VirtualizerTool tool) {
ValueNode alias = tool.getAlias(object());
if (alias instanceof VirtualObjectNode) {
VirtualObjectNode virtual = (VirtualObjectNode) alias;
ValueNode offsetValue = tool.getAlias(offset());
if (offsetValue.isConstant()) {
long off = offsetValue.asJavaConstant().asLong();
int entryIndex = virtual.entryIndexForOffset(tool.getArrayOffsetProvider(), off, accessKind());
if (entryIndex != -1) {
ValueNode entry = tool.getEntry(virtual, entryIndex);
JavaKind entryKind = virtual.entryKind(entryIndex);
if (entry.getStackKind() == getStackKind() || entryKind == accessKind()) {
if (!(entry.stamp(NodeView.DEFAULT).isCompatible(stamp(NodeView.DEFAULT)))) {
if (entry.stamp(NodeView.DEFAULT) instanceof PrimitiveStamp && stamp instanceof PrimitiveStamp) {
PrimitiveStamp p1 = (PrimitiveStamp) stamp;
PrimitiveStamp p2 = (PrimitiveStamp) entry.stamp(NodeView.DEFAULT);
int width1 = p1.getBits();
int width2 = p2.getBits();
if (width1 == width2) {
Node replacement = ReinterpretNode.create(p2, entry, NodeView.DEFAULT);
tool.replaceWith((ValueNode) replacement);
return;
} else {
// different bit width
return;
}
} else {
// cannot reinterpret for arbitrary objects
return;
}
}
tool.replaceWith(entry);
}
}
}
}
}
use of jdk.vm.ci.meta.JavaKind in project graal by oracle.
the class TruffleGraphBuilderPlugins method registerExactMathPlugins.
public static void registerExactMathPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess) {
final ResolvedJavaType exactMathType = getRuntime().resolveType(metaAccess, "com.oracle.truffle.api.ExactMath");
Registration r = new Registration(plugins, new ResolvedJavaSymbol(exactMathType));
for (JavaKind kind : new JavaKind[] { JavaKind.Int, JavaKind.Long }) {
Class<?> type = kind.toJavaClass();
r.register2("multiplyHigh", type, type, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
b.addPush(kind, new IntegerMulHighNode(x, y));
return true;
}
});
r.register2("multiplyHighUnsigned", type, type, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x, ValueNode y) {
b.addPush(kind, new UnsignedMulHighNode(x, y));
return true;
}
});
}
}
use of jdk.vm.ci.meta.JavaKind in project graal by oracle.
the class NewFrameNode method virtualize.
@Override
public void virtualize(VirtualizerTool tool) {
ResolvedJavaType frameType = stamp(NodeView.DEFAULT).javaType(tool.getMetaAccessProvider());
ResolvedJavaField[] frameFields = frameType.getInstanceFields(true);
ResolvedJavaField descriptorField = findField(frameFields, "descriptor");
ResolvedJavaField argumentsField = findField(frameFields, "arguments");
ResolvedJavaField localsField = findField(frameFields, "locals");
ResolvedJavaField primitiveLocalsField = findField(frameFields, "primitiveLocals");
ResolvedJavaField tagsField = findField(frameFields, "tags");
ValueNode[] objectArrayEntryState = new ValueNode[frameSize];
ValueNode[] primitiveArrayEntryState = new ValueNode[frameSize];
ValueNode[] tagArrayEntryState = new ValueNode[frameSize];
if (frameSize > 0) {
Arrays.fill(objectArrayEntryState, frameDefaultValue);
if (virtualFrameTagArray != null) {
Arrays.fill(tagArrayEntryState, smallIntConstants.get(0));
}
if (virtualFramePrimitiveArray != null) {
for (int i = 0; i < frameSize; i++) {
JavaKind kind = frameSlotKinds[i];
if (kind == null) {
kind = JavaKind.Int;
}
primitiveArrayEntryState[i] = ConstantNode.defaultForKind(kind, graph());
}
}
}
tool.createVirtualObject(virtualFrameObjectArray, objectArrayEntryState, Collections.<MonitorIdNode>emptyList(), false);
if (virtualFramePrimitiveArray != null) {
tool.createVirtualObject(virtualFramePrimitiveArray, primitiveArrayEntryState, Collections.<MonitorIdNode>emptyList(), false);
}
if (virtualFrameTagArray != null) {
tool.createVirtualObject(virtualFrameTagArray, tagArrayEntryState, Collections.<MonitorIdNode>emptyList(), false);
}
assert frameFields.length == 5 || frameFields.length == 3;
ValueNode[] frameEntryState = new ValueNode[frameFields.length];
List<ResolvedJavaField> frameFieldList = Arrays.asList(frameFields);
frameEntryState[frameFieldList.indexOf(descriptorField)] = getDescriptor();
frameEntryState[frameFieldList.indexOf(argumentsField)] = getArguments();
frameEntryState[frameFieldList.indexOf(localsField)] = virtualFrameObjectArray;
if (primitiveLocalsField != null) {
frameEntryState[frameFieldList.indexOf(primitiveLocalsField)] = virtualFramePrimitiveArray;
}
if (tagsField != null) {
frameEntryState[frameFieldList.indexOf(tagsField)] = virtualFrameTagArray;
}
/*
* The new frame is created with "ensureVirtualized" enabled, so that it cannot be
* materialized. This can only be lifted by a AllowMaterializeNode, which corresponds to a
* frame.materialize() call.
*/
tool.createVirtualObject(virtualFrame, frameEntryState, Collections.<MonitorIdNode>emptyList(), true);
tool.replaceWithVirtual(virtualFrame);
}
use of jdk.vm.ci.meta.JavaKind in project graal by oracle.
the class MultiTypeGuardInlineInfo method inlineMultipleMethods.
private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers) {
int numberOfMethods = concretes.size();
FixedNode continuation = invoke.next();
// setup merge and phi nodes for results and exceptions
AbstractMergeNode returnMerge = graph.add(new MergeNode());
returnMerge.setStateAfter(invoke.stateAfter());
PhiNode returnValuePhi = null;
if (invoke.asNode().getStackKind() != JavaKind.Void) {
returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp(NodeView.DEFAULT).unrestricted(), returnMerge));
}
AbstractMergeNode exceptionMerge = null;
PhiNode exceptionObjectPhi = null;
if (invoke instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithException.exceptionEdge();
exceptionMerge = graph.add(new MergeNode());
FixedNode exceptionSux = exceptionEdge.next();
graph.addBeforeFixed(exceptionSux, exceptionMerge);
exceptionObjectPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(JavaKind.Object), exceptionMerge));
exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, JavaKind.Object, new JavaKind[] { JavaKind.Object }, new ValueNode[] { exceptionObjectPhi }));
}
// create one separate block for each invoked method
AbstractBeginNode[] successors = new AbstractBeginNode[numberOfMethods + 1];
for (int i = 0; i < numberOfMethods; i++) {
successors[i] = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, true);
}
// create the successor for an unknown type
FixedNode unknownTypeSux;
if (shouldFallbackToInvoke()) {
unknownTypeSux = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, false);
} else {
unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated));
}
successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
// replace the invoke exception edge
if (invoke instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invoke;
ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithExceptionNode.exceptionEdge();
exceptionEdge.replaceAtUsages(exceptionObjectPhi);
exceptionEdge.setNext(null);
GraphUtil.killCFG(invokeWithExceptionNode.exceptionEdge());
}
assert invoke.asNode().isAlive();
// replace the invoke with a switch on the type of the actual receiver
boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, providers.getStampProvider(), providers.getConstantReflection());
assert invoke.next() == continuation;
invoke.setNext(null);
returnMerge.setNext(continuation);
if (returnValuePhi != null) {
invoke.asNode().replaceAtUsages(returnValuePhi);
}
invoke.asNode().safeDelete();
ArrayList<PiNode> replacementNodes = new ArrayList<>();
// prepare the anchors for the invokes
for (int i = 0; i < numberOfMethods; i++) {
AbstractBeginNode node = successors[i];
Invoke invokeForInlining = (Invoke) node.next();
ResolvedJavaType commonType;
if (methodDispatch) {
commonType = concretes.get(i).getDeclaringClass();
} else {
commonType = getLeastCommonType(i);
}
ValueNode receiver = ((MethodCallTargetNode) invokeForInlining.callTarget()).receiver();
boolean exact = (getTypeCount(i) == 1 && !methodDispatch);
PiNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, node, commonType, receiver, exact);
invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
assert !anchoredReceiver.isDeleted() : anchoredReceiver;
replacementNodes.add(anchoredReceiver);
}
if (shouldFallbackToInvoke()) {
replacementNodes.add(null);
}
EconomicSet<Node> canonicalizeNodes = EconomicSet.create(Equivalence.DEFAULT);
// do the actual inlining for every invoke
for (int i = 0; i < numberOfMethods; i++) {
Invoke invokeForInlining = (Invoke) successors[i].next();
canonicalizeNodes.addAll(doInline(i, invokeForInlining));
}
if (returnValuePhi != null) {
canonicalizeNodes.add(returnValuePhi);
}
return canonicalizeNodes;
}
Aggregations