home *** CD-ROM | disk | FTP | other *** search
- // heapview.cpp
- //
- // Created 10/04/98
- //
- // (C)Copyright 1998-1999 Microsoft Corporation, All rights reserved.
- //
-
- #include "pch.hpp"
- #pragma hdrstop
-
- #include "heapview.hpp"
- #include "resource.h"
-
-
- LRESULT CALLBACK HeapViewer::WndProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_HVEVENT_THREAD_CREATED:
- {
- THREADID thd = (THREADID)lParam;
- AddNewThread(thd);
- }
- return 0;
-
- case WM_HVEVENT_NEW_PACKAGE:
- {
- PKGID pkg = (PKGID)lParam;
- AddTreeItemForID(GetRootForPackage(pkg->parent), pkg);
- }
- return 0;
-
- case WM_HVEVENT_THREAD_DESTROYED:
- {
- THREADID thd = (THREADID)lParam;
- HTREEITEM htiThread = FindChildItemForID(m_htiThreads, thd);
- if (htiThread)
- {
- TV_ITEM tvi;
- CHAR buf[256];
- tvi.hItem = htiThread;
- tvi.mask = TVIF_TEXT;
- tvi.pszText = &buf[0];
- tvi.cchTextMax = sizeof(buf);
-
- PSTR pszText = NULL;
-
- if (TreeView_GetItem(m_htree, &tvi) && (tvi.mask & TVIF_TEXT))
- {
- pszText = &buf[0];
- }
-
- tvi.mask = (TVIF_IMAGE | TVIF_TEXT | TVIF_PARAM);
- tvi.iImage = HVTII_DEAD_THREAD;
- tvi.lParam = NULL;
-
- if (!pszText || !TreeView_SetItem(m_htree, &tvi))
- {
- DeleteTreeItem(htiThread);
- }
-
- ASSERT(!FindChildItemForID(m_htiThreads, thd));
- }
- }
- return 0;
-
- case WM_HVEVENT_CLASS_LOADED:
- {
- CLASSID cls = (CLASSID)lParam;
- AddTreeItemForID(GetRootForPackage(cls->pkg), cls);
- }
- return 0;
-
- case WM_HVEVENT_CLASS_UNLOADED:
- // TODO
- return 0;
-
- case WM_HVEVENT_ROOT_REFERENCES:
- AddRootReferences((RootReferencesEventInfo*)lParam);
- return 0;
- }
-
- return ObjectViewer::WndProc(wnd, msg, wParam, lParam);
- }
-
-
- //static
- int HeapViewer::PopulateTreeCB (ID id, PVOID token)
- {
- HeapViewer *hv = (HeapViewer*)token;
-
- ASSERT(hv->Entered());
- ASSERT(hv->m_mgr->CanSendUIMessages());
-
- if (id->type != ID_OBJECT && (hv->m_fStopped || id->type < ID_FIRST_TRANSIENT))
- {
- HTREEITEM htiroot = hv->GetTreeItemForID(id);
-
- if (htiroot == NULL)
- {
- // TODO: indicate that tree is incomplete
- }
- }
-
- return 1;
- }
-
-
- //static
- int HeapViewer::PopulateRootObjectsCB (ID id, ObjectID refvmid, PVOID token)
- {
- HeapViewer *hv = (HeapViewer*)token;
-
- HTREEITEM hti = hv->GetTreeItemForID(id);
- if (hti != NULL)
- {
- OBJID refid = (OBJID)hv->m_mgr->LookupID(refvmid);
- if (refid != NULL)
- hv->AddTreeItemForReferencedID(hti, refid);
- else
- hv->AddTreeItemForObject(hti, refvmid);
- }
-
- return 1;
- }
-
-
- // TODO: if have to substitute an "outer" container or TVI_ROOT, indicate
- // that tree is incomplete
-
-
- HTREEITEM HeapViewer::GetRootForThreads ()
- {
- HTREEITEM root;
-
- root = m_htiThreads;
- if (root == NULL)
- root = CreateRoot(&m_htiThreads, "Threads", HVTII_FOLDER);
-
- return root;
- }
-
-
- HTREEITEM HeapViewer::GetRootForClasses ()
- {
- HTREEITEM root;
-
- root = m_htiClasses;
- if (root == NULL)
- root = CreateRoot(&m_htiClasses, "Classes", HVTII_FOLDER);
-
- return root;
- }
-
-
- HTREEITEM HeapViewer::GetRootForPackage (PKGID pkg)
- {
- if (pkg == NULL)
- return GetRootForClasses();
-
- HTREEITEM htiParent = GetRootForPackage(pkg->parent);
- if (htiParent == TVI_ROOT)
- return TVI_ROOT;
-
- HTREEITEM htipkg = FindChildItemForID(htiParent, pkg);
- if (htipkg != NULL)
- return htipkg;
-
- htipkg = AddTreeItemForID(htiParent, pkg);
- if (htipkg == NULL)
- htipkg = TVI_ROOT;
-
- return htipkg;
- }
-
-
- HTREEITEM HeapViewer::GetRootForObjects ()
- {
- HTREEITEM root;
-
- root = m_htiObjects;
- if (root == NULL)
- root = CreateRoot(&m_htiObjects, "Objects", HVTII_FOLDER);
-
- return root;
- }
-
-
- HTREEITEM HeapViewer::GetRootForRoots ()
- {
- HTREEITEM root;
-
- root = m_htiRoots;
- if (root == NULL)
- root = CreateRoot(&m_htiRoots, "Roots", HVTII_FOLDER);
-
- return root;
- }
-
-
- HTREEITEM HeapViewer::GetTreeItemForThread (THREADID thd)
- {
- HTREEITEM htithdroot = GetRootForThreads();
- HTREEITEM htithd = FindChildItemForID(htithdroot, thd);
- if (htithd == NULL)
- htithd = AddTreeItemForID(htithdroot, thd);
- if (htithd == NULL)
- htithd = htithdroot;
- return htithd;
- }
-
-
- HTREEITEM HeapViewer::GetTreeItemForClass (CLASSID cls)
- {
- HTREEITEM hticlsroot = GetRootForPackage(cls->pkg);
- HTREEITEM hticls = FindChildItemForID(hticlsroot, cls);
- if (hticls == NULL)
- hticls = AddTreeItemForID(hticlsroot, cls);
- if (hticls == NULL)
- hticls = hticlsroot;
- return hticls;
- }
-
-
- HTREEITEM HeapViewer::GetTreeItemForRoot (ROOTID root)
- {
- HTREEITEM htiroots = GetRootForRoots();
- HTREEITEM htiroot = FindChildItemForID(htiroots, root);
- if (htiroot == NULL)
- htiroot = AddTreeItemForID(htiroots, root);
- if (htiroot == NULL)
- htiroot = htiroots;
- return htiroot;
- }
-
-
- HTREEITEM HeapViewer::GetTreeItemForStackFrame (HTREEITEM htiThread, STACKID frm)
- {
- HTREEITEM htiFrame = FindChildItemForID(htiThread, frm);
- if (htiFrame == NULL)
- {
- HTREEITEM htiParentFrame;
- if (frm->parent != NULL)
- htiParentFrame = GetTreeItemForStackFrame(htiThread, frm->parent);
- else
- htiParentFrame = TVI_FIRST;
- htiFrame = AddTreeItemForID(htiThread, htiParentFrame, frm);
- }
- if (htiFrame == NULL)
- htiFrame = htiThread;
- return htiFrame;
- }
-
-
- HTREEITEM HeapViewer::GetTreeItemForStackFrame (STACKID frm)
- {
- HTREEITEM htiThread;
- if (frm->thd != NULL)
- htiThread = GetTreeItemForThread(frm->thd);
- else
- htiThread = GetRootForThreads();
- return GetTreeItemForStackFrame(htiThread, frm);
- }
-
-
- HTREEITEM HeapViewer::GetTreeItemForID (ID id)
- {
- HTREEITEM hti = NULL;
-
- switch (id->type)
- {
- case ID_CLASS:
- hti = GetTreeItemForClass((CLASSID)id);
- break;
-
- case ID_THREAD:
- case ID_GHOST_THREAD:
- hti = GetTreeItemForThread((THREADID)id);
- break;
-
- case ID_PACKAGE:
- hti = GetRootForPackage((PKGID)id);
- break;
-
- case ID_ROOT:
- hti = GetTreeItemForRoot((ROOTID)id);
- break;
-
- case ID_STACKFRAME:
- hti = GetTreeItemForStackFrame((STACKID)id);
- break;
-
- default:
- ASSERT(!"Unknown id type");
- }
-
- return hti;
- }
-
-
- HTREEITEM HeapViewer::AddNewThread (THREADID thd)
- {
- return AddTreeItemForID(GetRootForThreads(), thd);
- }
-
-
- BOOL HeapViewer::AddRootReferences (RootReferencesEventInfo *pinfo)
- {
- HTREEITEM htiroot = GetTreeItemForID(pinfo->rootid);
- if (htiroot == NULL)
- htiroot = GetRootForRoots();
-
- unsigned nrefs = pinfo->nrefs;
- const ObjectID *rgrefs = pinfo->rgrefs;
-
- for (unsigned i = 0; i < nrefs; i++)
- {
- ObjectID vmid = rgrefs[i];
- if (vmid != NULL)
- {
- // TODO: have the manager pump these over to avoid redundant lookups
-
- OBJID id = (OBJID)m_mgr->LookupID(vmid);
- if (id == NULL)
- AddTreeItemForObject(htiroot, vmid);
- else
- AddTreeItemForReferencedID(htiroot, id);
- }
- }
-
- return TRUE;
- }
-
-
- HeapViewer::HeapViewer ()
- {
- m_htiClasses = NULL;
- m_htiThreads = NULL;
- m_htiObjects = NULL;
- m_htiRoots = NULL;
-
- m_fStopped = FALSE;
- }
-
-
- BOOL HeapViewer::Initialize (HeapMonitorManager *mgr)
- {
- BOOL result;
-
- result = OVPreInitialize(mgr, "Heap Viewer");
-
- if (result)
- {
- Enter();
- {
- m_fStopped = mgr->IsStopped_Safe();
-
- HeapMonitorClientRegistrationInfo reginfo;
- ZeroMemory(®info, sizeof(reginfo));
-
- reginfo.EventMask = HMC_CLASS_EVENTS | HMC_THREAD_EVENTS;
- reginfo.StoppedEventMask = HMC_ROOT_EVENTS | HMC_HEAP_EVENTS;
-
- result = OVPostInitialize(®info);
-
- if (result)
- {
- mgr->IterateIDs_Safe(&PopulateTreeCB, this);
-
- if (m_fStopped)
- {
- mgr->IterateKnownRootReferences(&PopulateRootObjectsCB, this);
- }
- }
- }
- Leave();
- }
-
- return result;
- }
-
-