home *** CD-ROM | disk | FTP | other *** search
- // clsview.cpp
- //
- // Created 10/05/98
- //
- // (C)Copyright 1998-1999 Microsoft Corporation, All rights reserved.
- //
-
- #include "pch.hpp"
- #pragma hdrstop
-
- #include "clsview.hpp"
- #include "hpmonmgr.hpp"
-
-
- BOOL ClassListViewer::s_fRegisteredClass = FALSE;
-
-
- //static
- LRESULT CALLBACK ClassListViewer::WndProc (HWND wnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- ClassListViewer *clv = (ClassListViewer*)GetWindowLong(wnd, GWL_USERDATA);
-
- switch (msg)
- {
- case WM_SIZE:
- {
- RECT rc;
- GetClientRect(wnd, &rc);
- MoveWindow(clv->m_list, rc.left, rc.top, rc.right, rc.bottom, TRUE);
- }
- break;
-
- case WM_NOTIFY:
- {
- //int idCtrl = (int)wParam;
- NMHDR *pnmh = (NMHDR*)lParam;
-
- switch (pnmh->code)
- {
- case LVN_GETDISPINFO:
- {
- NMLVDISPINFO *pnmv = (NMLVDISPINFO*)lParam;
- LVITEM *pitem = &pnmv->item;
-
- if (pitem->mask & LVIF_TEXT)
- {
- ClassDataSnapshot *pdata = NULL;
-
- if (pitem->mask & LVIF_PARAM)
- {
- pdata = (ClassDataSnapshot*)pitem->lParam;
- }
- else
- {
- LVITEM lvi;
- lvi.mask = LVIF_PARAM;
- lvi.iItem = pitem->iItem;
- lvi.iSubItem = 0;
- if (ListView_GetItem(clv->m_list, &lvi))
- pdata = (ClassDataSnapshot*)pitem->lParam;
- }
-
- if (pdata != NULL)
- {
- int col = pitem->iSubItem;
- switch (col)
- {
- case CLV_COL_CLASSNAME:
- {
- PCSTR clsname = clv->m_mgr->FetchIDFriendlyName(pdata->id);
- if (clsname != NULL)
- {
- FitText(pitem->pszText, pitem->cchTextMax, clsname);
- return 0;
- }
- }
- break;
-
- case CLV_COL_TOTALINSTANCES:
- FormatNumber(pitem->pszText, pitem->cchTextMax, "%I64u", pdata->totalinstances);
- return 0;
-
- case CLV_COL_LIVEINSTANCES:
- if (pdata->valid)
- FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", pdata->liveinstances);
- else
- FitText(pitem->pszText, pitem->cchTextMax, "<not available>");
- return 0;
-
- case CLV_COL_LIVESIZE:
- if (pdata->valid)
- FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", pdata->livesize);
- else
- FitText(pitem->pszText, pitem->cchTextMax, "<not available>");
- return 0;
-
- default:
- {
- col -= CLV_NUM_COLUMNS;
-
- if (clv->m_mgr->SupportsAllocatedSize())
- {
- if (col == 0)
- {
- if (pdata->valid)
- FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", pdata->totalsize);
- else
- FitText(pitem->pszText, pitem->cchTextMax, "<not available>");
- return 0;
- }
-
- col--;
- }
-
- if (clv->m_mgr->SupportsObjectAging())
- {
- if (col == 0)
- {
- if (pdata->valid)
- {
- if (pdata->liveinstances == 0)
- FitText(pitem->pszText, pitem->cchTextMax, "---");
- else
- FormatNumber(pitem->pszText, pitem->cchTextMax, "%u", pdata->agesum / pdata->liveinstances);
- }
- else
- {
- FitText(pitem->pszText, pitem->cchTextMax, "<not available>");
- }
- return 0;
- }
-
- col--;
- }
- }
- break;
- }
- }
- }
- }
- break;
-
- case LVN_COLUMNCLICK:
- {
- NMLISTVIEW *pnmlv = (NMLISTVIEW*)lParam;
- if (pnmlv->iSubItem == clv->m_sortcol)
- {
- clv->m_sortdir = -clv->m_sortdir;
- }
- else
- {
- clv->m_sortcol = pnmlv->iSubItem;
- if (pnmlv->iSubItem == 0)
- clv->m_sortdir = 1;
- else
- clv->m_sortdir = -1;
- }
-
- ListView_SortItems(clv->m_list, &SortColumnCB, clv);
-
- return 0;
- }
- break;
- }
- }
- break;
-
- case CVWM_SNAPSHOT: {
- int nitems = ListView_GetItemCount(clv->m_list);
- for (int iitem = 0; iitem < nitems; iitem++)
- {
- LVITEM lvi;
- lvi.iItem = iitem;
- lvi.iSubItem = 0;
- lvi.mask = LVIF_PARAM;
- if (ListView_GetItem(clv->m_list, &lvi))
- {
- ClassDataSnapshot *pdata = (ClassDataSnapshot*)lvi.lParam;
- ASSERT(pdata);
-
- clv->UpdateClassData(pdata);
- }
- }
- break; }
- }
-
- return clv->BaseWndProc(wnd, msg, wParam, lParam);
- }
-
-
- BOOL ClassListViewer::OnCreateWindow ()
- {
- BOOL result;
-
- HINSTANCE hinst = m_mgr->GetInstance();
-
- RECT rc;
-
- GetClientRect(m_hwnd, &rc);
-
- result = (m_list = CreateWindow(
- WC_LISTVIEW,
- NULL,
- WS_CHILD | LVS_REPORT,
- rc.left, rc.top, rc.right, rc.bottom,
- m_hwnd,
- NULL,
- hinst,
- NULL)) != NULL;
-
- if (result)
- {
- static PSTR colnames[] = {
- "Class",
- "Total instances",
- "Live instances",
- "Live size",
- };
-
- unsigned nextracols = 0;
- if (m_mgr->SupportsAllocatedSize())
- nextracols++;
- if (m_mgr->SupportsObjectAging())
- nextracols++;
-
- unsigned ncols = CLV_NUM_COLUMNS + nextracols;
-
- unsigned spaceleft = rc.right - rc.left;
-
- LVCOLUMN lvc;
- lvc.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
- lvc.fmt = LVCFMT_CENTER;
-
- lvc.cx = spaceleft/3;
-
- unsigned i = 0;
- for (;;)
- {
- if (i < CLV_NUM_COLUMNS)
- {
- lvc.pszText = colnames[i];
- }
- else
- {
- unsigned extrai = i - CLV_NUM_COLUMNS;
- if (m_mgr->SupportsAllocatedSize())
- {
- if (extrai == 0)
- lvc.pszText = "total size allocated";
- extrai--;
- }
- if (m_mgr->SupportsObjectAging())
- {
- if (extrai == 0)
- lvc.pszText = "average age";
- extrai--;
- }
- }
-
- result = (ListView_InsertColumn(m_list, i, &lvc) != -1);
- if (!result)
- break;
-
- i++;
- if (i >= ncols)
- break;
- spaceleft -= lvc.cx;
- lvc.cx = spaceleft / (ncols-i);
- }
- }
-
- if (result)
- {
- m_mgr->IterateIDs(&PopulateListCB, this);
- }
-
- if (result)
- {
- ShowWindow(m_list, SW_SHOWNA);
- }
-
- return result;
- }
-
-
- //static
- int ClassListViewer::PopulateListCB (ID id, PVOID token)
- {
- ClassListViewer *clv = (ClassListViewer*)token;
-
- if (id->type == ID_CLASS)
- {
- clv->AddClass((CLASSID)id);
- }
-
- return 1;
- }
-
-
- BOOL ClassListViewer::AddClass (CLASSID cls)
- {
- ASSERT(m_mgr->CanSendUIMessages());
-
- BOOL result = FALSE;
-
- ClassDataSnapshot *pdata = new(ClassDataSnapshot());
- if (pdata)
- {
- ZeroMemory(pdata, sizeof(*pdata));
-
- pdata->id = cls;
-
- UpdateClassData(pdata);
-
- LVITEM lvi;
- lvi.mask = LVIF_PARAM | LVIF_TEXT;
- lvi.lParam = (LPARAM)pdata;
- lvi.pszText = LPSTR_TEXTCALLBACK;
- lvi.iItem = ListView_GetItemCount(m_list);
- lvi.iSubItem = 0;
- result = ListView_InsertItem(m_list, &lvi) != -1;
-
- if (!result)
- delete(pdata);
- }
-
- return result;
- }
-
-
- VOID ClassListViewer::UpdateClassData (ClassDataSnapshot *pdata)
- {
- CLASSID cls = pdata->id;
-
- __int64 totalinstances;
- IJavaEventMonitorIDInfo2 *vminfo = m_mgr->GetVMInfoInterface();
- if (vminfo->ClassInformation(cls->vmid, NULL, NULL, NULL, NULL, &totalinstances) == S_OK)
- {
- if (m_mgr->GetCurrentGCInfo() != NULL)
- ASSERT(totalinstances >= cls->liveinstances);
- pdata->totalinstances = totalinstances;
- }
- vminfo->Release();
-
- if (m_mgr->GetCurrentGCInfo())
- pdata->valid = TRUE;
-
- if (pdata->valid)
- {
- pdata->liveinstances = cls->liveinstances;
- pdata->livesize = cls->livesize;
- pdata->totalsize = cls->totalsize;
- pdata->liveinstances = cls->liveinstances;
- pdata->agesum = cls->agesum;
- }
- }
-
-
- //static
- int CALLBACK ClassListViewer::SortColumnCB (LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort)
- {
- ClassListViewer *clv = (ClassListViewer*)lParamSort;
- ClassDataSnapshot *pdata1 = (ClassDataSnapshot*)lParam1;
- ClassDataSnapshot *pdata2 = (ClassDataSnapshot*)lParam2;
-
- int cmp = 0;
-
- unsigned col = clv->m_sortcol;
- switch (col)
- {
- case CLV_COL_CLASSNAME:
- {
- PCSTR clsname1 = clv->m_mgr->FetchIDFriendlyName(pdata1->id);
- PCSTR clsname2 = clv->m_mgr->FetchIDFriendlyName(pdata2->id);
- if (clsname1 != NULL && clsname2 != NULL)
- cmp = strcmp(clsname1, clsname2);
- }
- break;
-
- case CLV_COL_TOTALINSTANCES:
- __int64 diff;
- diff = pdata1->totalinstances - pdata2->totalinstances;
- if (diff > 0)
- cmp = 1;
- else if (diff == 0)
- cmp = 0;
- else
- cmp = -1;
- break;
-
- case CLV_COL_LIVEINSTANCES:
- if (pdata1->valid && pdata2->valid)
- cmp = pdata1->liveinstances - pdata2->liveinstances;
- break;
-
- case CLV_COL_LIVESIZE:
- if (pdata1->valid && pdata2->valid)
- cmp = pdata1->livesize - pdata2->livesize;
- break;
-
- default:
- col -= CLV_NUM_COLUMNS;
-
- if (clv->m_mgr->SupportsAllocatedSize())
- {
- if (col == 0)
- {
- if (pdata1->valid && pdata2->valid)
- cmp = pdata1->totalsize - pdata2->totalsize;
-
- break;
- }
-
- col--;
- }
-
- if (clv->m_mgr->SupportsObjectAging())
- {
- if (col == 0)
- {
- if (pdata1->valid && pdata2->valid)
- {
- unsigned age1 = 0;
- unsigned age2 = 0;
- if (pdata1->liveinstances != 0)
- age1 = pdata1->agesum / pdata1->liveinstances;
- if (pdata2->liveinstances != 0)
- age2 = pdata2->agesum / pdata2->liveinstances;
- cmp = age1 - age2;
- }
-
- break;
- }
-
- col--;
- }
- }
-
- return cmp * clv->m_sortdir;
- }
-
-
- BOOL ClassListViewer::Initialize (HeapMonitorManager *mgr)
- {
- BOOL result = TRUE;
-
- if (!s_fRegisteredClass)
- {
- WNDCLASS wc;
- ZeroMemory(&wc, sizeof(wc));
- wc.lpfnWndProc = &WndProc;
- wc.hInstance = mgr->GetInstance();
- wc.lpszClassName = WC_HEAPMONITOR_CLASSLISTVIEWER;
- wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- result = RegisterClass(&wc);
-
- s_fRegisteredClass = result;
- }
-
- if (result)
- {
- HeapMonitorClientRegistrationInfo reginfo;
- ZeroMemory(®info, sizeof(reginfo));
-
- reginfo.EventMask = HMC_CLASS_EVENTS | HMC_HEAP_EVENTS;
- reginfo.StoppedEventMask = HMC_HEAP_EVENTS;
- reginfo.StoppedInfoMask = HMC_INFO_HEAP_OBJECTS;
-
- result = BaseInitialize(mgr, WC_HEAPMONITOR_CLASSLISTVIEWER, "Per-Class Info", ®info);
- }
-
- return result;
- }
-
-