use of jdk.vm.ci.meta.JavaTypeProfile in project graal by oracle.
the class BytecodeParser method genCheckCast.
private void genCheckCast() {
int cpi = getStream().readCPI();
JavaType type = lookupType(cpi, CHECKCAST);
ValueNode object = frameState.pop(JavaKind.Object);
if (!(type instanceof ResolvedJavaType)) {
handleUnresolvedCheckCast(type, object);
return;
}
TypeReference checkedType = TypeReference.createTrusted(graph.getAssumptions(), (ResolvedJavaType) type);
JavaTypeProfile profile = getProfileForTypeCheck(checkedType);
for (NodePlugin plugin : graphBuilderConfig.getPlugins().getNodePlugins()) {
if (plugin.handleCheckCast(this, object, checkedType.getType(), profile)) {
return;
}
}
ValueNode castNode = null;
if (profile != null) {
if (profile.getNullSeen().isFalse()) {
object = nullCheckedValue(object);
ResolvedJavaType singleType = profile.asSingleType();
if (singleType != null && checkedType.getType().isAssignableFrom(singleType)) {
LogicNode typeCheck = append(createInstanceOf(TypeReference.createExactTrusted(singleType), object, profile));
if (typeCheck.isTautology()) {
castNode = object;
} else {
FixedGuardNode fixedGuard = append(new FixedGuardNode(typeCheck, DeoptimizationReason.TypeCheckedInliningViolated, DeoptimizationAction.InvalidateReprofile, false));
castNode = append(PiNode.create(object, StampFactory.objectNonNull(TypeReference.createExactTrusted(singleType)), fixedGuard));
}
}
}
}
boolean nonNull = ((ObjectStamp) object.stamp(NodeView.DEFAULT)).nonNull();
if (castNode == null) {
LogicNode condition = genUnique(createInstanceOfAllowNull(checkedType, object, null));
if (condition.isTautology()) {
castNode = object;
} else {
FixedGuardNode fixedGuard = append(new FixedGuardNode(condition, DeoptimizationReason.ClassCastException, DeoptimizationAction.InvalidateReprofile, false));
castNode = append(PiNode.create(object, StampFactory.object(checkedType, nonNull), fixedGuard));
}
}
frameState.push(JavaKind.Object, castNode);
}
use of jdk.vm.ci.meta.JavaTypeProfile in project graal by oracle.
the class BytecodeParser method appendInvoke.
protected Invoke appendInvoke(InvokeKind initialInvokeKind, ResolvedJavaMethod initialTargetMethod, ValueNode[] args) {
ResolvedJavaMethod targetMethod = initialTargetMethod;
InvokeKind invokeKind = initialInvokeKind;
if (initialInvokeKind.isIndirect()) {
ResolvedJavaType contextType = this.frameState.getMethod().getDeclaringClass();
ResolvedJavaMethod specialCallTarget = MethodCallTargetNode.findSpecialCallTarget(initialInvokeKind, args[0], initialTargetMethod, contextType);
if (specialCallTarget != null) {
invokeKind = InvokeKind.Special;
targetMethod = specialCallTarget;
}
}
JavaKind resultType = targetMethod.getSignature().getReturnKind();
if (!parsingIntrinsic() && DeoptALot.getValue(options)) {
append(new DeoptimizeNode(DeoptimizationAction.None, RuntimeConstraint));
frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, graph));
return null;
}
JavaType returnType = targetMethod.getSignature().getReturnType(method.getDeclaringClass());
if (graphBuilderConfig.eagerResolving() || parsingIntrinsic()) {
returnType = returnType.resolve(targetMethod.getDeclaringClass());
}
if (invokeKind.hasReceiver()) {
args[0] = emitExplicitExceptions(args[0]);
}
if (initialInvokeKind == InvokeKind.Special && !targetMethod.isConstructor()) {
emitCheckForInvokeSuperSpecial(args);
}
InlineInfo inlineInfo = null;
try {
currentInvoke = new CurrentInvoke(args, invokeKind, returnType);
if (tryNodePluginForInvocation(args, targetMethod)) {
if (TraceParserPlugins.getValue(options)) {
traceWithContext("used node plugin for %s", targetMethod.format("%h.%n(%p)"));
}
return null;
}
if (invokeKind.hasReceiver() && args[0].isNullConstant()) {
append(new DeoptimizeNode(InvalidateRecompile, NullCheckException));
return null;
}
if (!invokeKind.isIndirect() || (UseGuardedIntrinsics.getValue(options) && !GeneratePIC.getValue(options))) {
if (tryInvocationPlugin(invokeKind, args, targetMethod, resultType, returnType)) {
if (TraceParserPlugins.getValue(options)) {
traceWithContext("used invocation plugin for %s", targetMethod.format("%h.%n(%p)"));
}
return null;
}
}
if (invokeKind.isDirect()) {
inlineInfo = tryInline(args, targetMethod);
if (inlineInfo == SUCCESSFULLY_INLINED) {
return null;
}
}
} finally {
currentInvoke = null;
}
int invokeBci = bci();
JavaTypeProfile profile = getProfileForInvoke(invokeKind);
ExceptionEdgeAction edgeAction = getActionForInvokeExceptionEdge(inlineInfo);
boolean partialIntrinsicExit = false;
if (intrinsicContext != null && intrinsicContext.isCallToOriginal(targetMethod)) {
partialIntrinsicExit = true;
ResolvedJavaMethod originalMethod = intrinsicContext.getOriginalMethod();
BytecodeParser intrinsicCallSiteParser = getNonIntrinsicAncestor();
if (intrinsicCallSiteParser != null) {
// When exiting a partial intrinsic, the invoke to the original
// must use the same context as the call to the intrinsic.
invokeBci = intrinsicCallSiteParser.bci();
profile = intrinsicCallSiteParser.getProfileForInvoke(invokeKind);
edgeAction = intrinsicCallSiteParser.getActionForInvokeExceptionEdge(inlineInfo);
} else {
// so the bci must be set to unknown, so that the inliner patches it later.
assert intrinsicContext.isPostParseInlined();
invokeBci = BytecodeFrame.UNKNOWN_BCI;
profile = null;
edgeAction = graph.method().getAnnotation(Snippet.class) == null ? ExceptionEdgeAction.INCLUDE_AND_HANDLE : ExceptionEdgeAction.OMIT;
}
if (originalMethod.isStatic()) {
invokeKind = InvokeKind.Static;
} else {
// The original call to the intrinsic must have been devirtualized
// otherwise we wouldn't be here.
invokeKind = InvokeKind.Special;
}
Signature sig = originalMethod.getSignature();
returnType = sig.getReturnType(method.getDeclaringClass());
resultType = sig.getReturnKind();
assert intrinsicContext.allowPartialIntrinsicArgumentMismatch() || checkPartialIntrinsicExit(intrinsicCallSiteParser == null ? null : intrinsicCallSiteParser.currentInvoke.args, args);
targetMethod = originalMethod;
}
Invoke invoke = createNonInlinedInvoke(edgeAction, invokeBci, args, targetMethod, invokeKind, resultType, returnType, profile);
if (partialIntrinsicExit) {
// This invoke must never be later inlined as it might select the intrinsic graph.
// Until there is a mechanism to guarantee that any late inlining will not select
// the intrinsic graph, prevent this invoke from being inlined.
invoke.setUseForInlining(false);
}
return invoke;
}
use of jdk.vm.ci.meta.JavaTypeProfile 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 jdk.vm.ci.meta.JavaTypeProfile in project graal by oracle.
the class StaticAnalysisResultsBuilder method makeTypeProfile.
private JavaTypeProfile makeTypeProfile(TypeState typeState) {
if (typeState == null || typeState.isUnknown() || PointstoOptions.AnalysisSizeCutoff.getValue(bb.getOptions()) != -1 && typeState.typesCount() > PointstoOptions.AnalysisSizeCutoff.getValue(bb.getOptions())) {
return null;
}
if (typeState.isEmpty()) {
synchronized (types0) {
return cachedTypeProfile(types0, 0, typeState);
}
} else if (typeState.isNull()) {
synchronized (types0) {
return cachedTypeProfile(types0, 1, typeState);
}
} else if (typeState.exactType() != null) {
if (typeState.canBeNull()) {
synchronized (types1Null) {
return cachedTypeProfile(types1Null, typeState.exactType().getId(), typeState);
}
} else {
synchronized (types1NonNull) {
return cachedTypeProfile(types1NonNull, typeState.exactType().getId(), typeState);
}
}
}
synchronized (types) {
JavaTypeProfile created = createTypeProfile(typeState);
types.putIfAbsent(created, created);
return created;
}
}
use of jdk.vm.ci.meta.JavaTypeProfile in project graal by oracle.
the class ProfilingInfoTest method testTypeProfile.
private void testTypeProfile(String testSnippet, int bci) {
ResolvedJavaType stringType = getMetaAccess().lookupJavaType(String.class);
ResolvedJavaType stringBuilderType = getMetaAccess().lookupJavaType(StringBuilder.class);
ProfilingInfo info = profile(testSnippet, "ABC");
JavaTypeProfile typeProfile = info.getTypeProfile(bci);
Assert.assertEquals(0.0, typeProfile.getNotRecordedProbability(), DELTA);
Assert.assertEquals(1, typeProfile.getTypes().length);
Assert.assertEquals(stringType, typeProfile.getTypes()[0].getType());
Assert.assertEquals(1.0, typeProfile.getTypes()[0].getProbability(), DELTA);
continueProfiling(testSnippet, new StringBuilder());
typeProfile = info.getTypeProfile(bci);
Assert.assertEquals(0.0, typeProfile.getNotRecordedProbability(), DELTA);
Assert.assertEquals(2, typeProfile.getTypes().length);
Assert.assertEquals(stringType, typeProfile.getTypes()[0].getType());
Assert.assertEquals(stringBuilderType, typeProfile.getTypes()[1].getType());
Assert.assertEquals(0.5, typeProfile.getTypes()[0].getProbability(), DELTA);
Assert.assertEquals(0.5, typeProfile.getTypes()[1].getProbability(), DELTA);
resetProfile(testSnippet);
typeProfile = info.getTypeProfile(bci);
Assert.assertNull(typeProfile);
}
Aggregations