mirror of
https://github.com/facebookarchive/prepack.git
synced 2024-08-17 10:30:32 +03:00
Refactoring of Generator DAG to Generator Tree. (#2434)
Summary: Release notes: None To avoid all kinds of serialization issues, generators should form a tree, and not a DAG. This is an attempt to establish that. Pull Request resolved: https://github.com/facebook/prepack/pull/2434 Differential Revision: D9887684 Pulled By: NTillmann fbshipit-source-id: c11c50c56dcd6eff02bd03448756bf79f6e2c820
This commit is contained in:
parent
0dced15809
commit
4b911f2138
@ -13,14 +13,13 @@ import invariant from "../invariant.js";
|
|||||||
import { FunctionValue, ObjectValue } from "../values/index.js";
|
import { FunctionValue, ObjectValue } from "../values/index.js";
|
||||||
import { Generator } from "../utils/generator.js";
|
import { Generator } from "../utils/generator.js";
|
||||||
|
|
||||||
// This class maintains a DAG containing all generators known so far,
|
// This class maintains a tree containing all generators known so far,
|
||||||
// and information about the most specific generator that created any
|
// and information about the most specific generator that created any
|
||||||
// particular object.
|
// particular object.
|
||||||
// New sub-DAGs are added in chunks, at the beginning for the global generator,
|
// New sub-trees are added in chunks, at the beginning for the global generator,
|
||||||
// and every time the visitor handles another additional function.
|
// and every time the visitor handles another additional function.
|
||||||
// NOTE: The serializer can only properly handle Generator trees, not actual DAGs.
|
export class GeneratorTree {
|
||||||
export class GeneratorDAG {
|
parents: Map<Generator, Generator | FunctionValue | "GLOBAL">;
|
||||||
parents: Map<Generator, Array<Generator | FunctionValue | "GLOBAL">>;
|
|
||||||
createdObjects: Map<ObjectValue, Generator>;
|
createdObjects: Map<ObjectValue, Generator>;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@ -28,16 +27,10 @@ export class GeneratorDAG {
|
|||||||
this.createdObjects = new Map();
|
this.createdObjects = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
// DAG TODO: This function is dubious in the presence of actual dags.
|
|
||||||
getParent(generator: Generator): Generator | FunctionValue | "GLOBAL" {
|
getParent(generator: Generator): Generator | FunctionValue | "GLOBAL" {
|
||||||
let a = this.parents.get(generator);
|
let parent = this.parents.get(generator);
|
||||||
invariant(a !== undefined && a.length >= 1);
|
invariant(parent !== undefined);
|
||||||
return a[0];
|
return parent;
|
||||||
}
|
|
||||||
|
|
||||||
isParent(parent: Generator | FunctionValue | "GLOBAL", generator: Generator): boolean {
|
|
||||||
let a = this.parents.get(generator);
|
|
||||||
return a !== undefined && a.includes(parent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCreator(value: ObjectValue): Generator | void {
|
getCreator(value: ObjectValue): Generator | void {
|
||||||
@ -49,9 +42,8 @@ export class GeneratorDAG {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_add(parent: Generator | FunctionValue | "GLOBAL", generator: Generator): void {
|
_add(parent: Generator | FunctionValue | "GLOBAL", generator: Generator): void {
|
||||||
let a = this.parents.get(generator);
|
invariant(!this.parents.has(generator));
|
||||||
if (a === undefined) this.parents.set(generator, (a = []));
|
this.parents.set(generator, parent);
|
||||||
if (!a.includes(parent)) a.push(parent);
|
|
||||||
let effects = generator.effectsToApply;
|
let effects = generator.effectsToApply;
|
||||||
if (effects !== undefined) {
|
if (effects !== undefined) {
|
||||||
invariant(parent instanceof FunctionValue);
|
invariant(parent instanceof FunctionValue);
|
@ -24,7 +24,7 @@ import { ResidualHeapSerializer } from "./ResidualHeapSerializer.js";
|
|||||||
import { getOrDefault } from "./utils.js";
|
import { getOrDefault } from "./utils.js";
|
||||||
import type { ResidualOptimizedFunctions } from "./ResidualOptimizedFunctions";
|
import type { ResidualOptimizedFunctions } from "./ResidualOptimizedFunctions";
|
||||||
import type { Referentializer } from "./Referentializer.js";
|
import type { Referentializer } from "./Referentializer.js";
|
||||||
import { GeneratorDAG } from "./GeneratorDAG.js";
|
import { GeneratorTree } from "./GeneratorTree.js";
|
||||||
|
|
||||||
const LAZY_OBJECTS_SERIALIZER_BODY_TYPE = "LazyObjectInitializer";
|
const LAZY_OBJECTS_SERIALIZER_BODY_TYPE = "LazyObjectInitializer";
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ export class LazyObjectsSerializer extends ResidualHeapSerializer {
|
|||||||
options: SerializerOptions,
|
options: SerializerOptions,
|
||||||
additionalFunctionValuesAndEffects: Map<FunctionValue, AdditionalFunctionEffects>,
|
additionalFunctionValuesAndEffects: Map<FunctionValue, AdditionalFunctionEffects>,
|
||||||
referentializer: Referentializer,
|
referentializer: Referentializer,
|
||||||
generatorDAG: GeneratorDAG,
|
generatorTree: GeneratorTree,
|
||||||
residualOptimizedFunctions: ResidualOptimizedFunctions
|
residualOptimizedFunctions: ResidualOptimizedFunctions
|
||||||
) {
|
) {
|
||||||
super(
|
super(
|
||||||
@ -62,7 +62,7 @@ export class LazyObjectsSerializer extends ResidualHeapSerializer {
|
|||||||
options,
|
options,
|
||||||
additionalFunctionValuesAndEffects,
|
additionalFunctionValuesAndEffects,
|
||||||
referentializer,
|
referentializer,
|
||||||
generatorDAG,
|
generatorTree,
|
||||||
residualOptimizedFunctions
|
residualOptimizedFunctions
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ import { ResidualReactElementSerializer } from "./ResidualReactElementSerializer
|
|||||||
import type { Binding } from "../environment.js";
|
import type { Binding } from "../environment.js";
|
||||||
import { GlobalEnvironmentRecord, DeclarativeEnvironmentRecord } from "../environment.js";
|
import { GlobalEnvironmentRecord, DeclarativeEnvironmentRecord } from "../environment.js";
|
||||||
import type { Referentializer } from "./Referentializer.js";
|
import type { Referentializer } from "./Referentializer.js";
|
||||||
import { GeneratorDAG } from "./GeneratorDAG.js";
|
import { GeneratorTree } from "./GeneratorTree.js";
|
||||||
import { type Replacement, getReplacement } from "./ResidualFunctionInstantiator.js";
|
import { type Replacement, getReplacement } from "./ResidualFunctionInstantiator.js";
|
||||||
import { describeValue } from "../utils.js";
|
import { describeValue } from "../utils.js";
|
||||||
import { getAsPropertyNameExpression } from "../utils/babelhelpers.js";
|
import { getAsPropertyNameExpression } from "../utils/babelhelpers.js";
|
||||||
@ -123,7 +123,7 @@ export class ResidualHeapSerializer {
|
|||||||
options: SerializerOptions,
|
options: SerializerOptions,
|
||||||
additionalFunctionValuesAndEffects: Map<FunctionValue, AdditionalFunctionEffects>,
|
additionalFunctionValuesAndEffects: Map<FunctionValue, AdditionalFunctionEffects>,
|
||||||
referentializer: Referentializer,
|
referentializer: Referentializer,
|
||||||
generatorDAG: GeneratorDAG,
|
generatorTree: GeneratorTree,
|
||||||
residualOptimizedFunctions: ResidualOptimizedFunctions
|
residualOptimizedFunctions: ResidualOptimizedFunctions
|
||||||
) {
|
) {
|
||||||
this.realm = realm;
|
this.realm = realm;
|
||||||
@ -215,7 +215,7 @@ export class ResidualHeapSerializer {
|
|||||||
this.rewrittenAdditionalFunctions = new Map();
|
this.rewrittenAdditionalFunctions = new Map();
|
||||||
this.declarativeEnvironmentRecordsBindings = residualHeapInfo.declarativeEnvironmentRecordsBindings;
|
this.declarativeEnvironmentRecordsBindings = residualHeapInfo.declarativeEnvironmentRecordsBindings;
|
||||||
this.globalBindings = residualHeapInfo.globalBindings;
|
this.globalBindings = residualHeapInfo.globalBindings;
|
||||||
this.generatorDAG = generatorDAG;
|
this.generatorTree = generatorTree;
|
||||||
this.conditionalFeasibility = residualHeapInfo.conditionalFeasibility;
|
this.conditionalFeasibility = residualHeapInfo.conditionalFeasibility;
|
||||||
this.additionalFunctionGenerators = new Map();
|
this.additionalFunctionGenerators = new Map();
|
||||||
this.declaredGlobalLets = new Map();
|
this.declaredGlobalLets = new Map();
|
||||||
@ -274,7 +274,7 @@ export class ResidualHeapSerializer {
|
|||||||
// TODO: revisit this and fix additional functions to be capable of delaying initializations
|
// TODO: revisit this and fix additional functions to be capable of delaying initializations
|
||||||
additionalFunctionValueNestedFunctions: Set<FunctionValue>;
|
additionalFunctionValueNestedFunctions: Set<FunctionValue>;
|
||||||
|
|
||||||
generatorDAG: GeneratorDAG;
|
generatorTree: GeneratorTree;
|
||||||
conditionalFeasibility: Map<AbstractValue, { t: boolean, f: boolean }>;
|
conditionalFeasibility: Map<AbstractValue, { t: boolean, f: boolean }>;
|
||||||
additionalGeneratorRoots: Map<Generator, Set<ObjectValue>>;
|
additionalGeneratorRoots: Map<Generator, Set<ObjectValue>>;
|
||||||
|
|
||||||
@ -888,7 +888,7 @@ export class ResidualHeapSerializer {
|
|||||||
generators = generators.filter(generator => {
|
generators = generators.filter(generator => {
|
||||||
let s = generator;
|
let s = generator;
|
||||||
while (s instanceof Generator) {
|
while (s instanceof Generator) {
|
||||||
s = this.generatorDAG.getParent(s);
|
s = this.generatorTree.getParent(s);
|
||||||
}
|
}
|
||||||
return s === "GLOBAL";
|
return s === "GLOBAL";
|
||||||
});
|
});
|
||||||
@ -904,7 +904,7 @@ export class ResidualHeapSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getGeneratorParent = g => {
|
const getGeneratorParent = g => {
|
||||||
let s = this.generatorDAG.getParent(g);
|
let s = this.generatorTree.getParent(g);
|
||||||
return s instanceof Generator ? s : undefined;
|
return s instanceof Generator ? s : undefined;
|
||||||
};
|
};
|
||||||
// This value is referenced from more than one generator.
|
// This value is referenced from more than one generator.
|
||||||
@ -2132,7 +2132,7 @@ export class ResidualHeapSerializer {
|
|||||||
|
|
||||||
_annotateGeneratorStatements(generator: Generator, statements: Array<BabelNodeStatement>): void {
|
_annotateGeneratorStatements(generator: Generator, statements: Array<BabelNodeStatement>): void {
|
||||||
let comment = `generator "${generator.getName()}"`;
|
let comment = `generator "${generator.getName()}"`;
|
||||||
let parent = this.generatorDAG.getParent(generator);
|
let parent = this.generatorTree.getParent(generator);
|
||||||
if (parent instanceof Generator) {
|
if (parent instanceof Generator) {
|
||||||
comment = `${comment} with parent "${parent.getName()}"`;
|
comment = `${comment} with parent "${parent.getName()}"`;
|
||||||
} else if (parent instanceof FunctionValue) {
|
} else if (parent instanceof FunctionValue) {
|
||||||
@ -2574,7 +2574,7 @@ export class ResidualHeapSerializer {
|
|||||||
for (let s of scopes)
|
for (let s of scopes)
|
||||||
if (s instanceof Generator) {
|
if (s instanceof Generator) {
|
||||||
let text = "";
|
let text = "";
|
||||||
for (; s instanceof Generator; s = this.generatorDAG.getParent(s)) text += "=>" + s.getName();
|
for (; s instanceof Generator; s = this.generatorTree.getParent(s)) text += "=>" + s.getName();
|
||||||
console.log(` ${text}`);
|
console.log(` ${text}`);
|
||||||
} else {
|
} else {
|
||||||
invariant(s instanceof FunctionValue);
|
invariant(s instanceof FunctionValue);
|
||||||
|
@ -65,7 +65,7 @@ import {
|
|||||||
import { createPathConditions, Environment, To } from "../singletons.js";
|
import { createPathConditions, Environment, To } from "../singletons.js";
|
||||||
import { isReactElement, isReactPropsObject, valueIsReactLibraryObject } from "../react/utils.js";
|
import { isReactElement, isReactPropsObject, valueIsReactLibraryObject } from "../react/utils.js";
|
||||||
import { ResidualReactElementVisitor } from "./ResidualReactElementVisitor.js";
|
import { ResidualReactElementVisitor } from "./ResidualReactElementVisitor.js";
|
||||||
import { GeneratorDAG } from "./GeneratorDAG.js";
|
import { GeneratorTree } from "./GeneratorTree.js";
|
||||||
import { PropertyDescriptor, AbstractJoinedDescriptor } from "../descriptors.js";
|
import { PropertyDescriptor, AbstractJoinedDescriptor } from "../descriptors.js";
|
||||||
|
|
||||||
type BindingState = {|
|
type BindingState = {|
|
||||||
@ -113,7 +113,7 @@ export class ResidualHeapVisitor {
|
|||||||
this.globalEnvironmentRecord = environment;
|
this.globalEnvironmentRecord = environment;
|
||||||
this.additionalGeneratorRoots = new Map();
|
this.additionalGeneratorRoots = new Map();
|
||||||
this.residualReactElementVisitor = new ResidualReactElementVisitor(this.realm, this);
|
this.residualReactElementVisitor = new ResidualReactElementVisitor(this.realm, this);
|
||||||
this.generatorDAG = new GeneratorDAG();
|
this.generatorTree = new GeneratorTree();
|
||||||
}
|
}
|
||||||
|
|
||||||
realm: Realm;
|
realm: Realm;
|
||||||
@ -142,7 +142,7 @@ export class ResidualHeapVisitor {
|
|||||||
classMethodInstances: Map<FunctionValue, ClassMethodInstance>;
|
classMethodInstances: Map<FunctionValue, ClassMethodInstance>;
|
||||||
// Parents will always be a generator, optimized function value or "GLOBAL"
|
// Parents will always be a generator, optimized function value or "GLOBAL"
|
||||||
additionalGeneratorRoots: Map<Generator, Set<ObjectValue>>;
|
additionalGeneratorRoots: Map<Generator, Set<ObjectValue>>;
|
||||||
generatorDAG: GeneratorDAG;
|
generatorTree: GeneratorTree;
|
||||||
globalEnvironmentRecord: GlobalEnvironmentRecord;
|
globalEnvironmentRecord: GlobalEnvironmentRecord;
|
||||||
residualReactElementVisitor: ResidualReactElementVisitor;
|
residualReactElementVisitor: ResidualReactElementVisitor;
|
||||||
|
|
||||||
@ -151,13 +151,13 @@ export class ResidualHeapVisitor {
|
|||||||
_getCommonScope(): FunctionValue | Generator {
|
_getCommonScope(): FunctionValue | Generator {
|
||||||
let s = this.scope;
|
let s = this.scope;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (s instanceof Generator) s = this.generatorDAG.getParent(s);
|
if (s instanceof Generator) s = this.generatorTree.getParent(s);
|
||||||
else if (s instanceof FunctionValue) {
|
else if (s instanceof FunctionValue) {
|
||||||
// Did we find an additional function?
|
// Did we find an additional function?
|
||||||
if (this.additionalFunctionValuesAndEffects.has(s)) return s;
|
if (this.additionalFunctionValuesAndEffects.has(s)) return s;
|
||||||
|
|
||||||
// Did the function itself get created by a generator we can chase?
|
// Did the function itself get created by a generator we can chase?
|
||||||
s = this.generatorDAG.getCreator(s) || "GLOBAL";
|
s = this.generatorTree.getCreator(s) || "GLOBAL";
|
||||||
} else {
|
} else {
|
||||||
invariant(s === "GLOBAL");
|
invariant(s === "GLOBAL");
|
||||||
let generator = this.globalGenerator;
|
let generator = this.globalGenerator;
|
||||||
@ -179,7 +179,7 @@ export class ResidualHeapVisitor {
|
|||||||
// created --- this causes the value later to be serialized in its
|
// created --- this causes the value later to be serialized in its
|
||||||
// creation scope, ensuring that the value has the right creation / life time.
|
// creation scope, ensuring that the value has the right creation / life time.
|
||||||
_registerAdditionalRoot(value: ObjectValue): void {
|
_registerAdditionalRoot(value: ObjectValue): void {
|
||||||
let creationGenerator = this.generatorDAG.getCreator(value) || this.globalGenerator;
|
let creationGenerator = this.generatorTree.getCreator(value) || this.globalGenerator;
|
||||||
|
|
||||||
let additionalFunction = this._getAdditionalFunctionOfScope() || "GLOBAL";
|
let additionalFunction = this._getAdditionalFunctionOfScope() || "GLOBAL";
|
||||||
let targetAdditionalFunction;
|
let targetAdditionalFunction;
|
||||||
@ -188,7 +188,7 @@ export class ResidualHeapVisitor {
|
|||||||
} else {
|
} else {
|
||||||
let s = creationGenerator;
|
let s = creationGenerator;
|
||||||
while (s instanceof Generator) {
|
while (s instanceof Generator) {
|
||||||
s = this.generatorDAG.getParent(s);
|
s = this.generatorTree.getParent(s);
|
||||||
invariant(s !== undefined);
|
invariant(s !== undefined);
|
||||||
}
|
}
|
||||||
invariant(s === "GLOBAL" || s instanceof FunctionValue);
|
invariant(s === "GLOBAL" || s instanceof FunctionValue);
|
||||||
@ -206,7 +206,7 @@ export class ResidualHeapVisitor {
|
|||||||
additionalFVEffects.additionalRoots.add(value);
|
additionalFVEffects.additionalRoots.add(value);
|
||||||
|
|
||||||
this._visitInUnrelatedScope(creationGenerator, value);
|
this._visitInUnrelatedScope(creationGenerator, value);
|
||||||
usageScope = this.generatorDAG.getCreator(value) || this.globalGenerator;
|
usageScope = this.generatorTree.getCreator(value) || this.globalGenerator;
|
||||||
}
|
}
|
||||||
|
|
||||||
usageScope = this.scope;
|
usageScope = this.scope;
|
||||||
@ -215,7 +215,7 @@ export class ResidualHeapVisitor {
|
|||||||
// applying effects; if so, store additional information that the serializer
|
// applying effects; if so, store additional information that the serializer
|
||||||
// can use to proactive serialize such objects from within the right generator
|
// can use to proactive serialize such objects from within the right generator
|
||||||
let anyRelevantEffects = false;
|
let anyRelevantEffects = false;
|
||||||
for (let g = usageScope; g instanceof Generator; g = this.generatorDAG.getParent(g)) {
|
for (let g = usageScope; g instanceof Generator; g = this.generatorTree.getParent(g)) {
|
||||||
if (g === creationGenerator) {
|
if (g === creationGenerator) {
|
||||||
if (anyRelevantEffects) {
|
if (anyRelevantEffects) {
|
||||||
let s = this.additionalGeneratorRoots.get(g);
|
let s = this.additionalGeneratorRoots.get(g);
|
||||||
@ -1098,7 +1098,7 @@ export class ResidualHeapVisitor {
|
|||||||
if (this.preProcessValue(val)) this.visitValueProxy(val);
|
if (this.preProcessValue(val)) this.visitValueProxy(val);
|
||||||
this.postProcessValue(val);
|
this.postProcessValue(val);
|
||||||
} else if (val instanceof FunctionValue) {
|
} else if (val instanceof FunctionValue) {
|
||||||
let creationGenerator = this.generatorDAG.getCreator(val) || this.globalGenerator;
|
let creationGenerator = this.generatorTree.getCreator(val) || this.globalGenerator;
|
||||||
|
|
||||||
// 1. Visit function in its creation scope
|
// 1. Visit function in its creation scope
|
||||||
this._enqueueWithUnrelatedScope(creationGenerator, () => {
|
this._enqueueWithUnrelatedScope(creationGenerator, () => {
|
||||||
@ -1132,7 +1132,7 @@ export class ResidualHeapVisitor {
|
|||||||
let callbacks = {
|
let callbacks = {
|
||||||
visitEquivalentValue: this.visitEquivalentValue.bind(this),
|
visitEquivalentValue: this.visitEquivalentValue.bind(this),
|
||||||
visitGenerator: (generator, parent) => {
|
visitGenerator: (generator, parent) => {
|
||||||
invariant(this.generatorDAG.isParent(parent, generator));
|
invariant(this.generatorTree.getParent(generator) === parent);
|
||||||
this.visitGenerator(generator, additionalFunctionInfo);
|
this.visitGenerator(generator, additionalFunctionInfo);
|
||||||
},
|
},
|
||||||
canOmit: (value: Value): boolean => {
|
canOmit: (value: Value): boolean => {
|
||||||
@ -1282,7 +1282,7 @@ export class ResidualHeapVisitor {
|
|||||||
this.additionalFunctionValueInfos.set(functionValue, additionalFunctionInfo);
|
this.additionalFunctionValueInfos.set(functionValue, additionalFunctionInfo);
|
||||||
|
|
||||||
let effectsGenerator = additionalEffects.generator;
|
let effectsGenerator = additionalEffects.generator;
|
||||||
this.generatorDAG.add(functionValue, effectsGenerator);
|
this.generatorTree.add(functionValue, effectsGenerator);
|
||||||
this.visitGenerator(effectsGenerator, additionalFunctionInfo);
|
this.visitGenerator(effectsGenerator, additionalFunctionInfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1294,7 +1294,7 @@ export class ResidualHeapVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
visitRoots(): void {
|
visitRoots(): void {
|
||||||
this.generatorDAG.add("GLOBAL", this.globalGenerator);
|
this.generatorTree.add("GLOBAL", this.globalGenerator);
|
||||||
this.visitGenerator(this.globalGenerator);
|
this.visitGenerator(this.globalGenerator);
|
||||||
for (let moduleValue of this.modules.initializedModules.values()) this.visitValue(moduleValue);
|
for (let moduleValue of this.modules.initializedModules.values()) this.visitValue(moduleValue);
|
||||||
|
|
||||||
@ -1316,7 +1316,7 @@ export class ResidualHeapVisitor {
|
|||||||
let expected = 0;
|
let expected = 0;
|
||||||
for (let { scope, action } of this.delayedActions) {
|
for (let { scope, action } of this.delayedActions) {
|
||||||
let generator;
|
let generator;
|
||||||
if (scope instanceof FunctionValue) generator = this.generatorDAG.getCreator(scope) || this.globalGenerator;
|
if (scope instanceof FunctionValue) generator = this.generatorTree.getCreator(scope) || this.globalGenerator;
|
||||||
else if (scope === "GLOBAL") generator = this.globalGenerator;
|
else if (scope === "GLOBAL") generator = this.globalGenerator;
|
||||||
else {
|
else {
|
||||||
invariant(scope instanceof Generator);
|
invariant(scope instanceof Generator);
|
||||||
@ -1370,10 +1370,10 @@ export class ResidualHeapVisitor {
|
|||||||
info.nestedEffectsRunners.push(runGeneratorAction);
|
info.nestedEffectsRunners.push(runGeneratorAction);
|
||||||
runGeneratorAction = undefined;
|
runGeneratorAction = undefined;
|
||||||
}
|
}
|
||||||
s = this.generatorDAG.getParent(s);
|
s = this.generatorTree.getParent(s);
|
||||||
} else if (s instanceof FunctionValue) {
|
} else if (s instanceof FunctionValue) {
|
||||||
invariant(this.additionalFunctionValuesAndEffects.has(s));
|
invariant(this.additionalFunctionValuesAndEffects.has(s));
|
||||||
s = this.generatorDAG.getCreator(s) || "GLOBAL";
|
s = this.generatorTree.getCreator(s) || "GLOBAL";
|
||||||
}
|
}
|
||||||
invariant(s instanceof Generator || s instanceof FunctionValue || s === "GLOBAL");
|
invariant(s instanceof Generator || s instanceof FunctionValue || s === "GLOBAL");
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
import { FunctionValue } from "../values/index.js";
|
import { FunctionValue } from "../values/index.js";
|
||||||
import type { AdditionalFunctionEffects } from "./types";
|
import type { AdditionalFunctionEffects } from "./types";
|
||||||
import invariant from "../invariant.js";
|
import invariant from "../invariant.js";
|
||||||
import { GeneratorDAG } from "./GeneratorDAG";
|
import { GeneratorTree } from "./GeneratorTree";
|
||||||
import type { Scope } from "./types.js";
|
import type { Scope } from "./types.js";
|
||||||
import { FunctionEnvironmentRecord } from "../environment";
|
import { FunctionEnvironmentRecord } from "../environment";
|
||||||
import type { Value } from "../values/index";
|
import type { Value } from "../values/index";
|
||||||
@ -20,16 +20,16 @@ import { Generator } from "../utils/generator";
|
|||||||
|
|
||||||
export class ResidualOptimizedFunctions {
|
export class ResidualOptimizedFunctions {
|
||||||
constructor(
|
constructor(
|
||||||
generatorDAG: GeneratorDAG,
|
generatorTree: GeneratorTree,
|
||||||
optimizedFunctionsAndEffects: Map<FunctionValue, AdditionalFunctionEffects>,
|
optimizedFunctionsAndEffects: Map<FunctionValue, AdditionalFunctionEffects>,
|
||||||
residualValues: Map<Value, Set<Scope>>
|
residualValues: Map<Value, Set<Scope>>
|
||||||
) {
|
) {
|
||||||
this._generatorDAG = generatorDAG;
|
this._generatorTree = generatorTree;
|
||||||
this._optimizedFunctionsAndEffects = optimizedFunctionsAndEffects;
|
this._optimizedFunctionsAndEffects = optimizedFunctionsAndEffects;
|
||||||
this._residualValues = residualValues;
|
this._residualValues = residualValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
_generatorDAG: GeneratorDAG;
|
_generatorTree: GeneratorTree;
|
||||||
_optimizedFunctionsAndEffects: Map<FunctionValue, AdditionalFunctionEffects>;
|
_optimizedFunctionsAndEffects: Map<FunctionValue, AdditionalFunctionEffects>;
|
||||||
_residualValues: Map<Value, Set<Scope>>;
|
_residualValues: Map<Value, Set<Scope>>;
|
||||||
|
|
||||||
@ -80,7 +80,7 @@ export class ResidualOptimizedFunctions {
|
|||||||
for (let scope of scopes) {
|
for (let scope of scopes) {
|
||||||
let s = scope;
|
let s = scope;
|
||||||
while (s instanceof Generator) {
|
while (s instanceof Generator) {
|
||||||
s = this._generatorDAG.getParent(s);
|
s = this._generatorTree.getParent(s);
|
||||||
}
|
}
|
||||||
if (s === "GLOBAL") return undefined;
|
if (s === "GLOBAL") return undefined;
|
||||||
invariant(s instanceof FunctionValue);
|
invariant(s instanceof FunctionValue);
|
||||||
|
@ -193,7 +193,7 @@ export class Serializer {
|
|||||||
if (this.realm.react.verbose) {
|
if (this.realm.react.verbose) {
|
||||||
this.logger.logInformation(`Visiting evaluated nodes...`);
|
this.logger.logInformation(`Visiting evaluated nodes...`);
|
||||||
}
|
}
|
||||||
let [residualHeapInfo, generatorDAG, inspector] = (() => {
|
let [residualHeapInfo, generatorTree, inspector] = (() => {
|
||||||
let residualHeapVisitor = new ResidualHeapVisitor(
|
let residualHeapVisitor = new ResidualHeapVisitor(
|
||||||
this.realm,
|
this.realm,
|
||||||
this.logger,
|
this.logger,
|
||||||
@ -201,12 +201,12 @@ export class Serializer {
|
|||||||
additionalFunctionValuesAndEffects
|
additionalFunctionValuesAndEffects
|
||||||
);
|
);
|
||||||
statistics.deepTraversal.measure(() => residualHeapVisitor.visitRoots());
|
statistics.deepTraversal.measure(() => residualHeapVisitor.visitRoots());
|
||||||
return [residualHeapVisitor.toInfo(), residualHeapVisitor.generatorDAG, residualHeapVisitor.inspector];
|
return [residualHeapVisitor.toInfo(), residualHeapVisitor.generatorTree, residualHeapVisitor.inspector];
|
||||||
})();
|
})();
|
||||||
if (this.logger.hasErrors()) return undefined;
|
if (this.logger.hasErrors()) return undefined;
|
||||||
|
|
||||||
let residualOptimizedFunctions = new ResidualOptimizedFunctions(
|
let residualOptimizedFunctions = new ResidualOptimizedFunctions(
|
||||||
generatorDAG,
|
generatorTree,
|
||||||
additionalFunctionValuesAndEffects,
|
additionalFunctionValuesAndEffects,
|
||||||
residualHeapInfo.values
|
residualHeapInfo.values
|
||||||
);
|
);
|
||||||
@ -270,7 +270,7 @@ export class Serializer {
|
|||||||
this.options,
|
this.options,
|
||||||
additionalFunctionValuesAndEffects,
|
additionalFunctionValuesAndEffects,
|
||||||
referentializer,
|
referentializer,
|
||||||
generatorDAG,
|
generatorTree,
|
||||||
residualOptimizedFunctions
|
residualOptimizedFunctions
|
||||||
).serialize();
|
).serialize();
|
||||||
});
|
});
|
||||||
@ -293,7 +293,7 @@ export class Serializer {
|
|||||||
this.options,
|
this.options,
|
||||||
additionalFunctionValuesAndEffects,
|
additionalFunctionValuesAndEffects,
|
||||||
referentializer,
|
referentializer,
|
||||||
generatorDAG,
|
generatorTree,
|
||||||
residualOptimizedFunctions
|
residualOptimizedFunctions
|
||||||
).serialize()
|
).serialize()
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user