mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 1665318 - reduce the overhead of collecting memory information for about:processes, r=dthayer.
Differential Revision: https://phabricator.services.mozilla.com/D125729
This commit is contained in:
parent
4fcdfbc981
commit
3ba2c38074
@ -126,7 +126,7 @@ let DefaultTabUnloaderMethods = {
|
||||
processInfo = { count: 0, topCount: 0, tabSet: new Set() };
|
||||
processMap.set(childProcInfo.pid, processInfo);
|
||||
}
|
||||
processInfo.memory = childProcInfo.residentUniqueSize;
|
||||
processInfo.memory = childProcInfo.memory;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
@ -672,15 +672,11 @@ dictionary ChildProcInfoDictionary {
|
||||
// Process filename (without the path name).
|
||||
DOMString filename = "";
|
||||
|
||||
// RSS, in bytes, i.e. the total amount of memory allocated
|
||||
// by this process.
|
||||
long long residentSetSize = 0;
|
||||
|
||||
// Resident unique size, i.e. the total amount of memory
|
||||
// allocated by this process *and not shared with other processes*.
|
||||
// Given that we share lots of memory between processes,
|
||||
// this is probably the best end-user measure for "memory used".
|
||||
long long residentUniqueSize = 0;
|
||||
// The best end-user measure for "memory used" that we can obtain without
|
||||
// triggering expensive computations. The value is in bytes.
|
||||
// On Mac and Linux this matches the values shown by the system monitors.
|
||||
// On Windows this will return the Commit Size.
|
||||
unsigned long long memory = 0;
|
||||
|
||||
// Time spent by the process in user mode, in ns.
|
||||
unsigned long long cpuUser = 0;
|
||||
@ -719,15 +715,11 @@ dictionary ParentProcInfoDictionary {
|
||||
// Process filename (without the path name).
|
||||
DOMString filename = "";
|
||||
|
||||
// RSS, in bytes, i.e. the total amount of memory allocated
|
||||
// by this process.
|
||||
long long residentSetSize = 0;
|
||||
|
||||
// Resident unique size, i.e. the total amount of memory
|
||||
// allocated by this process *and not shared with other processes*.
|
||||
// Given that we share lots of memory between processes,
|
||||
// this is probably the best end-user measure for "memory used".
|
||||
long long residentUniqueSize = 0;
|
||||
// The best end-user measure for "memory used" that we can obtain without
|
||||
// triggering expensive computations. The value is in bytes.
|
||||
// On Mac and Linux this matches the values shown by the system monitors.
|
||||
// On Windows this will return the Commit Size.
|
||||
unsigned long long memory = 0;
|
||||
|
||||
// Time spent by the process in user mode, in ns.
|
||||
unsigned long long cpuUser = 0;
|
||||
|
@ -308,18 +308,11 @@ var State = {
|
||||
*/
|
||||
_getProcessDelta(cur, prev) {
|
||||
let windows = this._getDOMWindows(cur);
|
||||
// Resident set size is the total memory used by the process, including shared memory.
|
||||
// Resident unique size is the memory used by the process, without shared memory.
|
||||
// Since all processes share memory with the parent process, we count the shared memory
|
||||
// as part of the parent process (`"browser"`) rather than as part of the individual
|
||||
// processes.
|
||||
let totalRamSize =
|
||||
cur.type == "browser" ? cur.residentSetSize : cur.residentUniqueSize;
|
||||
let result = {
|
||||
pid: cur.pid,
|
||||
childID: cur.childID,
|
||||
filename: cur.filename,
|
||||
totalRamSize,
|
||||
totalRamSize: cur.memory,
|
||||
deltaRamSize: null,
|
||||
totalCpuUser: cur.cpuUser,
|
||||
slopeCpuUser: null,
|
||||
@ -372,10 +365,7 @@ var State = {
|
||||
return this._getThreadDelta(curThread, prevThread, deltaT);
|
||||
});
|
||||
}
|
||||
result.deltaRamSize =
|
||||
cur.type == "browser"
|
||||
? cur.residentSetSize - prev.residentSetSize
|
||||
: cur.residentUniqueSize - prev.residentUniqueSize;
|
||||
result.deltaRamSize = cur.memory - prev.memory;
|
||||
result.slopeCpuUser = (cur.cpuUser - prev.cpuUser) / deltaT;
|
||||
result.slopeCpuKernel = (cur.cpuKernel - prev.cpuKernel) / deltaT;
|
||||
result.slopeCpu = result.slopeCpuUser + result.slopeCpuKernel;
|
||||
|
@ -105,10 +105,8 @@ struct ProcInfo {
|
||||
nsCString origin;
|
||||
// Process filename (without the path name).
|
||||
nsString filename;
|
||||
// RSS in bytes.
|
||||
int64_t residentSetSize = 0;
|
||||
// Unshared resident size in bytes.
|
||||
int64_t residentUniqueSize = 0;
|
||||
// Memory size in bytes.
|
||||
uint64_t memory = 0;
|
||||
// User time in ns.
|
||||
uint64_t cpuUser = 0;
|
||||
// System time in ns.
|
||||
@ -212,8 +210,7 @@ nsresult CopySysProcInfoToDOM(const ProcInfo& source, T* dest) {
|
||||
// Copy system info.
|
||||
dest->mPid = source.pid;
|
||||
dest->mFilename.Assign(source.filename);
|
||||
dest->mResidentSetSize = source.residentSetSize;
|
||||
dest->mResidentUniqueSize = source.residentUniqueSize;
|
||||
dest->mMemory = source.memory;
|
||||
dest->mCpuUser = source.cpuUser;
|
||||
dest->mCpuKernel = source.cpuKernel;
|
||||
|
||||
|
@ -32,127 +32,126 @@ RefPtr<ProcInfoPromise> GetProcInfo(nsTArray<ProcInfoRequest>&& aRequests) {
|
||||
return promise;
|
||||
}
|
||||
|
||||
RefPtr<nsIRunnable> r = NS_NewRunnableFunction(
|
||||
__func__, [holder = std::move(holder), requests = std::move(aRequests)]() {
|
||||
HashMap<base::ProcessId, ProcInfo> gathered;
|
||||
if (!gathered.reserve(requests.Length())) {
|
||||
RefPtr<nsIRunnable> r = NS_NewRunnableFunction(__func__, [holder = std::move(holder),
|
||||
requests = std::move(aRequests)]() {
|
||||
HashMap<base::ProcessId, ProcInfo> gathered;
|
||||
if (!gathered.reserve(requests.Length())) {
|
||||
holder->Reject(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
return;
|
||||
}
|
||||
for (const auto& request : requests) {
|
||||
ProcInfo info;
|
||||
info.pid = request.pid;
|
||||
info.childId = request.childId;
|
||||
info.type = request.processType;
|
||||
info.origin = std::move(request.origin);
|
||||
info.windows = std::move(request.windowInfo);
|
||||
struct proc_bsdinfo proc;
|
||||
if ((unsigned long)proc_pidinfo(request.pid, PROC_PIDTBSDINFO, 0, &proc,
|
||||
PROC_PIDTBSDINFO_SIZE) < PROC_PIDTBSDINFO_SIZE) {
|
||||
// Can't read data for this proc.
|
||||
// Probably either a sandboxing issue or a race condition, e.g.
|
||||
// the process has been just been killed. Regardless, skip process.
|
||||
continue;
|
||||
}
|
||||
|
||||
struct proc_taskinfo pti;
|
||||
if ((unsigned long)proc_pidinfo(request.pid, PROC_PIDTASKINFO, 0, &pti,
|
||||
PROC_PIDTASKINFO_SIZE) < PROC_PIDTASKINFO_SIZE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// copying all the info to the ProcInfo struct
|
||||
info.filename.AssignASCII(proc.pbi_name);
|
||||
info.cpuUser = pti.pti_total_user;
|
||||
info.cpuKernel = pti.pti_total_system;
|
||||
|
||||
mach_port_t selectedTask;
|
||||
// If we did not get a task from a child process, we use mach_task_self()
|
||||
if (request.childTask == MACH_PORT_NULL) {
|
||||
selectedTask = mach_task_self();
|
||||
} else {
|
||||
selectedTask = request.childTask;
|
||||
}
|
||||
|
||||
// The phys_footprint value (introduced in 10.11) of the TASK_VM_INFO data
|
||||
// matches the value in the 'Memory' column of the Activity Monitor.
|
||||
task_vm_info_data_t task_vm_info;
|
||||
mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
|
||||
kern_return_t kr = task_info(selectedTask, TASK_VM_INFO, (task_info_t)&task_vm_info, &count);
|
||||
info.memory = kr == KERN_SUCCESS ? task_vm_info.phys_footprint : 0;
|
||||
|
||||
// Now getting threads info
|
||||
|
||||
// task_threads() gives us a snapshot of the process threads
|
||||
// but those threads can go away. All the code below makes
|
||||
// the assumption that thread_info() calls may fail, and
|
||||
// these errors will be ignored.
|
||||
thread_act_port_array_t threadList;
|
||||
mach_msg_type_number_t threadCount;
|
||||
kern_return_t kret = task_threads(selectedTask, &threadList, &threadCount);
|
||||
if (kret != KERN_SUCCESS) {
|
||||
// For some reason, we have no data on the threads for this process.
|
||||
// Most likely reason is that we have just lost a race condition and
|
||||
// the process is dead.
|
||||
// Let's stop here and ignore the entire process.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Deallocate the thread list.
|
||||
// Note that this deallocation is entirely undocumented, so the following code is based
|
||||
// on guesswork and random examples found on the web.
|
||||
auto guardThreadCount = MakeScopeExit([&] {
|
||||
if (threadList == nullptr) {
|
||||
return;
|
||||
}
|
||||
// Free each thread to avoid leaks.
|
||||
for (mach_msg_type_number_t i = 0; i < threadCount; i++) {
|
||||
mach_port_deallocate(mach_task_self(), threadList[i]);
|
||||
}
|
||||
vm_deallocate(mach_task_self(), /* address */ (vm_address_t)threadList,
|
||||
/* size */ sizeof(thread_t) * threadCount);
|
||||
});
|
||||
|
||||
for (mach_msg_type_number_t i = 0; i < threadCount; i++) {
|
||||
// Basic thread info.
|
||||
thread_extended_info_data_t threadInfoData;
|
||||
count = THREAD_EXTENDED_INFO_COUNT;
|
||||
kret = thread_info(threadList[i], THREAD_EXTENDED_INFO, (thread_info_t)&threadInfoData,
|
||||
&count);
|
||||
if (kret != KERN_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Getting the thread id.
|
||||
thread_identifier_info identifierInfo;
|
||||
count = THREAD_IDENTIFIER_INFO_COUNT;
|
||||
kret = thread_info(threadList[i], THREAD_IDENTIFIER_INFO, (thread_info_t)&identifierInfo,
|
||||
&count);
|
||||
if (kret != KERN_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The two system calls were successful, let's add that thread
|
||||
ThreadInfo* thread = info.threads.AppendElement(fallible);
|
||||
if (!thread) {
|
||||
holder->Reject(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
return;
|
||||
}
|
||||
for (const auto& request : requests) {
|
||||
ProcInfo info;
|
||||
info.pid = request.pid;
|
||||
info.childId = request.childId;
|
||||
info.type = request.processType;
|
||||
info.origin = std::move(request.origin);
|
||||
info.windows = std::move(request.windowInfo);
|
||||
struct proc_bsdinfo proc;
|
||||
if ((unsigned long)proc_pidinfo(request.pid, PROC_PIDTBSDINFO, 0, &proc,
|
||||
PROC_PIDTBSDINFO_SIZE) < PROC_PIDTBSDINFO_SIZE) {
|
||||
// Can't read data for this proc.
|
||||
// Probably either a sandboxing issue or a race condition, e.g.
|
||||
// the process has been just been killed. Regardless, skip process.
|
||||
continue;
|
||||
}
|
||||
thread->cpuUser = threadInfoData.pth_user_time;
|
||||
thread->cpuKernel = threadInfoData.pth_system_time;
|
||||
thread->name.AssignASCII(threadInfoData.pth_name);
|
||||
thread->tid = identifierInfo.thread_id;
|
||||
}
|
||||
|
||||
struct proc_taskinfo pti;
|
||||
if ((unsigned long)proc_pidinfo(request.pid, PROC_PIDTASKINFO, 0, &pti,
|
||||
PROC_PIDTASKINFO_SIZE) < PROC_PIDTASKINFO_SIZE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// copying all the info to the ProcInfo struct
|
||||
info.filename.AssignASCII(proc.pbi_name);
|
||||
info.residentSetSize = pti.pti_resident_size;
|
||||
info.cpuUser = pti.pti_total_user;
|
||||
info.cpuKernel = pti.pti_total_system;
|
||||
|
||||
mach_port_t selectedTask;
|
||||
// If we did not get a task from a child process, we use mach_task_self()
|
||||
if (request.childTask == MACH_PORT_NULL) {
|
||||
selectedTask = mach_task_self();
|
||||
} else {
|
||||
selectedTask = request.childTask;
|
||||
}
|
||||
// Computing the resident unique size is somewhat tricky,
|
||||
// so we use about:memory's implementation. This implementation
|
||||
// uses the `task` so, in theory, should be no additional
|
||||
// race condition. However, in case of error, the result is `0`.
|
||||
info.residentUniqueSize = nsMemoryReporterManager::ResidentUnique(selectedTask);
|
||||
|
||||
// Now getting threads info
|
||||
|
||||
// task_threads() gives us a snapshot of the process threads
|
||||
// but those threads can go away. All the code below makes
|
||||
// the assumption that thread_info() calls may fail, and
|
||||
// these errors will be ignored.
|
||||
thread_act_port_array_t threadList;
|
||||
mach_msg_type_number_t threadCount;
|
||||
kern_return_t kret = task_threads(selectedTask, &threadList, &threadCount);
|
||||
if (kret != KERN_SUCCESS) {
|
||||
// For some reason, we have no data on the threads for this process.
|
||||
// Most likely reason is that we have just lost a race condition and
|
||||
// the process is dead.
|
||||
// Let's stop here and ignore the entire process.
|
||||
continue;
|
||||
}
|
||||
|
||||
// Deallocate the thread list.
|
||||
// Note that this deallocation is entirely undocumented, so the following code is based
|
||||
// on guesswork and random examples found on the web.
|
||||
auto guardThreadCount = MakeScopeExit([&] {
|
||||
if (threadList == nullptr) {
|
||||
return;
|
||||
}
|
||||
// Free each thread to avoid leaks.
|
||||
for (mach_msg_type_number_t i = 0; i < threadCount; i++) {
|
||||
mach_port_deallocate(mach_task_self(), threadList[i]);
|
||||
}
|
||||
vm_deallocate(mach_task_self(), /* address */ (vm_address_t)threadList,
|
||||
/* size */ sizeof(thread_t) * threadCount);
|
||||
});
|
||||
|
||||
mach_msg_type_number_t count;
|
||||
|
||||
for (mach_msg_type_number_t i = 0; i < threadCount; i++) {
|
||||
// Basic thread info.
|
||||
thread_extended_info_data_t threadInfoData;
|
||||
count = THREAD_EXTENDED_INFO_COUNT;
|
||||
kret = thread_info(threadList[i], THREAD_EXTENDED_INFO, (thread_info_t)&threadInfoData,
|
||||
&count);
|
||||
if (kret != KERN_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Getting the thread id.
|
||||
thread_identifier_info identifierInfo;
|
||||
count = THREAD_IDENTIFIER_INFO_COUNT;
|
||||
kret = thread_info(threadList[i], THREAD_IDENTIFIER_INFO,
|
||||
(thread_info_t)&identifierInfo, &count);
|
||||
if (kret != KERN_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// The two system calls were successful, let's add that thread
|
||||
ThreadInfo* thread = info.threads.AppendElement(fallible);
|
||||
if (!thread) {
|
||||
holder->Reject(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
return;
|
||||
}
|
||||
thread->cpuUser = threadInfoData.pth_user_time;
|
||||
thread->cpuKernel = threadInfoData.pth_system_time;
|
||||
thread->name.AssignASCII(threadInfoData.pth_name);
|
||||
thread->tid = identifierInfo.thread_id;
|
||||
}
|
||||
|
||||
if (!gathered.put(request.pid, std::move(info))) {
|
||||
holder->Reject(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// ... and we're done!
|
||||
holder->Resolve(std::move(gathered), __func__);
|
||||
});
|
||||
if (!gathered.put(request.pid, std::move(info))) {
|
||||
holder->Reject(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// ... and we're done!
|
||||
holder->Resolve(std::move(gathered), __func__);
|
||||
});
|
||||
|
||||
rv = target->Dispatch(r.forget(), NS_DISPATCH_NORMAL);
|
||||
if (NS_FAILED(rv)) {
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/ScopeExit.h"
|
||||
#include "mozilla/ipc/GeckoChildProcessHost.h"
|
||||
#include "nsLocalFile.h"
|
||||
#include "nsMemoryReporterManager.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
@ -38,9 +37,7 @@ namespace mozilla {
|
||||
class StatReader {
|
||||
public:
|
||||
explicit StatReader(const base::ProcessId aPid)
|
||||
: mPid(aPid), mMaxIndex(53), mTicksPerSec(sysconf(_SC_CLK_TCK)) {
|
||||
mFilepath.AppendPrintf("/proc/%u/stat", mPid);
|
||||
}
|
||||
: mPid(aPid), mMaxIndex(15), mTicksPerSec(sysconf(_SC_CLK_TCK)) {}
|
||||
|
||||
nsresult ParseProc(ProcInfo& aInfo) {
|
||||
nsAutoString fileContent;
|
||||
@ -89,14 +86,6 @@ class StatReader {
|
||||
aInfo.cpuKernel = GetCPUTime(aToken, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
break;
|
||||
case 23:
|
||||
// Resident Set Size: number of pages the process has
|
||||
// in real memory.
|
||||
uint64_t pageCount = Get64Value(aToken, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
uint64_t pageSize = sysconf(_SC_PAGESIZE);
|
||||
aInfo.residentSetSize = pageCount * pageSize;
|
||||
break;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -136,21 +125,17 @@ class StatReader {
|
||||
private:
|
||||
// Reads the stat file and puts its content in a nsString.
|
||||
nsresult ReadFile(nsAutoString& aFileContent) {
|
||||
RefPtr<nsLocalFile> file = new nsLocalFile(mFilepath);
|
||||
bool exists;
|
||||
nsresult rv = file->Exists(&exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!exists) {
|
||||
if (mFilepath.IsEmpty()) {
|
||||
mFilepath.AppendPrintf("/proc/%u/stat", mPid);
|
||||
}
|
||||
FILE* fstat = fopen(mFilepath.get(), "r");
|
||||
if (!fstat) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
// /proc is a virtual file system and all files are
|
||||
// of size 0, so GetFileSize() and related functions will
|
||||
// return 0 - so the way to read the file is to fill a buffer
|
||||
// of an arbitrary big size and look for the end of line char.
|
||||
FILE* fstat;
|
||||
if (NS_FAILED(file->OpenANSIFileDesc("r", &fstat)) || !fstat) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
char buffer[2048];
|
||||
char* end;
|
||||
char* start = fgets(buffer, 2048, fstat);
|
||||
@ -176,10 +161,7 @@ class ThreadInfoReader final : public StatReader {
|
||||
public:
|
||||
ThreadInfoReader(const base::ProcessId aPid, const base::ProcessId aTid)
|
||||
: StatReader(aPid), mTid(aTid) {
|
||||
// Adding the thread path
|
||||
mFilepath.Truncate();
|
||||
mFilepath.AppendPrintf("/proc/%u/task/%u/stat", aPid, mTid);
|
||||
mMaxIndex = 17;
|
||||
}
|
||||
|
||||
nsresult ParseThread(ThreadInfo& aInfo) {
|
||||
@ -230,12 +212,22 @@ RefPtr<ProcInfoPromise> GetProcInfo(nsTArray<ProcInfoRequest>&& aRequests) {
|
||||
// the process has been just been killed. Regardless, skip process.
|
||||
continue;
|
||||
}
|
||||
// Computing the resident unique size is somewhat tricky,
|
||||
// so we use about:memory's implementation. This implementation
|
||||
// reopens `/proc/[pid]`, so there is the risk of an additional
|
||||
// race condition. In that case, the result is `0`.
|
||||
info.residentUniqueSize =
|
||||
nsMemoryReporterManager::ResidentUnique(request.pid);
|
||||
|
||||
// The 'Memory' value displayed in the system monitor is resident -
|
||||
// shared. statm contains more fields, but we're only interested in
|
||||
// the first three.
|
||||
static const int MAX_FIELD = 3;
|
||||
size_t VmSize, resident, shared;
|
||||
info.memory = 0;
|
||||
FILE* f =
|
||||
fopen(nsPrintfCString("/proc/%u/statm", request.pid).get(), "r");
|
||||
if (f) {
|
||||
int nread = fscanf(f, "%zu %zu %zu", &VmSize, &resident, &shared);
|
||||
fclose(f);
|
||||
if (nread == MAX_FIELD) {
|
||||
info.memory = (resident - shared) * getpagesize();
|
||||
}
|
||||
}
|
||||
|
||||
// Extra info
|
||||
info.pid = request.pid;
|
||||
|
@ -68,7 +68,7 @@ RefPtr<ProcInfoPromise> GetProcInfo(nsTArray<ProcInfoRequest>&& aRequests) {
|
||||
// Ignore process, it may have died.
|
||||
continue;
|
||||
}
|
||||
PROCESS_MEMORY_COUNTERS memoryCounters;
|
||||
PROCESS_MEMORY_COUNTERS_EX memoryCounters;
|
||||
if (!GetProcessMemoryInfo(handle.get(),
|
||||
(PPROCESS_MEMORY_COUNTERS)&memoryCounters,
|
||||
sizeof(memoryCounters))) {
|
||||
@ -91,14 +91,7 @@ RefPtr<ProcInfoPromise> GetProcInfo(nsTArray<ProcInfoRequest>&& aRequests) {
|
||||
info.filename.Assign(filename);
|
||||
info.cpuKernel = ToNanoSeconds(kernelTime);
|
||||
info.cpuUser = ToNanoSeconds(userTime);
|
||||
info.residentSetSize = memoryCounters.WorkingSetSize;
|
||||
|
||||
// Computing the resident unique size is somewhat tricky,
|
||||
// so we use about:memory's implementation. This implementation
|
||||
// uses the `HANDLE` so, in theory, should be no additional
|
||||
// race condition. However, in case of error, the result is `0`.
|
||||
info.residentUniqueSize =
|
||||
nsMemoryReporterManager::ResidentUnique(handle.get());
|
||||
info.memory = memoryCounters.PrivateUsage;
|
||||
|
||||
if (!gathered.put(request.pid, std::move(info))) {
|
||||
holder->Reject(NS_ERROR_OUT_OF_MEMORY, __func__);
|
||||
|
@ -20,7 +20,6 @@ const isFissionEnabled = SpecialPowers.useRemoteSubframes;
|
||||
const SAMPLE_SIZE = 10;
|
||||
|
||||
add_task(async function test_proc_info() {
|
||||
console.log("YORIC", "Test starts");
|
||||
// Open a few `about:home` tabs, they'll end up in `privilegedabout`.
|
||||
let tabsAboutHome = [];
|
||||
for (let i = 0; i < 5; ++i) {
|
||||
@ -59,14 +58,7 @@ add_task(async function test_proc_info() {
|
||||
);
|
||||
}
|
||||
|
||||
Assert.ok(
|
||||
parentProc.residentUniqueSize > 0,
|
||||
"Resident-unique-size was set"
|
||||
);
|
||||
Assert.ok(
|
||||
parentProc.residentUniqueSize <= parentProc.residentSetSize,
|
||||
`Resident-unique-size should be bounded by resident-set-size ${parentProc.residentUniqueSize} <= ${parentProc.residentSetSize}`
|
||||
);
|
||||
Assert.ok(parentProc.memory > 0, "Memory was set");
|
||||
|
||||
// While it's very unlikely that the parent will disappear while we're running
|
||||
// tests, some children can easily vanish. So we go twice through the list of
|
||||
@ -120,14 +112,7 @@ add_task(async function test_proc_info() {
|
||||
continue;
|
||||
}
|
||||
hasPrivilegedAbout = true;
|
||||
Assert.ok(
|
||||
childProc.residentUniqueSize > 0,
|
||||
"Resident-unique-size was set"
|
||||
);
|
||||
Assert.ok(
|
||||
childProc.residentUniqueSize <= childProc.residentSetSize,
|
||||
`Resident-unique-size should be bounded by resident-set-size ${childProc.residentUniqueSize} <= ${childProc.residentSetSize}`
|
||||
);
|
||||
Assert.ok(childProc.memory > 0, "Memory was set");
|
||||
|
||||
for (var win of childProc.windows) {
|
||||
if (win.documentURI.spec != "about:home") {
|
||||
|
Loading…
Reference in New Issue
Block a user