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

Commit

Permalink
Fix duplicate edges issue in Prepack graph visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
YingHui Tan committed Jan 2, 2018
1 parent d2cbd33 commit 51b9447
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 23 deletions.
3 changes: 2 additions & 1 deletion src/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

/* @flow */

import type { HeapGraphFormat } from "./prepack-options";
import type { ErrorHandler } from "./errors.js";

export type Compatibility = "browser" | "jsc-600-1-4-17" | "node-source-maps" | "node-cli" | "react-mocks";
Expand Down Expand Up @@ -47,7 +48,7 @@ export type SerializerOptions = {
inlineExpressions?: boolean,
simpleClosures?: boolean,
trace?: boolean,
heapGraph?: boolean,
heapGraphFormat?: HeapGraphFormat,
};

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
11 changes: 8 additions & 3 deletions src/prepack-options.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@ import type { SerializerOptions, RealmOptions, Compatibility, DebuggerOptions, R
import { Realm } from "./realm.js";
import invariant from "./invariant.js";

// VIS.JS is used by https://prepack.io REPL to visualize the graph.
export type HeapGraphFormat = "DotLanguage" | "VISJS";

export type PrepackOptions = {|
additionalGlobals?: Realm => void,
additionalFunctions?: Array<string>,
abstractEffectsInAdditionalFunctions?: boolean,
lazyObjectsRuntime?: string,
heapGraphFilePath?: string,
heapGraphFormat?: HeapGraphFormat,
compatibility?: Compatibility,
debugNames?: boolean,
delayInitializations?: boolean,
Expand Down Expand Up @@ -90,7 +93,7 @@ export function getRealmOptions({
export function getSerializerOptions({
additionalFunctions,
lazyObjectsRuntime,
heapGraphFilePath,
heapGraphFormat,
delayInitializations = false,
delayUnsupportedRequires = false,
accelerateUnsupportedRequires = true,
Expand All @@ -117,12 +120,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
26 changes: 21 additions & 5 deletions src/serializer/ResidualHeapGraphGenerator.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import type { Modules } from "./modules.js";
import type { Realm } from "../realm.js";
import type { ObjectRefCount, AdditionalFunctionEffects } from "./types.js";
import type { ResidualHeapValueIdentifiers } from "./ResidualHeapValueIdentifiers";
import type { HeapGraphFormat } from "../prepack-options";

import invariant from "../invariant.js";
import {
Expand Down Expand Up @@ -114,7 +115,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 +143,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 +198,9 @@ export class ResidualHeapGraphGenerator extends ResidualHeapVisitor {
return shape;
}

generateResult(): string {
return this._generateGraphData(this._visitedValues, this._edges);
generateResult(heapGraphFormat: HeapGraphFormat): 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

0 comments on commit 51b9447

Please sign in to comment.