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

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

Issue 2915523003: Create new interface instead of ClosureClassMap for variable usage information that is not Element-…
Patch Set: . Created 3 years, 6 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/resolution_types.dart'; 7 import '../elements/resolution_types.dart';
8 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
9 import '../elements/entities.dart'; 9 import '../elements/entities.dart';
10 import '../io/source_information.dart'; 10 import '../io/source_information.dart';
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 HInstruction box = new HCreateBox(commonMasks.nonNullType); 132 HInstruction box = new HCreateBox(commonMasks.nonNullType);
133 builder.add(box); 133 builder.add(box);
134 return box; 134 return box;
135 } 135 }
136 136
137 /// If the scope (function or loop) [node] has captured variables then this 137 /// If the scope (function or loop) [node] has captured variables then this
138 /// method creates a box and sets up the redirections. 138 /// method creates a box and sets up the redirections.
139 void enterScope(ast.Node node, {bool forGenerativeConstructorBody: false}) { 139 void enterScope(ast.Node node, {bool forGenerativeConstructorBody: false}) {
140 // See if any variable in the top-scope of the function is captured. If yes 140 // See if any variable in the top-scope of the function is captured. If yes
141 // we need to create a box-object. 141 // we need to create a box-object.
142 ClosureScope scopeData = closureData.capturingScopes[node]; 142 CapturedVariableInfo scopeData =
143 if (scopeData == null) return; 143 _closureToClassMapper.getCapturedVariableInfo(node);
144 if (!scopeData.hasCapturedVariables()) return;
145 Local localExecutableContext =
146 _closureToClassMapper.getExecutableContext(node);
147
144 HInstruction box; 148 HInstruction box;
145 // The scope has captured variables. 149 // The scope has captured variables.
146 if (forGenerativeConstructorBody) { 150 if (forGenerativeConstructorBody) {
147 // The box is passed as a parameter to a generative 151 // The box is passed as a parameter to a generative
148 // constructor body. 152 // constructor body.
149 box = builder.addParameter(scopeData.boxElement, commonMasks.nonNullType); 153 box =
154 builder.addParameter(localExecutableContext, commonMasks.nonNullType);
150 } else { 155 } else {
151 box = createBox(); 156 box = createBox();
152 } 157 }
153 // Add the box to the known locals. 158 // Add the box to the known locals.
154 directLocals[scopeData.boxElement] = box; 159 directLocals[localExecutableContext] = box;
155 // Make sure that accesses to the boxed locals go into the box. We also 160 // Make sure that accesses to the boxed locals go into the box. We also
156 // need to make sure that parameters are copied into the box if necessary. 161 // need to make sure that parameters are copied into the box if necessary.
157 scopeData.forEachCapturedVariable( 162 scopeData.forEachCapturedVariable(
158 (LocalVariableElement from, BoxFieldElement to) { 163 (LocalVariableElement from, BoxFieldElement to) {
159 // The [from] can only be a parameter for function-scopes and not 164 // The [from] can only be a parameter for function-scopes and not
160 // loop scopes. 165 // loop scopes.
161 if (from.isRegularParameter && !forGenerativeConstructorBody) { 166 if (from.isRegularParameter && !forGenerativeConstructorBody) {
162 // Now that the redirection is set up, the update to the local will 167 // Now that the redirection is set up, the update to the local will
163 // write the parameter value into the box. 168 // write the parameter value into the box.
164 // Store the captured parameter in the box. Get the current value 169 // Store the captured parameter in the box. Get the current value
165 // before we put the redirection in place. 170 // before we put the redirection in place.
166 // We don't need to update the local for a generative 171 // We don't need to update the local for a generative
167 // constructor body, because it receives a box that already 172 // constructor body, because it receives a box that already
168 // contains the updates as the last parameter. 173 // contains the updates as the last parameter.
169 HInstruction instruction = readLocal(from); 174 HInstruction instruction = readLocal(from);
170 redirectElement(from, to); 175 redirectElement(from, to);
171 updateLocal(from, instruction); 176 updateLocal(from, instruction);
172 } else { 177 } else {
173 redirectElement(from, to); 178 redirectElement(from, to);
174 } 179 }
175 }); 180 });
176 } 181 }
177 182
178 /// Replaces the current box with a new box and copies over the given list 183 /// Replaces the current box with a new box and copies over the given list
179 /// of elements from the old box into the new box. 184 /// of elements from the old box into the new box.
180 void updateCaptureBox( 185 void updateCaptureBox(
181 BoxLocal boxElement, List<LocalVariableElement> toBeCopiedElements) { 186 Local boxElement, List<LocalVariableElement> toBeCopiedElements) {
182 // Create a new box and copy over the values from the old box into the 187 // Create a new box and copy over the values from the old box into the
183 // new one. 188 // new one.
184 HInstruction oldBox = readLocal(boxElement); 189 HInstruction oldBox = readLocal(boxElement);
185 HInstruction newBox = createBox(); 190 HInstruction newBox = createBox();
186 for (LocalVariableElement boxedVariable in toBeCopiedElements) { 191 for (LocalVariableElement boxedVariable in toBeCopiedElements) {
187 // [readLocal] uses the [boxElement] to find its box. By replacing it 192 // [readLocal] uses the [boxElement] to find its box. By replacing it
188 // behind its back we can still get to the old values. 193 // behind its back we can still get to the old values.
189 updateLocal(boxElement, oldBox); 194 updateLocal(boxElement, oldBox);
190 HInstruction oldValue = readLocal(boxedVariable); 195 HInstruction oldValue = readLocal(boxedVariable);
191 updateLocal(boxElement, newBox); 196 updateLocal(boxElement, newBox);
192 updateLocal(boxedVariable, oldValue); 197 updateLocal(boxedVariable, oldValue);
193 } 198 }
194 updateLocal(boxElement, newBox); 199 updateLocal(boxElement, newBox);
195 } 200 }
196 201
197 /// Documentation wanted -- johnniwinther 202 /// Documentation wanted -- johnniwinther
198 /// 203 ///
199 /// Invariant: [function] must be an implementation element. 204 /// Invariant: [function] must be an implementation element.
200 void startFunction(MemberEntity element, ast.Node node, 205 void startFunction(MemberEntity element, ast.Node node,
201 {bool isGenerativeConstructorBody}) { 206 {bool isGenerativeConstructorBody}) {
202 assert(invariant( 207 assert(invariant(
203 element, !(element is MemberElement && !element.isImplementation))); 208 element, !(element is MemberElement && !element.isImplementation)));
204 closureData = _closureToClassMapper.getMemberMap(element); 209 closureData = _closureToClassMapper.getMemberMap(element);
205 210
206 if (element is MethodElement) { 211 if (element is MethodElement) {
207 MethodElement functionElement = element; 212 MethodElement functionElement = element;
208 FunctionSignature params = functionElement.functionSignature; 213 FunctionSignature params = functionElement.functionSignature;
209 ClosureScope scopeData = closureData.capturingScopes[node];
210 params.orderedForEachParameter((ParameterElement parameterElement) { 214 params.orderedForEachParameter((ParameterElement parameterElement) {
211 if (element.isGenerativeConstructorBody) { 215 if (element.isGenerativeConstructorBody) {
212 if (scopeData != null && 216 if (_closureToClassMapper
213 scopeData.isCapturedVariable(parameterElement)) { 217 .getCapturedVariableInfo(node)
218 .isCaptured(parameterElement)) {
214 // The parameter will be a field in the box passed as the 219 // The parameter will be a field in the box passed as the
215 // last parameter. So no need to have it. 220 // last parameter. So no need to have it.
216 return; 221 return;
217 } 222 }
218 } 223 }
219 HInstruction parameter = builder.addParameter( 224 HInstruction parameter = builder.addParameter(
220 parameterElement, 225 parameterElement,
221 TypeMaskFactory.inferredTypeForParameter( 226 TypeMaskFactory.inferredTypeForParameter(
222 parameterElement, _globalInferenceResults)); 227 parameterElement, _globalInferenceResults));
223 builder.parameters[parameterElement] = parameter; 228 builder.parameters[parameterElement] = parameter;
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 /// <Create box> <== move the first box creation outside the loop. 475 /// <Create box> <== move the first box creation outside the loop.
471 /// <initializer>; 476 /// <initializer>;
472 /// loop-entry: 477 /// loop-entry:
473 /// if (!<condition>) goto loop-exit; 478 /// if (!<condition>) goto loop-exit;
474 /// <body> 479 /// <body>
475 /// <update box> // create a new box and copy the captured loop-variables. 480 /// <update box> // create a new box and copy the captured loop-variables.
476 /// <updates> 481 /// <updates>
477 /// goto loop-entry; 482 /// goto loop-entry;
478 /// loop-exit: 483 /// loop-exit:
479 void startLoop(ast.Node node) { 484 void startLoop(ast.Node node) {
480 ClosureScope scopeData = closureData.capturingScopes[node]; 485 CapturedVariableInfo scopeData =
481 if (scopeData == null) return; 486 _closureToClassMapper.getCapturedVariableInfo(node);
482 if (scopeData.hasBoxedLoopVariables()) { 487 if (scopeData.hasBoxedLoopVariables()) {
483 // If there are boxed loop variables then we set up the box and 488 // If there are boxed loop variables then we set up the box and
484 // redirections already now. This way the initializer can write its 489 // redirections already now. This way the initializer can write its
485 // values into the box. 490 // values into the box.
486 // For other loops the box will be created when entering the body. 491 // For other loops the box will be created when entering the body.
487 enterScope(node); 492 enterScope(node);
488 } 493 }
489 } 494 }
490 495
491 /// Create phis at the loop entry for local variables (ready for the values 496 /// Create phis at the loop entry for local variables (ready for the values
(...skipping 13 matching lines...) Expand all
505 loopEntry.addPhi(phi); 510 loopEntry.addPhi(phi);
506 directLocals[local] = phi; 511 directLocals[local] = phi;
507 } else { 512 } else {
508 directLocals[local] = instruction; 513 directLocals[local] = instruction;
509 } 514 }
510 } 515 }
511 }); 516 });
512 } 517 }
513 518
514 void enterLoopBody(ast.Node node) { 519 void enterLoopBody(ast.Node node) {
515 ClosureScope scopeData = closureData.capturingScopes[node]; 520 CapturedVariableInfo scopeData =
516 if (scopeData == null) return; 521 _closureToClassMapper.getCapturedVariableInfo(node);
517 // If there are no declared boxed loop variables then we did not create the 522 // If there are no declared boxed loop variables then we did not create the
518 // box before the initializer and we have to create the box now. 523 // box before the initializer and we have to create the box now.
519 if (!scopeData.hasBoxedLoopVariables()) { 524 if (!scopeData.hasBoxedLoopVariables()) {
520 enterScope(node); 525 enterScope(node);
521 } 526 }
522 } 527 }
523 528
524 void enterLoopUpdates(ast.Node node) { 529 void enterLoopUpdates(ast.Node node) {
525 // If there are declared boxed loop variables then the updates might have 530 // If there are declared boxed loop variables then the updates might have
526 // access to the box and we must switch to a new box before executing the 531 // access to the box and we must switch to a new box before executing the
527 // updates. 532 // updates.
528 // In all other cases a new box will be created when entering the body of 533 // In all other cases a new box will be created when entering the body of
529 // the next iteration. 534 // the next iteration.
530 ClosureScope scopeData = closureData.capturingScopes[node]; 535 CapturedVariableInfo scopeData =
531 if (scopeData == null) return; 536 _closureToClassMapper.getCapturedVariableInfo(node);
532 if (scopeData.hasBoxedLoopVariables()) { 537 if (scopeData.hasBoxedLoopVariables()) {
533 updateCaptureBox(scopeData.boxElement, scopeData.boxedLoopVariables); 538 updateCaptureBox(_closureToClassMapper.getExecutableContext(node),
539 scopeData.boxedLoopVariables);
534 } 540 }
535 } 541 }
536 542
537 /// Goes through the phis created in beginLoopHeader entry and adds the 543 /// Goes through the phis created in beginLoopHeader entry and adds the
538 /// input from the back edge (from the current value of directLocals) to them. 544 /// input from the back edge (from the current value of directLocals) to them.
539 void endLoop(HBasicBlock loopEntry) { 545 void endLoop(HBasicBlock loopEntry) {
540 // If the loop has an aborting body, we don't update the loop 546 // If the loop has an aborting body, we don't update the loop
541 // phis. 547 // phis.
542 if (loopEntry.predecessors.length == 1) return; 548 if (loopEntry.predecessors.length == 1) return;
543 loopEntry.forEachPhi((HPhi phi) { 549 loopEntry.forEachPhi((HPhi phi) {
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
679 final MemberEntity memberContext; 685 final MemberEntity memberContext;
680 686
681 // Avoid slow Object.hashCode. 687 // Avoid slow Object.hashCode.
682 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); 688 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30);
683 static int _nextHashCode = 0; 689 static int _nextHashCode = 0;
684 690
685 SyntheticLocal(this.name, this.executableContext, this.memberContext); 691 SyntheticLocal(this.name, this.executableContext, this.memberContext);
686 692
687 toString() => 'SyntheticLocal($name)'; 693 toString() => 'SyntheticLocal($name)';
688 } 694 }
OLDNEW
« pkg/compiler/lib/src/ssa/builder_kernel.dart ('K') | « pkg/compiler/lib/src/ssa/builder_kernel.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698