Search in sources :

Example 16 with ResolvedJavaField

use of jdk.vm.ci.meta.ResolvedJavaField in project graal by oracle.

the class HotSpotResolvedJavaFieldTest method testEquivalenceForInternalFields.

/**
 * Tests that {@code HotSpotResolvedObjectType#createField(String, JavaType, long, int)} always
 * returns an {@linkplain ResolvedJavaField#equals(Object) equivalent} object for an internal
 * field.
 *
 * @throws InvocationTargetException
 * @throws IllegalArgumentException
 * @throws IllegalAccessException
 */
@Test
public void testEquivalenceForInternalFields() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    for (Class<?> c : classesWithInternalFields) {
        HotSpotResolvedObjectType type = HotSpotResolvedObjectType.fromObjectClass(c);
        for (ResolvedJavaField field : type.getInstanceFields(false)) {
            if (field.isInternal()) {
                HotSpotResolvedJavaField expected = (HotSpotResolvedJavaField) field;
                int index = indexField.getInt(expected);
                ResolvedJavaField actual = (ResolvedJavaField) createFieldMethod.invoke(type, expected.getType(), expected.offset(), expected.getModifiers(), index);
                Assert.assertEquals(expected, actual);
            }
        }
    }
}
Also used : HotSpotResolvedObjectType(jdk.vm.ci.hotspot.HotSpotResolvedObjectType) HotSpotResolvedJavaField(jdk.vm.ci.hotspot.HotSpotResolvedJavaField) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) HotSpotResolvedJavaField(jdk.vm.ci.hotspot.HotSpotResolvedJavaField) Test(org.junit.Test)

Example 17 with ResolvedJavaField

use of jdk.vm.ci.meta.ResolvedJavaField in project graal by oracle.

the class AnnotationSubstitutionProcessor method handleSubstitutionClass.

private void handleSubstitutionClass(Class<?> annotatedClass, Class<?> originalClass) {
    // Not sure what happens if the target class is in a hierarchy - so prohibit that for now.
    guarantee(annotatedClass.isInterface() == originalClass.isInterface(), "if original is interface, target must also be interface: %s", annotatedClass);
    guarantee(originalClass.getSuperclass() == Object.class || originalClass.isInterface(), "target class must inherit directly from Object: %s", originalClass);
    ResolvedJavaType original = metaAccess.lookupJavaType(originalClass);
    ResolvedJavaType annotated = metaAccess.lookupJavaType(annotatedClass);
    for (int i = 0; i < ARRAY_DIMENSIONS; i++) {
        ResolvedJavaType substitution = new SubstitutionType(original, annotated);
        register(typeSubstitutions, annotated, original, substitution);
        original = original.getArrayClass();
        annotated = annotated.getArrayClass();
    }
    for (Method m : annotatedClass.getDeclaredMethods()) {
        handleAnnotatedMethodInSubstitutionClass(m, originalClass);
    }
    for (Constructor<?> c : annotatedClass.getDeclaredConstructors()) {
        handleAnnotatedMethodInSubstitutionClass(c, originalClass);
    }
    for (Method m : originalClass.getDeclaredMethods()) {
        handleOriginalMethodInSubstitutionClass(m);
    }
    for (Constructor<?> c : originalClass.getDeclaredConstructors()) {
        handleOriginalMethodInSubstitutionClass(c);
    }
    for (Field f : originalClass.getDeclaredFields()) {
        registerAsDeleted(null, metaAccess.lookupJavaField(f), SUBSTITUTION_DELETE);
    }
    for (Field f : annotatedClass.getDeclaredFields()) {
        ResolvedJavaField field = metaAccess.lookupJavaField(f);
        ResolvedJavaField alias = fieldValueRecomputation(annotatedClass, field, field, f);
        if (!alias.equals(field)) {
            register(fieldSubstitutions, field, null, alias);
        }
    }
}
Also used : AnnotationSubstitutionType(com.oracle.svm.hosted.annotation.AnnotationSubstitutionType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField) Field(java.lang.reflect.Field) AnalysisField(com.oracle.graal.pointsto.meta.AnalysisField) Method(java.lang.reflect.Method) CustomSubstitutionMethod(com.oracle.svm.hosted.annotation.CustomSubstitutionMethod) ResolvedJavaMethod(jdk.vm.ci.meta.ResolvedJavaMethod) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField)

Example 18 with ResolvedJavaField

use of jdk.vm.ci.meta.ResolvedJavaField in project graal by oracle.

the class AnnotationSubstitutionProcessor method processComputedValueFields.

/**
 * Eagerly register all target fields of recomputed value fields as unsafe accessed.
 */
public void processComputedValueFields(BigBang bb) {
    for (ResolvedJavaField field : fieldSubstitutions.values()) {
        if (field instanceof ComputedValue) {
            ComputedValue cvField = (ComputedValue) field;
            switch(cvField.getRecomputeValueKind()) {
                case FieldOffset:
                    AnalysisField targetField = bb.getMetaAccess().lookupJavaField(cvField.getTargetField());
                    targetField.registerAsAccessed();
                    targetField.registerAsUnsafeAccessed();
                    break;
            }
        }
    }
}
Also used : AnalysisField(com.oracle.graal.pointsto.meta.AnalysisField) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField)

Example 19 with ResolvedJavaField

use of jdk.vm.ci.meta.ResolvedJavaField in project graal by oracle.

the class AnnotationSubstitutionProcessor method handleFieldInAliasClass.

private void handleFieldInAliasClass(Field annotatedField, Class<?> originalClass) {
    if (!NativeImageGenerator.includedIn(ImageSingletons.lookup(Platform.class), lookupAnnotation(annotatedField, Platforms.class))) {
        return;
    }
    ResolvedJavaField annotated = metaAccess.lookupJavaField(annotatedField);
    Delete deleteAnnotation = lookupAnnotation(annotatedField, Delete.class);
    Alias aliasAnnotation = lookupAnnotation(annotatedField, Alias.class);
    Inject injectAnnotation = lookupAnnotation(annotatedField, Inject.class);
    int numAnnotations = (deleteAnnotation != null ? 1 : 0) + (aliasAnnotation != null ? 1 : 0) + (injectAnnotation != null ? 1 : 0);
    if (numAnnotations == 0) {
        guarantee(annotatedField.getName().equals("$assertionsDisabled"), "One of @Delete, @Alias, or @Inject must be used: %s", annotatedField);
        /*
             * The field $assertionsDisabled can be present in the original class, but does not have
             * to. We treat it like an optional @Alias fields without field value recomputation.
             */
        ResolvedJavaField original = findOriginalField(annotatedField, originalClass, true);
        if (original != null) {
            register(fieldSubstitutions, annotated, null, original);
        }
        return;
    }
    guarantee(numAnnotations == 1, "Only one of @Delete, @Alias, or @Inject can be used: %s", annotatedField);
    if (injectAnnotation != null) {
        guarantee(!annotated.isStatic(), "@Inject field must not be static: %s", annotated);
        ResolvedJavaField injected = fieldValueRecomputation(originalClass, annotated, annotated, annotatedField);
        register(fieldSubstitutions, annotated, null, injected);
        ResolvedJavaType original = metaAccess.lookupJavaType(originalClass);
        InjectedFieldsType substitution;
        if (typeSubstitutions.get(original) instanceof InjectedFieldsType) {
            substitution = (InjectedFieldsType) typeSubstitutions.get(original);
            register(typeSubstitutions, annotated.getDeclaringClass(), original, substitution);
        } else {
            substitution = new InjectedFieldsType(original);
            register(typeSubstitutions, annotated.getDeclaringClass(), original, substitution);
        }
        substitution.addInjectedField(injected);
    } else {
        ResolvedJavaField original = findOriginalField(annotatedField, originalClass, false);
        if (original == null) {
            return;
        }
        guarantee(annotated.isStatic() == original.isStatic(), "Static modifier mismatch: %s, %s", annotated, original);
        guarantee(annotated.getJavaKind() == original.getJavaKind(), "Type mismatch: %s, %s", annotated, original);
        if (deleteAnnotation != null) {
            registerAsDeleted(annotated, original, deleteAnnotation);
        } else {
            ResolvedJavaField alias = fieldValueRecomputation(originalClass, original, annotated, annotatedField);
            register(fieldSubstitutions, annotated, original, alias);
        }
    }
}
Also used : Delete(com.oracle.svm.core.annotate.Delete) Inject(com.oracle.svm.core.annotate.Inject) Alias(com.oracle.svm.core.annotate.Alias) ResolvedJavaType(jdk.vm.ci.meta.ResolvedJavaType) ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField)

Example 20 with ResolvedJavaField

use of jdk.vm.ci.meta.ResolvedJavaField in project graal by oracle.

the class UnsafeAutomaticSubstitutionProcessor method tryAutomaticRecomputation.

/**
 * Try to register the automatic substitution for a field. Bail if the field was deleted or
 * another substitution is detected.
 */
private boolean tryAutomaticRecomputation(ResolvedJavaField field, Kind kind, Supplier<ComputedValueField> substitutionSupplier) {
    if (annotationSubstitutions.isDeleted(field)) {
        String conflictingSubstitution = "The field " + field.format("%H.%n") + " is marked as deleted. ";
        reportConflictingSubstitution(field, kind, conflictingSubstitution);
        return false;
    } else {
        Optional<ResolvedJavaField> annotationSubstitution = annotationSubstitutions.findSubstitution(field);
        if (annotationSubstitution.isPresent()) {
            /* An annotation substitutions detected. */
            ResolvedJavaField substitutionField = annotationSubstitution.get();
            if (substitutionField instanceof ComputedValueField) {
                ComputedValueField computedSubstitutionField = (ComputedValueField) substitutionField;
                if (computedSubstitutionField.getRecomputeValueKind().equals(kind)) {
                    reportUnnecessarySubstitution(substitutionField, computedSubstitutionField);
                    return false;
                } else if (computedSubstitutionField.getRecomputeValueKind().equals(Kind.None)) {
                    /*
                         * This is essentially and @Alias field. An @Alias for a field with an
                         * automatic recomputed value is allowed but the alias needs to be
                         * overwritten otherwise would read the value from the original field. To do
                         * this a new recomputed value field is registered in the automatic
                         * substitution processor, which follows the annotation substitution
                         * processor in the substitutions chain. Thus, every time the substitutions
                         * chain is queried for the original field, e.g., in
                         * AnalysisUniverse.lookupAllowUnresolved(JavaField), the alias field is
                         * forwarded to the the automatic substitution.
                         */
                    addSubstitutionField(computedSubstitutionField, substitutionSupplier.get());
                    reportOvewrittenSubstitution(substitutionField, kind, computedSubstitutionField.getAnnotated(), computedSubstitutionField.getRecomputeValueKind());
                    return true;
                } else {
                    String conflictingSubstitution = "Detected RecomputeFieldValue." + computedSubstitutionField.getRecomputeValueKind() + " " + computedSubstitutionField.getAnnotated().format("%H.%n") + " substitution field. ";
                    reportConflictingSubstitution(substitutionField, kind, conflictingSubstitution);
                    return false;
                }
            } else {
                String conflictingSubstitution = "Detected " + substitutionField.format("%H.%n") + " substitution field. ";
                reportConflictingSubstitution(substitutionField, kind, conflictingSubstitution);
                return false;
            }
        } else {
            /* No other substitutions detected. */
            addSubstitutionField(field, substitutionSupplier.get());
            return true;
        }
    }
}
Also used : ResolvedJavaField(jdk.vm.ci.meta.ResolvedJavaField)

Aggregations

ResolvedJavaField (jdk.vm.ci.meta.ResolvedJavaField)45 ValueNode (org.graalvm.compiler.nodes.ValueNode)16 ResolvedJavaMethod (jdk.vm.ci.meta.ResolvedJavaMethod)10 ResolvedJavaType (jdk.vm.ci.meta.ResolvedJavaType)10 ArrayList (java.util.ArrayList)7 StructuredGraph (org.graalvm.compiler.nodes.StructuredGraph)6 AnalysisField (com.oracle.graal.pointsto.meta.AnalysisField)4 Field (java.lang.reflect.Field)4 JavaKind (jdk.vm.ci.meta.JavaKind)4 Invoke (org.graalvm.compiler.nodes.Invoke)4 OffsetAddressNode (org.graalvm.compiler.nodes.memory.address.OffsetAddressNode)4 SnippetReflectionProvider (org.graalvm.compiler.api.replacements.SnippetReflectionProvider)3 DebugCloseable (org.graalvm.compiler.debug.DebugCloseable)3 NodePlugin (org.graalvm.compiler.nodes.graphbuilderconf.NodePlugin)3 LoadFieldNode (org.graalvm.compiler.nodes.java.LoadFieldNode)3 LocationIdentity (org.graalvm.word.LocationIdentity)3 Delete (com.oracle.svm.core.annotate.Delete)2 Method (java.lang.reflect.Method)2 JavaField (jdk.vm.ci.meta.JavaField)2 MetaAccessProvider (jdk.vm.ci.meta.MetaAccessProvider)2