size_t AVMPI_getPrivateResidentPageCount() { size_t pageSize = VMPI_getVMPageSize(); if(pageSize > 0) { TInt freeRAM; HAL::Get(HAL::EMemoryRAMFree, freeRAM); return freeRAM/pageSize; } else { return 0; } }
size_t AVMPI_getPrivateResidentPageCount() { void *addr = 0; size_t bytes=0; MEMORY_BASIC_INFORMATION mib; while(true) { size_t ret = VirtualQuery(addr, &mib, sizeof(MEMORY_BASIC_INFORMATION)); if(ret == 0) break; if((mib.State & MEM_COMMIT) && (mib.Type & MEM_PRIVATE)) bytes += mib.RegionSize; addr = (void*) ((intptr_t)mib.BaseAddress + mib.RegionSize); } return bytes / VMPI_getVMPageSize(); }
void* AVMPI_allocateAlignedMemory(size_t size) { char *ptr, *ptr2, *aligned_ptr; size_t align_size = VMPI_getVMPageSize(); size_t align_mask = align_size - 1; size_t alloc_size = size + align_size + sizeof(int); ptr = (char *)malloc(alloc_size); if(ptr==NULL) return(NULL); ptr2 = ptr + sizeof(int); aligned_ptr = ptr2 + (align_size - ((size_t)ptr2 & align_mask)); ptr2 = aligned_ptr - sizeof(int); *((int *)ptr2)=(int)(aligned_ptr - ptr); return(aligned_ptr); }
void *AVMPI_allocateCodeMemory(size_t nbytes) { MMgc::GCHeap* heap = MMgc::GCHeap::GetGCHeap(); size_t pagesize = VMPI_getVMPageSize(); if (nbytes % pagesize != 0) { #ifdef DEBUG char buf[256]; VMPI_snprintf(buf, sizeof(buf), "AVMPI_allocateCodeMemory invariants violated: request=%lu pagesize=%lu\nAborting.\n", (unsigned long)nbytes, (unsigned long)pagesize); VMPI_log(buf); #endif VMPI_abort(); } size_t nblocks = nbytes / MMgc::GCHeap::kBlockSize; heap->SignalCodeMemoryAllocation(nblocks, true); return heap->Alloc(nblocks, MMgc::GCHeap::flags_Alloc, pagesize/MMgc::GCHeap::kBlockSize); }
void AVMPI_makeCodeMemoryExecutable(void *address, size_t nbytes, bool makeItSo) { size_t pagesize = VMPI_getVMPageSize(); if ((uintptr_t)address % pagesize != 0 || nbytes % pagesize != 0) { #ifdef DEBUG char buf[256]; VMPI_snprintf(buf, sizeof(buf), "AVMPI_makeCodeMemoryExecutable invariants violated: address=%llu size=%llu pagesize=%llu\nAborting.\n", (unsigned long long)(uintptr_t)address, (unsigned long long)nbytes, (unsigned long long)pagesize); VMPI_log(buf); #endif VMPI_abort(); } DWORD oldProtectFlags = 0; DWORD newProtectFlags = 0; if ( makeItSo ) newProtectFlags = PAGE_EXECUTE_READ; else newProtectFlags = PAGE_READWRITE; BOOL retval; do { MEMORY_BASIC_INFORMATION mbi; VirtualQuery(address, &mbi, sizeof(MEMORY_BASIC_INFORMATION)); size_t markSize = nbytes > mbi.RegionSize ? mbi.RegionSize : nbytes; // handle multiple adjoining regions retval = VirtualProtect(address, markSize, newProtectFlags, &oldProtectFlags); AvmAssert(retval != 0); address = (char*) address + markSize; nbytes -= markSize; } while(nbytes != 0 && retval != 0); }
void AVMPI_makeCodeMemoryExecutable(void *address, size_t nbytes, bool makeItSo) { size_t pagesize = VMPI_getVMPageSize(); if ((uintptr_t)address % pagesize != 0 || nbytes % pagesize != 0) { #ifdef DEBUG char buf[256]; VMPI_snprintf(buf, sizeof(buf), "AVMPI_makeCodeMemoryExecutable invariants violated: address=%lu size=%lu pagesize=%lu\nAborting.\n", (unsigned long)address, (unsigned long)nbytes, (unsigned long)pagesize); VMPI_log(buf); #endif VMPI_abort(); } int flags = makeItSo ? PROT_EXEC|PROT_READ : PROT_WRITE|PROT_READ; int retval = mprotect((maddr_ptr)address, (unsigned int)nbytes, flags); AvmAssert(retval == 0); (void)retval; }
void AVMPI_freeCodeMemory(void* address, size_t nbytes) { MMgc::GCHeap* heap = MMgc::GCHeap::GetGCHeap(); size_t pagesize = VMPI_getVMPageSize(); size_t nblocks = heap->Size(address); size_t actualBytes = nblocks * MMgc::GCHeap::kBlockSize; if ((uintptr_t)address % pagesize != 0 || nbytes % pagesize != 0 || nbytes != actualBytes) { #ifdef DEBUG char buf[256]; VMPI_snprintf(buf, sizeof(buf), "AVMPI_freeCodeMemory invariants violated: address=%lu provided=%lu actual=%lu\nAborting.\n", (unsigned long)address, (unsigned long)nbytes, (unsigned long)actualBytes); VMPI_log(buf); #endif VMPI_abort(); } heap->Free(address); heap->SignalCodeMemoryDeallocated(nblocks, true); }
double ProgramClass::get_privateMemory() { return double(AVMPI_getPrivateResidentPageCount() * VMPI_getVMPageSize()); }
THIS WILL NOT WORK ON WINCE 6.0 AND ABOVE #endif #endif #ifdef UNDER_CE // The WinCE version of getPrivateResidentPageCount must do some specific things to get // an accurate picture of private bytes due to how WinCE lays out memory for the process. // see http://msdn.microsoft.com/en-us/library/bb331824.aspx for a desccription of how the memory is laid out. // Note that we are running on Windows Mobile 6.0, but that is based on WinCE 5.0. // Basically, first we walk the memory for the process slot, from 0x10000 to 0x2000000. Then we walk the memory // in the large memory area (0x42000000 - 0x80000000), as this is where gcheap allocates memory from. size_t AVMPI_getPrivateResidentPageCount() { void *addr = (void*)(0x00010000); void *endAddr = (void*)(0x02000000); size_t bytes=0; MEMORY_BASIC_INFORMATION mib; while(true) { size_t ret = VirtualQuery(addr, &mib, sizeof(MEMORY_BASIC_INFORMATION)); if(ret == 0) break; if((mib.State & MEM_COMMIT)) if ((DWORD)mib.BaseAddress + mib.RegionSize > (DWORD)endAddr) bytes += (DWORD)endAddr - (DWORD)mib.BaseAddress; else bytes += mib.RegionSize; addr = (void*) ((intptr_t)mib.BaseAddress + mib.RegionSize); if (addr>=endAddr) break; } MMgc::GCHeap* heap = MMgc::GCHeap::GetGCHeap(); // We need to also walk the shared memory regions to make sure we // count the blocks we've allocated there MMgc::GCHeap::Region* curRegion = heap->lastRegion; if (curRegion) addr = curRegion->baseAddr; else addr = NULL; while (curRegion!=NULL) { addr = curRegion->baseAddr; if (addr < (void*)0x42000000) { // Not in the shared regions curRegion = curRegion->prev; continue; } while(true) { size_t ret = VirtualQuery(addr, &mib, sizeof(MEMORY_BASIC_INFORMATION)); if(ret == 0) break; if((mib.State & MEM_COMMIT)) // && (mib.Type & MEM_PRIVATE)) { if ((DWORD)mib.BaseAddress + mib.RegionSize > (DWORD)curRegion->reserveTop) bytes += (DWORD)curRegion->reserveTop - (DWORD)mib.BaseAddress; else bytes += mib.RegionSize; } addr = (void*) ((intptr_t)mib.BaseAddress + mib.RegionSize); if (addr>=curRegion->reserveTop) break; } curRegion = curRegion->prev; } return bytes / VMPI_getVMPageSize(); }