Skip to content
This repository has been archived by the owner on Feb 12, 2022. It is now read-only.

Fix duplicate edges issue in Prepack heap visualization #1308

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ export type SerializerOptions = {
inlineExpressions?: boolean,
simpleClosures?: boolean,
trace?: boolean,
heapGraph?: boolean,
heapGraphFormat?: "DotLanguage" | "VISJS",
};

export type PartialEvaluatorOptions = {
Expand Down
2 changes: 1 addition & 1 deletion src/prepack-cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ function run(
timeout: timeout,
additionalFunctions: additionalFunctions,
lazyObjectsRuntime: lazyObjectsRuntime,
heapGraphFilePath: heapGraphFilePath,
heapGraphFormat: "DotLanguage",
debugInFilePath: debugInFilePath,
debugOutFilePath: debugOutFilePath,
},
Expand Down
8 changes: 5 additions & 3 deletions src/prepack-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export type PrepackOptions = {|
additionalFunctions?: Array<string>,
abstractEffectsInAdditionalFunctions?: boolean,
lazyObjectsRuntime?: string,
heapGraphFilePath?: string,
heapGraphFormat?: "DotLanguage" | "VISJS",
compatibility?: Compatibility,
debugNames?: boolean,
delayInitializations?: boolean,
Expand Down Expand Up @@ -90,7 +90,7 @@ export function getRealmOptions({
export function getSerializerOptions({
additionalFunctions,
lazyObjectsRuntime,
heapGraphFilePath,
heapGraphFormat,
delayInitializations = false,
delayUnsupportedRequires = false,
accelerateUnsupportedRequires = true,
Expand All @@ -117,12 +117,14 @@ export function getSerializerOptions({
inlineExpressions,
simpleClosures,
trace,
heapGraph: !!heapGraphFilePath,
};
if (additionalFunctions) result.additionalFunctions = additionalFunctions;
if (lazyObjectsRuntime !== undefined) {
result.lazyObjectsRuntime = lazyObjectsRuntime;
}
if (heapGraphFormat !== undefined) {
result.heapGraphFormat = heapGraphFormat;
}
return result;
}

Expand Down
25 changes: 20 additions & 5 deletions src/serializer/ResidualHeapGraphGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,20 @@ export class ResidualHeapGraphGenerator extends ResidualHeapVisitor {
return val.__originalName ? `${serializedId.name}(${val.__originalName})` : serializedId.name;
}

_generateGraphData(nodes: Set<Value>, edges: Array<Edge>): string {
_generateDotGraphData(nodes: Set<Value>, edges: Array<Edge>): string {
let content = "digraph{\n";
for (const val of nodes) {
const nodeId = this._getValueId(val);
content += ` node${nodeId} [shape=${this._getValueShape(val)} label=${this._getValueLabel(val)}];\n`;
}
for (const edge of edges) {
content += ` node${edge.fromId} -> node${edge.toId};\n`;
}
content += "}";
return content;
}

_generateVisJSGraphData(nodes: Set<Value>, edges: Array<Edge>): string {
let nodesData = [];
let edgesData = [];

Expand All @@ -129,9 +142,9 @@ export class ResidualHeapGraphGenerator extends ResidualHeapVisitor {
nodesData.push(nodeData);
}

for (let edge of edges) {
for (let [index, edge] of edges.entries()) {
let edgeData = {
id: `${edge.fromId}-${edge.toId}`,
id: index,
from: `${edge.fromId}`,
to: `${edge.toId}`,
arrows: "to",
Expand Down Expand Up @@ -184,7 +197,9 @@ export class ResidualHeapGraphGenerator extends ResidualHeapVisitor {
return shape;
}

generateResult(): string {
return this._generateGraphData(this._visitedValues, this._edges);
generateResult(heapGraphFormat: "DotLanguage" | "VISJS"): string {
return heapGraphFormat === "DotLanguage"
? this._generateDotGraphData(this._visitedValues, this._edges)
: this._generateVisJSGraphData(this._visitedValues, this._edges);
}
}
5 changes: 3 additions & 2 deletions src/serializer/serializer.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export class Serializer {
);

let heapGraph;
if (this.options.heapGraph) {
if (this.options.heapGraphFormat) {
const heapRefCounter = new ResidualHeapRefCounter(
this.realm,
this.logger,
Expand All @@ -161,7 +161,8 @@ export class Serializer {
heapRefCounter.getResult()
);
heapGraphGenerator.visitRoots();
heapGraph = heapGraphGenerator.generateResult();
invariant(this.options.heapGraphFormat);
heapGraph = heapGraphGenerator.generateResult(this.options.heapGraphFormat);
}

// Phase 2: Let's serialize the heap and generate code.
Expand Down
22 changes: 11 additions & 11 deletions website/js/repl-worker.js
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
self.importScripts('prepack.min.js');

onmessage = function(e) {
var buffer = [];
let buffer = [];

function errorHandler(error) {
// Syntax errors contain their location at the end, remove that
if (error.errorCode === 'PP1004') {
if (error.errorCode === "PP1004") {
let msg = error.message;
error.message = msg.substring(0, msg.lastIndexOf('('));
error.message = msg.substring(0, msg.lastIndexOf("("));
}
buffer.push({
severity: error.severity,
location: error.location,
message: error.message,
errorCode: error.errorCode,
});
return 'Recover';
return "Recover";
}

try {
var sources = [{ filePath: 'dummy', fileContents: e.data.code }];
var options = {
compatibility: 'browser',
filename: 'repl',
let sources = [{ filePath: "dummy", fileContents: e.data.code }];
let options = {
compatibility: "browser",
filename: "repl",
timeout: 1000,
serialize: true,
heapGraphFilePath: "/tmp/foo.txt", /* this path will not be used, it is needed to trigger the graph computation */
heapGraphFormat: "VISJS",
errorHandler,
};
for (var property in e.data.options) {
for (let property in e.data.options) {
if (e.data.options.hasOwnProperty(property)) {
options[property] = e.data.options[property];
}
}
var result = Prepack.prepackSources(sources, options);
let result = Prepack.prepackSources(sources, options);
if (result && !buffer.length) {
postMessage({ type: 'success', data: result.code, graph: result.heapGraph });
} else {
Expand Down