tor-browser

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

memory.js (3653B)


      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 const { memorySpec } = require("resource://devtools/shared/specs/memory.js");
      8 const {
      9  FrontClassWithSpec,
     10  registerFront,
     11 } = require("resource://devtools/shared/protocol.js");
     12 
     13 const lazy = {};
     14 ChromeUtils.defineESModuleGetters(lazy, {
     15  FileUtils: "resource://gre/modules/FileUtils.sys.mjs",
     16 });
     17 loader.lazyRequireGetter(
     18  this,
     19  "HeapSnapshotFileUtils",
     20  "resource://devtools/shared/heapsnapshot/HeapSnapshotFileUtils.js"
     21 );
     22 
     23 class MemoryFront extends FrontClassWithSpec(memorySpec) {
     24  constructor(client, targetFront, parentFront) {
     25    super(client, targetFront, parentFront);
     26    this._client = client;
     27 
     28    // Attribute name from which to retrieve the actorID out of the target actor's form
     29    this.formAttributeName = "memoryActor";
     30  }
     31 
     32  /**
     33   * Save a heap snapshot, transfer it from the server to the client if the
     34   * server and client do not share a file system, and return the local file
     35   * path to the heap snapshot.
     36   *
     37   * Note that this is safe to call for actors inside sandoxed child processes,
     38   * as we jump through the correct IPDL hoops.
     39   *
     40   * @param {object} options
     41   * @param {boolean} options.forceCopy
     42   *         Always force a bulk data copy of the saved heap snapshot, even when
     43   *         the server and client share a file system.
     44   *
     45   * @param {object | undefined} options.boundaries
     46   *         The boundaries for the heap snapshot. See
     47   *         ChromeUtils.webidl for more details.
     48   *
     49   * @returns Promise<String>
     50   */
     51  async saveHeapSnapshot(options = {}) {
     52    const snapshotId = await super.saveHeapSnapshot(options.boundaries);
     53 
     54    if (
     55      !options.forceCopy &&
     56      (await HeapSnapshotFileUtils.haveHeapSnapshotTempFile(snapshotId))
     57    ) {
     58      return HeapSnapshotFileUtils.getHeapSnapshotTempFilePath(snapshotId);
     59    }
     60 
     61    return this.transferHeapSnapshot(snapshotId);
     62  }
     63 
     64  /**
     65   * Given that we have taken a heap snapshot with the given id, transfer the
     66   * heap snapshot file to the client. The path to the client's local file is
     67   * returned.
     68   *
     69   * @param {string} snapshotId
     70   *
     71   * @returns Promise<String>
     72   */
     73  async transferHeapSnapshot(snapshotId) {
     74    const heapSnapshotFileFront =
     75      await this._client.mainRoot.getFront("heapSnapshotFile");
     76 
     77    try {
     78      const request = heapSnapshotFileFront.transferHeapSnapshot(snapshotId);
     79 
     80      const outFilePath =
     81        HeapSnapshotFileUtils.getNewUniqueHeapSnapshotTempFilePath();
     82      const outFile = new lazy.FileUtils.File(outFilePath);
     83      const outFileStream = lazy.FileUtils.openSafeFileOutputStream(outFile);
     84 
     85      // This request is a bulk request. That's why the result of the request is
     86      // an object with the `copyTo` function that can transfer the data to
     87      // another stream.
     88      // See devtools/shared/transport/transport.js to know more about this mode.
     89      const { copyTo } = await request;
     90      await copyTo(outFileStream);
     91 
     92      lazy.FileUtils.closeSafeFileOutputStream(outFileStream);
     93      return outFilePath;
     94    } catch (e) {
     95      if (e.error) {
     96        // This isn't a real error, rather this is a message coming from the
     97        // server. So let's throw a real error instead.
     98        throw new Error(
     99          `The server's actor threw an error: (${e.error}) ${e.message}`
    100        );
    101      }
    102 
    103      // Otherwise, rethrow the error
    104      throw e;
    105    }
    106  }
    107 }
    108 
    109 exports.MemoryFront = MemoryFront;
    110 registerFront(MemoryFront);