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/. */
7 const { memorySpec
} = require("resource://devtools/shared/specs/memory.js");
11 } = require("resource://devtools/shared/protocol.js");
14 ChromeUtils
.defineESModuleGetters(lazy
, {
15 FileUtils
: "resource://gre/modules/FileUtils.sys.mjs",
17 loader
.lazyRequireGetter(
19 "HeapSnapshotFileUtils",
20 "resource://devtools/shared/heapsnapshot/HeapSnapshotFileUtils.js"
23 class MemoryFront
extends FrontClassWithSpec(memorySpec
) {
24 constructor(client
, targetFront
, parentFront
) {
25 super(client
, targetFront
, parentFront
);
26 this._client
= client
;
27 this.heapSnapshotFileActorID
= null;
29 // Attribute name from which to retrieve the actorID out of the target actor's form
30 this.formAttributeName
= "memoryActor";
34 * Save a heap snapshot, transfer it from the server to the client if the
35 * server and client do not share a file system, and return the local file
36 * path to the heap snapshot.
38 * Note that this is safe to call for actors inside sandoxed child processes,
39 * as we jump through the correct IPDL hoops.
41 * @params 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.
45 * @params {Object|undefined} options.boundaries
46 * The boundaries for the heap snapshot. See
47 * ChromeUtils.webidl for more details.
49 * @returns Promise<String>
51 async
saveHeapSnapshot(options
= {}) {
52 const snapshotId
= await
super.saveHeapSnapshot(options
.boundaries
);
56 (await HeapSnapshotFileUtils
.haveHeapSnapshotTempFile(snapshotId
))
58 return HeapSnapshotFileUtils
.getHeapSnapshotTempFilePath(snapshotId
);
61 return this.transferHeapSnapshot(snapshotId
);
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
69 * @param {String} snapshotId
71 * @returns Promise<String>
73 async
transferHeapSnapshot(snapshotId
) {
74 if (!this.heapSnapshotFileActorID
) {
75 const form
= await
this._client
.mainRoot
.rootForm
;
76 this.heapSnapshotFileActorID
= form
.heapSnapshotFileActor
;
80 const request
= this._client
.request({
81 to
: this.heapSnapshotFileActorID
,
82 type
: "transferHeapSnapshot",
87 HeapSnapshotFileUtils
.getNewUniqueHeapSnapshotTempFilePath();
88 const outFile
= new lazy
.FileUtils
.File(outFilePath
);
89 const outFileStream
= lazy
.FileUtils
.openSafeFileOutputStream(outFile
);
91 // This request is a bulk request. That's why the result of the request is
92 // an object with the `copyTo` function that can transfer the data to
94 // See devtools/shared/transport/transport.js to know more about this mode.
95 const { copyTo
} = await request
;
96 await
copyTo(outFileStream
);
98 lazy
.FileUtils
.closeSafeFileOutputStream(outFileStream
);
102 // This isn't a real error, rather this is a message coming from the
103 // server. So let's throw a real error instead.
105 `The server's actor threw an error: (${e.error}) ${e.message}`
109 // Otherwise, rethrow the error
115 exports
.MemoryFront
= MemoryFront
;
116 registerFront(MemoryFront
);