| 324 | // |
| 325 | //************************************************************************************* |
| 326 | void CFragmentCache::DumpStats( const char * outputdir ) const |
| 327 | { |
| 328 | typedef std::vector< CFragment * > FragmentList; |
| 329 | FragmentList all_fragments; |
| 330 | |
| 331 | all_fragments.reserve( mFragments.size() ); |
| 332 | |
| 333 | u32 total_cycles( 0 ); |
| 334 | |
| 335 | // Sort in order of expended cycles |
| 336 | for(FragmentVec::const_iterator it = mFragments.begin(); it != mFragments.end(); ++it) |
| 337 | { |
| 338 | all_fragments.push_back( it->Fragment ); |
| 339 | total_cycles += it->Fragment->GetCyclesExecuted(); |
| 340 | } |
| 341 | |
| 342 | std::sort( all_fragments.begin(), all_fragments.end(), SDescendingCyclesSort() ); |
| 343 | |
| 344 | |
| 345 | IO::Filename filename; |
| 346 | IO::Filename fragments_dir; |
| 347 | |
| 348 | IO::Path::Assign( fragments_dir, outputdir ); |
| 349 | IO::Path::Append( fragments_dir, "fragments" ); |
| 350 | IO::Directory::EnsureExists( fragments_dir ); |
| 351 | |
| 352 | IO::Path::Combine( filename, outputdir, "fragments.html" ); |
| 353 | |
| 354 | FILE * fh( fopen( filename, "w" ) ); |
| 355 | if(fh) |
| 356 | { |
| 357 | fputs( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">", fh ); |
| 358 | fputs( "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n", fh ); |
| 359 | fputs( "<head><title>Fragments</title>\n", fh ); |
| 360 | fputs( "<link rel=\"stylesheet\" href=\"default.css\" type=\"text/css\" media=\"all\" />\n", fh ); |
| 361 | fputs( "</head><body>\n", fh ); |
| 362 | |
| 363 | |
| 364 | fputs( "<h1>Fragments</h1>\n", fh ); |
| 365 | fputs( "<div align=\"center\"><table>\n", fh ); |
| 366 | fputs( "<tr><th>Address</th><th>Loops</th><th>Cycle Count</th><th>Cycle %</th><th>Hit Count</th><th>Input Bytes</th><th>Output Bytes</th><th>Expansion Ratio</th></tr>\n", fh ); |
| 367 | |
| 368 | for(FragmentList::const_iterator it = all_fragments.begin(); it != all_fragments.end(); ++it) |
| 369 | { |
| 370 | const CFragment * fragment( *it ); |
| 371 | |
| 372 | if (fragment->GetCyclesExecuted() == 0) |
| 373 | continue; |
| 374 | |
| 375 | fputs( "<tr>", fh ); |
| 376 | fprintf( fh, "<td><a href=\"fragments//%08x.html\">0x%08x</a></td>", fragment->GetEntryAddress(), fragment->GetEntryAddress() ); |
| 377 | fprintf( fh, "<td>%s</td>", fragment->GetEntryAddress() == fragment->GetExitAddress() ? "*" : " " ); |
| 378 | fprintf( fh, "<td>%d</td>", fragment->GetCyclesExecuted() ); |
| 379 | fprintf( fh, "<td>%#.2f%%</td>", f32( fragment->GetCyclesExecuted() * 100.0f ) / f32( total_cycles ) ); |
| 380 | fprintf( fh, "<td>%d</td>", fragment->GetHitCount() ); |
| 381 | fprintf( fh, "<td>%d</td>", fragment->GetInputLength() ); |
| 382 | fprintf( fh, "<td>%d</td>", fragment->GetOutputLength() ); |
| 383 | fprintf( fh, "<td>%#.2f</td>", f32( fragment->GetOutputLength() ) / f32( fragment->GetInputLength() ) ); |
no test coverage detected