package com.oracle.svm.core.graal.meta;
import static com.oracle.svm.core.util.VMError.shouldNotReachHere;
import java.util.HashMap;
import java.util.Map;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.core.common.spi.ForeignCallDescriptor;
import org.graalvm.compiler.core.common.spi.ForeignCallSignature;
import org.graalvm.compiler.phases.util.Providers;
import org.graalvm.compiler.replacements.arraycopy.ArrayCopyForeignCalls;
import org.graalvm.compiler.replacements.arraycopy.ArrayCopyLookup;
import org.graalvm.nativeimage.ImageSingletons;
import org.graalvm.nativeimage.Platform;
import org.graalvm.nativeimage.Platforms;
import org.graalvm.word.LocationIdentity;
import com.oracle.svm.core.SubstrateTargetDescription;
import com.oracle.svm.core.snippets.SnippetRuntime;
import com.oracle.svm.core.util.VMError;
import jdk.vm.ci.meta.JavaKind;
public class SubstrateForeignCallsProvider implements ArrayCopyForeignCalls {
private final Map<ForeignCallSignature, SubstrateForeignCallLinkage> foreignCalls;
protected ArrayCopyLookup arrayCopyLookup;
@Platforms(Platform.HOSTED_ONLY.class)
public SubstrateForeignCallsProvider() {
this.foreignCalls = new HashMap<>();
}
public Map<ForeignCallSignature, SubstrateForeignCallLinkage> getForeignCalls() {
return foreignCalls;
}
public void register(Providers providers, SnippetRuntime.SubstrateForeignCallDescriptor... descriptors) {
for (SnippetRuntime.SubstrateForeignCallDescriptor descriptor : descriptors) {
SubstrateForeignCallLinkage linkage = new SubstrateForeignCallLinkage(providers, descriptor);
foreignCalls.put(descriptor.getSignature(), linkage);
}
}
@Override
public SubstrateForeignCallLinkage lookupForeignCall(ForeignCallDescriptor descriptor) {
SubstrateForeignCallLinkage callTarget = foreignCalls.get(descriptor.getSignature());
if (callTarget == null) {
throw shouldNotReachHere("missing implementation for runtime call: " + descriptor);
}
return callTarget;
}
@Override
public ForeignCallDescriptor getDescriptor(ForeignCallSignature signature) {
SubstrateForeignCallLinkage linkage = foreignCalls.get(signature);
return linkage.getDescriptor();
}
@Override
public LIRKind getValueKind(JavaKind javaKind) {
return LIRKind.fromJavaKind(ImageSingletons.lookup(SubstrateTargetDescription.class).arch, javaKind);
}
public void registerArrayCopyForeignCallsDelegate(ArrayCopyLookup arraycopyForeignCalls) {
this.arrayCopyLookup = arraycopyForeignCalls;
}
@Override
public ForeignCallDescriptor lookupCheckcastArraycopyDescriptor(boolean uninit) {
if (arrayCopyLookup != null) {
return arrayCopyLookup.lookupCheckcastArraycopyDescriptor(uninit);
} else {
throw VMError.unsupportedFeature("Fast checkcast ArrayCopy not supported yet.");
}
}
@Override
public ForeignCallDescriptor lookupArraycopyDescriptor(JavaKind kind, boolean aligned, boolean disjoint, boolean uninit, LocationIdentity killedLocation) {
if (arrayCopyLookup != null) {
return arrayCopyLookup.lookupArraycopyDescriptor(kind, aligned, disjoint, uninit, killedLocation);
} else {
throw VMError.unsupportedFeature("Fast ArrayCopy not supported yet.");
}
}
}