tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

head.js (3843B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 /* exported timeThis */
      8 
      9 // Load the shared-head file first.
     10 Services.scriptloader.loadSubScript(
     11  "chrome://mochitests/content/browser/accessible/tests/browser/shared-head.js",
     12  this
     13 );
     14 
     15 // Load common.js and promisified-events.js from accessible/tests/mochitest/ for
     16 // all tests.
     17 loadScripts(
     18  { name: "common.js", dir: MOCHITESTS_DIR },
     19  { name: "promisified-events.js", dir: MOCHITESTS_DIR }
     20 );
     21 
     22 // All the A11Y metrics in tools/performance/PerfStats.h.
     23 const ALL_A11Y_PERFSTATS_FEATURES = [
     24  "A11Y_DoInitialUpdate",
     25  "A11Y_ProcessQueuedCacheUpdate",
     26  "A11Y_ContentRemovedNode",
     27  "A11Y_ContentRemovedAcc",
     28  "A11Y_PruneOrInsertSubtree",
     29  "A11Y_ShutdownChildrenInSubtree",
     30  "A11Y_ShowEvent",
     31  "A11Y_RecvCache",
     32  "A11Y_ProcessShowEvent",
     33  "A11Y_CoalesceEvents",
     34  "A11Y_CoalesceMutationEvents",
     35  "A11Y_ProcessHideEvent",
     36  "A11Y_SendCache",
     37  "A11Y_WillRefresh",
     38  "A11Y_AccessibilityServiceInit",
     39  "A11Y_PlatformShowHideEvent",
     40 ];
     41 
     42 const LOG_PREFIX = "perfMetrics";
     43 
     44 function logToPerfMetrics(stat) {
     45  info(`${LOG_PREFIX} | ${JSON.stringify(stat)}`);
     46 }
     47 
     48 /**
     49 * Time a function and log how long it took. The given name is included in log
     50 * messages. All accessibility PerfStats metrics are also captured and logged.
     51 * This function may only be called once per task, and we are limited to one
     52 * task per file.
     53 */
     54 async function timeThis(func) {
     55  const start = performance.now();
     56  ChromeUtils.setPerfStatsFeatures(ALL_A11Y_PERFSTATS_FEATURES);
     57  const journal = {};
     58 
     59  // Run the specified testing task
     60  await func();
     61 
     62  // Log our total elapsed time
     63  journal.A11Y_TotalTime = performance.now() - start;
     64 
     65  const stats = JSON.parse(await ChromeUtils.collectPerfStats());
     66  ChromeUtils.setPerfStatsFeatures([]);
     67  // Filter stuff out of stats that we don't care about.
     68  // Filter out the GPU process, since accessibility doesn't do anything there.
     69  stats.processes = stats.processes.filter(process => process.type != "gpu");
     70  for (const process of stats.processes) {
     71    // Because of weird JS -> WebIDL 64 bit number issues, we get metrics here
     72    // that aren't for accessibility. For example, 1 << 32 also gets us 1 << 0.
     73    // Filter those out. Also, filter out any metrics with a count of 0.
     74    process.perfstats.metrics = process.perfstats.metrics.filter(
     75      metric => metric.metric.startsWith("A11Y_") && metric.count > 0
     76    );
     77  }
     78  // Now that we've filtered metrics, remove any processes that have no metrics left.
     79  stats.processes = stats.processes.filter(
     80    process => !!process.perfstats.metrics.length
     81  );
     82  // Also, filter out readings for the blank new tab that gets opened before the
     83  // tab with our test content opens.
     84  // We may get a reading that isn't attached to any URL; this contains
     85  // the startup time for the Accessibility Service which we should keep.
     86  // Our parent process readings have no URL field.
     87  stats.processes = stats.processes.filter(
     88    process =>
     89      process.type == "parent" ||
     90      !process.urls.length ||
     91      !process.urls.includes("about:newtab")
     92  );
     93 
     94  // Because our perfstats measure both occurances and timing, log values separately
     95  // under different probe names with different units.
     96  // Also, as the same probes can be triggered in content and parent, append a process
     97  // indicator to the end of each probe name.
     98  for (const process of stats.processes) {
     99    for (const stat of process.perfstats.metrics) {
    100      journal[stat.metric + "_" + process.type] = stat.time;
    101      if (stat.count) {
    102        journal[stat.metric + "_Count_" + process.type] = stat.count;
    103      }
    104    }
    105  }
    106 
    107  logToPerfMetrics(journal);
    108 }