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

Side by Side Diff: pkg/compiler/lib/src/ssa/locals_handler.dart

Issue 2995353002: Test the CapturedScope for local functions (Closed)
Patch Set: 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 unified diff | Download patch
OLDNEW
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698