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

Unified Diff: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart

Issue 1080003005: Make the mutable variables local to an IR builder instead of global. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: A pair of bug fixes. Created 5 years, 8 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 | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index decab2ca7dc25ea63cd4b2380e39fbb9d82d27be..51c737d1b1b245171d3e1448e5a1cc1d6dfed077 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -376,7 +376,7 @@ abstract class IrBuilderMixin<N> {
}
/// Shared state between delimited IrBuilders within the same function.
-class IrBuilderDelimitedState {
+class IrBuilderSharedState {
final ConstantSystem constantSystem;
/// A stack of collectors for breaks.
@@ -395,7 +395,7 @@ class IrBuilderDelimitedState {
final List<ir.Definition> functionParameters = <ir.Definition>[];
- IrBuilderDelimitedState(this.constantSystem, this.currentElement);
+ IrBuilderSharedState(this.constantSystem, this.currentElement);
ir.Parameter get thisParameter => _thisParameter;
void set thisParameter(ir.Parameter value) {
@@ -418,20 +418,6 @@ class ThisParameterLocal implements Local {
abstract class IrBuilder {
IrBuilder _makeInstance();
- /// True if [local] should currently be accessed from a [ir.MutableVariable].
- bool isInMutableVariable(Local local);
-
- /// Creates a [ir.MutableVariable] for the given local.
- void makeMutableVariable(Local local);
-
- /// Remove an [ir.MutableVariable] for a local.
- ///
- /// Subsequent access to the local will be direct rather than through the
- /// mutable variable. This is used for variables that do not spend their
- /// entire lifetime as mutable variables (e.g., variables that are boxed
- /// in mutable variables for a try block).
- void removeMutableVariable(Local local);
-
void declareLocalVariable(LocalVariableElement element,
{ir.Primitive initialValue});
@@ -482,7 +468,7 @@ abstract class IrBuilder {
final List<ir.Parameter> _parameters = <ir.Parameter>[];
- IrBuilderDelimitedState state;
+ IrBuilderSharedState state;
/// A map from variable indexes to their values.
///
@@ -490,6 +476,36 @@ abstract class IrBuilder {
/// in the map; look up their [BoxLocal] instead.
Environment environment;
+ /// A map from mutable local variables to their [ir.MutableVariable]s.
+ ///
+ /// Mutable variables are treated as boxed. Writes to them are observable
+ /// side effects.
+ Map<Local, ir.MutableVariable> mutableVariables;
+
+ /// True if [local] should currently be accessed from a [ir.MutableVariable].
+ bool isInMutableVariable(Local local) {
+ return mutableVariables.containsKey(local);
+ }
+
+ /// Creates a [ir.MutableVariable] for the given local.
+ void makeMutableVariable(Local local) {
+ mutableVariables[local] =
+ new ir.MutableVariable(local.executableContext, local);
+ }
+
+ /// Remove an [ir.MutableVariable] for a local.
+ ///
+ /// Subsequent access to the local will be direct rather than through the
+ /// mutable variable.
+ void removeMutableVariable(Local local) {
+ mutableVariables.remove(local);
+ }
+
+ /// Gets the [MutableVariable] containing the value of [local].
+ ir.MutableVariable getMutableVariable(Local local) {
+ return mutableVariables[local];
+ }
+
// The IR builder maintains a context, which is an expression with a hole in
// it. The hole represents the focus where new expressions can be added.
// The context is implemented by 'root' which is the root of the expression
@@ -519,8 +535,9 @@ abstract class IrBuilder {
/// Initialize a new top-level IR builder.
void _init(ConstantSystem constantSystem, ExecutableElement currentElement) {
- state = new IrBuilderDelimitedState(constantSystem, currentElement);
+ state = new IrBuilderSharedState(constantSystem, currentElement);
environment = new Environment.empty();
+ mutableVariables = <Local, ir.MutableVariable>{};
}
/// Construct a delimited visitor for visiting a subtree.
@@ -535,25 +552,29 @@ abstract class IrBuilder {
IrBuilder makeDelimitedBuilder([Environment env = null]) {
return _makeInstance()
..state = state
- ..environment = env != null ? env : new Environment.from(environment);
+ ..environment = env != null ? env : new Environment.from(environment)
+ ..mutableVariables = mutableVariables;
}
/// Construct a builder for making constructor field initializers.
IrBuilder makeInitializerBuilder() {
return _makeInstance()
- ..state = new IrBuilderDelimitedState(state.constantSystem,
- state.currentElement)
- ..environment = new Environment.from(environment);
+ ..state = new IrBuilderSharedState(state.constantSystem,
+ state.currentElement)
+ ..environment = new Environment.from(environment)
+ ..mutableVariables = mutableVariables;
}
/// Construct a builder for an inner function.
IrBuilder makeInnerFunctionBuilder(ExecutableElement currentElement) {
- IrBuilderDelimitedState innerState =
- new IrBuilderDelimitedState(state.constantSystem, currentElement)
+ IrBuilderSharedState innerState =
+ new IrBuilderSharedState(state.constantSystem, currentElement)
..enclosingMethodThisParameter = state.enclosingMethodThisParameter;
return _makeInstance()
..state = innerState
- ..environment = new Environment.empty();
+ ..environment = new Environment.empty()
+ ..mutableVariables =
+ new Map<Local, ir.MutableVariable>.from(mutableVariables);
Kevin Millikin (Google) 2015/04/20 10:32:20 Inner function builders need to inherit the mutabl
}
bool get isOpen => _root == null || _current != null;
@@ -1715,12 +1736,10 @@ abstract class IrBuilder {
JumpCollector join = new ForwardJumpCollector(environment);
IrBuilder tryCatchBuilder = makeDelimitedBuilder();
- // Variables that are boxed due to being captured in a closure are boxed
- // for their entire lifetime, and so they do not need to be boxed on
- // entry to any try block. They are not filtered out before this because
- // we can not identify all of them in the same pass where we identify the
- // variables assigned in the try (they may be captured by a closure after
- // the try statement).
+ // Variables treated as mutable in a try are not mutable outside of it.
+ // Work with a copy of the outer builder's mutable variables.
+ tryCatchBuilder.mutableVariables =
+ new Map<Local, ir.MutableVariable>.from(mutableVariables);
for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) {
assert(!tryCatchBuilder.isInMutableVariable(variable));
ir.Primitive value = tryCatchBuilder.buildLocalVariableGet(variable);
@@ -1751,10 +1770,8 @@ abstract class IrBuilder {
for (LocalVariableElement variable in tryStatementInfo.boxedOnEntry) {
assert(catchBuilder.isInMutableVariable(variable));
ir.Primitive value = catchBuilder.buildLocalVariableGet(variable);
- // Note that we remove the variable from the set of mutable variables
- // here (and not above for the try body). This is because the set of
- // mutable variables is global for the whole function and not local to
- // a delimited builder.
+ // After this point, the variables that were boxed on entry to the try
+ // are no longer treated as mutable.
catchBuilder.removeMutableVariable(variable);
catchBuilder.environment.update(variable, value);
}
@@ -2041,23 +2058,8 @@ abstract class IrBuilder {
/// Shared state between DartIrBuilders within the same method.
class DartIrBuilderSharedState {
- /// Maps local variables to their corresponding [MutableVariable] object.
- final Map<Local, ir.MutableVariable> local2mutable =
- <Local, ir.MutableVariable>{};
-
- /// Creates a [MutableVariable] for the given local.
- void makeMutableVariable(Local local) {
- ir.MutableVariable variable =
- new ir.MutableVariable(local.executableContext, local);
- local2mutable[local] = variable;
- }
-
/// [MutableVariable]s that should temporarily be treated as registers.
final Set<Local> registerizedMutableVariables = new Set<Local>();
-
- DartIrBuilderSharedState(Set<Local> capturedVariables) {
- capturedVariables.forEach(makeMutableVariable);
- }
}
/// Dart-specific subclass of [IrBuilder].
@@ -2076,28 +2078,17 @@ class DartIrBuilder extends IrBuilder {
DartIrBuilder(ConstantSystem constantSystem,
ExecutableElement currentElement,
Set<Local> capturedVariables)
- : dartState = new DartIrBuilderSharedState(capturedVariables) {
+ : dartState = new DartIrBuilderSharedState() {
Kevin Millikin (Google) 2015/04/20 10:32:20 There should be only one of these, not one per bui
_init(constantSystem, currentElement);
+ capturedVariables.forEach(makeMutableVariable);
}
+ @override
bool isInMutableVariable(Local local) {
- return dartState.local2mutable.containsKey(local) &&
+ return mutableVariables.containsKey(local) &&
!dartState.registerizedMutableVariables.contains(local);
}
- void makeMutableVariable(Local local) {
- dartState.makeMutableVariable(local);
- }
-
- void removeMutableVariable(Local local) {
- dartState.local2mutable.remove(local);
- }
-
- /// Gets the [MutableVariable] containing the value of [local].
- ir.MutableVariable getMutableVariable(Local local) {
- return dartState.local2mutable[local];
- }
-
void _enterScope(ClosureScope scope) {
assert(scope == null);
}
@@ -2110,7 +2101,7 @@ class DartIrBuilder extends IrBuilder {
List<LocalElement> loopVariables) {
assert(scope == null);
for (LocalElement loopVariable in loopVariables) {
- if (dartState.local2mutable.containsKey(loopVariable)) {
+ if (mutableVariables.containsKey(loopVariable)) {
// Temporarily keep the loop variable in a primitive.
// The loop variable will be added to environment when
// [declareLocalVariable] is called.
@@ -2123,7 +2114,7 @@ class DartIrBuilder extends IrBuilder {
List<LocalElement> loopVariables) {
assert(scope == null);
for (LocalElement loopVariable in loopVariables) {
- if (dartState.local2mutable.containsKey(loopVariable)) {
+ if (mutableVariables.containsKey(loopVariable)) {
// Move from [Primitive] into [MutableVariable].
dartState.registerizedMutableVariables.remove(loopVariable);
add(new ir.LetMutable(getMutableVariable(loopVariable),
@@ -2292,12 +2283,6 @@ class JsIrBuilder extends IrBuilder {
_init(constantSystem, currentElement);
}
- Map<ast.TryStatement, TryStatementInfo> get tryStatements => null;
- Set<Local> get mutableCapturedVariables => null;
- bool isInMutableVariable(Local local) => false;
- void makeMutableVariable(Local local) {}
- void removeMutableVariable(Local local) {}
-
void enterInitializers() {
assert(jsState.inInitializers == false);
jsState.inInitializers = true;
@@ -2391,6 +2376,9 @@ class JsIrBuilder extends IrBuilder {
add(new ir.SetField(environment.lookup(location.box),
location.field,
initialValue));
+ } else if (isInMutableVariable(variableElement)) {
+ add(new ir.LetMutable(getMutableVariable(variableElement),
+ initialValue));
} else {
initialValue.useElementAsHint(variableElement);
environment.extend(variableElement, initialValue);
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698