tor-browser

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

profiler.js (4384B)


      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 // The functions in the class use standard functions called from tracer.js but we want to keep the
      8 // arguments intact.
      9 /* eslint "no-unused-vars": ["error", {args: "none"} ]*/
     10 
     11 class ProfilerTracingListener {
     12  constructor({ targetActor, traceActor }) {
     13    this.targetActor = targetActor;
     14    this.traceActor = traceActor;
     15  }
     16 
     17  /**
     18   * Stop the record and return the gecko profiler data.
     19   *
     20   * @param {object} nativeTrace
     21   *         If we're using native tracing, this contains a table of what the
     22   *         native tracer has collected.
     23   * @return {object}
     24   *         The Gecko profile object.
     25   */
     26  async stop(nativeTrace) {
     27    // Pause profiler before we collect the profile, so that we don't capture
     28    // more samples while the parent process or android threads wait for subprocess profiles.
     29    Services.profiler.Pause();
     30 
     31    let profile;
     32    try {
     33      // Attempt to pull out the data.
     34      profile = await Services.profiler.getProfileDataAsync();
     35 
     36      if (Object.keys(profile).length === 0) {
     37        console.error(
     38          "An empty object was received from getProfileDataAsync.getProfileDataAsync(), " +
     39            "meaning that a profile could not successfully be serialized and captured."
     40        );
     41        profile = null;
     42      }
     43    } catch (e) {
     44      // Explicitly set the profile to null if there as an error.
     45      profile = null;
     46      console.error(`There was an error fetching a profile`, e);
     47    }
     48 
     49    Services.profiler.StopProfiler();
     50 
     51    return profile;
     52  }
     53 
     54  /**
     55   * Be notified by the underlying JavaScriptTracer class
     56   * in case it stops by itself, instead of being stopped when the Actor's stopTracing
     57   * method is called by the user.
     58   *
     59   * @param {boolean} enabled
     60   *        True if the tracer starts tracing, false it it stops.
     61   * @return {boolean}
     62   *         Return true, if the JavaScriptTracer should log a message to stdout.
     63   */
     64  onTracingToggled(enabled) {
     65    if (!enabled) {
     66      this.traceActor.stopTracing();
     67    } else {
     68      Services.profiler.StartProfiler(
     69        // Note that this is the same default as profiler ones defined in:
     70        // devtools/client/performance-new/shared/background.sys.mjs
     71        128 * 1024 * 1024,
     72        1,
     73        ["screenshots", "tracing"],
     74        ["GeckoMain", "DOM Worker"],
     75        this.targetActor.sessionContext.browserId,
     76        0
     77      );
     78    }
     79    return false;
     80  }
     81 
     82  /**
     83   * Called when "trace on next user interaction" is enabled, to notify the user
     84   * that the tracer is initialized but waiting for the user first input.
     85   */
     86  onTracingPending() {
     87    return false;
     88  }
     89 
     90  /**
     91   * Called by JavaScriptTracer class when a new mutation happened on any DOM Element.
     92   *
     93   * @param {object} options
     94   * @param {number} options.depth
     95   *        Represents the depth of the frame in the call stack.
     96   * @param {string} options.prefix
     97   *        A string to be displayed as a prefix of any logged frame.
     98   * @param {nsIStackFrame} options.caller
     99   *        The JS Callsite which caused this mutation.
    100   * @param {string} options.type
    101   *        Type of DOM Mutation:
    102   *        - "add": Node being added,
    103   *        - "attributes": Node whose attributes changed,
    104   *        - "remove": Node being removed,
    105   * @param {DOMNode} options.element
    106   *        The DOM Node related to the current mutation.
    107   * @return {boolean}
    108   *         Return true, if the JavaScriptTracer should log a message to stdout.
    109   */
    110  onTracingDOMMutation({ depth, prefix, type, caller, element }) {
    111    let elementDescription = element.tagName?.toLowerCase();
    112    if (element.id) {
    113      elementDescription += `#${element.id}`;
    114    }
    115    if (element.className) {
    116      elementDescription += `.${element.className.trim().replace(/ +/g, ".")}`;
    117    }
    118 
    119    const description = `${type} on ${elementDescription}`;
    120 
    121    // Bug 1904602: we need a tweak in profiler frontend before being able to show
    122    // dom mutation in the stack chart. Until then, add a custom marker.
    123    ChromeUtils.addProfilerMarker("DOM-Mutation", undefined, description);
    124 
    125    return false;
    126  }
    127 }
    128 
    129 exports.ProfilerTracingListener = ProfilerTracingListener;