Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(585)

Unified Diff: pkg/compiler/lib/src/js_model/closure.dart

Issue 3007743002: Add boxing for modified variables (Closed)
Patch Set: merged with master Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/compiler/lib/src/closure.dart ('k') | pkg/compiler/lib/src/js_model/closure_visitors.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/js_model/closure.dart
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 236388488216f0fa3e46158507b5993c514583c3..0d9a9df1764227379ffeda3a30605821a994d4bf 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -100,18 +100,23 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
JsClosedWorld closedWorldRefiner) {
closureModels.forEach((MemberEntity member, ScopeModel model) {
KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(member);
- if (model.scopeInfo != null) {
- _scopeMap[member] = new JsScopeInfo.from(model.scopeInfo, localsMap);
- }
+ Map<Local, JRecordField> allBoxedVariables =
+ _elementMap.makeRecordContainer(model.scopeInfo, member, localsMap);
+ _scopeMap[member] =
+ new JsScopeInfo.from(allBoxedVariables, model.scopeInfo, localsMap);
model.capturedScopesMap
.forEach((ir.Node node, KernelCapturedScope scope) {
+ Map<Local, JRecordField> boxedVariables =
+ _elementMap.makeRecordContainer(scope, member, localsMap);
if (scope is KernelCapturedLoopScope) {
_capturedScopesMap[node] =
- new JsCapturedLoopScope.from(scope, localsMap);
+ new JsCapturedLoopScope.from(boxedVariables, scope, localsMap);
} else {
- _capturedScopesMap[node] = new JsCapturedScope.from(scope, localsMap);
+ _capturedScopesMap[node] =
+ new JsCapturedScope.from(boxedVariables, scope, localsMap);
}
+ allBoxedVariables.addAll(boxedVariables);
});
Map<ir.TreeNode, KernelScopeInfo> closuresToGenerate =
@@ -126,7 +131,11 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
failedAt(member, "Unexpected closure node ${node}");
}
KernelClosureClass closureClass = _produceSyntheticElements(
- member, functionNode, closuresToGenerate[node], closedWorldRefiner);
+ member,
+ functionNode,
+ closuresToGenerate[node],
+ allBoxedVariables,
+ closedWorldRefiner);
// Add also for the call method.
_scopeMap[closureClass.callMethod] = closureClass;
}
@@ -143,10 +152,17 @@ class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
MemberEntity member,
ir.FunctionNode node,
KernelScopeInfo info,
+ Map<Local, JRecordField> boxedVariables,
JsClosedWorld closedWorldRefiner) {
KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(member);
KernelClosureClass closureClass = closedWorldRefiner.buildClosureClass(
- member, node, member.library, info, node.location, localsMap);
+ member,
+ node,
+ member.library,
+ boxedVariables,
+ info,
+ node.location,
+ localsMap);
// We want the original declaration where that function is used to point
// to the correct closure class.
@@ -265,29 +281,24 @@ class KernelScopeInfo {
class JsScopeInfo extends ScopeInfo {
final Set<Local> localsUsedInTryOrSync;
final Local thisLocal;
- final Set<Local> boxedVariables;
+ final Map<Local, JRecordField> boxedVariables;
/// The set of variables that were defined in another scope, but are used in
/// this scope.
final Set<Local> freeVariables;
- JsScopeInfo(this.thisLocal, this.localsUsedInTryOrSync, this.boxedVariables,
- this.freeVariables);
-
- JsScopeInfo.from(KernelScopeInfo info, KernelToLocalsMap localsMap)
+ JsScopeInfo.from(
+ this.boxedVariables, KernelScopeInfo info, KernelToLocalsMap localsMap)
: this.thisLocal =
info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
this.localsUsedInTryOrSync =
info.localsUsedInTryOrSync.map(localsMap.getLocalVariable).toSet(),
- this.boxedVariables =
- info.boxedVariables.map(localsMap.getLocalVariable).toSet(),
this.freeVariables =
info.freeVariables.map(localsMap.getLocalVariable).toSet();
void forEachBoxedVariable(f(Local local, FieldEntity field)) {
- boxedVariables.forEach((Local l) {
- // TODO(efortuna): add FieldEntities as created.
- f(l, null);
+ boxedVariables.forEach((Local l, JRecordField box) {
+ f(l, box);
});
}
@@ -301,16 +312,13 @@ class JsScopeInfo extends ScopeInfo {
return sb.toString();
}
- bool isBoxed(Local variable) => boxedVariables.contains(variable);
+ bool isBoxed(Local variable) => boxedVariables.containsKey(variable);
}
class KernelCapturedScope extends KernelScopeInfo {
- final ir.TreeNode context;
-
KernelCapturedScope(
Set<ir.VariableDeclaration> boxedVariables,
NodeBox capturedVariablesAccessor,
- this.context,
Set<ir.VariableDeclaration> localsUsedInTryOrSync,
Set<ir.VariableDeclaration> freeVariables,
bool hasThisLocal)
@@ -323,10 +331,11 @@ class KernelCapturedScope extends KernelScopeInfo {
class JsCapturedScope extends JsScopeInfo implements CapturedScope {
final Local context;
- JsCapturedScope.from(
+ JsCapturedScope.from(Map<Local, JRecordField> boxedVariables,
KernelCapturedScope capturedScope, KernelToLocalsMap localsMap)
- : this.context = localsMap.getLocalVariable(capturedScope.context),
- super.from(capturedScope, localsMap);
+ : this.context =
+ boxedVariables.isNotEmpty ? boxedVariables.values.first.box : null,
+ super.from(boxedVariables, capturedScope, localsMap);
bool get requiresContextBox => boxedVariables.isNotEmpty;
}
@@ -338,12 +347,11 @@ class KernelCapturedLoopScope extends KernelCapturedScope {
Set<ir.VariableDeclaration> boxedVariables,
NodeBox capturedVariablesAccessor,
this.boxedLoopVariables,
- ir.TreeNode context,
Set<ir.VariableDeclaration> localsUsedInTryOrSync,
Set<ir.VariableDeclaration> freeVariables,
bool hasThisLocal)
- : super(boxedVariables, capturedVariablesAccessor, context,
- localsUsedInTryOrSync, freeVariables, hasThisLocal);
+ : super(boxedVariables, capturedVariablesAccessor, localsUsedInTryOrSync,
+ freeVariables, hasThisLocal);
bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty;
}
@@ -351,12 +359,12 @@ class KernelCapturedLoopScope extends KernelCapturedScope {
class JsCapturedLoopScope extends JsCapturedScope implements CapturedLoopScope {
final List<Local> boxedLoopVariables;
- JsCapturedLoopScope.from(
+ JsCapturedLoopScope.from(Map<Local, JRecordField> boxedVariables,
KernelCapturedLoopScope capturedScope, KernelToLocalsMap localsMap)
: this.boxedLoopVariables = capturedScope.boxedLoopVariables
.map(localsMap.getLocalVariable)
.toList(),
- super.from(capturedScope, localsMap);
+ super.from(boxedVariables, capturedScope, localsMap);
bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty;
}
@@ -374,32 +382,32 @@ class KernelClosureClass extends JsScopeInfo
KernelClosureClass.fromScopeInfo(
this.closureClassEntity,
ir.FunctionNode closureSourceNode,
+ Map<Local, JRecordField> boxedVariables,
KernelScopeInfo info,
KernelToLocalsMap localsMap,
this.closureEntity,
this.thisLocal)
- : super.from(info, localsMap);
+ : super.from(boxedVariables, info, localsMap);
List<Local> get createdFieldEntities => localToFieldMap.keys.toList();
FieldEntity get thisFieldEntity => localToFieldMap[thisLocal];
void forEachCapturedVariable(f(Local from, JField to)) {
- localToFieldMap.forEach(f);
+ for (Local l in localToFieldMap.keys) {
+ var jField = localToFieldMap[l];
+ if (l is! BoxLocal) f(l, jField);
+ }
}
@override
void forEachBoxedVariable(f(Local local, JField field)) {
- for (Local l in localToFieldMap.keys) {
- if (localToFieldMap[l] is JRecordField) f(l, localToFieldMap[l]);
- }
+ boxedVariables.forEach(f);
}
void forEachFreeVariable(f(Local variable, JField field)) {
- for (Local l in localToFieldMap.keys) {
- var jField = localToFieldMap[l];
- if (jField is! JRecordField && jField is! BoxLocal) f(l, jField);
- }
+ localToFieldMap.forEach(f);
+ boxedVariables.forEach(f);
}
bool isVariableBoxed(Local variable) =>
« no previous file with comments | « pkg/compiler/lib/src/closure.dart ('k') | pkg/compiler/lib/src/js_model/closure_visitors.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698