use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class CFunctionCallStubMethod method buildGraph.
@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
NativeLibraries nativeLibraries = CEntryPointCallStubSupport.singleton().getNativeLibraries();
CFunction annotation = method.getAnnotation(CFunction.class);
boolean needsTransition = annotation.transition() != Transition.NO_TRANSITION;
if (purpose == Purpose.PREPARE_RUNTIME_COMPILATION && needsTransition) {
/*
* C function calls that need a transition cannot be runtime compiled (and cannot be
* inlined during runtime compilation). Deoptimization could be required while we are
* blocked in native code, which means the deoptimization stub would need to do the
* native-to-Java transition.
*/
ImageSingletons.lookup(CFunctionFeature.class).warnRuntimeCompilationReachableCFunctionWithTransition(this);
return null;
}
boolean deoptimizationTarget = method instanceof SharedMethod && ((SharedMethod) method).isDeoptTarget();
HostedGraphKit kit = new HostedGraphKit(debug, providers, method);
FrameStateBuilder state = kit.getFrameState();
ValueNode callAddress = kit.unique(new CGlobalDataLoadAddressNode(linkage));
List<ValueNode> arguments = kit.loadArguments(method.toParameterTypes());
Signature signature = adaptSignatureAndConvertArguments(method, providers, nativeLibraries, kit, method.getSignature(), arguments);
state.clearLocals();
ValueNode returnValue = kit.createCFunctionCall(callAddress, method, arguments, signature, needsTransition, deoptimizationTarget);
returnValue = adaptReturnValue(method, providers, nativeLibraries, kit, returnValue);
kit.createReturn(returnValue, signature.getReturnKind());
assert kit.getGraph().verify();
return kit.getGraph();
}
use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class FrameStateBuilder method initializeFromArgumentsArray.
public void initializeFromArgumentsArray(ValueNode[] arguments) {
int javaIndex = 0;
int index = 0;
if (!getMethod().isStatic()) {
// set the receiver
locals[javaIndex] = arguments[index];
javaIndex = 1;
index = 1;
}
Signature sig = getMethod().getSignature();
int max = sig.getParameterCount(false);
for (int i = 0; i < max; i++) {
JavaKind kind = sig.getParameterKind(i);
locals[javaIndex] = arguments[index];
javaIndex++;
if (kind.needsTwoSlots()) {
locals[javaIndex] = TWO_SLOT_MARKER;
javaIndex++;
}
index++;
}
}
use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class GraphKit method startInvokeWithException.
public InvokeWithExceptionNode startInvokeWithException(ResolvedJavaMethod method, InvokeKind invokeKind, FrameStateBuilder frameStateBuilder, int invokeBci, int exceptionEdgeBci, ValueNode... args) {
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);
}
ExceptionObjectNode exceptionObject = add(new ExceptionObjectNode(getMetaAccess()));
if (frameStateBuilder != null) {
FrameStateBuilder exceptionState = frameStateBuilder.copy();
exceptionState.clearStack();
exceptionState.push(JavaKind.Object, exceptionObject);
exceptionState.setRethrowException(false);
exceptionObject.setStateAfter(exceptionState.create(exceptionEdgeBci, exceptionObject));
}
MethodCallTargetNode callTarget = graph.add(createMethodCallTarget(invokeKind, method, args, returnStamp, invokeBci));
InvokeWithExceptionNode invoke = append(new InvokeWithExceptionNode(callTarget, exceptionObject, invokeBci));
AbstractBeginNode noExceptionEdge = graph.add(KillingBeginNode.create(LocationIdentity.any()));
invoke.setNext(noExceptionEdge);
if (frameStateBuilder != null) {
if (invoke.getStackKind() != JavaKind.Void) {
frameStateBuilder.push(invoke.getStackKind(), invoke);
}
invoke.setStateAfter(frameStateBuilder.create(invokeBci, invoke));
if (invoke.getStackKind() != JavaKind.Void) {
frameStateBuilder.pop(invoke.getStackKind());
}
}
lastFixedNode = null;
InvokeWithExceptionStructure s = new InvokeWithExceptionStructure();
s.state = InvokeWithExceptionStructure.State.INVOKE;
s.noExceptionEdge = noExceptionEdge;
s.exceptionEdge = exceptionObject;
s.exceptionObject = exceptionObject;
pushStructure(s);
return invoke;
}
use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class JNIJavaCallWrapperMethod method createSignature.
private JNISignature createSignature(MetaAccessProvider metaAccess) {
ResolvedJavaType objectHandle = metaAccess.lookupJavaType(JNIObjectHandle.class);
List<JavaType> args = new ArrayList<>();
args.add(metaAccess.lookupJavaType(JNIEnvironment.class));
// this (instance method) or class (static method)
args.add(objectHandle);
if (nonVirtual) {
// class of implementation to invoke
args.add(objectHandle);
}
args.add(metaAccess.lookupJavaType(JNIMethodId.class));
Signature targetSignature = targetMethod.getSignature();
if (callVariant == CallVariant.VARARGS) {
for (JavaType targetArg : targetSignature.toParameterTypes(null)) {
JavaKind kind = targetArg.getJavaKind();
if (kind.isObject()) {
args.add(objectHandle);
} else if (kind == JavaKind.Float) {
// C varargs promote float to double
args.add(metaAccess.lookupJavaType(JavaKind.Double.toJavaClass()));
} else {
args.add(targetArg);
}
}
} else if (callVariant == CallVariant.ARRAY) {
// const jvalue *
args.add(metaAccess.lookupJavaType(JNIValue.class));
} else if (callVariant == CallVariant.VA_LIST) {
// va_list (a pointer of some kind)
args.add(metaAccess.lookupJavaType(WordBase.class));
} else {
throw VMError.shouldNotReachHere();
}
JavaType returnType = targetSignature.getReturnType(null);
if (returnType.getJavaKind().isObject() || targetMethod.isConstructor()) {
// Constructor: returns `this` to implement NewObject
returnType = objectHandle;
}
return new JNISignature(args, returnType);
}
use of jdk.vm.ci.meta.Signature in project graal by oracle.
the class JNIJavaCallWrapperMethod method buildGraph.
@Override
public StructuredGraph buildGraph(DebugContext debug, ResolvedJavaMethod method, HostedProviders providers, Purpose purpose) {
UniverseMetaAccess metaAccess = (UniverseMetaAccess) providers.getMetaAccess();
JNIGraphKit kit = new JNIGraphKit(debug, providers, method);
StructuredGraph graph = kit.getGraph();
FrameStateBuilder state = new FrameStateBuilder(null, method, graph);
state.initializeForMethodStart(null, true, providers.getGraphBuilderPlugins());
JavaKind vmThreadKind = metaAccess.lookupJavaType(JNIEnvironment.class).getJavaKind();
ValueNode vmThread = kit.loadLocal(0, vmThreadKind);
kit.append(new CEntryPointEnterNode(EnterAction.Enter, vmThread));
ResolvedJavaMethod invokeMethod = providers.getMetaAccess().lookupJavaMethod(reflectMethod);
Signature invokeSignature = invokeMethod.getSignature();
List<Pair<ValueNode, ResolvedJavaType>> argsWithTypes = loadAndUnboxArguments(kit, providers, invokeMethod, invokeSignature);
JavaKind returnKind = invokeSignature.getReturnKind();
if (invokeMethod.isConstructor()) {
// return `this` to implement NewObject
assert returnKind == JavaKind.Void;
returnKind = JavaKind.Object;
}
IfNode ifNode = kit.startIf(null, BranchProbabilityNode.FAST_PATH_PROBABILITY);
kit.thenPart();
LogicNode typeChecks = LogicConstantNode.tautology(kit.getGraph());
ValueNode[] args = new ValueNode[argsWithTypes.size()];
for (int i = 0; i < argsWithTypes.size(); i++) {
ValueNode value = argsWithTypes.get(i).getLeft();
ResolvedJavaType type = argsWithTypes.get(i).getRight();
if (!type.isPrimitive() && !type.isJavaLangObject()) {
TypeReference typeRef = TypeReference.createTrusted(kit.getAssumptions(), type);
LogicNode instanceOf = kit.unique(InstanceOfNode.createAllowNull(typeRef, value, null, null));
typeChecks = LogicNode.and(typeChecks, instanceOf, BranchProbabilityNode.FAST_PATH_PROBABILITY);
FixedGuardNode guard = kit.append(new FixedGuardNode(instanceOf, DeoptimizationReason.ClassCastException, DeoptimizationAction.None, false));
value = kit.append(PiNode.create(value, StampFactory.object(typeRef), guard));
}
args[i] = value;
}
// safe because logic nodes are floating
ifNode.setCondition(typeChecks);
InvokeKind kind = //
invokeMethod.isStatic() ? //
InvokeKind.Static : ((nonVirtual || invokeMethod.isConstructor()) ? InvokeKind.Special : InvokeKind.Virtual);
ValueNode invokeResult = createInvoke(kit, invokeMethod, kind, state, kit.bci(), args);
if (invokeMethod.isConstructor()) {
// return `this` to implement NewObject
invokeResult = args[0];
}
// illegal parameter types
kit.elsePart();
ConstantNode exceptionObject = kit.createObject(cachedArgumentClassCastException);
kit.retainPendingException(exceptionObject);
ValueNode typeMismatchValue = null;
if (returnKind != JavaKind.Void) {
typeMismatchValue = kit.unique(ConstantNode.defaultForKind(returnKind.getStackKind()));
}
AbstractMergeNode merge = kit.endIf();
ValueNode returnValue = null;
if (returnKind != JavaKind.Void) {
ValueNode[] inputs = { invokeResult, typeMismatchValue };
returnValue = kit.getGraph().addWithoutUnique(new ValuePhiNode(invokeResult.stamp(NodeView.DEFAULT), merge, inputs));
state.push(returnKind, returnValue);
}
merge.setStateAfter(state.create(kit.bci(), merge));
if (returnKind != JavaKind.Void) {
state.pop(returnKind);
if (returnKind.isObject()) {
returnValue = kit.boxObjectInLocalHandle(returnValue);
}
}
kit.append(new CEntryPointLeaveNode(LeaveAction.Leave));
kit.createReturn(returnValue, returnKind);
assert graph.verify();
return graph;
}
Aggregations