| OLD | NEW |
| 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 '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; | 5 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; |
| 6 import '../common/names.dart' show Selectors; | 6 import '../common/names.dart' show Selectors; |
| 7 import '../common/tasks.dart' show CompilerTask; | 7 import '../common/tasks.dart' show CompilerTask; |
| 8 import '../compiler.dart' show Compiler; | 8 import '../compiler.dart' show Compiler; |
| 9 import '../constants/constant_system.dart'; | 9 import '../constants/constant_system.dart'; |
| 10 import '../constants/values.dart'; | 10 import '../constants/values.dart'; |
| (...skipping 450 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 closedWorld.locateSingleElement(node.selector, receiverType); | 461 closedWorld.locateSingleElement(node.selector, receiverType); |
| 462 // TODO(ngeoffray): Also fold if it's a getter or variable. | 462 // TODO(ngeoffray): Also fold if it's a getter or variable. |
| 463 if (element != null && | 463 if (element != null && |
| 464 element.isFunction | 464 element.isFunction |
| 465 // If we found out that the only target is an implicitly called | 465 // If we found out that the only target is an implicitly called |
| 466 // [:noSuchMethod:] we just ignore it. | 466 // [:noSuchMethod:] we just ignore it. |
| 467 && | 467 && |
| 468 node.selector.applies(element)) { | 468 node.selector.applies(element)) { |
| 469 MethodElement method = element; | 469 MethodElement method = element; |
| 470 | 470 |
| 471 if (backend.isNative(method)) { | 471 if (backend.nativeData.isNativeMember(method)) { |
| 472 HInstruction folded = tryInlineNativeMethod(node, method); | 472 HInstruction folded = tryInlineNativeMethod(node, method); |
| 473 if (folded != null) return folded; | 473 if (folded != null) return folded; |
| 474 } else { | 474 } else { |
| 475 // TODO(ngeoffray): If the method has optional parameters, | 475 // TODO(ngeoffray): If the method has optional parameters, |
| 476 // we should pass the default values. | 476 // we should pass the default values. |
| 477 ResolutionFunctionType type = method.type; | 477 ResolutionFunctionType type = method.type; |
| 478 int optionalParameterCount = | 478 int optionalParameterCount = |
| 479 type.optionalParameterTypes.length + type.namedParameters.length; | 479 type.optionalParameterTypes.length + type.namedParameters.length; |
| 480 if (optionalParameterCount == 0 || | 480 if (optionalParameterCount == 0 || |
| 481 type.parameterTypes.length + optionalParameterCount == | 481 type.parameterTypes.length + optionalParameterCount == |
| 482 node.selector.argumentCount) { | 482 node.selector.argumentCount) { |
| 483 node.element = method; | 483 node.element = method; |
| 484 } | 484 } |
| 485 } | 485 } |
| 486 return node; | 486 return node; |
| 487 } | 487 } |
| 488 | 488 |
| 489 // Replace method calls through fields with a closure call on the value of | 489 // Replace method calls through fields with a closure call on the value of |
| 490 // the field. This usually removes the demand for the call-through stub and | 490 // the field. This usually removes the demand for the call-through stub and |
| 491 // makes the field load available to further optimization, e.g. LICM. | 491 // makes the field load available to further optimization, e.g. LICM. |
| 492 | 492 |
| 493 if (element != null && | 493 if (element != null && |
| 494 element.isField && | 494 element.isField && |
| 495 element.name == node.selector.name) { | 495 element.name == node.selector.name) { |
| 496 FieldEntity field = element; | 496 FieldEntity field = element; |
| 497 if (!backend.isNative(field) && !node.isCallOnInterceptor(closedWorld)) { | 497 if (!backend.nativeData.isNativeMember(field) && |
| 498 !node.isCallOnInterceptor(closedWorld)) { |
| 498 HInstruction receiver = node.getDartReceiver(closedWorld); | 499 HInstruction receiver = node.getDartReceiver(closedWorld); |
| 499 TypeMask type = TypeMaskFactory.inferredTypeForElement( | 500 TypeMask type = TypeMaskFactory.inferredTypeForElement( |
| 500 field as Entity, globalInferenceResults); | 501 field as Entity, globalInferenceResults); |
| 501 HInstruction load = new HFieldGet(field, receiver, type); | 502 HInstruction load = new HFieldGet(field, receiver, type); |
| 502 node.block.addBefore(node, load); | 503 node.block.addBefore(node, load); |
| 503 Selector callSelector = new Selector.callClosureFrom(node.selector); | 504 Selector callSelector = new Selector.callClosureFrom(node.selector); |
| 504 List<HInstruction> inputs = <HInstruction>[load] | 505 List<HInstruction> inputs = <HInstruction>[load] |
| 505 ..addAll(node.inputs.skip(node.isInterceptedCall ? 2 : 1)); | 506 ..addAll(node.inputs.skip(node.isInterceptedCall ? 2 : 1)); |
| 506 HInstruction closureCall = | 507 HInstruction closureCall = |
| 507 new HInvokeClosure(callSelector, inputs, node.instructionType) | 508 new HInvokeClosure(callSelector, inputs, node.instructionType) |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 type.parameterTypes.forEach(checkParameterType); | 563 type.parameterTypes.forEach(checkParameterType); |
| 563 type.optionalParameterTypes.forEach(checkParameterType); | 564 type.optionalParameterTypes.forEach(checkParameterType); |
| 564 type.namedParameterTypes.forEach(checkParameterType); | 565 type.namedParameterTypes.forEach(checkParameterType); |
| 565 } | 566 } |
| 566 | 567 |
| 567 if (!canInline) return null; | 568 if (!canInline) return null; |
| 568 | 569 |
| 569 // Strengthen instruction type from annotations to help optimize | 570 // Strengthen instruction type from annotations to help optimize |
| 570 // dependent instructions. | 571 // dependent instructions. |
| 571 native.NativeBehavior nativeBehavior = | 572 native.NativeBehavior nativeBehavior = |
| 572 backend.getNativeMethodBehavior(method); | 573 backend.nativeData.getNativeMethodBehavior(method); |
| 573 TypeMask returnType = | 574 TypeMask returnType = |
| 574 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); | 575 TypeMaskFactory.fromNativeBehavior(nativeBehavior, closedWorld); |
| 575 HInvokeDynamicMethod result = | 576 HInvokeDynamicMethod result = |
| 576 new HInvokeDynamicMethod(node.selector, node.mask, inputs, returnType); | 577 new HInvokeDynamicMethod(node.selector, node.mask, inputs, returnType); |
| 577 result.element = method; | 578 result.element = method; |
| 578 return result; | 579 return result; |
| 579 } | 580 } |
| 580 | 581 |
| 581 HInstruction visitBoundsCheck(HBoundsCheck node) { | 582 HInstruction visitBoundsCheck(HBoundsCheck node) { |
| 582 HInstruction index = node.index; | 583 HInstruction index = node.index; |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 951 node.sideEffects.clearAllDependencies(); | 952 node.sideEffects.clearAllDependencies(); |
| 952 node.sideEffects.clearAllSideEffects(); | 953 node.sideEffects.clearAllSideEffects(); |
| 953 node.setUseGvn(); // We don't care about identity of tear-offs. | 954 node.setUseGvn(); // We don't care about identity of tear-offs. |
| 954 } | 955 } |
| 955 } | 956 } |
| 956 } | 957 } |
| 957 return node; | 958 return node; |
| 958 } | 959 } |
| 959 | 960 |
| 960 HInstruction directFieldGet(HInstruction receiver, FieldEntity field) { | 961 HInstruction directFieldGet(HInstruction receiver, FieldEntity field) { |
| 961 bool isAssignable = !closedWorld.fieldNeverChanges(field as MemberEntity); | 962 bool isAssignable = !closedWorld.fieldNeverChanges(field); |
| 962 | 963 |
| 963 TypeMask type; | 964 TypeMask type; |
| 964 if (backend.isNative(field.enclosingClass)) { | 965 if (backend.nativeData.isNativeClass(field.enclosingClass)) { |
| 965 type = TypeMaskFactory.fromNativeBehavior( | 966 type = TypeMaskFactory.fromNativeBehavior( |
| 966 backend.getNativeFieldLoadBehavior(field), closedWorld); | 967 backend.nativeData.getNativeFieldLoadBehavior(field), closedWorld); |
| 967 } else { | 968 } else { |
| 968 type = TypeMaskFactory.inferredTypeForElement( | 969 type = TypeMaskFactory.inferredTypeForElement( |
| 969 field as Entity, globalInferenceResults); | 970 field as Entity, globalInferenceResults); |
| 970 } | 971 } |
| 971 | 972 |
| 972 return new HFieldGet(field, receiver, type, isAssignable: isAssignable); | 973 return new HFieldGet(field, receiver, type, isAssignable: isAssignable); |
| 973 } | 974 } |
| 974 | 975 |
| 975 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { | 976 HInstruction visitInvokeDynamicSetter(HInvokeDynamicSetter node) { |
| 976 if (node.isInterceptedCall) { | 977 if (node.isInterceptedCall) { |
| (...skipping 1803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2780 | 2781 |
| 2781 keyedValues.forEach((receiver, values) { | 2782 keyedValues.forEach((receiver, values) { |
| 2782 result.keyedValues[receiver] = | 2783 result.keyedValues[receiver] = |
| 2783 new Map<HInstruction, HInstruction>.from(values); | 2784 new Map<HInstruction, HInstruction>.from(values); |
| 2784 }); | 2785 }); |
| 2785 | 2786 |
| 2786 result.nonEscapingReceivers.addAll(nonEscapingReceivers); | 2787 result.nonEscapingReceivers.addAll(nonEscapingReceivers); |
| 2787 return result; | 2788 return result; |
| 2788 } | 2789 } |
| 2789 } | 2790 } |
| OLD | NEW |