"encoding/json"
"fmt"
"os"
+ "strings"
)
// CallStat summarizes a single call site.
return recv.Type
}
-// interfaceCallRecvType returns the type of the interface used in an interface
-// call.
-func interfaceCallRecvType(call *ir.CallExpr) *types.Type {
+// interfaceCallRecvTypeAndMethod returns the type and the method of the interface
+// used in an interface call.
+func interfaceCallRecvTypeAndMethod(call *ir.CallExpr) (*types.Type, *types.Sym) {
if call.Op() != ir.OCALLINTER {
base.Fatalf("Call isn't OCALLINTER: %+v", call)
}
base.Fatalf("OCALLINTER doesn't contain SelectorExpr: %+v", call)
}
- return sel.X.Type()
+ return sel.X.Type(), sel.Sel
}
// findHotConcreteCallee returns the *ir.Func of the hottest callee of an
callerNode := p.WeightedCG.IRNodes[callerName]
callOffset := pgo.NodeLineOffset(call, caller)
- inter := interfaceCallRecvType(call)
+ inter, method := interfaceCallRecvTypeAndMethod(call)
var hottest *pgo.IREdge
continue
}
+ // If the method name is different it is most likely from a
+ // different call on the same line
+ if !strings.HasSuffix(e.Dst.Name(), "."+method.Name) {
+ if base.Debug.PGODebug >= 2 {
+ fmt.Printf("%v: edge %s:%d -> %s (weight %d): callee is a different method\n", ir.Line(call), callerName, callOffset, e.Dst.Name(), e.Weight)
+ }
+ continue
+ }
+
if base.Debug.PGODebug >= 2 {
fmt.Printf("%v: edge %s:%d -> %s (weight %d): hottest so far\n", ir.Line(call), callerName, callOffset, e.Dst.Name(), e.Weight)
}