home *** CD-ROM | disk | FTP | other *** search
/ Enter 1999 November / ENTER11_1.bin / WARSZTAT / SDKJava32.exe / data1.cab / fg_Samples / Samples / Profiler / jviewprf / allocprf.cpp next >
Encoding:
C/C++ Source or Header  |  1999-03-17  |  9.0 KB  |  266 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        2
  63. #define WIDTH_CLASS_PCTCB       2
  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+2+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 %I64u instances but only reported %u allocations\n", nTotalAllocated, cur->nAlloc);
  82.             }
  83.  
  84.             WriteOutputEx(WRITE_FIT | WRITE_WRAP | WRITE_UTF8, "s ", TOTAL_CLASS_FIXED_WIDTH, 1.0, 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.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_CLASS_NTOTAL, cur->nAlloc);
  98.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_CLASS_CBTOTAL, cur->cbAlloc);
  99.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_CLASS_NPERGC, npergc);
  100.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_CLASS_CBPERGC, cbpergc);
  101.             WriteOutputEx(WRITE_RIGHT_JUSTIFIED, "u%% ", WIDTH_CLASS_PCTN, pctnoverall);
  102.             WriteOutputEx(WRITE_RIGHT_JUSTIFIED, "u%%\n", WIDTH_CLASS_PCTCB, pctcboverall);
  103.  
  104.             CoTaskMemFree(pszNameUtf8);
  105.         }
  106.     }
  107.  
  108.     return 1;
  109. }
  110.  
  111.  
  112. #define PCT_WIDTH_METHOD_LOCATION   0.66
  113. #define PCT_WIDTH_METHOD_TYPE       0.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           2
  120. #define WIDTH_METHOD_PCTCB          2
  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+2+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.                 WriteOutputEx(WRITE_FIT | WRITE_WRAP | WRITE_UTF8, "s ", TOTAL_METHOD_FIXED_WIDTH, PCT_WIDTH_METHOD_LOCATION, 0.0, 0, pszLocationNameUtf8);
  137.                 WriteOutputEx(WRITE_FIT | WRITE_WRAP | WRITE_UTF8, "s ", TOTAL_METHOD_FIXED_WIDTH, PCT_WIDTH_METHOD_TYPE, PCT_WIDTH_METHOD_LOCATION, 1, pszTypeNameUtf8);
  138.  
  139.                 ULONG npergc = cur->nAlloc / m_iGC;
  140.                 ULONG cbpergc = cur->cbAlloc / m_iGC;
  141.  
  142.                 unsigned pctnoverall = 0;
  143.                 if (m_nTotalAlloc)
  144.                     pctnoverall = cur->nAlloc*100 / m_nTotalAlloc;
  145.  
  146.                 unsigned pctcboverall = 0;
  147.                 if (m_cbTotalAlloc)
  148.                     pctcboverall = cur->cbAlloc*100 / m_cbTotalAlloc;
  149.  
  150.                 WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_METHOD_NTOTAL, cur->nAlloc);
  151.                 WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_METHOD_CBTOTAL, cur->cbAlloc);
  152.                 WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_METHOD_NPERGC, npergc);
  153.                 WriteOutputEx(WRITE_LEFT_JUSTIFIED, "u ", WIDTH_METHOD_CBPERGC, cbpergc);
  154.                 WriteOutputEx(WRITE_RIGHT_JUSTIFIED, "u%% ", WIDTH_METHOD_PCTN, pctnoverall);
  155.                 WriteOutputEx(WRITE_RIGHT_JUSTIFIED, "u%%\n", WIDTH_METHOD_PCTCB, pctcboverall);
  156.  
  157.                 CoTaskMemFree(pszLocationNameUtf8);
  158.             }
  159.  
  160.             CoTaskMemFree(pszTypeNameUtf8);
  161.         }
  162.     }
  163.  
  164.     return 1;
  165. }
  166.  
  167.  
  168. int AllocationProfiler::Iterate (POBJITERFN fn, PVOID token)
  169. {
  170.     int res = 1;
  171.     
  172.     for (unsigned i = 0; i < ARRAY_ELEMENTS(m_hash); i++)
  173.     {
  174.         AllocationProfilerEntry *cur = m_hash[i];
  175.         while (cur != NULL)
  176.         {
  177.             AllocationProfilerEntry *next = cur->next;
  178.             res = (this->*fn)(cur, token);
  179.             if (res <= 0)
  180.                 break;
  181.             cur = next;
  182.         }
  183.     }
  184.  
  185.     return res;
  186. }
  187.  
  188.  
  189. VOID AllocationProfiler::SpewResults ()
  190. {
  191.     if (!(g_ProfOptions & OPT_PROF_ALLOC))
  192.         return;
  193.  
  194.     WriteOutputFmt("Allocations:\n" "%u objects\n" "%u bytes\n", m_nTotalAlloc, m_cbTotalAlloc);
  195.  
  196.     if (g_ProfOptions & OPT_ALLOC_PER_METHOD)
  197.     {
  198.         if (g_OutputWidth)
  199.         {
  200.             WriteOutputEx(WRITE_FIT, "s ", TOTAL_METHOD_FIXED_WIDTH, 1.0, "");
  201.             WriteOutputEx(WRITE_CENTERED, "s ", WIDTH_METHOD_NTOTAL+1+WIDTH_METHOD_CBTOTAL, "Total");
  202.             WriteOutputEx(WRITE_CENTERED, "s ", WIDTH_METHOD_NPERGC+1+WIDTH_METHOD_CBPERGC, "Per GC");
  203.             WriteOutputEx(WRITE_CENTERED, "s\n", WIDTH_METHOD_PCTN+1+WIDTH_METHOD_PCTCB, "Overall");
  204.  
  205.             WriteOutputEx(WRITE_FIT, "s ", TOTAL_METHOD_FIXED_WIDTH, PCT_WIDTH_METHOD_LOCATION, "Method");
  206.             WriteOutputEx(WRITE_FIT, "s ", TOTAL_METHOD_FIXED_WIDTH, PCT_WIDTH_METHOD_TYPE, "Type");
  207.  
  208.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "s ", WIDTH_METHOD_NTOTAL, "Num");
  209.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "s ", WIDTH_METHOD_CBTOTAL, "Bytes");
  210.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "s ", WIDTH_METHOD_NPERGC, "Num");
  211.             WriteOutputEx(WRITE_LEFT_JUSTIFIED, "s ", WIDTH_METHOD_CBPERGC, "Bytes");
  212.             WriteOutputEx(WRITE_CENTERED, "s\n", WIDTH_METHOD_PCTN+2+WIDTH_METHOD_PCTCB+1, "#/Bytes");
  213.         }
  214.         else
  215.         {
  216.             WriteOutput("Method Type Total Bytes PerGCTotal PerGCBytes PctOverallTotal PctOverallBytes\n");
  217.         }
  218.  
  219.         Iterate(&AllocationProfiler::SpewMethodsCB);
  220.     }
  221.  
  222.     if (g_ProfOptions & OPT_ALLOC_PER_CLASS)
  223.     {
  224.         if (g_ProfOptions & OPT_ALLOC_PER_METHOD)
  225.         {
  226.             Iterate(&AllocationProfiler::ComputeTotalsCB);
  227.         }
  228.  
  229.         WriteOutputEx(WRITE_FIT, "s ", TOTAL_CLASS_FIXED_WIDTH, 1.0, "");
  230.         WriteOutputEx(WRITE_CENTERED, "s ", WIDTH_CLASS_NTOTAL+1+WIDTH_CLASS_CBTOTAL, "Total");
  231.         WriteOutputEx(WRITE_CENTERED, "s ", WIDTH_CLASS_NPERGC+1+WIDTH_CLASS_CBPERGC, "Per GC");
  232.         WriteOutputEx(WRITE_CENTERED, "s\n", WIDTH_CLASS_PCTN+2+WIDTH_CLASS_PCTCB+1, "Overall");
  233.  
  234.         WriteOutputEx(WRITE_FIT, "s ", TOTAL_CLASS_FIXED_WIDTH, 1.0, "Type");
  235.  
  236.         WriteOutputEx(WRITE_LEFT_JUSTIFIED, "s ", WIDTH_CLASS_NTOTAL, "Num");
  237.         WriteOutputEx(WRITE_LEFT_JUSTIFIED, "s ", WIDTH_CLASS_CBTOTAL, "Bytes");
  238.         WriteOutputEx(WRITE_LEFT_JUSTIFIED, "s ", WIDTH_CLASS_NPERGC, "Num");
  239.         WriteOutputEx(WRITE_LEFT_JUSTIFIED, "s ", WIDTH_CLASS_CBPERGC, "Bytes");
  240.         WriteOutputEx(WRITE_CENTERED, "s\n", WIDTH_CLASS_PCTN+2+WIDTH_CLASS_PCTCB+1, "#/Bytes");
  241.  
  242.         Iterate(&AllocationProfiler::SpewTotalsCB);
  243.     }
  244. }
  245.  
  246.  
  247. VOID AllocationProfiler::InstanceCreated (ClassID idType, size_t size, MethodID idCreatingMethod)
  248. {
  249.     EnterCriticalSection(&m_cs);
  250.     {
  251.         m_nTotalAlloc++;
  252.         m_cbTotalAlloc += size;
  253.         
  254.         AllocationProfilerEntry *pent = LookupObject(idType, idCreatingMethod);
  255.         if (pent)
  256.         {
  257.             pent->nAlloc++;
  258.             pent->cbAlloc += size;
  259.         }
  260.     }
  261.     LeaveCriticalSection(&m_cs);
  262. }
  263.  
  264.  
  265.  
  266.