diff --git a/scripts/test-runner.js b/scripts/test-runner.js index cceac8eac5..9c6613353e 100644 --- a/scripts/test-runner.js +++ b/scripts/test-runner.js @@ -286,6 +286,7 @@ function runTest(name, code, options: PrepackOptions, args) { options.invariantLevel = code.includes("// omit invariants") || args.verbose ? 0 : 99; if (code.includes("// emit concrete model")) options.emitConcreteModel = true; if (code.includes("// exceeds stack limit")) options.maxStackDepth = 10; + if (code.includes("// heapGraphFilePath")) options.heapGraphFormat = "VISJS"; if (code.includes("// react")) { options.reactEnabled = true; options.reactOutput = "jsx"; diff --git a/src/serializer/serializer.js b/src/serializer/serializer.js index 0849c6ffc6..57329d4283 100644 --- a/src/serializer/serializer.js +++ b/src/serializer/serializer.js @@ -182,6 +182,9 @@ export class Serializer { additionalFunctionValuesAndEffects, referentializer ); + // Copying dERB map so cache lookup returns the same object, and the subsequent + // invariant in ModifiedBindingEntry's visit() passes. + heapRefCounter.declarativeEnvironmentRecordsBindings = residualHeapVisitor.declarativeEnvironmentRecordsBindings; heapRefCounter.visitRoots(); const heapGraphGenerator = new ResidualHeapGraphGenerator( @@ -193,6 +196,7 @@ export class Serializer { heapRefCounter.getResult(), referentializer ); + heapGraphGenerator.declarativeEnvironmentRecordsBindings = residualHeapVisitor.declarativeEnvironmentRecordsBindings; heapGraphGenerator.visitRoots(); invariant(this.options.heapGraphFormat); heapGraph = heapGraphGenerator.generateResult(this.options.heapGraphFormat); diff --git a/src/utils/generator.js b/src/utils/generator.js index 75c91f95a5..b4a7f52f02 100644 --- a/src/utils/generator.js +++ b/src/utils/generator.js @@ -253,10 +253,11 @@ class ModifiedBindingEntry extends GeneratorEntry { containingGenerator === this.containingGenerator, "This entry requires effects to be applied and may not be moved" ); - invariant(this.modifiedBinding.value === this.newValue); + invariant(this.modifiedBinding.value === this.newValue, "ModifiedBinding's value has been improperly modified."); let [residualBinding, newValue] = context.visitModifiedBinding(this.modifiedBinding); - invariant(this.residualFunctionBinding === undefined || this.residualFunctionBinding === residualBinding); + invariant(this.residualFunctionBinding === undefined || this.residualFunctionBinding === residualBinding, "ResidualFunctionBinding improperly mutated"); this.residualFunctionBinding = residualBinding; + this.modifiedBinding.value = newValue; this.newValue = newValue; return true; } diff --git a/test/serializer/additional-functions/heapGraph.js b/test/serializer/additional-functions/heapGraph.js new file mode 100644 index 0000000000..9df2941e40 --- /dev/null +++ b/test/serializer/additional-functions/heapGraph.js @@ -0,0 +1,18 @@ +// Tests that code with heapgraph enabled doesn't crash. +// Regression test for issue #1732. + +// heapGraphFilePath + +(function () { + let a = global.__abstract ? __abstract("number", "5") : 5; + let b, c; + global.f = function() { + b = a + 42; + c = a + 42; + return b; + } + global.__optimize && __optimize(f); + +})(); + +inspect = function() { return global.f(); } \ No newline at end of file