Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  perf.js

  Sprache: JAVA
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


"use strict";

/**
 * @typedef {import("perf").BulkReceiving} BulkSending
 */


const { Actor } = require("resource://devtools/shared/protocol.js");
const { perfSpec } = require("resource://devtools/shared/specs/perf.js");

ChromeUtils.defineESModuleGetters(
  this,
  {
    RecordingUtils:
      "resource://devtools/shared/performance-new/recording-utils.sys.mjs",
    Symbolication:
      "resource://devtools/shared/performance-new/symbolication.sys.mjs",
  },
  { global: "contextual" }
);

// Some platforms are built without the Gecko Profiler.
const IS_SUPPORTED_PLATFORM = "nsIProfiler" in Ci;

/**
 * The PerfActor wraps the Gecko Profiler interface (aka Services.profiler).
 */

exports.PerfActor = class PerfActor extends Actor {
  /**
   * This counter is incremented at each new capture. This makes sure that the
   * profile data and the additionalInformation are in sync.
   *
   * @type {number}
   */

  #captureHandleCounter = 0;

  /**
   * This stores the profile data retrieved from the last call to
   * startCaptureAndStopProfiler.
   *
   * @type {Promise<ArrayBuffer> |null}
   */

  #previouslyRetrievedProfileDataPromise = null;

  /**
   * This stores the additionalInformation returned by
   * getProfileDataAsGzippedArrayBufferThenStop so that it can be sent to the
   * front using getPreviouslyRetrievedAdditionalInformation.
   *
   * @type {Promise<MockedExports.ProfileGenerationAdditionalInformation>| null}
   */

  #previouslyRetrievedAdditionalInformationPromise = null;

  constructor(conn) {
    super(conn, perfSpec);

    // Only setup the observers on a supported platform.
    if (IS_SUPPORTED_PLATFORM) {
      this._observer = {
        observe: this._observe.bind(this),
      };
      Services.obs.addObserver(this._observer, "profiler-started");
      Services.obs.addObserver(this._observer, "profiler-stopped");
    }
  }

  destroy() {
    super.destroy();

    if (!IS_SUPPORTED_PLATFORM) {
      return;
    }
    Services.obs.removeObserver(this._observer, "profiler-started");
    Services.obs.removeObserver(this._observer, "profiler-stopped");
  }

  startProfiler(options) {
    if (!IS_SUPPORTED_PLATFORM) {
      return false;
    }

    // For a quick implementation, decide on some default values. These may need
    // to be tweaked or made configurable as needed.
    const settings = {
      entries: options.entries || 1000000,
      duration: options.duration || 0,
      interval: options.interval || 1,
      features: options.features || ["js""stackwalk""cpu""memory"],
      threads: options.threads || ["GeckoMain""Compositor"],
      activeTabID: RecordingUtils.getActiveBrowserID(),
    };

    try {
      // This can throw an error if the profiler is in the wrong state.
      Services.profiler.StartProfiler(
        settings.entries,
        settings.interval,
        settings.features,
        settings.threads,
        settings.activeTabID,
        settings.duration
      );
    } catch (e) {
      // In case any errors get triggered, bailout with a false.
      return false;
    }

    return true;
  }

  stopProfilerAndDiscardProfile() {
    if (!IS_SUPPORTED_PLATFORM) {
      return null;
    }
    return Services.profiler.StopProfiler();
  }

  /**
   * @type {string} debugPath
   * @type {string} breakpadId
   * @returns {Promise<[number[], number[], number[]]>}
   */

  async getSymbolTable(debugPath, breakpadId) {
    const libraries = Services.profiler.sharedLibraries;
    const symbolicationService = Symbolication.createLocalSymbolicationService(
      libraries,
      []
    );
    const debugName = libraries.find(
      lib => lib.path === debugPath && lib.breakpadId === breakpadId
    )?.debugName;

    if (debugName === undefined) {
      throw new Error(
        `Couldn't find the library with path ${debugPath} and breakpadId ${breakpadId}`
      );
    }

    const [addr, index, buffer] = await symbolicationService.getSymbolTable(
      debugName,
      breakpadId
    );
    // The protocol does not support the transfer of typed arrays, so we convert
    // these typed arrays to plain JS arrays of numbers now.
    // Our return value type is declared as "array:array:number".
    return [Array.from(addr), Array.from(index), Array.from(buffer)];
  }

  async startCaptureAndStopProfiler() {
    if (!IS_SUPPORTED_PLATFORM) {
      throw new Error("Profiling is not supported on this platform.");
    }

    const capturePromise =
      RecordingUtils.getProfileDataAsGzippedArrayBufferThenStop();

    this.#previouslyRetrievedProfileDataPromise = capturePromise.then(
      ({ profileCaptureResult }) => {
        if (profileCaptureResult.type === "ERROR") {
          throw profileCaptureResult.error;
        }

        return profileCaptureResult.profile;
      }
    );

    this.#previouslyRetrievedAdditionalInformationPromise = capturePromise.then(
      ({ additionalInformation }) => additionalInformation
    );

    return ++this.#captureHandleCounter;
  }

  /**
   * This actor function returns the profile data using the bulk protocol.
   *
   * @param {number} handle returned by startCaptureAndStopProfiler
   * @returns {Promise<void>}
   */

  async getPreviouslyCapturedProfileDataBulk(handle, startBulkSend) {
    if (handle < this.#captureHandleCounter) {
      // This handle is outdated, write a message to the console and throw an error
      console.error(
        `[devtools perf actor] In getPreviouslyCapturedProfileDataBulk, the requested handle ${handle} is smaller than the current counter ${this.#captureHandleCounter}.`
      );
      throw new Error(`The requested data was not found.`);
    }

    if (this.#previouslyRetrievedProfileDataPromise === null) {
      // No capture operation has been started, write a message and throw an error.
      console.error(
        `[devtools perf actor] In getPreviouslyCapturedProfileDataBulk, there's no data to be returned.`
      );
      throw new Error(`The requested data was not found.`);
    }

    // Note that this promise might be rejected if there was an error. That's OK
    // and part of the design.
    const profile = await this.#previouslyRetrievedProfileDataPromise;
    this.#previouslyRetrievedProfileDataPromise = null;

    const bulk = await startBulkSend(profile.byteLength);
    await bulk.copyFromBuffer(profile);
  }

  /**
   * @param {number} handle returned by startCaptureAndStopProfiler
   * @returns {Promise<MockedExports.ProfileGenerationAdditionalInformation>}
   */

  async getPreviouslyRetrievedAdditionalInformation(handle) {
    if (handle < this.#captureHandleCounter) {
      // This handle is outdated, write a message to the console and throw an error
      console.error(
        `[devtools perf actor] In getPreviouslyRetrievedAdditionalInformation, the requested handle ${handle} is smaller than the current counter ${this.#captureHandleCounter}.`
      );
      throw new Error(`The requested data was not found.`);
    }

    if (this.#previouslyRetrievedAdditionalInformationPromise === null) {
      // No capture operation has been started, write a message and throw an error.
      console.error(
        `[devtools perf actor] In getPreviouslyRetrievedAdditionalInformation, there's no data to be returned.`
      );
      throw new Error(`The requested data was not found.`);
    }

    try {
      return this.#previouslyRetrievedAdditionalInformationPromise;
    } finally {
      this.#previouslyRetrievedAdditionalInformationPromise = null;
    }
  }

  isActive() {
    if (!IS_SUPPORTED_PLATFORM) {
      return false;
    }
    return Services.profiler.IsActive();
  }

  isSupportedPlatform() {
    return IS_SUPPORTED_PLATFORM;
  }

  /**
   * Watch for events that happen within the browser. These can affect the
   * current availability and state of the Gecko Profiler.
   */

  _observe(subject, topic, _data) {
    // Note! If emitting new events make sure and update the list of bridged
    // events in the perf actor.
    switch (topic) {
      case "profiler-started": {
        const param = subject.QueryInterface(Ci.nsIProfilerStartParams);
        this.emit(
          topic,
          param.entries,
          param.interval,
          param.features,
          param.duration,
          param.activeTabID
        );
        break;
      }
      case "profiler-stopped":
        this.emit(topic);
        break;
    }
  }

  /**
   * Lists the supported features of the profiler for the current browser.
   *
   * @returns {string[]}
   */

  getSupportedFeatures() {
    if (!IS_SUPPORTED_PLATFORM) {
      return [];
    }
    return Services.profiler.GetFeatures();
  }
};

Messung V0.5 in Prozent
C=66 H=99 G=83

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=752002