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

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

Issue 2721403006: Split NativeData (Closed)
Patch Set: Created 3 years, 9 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) 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 import 'dart:collection'; 5 import 'dart:collection';
6 6
7 import 'package:js_runtime/shared/embedded_names.dart'; 7 import 'package:js_runtime/shared/embedded_names.dart';
8 8
9 import '../closure.dart'; 9 import '../closure.dart';
10 import '../common.dart'; 10 import '../common.dart';
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 /** 406 /**
407 * Try to inline [element] within the correct context of the builder. The 407 * Try to inline [element] within the correct context of the builder. The
408 * insertion point is the state of the builder. 408 * insertion point is the state of the builder.
409 */ 409 */
410 bool tryInlineMethod(MethodElement element, Selector selector, TypeMask mask, 410 bool tryInlineMethod(MethodElement element, Selector selector, TypeMask mask,
411 List<HInstruction> providedArguments, ast.Node currentNode, 411 List<HInstruction> providedArguments, ast.Node currentNode,
412 {ResolutionInterfaceType instanceType}) { 412 {ResolutionInterfaceType instanceType}) {
413 registry.addImpact( 413 registry.addImpact(
414 backend.codegenEnqueuerListener.registerUsedElement(element)); 414 backend.codegenEnqueuerListener.registerUsedElement(element));
415 415
416 if (backend.isJsInterop(element) && !element.isFactoryConstructor) { 416 if (backend.nativeData.isJsInterop(element) &&
417 !element.isFactoryConstructor) {
417 // We only inline factory JavaScript interop constructors. 418 // We only inline factory JavaScript interop constructors.
418 return false; 419 return false;
419 } 420 }
420 421
421 // Ensure that [element] is an implementation element. 422 // Ensure that [element] is an implementation element.
422 element = element.implementation; 423 element = element.implementation;
423 424
424 if (compiler.elementHasCompileTimeError(element)) return false; 425 if (compiler.elementHasCompileTimeError(element)) return false;
425 426
426 MethodElement function = element; 427 MethodElement function = element;
(...skipping 15 matching lines...) Expand all
442 Elements.isStaticOrTopLevel(function) || 443 Elements.isStaticOrTopLevel(function) ||
443 function.isGenerativeConstructorBody, 444 function.isGenerativeConstructorBody,
444 message: "Missing selector for inlining of $function.")); 445 message: "Missing selector for inlining of $function."));
445 if (selector != null) { 446 if (selector != null) {
446 if (!selector.applies(function)) return false; 447 if (!selector.applies(function)) return false;
447 if (mask != null && !mask.canHit(function, selector, closedWorld)) { 448 if (mask != null && !mask.canHit(function, selector, closedWorld)) {
448 return false; 449 return false;
449 } 450 }
450 } 451 }
451 452
452 if (backend.isJsInterop(function)) return false; 453 if (backend.nativeData.isJsInterop(function)) return false;
453 454
454 // Don't inline operator== methods if the parameter can be null. 455 // Don't inline operator== methods if the parameter can be null.
455 if (function.name == '==') { 456 if (function.name == '==') {
456 if (function.enclosingClass != commonElements.objectClass && 457 if (function.enclosingClass != commonElements.objectClass &&
457 providedArguments[1].canBeNull()) { 458 providedArguments[1].canBeNull()) {
458 return false; 459 return false;
459 } 460 }
460 } 461 }
461 462
462 // Generative constructors of native classes should not be called directly 463 // Generative constructors of native classes should not be called directly
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 * Invariant: [functionElement] must be an implementation element. 687 * Invariant: [functionElement] must be an implementation element.
687 */ 688 */
688 HGraph buildMethod(MethodElement functionElement) { 689 HGraph buildMethod(MethodElement functionElement) {
689 assert(invariant(functionElement, functionElement.isImplementation)); 690 assert(invariant(functionElement, functionElement.isImplementation));
690 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement); 691 graph.calledInLoop = closedWorld.isCalledInLoop(functionElement);
691 ast.FunctionExpression function = resolvedAst.node; 692 ast.FunctionExpression function = resolvedAst.node;
692 assert(function != null); 693 assert(function != null);
693 assert(elements.getFunctionDefinition(function) != null); 694 assert(elements.getFunctionDefinition(function) != null);
694 openFunction(functionElement, function); 695 openFunction(functionElement, function);
695 String name = functionElement.name; 696 String name = functionElement.name;
696 if (backend.isJsInterop(functionElement)) { 697 if (backend.nativeData.isJsInterop(functionElement)) {
697 push(invokeJsInteropFunction(functionElement, parameters.values.toList(), 698 push(invokeJsInteropFunction(functionElement, parameters.values.toList(),
698 sourceInformationBuilder.buildGeneric(function))); 699 sourceInformationBuilder.buildGeneric(function)));
699 var value = pop(); 700 var value = pop();
700 closeAndGotoExit(new HReturn( 701 closeAndGotoExit(new HReturn(
701 value, sourceInformationBuilder.buildReturn(functionElement.node))); 702 value, sourceInformationBuilder.buildReturn(functionElement.node)));
702 return closeFunction(); 703 return closeFunction();
703 } 704 }
704 assert(invariant(functionElement, !function.modifiers.isExternal)); 705 assert(invariant(functionElement, !function.modifiers.isExternal));
705 706
706 // If [functionElement] is `operator==` we explicitly add a null check at 707 // If [functionElement] is `operator==` we explicitly add a null check at
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1173 * to, starting from the current constructor. 1174 * to, starting from the current constructor.
1174 * - Call the constructor bodies, starting from the constructor(s) in the 1175 * - Call the constructor bodies, starting from the constructor(s) in the
1175 * super class(es). 1176 * super class(es).
1176 */ 1177 */
1177 HGraph buildFactory(ResolvedAst resolvedAst) { 1178 HGraph buildFactory(ResolvedAst resolvedAst) {
1178 ConstructorElement functionElement = resolvedAst.element; 1179 ConstructorElement functionElement = resolvedAst.element;
1179 functionElement = functionElement.implementation; 1180 functionElement = functionElement.implementation;
1180 ClassElement classElement = functionElement.enclosingClass.implementation; 1181 ClassElement classElement = functionElement.enclosingClass.implementation;
1181 bool isNativeUpgradeFactory = 1182 bool isNativeUpgradeFactory =
1182 backend.nativeData.isNativeOrExtendsNative(classElement) && 1183 backend.nativeData.isNativeOrExtendsNative(classElement) &&
1183 !backend.isJsInterop(classElement); 1184 !backend.nativeData.isJsInterop(classElement);
1184 ast.FunctionExpression function; 1185 ast.FunctionExpression function;
1185 if (resolvedAst.kind == ResolvedAstKind.PARSED) { 1186 if (resolvedAst.kind == ResolvedAstKind.PARSED) {
1186 function = resolvedAst.node; 1187 function = resolvedAst.node;
1187 } 1188 }
1188 1189
1189 // Note that constructors (like any other static function) do not need 1190 // Note that constructors (like any other static function) do not need
1190 // to deal with optional arguments. It is the callers job to provide all 1191 // to deal with optional arguments. It is the callers job to provide all
1191 // arguments as if they were positional. 1192 // arguments as if they were positional.
1192 1193
1193 if (inliningStack.isEmpty) { 1194 if (inliningStack.isEmpty) {
(...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2503 HInstruction compileArgument(ast.Node argument) { 2504 HInstruction compileArgument(ast.Node argument) {
2504 visit(argument); 2505 visit(argument);
2505 return pop(); 2506 return pop();
2506 } 2507 }
2507 2508
2508 return Elements.makeArgumentsList<HInstruction>( 2509 return Elements.makeArgumentsList<HInstruction>(
2509 callStructure, 2510 callStructure,
2510 arguments, 2511 arguments,
2511 element, 2512 element,
2512 compileArgument, 2513 compileArgument,
2513 backend.isJsInterop(element) 2514 backend.nativeData.isJsInterop(element)
2514 ? handleConstantForOptionalParameterJsInterop 2515 ? handleConstantForOptionalParameterJsInterop
2515 : handleConstantForOptionalParameter); 2516 : handleConstantForOptionalParameter);
2516 } 2517 }
2517 2518
2518 void addGenericSendArgumentsToList( 2519 void addGenericSendArgumentsToList(
2519 Link<ast.Node> link, List<HInstruction> list) { 2520 Link<ast.Node> link, List<HInstruction> list) {
2520 for (; !link.isEmpty; link = link.tail) { 2521 for (; !link.isEmpty; link = link.tail) {
2521 visit(link.head); 2522 visit(link.head);
2522 list.add(pop()); 2523 list.add(pop());
2523 } 2524 }
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after
3307 } else if (isGrowableListConstructorCall) { 3308 } else if (isGrowableListConstructorCall) {
3308 TypeMask inferred = _inferredTypeOfNewList(send); 3309 TypeMask inferred = _inferredTypeOfNewList(send);
3309 return inferred.containsAll(closedWorld) 3310 return inferred.containsAll(closedWorld)
3310 ? commonMasks.extendableArrayType 3311 ? commonMasks.extendableArrayType
3311 : inferred; 3312 : inferred;
3312 } else if (Elements.isConstructorOfTypedArraySubclass( 3313 } else if (Elements.isConstructorOfTypedArraySubclass(
3313 originalElement, closedWorld)) { 3314 originalElement, closedWorld)) {
3314 isFixedList = true; 3315 isFixedList = true;
3315 TypeMask inferred = _inferredTypeOfNewList(send); 3316 TypeMask inferred = _inferredTypeOfNewList(send);
3316 ClassElement cls = element.enclosingClass; 3317 ClassElement cls = element.enclosingClass;
3317 assert(backend.isNative(cls.thisType.element)); 3318 assert(backend.nativeData.isNativeClass(cls));
3318 return inferred.containsAll(closedWorld) 3319 return inferred.containsAll(closedWorld)
3319 ? new TypeMask.nonNullExact(cls.thisType.element, closedWorld) 3320 ? new TypeMask.nonNullExact(cls, closedWorld)
Siggi Cherem (dart-lang) 2017/03/14 00:15:59 not sure I follow this change (same below in 3327)
Johnni Winther 2017/03/14 15:48:04 By definition `cls.thisType` is an InterfaceType w
3320 : inferred; 3321 : inferred;
3321 } else if (element.isGenerativeConstructor) { 3322 } else if (element.isGenerativeConstructor) {
3322 ClassElement cls = element.enclosingClass; 3323 ClassElement cls = element.enclosingClass;
3323 if (cls.isAbstract) { 3324 if (cls.isAbstract) {
3324 // An error will be thrown. 3325 // An error will be thrown.
3325 return new TypeMask.nonNullEmpty(); 3326 return new TypeMask.nonNullEmpty();
3326 } else { 3327 } else {
3327 return new TypeMask.nonNullExact(cls.thisType.element, closedWorld); 3328 return new TypeMask.nonNullExact(cls, closedWorld);
3328 } 3329 }
3329 } else { 3330 } else {
3330 return TypeMaskFactory.inferredReturnTypeForElement( 3331 return TypeMaskFactory.inferredReturnTypeForElement(
3331 originalElement, globalInferenceResults); 3332 originalElement, globalInferenceResults);
3332 } 3333 }
3333 } 3334 }
3334 3335
3335 CallStructure callStructure = elements.getSelector(send).callStructure; 3336 CallStructure callStructure = elements.getSelector(send).callStructure;
3336 ConstructorElement constructorDeclaration = constructor; 3337 ConstructorElement constructorDeclaration = constructor;
3337 ConstructorElement constructorImplementation = constructor.implementation; 3338 ConstructorElement constructorImplementation = constructor.implementation;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
3397 if (constructorImplementation.isMalformed || 3398 if (constructorImplementation.isMalformed ||
3398 !callStructure.signatureApplies(constructorImplementation.type)) { 3399 !callStructure.signatureApplies(constructorImplementation.type)) {
3399 generateWrongArgumentCountError(send, constructor, send.arguments); 3400 generateWrongArgumentCountError(send, constructor, send.arguments);
3400 return; 3401 return;
3401 } 3402 }
3402 3403
3403 List<HInstruction> inputs = <HInstruction>[]; 3404 List<HInstruction> inputs = <HInstruction>[];
3404 if (constructor.isGenerativeConstructor && 3405 if (constructor.isGenerativeConstructor &&
3405 backend.nativeData 3406 backend.nativeData
3406 .isNativeOrExtendsNative(constructor.enclosingClass) && 3407 .isNativeOrExtendsNative(constructor.enclosingClass) &&
3407 !backend.isJsInterop(constructor)) { 3408 !backend.nativeData.isJsInterop(constructor)) {
3408 // Native class generative constructors take a pre-constructed object. 3409 // Native class generative constructors take a pre-constructed object.
3409 inputs.add(graph.addConstantNull(closedWorld)); 3410 inputs.add(graph.addConstantNull(closedWorld));
3410 } 3411 }
3411 inputs.addAll(makeStaticArgumentList( 3412 inputs.addAll(makeStaticArgumentList(
3412 callStructure, send.arguments, constructorImplementation)); 3413 callStructure, send.arguments, constructorImplementation));
3413 3414
3414 TypeMask elementType = computeType(constructor); 3415 TypeMask elementType = computeType(constructor);
3415 if (isFixedListConstructorCall) { 3416 if (isFixedListConstructorCall) {
3416 if (!inputs[0].isNumber(closedWorld)) { 3417 if (!inputs[0].isNumber(closedWorld)) {
3417 HTypeConversion conversion = new HTypeConversion( 3418 HTypeConversion conversion = new HTypeConversion(
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
4004 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type) 4005 push(new HInvokeDynamicSetter(selector, mask, null, inputs, type)
4005 ..sourceInformation = sourceInformation); 4006 ..sourceInformation = sourceInformation);
4006 } else { 4007 } else {
4007 push(new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted) 4008 push(new HInvokeDynamicMethod(selector, mask, inputs, type, isIntercepted)
4008 ..sourceInformation = sourceInformation); 4009 ..sourceInformation = sourceInformation);
4009 } 4010 }
4010 } 4011 }
4011 4012
4012 HForeignCode invokeJsInteropFunction(MethodElement element, 4013 HForeignCode invokeJsInteropFunction(MethodElement element,
4013 List<HInstruction> arguments, SourceInformation sourceInformation) { 4014 List<HInstruction> arguments, SourceInformation sourceInformation) {
4014 assert(backend.isJsInterop(element)); 4015 assert(backend.nativeData.isJsInterop(element));
4015 nativeEmitter.nativeMethods.add(element); 4016 nativeEmitter.nativeMethods.add(element);
4016 4017
4017 if (element.isFactoryConstructor && 4018 if (element.isFactoryConstructor &&
4018 backend.jsInteropAnalysis 4019 backend.jsInteropAnalysis
4019 .hasAnonymousAnnotation(element.contextClass)) { 4020 .hasAnonymousAnnotation(element.contextClass)) {
4020 // Factory constructor that is syntactic sugar for creating a JavaScript 4021 // Factory constructor that is syntactic sugar for creating a JavaScript
4021 // object literal. 4022 // object literal.
4022 ConstructorElement constructor = element; 4023 ConstructorElement constructor = element;
4023 FunctionSignature params = constructor.functionSignature; 4024 FunctionSignature params = constructor.functionSignature;
4024 int i = 0; 4025 int i = 0;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
4073 // Native behavior effects here are similar to native/behavior.dart. 4074 // Native behavior effects here are similar to native/behavior.dart.
4074 // The return type is dynamic if we don't trust js-interop type 4075 // The return type is dynamic if we don't trust js-interop type
4075 // declarations. 4076 // declarations.
4076 nativeBehavior.typesReturned.add( 4077 nativeBehavior.typesReturned.add(
4077 compiler.options.trustJSInteropTypeAnnotations 4078 compiler.options.trustJSInteropTypeAnnotations
4078 ? type 4079 ? type
4079 : const ResolutionDynamicType()); 4080 : const ResolutionDynamicType());
4080 4081
4081 // The allocation effects include the declared type if it is native (which 4082 // The allocation effects include the declared type if it is native (which
4082 // includes js interop types). 4083 // includes js interop types).
4083 if (type.element != null && backend.isNative(type.element)) { 4084 if (type is ResolutionInterfaceType &&
4085 backend.nativeData.isNativeClass(type.element)) {
4084 nativeBehavior.typesInstantiated.add(type); 4086 nativeBehavior.typesInstantiated.add(type);
4085 } 4087 }
4086 4088
4087 // It also includes any other JS interop type if we don't trust the 4089 // It also includes any other JS interop type if we don't trust the
4088 // annotation or if is declared too broad. 4090 // annotation or if is declared too broad.
4089 if (!compiler.options.trustJSInteropTypeAnnotations || 4091 if (!compiler.options.trustJSInteropTypeAnnotations ||
4090 type.isObject || 4092 type.isObject ||
4091 type.isDynamic) { 4093 type.isDynamic) {
4092 ClassElement cls = backend.helpers.jsJavaScriptObjectClass; 4094 ClassElement cls = backend.helpers.jsJavaScriptObjectClass;
4093 nativeBehavior.typesInstantiated.add(cls.thisType); 4095 nativeBehavior.typesInstantiated.add(cls.thisType);
(...skipping 27 matching lines...) Expand all
4121 return; 4123 return;
4122 } 4124 }
4123 4125
4124 if (typeMask == null) { 4126 if (typeMask == null) {
4125 typeMask = TypeMaskFactory.inferredReturnTypeForElement( 4127 typeMask = TypeMaskFactory.inferredReturnTypeForElement(
4126 element, globalInferenceResults); 4128 element, globalInferenceResults);
4127 } 4129 }
4128 bool targetCanThrow = !closedWorld.getCannotThrow(element); 4130 bool targetCanThrow = !closedWorld.getCannotThrow(element);
4129 // TODO(5346): Try to avoid the need for calling [declaration] before 4131 // TODO(5346): Try to avoid the need for calling [declaration] before
4130 var instruction; 4132 var instruction;
4131 if (backend.isJsInterop(element)) { 4133 if (backend.nativeData.isJsInterop(element)) {
4132 instruction = 4134 instruction =
4133 invokeJsInteropFunction(element, arguments, sourceInformation); 4135 invokeJsInteropFunction(element, arguments, sourceInformation);
4134 } else { 4136 } else {
4135 // creating an [HInvokeStatic]. 4137 // creating an [HInvokeStatic].
4136 instruction = new HInvokeStatic(element, arguments, typeMask, 4138 instruction = new HInvokeStatic(element, arguments, typeMask,
4137 targetCanThrow: targetCanThrow) 4139 targetCanThrow: targetCanThrow)
4138 ..sourceInformation = sourceInformation; 4140 ..sourceInformation = sourceInformation;
4139 if (currentInlinedInstantiations.isNotEmpty) { 4141 if (currentInlinedInstantiations.isNotEmpty) {
4140 instruction.instantiatedTypes = 4142 instruction.instantiatedTypes =
4141 new List<ResolutionDartType>.from(currentInlinedInstantiations); 4143 new List<ResolutionDartType>.from(currentInlinedInstantiations);
(...skipping 2585 matching lines...) Expand 10 before | Expand all | Expand 10 after
6727 this.oldReturnLocal, 6729 this.oldReturnLocal,
6728 this.oldReturnType, 6730 this.oldReturnType,
6729 this.oldResolvedAst, 6731 this.oldResolvedAst,
6730 this.oldStack, 6732 this.oldStack,
6731 this.oldLocalsHandler, 6733 this.oldLocalsHandler,
6732 this.inTryStatement, 6734 this.inTryStatement,
6733 this.allFunctionsCalledOnce, 6735 this.allFunctionsCalledOnce,
6734 this.oldElementInferenceResults) 6736 this.oldElementInferenceResults)
6735 : super(function); 6737 : super(function);
6736 } 6738 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698