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

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

Issue 2898983005: Add ClosureClassMaps super interface for ClosureTask (Closed)
Patch Set: Updated cf. comments 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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
78 ? null 78 ? null
79 : instanceType; 79 : instanceType;
80 80
81 ClosedWorld get closedWorld => builder.closedWorld; 81 ClosedWorld get closedWorld => builder.closedWorld;
82 82
83 CommonMasks get commonMasks => closedWorld.commonMasks; 83 CommonMasks get commonMasks => closedWorld.commonMasks;
84 84
85 GlobalTypeInferenceResults get _globalInferenceResults => 85 GlobalTypeInferenceResults get _globalInferenceResults =>
86 builder.globalInferenceResults; 86 builder.globalInferenceResults;
87 87
88 ClosureTask get _closureToClassMapper => builder.closureToClassMapper; 88 ClosureClassMaps get _closureToClassMapper => builder.closureToClassMapper;
89 89
90 /// Substituted type variables occurring in [type] into the context of 90 /// Substituted type variables occurring in [type] into the context of
91 /// [contextClass]. 91 /// [contextClass].
92 ResolutionDartType substInContext(ResolutionDartType type) { 92 ResolutionDartType substInContext(ResolutionDartType type) {
93 if (contextClass != null) { 93 if (contextClass != null) {
94 ClassElement typeContext = Types.getClassContext(type); 94 ClassElement typeContext = Types.getClassContext(type);
95 if (typeContext != null) { 95 if (typeContext != null) {
96 type = type.substByContext(contextClass.asInstanceOf(typeContext)); 96 type = type.substByContext(contextClass.asInstanceOf(typeContext));
97 } 97 }
98 } 98 }
(...skipping 30 matching lines...) Expand all
129 } 129 }
130 130
131 HInstruction createBox() { 131 HInstruction createBox() {
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, Element element) { 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 ClosureScope scopeData = closureData.capturingScopes[node];
143 if (scopeData == null) return; 143 if (scopeData == null) return;
144 HInstruction box; 144 HInstruction box;
145 // The scope has captured variables. 145 // The scope has captured variables.
146 if (element != null && element.isGenerativeConstructorBody) { 146 if (forGenerativeConstructorBody) {
147 // The box is passed as a parameter to a generative 147 // The box is passed as a parameter to a generative
148 // constructor body. 148 // constructor body.
149 box = builder.addParameter(scopeData.boxElement, commonMasks.nonNullType); 149 box = builder.addParameter(scopeData.boxElement, commonMasks.nonNullType);
150 } else { 150 } else {
151 box = createBox(); 151 box = createBox();
152 } 152 }
153 // Add the box to the known locals. 153 // Add the box to the known locals.
154 directLocals[scopeData.boxElement] = box; 154 directLocals[scopeData.boxElement] = box;
155 // Make sure that accesses to the boxed locals go into the box. We also 155 // 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. 156 // need to make sure that parameters are copied into the box if necessary.
157 scopeData.forEachCapturedVariable( 157 scopeData.forEachCapturedVariable(
158 (LocalVariableElement from, BoxFieldElement to) { 158 (LocalVariableElement from, BoxFieldElement to) {
159 // The [from] can only be a parameter for function-scopes and not 159 // The [from] can only be a parameter for function-scopes and not
160 // loop scopes. 160 // loop scopes.
161 if (from.isRegularParameter && !element.isGenerativeConstructorBody) { 161 if (from.isRegularParameter && !forGenerativeConstructorBody) {
162 // Now that the redirection is set up, the update to the local will 162 // Now that the redirection is set up, the update to the local will
163 // write the parameter value into the box. 163 // write the parameter value into the box.
164 // Store the captured parameter in the box. Get the current value 164 // Store the captured parameter in the box. Get the current value
165 // before we put the redirection in place. 165 // before we put the redirection in place.
166 // We don't need to update the local for a generative 166 // We don't need to update the local for a generative
167 // constructor body, because it receives a box that already 167 // constructor body, because it receives a box that already
168 // contains the updates as the last parameter. 168 // contains the updates as the last parameter.
169 HInstruction instruction = readLocal(from); 169 HInstruction instruction = readLocal(from);
170 redirectElement(from, to); 170 redirectElement(from, to);
171 updateLocal(from, instruction); 171 updateLocal(from, instruction);
(...skipping 18 matching lines...) Expand all
190 HInstruction oldValue = readLocal(boxedVariable); 190 HInstruction oldValue = readLocal(boxedVariable);
191 updateLocal(boxElement, newBox); 191 updateLocal(boxElement, newBox);
192 updateLocal(boxedVariable, oldValue); 192 updateLocal(boxedVariable, oldValue);
193 } 193 }
194 updateLocal(boxElement, newBox); 194 updateLocal(boxElement, newBox);
195 } 195 }
196 196
197 /// Documentation wanted -- johnniwinther 197 /// Documentation wanted -- johnniwinther
198 /// 198 ///
199 /// Invariant: [function] must be an implementation element. 199 /// Invariant: [function] must be an implementation element.
200 void startFunction(MemberElement element, ast.Node node) { 200 void startFunction(MemberEntity element, ast.Node node,
201 assert(invariant(element, element.isImplementation)); 201 {bool isGenerativeConstructorBody}) {
202 closureData = 202 assert(invariant(
203 _closureToClassMapper.getClosureToClassMapping(element.resolvedAst); 203 element, !(element is MemberElement && !element.isImplementation)));
204 closureData = _closureToClassMapper.getMemberMap(element);
204 205
205 if (element is MethodElement) { 206 if (element is MethodElement) {
206 MethodElement functionElement = element; 207 MethodElement functionElement = element;
207 FunctionSignature params = functionElement.functionSignature; 208 FunctionSignature params = functionElement.functionSignature;
208 ClosureScope scopeData = closureData.capturingScopes[node]; 209 ClosureScope scopeData = closureData.capturingScopes[node];
209 params.orderedForEachParameter((ParameterElement parameterElement) { 210 params.orderedForEachParameter((ParameterElement parameterElement) {
210 if (element.isGenerativeConstructorBody) { 211 if (element.isGenerativeConstructorBody) {
211 if (scopeData != null && 212 if (scopeData != null &&
212 scopeData.isCapturedVariable(parameterElement)) { 213 scopeData.isCapturedVariable(parameterElement)) {
213 // The parameter will be a field in the box passed as the 214 // The parameter will be a field in the box passed as the
214 // last parameter. So no need to have it. 215 // last parameter. So no need to have it.
215 return; 216 return;
216 } 217 }
217 } 218 }
218 HInstruction parameter = builder.addParameter( 219 HInstruction parameter = builder.addParameter(
219 parameterElement, 220 parameterElement,
220 TypeMaskFactory.inferredTypeForParameter( 221 TypeMaskFactory.inferredTypeForParameter(
221 parameterElement, _globalInferenceResults)); 222 parameterElement, _globalInferenceResults));
222 builder.parameters[parameterElement] = parameter; 223 builder.parameters[parameterElement] = parameter;
223 directLocals[parameterElement] = parameter; 224 directLocals[parameterElement] = parameter;
224 }); 225 });
225 } 226 }
226 227
227 enterScope(node, element); 228 enterScope(node, forGenerativeConstructorBody: isGenerativeConstructorBody);
228 229
229 // If the freeVariableMapping is not empty, then this function was a 230 // If the freeVariableMapping is not empty, then this function was a
230 // nested closure that captures variables. Redirect the captured 231 // nested closure that captures variables. Redirect the captured
231 // variables to fields in the closure. 232 // variables to fields in the closure.
232 closureData.forEachFreeVariable((Local from, CapturedVariable to) { 233 closureData.forEachFreeVariable((Local from, CapturedVariable to) {
233 redirectElement(from, to); 234 redirectElement(from, to);
234 }); 235 });
235 if (closureData.isClosure) { 236 if (closureData.isClosure) {
236 // Inside closure redirect references to itself to [:this:]. 237 // Inside closure redirect references to itself to [:this:].
237 HThis thisInstruction = 238 HThis thisInstruction =
(...skipping 13 matching lines...) Expand all
251 252
252 // If this method is an intercepted method, add the extra 253 // If this method is an intercepted method, add the extra
253 // parameter to it, that is the actual receiver for intercepted 254 // parameter to it, that is the actual receiver for intercepted
254 // classes, or the same as [:this:] for non-intercepted classes. 255 // classes, or the same as [:this:] for non-intercepted classes.
255 ClassElement cls = element.enclosingClass; 256 ClassElement cls = element.enclosingClass;
256 257
257 // When the class extends a native class, the instance is pre-constructed 258 // When the class extends a native class, the instance is pre-constructed
258 // and passed to the generative constructor factory function as a parameter. 259 // and passed to the generative constructor factory function as a parameter.
259 // Instead of allocating and initializing the object, the constructor 260 // Instead of allocating and initializing the object, the constructor
260 // 'upgrades' the native subclass object by initializing the Dart fields. 261 // 'upgrades' the native subclass object by initializing the Dart fields.
261 bool isNativeUpgradeFactory = element.isGenerativeConstructor && 262 bool isNativeUpgradeFactory = element is ConstructorEntity &&
263 element.isGenerativeConstructor &&
262 _nativeData.isNativeOrExtendsNative(cls); 264 _nativeData.isNativeOrExtendsNative(cls);
263 if (_interceptorData.isInterceptedMethod(element)) { 265 if (_interceptorData.isInterceptedMethod(element)) {
264 bool isInterceptedClass = 266 bool isInterceptedClass = _interceptorData.isInterceptedClass(cls);
265 _interceptorData.isInterceptedClass(cls.declaration);
266 String name = isInterceptedClass ? 'receiver' : '_'; 267 String name = isInterceptedClass ? 'receiver' : '_';
267 SyntheticLocal parameter = createLocal(name); 268 SyntheticLocal parameter = createLocal(name);
268 HParameterValue value = new HParameterValue(parameter, getTypeOfThis()); 269 HParameterValue value = new HParameterValue(parameter, getTypeOfThis());
269 builder.graph.explicitReceiverParameter = value; 270 builder.graph.explicitReceiverParameter = value;
270 builder.graph.entry.addAfter(directLocals[closureData.thisLocal], value); 271 builder.graph.entry.addAfter(directLocals[closureData.thisLocal], value);
271 if (builder.lastAddedParameter == null) { 272 if (builder.lastAddedParameter == null) {
272 // If this is the first parameter inserted, make sure it stays first. 273 // If this is the first parameter inserted, make sure it stays first.
273 builder.lastAddedParameter = value; 274 builder.lastAddedParameter = value;
274 } 275 }
275 if (isInterceptedClass) { 276 if (isInterceptedClass) {
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
476 /// goto loop-entry; 477 /// goto loop-entry;
477 /// loop-exit: 478 /// loop-exit:
478 void startLoop(ast.Node node) { 479 void startLoop(ast.Node node) {
479 ClosureScope scopeData = closureData.capturingScopes[node]; 480 ClosureScope scopeData = closureData.capturingScopes[node];
480 if (scopeData == null) return; 481 if (scopeData == null) return;
481 if (scopeData.hasBoxedLoopVariables()) { 482 if (scopeData.hasBoxedLoopVariables()) {
482 // If there are boxed loop variables then we set up the box and 483 // If there are boxed loop variables then we set up the box and
483 // redirections already now. This way the initializer can write its 484 // redirections already now. This way the initializer can write its
484 // values into the box. 485 // values into the box.
485 // For other loops the box will be created when entering the body. 486 // For other loops the box will be created when entering the body.
486 enterScope(node, null); 487 enterScope(node);
487 } 488 }
488 } 489 }
489 490
490 /// Create phis at the loop entry for local variables (ready for the values 491 /// Create phis at the loop entry for local variables (ready for the values
491 /// from the back edge). Populate the phis with the current values. 492 /// from the back edge). Populate the phis with the current values.
492 void beginLoopHeader(HBasicBlock loopEntry) { 493 void beginLoopHeader(HBasicBlock loopEntry) {
493 // Create a copy because we modify the map while iterating over it. 494 // Create a copy because we modify the map while iterating over it.
494 Map<Local, HInstruction> savedDirectLocals = 495 Map<Local, HInstruction> savedDirectLocals =
495 new Map<Local, HInstruction>.from(directLocals); 496 new Map<Local, HInstruction>.from(directLocals);
496 497
(...skipping 12 matching lines...) Expand all
509 } 510 }
510 }); 511 });
511 } 512 }
512 513
513 void enterLoopBody(ast.Node node) { 514 void enterLoopBody(ast.Node node) {
514 ClosureScope scopeData = closureData.capturingScopes[node]; 515 ClosureScope scopeData = closureData.capturingScopes[node];
515 if (scopeData == null) return; 516 if (scopeData == null) return;
516 // If there are no declared boxed loop variables then we did not create the 517 // If there are no declared boxed loop variables then we did not create the
517 // box before the initializer and we have to create the box now. 518 // box before the initializer and we have to create the box now.
518 if (!scopeData.hasBoxedLoopVariables()) { 519 if (!scopeData.hasBoxedLoopVariables()) {
519 enterScope(node, null); 520 enterScope(node);
520 } 521 }
521 } 522 }
522 523
523 void enterLoopUpdates(ast.Node node) { 524 void enterLoopUpdates(ast.Node node) {
524 // If there are declared boxed loop variables then the updates might have 525 // If there are declared boxed loop variables then the updates might have
525 // access to the box and we must switch to a new box before executing the 526 // access to the box and we must switch to a new box before executing the
526 // updates. 527 // updates.
527 // In all other cases a new box will be created when entering the body of 528 // In all other cases a new box will be created when entering the body of
528 // the next iteration. 529 // the next iteration.
529 ClosureScope scopeData = closureData.capturingScopes[node]; 530 ClosureScope scopeData = closureData.capturingScopes[node];
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
678 final MemberEntity memberContext; 679 final MemberEntity memberContext;
679 680
680 // Avoid slow Object.hashCode. 681 // Avoid slow Object.hashCode.
681 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); 682 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30);
682 static int _nextHashCode = 0; 683 static int _nextHashCode = 0;
683 684
684 SyntheticLocal(this.name, this.executableContext, this.memberContext); 685 SyntheticLocal(this.name, this.executableContext, this.memberContext);
685 686
686 toString() => 'SyntheticLocal($name)'; 687 toString() => 'SyntheticLocal($name)';
687 } 688 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/graph_builder.dart ('k') | pkg/compiler/lib/src/ssa/rasta_ssa_builder_task.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698