home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 39 / IOPROG_39.ISO / SOFT / sdkjava40.exe / data1.cab / fg_Samples / Samples / Profiler / jviewprf / allocprf.cpp next >
Encoding:
C/C++ Source or Header  |  2000-05-04  |  9.9 KB  |  285 lines

  1. // allocprf.cpp
  2. //
  3. // Created 01/19/99
  4. //
  5. // (C) Copyright 1995 - 1999 Microsoft Corporation.  All rights reserved.
  6. //
  7.  
  8. #include "project.hpp"
  9. #pragma hdrstop
  10.  
  11. #include <jevmon.h>
  12.  
  13. #include "allocprf.hpp"
  14. #include "jviewprf.hpp"
  15. #include "utils.hpp"
  16.  
  17.  
  18. HRESULT AllocationProfiler::Initialize (EventMonitor *pmon)
  19. {
  20.     (m_pmon = pmon)->AddRef();
  21.  
  22.     return S_OK;
  23. }
  24.  
  25. VOID AllocationProfiler::Destruct ()
  26. {
  27.     Iterate(&AllocationProfiler::DeleteCB);
  28.  
  29.     DeleteCriticalSection(&m_cs);
  30.  
  31.     if (m_pmon)
  32.         m_pmon->Release();
  33. }
  34.  
  35.  
  36. //static
  37. int AllocationProfiler::DeleteCB (AllocationProfilerEntry *ent, PVOID token)
  38. {
  39.     delete(ent);
  40.     return 1;
  41. }
  42.  
  43.  
  44. //static
  45. int AllocationProfiler::ComputeTotalsCB (AllocationProfilerEntry *cur, PVOID token)
  46. {
  47.     AllocationProfilerEntry *firstcls = cur->firstcls;
  48.     if (firstcls)
  49.     {
  50.         firstcls->nAlloc += cur->nAlloc;
  51.         firstcls->cbAlloc += cur->cbAlloc;
  52.     }
  53.  
  54.     return 1;
  55. }
  56.  
  57.  
  58. #define WIDTH_CLASS_NTOTAL      5
  59. #define WIDTH_CLASS_CBTOTAL     7
  60. #define WIDTH_CLASS_NPERGC      4
  61. #define WIDTH_CLASS_CBPERGC     6
  62. #define WIDTH_CLASS_PCTN        3
  63. #define WIDTH_CLASS_PCTCB       3
  64.  
  65. #define TOTAL_CLASS_FIXED_WIDTH (1+WIDTH_CLASS_NTOTAL+1+WIDTH_CLASS_CBTOTAL+1+WIDTH_CLASS_NPERGC+1+WIDTH_CLASS_CBPERGC+1+WIDTH_CLASS_PCTN+1+WIDTH_CLASS_PCTCB+1)
  66.  
  67.  
  68. //static
  69. int AllocationProfiler::SpewTotalsCB (AllocationProfilerEntry *cur, PVOID token)
  70. {
  71.     if (!cur->firstcls)
  72.     {
  73.         PSTR pszNameUtf8;
  74.         __int64 nTotalAllocated;
  75.         if (SUCCEEDED(m_pmon->GetVMInfoIfc()->ClassInformation(cur->id, &pszNameUtf8, NULL, NULL, NULL, &nTotalAllocated)))
  76.         {
  77.             if (nTotalAllocated != cur->nAlloc)
  78.             {
  79.                 WriteOutput("warning: count mismatch for ");
  80.                 WriteOutputUtf8(pszNameUtf8);
  81.                 WriteOutputFmt(", VM recorded %u instances but only reported %u allocations\n", (ULONG)nTotalAllocated, cur->nAlloc);
  82.             }
  83.  
  84.             WriteOutputFitString(WRITE_FIT | WRITE_WRAP | WRITE_UTF8 | WRITE_SPACE, TOTAL_CLASS_FIXED_WIDTH, 100, pszNameUtf8);
  85.  
  86.             ULONG npergc = cur->nAlloc / m_iGC;
  87.             ULONG cbpergc = cur->cbAlloc / m_iGC;
  88.  
  89.             unsigned pctnoverall = 0;
  90.             if (m_nTotalAlloc)
  91.                 pctnoverall = cur->nAlloc*100 / m_nTotalAlloc;
  92.  
  93.             unsigned pctcboverall = 0;
  94.             if (m_cbTotalAlloc)
  95.                 pctcboverall = cur->cbAlloc*100 / m_cbTotalAlloc;
  96.  
  97.             WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE,   WIDTH_CLASS_NTOTAL, cur->nAlloc);
  98.             WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE,   WIDTH_CLASS_CBTOTAL, cur->cbAlloc);
  99.             WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE,   WIDTH_CLASS_NPERGC, npergc);
  100.             WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE,   WIDTH_CLASS_CBPERGC, cbpergc);
  101.             WriteOutputColumnFmt(WRITE_RIGHT_JUSTIFIED | WRITE_SPACE,   WIDTH_CLASS_PCTN, "%u%%", pctnoverall);
  102.             WriteOutputColumnFmt(WRITE_RIGHT_JUSTIFIED | WRITE_NEWLINE, WIDTH_CLASS_PCTCB, "%u%%", pctcboverall);
  103.  
  104.             CoTaskMemFree(pszNameUtf8);
  105.         }
  106.     }
  107.  
  108.     return 1;
  109. }
  110.  
  111.  
  112. #define PCT_WIDTH_METHOD_LOCATION   66
  113. #define PCT_WIDTH_METHOD_TYPE       33
  114.  
  115. #define WIDTH_METHOD_NTOTAL         5
  116. #define WIDTH_METHOD_CBTOTAL        7
  117. #define WIDTH_METHOD_NPERGC         4
  118. #define WIDTH_METHOD_CBPERGC        6
  119. #define WIDTH_METHOD_PCTN           3
  120. #define WIDTH_METHOD_PCTCB          3
  121.  
  122. #define TOTAL_METHOD_FIXED_WIDTH (1+WIDTH_METHOD_NTOTAL+1+WIDTH_METHOD_CBTOTAL+1+WIDTH_METHOD_NPERGC+1+WIDTH_METHOD_CBPERGC+1+WIDTH_METHOD_PCTN+1+WIDTH_METHOD_PCTCB+1)
  123.  
  124.  
  125. //static
  126. int AllocationProfiler::SpewMethodsCB (AllocationProfilerEntry *cur, PVOID token)
  127. {
  128.     if (cur->loc)
  129.     {
  130.         PSTR pszTypeNameUtf8;
  131.         if (SUCCEEDED(m_pmon->GetVMInfoIfc()->ClassInformation(cur->id, &pszTypeNameUtf8, NULL, NULL, NULL, NULL)))
  132.         {
  133.             PSTR pszLocationNameUtf8;
  134.             if (SUCCEEDED(m_pmon->GetVMInfoIfc()->MethodInformation(cur->loc, &pszLocationNameUtf8, NULL, NULL, NULL, NULL)))
  135.             {
  136.                 WriteOutputExArgs args;
  137.  
  138.                 args.Width = TOTAL_METHOD_FIXED_WIDTH;
  139.  
  140.                 args.PctFreeSpaceToUse = PCT_WIDTH_METHOD_LOCATION;
  141.                 args.PctFreeSpaceUsed = 0;
  142.                 args.FixedSpaceUsed = 0;
  143.  
  144.                 WriteOutputEx(WRITE_FIT | WRITE_WRAP | WRITE_UTF8 | WRITE_SPACE, &args, pszLocationNameUtf8);
  145.  
  146.                 args.PctFreeSpaceToUse = PCT_WIDTH_METHOD_TYPE;
  147.                 args.PctFreeSpaceUsed = PCT_WIDTH_METHOD_LOCATION;
  148.                 args.FixedSpaceUsed = 1;
  149.  
  150.                 WriteOutputEx(WRITE_FIT | WRITE_WRAP | WRITE_UTF8 | WRITE_SPACE, &args, pszTypeNameUtf8);
  151.  
  152.                 ULONG npergc = cur->nAlloc / m_iGC;
  153.                 ULONG cbpergc = cur->cbAlloc / m_iGC;
  154.  
  155.                 unsigned pctnoverall = 0;
  156.                 if (m_nTotalAlloc)
  157.                     pctnoverall = cur->nAlloc*100 / m_nTotalAlloc;
  158.  
  159.                 unsigned pctcboverall = 0;
  160.                 if (m_cbTotalAlloc)
  161.                     pctcboverall = cur->cbAlloc*100 / m_cbTotalAlloc;
  162.  
  163.                 WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_NTOTAL, cur->nAlloc);
  164.                 WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_CBTOTAL, cur->cbAlloc);
  165.                 WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_NPERGC, npergc);
  166.                 WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_CBPERGC, cbpergc);
  167.  
  168.                 args.Width = WIDTH_METHOD_PCTN;
  169.  
  170.                 WriteOutputFmtEx(WRITE_RIGHT_JUSTIFIED | WRITE_SPACE, &args, "%u%%", pctnoverall);
  171.  
  172.                 args.Width = WIDTH_METHOD_PCTCB;
  173.  
  174.                 WriteOutputFmtEx(WRITE_RIGHT_JUSTIFIED | WRITE_NEWLINE, &args, "%u%%", pctcboverall);
  175.  
  176.                 CoTaskMemFree(pszLocationNameUtf8);
  177.             }
  178.  
  179.             CoTaskMemFree(pszTypeNameUtf8);
  180.         }
  181.     }
  182.  
  183.     return 1;
  184. }
  185.  
  186.  
  187. int AllocationProfiler::Iterate (POBJITERFN fn, PVOID token)
  188. {
  189.     int res = 1;
  190.     
  191.     for (unsigned i = 0; i < ARRAY_ELEMENTS(m_hash); i++)
  192.     {
  193.         AllocationProfilerEntry *cur = m_hash[i];
  194.         while (cur != NULL)
  195.         {
  196.             AllocationProfilerEntry *next = cur->next;
  197.             res = (this->*fn)(cur, token);
  198.             if (res <= 0)
  199.                 break;
  200.             cur = next;
  201.         }
  202.     }
  203.  
  204.     return res;
  205. }
  206.  
  207.  
  208. VOID AllocationProfiler::SpewResults ()
  209. {
  210.     if (!(g_ProfOptions & OPT_PROF_ALLOC))
  211.         return;
  212.  
  213.     WriteOutputFmt("Allocations:\n" "%u objects\n" "%u bytes\n", m_nTotalAlloc, m_cbTotalAlloc);
  214.  
  215.     if (g_ProfOptions & OPT_ALLOC_PER_METHOD)
  216.     {
  217.         if (g_OutputWidth)
  218.         {
  219.             WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_METHOD_FIXED_WIDTH, 100, "");
  220.             WriteOutputColumnString(WRITE_CENTERED | WRITE_SPACE, WIDTH_METHOD_NTOTAL+1+WIDTH_METHOD_CBTOTAL, "Total");
  221.             WriteOutputColumnString(WRITE_CENTERED | WRITE_SPACE, WIDTH_METHOD_NPERGC+1+WIDTH_METHOD_CBPERGC, "Per GC");
  222.             WriteOutputColumnString(WRITE_CENTERED | WRITE_NEWLINE, WIDTH_METHOD_PCTN+1+WIDTH_METHOD_PCTCB, "Overall");
  223.  
  224.             WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_METHOD_FIXED_WIDTH, PCT_WIDTH_METHOD_LOCATION, "Method");
  225.             WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_METHOD_FIXED_WIDTH, PCT_WIDTH_METHOD_TYPE, "Type");
  226.  
  227.             WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_NTOTAL, "Num");
  228.             WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_CBTOTAL, "Bytes");
  229.             WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_NPERGC, "Num");
  230.             WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_CBPERGC, "Bytes");
  231.             WriteOutputColumnString(WRITE_CENTERED | WRITE_NEWLINE, WIDTH_METHOD_PCTN+1+WIDTH_METHOD_PCTCB, "#/Bytes");
  232.         }
  233.         else
  234.         {
  235.             WriteOutput("Method Type Total Bytes PerGCTotal PerGCBytes PctOverallTotal PctOverallBytes\n");
  236.         }
  237.  
  238.         Iterate(&AllocationProfiler::SpewMethodsCB);
  239.     }
  240.  
  241.     if (g_ProfOptions & OPT_ALLOC_PER_CLASS)
  242.     {
  243.         if (g_ProfOptions & OPT_ALLOC_PER_METHOD)
  244.         {
  245.             Iterate(&AllocationProfiler::ComputeTotalsCB);
  246.         }
  247.  
  248.         WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_CLASS_FIXED_WIDTH, 100, "");
  249.         WriteOutputColumnString(WRITE_CENTERED | WRITE_SPACE, WIDTH_CLASS_NTOTAL+1+WIDTH_CLASS_CBTOTAL, "Total");
  250.         WriteOutputColumnString(WRITE_CENTERED | WRITE_SPACE, WIDTH_CLASS_NPERGC+1+WIDTH_CLASS_CBPERGC, "Per GC");
  251.         WriteOutputColumnString(WRITE_CENTERED | WRITE_NEWLINE, WIDTH_CLASS_PCTN+2+WIDTH_CLASS_PCTCB+1, "Overall");
  252.  
  253.         WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_CLASS_FIXED_WIDTH, 100, "Type");
  254.  
  255.         WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_NTOTAL, "Num");
  256.         WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_CBTOTAL, "Bytes");
  257.         WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_NPERGC, "Num");
  258.         WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_CBPERGC, "Bytes");
  259.         WriteOutputColumnString(WRITE_CENTERED | WRITE_NEWLINE, WIDTH_CLASS_PCTN+2+WIDTH_CLASS_PCTCB+1, "#/Bytes");
  260.  
  261.         Iterate(&AllocationProfiler::SpewTotalsCB);
  262.     }
  263. }
  264.  
  265.  
  266. VOID AllocationProfiler::InstanceCreated (ClassID idType, size_t size, MethodID idCreatingMethod)
  267. {
  268.     EnterCriticalSection(&m_cs);
  269.     {
  270.         m_nTotalAlloc++;
  271.         m_cbTotalAlloc += size;
  272.         
  273.         AllocationProfilerEntry *pent = LookupObject(idType, idCreatingMethod);
  274.         if (pent)
  275.         {
  276.             pent->nAlloc++;
  277.             pent->cbAlloc += size;
  278.         }
  279.     }
  280.     LeaveCriticalSection(&m_cs);
  281. }
  282.  
  283.  
  284.  
  285.