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

  1. // heapview.cpp
  2. //
  3. // Created 10/04/98
  4. //
  5. // (C)Copyright 1998-1999 Microsoft Corporation, All rights reserved.
  6. //
  7.  
  8. #include "pch.hpp"
  9. #pragma hdrstop
  10.  
  11. #include "heapview.hpp"
  12. #include "resource.h"
  13.  
  14.  
  15. LRESULT CALLBACK HeapViewer::WndProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
  16. {
  17.     switch (msg)
  18.     {
  19.     case WM_HVEVENT_THREAD_CREATED:
  20.         {
  21.             THREADID thd = (THREADID)lParam;
  22.             AddNewThread(thd);
  23.         }
  24.         return 0;
  25.         
  26.     case WM_HVEVENT_NEW_PACKAGE:
  27.         {
  28.             PKGID pkg = (PKGID)lParam;
  29.             AddTreeItemForID(GetRootForPackage(pkg->parent), pkg);
  30.         }
  31.         return 0;
  32.  
  33.     case WM_HVEVENT_THREAD_DESTROYED:
  34.         {
  35.             THREADID thd = (THREADID)lParam;
  36.             HTREEITEM htiThread = FindChildItemForID(m_htiThreads, thd);
  37.             if (htiThread)
  38.             {
  39.                 TV_ITEM tvi;
  40.                 CHAR buf[256];
  41.                 tvi.hItem = htiThread;
  42.                 tvi.mask = TVIF_TEXT;
  43.                 tvi.pszText = &buf[0];
  44.                 tvi.cchTextMax = sizeof(buf);
  45.  
  46.                 PSTR pszText = NULL;
  47.  
  48.                 if (TreeView_GetItem(m_htree, &tvi) && (tvi.mask & TVIF_TEXT))
  49.                 {
  50.                     pszText = &buf[0];
  51.                 }
  52.  
  53.                 tvi.mask = (TVIF_IMAGE | TVIF_TEXT | TVIF_PARAM);
  54.                 tvi.iImage = HVTII_DEAD_THREAD;
  55.                 tvi.lParam = NULL;
  56.  
  57.                 if (!pszText || !TreeView_SetItem(m_htree, &tvi))
  58.                 {
  59.                     DeleteTreeItem(htiThread);
  60.                 }
  61.  
  62.                 ASSERT(!FindChildItemForID(m_htiThreads, thd));
  63.             }
  64.         }
  65.         return 0;
  66.         
  67.     case WM_HVEVENT_CLASS_LOADED:
  68.         {
  69.             CLASSID cls = (CLASSID)lParam;
  70.             AddTreeItemForID(GetRootForPackage(cls->pkg), cls);
  71.         }
  72.         return 0;
  73.  
  74.     case WM_HVEVENT_CLASS_UNLOADED:
  75.         // TODO
  76.         return 0;
  77.  
  78.     case WM_HVEVENT_ROOT_REFERENCES:
  79.         AddRootReferences((RootReferencesEventInfo*)lParam);
  80.         return 0;
  81.     }
  82.  
  83.     return ObjectViewer::WndProc(wnd, msg, wParam, lParam);
  84. }
  85.  
  86.  
  87. //static
  88. int HeapViewer::PopulateTreeCB (ID id, PVOID token)
  89. {
  90.     HeapViewer *hv = (HeapViewer*)token;
  91.  
  92.     ASSERT(hv->Entered());
  93.     ASSERT(hv->m_mgr->CanSendUIMessages());
  94.  
  95.     if (id->type != ID_OBJECT && (hv->m_fStopped || id->type < ID_FIRST_TRANSIENT))
  96.     {
  97.         HTREEITEM htiroot = hv->GetTreeItemForID(id);
  98.     
  99.         if (htiroot == NULL)
  100.         {
  101.             // TODO: indicate that tree is incomplete
  102.         }
  103.     }
  104.  
  105.     return 1;
  106. }
  107.  
  108.  
  109. //static
  110. int HeapViewer::PopulateRootObjectsCB (ID id, ObjectID refvmid, PVOID token)
  111. {
  112.     HeapViewer *hv = (HeapViewer*)token;
  113.  
  114.     HTREEITEM hti = hv->GetTreeItemForID(id);
  115.     if (hti != NULL)
  116.     {
  117.         OBJID refid = (OBJID)hv->m_mgr->LookupID(refvmid);
  118.         if (refid != NULL)
  119.             hv->AddTreeItemForReferencedID(hti, refid);
  120.         else
  121.             hv->AddTreeItemForObject(hti, refvmid);
  122.     }
  123.     
  124.     return 1;
  125. }
  126.  
  127.  
  128. // TODO: if have to substitute an "outer" container or TVI_ROOT, indicate
  129. // that tree is incomplete
  130.  
  131.  
  132. HTREEITEM HeapViewer::GetRootForThreads ()
  133. {
  134.     HTREEITEM root;
  135.  
  136.     root = m_htiThreads;
  137.     if (root == NULL)
  138.         root = CreateRoot(&m_htiThreads, "Threads", HVTII_FOLDER);
  139.  
  140.     return root;
  141. }
  142.  
  143.  
  144. HTREEITEM HeapViewer::GetRootForClasses ()
  145. {
  146.     HTREEITEM root;
  147.  
  148.     root = m_htiClasses;
  149.     if (root == NULL)
  150.         root = CreateRoot(&m_htiClasses, "Classes", HVTII_FOLDER);
  151.  
  152.     return root;
  153. }
  154.  
  155.  
  156. HTREEITEM HeapViewer::GetRootForPackage (PKGID pkg)
  157. {
  158.     if (pkg == NULL)
  159.         return GetRootForClasses();
  160.  
  161.     HTREEITEM htiParent = GetRootForPackage(pkg->parent);
  162.     if (htiParent == TVI_ROOT)
  163.         return TVI_ROOT;
  164.  
  165.     HTREEITEM htipkg = FindChildItemForID(htiParent, pkg);
  166.     if (htipkg != NULL)
  167.         return htipkg;
  168.  
  169.     htipkg = AddTreeItemForID(htiParent, pkg);
  170.     if (htipkg == NULL)
  171.         htipkg = TVI_ROOT;
  172.  
  173.     return htipkg;
  174. }
  175.  
  176.  
  177. HTREEITEM HeapViewer::GetRootForObjects ()
  178. {
  179.     HTREEITEM root;
  180.  
  181.     root = m_htiObjects;
  182.     if (root == NULL)
  183.         root = CreateRoot(&m_htiObjects, "Objects", HVTII_FOLDER);
  184.  
  185.     return root;
  186. }
  187.  
  188.  
  189. HTREEITEM HeapViewer::GetRootForRoots ()
  190. {
  191.     HTREEITEM root;
  192.  
  193.     root = m_htiRoots;
  194.     if (root == NULL)
  195.         root = CreateRoot(&m_htiRoots, "Roots", HVTII_FOLDER);
  196.  
  197.     return root;
  198. }
  199.  
  200.  
  201. HTREEITEM HeapViewer::GetTreeItemForThread (THREADID thd)
  202. {
  203.     HTREEITEM htithdroot = GetRootForThreads();
  204.     HTREEITEM htithd = FindChildItemForID(htithdroot, thd);
  205.     if (htithd == NULL)
  206.         htithd = AddTreeItemForID(htithdroot, thd);
  207.     if (htithd == NULL)
  208.         htithd = htithdroot;
  209.     return htithd;
  210. }
  211.  
  212.  
  213. HTREEITEM HeapViewer::GetTreeItemForClass (CLASSID cls)
  214. {
  215.     HTREEITEM hticlsroot = GetRootForPackage(cls->pkg);
  216.     HTREEITEM hticls = FindChildItemForID(hticlsroot, cls);
  217.     if (hticls == NULL)
  218.         hticls = AddTreeItemForID(hticlsroot, cls);
  219.     if (hticls == NULL)
  220.         hticls = hticlsroot;
  221.     return hticls;
  222. }
  223.  
  224.  
  225. HTREEITEM HeapViewer::GetTreeItemForRoot (ROOTID root)
  226. {
  227.     HTREEITEM htiroots = GetRootForRoots();
  228.     HTREEITEM htiroot = FindChildItemForID(htiroots, root);
  229.     if (htiroot == NULL)
  230.         htiroot = AddTreeItemForID(htiroots, root);
  231.     if (htiroot == NULL)
  232.         htiroot = htiroots;
  233.     return htiroot;
  234. }
  235.  
  236.  
  237. HTREEITEM HeapViewer::GetTreeItemForStackFrame (HTREEITEM htiThread, STACKID frm)
  238. {
  239.     HTREEITEM htiFrame = FindChildItemForID(htiThread, frm);
  240.     if (htiFrame == NULL)
  241.     {
  242.         HTREEITEM htiParentFrame;
  243.         if (frm->parent != NULL)
  244.             htiParentFrame = GetTreeItemForStackFrame(htiThread, frm->parent);
  245.         else
  246.             htiParentFrame = TVI_FIRST;
  247.         htiFrame = AddTreeItemForID(htiThread, htiParentFrame, frm);
  248.     }
  249.     if (htiFrame == NULL)
  250.         htiFrame = htiThread;
  251.     return htiFrame;
  252. }
  253.  
  254.  
  255. HTREEITEM HeapViewer::GetTreeItemForStackFrame (STACKID frm)
  256. {
  257.     HTREEITEM htiThread;
  258.     if (frm->thd != NULL)
  259.         htiThread = GetTreeItemForThread(frm->thd);
  260.     else
  261.         htiThread = GetRootForThreads();
  262.     return GetTreeItemForStackFrame(htiThread, frm);
  263. }
  264.  
  265.  
  266. HTREEITEM HeapViewer::GetTreeItemForID (ID id)
  267. {
  268.     HTREEITEM hti = NULL;
  269.  
  270.     switch (id->type)
  271.     {
  272.     case ID_CLASS:
  273.         hti = GetTreeItemForClass((CLASSID)id);
  274.         break;
  275.  
  276.     case ID_THREAD:
  277.     case ID_GHOST_THREAD:
  278.         hti = GetTreeItemForThread((THREADID)id);
  279.         break;
  280.  
  281.     case ID_PACKAGE:
  282.         hti = GetRootForPackage((PKGID)id);
  283.         break;
  284.  
  285.     case ID_ROOT:
  286.         hti = GetTreeItemForRoot((ROOTID)id);
  287.         break;
  288.  
  289.     case ID_STACKFRAME:
  290.         hti = GetTreeItemForStackFrame((STACKID)id);
  291.         break;
  292.  
  293.     default:
  294.         ASSERT(!"Unknown id type");
  295.     }
  296.  
  297.     return hti;
  298. }
  299.  
  300.  
  301. HTREEITEM HeapViewer::AddNewThread (THREADID thd)
  302. {
  303.     return AddTreeItemForID(GetRootForThreads(), thd);
  304. }
  305.  
  306.  
  307. BOOL HeapViewer::AddRootReferences (RootReferencesEventInfo *pinfo)
  308. {
  309.     HTREEITEM htiroot = GetTreeItemForID(pinfo->rootid);
  310.     if (htiroot == NULL)
  311.         htiroot = GetRootForRoots();
  312.  
  313.     unsigned nrefs = pinfo->nrefs;
  314.     const ObjectID *rgrefs = pinfo->rgrefs;
  315.  
  316.     for (unsigned i = 0; i < nrefs; i++)
  317.     {
  318.         ObjectID vmid = rgrefs[i];
  319.         if (vmid != NULL)
  320.         {
  321.             // TODO: have the manager pump these over to avoid redundant lookups
  322.  
  323.             OBJID id = (OBJID)m_mgr->LookupID(vmid);
  324.             if (id == NULL)
  325.                 AddTreeItemForObject(htiroot, vmid);
  326.             else
  327.                 AddTreeItemForReferencedID(htiroot, id);
  328.         }
  329.     }
  330.     
  331.     return TRUE;
  332. }
  333.  
  334.  
  335. HeapViewer::HeapViewer ()
  336. {
  337.     m_htiClasses = NULL;
  338.     m_htiThreads = NULL;
  339.     m_htiObjects = NULL;
  340.     m_htiRoots = NULL;
  341.  
  342.     m_fStopped = FALSE;
  343. }
  344.  
  345.  
  346. BOOL HeapViewer::Initialize (HeapMonitorManager *mgr)
  347. {
  348.     BOOL result;
  349.  
  350.     result = OVPreInitialize(mgr, "Heap Viewer");
  351.     
  352.     if (result)
  353.     {
  354.         Enter();
  355.         {
  356.             m_fStopped = mgr->IsStopped_Safe();
  357.  
  358.             HeapMonitorClientRegistrationInfo reginfo;
  359.             ZeroMemory(®info, sizeof(reginfo));
  360.  
  361.             reginfo.EventMask = HMC_CLASS_EVENTS | HMC_THREAD_EVENTS;
  362.             reginfo.StoppedEventMask = HMC_ROOT_EVENTS | HMC_HEAP_EVENTS;
  363.             
  364.             result = OVPostInitialize(®info);
  365.  
  366.             if (result)
  367.             {
  368.                 mgr->IterateIDs_Safe(&PopulateTreeCB, this);
  369.  
  370.                 if (m_fStopped)
  371.                 {
  372.                     mgr->IterateKnownRootReferences(&PopulateRootObjectsCB, this);
  373.                 }
  374.             }
  375.         }
  376.         Leave();
  377.     }
  378.  
  379.     return result;
  380. }
  381.  
  382.