rdar://problem/21469556

Make sure that the memory report is correct for 64-bit devices.

llvm-svn: 240728
This commit is contained in:
Han Ming Ong 2015-06-25 23:39:56 +00:00
parent 520b45df84
commit 74c14819ce
3 changed files with 44 additions and 17 deletions

View File

@ -382,7 +382,11 @@ MachTask::GetProfileData (DNBProfileDataScanType scanType)
get_threads_profile_data(scanType, task, pid, threads_id, threads_name, threads_used_usec);
}
struct vm_statistics vm_stats;
#if defined (HOST_VM_INFO64_COUNT)
vm_statistics64_data_t vminfo;
#elif
struct vm_statistics vminfo;
#endif
uint64_t physical_memory;
mach_vm_size_t rprvt = 0;
mach_vm_size_t rsize = 0;
@ -391,7 +395,7 @@ MachTask::GetProfileData (DNBProfileDataScanType scanType)
mach_vm_size_t dirty_size = 0;
mach_vm_size_t purgeable = 0;
mach_vm_size_t anonymous = 0;
if (m_vm_memory.GetMemoryProfile(scanType, task, task_info, m_process->GetCPUType(), pid, vm_stats, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size, purgeable, anonymous))
if (m_vm_memory.GetMemoryProfile(scanType, task, task_info, m_process->GetCPUType(), pid, vminfo, physical_memory, rprvt, rsize, vprvt, vsize, dirty_size, purgeable, anonymous))
{
std::ostringstream profile_data_stream;
@ -444,6 +448,9 @@ MachTask::GetProfileData (DNBProfileDataScanType scanType)
if (scanType & eProfileMemory)
{
#if defined (HOST_VM_INFO64_COUNT)
static vm_size_t pagesize = vm_kernel_page_size;
#elif
static vm_size_t pagesize;
static bool calculated = false;
if (!calculated)
@ -451,16 +458,22 @@ MachTask::GetProfileData (DNBProfileDataScanType scanType)
calculated = true;
pagesize = PageSize();
}
#endif
/* Unused values. Optimized out for transfer performance.
profile_data_stream << "wired:" << vm_stats.wire_count * pagesize << ';';
profile_data_stream << "active:" << vm_stats.active_count * pagesize << ';';
profile_data_stream << "inactive:" << vm_stats.inactive_count * pagesize << ';';
profile_data_stream << "wired:" << vminfo.wire_count * pagesize << ';';
profile_data_stream << "active:" << vminfo.active_count * pagesize << ';';
profile_data_stream << "inactive:" << vminfo.inactive_count * pagesize << ';';
*/
uint64_t total_used_count = vm_stats.wire_count + vm_stats.inactive_count + vm_stats.active_count;
#if defined (HOST_VM_INFO64_COUNT)
// This mimicks Activity Monitor.
uint64_t total_used_count = (physical_memory / vm_kernel_page_size) - (vminfo.free_count - vminfo.speculative_count) - vminfo.external_page_count - vminfo.purgeable_count;
#elif
uint64_t total_used_count = vminfo.wire_count + vminfo.inactive_count + vminfo.active_count;
#endif
profile_data_stream << "used:" << total_used_count * pagesize << ';';
/* Unused values. Optimized out for transfer performance.
profile_data_stream << "free:" << vm_stats.free_count * pagesize << ';';
profile_data_stream << "free:" << vminfo.free_count * pagesize << ';';
*/
profile_data_stream << "rprvt:" << rprvt << ';';

View File

@ -236,11 +236,10 @@ static uint64_t GetPhysicalMemory()
static bool calculated = false;
if (calculated) return physical_memory;
int mib[2];
mib[0] = CTL_HW;
mib[1] = HW_MEMSIZE;
size_t len = sizeof(physical_memory);
sysctl(mib, 2, &physical_memory, &len, NULL, 0);
sysctlbyname("hw.memsize", &physical_memory, &len, NULL, 0);
calculated = true;
return physical_memory;
}
@ -418,8 +417,13 @@ GetPurgeableAndAnonymous(task_t task, uint64_t &purgeable, uint64_t &anonymous)
#endif
}
#if defined (HOST_VM_INFO64_COUNT)
nub_bool_t
MachVMMemory::GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size, mach_vm_size_t &purgeable, mach_vm_size_t &anonymous)
MachVMMemory::GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics64_data_t &vminfo, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size, mach_vm_size_t &purgeable, mach_vm_size_t &anonymous)
#elif
nub_bool_t
MachVMMemory::GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vminfo, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size, mach_vm_size_t &purgeable, mach_vm_size_t &anonymous)
#endif
{
if (scanType & eProfileHostMemory)
physical_memory = GetPhysicalMemory();
@ -427,12 +431,17 @@ MachVMMemory::GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, str
if (scanType & eProfileMemory)
{
static mach_port_t localHost = mach_host_self();
#if defined (HOST_VM_INFO64_COUNT)
mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;
host_statistics64(localHost, HOST_VM_INFO64, (host_info64_t)&vminfo, &count);
#elif
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
host_statistics(localHost, HOST_VM_INFO, (host_info_t)&vm_stats, &count);
vm_stats.wire_count += GetStolenPages(task);
host_statistics(localHost, HOST_VM_INFO, (host_info_t)&vminfo, &count);
vminfo.wire_count += GetStolenPages(task);
#endif
/* We are no longer reporting these. Let's not waste time.
GetMemorySizes(task, cputype, pid, rprvt, vprvt);
rsize = ti.resident_size;
vsize = ti.virtual_size;
@ -441,6 +450,7 @@ MachVMMemory::GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, str
// This uses vmmap strategy. We don't use the returned rsize for now. We prefer to match top's version since that's what we do for the rest of the metrics.
GetRegionSizes(task, rsize, dirty_size);
}
*/
if (scanType & eProfileMemoryAnonymous)
{

View File

@ -28,7 +28,11 @@ public:
nub_size_t Write(task_t task, nub_addr_t address, const void *data, nub_size_t data_count);
nub_size_t PageSize(task_t task);
nub_bool_t GetMemoryRegionInfo(task_t task, nub_addr_t address, DNBRegionInfo *region_info);
nub_bool_t GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vm_stats, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size, mach_vm_size_t &purgable, mach_vm_size_t &anonymous);
#if defined (HOST_VM_INFO64_COUNT)
nub_bool_t GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics64_data_t &vminfo, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size, mach_vm_size_t &purgeable, mach_vm_size_t &anonymous);
#elif
nub_bool_t GetMemoryProfile(DNBProfileDataScanType scanType, task_t task, struct task_basic_info ti, cpu_type_t cputype, nub_process_t pid, vm_statistics_data_t &vminfo, uint64_t &physical_memory, mach_vm_size_t &rprvt, mach_vm_size_t &rsize, mach_vm_size_t &vprvt, mach_vm_size_t &vsize, mach_vm_size_t &dirty_size, mach_vm_size_t &purgeable, mach_vm_size_t &anonymous);
#endif
protected:
nub_size_t MaxBytesLeftInPage(task_t task, nub_addr_t addr, nub_size_t count);