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

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

Issue 1133903003: Forward instantiation type to LocalsHandler. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 part of ssa; 5 part of ssa;
6 6
7 class SsaFunctionCompiler implements FunctionCompiler { 7 class SsaFunctionCompiler implements FunctionCompiler {
8 SsaCodeGeneratorTask generator; 8 SsaCodeGeneratorTask generator;
9 SsaBuilderTask builder; 9 SsaBuilderTask builder;
10 SsaOptimizerTask optimizer; 10 SsaOptimizerTask optimizer;
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
194 SsaBuilder builder; 194 SsaBuilder builder;
195 ClosureClassMap closureData; 195 ClosureClassMap closureData;
196 Map<TypeVariableType, TypeVariableLocal> typeVariableLocals = 196 Map<TypeVariableType, TypeVariableLocal> typeVariableLocals =
197 new Map<TypeVariableType, TypeVariableLocal>(); 197 new Map<TypeVariableType, TypeVariableLocal>();
198 final ExecutableElement executableContext; 198 final ExecutableElement executableContext;
199 199
200 /// The class that defines the current type environment or null if no type 200 /// The class that defines the current type environment or null if no type
201 /// variables are in scope. 201 /// variables are in scope.
202 ClassElement get contextClass => executableContext.contextClass; 202 ClassElement get contextClass => executableContext.contextClass;
203 203
204 /// The type of the current instance, if concrete.
205 ///
206 /// This allows for handling fixed type argument in case of inlining. For
207 /// instance, checking `'foo'` against `String` instead of `T` in `main`:
208 ///
209 /// class Foo<T> {
210 /// T field;
211 /// Foo(this.field);
212 /// }
213 /// main() {
214 /// new Foo<String>('foo');
215 /// }
216 ///
217 /// [instanceType] is not used it contains type variables, since these might
zarah 2015/05/11 13:12:55 insert 'when/if' between 'used' and 'it'.
Johnni Winther 2015/05/11 15:56:05 Done.
218 /// not be in scope or from the current instance.
219 ///
220 final InterfaceType instanceType;
221
204 SourceInformationBuilder get sourceInformationBuilder { 222 SourceInformationBuilder get sourceInformationBuilder {
205 return builder.sourceInformationBuilder; 223 return builder.sourceInformationBuilder;
206 } 224 }
207 225
208 LocalsHandler(this.builder, this.executableContext); 226 LocalsHandler(this.builder, this.executableContext,
227 InterfaceType instanceType)
228 : this.instanceType =
229 instanceType == null || instanceType.containsTypeVariables
230 ? null : instanceType;
209 231
210 /// Substituted type variables occurring in [type] into the context of 232 /// Substituted type variables occurring in [type] into the context of
211 /// [contextClass]. 233 /// [contextClass].
212 DartType substInContext(DartType type) { 234 DartType substInContext(DartType type) {
213 if (contextClass != null) { 235 if (contextClass != null) {
214 ClassElement typeContext = Types.getClassContext(type); 236 ClassElement typeContext = Types.getClassContext(type);
215 if (typeContext != null) { 237 if (typeContext != null) {
216 type = type.substByContext( 238 type = type.substByContext(
217 contextClass.asInstanceOf(typeContext)); 239 contextClass.asInstanceOf(typeContext));
218 } 240 }
219 } 241 }
242 if (instanceType != null) {
243 type = type.substByContext(instanceType);
244 }
220 return type; 245 return type;
221 } 246 }
222 247
223 get typesTask => builder.compiler.typesTask; 248 get typesTask => builder.compiler.typesTask;
224 249
225 /** 250 /**
226 * Creates a new [LocalsHandler] based on [other]. We only need to 251 * Creates a new [LocalsHandler] based on [other]. We only need to
227 * copy the [directLocals], since the other fields can be shared 252 * copy the [directLocals], since the other fields can be shared
228 * throughout the AST visit. 253 * throughout the AST visit.
229 */ 254 */
230 LocalsHandler.from(LocalsHandler other) 255 LocalsHandler.from(LocalsHandler other)
231 : directLocals = new Map<Local, HInstruction>.from(other.directLocals), 256 : directLocals = new Map<Local, HInstruction>.from(other.directLocals),
232 redirectionMapping = other.redirectionMapping, 257 redirectionMapping = other.redirectionMapping,
233 executableContext = other.executableContext, 258 executableContext = other.executableContext,
259 instanceType = other.instanceType,
234 builder = other.builder, 260 builder = other.builder,
235 closureData = other.closureData; 261 closureData = other.closureData;
236 262
237 /** 263 /**
238 * Redirects accesses from element [from] to element [to]. The [to] element 264 * Redirects accesses from element [from] to element [to]. The [to] element
239 * must be a boxed variable or a variable that is stored in a closure-field. 265 * must be a boxed variable or a variable that is stored in a closure-field.
240 */ 266 */
241 void redirectElement(Local from, CapturedVariable to) { 267 void redirectElement(Local from, CapturedVariable to) {
242 assert(redirectionMapping[from] == null); 268 assert(redirectionMapping[from] == null);
243 redirectionMapping[from] = to; 269 redirectionMapping[from] = to;
(...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after
1087 SsaBuilder(JavaScriptBackend backend, 1113 SsaBuilder(JavaScriptBackend backend,
1088 CodegenWorkItem work, 1114 CodegenWorkItem work,
1089 this.nativeEmitter, 1115 this.nativeEmitter,
1090 SourceInformationFactory sourceInformationFactory) 1116 SourceInformationFactory sourceInformationFactory)
1091 : this.compiler = backend.compiler, 1117 : this.compiler = backend.compiler,
1092 this.backend = backend, 1118 this.backend = backend,
1093 this.constantSystem = backend.constantSystem, 1119 this.constantSystem = backend.constantSystem,
1094 this.work = work, 1120 this.work = work,
1095 this.rti = backend.rti, 1121 this.rti = backend.rti,
1096 super(work.resolutionTree) { 1122 super(work.resolutionTree) {
1097 localsHandler = new LocalsHandler(this, work.element); 1123 localsHandler = new LocalsHandler(this, work.element, null);
1098 sourceElementStack.add(work.element); 1124 sourceElementStack.add(work.element);
1099 sourceInformationBuilder = 1125 sourceInformationBuilder =
1100 sourceInformationFactory.forContext(work.element.implementation); 1126 sourceInformationFactory.forContext(work.element.implementation);
1101 } 1127 }
1102 1128
1103 CodegenRegistry get registry => work.registry; 1129 CodegenRegistry get registry => work.registry;
1104 1130
1105 /// Returns the current source element. 1131 /// Returns the current source element.
1106 /// 1132 ///
1107 /// The returned element is a declaration element. 1133 /// The returned element is a declaration element.
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
1265 return compiledArguments; 1291 return compiledArguments;
1266 } 1292 }
1267 1293
1268 /** 1294 /**
1269 * Try to inline [element] within the currect context of the builder. The 1295 * Try to inline [element] within the currect context of the builder. The
1270 * insertion point is the state of the builder. 1296 * insertion point is the state of the builder.
1271 */ 1297 */
1272 bool tryInlineMethod(Element element, 1298 bool tryInlineMethod(Element element,
1273 Selector selector, 1299 Selector selector,
1274 List<HInstruction> providedArguments, 1300 List<HInstruction> providedArguments,
1275 ast.Node currentNode) { 1301 ast.Node currentNode,
1302 {InterfaceType instanceType}) {
1276 // TODO(johnniwinther): Register this on the [registry]. Currently the 1303 // TODO(johnniwinther): Register this on the [registry]. Currently the
1277 // [CodegenRegistry] calls the enqueuer, but [element] should _not_ be 1304 // [CodegenRegistry] calls the enqueuer, but [element] should _not_ be
1278 // enqueued. 1305 // enqueued.
1279 backend.registerStaticUse(element, compiler.enqueuer.codegen); 1306 backend.registerStaticUse(element, compiler.enqueuer.codegen);
1280 1307
1281 // Ensure that [element] is an implementation element. 1308 // Ensure that [element] is an implementation element.
1282 element = element.implementation; 1309 element = element.implementation;
1283 1310
1284 if (compiler.elementHasCompileTimeError(element)) return false; 1311 if (compiler.elementHasCompileTimeError(element)) return false;
1285 1312
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
1421 if (element.isInstanceMember 1448 if (element.isInstanceMember
1422 && !element.isGenerativeConstructorBody 1449 && !element.isGenerativeConstructorBody
1423 && (selector.mask == null || selector.mask.isNullable)) { 1450 && (selector.mask == null || selector.mask.isNullable)) {
1424 addWithPosition( 1451 addWithPosition(
1425 new HFieldGet(null, providedArguments[0], backend.dynamicType, 1452 new HFieldGet(null, providedArguments[0], backend.dynamicType,
1426 isAssignable: false), 1453 isAssignable: false),
1427 currentNode); 1454 currentNode);
1428 } 1455 }
1429 List<HInstruction> compiledArguments = completeSendArgumentsList( 1456 List<HInstruction> compiledArguments = completeSendArgumentsList(
1430 function, selector, providedArguments, currentNode); 1457 function, selector, providedArguments, currentNode);
1431 enterInlinedMethod(function, currentNode, compiledArguments); 1458 enterInlinedMethod(
1459 function, currentNode, compiledArguments, instanceType: instanceType);
1432 inlinedFrom(function, () { 1460 inlinedFrom(function, () {
1433 if (!isReachable) { 1461 if (!isReachable) {
1434 emitReturn(graph.addConstantNull(compiler), null); 1462 emitReturn(graph.addConstantNull(compiler), null);
1435 } else { 1463 } else {
1436 doInline(function); 1464 doInline(function);
1437 } 1465 }
1438 }); 1466 });
1439 leaveInlinedMethod(); 1467 leaveInlinedMethod();
1440 } 1468 }
1441 1469
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
1684 /** 1712 /**
1685 * This method sets up the local state of the builder for inlining [function]. 1713 * This method sets up the local state of the builder for inlining [function].
1686 * The arguments of the function are inserted into the [localsHandler]. 1714 * The arguments of the function are inserted into the [localsHandler].
1687 * 1715 *
1688 * When inlining a function, [:return:] statements are not emitted as 1716 * When inlining a function, [:return:] statements are not emitted as
1689 * [HReturn] instructions. Instead, the value of a synthetic element is 1717 * [HReturn] instructions. Instead, the value of a synthetic element is
1690 * updated in the [localsHandler]. This function creates such an element and 1718 * updated in the [localsHandler]. This function creates such an element and
1691 * stores it in the [returnLocal] field. 1719 * stores it in the [returnLocal] field.
1692 */ 1720 */
1693 void setupStateForInlining(FunctionElement function, 1721 void setupStateForInlining(FunctionElement function,
1694 List<HInstruction> compiledArguments) { 1722 List<HInstruction> compiledArguments,
1695 localsHandler = new LocalsHandler(this, function); 1723 {InterfaceType instanceType}) {
1724 localsHandler = new LocalsHandler(this, function, instanceType);
1696 localsHandler.closureData = 1725 localsHandler.closureData =
1697 compiler.closureToClassMapper.computeClosureToClassMapping( 1726 compiler.closureToClassMapper.computeClosureToClassMapping(
1698 function, function.node, elements); 1727 function, function.node, elements);
1699 returnLocal = new SyntheticLocal("result", function); 1728 returnLocal = new SyntheticLocal("result", function);
1700 localsHandler.updateLocal(returnLocal, 1729 localsHandler.updateLocal(returnLocal,
1701 graph.addConstantNull(compiler)); 1730 graph.addConstantNull(compiler));
1702 1731
1703 inTryStatement = false; // TODO(lry): why? Document. 1732 inTryStatement = false; // TODO(lry): why? Document.
1704 1733
1705 int argumentIndex = 0; 1734 int argumentIndex = 0;
(...skipping 1876 matching lines...) Expand 10 before | Expand all | Expand 10 after
3582 if (type.isFunctionType) { 3611 if (type.isFunctionType) {
3583 List arguments = [buildFunctionType(type), expression]; 3612 List arguments = [buildFunctionType(type), expression];
3584 pushInvokeDynamic( 3613 pushInvokeDynamic(
3585 node, new Selector.call('_isTest', backend.jsHelperLibrary, 1), 3614 node, new Selector.call('_isTest', backend.jsHelperLibrary, 1),
3586 arguments); 3615 arguments);
3587 return new HIs.compound(type, expression, pop(), backend.boolType); 3616 return new HIs.compound(type, expression, pop(), backend.boolType);
3588 } else if (type.isTypeVariable) { 3617 } else if (type.isTypeVariable) {
3589 HInstruction runtimeType = addTypeVariableReference(type); 3618 HInstruction runtimeType = addTypeVariableReference(type);
3590 Element helper = backend.getCheckSubtypeOfRuntimeType(); 3619 Element helper = backend.getCheckSubtypeOfRuntimeType();
3591 List<HInstruction> inputs = <HInstruction>[expression, runtimeType]; 3620 List<HInstruction> inputs = <HInstruction>[expression, runtimeType];
3592 pushInvokeStatic(null, helper, inputs, backend.boolType); 3621 pushInvokeStatic(null, helper, inputs, typeMask: backend.boolType);
3593 HInstruction call = pop(); 3622 HInstruction call = pop();
3594 return new HIs.variable(type, expression, call, backend.boolType); 3623 return new HIs.variable(type, expression, call, backend.boolType);
3595 } else if (RuntimeTypes.hasTypeArguments(type)) { 3624 } else if (RuntimeTypes.hasTypeArguments(type)) {
3596 ClassElement element = type.element; 3625 ClassElement element = type.element;
3597 Element helper = backend.getCheckSubtype(); 3626 Element helper = backend.getCheckSubtype();
3598 HInstruction representations = 3627 HInstruction representations =
3599 buildTypeArgumentRepresentations(type); 3628 buildTypeArgumentRepresentations(type);
3600 add(representations); 3629 add(representations);
3601 String operator = backend.namer.operatorIs(element); 3630 String operator = backend.namer.operatorIs(element);
3602 HInstruction isFieldName = addConstantString(operator); 3631 HInstruction isFieldName = addConstantString(operator);
3603 HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element) 3632 HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element)
3604 ? addConstantString(backend.namer.substitutionName(element)) 3633 ? addConstantString(backend.namer.substitutionName(element))
3605 : graph.addConstantNull(compiler); 3634 : graph.addConstantNull(compiler);
3606 List<HInstruction> inputs = <HInstruction>[expression, 3635 List<HInstruction> inputs = <HInstruction>[expression,
3607 isFieldName, 3636 isFieldName,
3608 representations, 3637 representations,
3609 asFieldName]; 3638 asFieldName];
3610 pushInvokeStatic(node, helper, inputs, backend.boolType); 3639 pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType);
3611 HInstruction call = pop(); 3640 HInstruction call = pop();
3612 return new HIs.compound(type, expression, call, backend.boolType); 3641 return new HIs.compound(type, expression, call, backend.boolType);
3613 } else if (type.isMalformed) { 3642 } else if (type.isMalformed) {
3614 ErroneousElement element = type.element; 3643 ErroneousElement element = type.element;
3615 generateTypeError(node, element.message); 3644 generateTypeError(node, element.message);
3616 HInstruction call = pop(); 3645 HInstruction call = pop();
3617 return new HIs.compound(type, expression, call, backend.boolType); 3646 return new HIs.compound(type, expression, call, backend.boolType);
3618 } else { 3647 } else {
3619 if (backend.hasDirectCheckFor(type)) { 3648 if (backend.hasDirectCheckFor(type)) {
3620 return new HIs.direct(type, expression, backend.boolType); 3649 return new HIs.direct(type, expression, backend.boolType);
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after
3835 <HInstruction>[])); 3864 <HInstruction>[]));
3836 } else { 3865 } else {
3837 // Call a helper method from the isolate library. The isolate 3866 // Call a helper method from the isolate library. The isolate
3838 // library uses its own isolate structure, that encapsulates 3867 // library uses its own isolate structure, that encapsulates
3839 // Leg's isolate. 3868 // Leg's isolate.
3840 Element element = backend.isolateHelperLibrary.find('_currentIsolate'); 3869 Element element = backend.isolateHelperLibrary.find('_currentIsolate');
3841 if (element == null) { 3870 if (element == null) {
3842 compiler.internalError(node, 3871 compiler.internalError(node,
3843 'Isolate library and compiler mismatch.'); 3872 'Isolate library and compiler mismatch.');
3844 } 3873 }
3845 pushInvokeStatic(null, element, [], backend.dynamicType); 3874 pushInvokeStatic(null, element, [], typeMask: backend.dynamicType);
3846 } 3875 }
3847 } 3876 }
3848 3877
3849 void handleForeingJsGetFlag(ast.Send node) { 3878 void handleForeingJsGetFlag(ast.Send node) {
3850 List<ast.Node> arguments = node.arguments.toList(); 3879 List<ast.Node> arguments = node.arguments.toList();
3851 ast.Node argument; 3880 ast.Node argument;
3852 switch (arguments.length) { 3881 switch (arguments.length) {
3853 case 0: 3882 case 0:
3854 compiler.reportError( 3883 compiler.reportError(
3855 node, MessageKind.GENERIC, 3884 node, MessageKind.GENERIC,
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
4046 backend.dynamicType)); 4075 backend.dynamicType));
4047 } else { 4076 } else {
4048 // Call a helper method from the isolate library. 4077 // Call a helper method from the isolate library.
4049 Element element = backend.isolateHelperLibrary.find('_callInIsolate'); 4078 Element element = backend.isolateHelperLibrary.find('_callInIsolate');
4050 if (element == null) { 4079 if (element == null) {
4051 compiler.internalError(node, 4080 compiler.internalError(node,
4052 'Isolate library and compiler mismatch.'); 4081 'Isolate library and compiler mismatch.');
4053 } 4082 }
4054 List<HInstruction> inputs = <HInstruction>[]; 4083 List<HInstruction> inputs = <HInstruction>[];
4055 addGenericSendArgumentsToList(link, inputs); 4084 addGenericSendArgumentsToList(link, inputs);
4056 pushInvokeStatic(node, element, inputs, backend.dynamicType); 4085 pushInvokeStatic(node, element, inputs, typeMask: backend.dynamicType);
4057 } 4086 }
4058 } 4087 }
4059 4088
4060 FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) { 4089 FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) {
4061 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) { 4090 if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
4062 compiler.internalError(node.argumentsNode, 4091 compiler.internalError(node.argumentsNode,
4063 '"$name" requires exactly one argument.'); 4092 '"$name" requires exactly one argument.');
4064 } 4093 }
4065 ast.Node closure = node.arguments.head; 4094 ast.Node closure = node.arguments.head;
4066 Element element = elements[closure]; 4095 Element element = elements[closure];
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
4253 ConstantValue kindConstant = 4282 ConstantValue kindConstant =
4254 constantSystem.createInt(selector.invocationMirrorKind); 4283 constantSystem.createInt(selector.invocationMirrorKind);
4255 4284
4256 pushInvokeStatic(null, 4285 pushInvokeStatic(null,
4257 createInvocationMirror, 4286 createInvocationMirror,
4258 [graph.addConstant(nameConstant, compiler), 4287 [graph.addConstant(nameConstant, compiler),
4259 graph.addConstant(internalNameConstant, compiler), 4288 graph.addConstant(internalNameConstant, compiler),
4260 graph.addConstant(kindConstant, compiler), 4289 graph.addConstant(kindConstant, compiler),
4261 argumentsInstruction, 4290 argumentsInstruction,
4262 argumentNamesInstruction], 4291 argumentNamesInstruction],
4263 backend.dynamicType); 4292 typeMask: backend.dynamicType);
4264 4293
4265 var inputs = <HInstruction>[pop()]; 4294 var inputs = <HInstruction>[pop()];
4266 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs)); 4295 push(buildInvokeSuper(compiler.noSuchMethodSelector, element, inputs));
4267 } 4296 }
4268 4297
4269 /// Generate a call to a super method or constructor. 4298 /// Generate a call to a super method or constructor.
4270 void generateSuperInvoke(ast.Send node, FunctionElement function) { 4299 void generateSuperInvoke(ast.Send node, FunctionElement function) {
4271 // TODO(5347): Try to avoid the need for calling [implementation] before 4300 // TODO(5347): Try to avoid the need for calling [implementation] before
4272 // calling [makeStaticArgumentList]. 4301 // calling [makeStaticArgumentList].
4273 Selector selector = elements.getSelector(node); 4302 Selector selector = elements.getSelector(node);
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
4503 if (needsSubstitutionForTypeVariableAccess(cls)) { 4532 if (needsSubstitutionForTypeVariableAccess(cls)) {
4504 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to 4533 // TODO(ahe): Creating a string here is unfortunate. It is slow (due to
4505 // string concatenation in the implementation), and may prevent 4534 // string concatenation in the implementation), and may prevent
4506 // segmentation of '$'. 4535 // segmentation of '$'.
4507 String substitutionNameString = backend.namer.runtimeTypeName(cls); 4536 String substitutionNameString = backend.namer.runtimeTypeName(cls);
4508 HInstruction substitutionName = graph.addConstantString( 4537 HInstruction substitutionName = graph.addConstantString(
4509 new ast.LiteralDartString(substitutionNameString), compiler); 4538 new ast.LiteralDartString(substitutionNameString), compiler);
4510 pushInvokeStatic(null, 4539 pushInvokeStatic(null,
4511 backend.getGetRuntimeTypeArgument(), 4540 backend.getGetRuntimeTypeArgument(),
4512 [target, substitutionName, index], 4541 [target, substitutionName, index],
4513 backend.dynamicType); 4542 typeMask: backend.dynamicType);
4514 } else { 4543 } else {
4515 pushInvokeStatic(null, backend.getGetTypeArgumentByIndex(), 4544 pushInvokeStatic(null, backend.getGetTypeArgumentByIndex(),
4516 [target, index], 4545 [target, index],
4517 backend.dynamicType); 4546 typeMask: backend.dynamicType);
4518 } 4547 }
4519 return pop(); 4548 return pop();
4520 } 4549 }
4521 4550
4522 // TODO(karlklose): this is needed to avoid a bug where the resolved type is 4551 // TODO(karlklose): this is needed to avoid a bug where the resolved type is
4523 // not stored on a type annotation in the closure translator. Remove when 4552 // not stored on a type annotation in the closure translator. Remove when
4524 // fixed. 4553 // fixed.
4525 bool hasDirectLocal(Local local) { 4554 bool hasDirectLocal(Local local) {
4526 return !localsHandler.isAccessedDirectly(local) || 4555 return !localsHandler.isAccessedDirectly(local) ||
4527 localsHandler.directLocals[local] != null; 4556 localsHandler.directLocals[local] != null;
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
4636 4665
4637 HInstruction typeInfo = buildLiteralList(rtiInputs); 4666 HInstruction typeInfo = buildLiteralList(rtiInputs);
4638 add(typeInfo); 4667 add(typeInfo);
4639 4668
4640 // Set the runtime type information on the object. 4669 // Set the runtime type information on the object.
4641 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo(); 4670 Element typeInfoSetterElement = backend.getSetRuntimeTypeInfo();
4642 pushInvokeStatic( 4671 pushInvokeStatic(
4643 null, 4672 null,
4644 typeInfoSetterElement, 4673 typeInfoSetterElement,
4645 <HInstruction>[newObject, typeInfo], 4674 <HInstruction>[newObject, typeInfo],
4646 backend.dynamicType); 4675 typeMask: backend.dynamicType);
4647 4676
4648 // The new object will now be referenced through the 4677 // The new object will now be referenced through the
4649 // `setRuntimeTypeInfo` call. We therefore set the type of that 4678 // `setRuntimeTypeInfo` call. We therefore set the type of that
4650 // instruction to be of the object's type. 4679 // instruction to be of the object's type.
4651 assert(stack.last is HInvokeStatic || stack.last == newObject); 4680 assert(stack.last is HInvokeStatic || stack.last == newObject);
4652 stack.last.instructionType = newObject.instructionType; 4681 stack.last.instructionType = newObject.instructionType;
4653 return pop(); 4682 return pop();
4654 } 4683 }
4655 4684
4656 handleNewSend(ast.NewExpression node) { 4685 handleNewSend(ast.NewExpression node) {
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4799 stack.last.instructionType = elementType; 4828 stack.last.instructionType = elementType;
4800 } else { 4829 } else {
4801 ClassElement cls = constructor.enclosingClass; 4830 ClassElement cls = constructor.enclosingClass;
4802 if (cls.isAbstract && constructor.isGenerativeConstructor) { 4831 if (cls.isAbstract && constructor.isGenerativeConstructor) {
4803 generateAbstractClassInstantiationError(send, cls.name); 4832 generateAbstractClassInstantiationError(send, cls.name);
4804 return; 4833 return;
4805 } 4834 }
4806 potentiallyAddTypeArguments(inputs, cls, expectedType); 4835 potentiallyAddTypeArguments(inputs, cls, expectedType);
4807 4836
4808 addInlinedInstantiation(expectedType); 4837 addInlinedInstantiation(expectedType);
4809 pushInvokeStatic(node, constructor, inputs, elementType); 4838 pushInvokeStatic(node, constructor, inputs,
4839 typeMask: elementType, instanceType: expectedType);
4810 removeInlinedInstantiation(expectedType); 4840 removeInlinedInstantiation(expectedType);
4811 } 4841 }
4812 HInstruction newInstance = stack.last; 4842 HInstruction newInstance = stack.last;
4813 if (isFixedList) { 4843 if (isFixedList) {
4814 // Overwrite the element type, in case the allocation site has 4844 // Overwrite the element type, in case the allocation site has
4815 // been inlined. 4845 // been inlined.
4816 newInstance.instructionType = elementType; 4846 newInstance.instructionType = elementType;
4817 JavaScriptItemCompilationContext context = work.compilationContext; 4847 JavaScriptItemCompilationContext context = work.compilationContext;
4818 context.allocatedFixedLists.add(newInstance); 4848 context.allocatedFixedLists.add(newInstance);
4819 } 4849 }
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after
5153 } 5183 }
5154 5184
5155 /// Generate the literal for [typeVariable] in the current context. 5185 /// Generate the literal for [typeVariable] in the current context.
5156 void generateTypeVariableLiteral(ast.Send node, 5186 void generateTypeVariableLiteral(ast.Send node,
5157 TypeVariableType typeVariable) { 5187 TypeVariableType typeVariable) {
5158 DartType type = localsHandler.substInContext(typeVariable); 5188 DartType type = localsHandler.substInContext(typeVariable);
5159 HInstruction value = analyzeTypeArgument(type); 5189 HInstruction value = analyzeTypeArgument(type);
5160 pushInvokeStatic(node, 5190 pushInvokeStatic(node,
5161 backend.getRuntimeTypeToString(), 5191 backend.getRuntimeTypeToString(),
5162 [value], 5192 [value],
5163 backend.stringType); 5193 typeMask: backend.stringType);
5164 pushInvokeStatic(node, 5194 pushInvokeStatic(node,
5165 backend.getCreateRuntimeType(), 5195 backend.getCreateRuntimeType(),
5166 [pop()]); 5196 [pop()]);
5167 } 5197 }
5168 5198
5169 /// Generate a call to a type literal. 5199 /// Generate a call to a type literal.
5170 void generateTypeLiteralCall(ast.Send node) { 5200 void generateTypeLiteralCall(ast.Send node) {
5171 // This send is of the form 'e(...)', where e is resolved to a type 5201 // This send is of the form 'e(...)', where e is resolved to a type
5172 // reference. We create a regular closure call on the result of the type 5202 // reference. We create a regular closure call on the result of the type
5173 // reference instead of creating a NoSuchMethodError to avoid pulling it 5203 // reference instead of creating a NoSuchMethodError to avoid pulling it
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
5382 } else { 5412 } else {
5383 pushWithPosition( 5413 pushWithPosition(
5384 new HInvokeDynamicMethod(selector, inputs, type, isIntercepted), 5414 new HInvokeDynamicMethod(selector, inputs, type, isIntercepted),
5385 location); 5415 location);
5386 } 5416 }
5387 } 5417 }
5388 5418
5389 void pushInvokeStatic(ast.Node location, 5419 void pushInvokeStatic(ast.Node location,
5390 Element element, 5420 Element element,
5391 List<HInstruction> arguments, 5421 List<HInstruction> arguments,
5392 [TypeMask type]) { 5422 {TypeMask typeMask,
5393 if (tryInlineMethod(element, null, arguments, location)) { 5423 InterfaceType instanceType}) {
5424 if (tryInlineMethod(element, null, arguments, location,
5425 instanceType: instanceType)) {
5394 return; 5426 return;
5395 } 5427 }
5396 5428
5397 if (type == null) { 5429 if (typeMask == null) {
5398 type = TypeMaskFactory.inferredReturnTypeForElement(element, compiler); 5430 typeMask =
5431 TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
5399 } 5432 }
5400 bool targetCanThrow = !compiler.world.getCannotThrow(element); 5433 bool targetCanThrow = !compiler.world.getCannotThrow(element);
5401 // TODO(5346): Try to avoid the need for calling [declaration] before 5434 // TODO(5346): Try to avoid the need for calling [declaration] before
5402 // creating an [HInvokeStatic]. 5435 // creating an [HInvokeStatic].
5403 HInvokeStatic instruction = new HInvokeStatic( 5436 HInvokeStatic instruction = new HInvokeStatic(
5404 element.declaration, arguments, type, targetCanThrow: targetCanThrow); 5437 element.declaration, arguments, typeMask,
5438 targetCanThrow: targetCanThrow);
5405 if (!currentInlinedInstantiations.isEmpty) { 5439 if (!currentInlinedInstantiations.isEmpty) {
5406 instruction.instantiatedTypes = new List<DartType>.from( 5440 instruction.instantiatedTypes = new List<DartType>.from(
5407 currentInlinedInstantiations); 5441 currentInlinedInstantiations);
5408 } 5442 }
5409 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element); 5443 instruction.sideEffects = compiler.world.getSideEffectsOfElement(element);
5410 if (location == null) { 5444 if (location == null) {
5411 push(instruction); 5445 push(instruction);
5412 } else { 5446 } else {
5413 pushWithPosition(instruction, location); 5447 pushWithPosition(instruction, location);
5414 } 5448 }
(...skipping 907 matching lines...) Expand 10 before | Expand all | Expand 10 after
6322 // type inference might discover a more specific type, or find nothing (in 6356 // type inference might discover a more specific type, or find nothing (in
6323 // dart2js unit tests). 6357 // dart2js unit tests).
6324 TypeMask mapType = 6358 TypeMask mapType =
6325 new TypeMask.nonNullSubtype(backend.mapLiteralClass, compiler.world); 6359 new TypeMask.nonNullSubtype(backend.mapLiteralClass, compiler.world);
6326 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement( 6360 TypeMask returnTypeMask = TypeMaskFactory.inferredReturnTypeForElement(
6327 constructor, compiler); 6361 constructor, compiler);
6328 TypeMask instructionType = 6362 TypeMask instructionType =
6329 mapType.intersection(returnTypeMask, compiler.world); 6363 mapType.intersection(returnTypeMask, compiler.world);
6330 6364
6331 addInlinedInstantiation(expectedType); 6365 addInlinedInstantiation(expectedType);
6332 pushInvokeStatic(node, constructor, inputs, instructionType); 6366 pushInvokeStatic(node, constructor, inputs,
6367 typeMask: instructionType, instanceType: expectedType);
6333 removeInlinedInstantiation(expectedType); 6368 removeInlinedInstantiation(expectedType);
6334 } 6369 }
6335 6370
6336 visitLiteralMapEntry(ast.LiteralMapEntry node) { 6371 visitLiteralMapEntry(ast.LiteralMapEntry node) {
6337 visit(node.value); 6372 visit(node.value);
6338 visit(node.key); 6373 visit(node.key);
6339 } 6374 }
6340 6375
6341 visitNamedArgument(ast.NamedArgument node) { 6376 visitNamedArgument(ast.NamedArgument node) {
6342 visit(node.expression); 6377 visit(node.expression);
(...skipping 671 matching lines...) Expand 10 before | Expand all | Expand 10 after
7014 visitTypeVariable(ast.TypeVariable node) { 7049 visitTypeVariable(ast.TypeVariable node) {
7015 compiler.internalError(node, 'SsaFromAstMixin.visitTypeVariable.'); 7050 compiler.internalError(node, 'SsaFromAstMixin.visitTypeVariable.');
7016 } 7051 }
7017 7052
7018 /** 7053 /**
7019 * This method is invoked before inlining the body of [function] into this 7054 * This method is invoked before inlining the body of [function] into this
7020 * [SsaBuilder]. 7055 * [SsaBuilder].
7021 */ 7056 */
7022 void enterInlinedMethod(FunctionElement function, 7057 void enterInlinedMethod(FunctionElement function,
7023 ast.Node _, 7058 ast.Node _,
7024 List<HInstruction> compiledArguments) { 7059 List<HInstruction> compiledArguments,
7060 {InterfaceType instanceType}) {
7025 TypesInferrer inferrer = compiler.typesTask.typesInferrer; 7061 TypesInferrer inferrer = compiler.typesTask.typesInferrer;
7026 AstInliningState state = new AstInliningState( 7062 AstInliningState state = new AstInliningState(
7027 function, returnLocal, returnType, elements, stack, localsHandler, 7063 function, returnLocal, returnType, elements, stack, localsHandler,
7028 inTryStatement, 7064 inTryStatement,
7029 allInlinedFunctionsCalledOnce && inferrer.isCalledOnce(function)); 7065 allInlinedFunctionsCalledOnce && inferrer.isCalledOnce(function));
7030 inliningStack.add(state); 7066 inliningStack.add(state);
7031 7067
7032 // Setting up the state of the (AST) builder is performed even when the 7068 // Setting up the state of the (AST) builder is performed even when the
7033 // inlined function is in IR, because the irInliner uses the [returnElement] 7069 // inlined function is in IR, because the irInliner uses the [returnElement]
7034 // of the AST builder. 7070 // of the AST builder.
7035 setupStateForInlining(function, compiledArguments); 7071 setupStateForInlining(
7072 function, compiledArguments, instanceType: instanceType);
7036 } 7073 }
7037 7074
7038 void leaveInlinedMethod() { 7075 void leaveInlinedMethod() {
7039 HInstruction result = localsHandler.readLocal(returnLocal); 7076 HInstruction result = localsHandler.readLocal(returnLocal);
7040 AstInliningState state = inliningStack.removeLast(); 7077 AstInliningState state = inliningStack.removeLast();
7041 restoreState(state); 7078 restoreState(state);
7042 stack.add(result); 7079 stack.add(result);
7043 } 7080 }
7044 7081
7045 void doInline(FunctionElement function) { 7082 void doInline(FunctionElement function) {
(...skipping 585 matching lines...) Expand 10 before | Expand all | Expand 10 after
7631 if (unaliased is TypedefType) throw 'unable to unalias $type'; 7668 if (unaliased is TypedefType) throw 'unable to unalias $type';
7632 unaliased.accept(this, builder); 7669 unaliased.accept(this, builder);
7633 } 7670 }
7634 7671
7635 void visitDynamicType(DynamicType type, SsaBuilder builder) { 7672 void visitDynamicType(DynamicType type, SsaBuilder builder) {
7636 JavaScriptBackend backend = builder.compiler.backend; 7673 JavaScriptBackend backend = builder.compiler.backend;
7637 ClassElement cls = backend.findHelper('DynamicRuntimeType'); 7674 ClassElement cls = backend.findHelper('DynamicRuntimeType');
7638 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld))); 7675 builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
7639 } 7676 }
7640 } 7677 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698