| 303 | } |
| 304 | |
| 305 | void Profiler::End() |
| 306 | { |
| 307 | if (_reportDone) |
| 308 | return; |
| 309 | ParseMapFile(); |
| 310 | _reportDone = true; |
| 311 | int i; |
| 312 | int nStats; |
| 313 | LONGLONG maxTime = 0; |
| 314 | for (i = 0; i < STAT_SIZE; i++) |
| 315 | { |
| 316 | FuncStat& stat = _stats[i]; |
| 317 | stat.address = (_start + i) << F_ALIGN_LOG; |
| 318 | if (stat.time.QuadPart != 0) |
| 319 | nStats = i + 1; |
| 320 | if (stat.time.QuadPart > maxTime) |
| 321 | maxTime = stat.time.QuadPart; |
| 322 | } |
| 323 | qsort(_stats, nStats, sizeof(*_stats), CmpStats); |
| 324 | double invMax = 100.0 / maxTime; |
| 325 | |
| 326 | LOG_DEBUG(Core, "----------------------------------------------------------"); |
| 327 | LOG_DEBUG(Core, "{:>40} {:>10} {:>5}", "Name", "Count", "Time"); |
| 328 | LOG_DEBUG(Core, "----------------------------------------------------------"); |
| 329 | |
| 330 | int penterAddr = (int)_penter; |
| 331 | int penterMap = PhysicalAddress("__penter"); |
| 332 | int offset = penterMap - penterAddr; |
| 333 | for (i = 0; i < nStats; i++) |
| 334 | { |
| 335 | FuncStat& stat = _stats[i]; |
| 336 | if (stat.count <= 0) |
| 337 | continue; |
| 338 | double relTime = (double)stat.time.QuadPart * invMax; |
| 339 | if (relTime < 0.5) |
| 340 | continue; |
| 341 | const char* name = MapNameFromPhysical(stat.address + offset); |
| 342 | LOG_DEBUG(Core, "{:>40} {:10} {:.1f}%", name, stat.count, relTime); |
| 343 | } |
| 344 | } |
| 345 | |
| 346 | static void AddStatistics(int timeLo, int timeHi, int function) |
| 347 | { |