use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.
the class TypeFlow method update.
public void update(BigBang bb) {
TypeState curState = getState();
for (TypeFlow<?> use : getUses()) {
use.addState(bb, curState);
}
notifyObservers(bb);
}
use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.
the class UniverseBuilder method collectHashCodeFieldInfo.
@SuppressWarnings("try")
private void collectHashCodeFieldInfo(BigBang bb) {
AnalysisMethod method;
try {
method = aMetaAccess.lookupJavaMethod(System.class.getMethod("identityHashCode", Object.class));
} catch (NoSuchMethodException | SecurityException e) {
throw shouldNotReachHere();
}
if (method == null) {
return;
}
DebugContext debug = bb.getDebug();
try (Indent ignore = debug.logAndIndent("check types for which identityHashCode is invoked")) {
// Check which types may be a parameter of System.identityHashCode (which is invoked by
// Object.hashCode).
TypeState thisParamState = method.getTypeFlow().getParameterTypeState(bb, 0);
assert thisParamState != null;
Iterable<AnalysisType> typesNeedHashCode = thisParamState.types();
if (typesNeedHashCode == null || thisParamState.isUnknown()) {
// This is the case if the identityHashCode parameter type is unknown. So all
// classes get the hashCode field.
// But this is only a fail-safe, because it cannot happen in the current
// implementation of the analysis pass.
debug.log("all types need a hashCode field");
for (HostedType hType : hUniverse.getTypes()) {
if (hType.isInstanceClass()) {
((HostedInstanceClass) hType).setNeedHashCodeField();
}
}
hUniverse.getObjectClass().setNeedHashCodeField();
} else {
for (AnalysisType type : typesNeedHashCode) {
debug.log("type %s is argument to identityHashCode", type);
/*
* Array types get a hash-code field by default. So we only have to deal with
* instance types here.
*/
if (type.isInstanceClass()) {
HostedInstanceClass hType = (HostedInstanceClass) hUniverse.lookup(type);
hType.setNeedHashCodeField();
}
}
}
}
}
use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.
the class UniverseBuilder method collectMonitorFieldInfo.
// @formatter:off
// /**
// * New version of the method that uses the static analysis results collected by the static
// * analysis results builder instead of accessing the type states directly.
// */
// @SuppressWarnings("try")
// private void collectHashCodeFieldInfo() {
//
// AnalysisMethod method = null;
// try {
// method = aMetaAccess.lookupJavaMethod(System.class.getMethod("identityHashCode", Object.class));
// } catch (NoSuchMethodException | SecurityException e) {
// throw shouldNotReachHere();
// }
// if (method == null) {
// return;
// }
//
// try (Indent indent = Debug.logAndIndent("check types for which identityHashCode is invoked")) {
//
// // Check which types may be a parameter of System.identityHashCode (which is invoked by
// // Object.hashCode).
//
// HostedMethod hMethod = hUniverse.methods.get(method);
// JavaTypeProfile paramProfile = hMethod.getProfilingInfo().getParameterTypeProfile(0);
//
// if (paramProfile == null) {
//
// // This is the case if the identityHashCode parameter type is unknown. So all
// // classes get the hashCode field.
// // But this is only a fail-safe, because it cannot happen in the current
// // implementation of the analysis pass.
//
// Debug.log("all types need a hashCode field");
// for (HostedType hType : hUniverse.getTypes()) {
// if (hType.isInstanceClass()) {
// ((HostedInstanceClass) hType).setNeedHashCodeField();
// }
// }
// hUniverse.getObjectClass().setNeedHashCodeField();
// } else {
//
// // Mark all paramter types of System.identityHashCode to have a hash-code field.
//
// for (ProfiledType type : paramProfile.getTypes()) {
// Debug.log("type %s is argument to identityHashCode", type);
//
// /*
// * Array types get a hash-code field by default. So we only have to deal with
// * instance types here.
// */
// if (type.getType().isInstanceClass()) {
// HostedInstanceClass hType = (HostedInstanceClass) hUniverse.lookup(type.getType());
// hType.setNeedHashCodeField();
// }
// }
// }
// }
// }
// @formatter:on
private void collectMonitorFieldInfo(BigBang bb) {
if (!SubstrateOptions.MultiThreaded.getValue()) {
/* No locking information needed in single-threaded mode. */
return;
}
TypeState allSynchronizedTypeState = bb.getAllSynchronizedTypeState();
for (AnalysisType aType : allSynchronizedTypeState.types()) {
if (canHaveMonitorFields(aType)) {
final HostedInstanceClass hostedInstanceClass = (HostedInstanceClass) hUniverse.lookup(aType);
hostedInstanceClass.setNeedMonitorField();
}
}
}
use of com.oracle.graal.pointsto.typestate.TypeState in project graal by oracle.
the class StaticAnalysisResultsBuilder method makeResults.
public StaticAnalysisResults makeResults(AnalysisMethod method) {
MethodTypeFlow methodFlow = method.getTypeFlow();
MethodFlowsGraph originalFlows = methodFlow.getOriginalMethodFlows();
ArrayList<JavaTypeProfile> paramProfiles = new ArrayList<>(originalFlows.getParameters().length);
for (int i = 0; i < originalFlows.getParameters().length; i++) {
JavaTypeProfile paramProfile = makeTypeProfile(methodFlow.foldTypeFlow(bb, originalFlows.getParameter(i)));
if (paramProfile != null) {
ensureSize(paramProfiles, i);
paramProfiles.set(i, paramProfile);
}
}
JavaTypeProfile[] parameterTypeProfiles = null;
if (paramProfiles.size() > 0) {
parameterTypeProfiles = paramProfiles.toArray(new JavaTypeProfile[paramProfiles.size()]);
}
JavaTypeProfile resultTypeProfile = makeTypeProfile(methodFlow.foldTypeFlow(bb, originalFlows.getResult()));
ArrayList<BytecodeEntry> entries = new ArrayList<>(method.getCodeSize());
for (InstanceOfTypeFlow originalInstanceOf : originalFlows.getInstaceOfFlows()) {
if (BytecodeLocation.hasValidBci(originalInstanceOf.getLocation())) {
int bci = originalInstanceOf.getLocation().getBci();
/* Fold the instanceof flows. */
TypeState instanceOfTypeState = methodFlow.foldTypeFlow(bb, originalInstanceOf);
originalInstanceOf.setState(bb, instanceOfTypeState);
JavaTypeProfile typeProfile = makeTypeProfile(instanceOfTypeState);
if (typeProfile != null) {
ensureSize(entries, bci);
assert entries.get(bci) == null : "In " + method.format("%h.%n(%p)") + " a profile with bci=" + bci + " already exists: " + entries.get(bci);
entries.set(bci, createBytecodeEntry(method, bci, typeProfile, null, null));
}
}
}
for (InvokeTypeFlow originalInvoke : originalFlows.getInvokes()) {
if (BytecodeLocation.hasValidBci(originalInvoke.getLocation())) {
int bci = originalInvoke.getLocation().getBci();
TypeState invokeTypeState = TypeState.forEmpty();
if (originalInvoke.getTargetMethod().hasReceiver()) {
invokeTypeState = methodFlow.foldTypeFlow(bb, originalInvoke.getReceiver());
originalInvoke.setState(bb, invokeTypeState);
}
TypeFlow<?> originalReturn = originalInvoke.getActualReturn();
TypeState returnTypeState = null;
if (originalReturn != null) {
returnTypeState = methodFlow.foldTypeFlow(bb, originalReturn);
originalReturn.setState(bb, returnTypeState);
}
JavaTypeProfile typeProfile = makeTypeProfile(invokeTypeState);
JavaMethodProfile methodProfile = makeMethodProfile(originalInvoke.getCallees());
JavaTypeProfile invokeResultTypeProfile = originalReturn == null ? null : makeTypeProfile(returnTypeState);
if (typeProfile != null || methodProfile != null || invokeResultTypeProfile != null) {
ensureSize(entries, bci);
assert entries.get(bci) == null : "In " + method.format("%h.%n(%p)") + " a profile with bci=" + bci + " already exists: " + entries.get(bci);
entries.set(bci, createBytecodeEntry(method, bci, typeProfile, methodProfile, invokeResultTypeProfile));
}
}
}
if (PointstoOptions.PrintSynchronizedAnalysis.getValue(bb.getOptions())) {
originalFlows.getMonitorEntries().stream().filter(m -> m.getState().typesCount() > 20).sorted(Comparator.comparingInt(m2 -> m2.getState().typesCount())).forEach(monitorEnter -> {
TypeState monitorEntryState = monitorEnter.getState();
String typesString = monitorEntryState.closeToAllInstantiated(bb) ? "close to all instantiated" : StreamSupport.stream(monitorEntryState.types().spliterator(), false).map(AnalysisType::getName).collect(Collectors.joining(", "));
StringBuilder strb = new StringBuilder();
strb.append("Location: ");
String methodName = method.format("%h.%n(%p)");
int bci = monitorEnter.getLocation().getBci();
if (bci != BytecodeLocation.UNKNOWN_BCI) {
StackTraceElement traceElement = method.asStackTraceElement(bci);
String sourceLocation = traceElement.getFileName() + ":" + traceElement.getLineNumber();
strb.append("@(").append(methodName).append(":").append(bci).append(")");
strb.append("=(").append(sourceLocation).append(")");
} else {
strb.append("@(").append(methodName).append(")");
}
strb.append("\n");
strb.append("Synchronized types #: ").append(monitorEntryState.typesCount()).append("\n");
strb.append("Types: ").append(typesString).append("\n");
System.out.println(strb);
});
}
BytecodeEntry first = null;
for (int i = entries.size() - 1; i >= 0; i--) {
BytecodeEntry cur = entries.get(i);
if (cur != null) {
cur.next = first;
first = cur;
}
}
return createStaticAnalysisResults(method, parameterTypeProfiles, resultTypeProfile, first);
}
use of com.oracle.graal.pointsto.typestate.TypeState 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);
}
}
Aggregations