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

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

Issue 2812633002: Decouple LocalsHandler from Compiler and JavaScriptBackend (Closed)
Patch Set: dartfmt Created 3 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 unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/ssa/graph_builder.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 '../compiler.dart' show Compiler;
8 import '../elements/resolution_types.dart'; 7 import '../elements/resolution_types.dart';
9 import '../elements/elements.dart'; 8 import '../elements/elements.dart';
10 import '../elements/entities.dart'; 9 import '../elements/entities.dart';
11 import '../io/source_information.dart'; 10 import '../io/source_information.dart';
12 import '../js/js.dart' as js; 11 import '../js/js.dart' as js;
13 import '../js_backend/js_backend.dart'; 12 import '../js_backend/native_data.dart';
13 import '../js_backend/interceptor_data.dart';
14 import '../native/native.dart' as native; 14 import '../native/native.dart' as native;
15 import '../tree/tree.dart' as ast; 15 import '../tree/tree.dart' as ast;
16 import '../types/types.dart'; 16 import '../types/types.dart';
17 import '../world.dart' show ClosedWorld; 17 import '../world.dart' show ClosedWorld;
18 18
19 import 'graph_builder.dart'; 19 import 'graph_builder.dart';
20 import 'nodes.dart'; 20 import 'nodes.dart';
21 import 'types.dart'; 21 import 'types.dart';
22 22
23 /// Keeps track of locals (including parameters and phis) when building. The 23 /// Keeps track of locals (including parameters and phis) when building. The
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 /// } 55 /// }
56 /// main() { 56 /// main() {
57 /// new Foo<String>('foo'); 57 /// new Foo<String>('foo');
58 /// } 58 /// }
59 /// 59 ///
60 /// [instanceType] is not used if it contains type variables, since these 60 /// [instanceType] is not used if it contains type variables, since these
61 /// might not be in scope or from the current instance. 61 /// might not be in scope or from the current instance.
62 /// 62 ///
63 final ResolutionInterfaceType instanceType; 63 final ResolutionInterfaceType instanceType;
64 64
65 final Compiler _compiler; 65 final NativeData _nativeData;
66 66
67 LocalsHandler(this.builder, this.executableContext, 67 final InterceptorData _interceptorData;
68 ResolutionInterfaceType instanceType, this._compiler) 68
69 LocalsHandler(
70 this.builder,
71 this.executableContext,
72 ResolutionInterfaceType instanceType,
73 this._nativeData,
74 this._interceptorData)
69 : this.instanceType = 75 : this.instanceType =
70 instanceType == null || instanceType.containsTypeVariables 76 instanceType == null || instanceType.containsTypeVariables
71 ? null 77 ? null
72 : instanceType; 78 : instanceType;
73 79
74 ClosedWorld get closedWorld => builder.closedWorld; 80 ClosedWorld get closedWorld => builder.closedWorld;
75 81
76 CommonMasks get commonMasks => closedWorld.commonMasks; 82 CommonMasks get commonMasks => closedWorld.commonMasks;
77 83
78 GlobalTypeInferenceResults get _globalInferenceResults => 84 GlobalTypeInferenceResults get _globalInferenceResults =>
79 _compiler.globalInference.results; 85 builder.globalInferenceResults;
86
87 ClosureTask get _closureToClassMapper => builder.closureToClassMapper;
80 88
81 /// Substituted type variables occurring in [type] into the context of 89 /// Substituted type variables occurring in [type] into the context of
82 /// [contextClass]. 90 /// [contextClass].
83 ResolutionDartType substInContext(ResolutionDartType type) { 91 ResolutionDartType substInContext(ResolutionDartType type) {
84 if (contextClass != null) { 92 if (contextClass != null) {
85 ClassElement typeContext = Types.getClassContext(type); 93 ClassElement typeContext = Types.getClassContext(type);
86 if (typeContext != null) { 94 if (typeContext != null) {
87 type = type.substByContext(contextClass.asInstanceOf(typeContext)); 95 type = type.substByContext(contextClass.asInstanceOf(typeContext));
88 } 96 }
89 } 97 }
90 if (instanceType != null) { 98 if (instanceType != null) {
91 type = type.substByContext(instanceType); 99 type = type.substByContext(instanceType);
92 } 100 }
93 return type; 101 return type;
94 } 102 }
95 103
96 /// Creates a new [LocalsHandler] based on [other]. We only need to 104 /// Creates a new [LocalsHandler] based on [other]. We only need to
97 /// copy the [directLocals], since the other fields can be shared 105 /// copy the [directLocals], since the other fields can be shared
98 /// throughout the AST visit. 106 /// throughout the AST visit.
99 LocalsHandler.from(LocalsHandler other) 107 LocalsHandler.from(LocalsHandler other)
100 : directLocals = new Map<Local, HInstruction>.from(other.directLocals), 108 : directLocals = new Map<Local, HInstruction>.from(other.directLocals),
101 redirectionMapping = other.redirectionMapping, 109 redirectionMapping = other.redirectionMapping,
102 executableContext = other.executableContext, 110 executableContext = other.executableContext,
103 instanceType = other.instanceType, 111 instanceType = other.instanceType,
104 builder = other.builder, 112 builder = other.builder,
105 closureData = other.closureData, 113 closureData = other.closureData,
106 _compiler = other._compiler, 114 _nativeData = other._nativeData,
115 _interceptorData = other._interceptorData,
107 activationVariables = other.activationVariables, 116 activationVariables = other.activationVariables,
108 cachedTypeOfThis = other.cachedTypeOfThis, 117 cachedTypeOfThis = other.cachedTypeOfThis,
109 cachedTypesOfCapturedVariables = other.cachedTypesOfCapturedVariables; 118 cachedTypesOfCapturedVariables = other.cachedTypesOfCapturedVariables;
110 119
111 /// Redirects accesses from element [from] to element [to]. The [to] element 120 /// Redirects accesses from element [from] to element [to]. The [to] element
112 /// must be a boxed variable or a variable that is stored in a closure-field. 121 /// must be a boxed variable or a variable that is stored in a closure-field.
113 void redirectElement(Local from, CapturedVariable to) { 122 void redirectElement(Local from, CapturedVariable to) {
114 assert(redirectionMapping[from] == null); 123 assert(redirectionMapping[from] == null);
115 redirectionMapping[from] = to; 124 redirectionMapping[from] = to;
116 assert(isStoredInClosureField(from) || isBoxed(from)); 125 assert(isStoredInClosureField(from) || isBoxed(from));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 updateLocal(boxedVariable, oldValue); 193 updateLocal(boxedVariable, oldValue);
185 } 194 }
186 updateLocal(boxElement, newBox); 195 updateLocal(boxElement, newBox);
187 } 196 }
188 197
189 /// Documentation wanted -- johnniwinther 198 /// Documentation wanted -- johnniwinther
190 /// 199 ///
191 /// Invariant: [function] must be an implementation element. 200 /// Invariant: [function] must be an implementation element.
192 void startFunction(MemberElement element, ast.Node node) { 201 void startFunction(MemberElement element, ast.Node node) {
193 assert(invariant(element, element.isImplementation)); 202 assert(invariant(element, element.isImplementation));
194 closureData = _compiler.closureToClassMapper 203 closureData =
195 .getClosureToClassMapping(element.resolvedAst); 204 _closureToClassMapper.getClosureToClassMapping(element.resolvedAst);
196 205
197 if (element is MethodElement) { 206 if (element is MethodElement) {
198 MethodElement functionElement = element; 207 MethodElement functionElement = element;
199 FunctionSignature params = functionElement.functionSignature; 208 FunctionSignature params = functionElement.functionSignature;
200 ClosureScope scopeData = closureData.capturingScopes[node]; 209 ClosureScope scopeData = closureData.capturingScopes[node];
201 params.orderedForEachParameter((ParameterElement parameterElement) { 210 params.orderedForEachParameter((ParameterElement parameterElement) {
202 if (element.isGenerativeConstructorBody) { 211 if (element.isGenerativeConstructorBody) {
203 if (scopeData != null && 212 if (scopeData != null &&
204 scopeData.isCapturedVariable(parameterElement)) { 213 scopeData.isCapturedVariable(parameterElement)) {
205 // 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
(...skipping 11 matching lines...) Expand all
217 } 226 }
218 227
219 enterScope(node, element); 228 enterScope(node, element);
220 229
221 // If the freeVariableMapping is not empty, then this function was a 230 // If the freeVariableMapping is not empty, then this function was a
222 // nested closure that captures variables. Redirect the captured 231 // nested closure that captures variables. Redirect the captured
223 // variables to fields in the closure. 232 // variables to fields in the closure.
224 closureData.forEachFreeVariable((Local from, CapturedVariable to) { 233 closureData.forEachFreeVariable((Local from, CapturedVariable to) {
225 redirectElement(from, to); 234 redirectElement(from, to);
226 }); 235 });
227 JavaScriptBackend backend = _compiler.backend;
228 if (closureData.isClosure) { 236 if (closureData.isClosure) {
229 // Inside closure redirect references to itself to [:this:]. 237 // Inside closure redirect references to itself to [:this:].
230 HThis thisInstruction = 238 HThis thisInstruction =
231 new HThis(closureData.thisLocal, commonMasks.nonNullType); 239 new HThis(closureData.thisLocal, commonMasks.nonNullType);
232 builder.graph.thisInstruction = thisInstruction; 240 builder.graph.thisInstruction = thisInstruction;
233 builder.graph.entry.addAtEntry(thisInstruction); 241 builder.graph.entry.addAtEntry(thisInstruction);
234 updateLocal(closureData.closureElement, thisInstruction); 242 updateLocal(closureData.closureElement, thisInstruction);
235 } else if (element.isInstanceMember) { 243 } else if (element.isInstanceMember) {
236 // Once closures have been mapped to classes their instance members might 244 // Once closures have been mapped to classes their instance members might
237 // not have any thisElement if the closure was created inside a static 245 // not have any thisElement if the closure was created inside a static
238 // context. 246 // context.
239 HThis thisInstruction = new HThis(closureData.thisLocal, getTypeOfThis()); 247 HThis thisInstruction = new HThis(closureData.thisLocal, getTypeOfThis());
240 builder.graph.thisInstruction = thisInstruction; 248 builder.graph.thisInstruction = thisInstruction;
241 builder.graph.entry.addAtEntry(thisInstruction); 249 builder.graph.entry.addAtEntry(thisInstruction);
242 directLocals[closureData.thisLocal] = thisInstruction; 250 directLocals[closureData.thisLocal] = thisInstruction;
243 } 251 }
244 252
245 // If this method is an intercepted method, add the extra 253 // If this method is an intercepted method, add the extra
246 // parameter to it, that is the actual receiver for intercepted 254 // parameter to it, that is the actual receiver for intercepted
247 // classes, or the same as [:this:] for non-intercepted classes. 255 // classes, or the same as [:this:] for non-intercepted classes.
248 ClassElement cls = element.enclosingClass; 256 ClassElement cls = element.enclosingClass;
249 257
250 // 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
251 // and passed to the generative constructor factory function as a parameter. 259 // and passed to the generative constructor factory function as a parameter.
252 // Instead of allocating and initializing the object, the constructor 260 // Instead of allocating and initializing the object, the constructor
253 // 'upgrades' the native subclass object by initializing the Dart fields. 261 // 'upgrades' the native subclass object by initializing the Dart fields.
254 bool isNativeUpgradeFactory = element.isGenerativeConstructor && 262 bool isNativeUpgradeFactory = element.isGenerativeConstructor &&
255 backend.nativeData.isNativeOrExtendsNative(cls); 263 _nativeData.isNativeOrExtendsNative(cls);
256 if (backend.interceptorData.isInterceptedMethod(element)) { 264 if (_interceptorData.isInterceptedMethod(element)) {
257 bool isInterceptedClass = 265 bool isInterceptedClass =
258 backend.interceptorData.isInterceptedClass(cls.declaration); 266 _interceptorData.isInterceptedClass(cls.declaration);
259 String name = isInterceptedClass ? 'receiver' : '_'; 267 String name = isInterceptedClass ? 'receiver' : '_';
260 SyntheticLocal parameter = new SyntheticLocal(name, executableContext); 268 SyntheticLocal parameter = new SyntheticLocal(name, executableContext);
261 HParameterValue value = new HParameterValue(parameter, getTypeOfThis()); 269 HParameterValue value = new HParameterValue(parameter, getTypeOfThis());
262 builder.graph.explicitReceiverParameter = value; 270 builder.graph.explicitReceiverParameter = value;
263 builder.graph.entry.addAfter(directLocals[closureData.thisLocal], value); 271 builder.graph.entry.addAfter(directLocals[closureData.thisLocal], value);
264 if (builder.lastAddedParameter == null) { 272 if (builder.lastAddedParameter == null) {
265 // 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.
266 builder.lastAddedParameter = value; 274 builder.lastAddedParameter = value;
267 } 275 }
268 if (isInterceptedClass) { 276 if (isInterceptedClass) {
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
311 return closureData.variablesUsedInTryOrGenerator.contains(local); 319 return closureData.variablesUsedInTryOrGenerator.contains(local);
312 } 320 }
313 321
314 /// Returns an [HInstruction] for the given element. If the element is 322 /// Returns an [HInstruction] for the given element. If the element is
315 /// boxed or stored in a closure then the method generates code to retrieve 323 /// boxed or stored in a closure then the method generates code to retrieve
316 /// the value. 324 /// the value.
317 HInstruction readLocal(Local local, {SourceInformation sourceInformation}) { 325 HInstruction readLocal(Local local, {SourceInformation sourceInformation}) {
318 if (isAccessedDirectly(local)) { 326 if (isAccessedDirectly(local)) {
319 if (directLocals[local] == null) { 327 if (directLocals[local] == null) {
320 if (local is TypeVariableElement) { 328 if (local is TypeVariableElement) {
321 _compiler.reporter.internalError(_compiler.currentElement, 329 throw new SpannableAssertionFailure(CURRENT_ELEMENT_SPANNABLE,
322 "Runtime type information not available for $local."); 330 "Runtime type information not available for $local.");
323 } else { 331 } else {
324 _compiler.reporter.internalError( 332 throw new SpannableAssertionFailure(
325 local, "Cannot find value $local in ${directLocals.keys}."); 333 local, "Cannot find value $local in ${directLocals.keys}.");
326 } 334 }
327 } 335 }
328 HInstruction value = directLocals[local]; 336 HInstruction value = directLocals[local];
329 if (sourceInformation != null) { 337 if (sourceInformation != null) {
330 value = new HRef(value, sourceInformation); 338 value = new HRef(value, sourceInformation);
331 builder.add(value); 339 builder.add(value);
332 } 340 }
333 return value; 341 return value;
334 } else if (isStoredInClosureField(local)) { 342 } else if (isStoredInClosureField(local)) {
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
670 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30); 678 final int hashCode = _nextHashCode = (_nextHashCode + 1).toUnsigned(30);
671 static int _nextHashCode = 0; 679 static int _nextHashCode = 0;
672 680
673 SyntheticLocal(this.name, this.executableContext); 681 SyntheticLocal(this.name, this.executableContext);
674 682
675 @override 683 @override
676 MemberElement get memberContext => executableContext.memberContext; 684 MemberElement get memberContext => executableContext.memberContext;
677 685
678 toString() => 'SyntheticLocal($name)'; 686 toString() => 'SyntheticLocal($name)';
679 } 687 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/ssa/graph_builder.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698