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

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

Issue 2363773005: Move closed world reasoning methods from ClassWorld to ClosedWorld. (Closed)
Patch Set: Created 4 years, 2 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 '../common.dart'; 5 import '../common.dart';
6 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem; 6 import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
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';
11 import '../core_types.dart' show CoreClasses; 11 import '../core_types.dart' show CoreClasses;
12 import '../dart_types.dart'; 12 import '../dart_types.dart';
13 import '../elements/elements.dart'; 13 import '../elements/elements.dart';
14 import '../io/source_information.dart'; 14 import '../io/source_information.dart';
15 import '../js/js.dart' as js; 15 import '../js/js.dart' as js;
16 import '../js_backend/backend_helpers.dart' show BackendHelpers; 16 import '../js_backend/backend_helpers.dart' show BackendHelpers;
17 import '../js_backend/js_backend.dart'; 17 import '../js_backend/js_backend.dart';
18 import '../js_emitter/js_emitter.dart' show NativeEmitter; 18 import '../js_emitter/js_emitter.dart' show NativeEmitter;
19 import '../native/native.dart' as native; 19 import '../native/native.dart' as native;
20 import '../types/types.dart'; 20 import '../types/types.dart';
21 import '../universe/call_structure.dart' show CallStructure; 21 import '../universe/call_structure.dart' show CallStructure;
22 import '../universe/selector.dart' show Selector; 22 import '../universe/selector.dart' show Selector;
23 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse; 23 import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
24 import '../util/util.dart'; 24 import '../util/util.dart';
25 import '../world.dart' show ClassWorld; 25 import '../world.dart' show ClosedWorld;
26 import 'codegen_helpers.dart'; 26 import 'codegen_helpers.dart';
27 import 'nodes.dart'; 27 import 'nodes.dart';
28 import 'variable_allocator.dart'; 28 import 'variable_allocator.dart';
29 29
30 class SsaCodeGeneratorTask extends CompilerTask { 30 class SsaCodeGeneratorTask extends CompilerTask {
31 final JavaScriptBackend backend; 31 final JavaScriptBackend backend;
32 final Compiler compiler; 32 final Compiler compiler;
33 final SourceInformationStrategy sourceInformationFactory; 33 final SourceInformationStrategy sourceInformationFactory;
34 34
35 SsaCodeGeneratorTask(JavaScriptBackend backend, this.sourceInformationFactory) 35 SsaCodeGeneratorTask(JavaScriptBackend backend, this.sourceInformationFactory)
(...skipping 2661 matching lines...) Expand 10 before | Expand all | Expand 10 after
2697 void emitIsViaInterceptor( 2697 void emitIsViaInterceptor(
2698 HIsViaInterceptor node, SourceInformation sourceInformation, 2698 HIsViaInterceptor node, SourceInformation sourceInformation,
2699 {bool negative: false}) { 2699 {bool negative: false}) {
2700 checkTypeViaProperty( 2700 checkTypeViaProperty(
2701 node.interceptor, node.typeExpression, sourceInformation, 2701 node.interceptor, node.typeExpression, sourceInformation,
2702 negative: negative); 2702 negative: negative);
2703 } 2703 }
2704 2704
2705 js.Expression generateReceiverOrArgumentTypeTest( 2705 js.Expression generateReceiverOrArgumentTypeTest(
2706 HInstruction input, TypeMask checkedType) { 2706 HInstruction input, TypeMask checkedType) {
2707 ClassWorld classWorld = compiler.closedWorld; 2707 ClosedWorld closedWorld = compiler.closedWorld;
2708 TypeMask inputType = input.instructionType; 2708 TypeMask inputType = input.instructionType;
2709 // Figure out if it is beneficial to turn this into a null check. 2709 // Figure out if it is beneficial to turn this into a null check.
2710 // V8 generally prefers 'typeof' checks, but for integers and 2710 // V8 generally prefers 'typeof' checks, but for integers and
2711 // indexable primitives we cannot compile this test into a single 2711 // indexable primitives we cannot compile this test into a single
2712 // typeof check so the null check is cheaper. 2712 // typeof check so the null check is cheaper.
2713 bool isIntCheck = checkedType.containsOnlyInt(classWorld); 2713 bool isIntCheck = checkedType.containsOnlyInt(closedWorld);
2714 bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler); 2714 bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler);
2715 bool turnIntoNullCheck = !turnIntoNumCheck && 2715 bool turnIntoNullCheck = !turnIntoNumCheck &&
2716 (checkedType.nullable() == inputType) && 2716 (checkedType.nullable() == inputType) &&
2717 (isIntCheck || 2717 (isIntCheck ||
2718 checkedType.satisfies(helpers.jsIndexableClass, classWorld)); 2718 checkedType.satisfies(helpers.jsIndexableClass, closedWorld));
2719 2719
2720 if (turnIntoNullCheck) { 2720 if (turnIntoNullCheck) {
2721 use(input); 2721 use(input);
2722 return new js.Binary("==", pop(), new js.LiteralNull()) 2722 return new js.Binary("==", pop(), new js.LiteralNull())
2723 .withSourceInformation(input.sourceInformation); 2723 .withSourceInformation(input.sourceInformation);
2724 } else if (isIntCheck && !turnIntoNumCheck) { 2724 } else if (isIntCheck && !turnIntoNumCheck) {
2725 // input is !int 2725 // input is !int
2726 checkBigInt(input, '!==', input.sourceInformation); 2726 checkBigInt(input, '!==', input.sourceInformation);
2727 return pop(); 2727 return pop();
2728 } else if (turnIntoNumCheck || checkedType.containsOnlyNum(classWorld)) { 2728 } else if (turnIntoNumCheck || checkedType.containsOnlyNum(closedWorld)) {
2729 // input is !num 2729 // input is !num
2730 checkNum(input, '!==', input.sourceInformation); 2730 checkNum(input, '!==', input.sourceInformation);
2731 return pop(); 2731 return pop();
2732 } else if (checkedType.containsOnlyBool(classWorld)) { 2732 } else if (checkedType.containsOnlyBool(closedWorld)) {
2733 // input is !bool 2733 // input is !bool
2734 checkBool(input, '!==', input.sourceInformation); 2734 checkBool(input, '!==', input.sourceInformation);
2735 return pop(); 2735 return pop();
2736 } else if (checkedType.containsOnlyString(classWorld)) { 2736 } else if (checkedType.containsOnlyString(closedWorld)) {
2737 // input is !string 2737 // input is !string
2738 checkString(input, '!==', input.sourceInformation); 2738 checkString(input, '!==', input.sourceInformation);
2739 return pop(); 2739 return pop();
2740 } 2740 }
2741 reporter.internalError(input, 'Unexpected check: $checkedType.'); 2741 reporter.internalError(input, 'Unexpected check: $checkedType.');
2742 return null; 2742 return null;
2743 } 2743 }
2744 2744
2745 void visitTypeConversion(HTypeConversion node) { 2745 void visitTypeConversion(HTypeConversion node) {
2746 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) { 2746 if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) {
2747 ClassWorld classWorld = compiler.closedWorld; 2747 ClosedWorld closedWorld = compiler.closedWorld;
2748 // An int check if the input is not int or null, is not 2748 // An int check if the input is not int or null, is not
2749 // sufficient for doing an argument or receiver check. 2749 // sufficient for doing an argument or receiver check.
2750 assert(compiler.options.trustTypeAnnotations || 2750 assert(compiler.options.trustTypeAnnotations ||
2751 !node.checkedType.containsOnlyInt(classWorld) || 2751 !node.checkedType.containsOnlyInt(closedWorld) ||
2752 node.checkedInput.isIntegerOrNull(compiler)); 2752 node.checkedInput.isIntegerOrNull(compiler));
2753 js.Expression test = generateReceiverOrArgumentTypeTest( 2753 js.Expression test = generateReceiverOrArgumentTypeTest(
2754 node.checkedInput, node.checkedType); 2754 node.checkedInput, node.checkedType);
2755 js.Block oldContainer = currentContainer; 2755 js.Block oldContainer = currentContainer;
2756 js.Statement body = new js.Block.empty(); 2756 js.Statement body = new js.Block.empty();
2757 currentContainer = body; 2757 currentContainer = body;
2758 if (node.isArgumentTypeCheck) { 2758 if (node.isArgumentTypeCheck) {
2759 generateThrowWithHelper( 2759 generateThrowWithHelper(
2760 helpers.throwIllegalArgumentException, node.checkedInput, 2760 helpers.throwIllegalArgumentException, node.checkedInput,
2761 sourceInformation: node.sourceInformation); 2761 sourceInformation: node.sourceInformation);
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
2906 node.dartType == (node.dartType.element as ClassElement).thisType); 2906 node.dartType == (node.dartType.element as ClassElement).thisType);
2907 registry.registerInstantiatedClass(coreClasses.listClass); 2907 registry.registerInstantiatedClass(coreClasses.listClass);
2908 push(new js.ArrayInitializer(arguments) 2908 push(new js.ArrayInitializer(arguments)
2909 .withSourceInformation(node.sourceInformation)); 2909 .withSourceInformation(node.sourceInformation));
2910 } 2910 }
2911 } 2911 }
2912 2912
2913 bool typeVariableAccessNeedsSubstitution( 2913 bool typeVariableAccessNeedsSubstitution(
2914 TypeVariableElement element, TypeMask receiverMask) { 2914 TypeVariableElement element, TypeMask receiverMask) {
2915 ClassElement cls = element.enclosingClass; 2915 ClassElement cls = element.enclosingClass;
2916 ClassWorld classWorld = compiler.closedWorld; 2916 ClosedWorld closedWorld = compiler.closedWorld;
2917 2917
2918 // See if the receiver type narrows the set of classes to ones that can be 2918 // See if the receiver type narrows the set of classes to ones that can be
2919 // indexed. 2919 // indexed.
2920 // TODO(sra): Currently the only convenient query is [singleClass]. We 2920 // TODO(sra): Currently the only convenient query is [singleClass]. We
2921 // should iterate over all the concrete classes in [receiverMask]. 2921 // should iterate over all the concrete classes in [receiverMask].
2922 ClassElement receiverClass = receiverMask.singleClass(classWorld); 2922 ClassElement receiverClass = receiverMask.singleClass(closedWorld);
2923 if (receiverClass != null) { 2923 if (receiverClass != null) {
2924 if (backend.rti.isTrivialSubstitution(receiverClass, cls)) { 2924 if (backend.rti.isTrivialSubstitution(receiverClass, cls)) {
2925 return false; 2925 return false;
2926 } 2926 }
2927 } 2927 }
2928 2928
2929 if (classWorld.isUsedAsMixin(cls)) return true; 2929 if (closedWorld.isUsedAsMixin(cls)) return true;
2930 2930
2931 return classWorld.anyStrictSubclassOf(cls, (ClassElement subclass) { 2931 return closedWorld.anyStrictSubclassOf(cls, (ClassElement subclass) {
2932 return !backend.rti.isTrivialSubstitution(subclass, cls); 2932 return !backend.rti.isTrivialSubstitution(subclass, cls);
2933 }); 2933 });
2934 } 2934 }
2935 2935
2936 void visitReadTypeVariable(HReadTypeVariable node) { 2936 void visitReadTypeVariable(HReadTypeVariable node) {
2937 TypeVariableElement element = node.dartType.element; 2937 TypeVariableElement element = node.dartType.element;
2938 Element helperElement = helpers.convertRtiToRuntimeType; 2938 Element helperElement = helpers.convertRtiToRuntimeType;
2939 registry.registerStaticUse( 2939 registry.registerStaticUse(
2940 new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG)); 2940 new StaticUse.staticInvoke(helperElement, CallStructure.ONE_ARG));
2941 2941
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
2999 registry.registerStaticUse(new StaticUse.staticInvoke( 2999 registry.registerStaticUse(new StaticUse.staticInvoke(
3000 helper, new CallStructure.unnamed(argumentCount))); 3000 helper, new CallStructure.unnamed(argumentCount)));
3001 return backend.emitter.staticFunctionAccess(helper); 3001 return backend.emitter.staticFunctionAccess(helper);
3002 } 3002 }
3003 3003
3004 @override 3004 @override
3005 void visitRef(HRef node) { 3005 void visitRef(HRef node) {
3006 visit(node.value); 3006 visit(node.value);
3007 } 3007 }
3008 } 3008 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698