Skip to content

Commit

Permalink
Avoid memory issues with hoisted variables
Browse files Browse the repository at this point in the history
  • Loading branch information
lukastaegert committed Jul 21, 2021
1 parent ea96ab0 commit b6745f0
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/ast/nodes/Identifier.ts
Expand Up @@ -60,7 +60,7 @@ export default class Identifier extends NodeBase implements PatternNode {
variable = this.scope.addDeclaration(this, this.context, init, true);
if (treeshake && treeshake.correctVarValueBeforeDeclaration) {
// Necessary to make sure the init is deoptimized. We cannot call deoptimizePath here.
this.scope.addDeclaration(this, this.context, UNDEFINED_EXPRESSION, true);
variable.markInitializersForDeoptimization();
}
break;
case 'function':
Expand Down
6 changes: 3 additions & 3 deletions src/ast/scopes/BlockScope.ts
@@ -1,7 +1,6 @@
import { AstContext } from '../../Module';
import Identifier from '../nodes/Identifier';
import { ExpressionEntity } from '../nodes/shared/Expression';
import { UNDEFINED_EXPRESSION } from '../values';
import LocalVariable from '../variables/LocalVariable';
import ChildScope from './ChildScope';

Expand All @@ -13,10 +12,11 @@ export default class BlockScope extends ChildScope {
isHoisted: boolean
): LocalVariable {
if (isHoisted) {
this.parent.addDeclaration(identifier, context, init, isHoisted);
const variable = this.parent.addDeclaration(identifier, context, init, isHoisted);
// Necessary to make sure the init is deoptimized for conditional declarations.
// We cannot call deoptimizePath here.
return this.parent.addDeclaration(identifier, context, UNDEFINED_EXPRESSION, isHoisted);
variable.markInitializersForDeoptimization();
return variable;
} else {
return super.addDeclaration(identifier, context, init, false);
}
Expand Down
19 changes: 12 additions & 7 deletions src/ast/variables/LocalVariable.ts
Expand Up @@ -21,7 +21,6 @@ import Variable from './Variable';
const MAX_PATH_DEPTH = 7;

export default class LocalVariable extends Variable {
additionalInitializers: ExpressionEntity[] | null = null;
calledFromTryStatement = false;
declarations: (Identifier | ExportDefaultDeclaration)[];
init: ExpressionEntity | null;
Expand All @@ -30,6 +29,7 @@ export default class LocalVariable extends Variable {
// Caching and deoptimization:
// We track deoptimization when we do not return something unknown
protected deoptimizationTracker: PathTracker;
private additionalInitializers: ExpressionEntity[] | null = null;
private expressionsToBeDeoptimized: DeoptimizableEntity[] = [];

constructor(
Expand All @@ -47,13 +47,9 @@ export default class LocalVariable extends Variable {

addDeclaration(identifier: Identifier, init: ExpressionEntity | null): void {
this.declarations.push(identifier);
if (this.additionalInitializers === null) {
this.additionalInitializers = this.init === null ? [] : [this.init];
this.init = UNKNOWN_EXPRESSION;
this.isReassigned = true;
}
const additionalInitializers = this.markInitializersForDeoptimization();
if (init !== null) {
this.additionalInitializers.push(init);
additionalInitializers.push(init);
}
}

Expand Down Expand Up @@ -212,4 +208,13 @@ export default class LocalVariable extends Variable {
markCalledFromTryStatement(): void {
this.calledFromTryStatement = true;
}

markInitializersForDeoptimization(): ExpressionEntity[] {
if (this.additionalInitializers === null) {
this.additionalInitializers = this.init === null ? [] : [this.init];
this.init = UNKNOWN_EXPRESSION;
this.isReassigned = true;
}
return this.additionalInitializers;
}
}

0 comments on commit b6745f0

Please sign in to comment.