Skip to content

Commit

Permalink
[GR-19721] Analysis refactoring.
Browse files Browse the repository at this point in the history
PullRequest: graal/5704
  • Loading branch information
cstancu committed Mar 16, 2020
2 parents 689dc19 + e9e44b7 commit cacb42e
Show file tree
Hide file tree
Showing 20 changed files with 306 additions and 194 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,13 @@
import com.oracle.graal.pointsto.util.CompletionExecutor.DebugContextRunnable;
import com.oracle.graal.pointsto.util.Timer;
import com.oracle.graal.pointsto.util.Timer.StopTimer;
import com.oracle.svm.util.ImageGeneratorThreadMarker;

import jdk.vm.ci.common.JVMCIError;
import jdk.vm.ci.meta.ConstantReflectionProvider;
import jdk.vm.ci.meta.JavaConstant;
import jdk.vm.ci.meta.JavaKind;
import com.oracle.svm.util.ImageGeneratorThreadMarker;
import jdk.vm.ci.meta.JavaType;

public abstract class BigBang {

Expand Down Expand Up @@ -300,6 +301,10 @@ public UnsupportedFeatures getUnsupportedFeatures() {
return unsupportedFeatures;
}

public AnalysisType lookup(JavaType type) {
return universe.lookup(type);
}

public AnalysisType getObjectType() {
return metaAccess.lookupJavaType(Object.class);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. 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.flow;

import org.graalvm.compiler.nodes.java.AccessFieldNode;

import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.typestate.TypeState;

/** The base class for a field store or load operation type flow. */
public abstract class AccessFieldTypeFlow<T extends AccessFieldNode> extends TypeFlow<T> {

/** The field that this flow stores into or loads from. */
protected final AnalysisField field;

protected AccessFieldTypeFlow(T node) {
/* The declared type of a field access node is the field declared type. */
super(node, ((AnalysisField) node.field()).getType());
this.field = (AnalysisField) node.field();
}

protected AccessFieldTypeFlow(AccessFieldTypeFlow<T> original, MethodFlowsGraph methodFlows) {
super(original, methodFlows);
this.field = original.field;
}

public AnalysisField field() {
return field;
}

@Override
public final boolean addState(BigBang bb, TypeState add) {
/* Only a clone should be updated */
assert this.isClone();
return super.addState(bb, add);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@
*/
public class AllSynchronizedTypeFlow extends TypeFlow<Object> {

public AllSynchronizedTypeFlow() {
super();
}

@Override
public String toString() {
return "AllSynchronizedFlow";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ public class CloneTypeFlow extends TypeFlow<ValueNode> {
/** The allocation context for the generated clone object. Null if this is not a clone. */
protected final AnalysisContext allocationContext;

public CloneTypeFlow(ValueNode node, BytecodeLocation cloneLabel, TypeFlow<?> input) {
super(node, null);
public CloneTypeFlow(ValueNode node, AnalysisType inputType, BytecodeLocation cloneLabel, TypeFlow<?> input) {
super(node, inputType);
this.cloneSite = cloneLabel;
this.allocationContext = null;
this.input = input;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import com.oracle.graal.pointsto.api.PointstoOptions;
import com.oracle.graal.pointsto.flow.context.AnalysisContext;
import com.oracle.graal.pointsto.flow.context.BytecodeLocation;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.graal.pointsto.typestate.TypeState;

public final class DynamicNewInstanceTypeFlow extends TypeFlow<ValueNode> {
Expand All @@ -44,8 +45,8 @@ public final class DynamicNewInstanceTypeFlow extends TypeFlow<ValueNode> {
*/
protected final AnalysisContext allocationContext;

public DynamicNewInstanceTypeFlow(TypeFlow<?> newTypeFlow, ValueNode node, BytecodeLocation allocationLabel) {
super(node, null);
public DynamicNewInstanceTypeFlow(TypeFlow<?> newTypeFlow, AnalysisType type, ValueNode node, BytecodeLocation allocationLabel) {
super(node, type);
this.allocationSite = allocationLabel;
this.allocationContext = null;
this.newTypeFlow = newTypeFlow;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,37 +25,41 @@
package com.oracle.graal.pointsto.flow;

import org.graalvm.compiler.nodes.ValueNode;

import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.meta.AnalysisMethod;
import com.oracle.graal.pointsto.meta.AnalysisType;
import com.oracle.graal.pointsto.typestate.TypeState;

/**
* The points-to analysis model of an {@code InstanceOfNode}, which represents an instanceof test.
*/
public class FilterTypeFlow extends TypeFlow<ValueNode> {

private final AnalysisType type;
/**
* If the filter is exact we only compare with the {@link #type}, not including its instantiated
* sub-types, otherwise we compare with the entire type hierarchy rooted at {@link #type}.
* If the filter is exact we only compare with the {@link #declaredType}, not including its
* instantiated sub-types, otherwise we compare with the entire type hierarchy rooted at
* {@link #declaredType}.
*/
private final boolean isExact;
/** True if the filter allows types assignable from the test type, false otherwise. */
private final boolean isAssignable;
/** True if the filter allows null, false otherwise. */
private final boolean includeNull;

public FilterTypeFlow(ValueNode node, AnalysisType type, boolean isAssignable, boolean includeNull) {
this(node, type, false, isAssignable, includeNull);
public FilterTypeFlow(ValueNode node, AnalysisType filterType, boolean isAssignable, boolean includeNull) {
this(node, filterType, false, isAssignable, includeNull);
}

public FilterTypeFlow(ValueNode node, AnalysisType type, boolean isExact, boolean isAssignable, boolean includeNull) {
super(node, null);
this.type = type;
public FilterTypeFlow(ValueNode node, AnalysisType filterType, boolean isExact, boolean isAssignable, boolean includeNull) {
super(node, filterType);
this.isExact = isExact;
this.isAssignable = isAssignable;
this.includeNull = includeNull;
}

public FilterTypeFlow(MethodFlowsGraph methodFlows, FilterTypeFlow original) {
super(original, methodFlows);
this.type = original.type;
this.isExact = original.isExact;
this.isAssignable = original.isAssignable;
this.includeNull = original.includeNull;
Expand All @@ -82,9 +86,9 @@ public TypeState filter(BigBang bb, TypeState update) {
* its entire hierarchy.
*/
if (isAssignable) {
result = TypeState.forIntersection(bb, update, TypeState.forExactType(bb, type, includeNull));
result = TypeState.forIntersection(bb, update, TypeState.forExactType(bb, declaredType, includeNull));
} else {
result = TypeState.forSubtraction(bb, update, TypeState.forExactType(bb, type, !includeNull));
result = TypeState.forSubtraction(bb, update, TypeState.forExactType(bb, declaredType, !includeNull));
}
} else {
/*
Expand All @@ -93,9 +97,9 @@ public TypeState filter(BigBang bb, TypeState update) {
* instantiated sub-types).
*/
if (isAssignable) {
result = TypeState.forIntersection(bb, update, type.getTypeFlow(bb, includeNull).getState());
result = TypeState.forIntersection(bb, update, declaredType.getTypeFlow(bb, includeNull).getState());
} else {
result = TypeState.forSubtraction(bb, update, type.getTypeFlow(bb, !includeNull).getState());
result = TypeState.forSubtraction(bb, update, declaredType.getTypeFlow(bb, !includeNull).getState());
}
}

Expand All @@ -108,10 +112,6 @@ public boolean addState(BigBang bb, TypeState add) {
return super.addState(bb, add);
}

public AnalysisType getType() {
return type;
}

public boolean isExact() {
return isExact;
}
Expand All @@ -126,6 +126,6 @@ public boolean includeNull() {

@Override
public String toString() {
return "FilterTypeFlow<" + type + ", isAssignable: " + isAssignable + ", includeNull: " + includeNull + ">";
return "FilterTypeFlow<" + declaredType + ", isAssignable: " + isAssignable + ", includeNull: " + includeNull + ">";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@
import com.oracle.graal.pointsto.meta.AnalysisType;

/**
* Reflects all types flow into an instanceof node.
*
* Reflects all types flow into an instanceof node, i.e., the state of this flow contains all types
* that flow into it, with no filtering. There is a separate {@link FilterTypeFlow} that implements
* the filtering operation and propagates the reduced state to uses. An InstanceOfTypeFlow is a sink
* flow, i.e., it doesn't have any uses.
*/
public class InstanceOfTypeFlow extends TypeFlow<ValueNode> {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,29 +28,19 @@

import com.oracle.graal.pointsto.BigBang;
import com.oracle.graal.pointsto.flow.context.object.AnalysisObject;
import com.oracle.graal.pointsto.meta.AnalysisField;
import com.oracle.graal.pointsto.typestate.TypeState;

/**
* Implements a field load operation type flow.
*/
public abstract class LoadFieldTypeFlow extends TypeFlow<LoadFieldNode> {
public abstract class LoadFieldTypeFlow extends AccessFieldTypeFlow<LoadFieldNode> {

/** The field that this flow loads from. */
protected final AnalysisField field;

public LoadFieldTypeFlow(LoadFieldNode node) {
super(node, null);
this.field = (AnalysisField) node.field();
protected LoadFieldTypeFlow(LoadFieldNode node) {
super(node);
}

public LoadFieldTypeFlow(MethodFlowsGraph methodFlows, LoadFieldTypeFlow original) {
protected LoadFieldTypeFlow(MethodFlowsGraph methodFlows, LoadFieldTypeFlow original) {
super(original, methodFlows);
this.field = original.field;
}

public AnalysisField field() {
return field;
}

public static class LoadStaticFieldTypeFlow extends LoadFieldTypeFlow {
Expand Down Expand Up @@ -83,12 +73,6 @@ public void initClone(BigBang bb) {
fieldFlow.addUse(bb, this);
}

@Override
public boolean addState(BigBang bb, TypeState add) {
assert this.isClone();
return super.addState(bb, add);
}

@Override
public String toString() {
return "LoadStaticFieldTypeFlow<" + getState() + ">";
Expand All @@ -102,8 +86,11 @@ public String toString() {
*/
public static class LoadInstanceFieldTypeFlow extends LoadFieldTypeFlow {

/** The flow of the receiver object. */
private final TypeFlow<?> objectFlow;
/**
* The flow of the receiver object. The load flow is registered as an observer of the
* receiver object.
*/
private TypeFlow<?> objectFlow;

LoadInstanceFieldTypeFlow(LoadFieldNode node, TypeFlow<?> objectFlow) {
super(node);
Expand All @@ -126,18 +113,6 @@ public TypeFlow<?> receiver() {
return objectFlow;
}

/** Return the state of the receiver object. */
public TypeState getObjectState() {
return objectFlow.getState();
}

@Override
public boolean addState(BigBang bb, TypeState add) {
/* Only a clone should be updated */
assert this.isClone();
return super.addState(bb, add);
}

@Override
public void onObservedUpdate(BigBang bb) {
/* Only a clone should be updated */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ public void cloneOriginalFlows(BigBang bb) {

@SuppressWarnings("unchecked")
public <T extends TypeFlow<?>> T lookupCloneOf(BigBang bb, T original) {
assert original != null && !original.isClone();
assert original != null : "Looking for the clone of a 'null' flow in " + this;
assert !original.isClone() : "Looking for the clone of the already cloned flow " + original + " in " + this;
assert !(original instanceof FieldTypeFlow) : "Trying to clone a field type flow";
assert !(original instanceof ArrayElementsTypeFlow) : "Trying to clone an mixed elements type flow";

Expand Down Expand Up @@ -329,11 +330,11 @@ public static boolean crossMethodUse(TypeFlow<?> flow, TypeFlow<?> use) {
}

public void linearizeGraph() {
linearizedGraph = getLinearizeGraph();
linearizedGraph = doLinearizeGraph();
isLinearized = true;
}

public TypeFlow<?>[] getLinearizeGraph() {
private TypeFlow<?>[] doLinearizeGraph() {

Deque<TypeFlow<?>> worklist = new ArrayDeque<>();

Expand Down
Loading

0 comments on commit cacb42e

Please sign in to comment.