+ if totusage > maxusage:
+ maxusage = totusage
+ if callinfo[4] is not None:
+ doesyield = 1
+ totyieldusage = usage + callinfo[4]
+ if totyieldusage > maxyieldusage:
+ maxyieldusage = totyieldusage
+ info[2] = maxusage
+ if doesyield:
+ info[4] = maxyieldusage
+ info[5] = totcalls
+
+# Try to arrange output so that functions that call each other are
+# near each other.
+def orderfuncs(funcaddrs, availfuncs):
+ l = [(availfuncs[funcaddr][5], availfuncs[funcaddr][0], funcaddr)
+ for funcaddr in funcaddrs if funcaddr in availfuncs]
+ l.sort()
+ l.reverse()
+ out = []
+ while l:
+ count, name, funcaddr = l.pop(0)
+ if funcaddr not in availfuncs:
+ continue
+ calladdrs = [calls[1] for calls in availfuncs[funcaddr][6]]
+ del availfuncs[funcaddr]
+ out = out + orderfuncs(calladdrs, availfuncs) + [funcaddr]
+ return out
+
+# Update function info with a found "yield" point.
+def noteYield(info, stackusage):
+ prevyield = info[3]
+ if prevyield is None or prevyield < stackusage:
+ info[3] = stackusage
+
+# Update function info with a found "call" point.
+def noteCall(info, subfuncs, insnaddr, calladdr, stackusage):
+ if (calladdr, stackusage) in subfuncs:
+ # Already noted a nearly identical call - ignore this one.
+ return
+ info[6].append((insnaddr, calladdr, stackusage))
+ subfuncs[(calladdr, stackusage)] = 1