POBJECT ObjectMemory::basicResize(POTE ote, MWORD byteSize, int extra) { ASSERT(!isIntegerObject(ote)); POBJECT pObject; /* #ifdef _DEBUG TRACESTREAM << "Resizing "; Interpreter::printObject(Oop(ote), TRACESTREAM); TRACESTREAM << " (" << ote->m_location << ") from size " << ObjectMemory::sizeOf(ote) << " to size " << byteSize << "\n"; #endif */ switch(ote->heapSpace()) { case OTEFlags::NormalSpace: { // TRACE("Resizing normal object...\n"); pObject = ote->m_location; pObject = reallocChunk(pObject, byteSize+extra); if (pObject) { ote->m_location = pObject; ote->setSize(byteSize); } break; } case OTEFlags::VirtualSpace: // TRACE("Resizing virtual object...\n"); pObject = resizeVirtual(ote, byteSize+extra); break; case OTEFlags::PoolSpace: { #if defined(_DEBUG) if (abs(Interpreter::executionTrace) > 0) checkPools(); #endif // May be able to do some quicker resizing here if size is still in same pool? if ((byteSize+extra) > MaxSmallObjectSize) { pObject = allocChunk(byteSize+extra); ote->m_flags.m_space = OTEFlags::NormalSpace; } else pObject = allocSmallChunk(byteSize+extra); POBJECT pOldObject = ote->m_location; MWORD oldSize = ote->getSize(); memcpy(pObject, pOldObject, min(oldSize, byteSize)); freeSmallChunk(pOldObject, ote->sizeOf()); ote->m_location = pObject; ote->setSize(byteSize); break; } default: // Not resizeable return NULL; } #if defined(_DEBUG) if (abs(Interpreter::executionTrace) > 0) checkPools(); // TRACESTREAM << "After Resize: "; // Interpreter::printObject(Oop(ote), TRACESTREAM); // TRACESTREAM << "\n"; #endif return pObject; }
void ObjectMemory::DumpStats() { tracelock lock(TRACESTREAM); TRACESTREAM << std::endl<< L"Object Memory Statistics:" << std::endl << L"------------------------------" << std::endl; CheckPoint(); _CrtMemDumpStatistics(&CRTMemState); #ifdef _DEBUG checkPools(); #endif TRACESTREAM << std::endl<< L"Pool Statistics:" << std::endl << L"------------------" << std::endl << std::dec << NumPools<< L" pools in the interval (" << m_pools[0].getSize()<< L" to: " << m_pools[NumPools-1].getSize()<< L" by: " << PoolGranularity << L')' << std::endl << std::endl; int pageWaste=0; int totalPages=0; int totalFreeBytes=0; int totalChunks=0; int totalFreeChunks=0; for (int i=0;i<NumPools;i++) { int nSize = m_pools[i].getSize(); int perPage = dwPageSize/nSize; int wastePerPage = dwPageSize - (perPage*nSize); int nPages = m_pools[i].getPages(); int nChunks = perPage*nPages; int waste = nPages*wastePerPage; int nFree = m_pools[i].getFree(); TRACE(L"%d: size %d, %d objects on %d pgs (%d per pg, %d free), waste %d (%d per page)\n", i, nSize, nChunks-nFree, nPages, perPage, nFree, waste, wastePerPage); totalChunks += nChunks; pageWaste += waste; totalPages += nPages; totalFreeBytes += nFree*nSize; totalFreeChunks += nFree; } int objectWaste = 0; int totalObjects = 0; const OTE* pEnd = m_pOT+m_nOTSize; for (OTE* ote=m_pOT; ote < pEnd; ote++) { if (!ote->isFree()) { totalObjects++; if (ote->heapSpace() == OTEFlags::PoolSpace) { int size = ote->sizeOf(); int chunkSize = _ROUND2(size, PoolGranularity); objectWaste += chunkSize - size; } } } int wastePercentage = (totalChunks - totalFreeChunks) == 0 ? 0 : int(double(objectWaste)/ double(totalChunks-totalFreeChunks)*100.0); TRACESTREAM<< L"===============================================" << std::endl; TRACE(L"Total objects = %d\n" "Total pool objs = %d\n" "Total chunks = %d\n" "Total Pages = %d\n" "Total Allocs = %d\n" "Total allocated = %d\n" "Page Waste = %d bytes\n" "Object Waste = %d bytes (avg 0.%d)\n" "Total Waste = %d\n" "Total free chks = %d\n" "Total Free = %d bytes\n", totalObjects, totalChunks-totalFreeChunks, totalChunks, totalPages, FixedSizePool::m_nAllocations, totalPages*dwPageSize, pageWaste, objectWaste, wastePercentage, pageWaste+objectWaste, totalFreeChunks, totalFreeBytes); }