use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class UnknownTypeState method doSubtraction.
private static TypeState doSubtraction(BigBang bb, MultiTypeState s1, SingleTypeState s2) {
boolean resultCanBeNull = s1.canBeNull() && !s2.canBeNull();
if (s1.containsType(s2.exactType())) {
/* See comment above for the limitation explanation. */
assert s2.objects.length == 1 && s2.objects[0].isContextInsensitiveObject() : "Current implementation limitation.";
/* Find the range of objects of s2.exactType() in s1. */
Range typeRange = s1.findTypeRange(s2.exactType());
int newLength = s1.objects.length - (typeRange.right - typeRange.left);
AnalysisObject[] resultObjects = new AnalysisObject[newLength];
/* Copy all the objects in s1 but the ones inside the range to the result list. */
System.arraycopy(s1.objects, 0, resultObjects, 0, typeRange.left);
System.arraycopy(s1.objects, typeRange.right, resultObjects, typeRange.left, s1.objects.length - typeRange.right);
if (resultObjects.length == 1) {
return new SingleTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, resultObjects[0]), resultObjects[0]);
} else if (TypeStateUtils.holdsSingleTypeState(resultObjects)) {
/* Multiple objects of the same type. */
return new SingleTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, resultObjects), resultObjects);
} else {
BitSet resultTypesBitSet = TypeStateUtils.clear(s1.typesBitSet, s2.exactType().getId());
return new MultiTypeState(bb, resultCanBeNull, bb.analysisPolicy().makePoperties(bb, resultObjects), resultTypesBitSet, resultObjects);
}
} else {
return s1.forCanBeNull(bb, resultCanBeNull);
}
}
use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class UnknownTypeState method forContextInsensitiveTypeState.
/**
* Simplifies a type state by replacing all context sensitive objects with context insensitive
* objects.
*/
public static TypeState forContextInsensitiveTypeState(BigBang bb, TypeState state) {
if (!PointstoOptions.AllocationSiteSensitiveHeap.getValue(bb.getOptions()) || state.isEmpty() || state.isNull() || state.isUnknown()) {
/* The type state is already context insensitive. */
return state;
} else {
if (state.isSingleTypeState()) {
AnalysisType type = state.exactType();
AnalysisObject analysisObject = type.getContextInsensitiveAnalysisObject();
return new SingleTypeState(bb, state.canBeNull(), bb.analysisPolicy().makePoperties(bb, analysisObject), analysisObject);
} else {
MultiTypeState multiState = (MultiTypeState) state;
AnalysisObject[] objectsArray = new AnalysisObject[multiState.typesCount()];
int i = 0;
for (AnalysisType type : multiState.types()) {
objectsArray[i++] = type.getContextInsensitiveAnalysisObject();
}
/*
* For types use the already created bit set. Since the original type state is
* immutable its types bit set cannot change.
*/
BitSet typesBitSet = multiState.typesBitSet;
int properties = bb.analysisPolicy().makePoperties(bb, objectsArray);
return new MultiTypeState(bb, multiState.canBeNull(), properties, typesBitSet, objectsArray);
}
}
}
use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class SpecialInvokeTypeFlow method onObservedUpdate.
@Override
public void onObservedUpdate(BigBang bb) {
assert this.isClone();
/*
* Initialize the callee lazily so that if the invoke flow is not reached in this context,
* i.e. for this clone, there is no callee linked.
*/
if (callee == null) {
MethodCallTargetNode target = (MethodCallTargetNode) invoke.callTarget();
callee = ((AnalysisMethod) target.targetMethod()).getTypeFlow();
// set the callee in the original invoke too
((DirectInvokeTypeFlow) originalInvoke).callee = callee;
}
TypeState invokeState = getReceiver().getState();
for (AnalysisObject receiverObject : invokeState.objects()) {
AnalysisContext calleeContext = bb.contextPolicy().calleeContext(bb, receiverObject, callerContext, callee);
MethodFlowsGraph calleeFlows = callee.addContext(bb, calleeContext, this);
if (calleesFlows.putIfAbsent(calleeFlows, Boolean.TRUE) == null) {
linkCallee(bb, false, calleeFlows);
}
updateReceiver(bb, calleeFlows, receiverObject);
}
}
use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class NewInstanceTypeFlow method cloneSourceState.
/**
* Create the type state for a clone.
*/
protected TypeState cloneSourceState(BigBang bb, MethodFlowsGraph methodFlows) {
assert !this.isClone();
AnalysisContext allocatorContext = methodFlows.context();
AnalysisContext allocationContext = bb.contextPolicy().allocationContext(allocatorContext, PointstoOptions.MaxHeapContextDepth.getValue(bb.getOptions()));
if (bb.analysisPolicy().isContextSensitiveAllocation(bb, type, allocationContext)) {
/*
* If the analysis is context sensitive create a new heap object for the new context, or
* return an existing one. The original NewInstanceTypeFlow is the one that stores the
* (Context->HeapObject) mapping.
*/
AnalysisObject newHeapObject = createHeapObject(bb, allocationContext);
return TypeState.forNonNullObject(bb, newHeapObject);
} else {
/*
* In the heap insensitive case instead of more precise heap abstractions (i.e.
* allocation site) we use just the type of the object wrapped into the AbstractObject
* base class. There is no cloning in this case.
*/
return TypeState.forExactType(bb, type, false);
}
}
use of com.oracle.graal.pointsto.flow.context.object.AnalysisObject in project graal by oracle.
the class AnalysisType method getCachedConstantObject.
public AnalysisObject getCachedConstantObject(BigBang bb, JavaConstant constant) {
/*
* Constant caching is only used we certain analysis policies. Ideally we would store the
* cache in the policy, but it is simpler to store the cache for each type.
*/
assert bb.analysisPolicy().needsConstantCache() : "The analysis policy doesn't specify the need for a constants cache.";
assert bb.trackConcreteAnalysisObjects(this);
assert !(constant instanceof PrimitiveConstant) : "The analysis should not model PrimitiveConstant.";
if (uniqueConstant != null) {
// The constants have been merged, return the unique constant
return uniqueConstant;
}
if (constantObjectsCache.size() > PointstoOptions.MaxConstantObjectsPerType.getValue(bb.getOptions())) {
// The number of constant objects has increased above the limit,
// merge the constants in the uniqueConstant and return it
mergeConstantObjects(bb);
return uniqueConstant;
}
// Get the analysis ConstantObject modeling the JavaConstant
AnalysisObject result = constantObjectsCache.get(constant);
if (result == null) {
// Create a ConstantObject to model each JavaConstant
ConstantContextSensitiveObject newValue = new ConstantContextSensitiveObject(bb, this, constant);
ConstantContextSensitiveObject oldValue = constantObjectsCache.putIfAbsent(constant, newValue);
result = oldValue != null ? oldValue : newValue;
if (PointstoOptions.ProfileConstantObjects.getValue(bb.getOptions())) {
ConstantObjectsProfiler.registerConstant(this);
ConstantObjectsProfiler.maybeDumpConstantHistogram();
}
}
return result;
}
Aggregations