All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oracle.graal.pointsto.standalone.features.StandaloneAnalysisFeatureImpl Maven / Gradle / Ivy

Go to download

A standalone version of SubstrateVM static analysis to use for general pointsto analysis

The newest version!
/*
 * Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
 * Copyright (c) 2022, 2022, Alibaba Group Holding Limited. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.oracle.graal.pointsto.standalone.features;

import java.lang.reflect.Executable;
import java.lang.reflect.Field;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.stream.Collectors;

import org.graalvm.nativeimage.hosted.Feature;
import org.graalvm.nativeimage.hosted.FieldValueTransformer;

import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.meta.AnalysisMetaAccess;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
import com.oracle.graal.pointsto.standalone.StandaloneHost;

import jdk.graal.compiler.debug.DebugContext;

public class StandaloneAnalysisFeatureImpl {
    public abstract static class FeatureAccessImpl implements Feature.FeatureAccess {

        protected final StandaloneAnalysisFeatureManager featureManager;
        protected final ClassLoader analysisClassLoader;
        protected final DebugContext debugContext;

        FeatureAccessImpl(StandaloneAnalysisFeatureManager featureManager, ClassLoader classLoader, DebugContext debugContext) {
            this.featureManager = featureManager;
            this.analysisClassLoader = classLoader;
            this.debugContext = debugContext;
        }

        @Override
        public Class findClassByName(String className) {
            try {
                return Class.forName(className, false, analysisClassLoader);
            } catch (ClassNotFoundException e) {
                return null;
            }
        }

        public DebugContext getDebugContext() {
            return debugContext;
        }

        @Override
        public List getApplicationClassPath() {
            return null;
        }

        @Override
        public List getApplicationModulePath() {
            return null;
        }

        @Override
        public ClassLoader getApplicationClassLoader() {
            return analysisClassLoader;
        }
    }

    abstract static class AnalysisAccessBase extends FeatureAccessImpl {

        protected final BigBang bb;

        AnalysisAccessBase(StandaloneAnalysisFeatureManager featureManager, ClassLoader imageClassLoader, BigBang bb, DebugContext debugContext) {
            super(featureManager, imageClassLoader, debugContext);
            this.bb = bb;
        }

        public BigBang getBigBang() {
            return bb;
        }

        public AnalysisUniverse getUniverse() {
            return bb.getUniverse();
        }

        public AnalysisMetaAccess getMetaAccess() {
            return bb.getMetaAccess();
        }

        public boolean isReachable(Class clazz) {
            return isReachable(getMetaAccess().lookupJavaType(clazz));
        }

        public boolean isReachable(AnalysisType type) {
            return type.isReachable();
        }

        public boolean isReachable(Field field) {
            return isReachable(getMetaAccess().lookupJavaField(field));
        }

        public boolean isReachable(AnalysisField field) {
            return field.isAccessed();
        }

        public boolean isReachable(Executable method) {
            return isReachable(getMetaAccess().lookupJavaMethod(method));
        }

        public boolean isReachable(AnalysisMethod method) {
            return method.isReachable();
        }

        public Set> reachableSubtypes(Class baseClass) {
            return reachableSubtypes(getMetaAccess().lookupJavaType(baseClass)).stream()
                            .map(AnalysisType::getJavaClass).collect(Collectors.toCollection(LinkedHashSet::new));
        }

        Set reachableSubtypes(AnalysisType baseType) {
            Set result = baseType.getAllSubtypes();
            result.removeIf(t -> !isReachable(t));
            return result;
        }

        public Set reachableMethodOverrides(Executable baseMethod) {
            return reachableMethodOverrides(getMetaAccess().lookupJavaMethod(baseMethod)).stream()
                            .map(AnalysisMethod::getJavaMethod)
                            .filter(Objects::nonNull)
                            .collect(Collectors.toCollection(LinkedHashSet::new));
        }

        Set reachableMethodOverrides(AnalysisMethod baseMethod) {
            return AnalysisUniverse.getMethodImplementations(baseMethod, true);
        }
    }

    public static class BeforeAnalysisAccessImpl extends AnalysisAccessBase implements Feature.BeforeAnalysisAccess {

        public BeforeAnalysisAccessImpl(StandaloneAnalysisFeatureManager featureManager, ClassLoader imageClassLoader, BigBang bb, DebugContext debugContext) {
            super(featureManager, imageClassLoader, bb, debugContext);
        }

        @Override
        public void registerAsUsed(Class clazz) {
            registerAsUsed(getMetaAccess().lookupJavaType(clazz), "registered from Feature API");
        }

        public void registerAsUsed(AnalysisType aType, Object reason) {
            aType.registerAsReachable(reason);
        }

        @Override
        public void registerAsInHeap(Class clazz) {
            registerAsInHeap(getMetaAccess().lookupJavaType(clazz), "registered from Feature API");
        }

        public void registerAsInHeap(AnalysisType aType, Object reason) {
            aType.registerAsInstantiated(reason);
        }

        @Override
        public void registerAsUnsafeAllocated(Class type) {
            getMetaAccess().lookupJavaType(type).registerAsUnsafeAllocated("registered from Feature API");
        }

        @Override
        public void registerAsAccessed(Field field) {
            registerAsAccessed(getMetaAccess().lookupJavaField(field), "registered from Feature API");
        }

        public void registerAsAccessed(AnalysisField aField, Object reason) {
            aField.registerAsAccessed(reason);
        }

        public void registerAsRead(Field field) {
            registerAsRead(getMetaAccess().lookupJavaField(field));
        }

        public void registerAsRead(AnalysisField aField) {
            aField.registerAsRead(null);
        }

        @Override
        public void registerAsUnsafeAccessed(Field field) {
            registerAsUnsafeAccessed(getMetaAccess().lookupJavaField(field), "registered from Feature API");
        }

        public boolean registerAsUnsafeAccessed(AnalysisField aField, Object reason) {
            if (!aField.isUnsafeAccessed()) {
                aField.registerAsUnsafeAccessed(reason);
                return true;
            }
            return false;
        }

        public void registerAsFrozenUnsafeAccessed(Field field) {
            registerAsFrozenUnsafeAccessed(getMetaAccess().lookupJavaField(field));
        }

        public void registerAsFrozenUnsafeAccessed(AnalysisField aField) {
            aField.registerAsFrozenUnsafeAccessed();
            registerAsUnsafeAccessed(aField, "registered from standalone feature");
        }

        public void registerAsUnsafeAccessed(Field field, Object reason) {
            registerAsUnsafeAccessed(getMetaAccess().lookupJavaField(field), reason);
        }

        public void registerAsInvoked(Executable method, boolean invokeSpecial, Object reason) {
            registerAsInvoked(getMetaAccess().lookupJavaMethod(method), invokeSpecial, reason);
        }

        public void registerAsInvoked(AnalysisMethod aMethod, boolean invokeSpecial, Object reason) {
            bb.addRootMethod(aMethod, invokeSpecial, reason);
        }

        public void registerUnsafeFieldsRecomputed(Class clazz) {
            getMetaAccess().lookupJavaType(clazz).registerUnsafeFieldsRecomputed();
        }

        public StandaloneHost getHostVM() {
            return (StandaloneHost) bb.getHostVM();
        }

        @Override
        public void registerReachabilityHandler(Consumer callback, Object... elements) {
        }

        @Override
        public void registerMethodOverrideReachabilityHandler(BiConsumer callback, Executable baseMethod) {
        }

        @Override
        public void registerSubtypeReachabilityHandler(BiConsumer> callback, Class baseClass) {
        }

        @Override
        public void registerClassInitializerReachabilityHandler(Consumer callback, Class clazz) {
        }

        @Override
        public void registerFieldValueTransformer(Field field, FieldValueTransformer transformer) {
        }
    }

    public static class DuringAnalysisAccessImpl extends BeforeAnalysisAccessImpl implements Feature.DuringAnalysisAccess {

        private boolean requireAnalysisIteration;

        public DuringAnalysisAccessImpl(StandaloneAnalysisFeatureManager featureManager, ClassLoader imageClassLoader, BigBang bb, DebugContext debugContext) {
            super(featureManager, imageClassLoader, bb, debugContext);
        }

        @Override
        public void requireAnalysisIteration() {
            requireAnalysisIteration = true;
        }

        public boolean getAndResetRequireAnalysisIteration() {
            boolean result = requireAnalysisIteration;
            requireAnalysisIteration = false;
            return result;
        }
    }

    public static class OnAnalysisExitAccessImpl extends AnalysisAccessBase implements Feature.OnAnalysisExitAccess {

        private final Map, Object> analysisResults = new HashMap<>();

        public OnAnalysisExitAccessImpl(StandaloneAnalysisFeatureManager featureManager, ClassLoader imageClassLoader, BigBang bb, DebugContext debugContext) {
            super(featureManager, imageClassLoader, bb, debugContext);
        }

        public void setAnalysisResult(Class feature, Object result) {
            analysisResults.put(feature, result);
        }

        public Object getResult(Class feature) {
            return analysisResults.get(feature);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy