home *** CD-ROM | disk | FTP | other *** search
- // allocprf.cpp
- //
- // Created 01/19/99
- //
- // (C) Copyright 1995 - 1999 Microsoft Corporation. All rights reserved.
- //
-
- #include "project.hpp"
- #pragma hdrstop
-
- #include <jevmon.h>
-
- #include "allocprf.hpp"
- #include "jviewprf.hpp"
- #include "utils.hpp"
-
-
- HRESULT AllocationProfiler::Initialize (EventMonitor *pmon)
- {
- (m_pmon = pmon)->AddRef();
-
- return S_OK;
- }
-
- VOID AllocationProfiler::Destruct ()
- {
- Iterate(&AllocationProfiler::DeleteCB);
-
- DeleteCriticalSection(&m_cs);
-
- if (m_pmon)
- m_pmon->Release();
- }
-
-
- //static
- int AllocationProfiler::DeleteCB (AllocationProfilerEntry *ent, PVOID token)
- {
- delete(ent);
- return 1;
- }
-
-
- //static
- int AllocationProfiler::ComputeTotalsCB (AllocationProfilerEntry *cur, PVOID token)
- {
- AllocationProfilerEntry *firstcls = cur->firstcls;
- if (firstcls)
- {
- firstcls->nAlloc += cur->nAlloc;
- firstcls->cbAlloc += cur->cbAlloc;
- }
-
- return 1;
- }
-
-
- #define WIDTH_CLASS_NTOTAL 5
- #define WIDTH_CLASS_CBTOTAL 7
- #define WIDTH_CLASS_NPERGC 4
- #define WIDTH_CLASS_CBPERGC 6
- #define WIDTH_CLASS_PCTN 3
- #define WIDTH_CLASS_PCTCB 3
-
- #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+1+WIDTH_CLASS_PCTCB+1)
-
-
- //static
- int AllocationProfiler::SpewTotalsCB (AllocationProfilerEntry *cur, PVOID token)
- {
- if (!cur->firstcls)
- {
- PSTR pszNameUtf8;
- __int64 nTotalAllocated;
- if (SUCCEEDED(m_pmon->GetVMInfoIfc()->ClassInformation(cur->id, &pszNameUtf8, NULL, NULL, NULL, &nTotalAllocated)))
- {
- if (nTotalAllocated != cur->nAlloc)
- {
- WriteOutput("warning: count mismatch for ");
- WriteOutputUtf8(pszNameUtf8);
- WriteOutputFmt(", VM recorded %u instances but only reported %u allocations\n", (ULONG)nTotalAllocated, cur->nAlloc);
- }
-
- WriteOutputFitString(WRITE_FIT | WRITE_WRAP | WRITE_UTF8 | WRITE_SPACE, TOTAL_CLASS_FIXED_WIDTH, 100, pszNameUtf8);
-
- ULONG npergc = cur->nAlloc / m_iGC;
- ULONG cbpergc = cur->cbAlloc / m_iGC;
-
- unsigned pctnoverall = 0;
- if (m_nTotalAlloc)
- pctnoverall = cur->nAlloc*100 / m_nTotalAlloc;
-
- unsigned pctcboverall = 0;
- if (m_cbTotalAlloc)
- pctcboverall = cur->cbAlloc*100 / m_cbTotalAlloc;
-
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_NTOTAL, cur->nAlloc);
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_CBTOTAL, cur->cbAlloc);
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_NPERGC, npergc);
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_CBPERGC, cbpergc);
- WriteOutputColumnFmt(WRITE_RIGHT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_PCTN, "%u%%", pctnoverall);
- WriteOutputColumnFmt(WRITE_RIGHT_JUSTIFIED | WRITE_NEWLINE, WIDTH_CLASS_PCTCB, "%u%%", pctcboverall);
-
- CoTaskMemFree(pszNameUtf8);
- }
- }
-
- return 1;
- }
-
-
- #define PCT_WIDTH_METHOD_LOCATION 66
- #define PCT_WIDTH_METHOD_TYPE 33
-
- #define WIDTH_METHOD_NTOTAL 5
- #define WIDTH_METHOD_CBTOTAL 7
- #define WIDTH_METHOD_NPERGC 4
- #define WIDTH_METHOD_CBPERGC 6
- #define WIDTH_METHOD_PCTN 3
- #define WIDTH_METHOD_PCTCB 3
-
- #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+1+WIDTH_METHOD_PCTCB+1)
-
-
- //static
- int AllocationProfiler::SpewMethodsCB (AllocationProfilerEntry *cur, PVOID token)
- {
- if (cur->loc)
- {
- PSTR pszTypeNameUtf8;
- if (SUCCEEDED(m_pmon->GetVMInfoIfc()->ClassInformation(cur->id, &pszTypeNameUtf8, NULL, NULL, NULL, NULL)))
- {
- PSTR pszLocationNameUtf8;
- if (SUCCEEDED(m_pmon->GetVMInfoIfc()->MethodInformation(cur->loc, &pszLocationNameUtf8, NULL, NULL, NULL, NULL)))
- {
- WriteOutputExArgs args;
-
- args.Width = TOTAL_METHOD_FIXED_WIDTH;
-
- args.PctFreeSpaceToUse = PCT_WIDTH_METHOD_LOCATION;
- args.PctFreeSpaceUsed = 0;
- args.FixedSpaceUsed = 0;
-
- WriteOutputEx(WRITE_FIT | WRITE_WRAP | WRITE_UTF8 | WRITE_SPACE, &args, pszLocationNameUtf8);
-
- args.PctFreeSpaceToUse = PCT_WIDTH_METHOD_TYPE;
- args.PctFreeSpaceUsed = PCT_WIDTH_METHOD_LOCATION;
- args.FixedSpaceUsed = 1;
-
- WriteOutputEx(WRITE_FIT | WRITE_WRAP | WRITE_UTF8 | WRITE_SPACE, &args, pszTypeNameUtf8);
-
- ULONG npergc = cur->nAlloc / m_iGC;
- ULONG cbpergc = cur->cbAlloc / m_iGC;
-
- unsigned pctnoverall = 0;
- if (m_nTotalAlloc)
- pctnoverall = cur->nAlloc*100 / m_nTotalAlloc;
-
- unsigned pctcboverall = 0;
- if (m_cbTotalAlloc)
- pctcboverall = cur->cbAlloc*100 / m_cbTotalAlloc;
-
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_NTOTAL, cur->nAlloc);
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_CBTOTAL, cur->cbAlloc);
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_NPERGC, npergc);
- WriteOutputColumnULONG(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_CBPERGC, cbpergc);
-
- args.Width = WIDTH_METHOD_PCTN;
-
- WriteOutputFmtEx(WRITE_RIGHT_JUSTIFIED | WRITE_SPACE, &args, "%u%%", pctnoverall);
-
- args.Width = WIDTH_METHOD_PCTCB;
-
- WriteOutputFmtEx(WRITE_RIGHT_JUSTIFIED | WRITE_NEWLINE, &args, "%u%%", pctcboverall);
-
- CoTaskMemFree(pszLocationNameUtf8);
- }
-
- CoTaskMemFree(pszTypeNameUtf8);
- }
- }
-
- return 1;
- }
-
-
- int AllocationProfiler::Iterate (POBJITERFN fn, PVOID token)
- {
- int res = 1;
-
- for (unsigned i = 0; i < ARRAY_ELEMENTS(m_hash); i++)
- {
- AllocationProfilerEntry *cur = m_hash[i];
- while (cur != NULL)
- {
- AllocationProfilerEntry *next = cur->next;
- res = (this->*fn)(cur, token);
- if (res <= 0)
- break;
- cur = next;
- }
- }
-
- return res;
- }
-
-
- VOID AllocationProfiler::SpewResults ()
- {
- if (!(g_ProfOptions & OPT_PROF_ALLOC))
- return;
-
- WriteOutputFmt("Allocations:\n" "%u objects\n" "%u bytes\n", m_nTotalAlloc, m_cbTotalAlloc);
-
- if (g_ProfOptions & OPT_ALLOC_PER_METHOD)
- {
- if (g_OutputWidth)
- {
- WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_METHOD_FIXED_WIDTH, 100, "");
- WriteOutputColumnString(WRITE_CENTERED | WRITE_SPACE, WIDTH_METHOD_NTOTAL+1+WIDTH_METHOD_CBTOTAL, "Total");
- WriteOutputColumnString(WRITE_CENTERED | WRITE_SPACE, WIDTH_METHOD_NPERGC+1+WIDTH_METHOD_CBPERGC, "Per GC");
- WriteOutputColumnString(WRITE_CENTERED | WRITE_NEWLINE, WIDTH_METHOD_PCTN+1+WIDTH_METHOD_PCTCB, "Overall");
-
- WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_METHOD_FIXED_WIDTH, PCT_WIDTH_METHOD_LOCATION, "Method");
- WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_METHOD_FIXED_WIDTH, PCT_WIDTH_METHOD_TYPE, "Type");
-
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_NTOTAL, "Num");
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_CBTOTAL, "Bytes");
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_NPERGC, "Num");
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_METHOD_CBPERGC, "Bytes");
- WriteOutputColumnString(WRITE_CENTERED | WRITE_NEWLINE, WIDTH_METHOD_PCTN+1+WIDTH_METHOD_PCTCB, "#/Bytes");
- }
- else
- {
- WriteOutput("Method Type Total Bytes PerGCTotal PerGCBytes PctOverallTotal PctOverallBytes\n");
- }
-
- Iterate(&AllocationProfiler::SpewMethodsCB);
- }
-
- if (g_ProfOptions & OPT_ALLOC_PER_CLASS)
- {
- if (g_ProfOptions & OPT_ALLOC_PER_METHOD)
- {
- Iterate(&AllocationProfiler::ComputeTotalsCB);
- }
-
- WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_CLASS_FIXED_WIDTH, 100, "");
- WriteOutputColumnString(WRITE_CENTERED | WRITE_SPACE, WIDTH_CLASS_NTOTAL+1+WIDTH_CLASS_CBTOTAL, "Total");
- WriteOutputColumnString(WRITE_CENTERED | WRITE_SPACE, WIDTH_CLASS_NPERGC+1+WIDTH_CLASS_CBPERGC, "Per GC");
- WriteOutputColumnString(WRITE_CENTERED | WRITE_NEWLINE, WIDTH_CLASS_PCTN+2+WIDTH_CLASS_PCTCB+1, "Overall");
-
- WriteOutputFitString(WRITE_FIT | WRITE_SPACE, TOTAL_CLASS_FIXED_WIDTH, 100, "Type");
-
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_NTOTAL, "Num");
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_CBTOTAL, "Bytes");
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_NPERGC, "Num");
- WriteOutputColumnString(WRITE_LEFT_JUSTIFIED | WRITE_SPACE, WIDTH_CLASS_CBPERGC, "Bytes");
- WriteOutputColumnString(WRITE_CENTERED | WRITE_NEWLINE, WIDTH_CLASS_PCTN+2+WIDTH_CLASS_PCTCB+1, "#/Bytes");
-
- Iterate(&AllocationProfiler::SpewTotalsCB);
- }
- }
-
-
- VOID AllocationProfiler::InstanceCreated (ClassID idType, size_t size, MethodID idCreatingMethod)
- {
- EnterCriticalSection(&m_cs);
- {
- m_nTotalAlloc++;
- m_cbTotalAlloc += size;
-
- AllocationProfilerEntry *pent = LookupObject(idType, idCreatingMethod);
- if (pent)
- {
- pent->nAlloc++;
- pent->cbAlloc += size;
- }
- }
- LeaveCriticalSection(&m_cs);
- }
-
-
-
-