use of com.oracle.svm.hosted.meta.HostedType in project graal by oracle.
the class RuntimeStrengthenStampsPhase method toTarget.
@Override
protected ResolvedJavaType toTarget(ResolvedJavaType type) {
AnalysisType result = ((HostedType) type).getWrapped();
/* Make sure that the SubstrateType is created. */
objectReplacer.createType(result);
return result;
}
use of com.oracle.svm.hosted.meta.HostedType in project graal by oracle.
the class Target_com_oracle_truffle_api_interop_java_ObjectProxyHandler method beforeCompilation.
@Override
public void beforeCompilation(BeforeCompilationAccess config) {
BeforeCompilationAccessImpl access = (BeforeCompilationAccessImpl) config;
if (GraalFeature.Options.PrintRuntimeCompileMethods.getValue() && blacklistViolations.size() > 0) {
System.out.println();
System.out.println("=== Found " + blacklistViolations.size() + " compilation blacklist violations ===");
System.out.println();
for (GraalFeature.CallTreeNode node : blacklistViolations) {
System.out.println("Blacklisted method");
System.out.println(node.getImplementationMethod().format(" %H.%n(%p)"));
System.out.println("called from");
for (GraalFeature.CallTreeNode cur = node; cur != null; cur = cur.getParent()) {
System.out.println(" " + cur.getSourceReference());
}
}
}
if (warnViolations.size() > 0) {
/*
* It is enough to print one warning message with one stack trace. Take the shortest
* stack trace.
*/
GraalFeature.CallTreeNode printNode = null;
int printLength = Integer.MAX_VALUE;
for (GraalFeature.CallTreeNode warnNode : warnViolations) {
int warnLength = 0;
for (GraalFeature.CallTreeNode cur = warnNode; cur != null; cur = cur.getParent()) {
warnLength++;
}
if (warnLength < printLength) {
printNode = warnNode;
printLength = warnLength;
}
}
System.out.println("WARNING: suspicious method reachable for runtime compilation: " + printNode.getImplementationMethod().format("%H.%n(%p)"));
System.out.println("Check the complete tree of reachable methods using the option " + GraalFeature.Options.PrintRuntimeCompileMethods.getDescriptor().getFieldName());
System.out.println("Suspicious method is called from");
for (GraalFeature.CallTreeNode cur = printNode; cur != null; cur = cur.getParent()) {
System.out.println(" " + cur.getSourceReference());
}
}
if (neverPartOfCompilationViolations.size() > 0) {
System.out.println("ERROR: CompilerAsserts.neverPartOfCompilation reachable for runtime compilation from " + neverPartOfCompilationViolations.size() + " places:");
for (GraalFeature.CallTreeNode neverPartOfCompilationNode : neverPartOfCompilationViolations) {
System.out.println("called from");
for (GraalFeature.CallTreeNode cur = neverPartOfCompilationNode; cur != null; cur = cur.getParent()) {
System.out.println(" " + cur.getSourceReference());
}
}
throw VMError.shouldNotReachHere("CompilerAsserts.neverPartOfCompilation reachable for runtime compilation");
}
if (Options.TruffleCheckFrameImplementation.getValue() && useTruffleCompiler()) {
/*
* Check that only one Frame implementation is seen as instantiated by the static
* analysis. That allows de-virtualization of all calls to Frame methods in the
* interpreter.
*
* The DefaultTruffleRuntime uses multiple Frame implementations (DefaultVirtualFrame,
* DefaultMaterializedFrame, ReadOnlyFrame) to detect wrong usages of the Frame API, so
* we can only check when running with compilation enabled.
*/
Optional<? extends ResolvedJavaType> optionalFrameType = access.getMetaAccess().optionalLookupJavaType(Frame.class);
if (optionalFrameType.isPresent()) {
HostedType frameType = (HostedType) optionalFrameType.get();
Set<HostedType> implementations = new HashSet<>();
collectImplementations(frameType, implementations);
if (implementations.size() > 1) {
throw UserError.abort("More than one implementation of " + Frame.class.getTypeName() + " found. For performance reasons, Truffle languages must not provide new implementations, and instead only use the single implementation provided by the Truffle runtime. " + "To disable this check, add " + SubstrateOptionsParser.commandArgument(Options.TruffleCheckFrameImplementation, "-") + " to the native-image command line. " + "Found classes: " + implementations.stream().map(m -> m.toJavaName(true)).collect(Collectors.joining(", ")));
} else {
assert implementations.size() == 0 || implementations.iterator().next() == frameType.getSingleImplementor();
}
}
}
}
use of com.oracle.svm.hosted.meta.HostedType in project graal by oracle.
the class JNIFunctionTablesFeature method buildInvokesInitializer.
private JNIStructFunctionsInitializer<JNIInvokeInterface> buildInvokesInitializer(CompilationAccessImpl access, CFunctionPointer unimplemented) {
HostedType invokes = access.getMetaAccess().lookupJavaType(JNIInvocationInterface.class);
HostedMethod[] methods = invokes.getDeclaredMethods();
int index = 0;
int[] offsets = new int[methods.length];
CFunctionPointer[] pointers = new CFunctionPointer[offsets.length];
for (HostedMethod method : methods) {
StructFieldInfo field = findFieldFor(invokeInterfaceMetadata, method.getName());
offsets[index] = field.getOffsetInfo().getProperty();
pointers[index] = getStubFunctionPointer(access, method);
index++;
}
VMError.guarantee(index == offsets.length && index == pointers.length);
return new JNIStructFunctionsInitializer<>(JNIInvokeInterface.class, offsets, pointers, unimplemented);
}
use of com.oracle.svm.hosted.meta.HostedType in project graal by oracle.
the class JNIFunctionTablesFeature method buildFunctionsInitializer.
private JNIStructFunctionsInitializer<JNINativeInterface> buildFunctionsInitializer(CompilationAccessImpl access, CFunctionPointer unimplemented) {
Class<JNIFunctions> clazz = JNIFunctions.class;
HostedType functions = access.getMetaAccess().lookupJavaType(clazz);
HostedMethod[] methods = functions.getDeclaredMethods();
int index = 0;
int count = methods.length + generatedMethods.length;
// Call, CallStatic, CallNonvirtual: for each return value kind: array, va_list, varargs
// NewObject: array, va_list, varargs
count += (jniKinds.size() * 3 + 1) * 3;
int[] offsets = new int[count];
CFunctionPointer[] pointers = new CFunctionPointer[offsets.length];
for (HostedMethod method : methods) {
StructFieldInfo field = findFieldFor(functionTableMetadata, method.getName());
offsets[index] = field.getOffsetInfo().getProperty();
pointers[index] = getStubFunctionPointer(access, method);
index++;
}
for (ResolvedJavaMethod accessor : generatedMethods) {
StructFieldInfo field = findFieldFor(functionTableMetadata, accessor.getName());
AnalysisUniverse analysisUniverse = access.getUniverse().getBigBang().getUniverse();
AnalysisMethod analysisMethod = analysisUniverse.lookup(accessor);
HostedMethod hostedMethod = access.getUniverse().lookup(analysisMethod);
offsets[index] = field.getOffsetInfo().getProperty();
pointers[index] = MethodPointer.factory(hostedMethod);
index++;
}
for (CallVariant variant : CallVariant.values()) {
CFunctionPointer trampoline = prepareCallTrampoline(access, variant, false);
String suffix = (variant == CallVariant.ARRAY) ? "A" : ((variant == CallVariant.VA_LIST) ? "V" : "");
CFunctionPointer nonvirtualTrampoline = prepareCallTrampoline(access, variant, true);
for (JavaKind kind : jniKinds) {
String[] prefixes = { "Call", "CallStatic" };
for (String prefix : prefixes) {
StructFieldInfo field = findFieldFor(functionTableMetadata, prefix + kind.name() + "Method" + suffix);
offsets[index] = field.getOffsetInfo().getProperty();
pointers[index] = trampoline;
index++;
}
StructFieldInfo field = findFieldFor(functionTableMetadata, "CallNonvirtual" + kind.name() + "Method" + suffix);
offsets[index] = field.getOffsetInfo().getProperty();
pointers[index] = nonvirtualTrampoline;
index++;
}
StructFieldInfo field = findFieldFor(functionTableMetadata, "NewObject" + suffix);
offsets[index] = field.getOffsetInfo().getProperty();
pointers[index] = trampoline;
index++;
}
VMError.guarantee(index == offsets.length && index == pointers.length);
return new JNIStructFunctionsInitializer<>(JNINativeInterface.class, offsets, pointers, unimplemented);
}
use of com.oracle.svm.hosted.meta.HostedType in project graal by oracle.
the class NativeImageHeap method addObjectToBootImageHeap.
/**
* It has been determined that an object should be added to the model of the native image heap.
* This is the mechanics of recursively adding the object and all its fields and array elements
* to the model of the native image heap.
*/
private void addObjectToBootImageHeap(final Object original, final Object canonicalObj, final boolean canonicalizable, boolean immutableFromParent, final int identityHashCode, final Object reason) {
final Optional<HostedType> optionalType = getMetaAccess().optionalLookupJavaType(canonicalObj.getClass());
if (!optionalType.isPresent() || !optionalType.get().isInstantiated()) {
throw UserError.abort("Image heap writing found an object whose class was not seen as instantiated during static analysis. " + "Did a static field or an object referenced from a static field changed during native image generation? " + "For example, a lazily initialized cache could have been initialized during image generation, " + "in which case you need to force eager initialization of the cache before static analysis or reset the cache using a field value recomputation.\n" + " object: " + original + " of class: " + original.getClass().getTypeName() + "\n" + " reachable through:\n" + fillReasonStack(new StringBuilder(), reason));
}
final HostedType type = optionalType.get();
if (type.isInstanceClass()) {
final HostedInstanceClass clazz = (HostedInstanceClass) type;
final JavaConstant con = SubstrateObjectConstant.forObject(canonicalObj);
final Object hybridArray;
final long size;
if (HybridLayout.isHybrid(clazz)) {
HybridLayout<?> hybridLayout = hybridLayouts.get(clazz);
if (hybridLayout == null) {
hybridLayout = new HybridLayout<>(clazz, layout);
hybridLayouts.put(clazz, hybridLayout);
}
/*
* The hybrid array and bit set are written within the hybrid object. So they may
* not be written as separate objects. We use the blacklist to check that.
*/
HostedField bitsetField = hybridLayout.getBitsetField();
if (bitsetField != null) {
BitSet bitSet = (BitSet) SubstrateObjectConstant.asObject(bitsetField.readStorageValue(con));
if (bitSet != null) {
blacklist.put(bitSet, Boolean.TRUE);
}
}
hybridArray = SubstrateObjectConstant.asObject(hybridLayout.getArrayField().readStorageValue(con));
blacklist.put(hybridArray, Boolean.TRUE);
size = hybridLayout.getTotalSize(Array.getLength(hybridArray));
} else {
hybridArray = null;
size = LayoutEncoding.getInstanceSize(clazz.getHub().getLayoutEncoding()).rawValue();
}
// All canonicalizable objects are immutable,
// as are instances of known immutable classes.
final ObjectInfo info = addToHeapPartition(original, canonicalObj, clazz, size, identityHashCode, canonicalizable, immutableFromParent, reason);
recursiveAddObject(clazz.getHub(), canonicalizable, false, info);
// Recursively add all the fields of the object.
// Even if the parent is not canonicalizable, the fields may be canonicalizable.
final boolean fieldsAreImmutable = canonicalObj instanceof String;
for (HostedField field : clazz.getInstanceFields(true)) {
if (field.getType().getStorageKind() == JavaKind.Object && !HybridLayout.isHybridField(field) && field.isAccessed()) {
assert field.getLocation() >= 0;
recursiveAddObject(SubstrateObjectConstant.asObject(field.readStorageValue(con)), canonicalizable, fieldsAreImmutable, info);
}
}
if (hybridArray instanceof Object[]) {
addArrayElements((Object[]) hybridArray, canonicalizable, info);
}
} else if (type.isArray()) {
HostedArrayClass clazz = (HostedArrayClass) type;
int length = Array.getLength(canonicalObj);
JavaKind kind = type.getComponentType().getJavaKind();
final long size = layout.getArraySize(kind, length);
final ObjectInfo info = addToHeapPartition(original, canonicalObj, clazz, size, identityHashCode, canonicalizable, immutableFromParent, reason);
recursiveAddObject(clazz.getHub(), canonicalizable, false, info);
if (kind == JavaKind.Object) {
addArrayElements((Object[]) canonicalObj, canonicalizable, info);
}
} else {
throw shouldNotReachHere();
}
}
Aggregations