use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class JNINativeCallWrapperMethod method buildGraph.
@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
JNIGraphKit kit = new JNIGraphKit(debug, providers, method);
StructuredGraph graph = kit.getGraph();
InvokeWithExceptionNode handleFrame = kit.nativeCallPrologue();
ValueNode callAddress = kit.nativeCallAddress(kit.createObject(linkage));
ValueNode environment = kit.environment();
JavaType javaReturnType = method.getSignature().getReturnType(null);
JavaType[] javaArgumentTypes = method.toParameterTypes();
List<ValueNode> javaArguments = kit.loadArguments(javaArgumentTypes);
List<ValueNode> jniArguments = new ArrayList<>(2 + javaArguments.size());
List<JavaType> jniArgumentTypes = new ArrayList<>(jniArguments.size());
JavaType environmentType = providers.getMetaAccess().lookupJavaType(JNIEnvironment.class);
JavaType objectHandleType = providers.getMetaAccess().lookupJavaType(JNIObjectHandle.class);
jniArguments.add(environment);
jniArgumentTypes.add(environmentType);
if (method.isStatic()) {
JavaConstant clazz = providers.getConstantReflection().asJavaClass(method.getDeclaringClass());
ConstantNode clazzNode = ConstantNode.forConstant(clazz, providers.getMetaAccess(), graph);
ValueNode box = kit.boxObjectInLocalHandle(clazzNode);
jniArguments.add(box);
jniArgumentTypes.add(objectHandleType);
}
for (int i = 0; i < javaArguments.size(); i++) {
ValueNode arg = javaArguments.get(i);
JavaType argType = javaArgumentTypes[i];
if (javaArgumentTypes[i].getJavaKind().isObject()) {
ValueNode obj = javaArguments.get(i);
arg = kit.boxObjectInLocalHandle(obj);
argType = objectHandleType;
}
jniArguments.add(arg);
jniArgumentTypes.add(argType);
}
assert jniArguments.size() == jniArgumentTypes.size();
JavaType jniReturnType = javaReturnType;
if (jniReturnType.getJavaKind().isObject()) {
jniReturnType = objectHandleType;
}
if (getOriginal().isSynchronized()) {
ValueNode monitorObject;
if (method.isStatic()) {
Constant hubConstant = providers.getConstantReflection().asObjectHub(method.getDeclaringClass());
DynamicHub hub = (DynamicHub) SubstrateObjectConstant.asObject(hubConstant);
monitorObject = ConstantNode.forConstant(SubstrateObjectConstant.forObject(hub), providers.getMetaAccess(), graph);
} else {
monitorObject = javaArguments.get(0);
}
MonitorIdNode monitorId = graph.add(new MonitorIdNode(kit.getFrameState().lockDepth(false)));
MonitorEnterNode monitorEnter = kit.append(new MonitorEnterNode(monitorObject, monitorId));
kit.getFrameState().pushLock(monitorEnter.object(), monitorEnter.getMonitorId());
monitorEnter.setStateAfter(kit.getFrameState().create(kit.bci(), monitorEnter));
}
kit.getFrameState().clearLocals();
Signature jniSignature = new JNISignature(jniArgumentTypes, jniReturnType);
ValueNode returnValue = kit.createCFunctionCall(callAddress, method, jniArguments, jniSignature, true, false);
if (getOriginal().isSynchronized()) {
MonitorIdNode monitorId = kit.getFrameState().peekMonitorId();
ValueNode monitorObject = kit.getFrameState().popLock();
MonitorExitNode monitorExit = kit.append(new MonitorExitNode(monitorObject, monitorId, null));
monitorExit.setStateAfter(kit.getFrameState().create(kit.bci(), monitorExit));
}
if (javaReturnType.getJavaKind().isObject()) {
// before destroying handles in epilogue
returnValue = kit.unboxHandle(returnValue);
}
kit.nativeCallEpilogue(handleFrame);
kit.rethrowPendingException();
if (javaReturnType.getJavaKind().isObject()) {
// Just before return to always run the epilogue and never suppress a pending exception
returnValue = castObject(kit, returnValue, (ResolvedJavaType) javaReturnType);
}
kit.createReturn(returnValue, javaReturnType.getJavaKind());
kit.mergeUnwinds();
assert graph.verify();
return graph;
}
use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class JNINativeCallWrapperMethod method getMaxLocals.
@Override
public int getMaxLocals() {
if (maxLocals == -1) {
maxLocals = 0;
Signature sig = getOriginal().getSignature();
int count = sig.getParameterCount(false);
if (!getOriginal().isStatic()) {
maxLocals++;
}
for (int i = 0; i < count; i++) {
maxLocals++;
if (sig.getParameterKind(i).needsTwoSlots()) {
maxLocals++;
}
}
}
return maxLocals;
}
use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class GraphKit method checkArgs.
/**
* Determines if a given set of arguments is compatible with the signature of a given method.
*
* @return true if {@code args} are compatible with the signature if {@code method}
* @throws AssertionError if {@code args} are not compatible with the signature if
* {@code method}
*/
public boolean checkArgs(ResolvedJavaMethod method, ValueNode... args) {
Signature signature = method.getSignature();
boolean isStatic = method.isStatic();
if (signature.getParameterCount(!isStatic) != args.length) {
throw new AssertionError(graph + ": wrong number of arguments to " + method);
}
int argIndex = 0;
if (!isStatic) {
JavaKind expected = asKind(method.getDeclaringClass());
JavaKind actual = args[argIndex++].stamp(NodeView.DEFAULT).getStackKind();
assert expected == actual : graph + ": wrong kind of value for receiver argument of call to " + method + " [" + actual + " != " + expected + "]";
}
for (int i = 0; i != signature.getParameterCount(false); i++) {
JavaKind expected = asKind(signature.getParameterType(i, method.getDeclaringClass())).getStackKind();
JavaKind actual = args[argIndex++].stamp(NodeView.DEFAULT).getStackKind();
if (expected != actual) {
throw new AssertionError(graph + ": wrong kind of value for argument " + i + " of call to " + method + " [" + actual + " != " + expected + "]");
}
}
return true;
}
use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class GraphKit method createInvoke.
/**
* Creates and appends an {@link InvokeNode} for a call to a given method with a given set of
* arguments.
*/
@SuppressWarnings("try")
public InvokeNode createInvoke(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int bci, ValueNode... args) {
try (DebugCloseable context = graph.withNodeSourcePosition(NodeSourcePosition.substitution(graph.currentNodeSourcePosition(), method))) {
assert method.isStatic() == (invokeKind == InvokeKind.Static);
Signature signature = method.getSignature();
JavaType returnType = signature.getReturnType(null);
assert checkArgs(method, args);
StampPair returnStamp = graphBuilderPlugins.getOverridingStamp(this, returnType, false);
if (returnStamp == null) {
returnStamp = StampFactory.forDeclaredType(graph.getAssumptions(), returnType, false);
}
MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, bci));
InvokeNode invoke = append(new InvokeNode(callTarget, bci));
if (frameStateBuilder != null) {
if (invoke.getStackKind() != JavaKind.Void) {
frameStateBuilder.push(invoke.getStackKind(), invoke);
}
invoke.setStateAfter(frameStateBuilder.create(bci, invoke));
if (invoke.getStackKind() != JavaKind.Void) {
frameStateBuilder.pop(invoke.getStackKind());
}
}
return invoke;
}
}
use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class MethodHandleNode method getTargetInvokeNode.
/**
* Helper function to get the {@link InvokeNode} for the targetMethod of a
* java.lang.invoke.MemberName.
*
* @param adder
* @param target the target, already loaded from the member name node
*
* @return invoke node for the member name target
*/
private static InvokeNode getTargetInvokeNode(GraphAdder adder, IntrinsicMethod intrinsicMethod, int bci, StampPair returnStamp, ValueNode[] originalArguments, ResolvedJavaMethod target, ResolvedJavaMethod original) {
if (target == null) {
return null;
}
// In lambda forms we erase signature types to avoid resolving issues
// involving class loaders. When we optimize a method handle invoke
// to a direct call we must cast the receiver and arguments to its
// actual types.
Signature signature = target.getSignature();
final boolean isStatic = target.isStatic();
final int receiverSkip = isStatic ? 0 : 1;
Assumptions assumptions = adder.getAssumptions();
ResolvedJavaMethod realTarget = null;
if (target.canBeStaticallyBound()) {
realTarget = target;
} else {
ResolvedJavaType targetType = target.getDeclaringClass();
// Try to bind based on the declaredType
AssumptionResult<ResolvedJavaMethod> concreteMethod = targetType.findUniqueConcreteMethod(target);
if (concreteMethod == null) {
// Try to get the most accurate receiver type
if (intrinsicMethod == IntrinsicMethod.LINK_TO_VIRTUAL || intrinsicMethod == IntrinsicMethod.LINK_TO_INTERFACE) {
ValueNode receiver = getReceiver(originalArguments);
TypeReference receiverType = StampTool.typeReferenceOrNull(receiver.stamp(NodeView.DEFAULT));
if (receiverType != null) {
concreteMethod = receiverType.getType().findUniqueConcreteMethod(target);
}
}
}
if (concreteMethod != null && concreteMethod.canRecordTo(assumptions)) {
concreteMethod.recordTo(assumptions);
realTarget = concreteMethod.getResult();
}
}
if (realTarget != null) {
// Don't mutate the passed in arguments
ValueNode[] arguments = originalArguments.clone();
// Cast receiver to its type.
if (!isStatic) {
JavaType receiverType = target.getDeclaringClass();
maybeCastArgument(adder, arguments, 0, receiverType);
}
// Cast reference arguments to its type.
for (int index = 0; index < signature.getParameterCount(false); index++) {
JavaType parameterType = signature.getParameterType(index, target.getDeclaringClass());
maybeCastArgument(adder, arguments, receiverSkip + index, parameterType);
}
InvokeNode invoke = createTargetInvokeNode(assumptions, intrinsicMethod, realTarget, original, bci, returnStamp, arguments);
assert invoke != null : "graph has been modified so this must result an invoke";
return invoke;
}
return null;
}
Aggregations