OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import '../closure.dart'; | 5 import '../closure.dart'; |
6 import '../common.dart'; | 6 import '../common.dart'; |
7 import '../elements/elements.dart'; | 7 import '../elements/elements.dart'; |
8 import '../elements/entities.dart'; | 8 import '../elements/entities.dart'; |
9 import '../elements/types.dart'; | 9 import '../elements/types.dart'; |
10 import '../io/source_information.dart'; | 10 import '../io/source_information.dart'; |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 cachedTypesOfCapturedVariables = other.cachedTypesOfCapturedVariables; | 123 cachedTypesOfCapturedVariables = other.cachedTypesOfCapturedVariables; |
124 | 124 |
125 /// Redirects accesses from element [from] to element [to]. The [to] element | 125 /// Redirects accesses from element [from] to element [to]. The [to] element |
126 /// must be a boxed variable or a variable that is stored in a closure-field. | 126 /// must be a boxed variable or a variable that is stored in a closure-field. |
127 void redirectElement(Local from, FieldEntity to) { | 127 void redirectElement(Local from, FieldEntity to) { |
128 assert(_redirectionMapping[from] == null); | 128 assert(_redirectionMapping[from] == null); |
129 _redirectionMapping[from] = to; | 129 _redirectionMapping[from] = to; |
130 assert(isStoredInClosureField(from) || isBoxed(from)); | 130 assert(isStoredInClosureField(from) || isBoxed(from)); |
131 } | 131 } |
132 | 132 |
133 HInstruction createBox() { | 133 HInstruction createBoxObject() { |
134 HInstruction box = new HCreateBox(commonMasks.nonNullType); | 134 HInstruction box = new HCreateBox(commonMasks.nonNullType); |
135 builder.add(box); | 135 builder.add(box); |
136 return box; | 136 return box; |
137 } | 137 } |
138 | 138 |
139 /// If the scope (function or loop) [node] has captured variables then this | 139 /// If the scope (function or loop) [node] has captured variables then this |
140 /// method creates a box and sets up the redirections. | 140 /// method creates a box and sets up the redirections. |
141 void enterScope(CapturedScope closureInfo, | 141 void enterScope(CapturedScope closureInfo, |
142 {bool forGenerativeConstructorBody: false}) { | 142 {bool forGenerativeConstructorBody: false}) { |
143 // See if any variable in the top-scope of the function is captured. If yes | 143 // See if any variable in the top-scope of the function is captured. If yes |
144 // we need to create a box-object. | 144 // we need to create a box-object. |
145 if (!closureInfo.requiresContextBox) return; | 145 if (!closureInfo.hasBox) return; |
146 HInstruction box; | 146 HInstruction boxObject; |
147 // The scope has captured variables. | 147 // The scope has captured variables. |
148 if (forGenerativeConstructorBody) { | 148 if (forGenerativeConstructorBody) { |
149 // The box is passed as a parameter to a generative | 149 // The box is passed as a parameter to a generative |
150 // constructor body. | 150 // constructor body. |
151 box = builder.addParameter(closureInfo.context, commonMasks.nonNullType); | 151 boxObject = |
| 152 builder.addParameter(closureInfo.box, commonMasks.nonNullType); |
152 } else { | 153 } else { |
153 box = createBox(); | 154 boxObject = createBoxObject(); |
154 } | 155 } |
155 // Add the box to the known locals. | 156 // Add the box to the known locals. |
156 directLocals[closureInfo.context] = box; | 157 directLocals[closureInfo.box] = boxObject; |
157 // Make sure that accesses to the boxed locals go into the box. We also | 158 // Make sure that accesses to the boxed locals go into the box. We also |
158 // need to make sure that parameters are copied into the box if necessary. | 159 // need to make sure that parameters are copied into the box if necessary. |
159 closureInfo.forEachBoxedVariable((_from, _to) { | 160 closureInfo.forEachBoxedVariable((_from, _to) { |
160 Local from = _from; | 161 Local from = _from; |
161 FieldEntity to = _to; | 162 FieldEntity to = _to; |
162 // The [from] can only be a parameter for function-scopes and not | 163 // The [from] can only be a parameter for function-scopes and not |
163 // loop scopes. | 164 // loop scopes. |
164 bool isParameter = | 165 bool isParameter = |
165 // TODO(johnniwinther): Avoid this hack. Maybe [Local] should have an | 166 // TODO(johnniwinther): Avoid this hack. Maybe [Local] should have an |
166 // [isParameter] property? | 167 // [isParameter] property? |
(...skipping 16 matching lines...) Expand all Loading... |
183 } | 184 } |
184 }); | 185 }); |
185 } | 186 } |
186 | 187 |
187 /// Replaces the current box with a new box and copies over the given list | 188 /// Replaces the current box with a new box and copies over the given list |
188 /// of elements from the old box into the new box. | 189 /// of elements from the old box into the new box. |
189 void updateCaptureBox(Local currentBox, List<Local> toBeCopiedElements) { | 190 void updateCaptureBox(Local currentBox, List<Local> toBeCopiedElements) { |
190 // Create a new box and copy over the values from the old box into the | 191 // Create a new box and copy over the values from the old box into the |
191 // new one. | 192 // new one. |
192 HInstruction oldBox = readLocal(currentBox); | 193 HInstruction oldBox = readLocal(currentBox); |
193 HInstruction newBox = createBox(); | 194 HInstruction newBox = createBoxObject(); |
194 for (Local boxedVariable in toBeCopiedElements) { | 195 for (Local boxedVariable in toBeCopiedElements) { |
195 // [readLocal] uses the [currentBox] to find its box. By replacing it | 196 // [readLocal] uses the [currentBox] to find its box. By replacing it |
196 // behind its back we can still get to the old values. | 197 // behind its back we can still get to the old values. |
197 updateLocal(currentBox, oldBox); | 198 updateLocal(currentBox, oldBox); |
198 HInstruction oldValue = readLocal(boxedVariable); | 199 HInstruction oldValue = readLocal(boxedVariable); |
199 updateLocal(currentBox, newBox); | 200 updateLocal(currentBox, newBox); |
200 updateLocal(boxedVariable, oldValue); | 201 updateLocal(boxedVariable, oldValue); |
201 } | 202 } |
202 updateLocal(currentBox, newBox); | 203 updateLocal(currentBox, newBox); |
203 } | 204 } |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
544 } | 545 } |
545 } | 546 } |
546 | 547 |
547 void enterLoopUpdates(CapturedLoopScope loopInfo) { | 548 void enterLoopUpdates(CapturedLoopScope loopInfo) { |
548 // If there are declared boxed loop variables then the updates might have | 549 // If there are declared boxed loop variables then the updates might have |
549 // access to the box and we must switch to a new box before executing the | 550 // access to the box and we must switch to a new box before executing the |
550 // updates. | 551 // updates. |
551 // In all other cases a new box will be created when entering the body of | 552 // In all other cases a new box will be created when entering the body of |
552 // the next iteration. | 553 // the next iteration. |
553 if (loopInfo.hasBoxedLoopVariables) { | 554 if (loopInfo.hasBoxedLoopVariables) { |
554 updateCaptureBox(loopInfo.context, loopInfo.boxedLoopVariables); | 555 updateCaptureBox(loopInfo.box, loopInfo.boxedLoopVariables); |
555 } | 556 } |
556 } | 557 } |
557 | 558 |
558 /// Goes through the phis created in beginLoopHeader entry and adds the | 559 /// Goes through the phis created in beginLoopHeader entry and adds the |
559 /// input from the back edge (from the current value of directLocals) to them. | 560 /// input from the back edge (from the current value of directLocals) to them. |
560 void endLoop(HBasicBlock loopEntry) { | 561 void endLoop(HBasicBlock loopEntry) { |
561 // If the loop has an aborting body, we don't update the loop | 562 // If the loop has an aborting body, we don't update the loop |
562 // phis. | 563 // phis. |
563 if (loopEntry.predecessors.length == 1) return; | 564 if (loopEntry.predecessors.length == 1) return; |
564 loopEntry.forEachPhi((HPhi phi) { | 565 loopEntry.forEachPhi((HPhi phi) { |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
700 final MemberEntity memberContext; | 701 final MemberEntity memberContext; |
701 | 702 |
702 // Avoid slow Object.hashCode. | 703 // Avoid slow Object.hashCode. |
703 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); | 704 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); |
704 static int _nextHashCode = 0; | 705 static int _nextHashCode = 0; |
705 | 706 |
706 SyntheticLocal(this.name, this.executableContext, this.memberContext); | 707 SyntheticLocal(this.name, this.executableContext, this.memberContext); |
707 | 708 |
708 toString() => 'SyntheticLocal($name)'; | 709 toString() => 'SyntheticLocal($name)'; |
709 } | 710 } |
OLD | NEW |