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

  1. // gcview.cpp
  2. //
  3. // Created 10/08/98
  4. //
  5. // (C)Copyright 1998-1999 Microsoft Corporation, All rights reserved.
  6. //
  7.  
  8. #include "pch.hpp"
  9. #pragma hdrstop
  10.  
  11. #include "gcview.hpp"
  12. #include "hpmonmgr.hpp"
  13.  
  14.  
  15. BOOL GCHistoryViewer::s_fRegisteredClass = FALSE;
  16.  
  17.  
  18. //static
  19. LRESULT CALLBACK GCHistoryViewer::WndProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
  20. {
  21.     GCHistoryViewer *gchv = (GCHistoryViewer*)GetWindowLong(wnd, GWL_USERDATA);
  22.     
  23.     switch (msg)
  24.     {
  25.     case WM_SIZE:
  26.         {
  27.             RECT rc;
  28.             GetClientRect(wnd, &rc);
  29.             MoveWindow(gchv->m_list, rc.left, rc.top, rc.right, rc.bottom, TRUE);
  30.         }
  31.         break;
  32.  
  33.     case WM_NOTIFY:
  34.         {
  35.             //int idCtrl = (int)wParam; 
  36.             NMHDR *pnmh = (NMHDR*)lParam; 
  37.  
  38.             switch (pnmh->code)
  39.             {
  40.             case LVN_GETDISPINFO:
  41.                 {
  42.                     NMLVDISPINFO *pnmv = (NMLVDISPINFO*)lParam; 
  43.                     LVITEM *pitem  = &pnmv->item;
  44.  
  45.                     if (pitem->mask & LVIF_TEXT)
  46.                     {
  47.                         PerGCInformation *gcinfo = NULL;
  48.  
  49.                         if (pitem->mask & LVIF_PARAM)
  50.                         {
  51.                             gcinfo = (PerGCInformation*)pitem->lParam;
  52.                         }
  53.                         else
  54.                         {
  55.                             LVITEM lvi;
  56.                             lvi.mask = LVIF_PARAM;
  57.                             lvi.iItem = pitem->iItem;
  58.                             lvi.iSubItem = 0;
  59.                             if (ListView_GetItem(gchv->m_list, &lvi))
  60.                                 gcinfo = (PerGCInformation*)pitem->lParam;
  61.                         }
  62.                         
  63.                         if (gcinfo != NULL)
  64.                         {
  65.                             static DWORD rgFlagsNeededForCol[] =
  66.                             {
  67.                                 /*GHV_COL_NUM*/                 0,
  68.                                 /*GHV_COL_OBJECTS*/             HMC_INFO_HEAP_OBJECTS,
  69.                                 /*GHV_COL_SIZE*/                HMC_INFO_HEAP_OBJECTS,
  70.                                 /*GHV_COL_MULTIREFOBJECTS*/     (HMC_INFO_HEAP_OBJECTS | HMC_INFO_HEAP_OBJECT_REFS),
  71.                                 /*GHV_COL_OBJECTEDGES*/         (HMC_INFO_HEAP_OBJECTS | HMC_INFO_HEAP_OBJECT_REFS),
  72.                                 /*GHV_COL_ROOTS*/               HMC_INFO_HEAP_ROOTS,
  73.                                 /*GHV_COL_ROOTEDGES*/           HMC_INFO_HEAP_ROOT_REFS,
  74.                                 /*GHV_COL_MONITORS*/            HMC_INFO_COUNT_MONITORS,
  75.                             };
  76.  
  77.                             int col = pitem->iSubItem;
  78.  
  79.                             DWORD FlagsNeeded = rgFlagsNeededForCol[col];
  80.                             if ((gcinfo->InfoMaskCollected & FlagsNeeded) == FlagsNeeded)
  81.                             {
  82.                                 switch (col)
  83.                                 {
  84.                                 case GHV_COL_NUM:
  85.                                     FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", gcinfo->iGC);
  86.                                     return 0;
  87.  
  88.                                 case GHV_COL_OBJECTS:
  89.                                     FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", gcinfo->nObjects);
  90.                                     return 0;
  91.  
  92.                                 case GHV_COL_SIZE:
  93.                                     FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", gcinfo->cbObjects);
  94.                                     return 0;
  95.  
  96.                                 case GHV_COL_MULTIREFOBJECTS:
  97.                                     FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", gcinfo->nObjectsWithMultipleReferences);
  98.                                     return 0;
  99.  
  100.                                 case GHV_COL_OBJECTEDGES:
  101.                                     FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", gcinfo->nObjectEdges);
  102.                                     return 0;
  103.  
  104.                                 case GHV_COL_ROOTS:
  105.                                     {
  106.                                         ULONG nRoots = 0;
  107.                                         for (unsigned i = 0; i < ARRAY_ELEMENTS(gcinfo->rgcRoots); i++)
  108.                                             nRoots += gcinfo->rgcRoots[i];
  109.                                         FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", nRoots);
  110.                                     }
  111.                                     return 0;
  112.  
  113.                                 case GHV_COL_ROOTEDGES:
  114.                                     FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", gcinfo->nRootEdges);
  115.                                     return 0;
  116.                                 
  117.                                 case GHV_COL_MONITORS:
  118.                                     FormatNumber(pitem->pszText, pitem->cchTextMax, "%I64u", gcinfo->nObjectMonitors);
  119.                                     return 0;
  120.                                     
  121.                                 default:;
  122.                                 }
  123.                             }
  124.                             else
  125.                             {
  126.                                 FitText(pitem->pszText, pitem->cchTextMax, "---");
  127.                                 return 0;
  128.                             }
  129.                         }
  130.                     }
  131.                 }
  132.                 break;
  133.             }
  134.         }
  135.         break;
  136.     }
  137.     
  138.     return gchv->BaseWndProc(wnd, msg, wParam, lParam);
  139. }
  140.  
  141.  
  142. BOOL GCHistoryViewer::OnCreateWindow ()
  143. {
  144.     BOOL result;
  145.  
  146.     HINSTANCE hinst = m_mgr->GetInstance();
  147.  
  148.     RECT rc;
  149.  
  150.     GetClientRect(m_hwnd, &rc);
  151.  
  152.     result = (m_list = CreateWindow(
  153.             WC_LISTVIEW,
  154.             NULL,
  155.             WS_CHILD | LVS_REPORT,
  156.             rc.left, rc.top, rc.right, rc.bottom,
  157.             m_hwnd,
  158.             NULL,
  159.             hinst,
  160.             NULL)) != NULL;
  161.  
  162.     if (result)
  163.     {
  164.         static PSTR colnames[] = {
  165.                 "GC number",
  166.                 "Objects",
  167.                 "Bytes of objects",
  168.                 "Objects with multiple references",
  169.                 "Object out-edges",
  170.                 "Roots",
  171.                 "Root edges",
  172.                 "Monitors",
  173.         };
  174.  
  175.         unsigned spaceleft = rc.right - rc.left;
  176.  
  177.         LVCOLUMN lvc;
  178.         lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
  179.         lvc.fmt = LVCFMT_CENTER;
  180.  
  181.         unsigned i = 0;
  182.         for (;;)
  183.         {
  184.             lvc.cx = spaceleft / (GHV_NUM_COLUMNS-i);
  185.             
  186.             lvc.pszText = colnames[i];
  187.         
  188.             result = (ListView_InsertColumn(m_list, i, &lvc) != -1);
  189.             if (!result)
  190.                 break;
  191.  
  192.             i++;
  193.             if (i >= GHV_NUM_COLUMNS)
  194.                 break;
  195.             spaceleft -= lvc.cx;
  196.         }
  197.     }
  198.  
  199.     if (result)
  200.     {
  201.         LVITEM lvi;
  202.         lvi.mask = LVIF_PARAM | LVIF_TEXT;
  203.         lvi.pszText = LPSTR_TEXTCALLBACK;
  204.         lvi.iSubItem = 0;
  205.     
  206.         unsigned i = 0;
  207.         PerGCInformation *gcinfo = m_mgr->GetCurrentGCInfo();
  208.  
  209.         m_iLastGCAdded = 0;
  210.         if (gcinfo)
  211.         {
  212.             m_iLastGCAdded = gcinfo->iGC;
  213.  
  214.             do
  215.             {
  216.                 lvi.iItem = i;
  217.                 lvi.lParam = (LPARAM)gcinfo;
  218.                 result = ListView_InsertItem(m_list, &lvi) != -1;
  219.                 if (!result)
  220.                     break;
  221.  
  222.                 gcinfo = gcinfo->next;
  223.                 i++;
  224.             }
  225.             while (gcinfo);
  226.         }
  227.     }
  228.  
  229.     if (result)
  230.     {
  231.         ShowWindow(m_list, SW_SHOWNA);
  232.     }
  233.  
  234.     return result;
  235. }
  236.  
  237.  
  238. STDMETHODIMP GCHistoryViewer::ObjectDiscoveryComplete ()
  239. {
  240.     PerGCInformation *pNewGCInfo = m_mgr->GetCurrentGCInfo();
  241.     ASSERT(pNewGCInfo->iGC >= m_iLastGCAdded);
  242.  
  243.     if (pNewGCInfo->iGC != m_iLastGCAdded)
  244.     {
  245.         LVITEM lvi;
  246.         lvi.mask = LVIF_PARAM | LVIF_TEXT;
  247.         lvi.pszText = LPSTR_TEXTCALLBACK;
  248.         lvi.iSubItem = 0;
  249.         lvi.iItem = 0;
  250.         lvi.lParam = (LPARAM)pNewGCInfo;
  251.         ListView_InsertItem(m_list, &lvi);
  252.  
  253.         m_iLastGCAdded = pNewGCInfo->iGC;
  254.     }
  255.  
  256.     return S_OK;
  257. }
  258.  
  259.  
  260. BOOL GCHistoryViewer::Initialize (HeapMonitorManager *mgr)
  261. {
  262.     BOOL result = TRUE;
  263.  
  264.     if (!s_fRegisteredClass)
  265.     {
  266.         WNDCLASS wc;
  267.         ZeroMemory(&wc, sizeof(wc));
  268.         wc.lpfnWndProc = &WndProc;
  269.         wc.hInstance = mgr->GetInstance();
  270.         wc.lpszClassName = WC_HEAPMONITOR_GCHISTORYVIEWER;
  271.         wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
  272.         wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  273.         result = RegisterClass(&wc);
  274.  
  275.         s_fRegisteredClass = result;
  276.     }
  277.  
  278.     if (result)
  279.     {
  280.         HeapMonitorClientRegistrationInfo reginfo;
  281.         ZeroMemory(®info, sizeof(reginfo));
  282.  
  283.         reginfo.EventMask = HMC_HEAP_EVENTS;
  284.         reginfo.InfoMask = (  HMC_INFO_HEAP_ROOTS
  285.                             | HMC_INFO_HEAP_ROOT_REFS
  286.                             | HMC_INFO_HEAP_OBJECTS
  287.                             | HMC_INFO_HEAP_OBJECT_REFS
  288.                             | HMC_INFO_COUNT_MONITORS);
  289.  
  290.         result = BaseInitialize(mgr, WC_HEAPMONITOR_GCHISTORYVIEWER, "GC History", ®info);
  291.     }
  292.  
  293.     return result;
  294. }
  295.  
  296.