/** * Checks if this invoke can be statically bound. * </p> * First we check if the call target can be trivially statically bound (i.e., it is final or * private or static, but not abstract, or the declaring class is final). * </p> * If it cannot be trivially statically bound then we look at the number of callees. Iff the * invoke links to one and only one callee then it can be statically bound. In the corner case * where the invoke doesn't link to any callee this method concludes that it cannot be * statically bound. If the invoke doesn't link to any callee then it is unreachable, i.e., it * has no implementation, and should be removed by the analysis client. */ public boolean canBeStaticallyBound() { /* * Check whether this method can be trivially statically bound, i.e., without the help of * the analysis, but asking the host VM. That means it is final or private or static, but * not abstract, or the declaring class is final. */ boolean triviallyStaticallyBound = invoke.callTarget().targetMethod().canBeStaticallyBound(); if (triviallyStaticallyBound) { /* * The check bellow is "size <= 1" and not "size == 1" because a method can be reported * as trivially statically bound by the host VM but unreachable in the analysis. */ assert getCallees().size() <= 1 : "Statically bound result mismatch between analysis and host VM."; return true; } return getCallees().size() == 1; }
private void processInvoke(InvokeTypeFlow invokeFlow, MethodNode callerNode, Deque<MethodNode> workList) { InvokeNode invokeNode = new InvokeNode(invokeFlow.getTargetMethod(), invokeFlow.invoke().getInvokeKind(), sourceReference(invokeFlow)); callerNode.addInvoke(invokeNode); invokeFlow.getCallees().stream().sorted(methodComparator).forEach(callee -> { if (methodToNode.containsKey(callee)) { MethodNodeReference calleeNode = new MethodNodeReference(methodToNode.get(callee)); invokeNode.addCallee(calleeNode); } else { MethodNode calleeNode = new MethodNode(callee); invokeNode.addCallee(calleeNode); methodToNode.put(callee, calleeNode); workList.add(calleeNode); } }); }
for (AnalysisMethod callee : invoke.getCallees()) {
JavaMethodProfile methodProfile = makeMethodProfile(originalInvoke.getCallees()); JavaTypeProfile invokeResultTypeProfile = originalReturn == null ? null : makeTypeProfile(returnTypeState);
continue; Collection<AnalysisMethod> allImplementationMethods = invokeFlow.getCallees();