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

Side by Side Diff: pkg/compiler/lib/src/js_backend/backend.dart

Issue 2569733002: Even less reliance on Compiler.closedWorld (Closed)
Patch Set: Updated cf. comments. Created 4 years 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 library js_backend.backend; 5 library js_backend.backend;
6 6
7 import 'dart:async' show Future; 7 import 'dart:async' show Future;
8 8
9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames; 9 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
10 10
11 import '../closure.dart'; 11 import '../closure.dart';
12 import '../common.dart'; 12 import '../common.dart';
13 import '../common/backend_api.dart' 13 import '../common/backend_api.dart'
14 show 14 show
15 Backend, 15 Backend,
16 BackendClasses, 16 BackendClasses,
17 ImpactTransformer, 17 ImpactTransformer,
18 ForeignResolver, 18 ForeignResolver,
19 NativeRegistry; 19 NativeRegistry;
20 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem; 20 import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem;
21 import '../common/names.dart' show Identifiers, Selectors, Uris; 21 import '../common/names.dart' show Identifiers, Uris;
22 import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact; 22 import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact;
23 import '../common/tasks.dart' show CompilerTask; 23 import '../common/tasks.dart' show CompilerTask;
24 import '../compiler.dart' show Compiler; 24 import '../compiler.dart' show Compiler;
25 import '../constants/constant_system.dart'; 25 import '../constants/constant_system.dart';
26 import '../constants/expressions.dart'; 26 import '../constants/expressions.dart';
27 import '../constants/values.dart'; 27 import '../constants/values.dart';
28 import '../core_types.dart' show CoreClasses, CoreTypes; 28 import '../core_types.dart' show CommonElements, CoreClasses, CoreTypes;
29 import '../dart_types.dart'; 29 import '../dart_types.dart';
30 import '../deferred_load.dart' show DeferredLoadTask; 30 import '../deferred_load.dart' show DeferredLoadTask;
31 import '../dump_info.dart' show DumpInfoTask; 31 import '../dump_info.dart' show DumpInfoTask;
32 import '../elements/elements.dart'; 32 import '../elements/elements.dart';
33 import '../elements/entities.dart'; 33 import '../elements/entities.dart';
34 import '../enqueue.dart' 34 import '../enqueue.dart'
35 show Enqueuer, ResolutionEnqueuer, TreeShakingEnqueuerStrategy; 35 show Enqueuer, ResolutionEnqueuer, TreeShakingEnqueuerStrategy;
36 import '../io/position_information.dart' show PositionSourceInformationStrategy; 36 import '../io/position_information.dart' show PositionSourceInformationStrategy;
37 import '../io/source_information.dart' show SourceInformationStrategy; 37 import '../io/source_information.dart' show SourceInformationStrategy;
38 import '../io/start_end_information.dart' 38 import '../io/start_end_information.dart'
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 functionCompiler = 590 functionCompiler =
591 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel); 591 new SsaFunctionCompiler(this, sourceInformationStrategy, useKernel);
592 serialization = new JavaScriptBackendSerialization(this); 592 serialization = new JavaScriptBackendSerialization(this);
593 backendClasses = new JavaScriptBackendClasses(helpers); 593 backendClasses = new JavaScriptBackendClasses(helpers);
594 } 594 }
595 595
596 ConstantSystem get constantSystem => constants.constantSystem; 596 ConstantSystem get constantSystem => constants.constantSystem;
597 597
598 DiagnosticReporter get reporter => compiler.reporter; 598 DiagnosticReporter get reporter => compiler.reporter;
599 599
600 CommonElements get commonElements => compiler.commonElements;
601
600 CoreClasses get coreClasses => compiler.coreClasses; 602 CoreClasses get coreClasses => compiler.coreClasses;
601 603
602 CoreTypes get coreTypes => compiler.coreTypes; 604 CoreTypes get coreTypes => compiler.coreTypes;
603 605
604 Resolution get resolution => compiler.resolution; 606 Resolution get resolution => compiler.resolution;
605 607
606 /// Returns constant environment for the JavaScript interpretation of the 608 /// Returns constant environment for the JavaScript interpretation of the
607 /// constants. 609 /// constants.
608 JavaScriptConstantCompiler get constants { 610 JavaScriptConstantCompiler get constants {
609 return constantCompilerTask.jsConstantCompiler; 611 return constantCompilerTask.jsConstantCompiler;
(...skipping 665 matching lines...) Expand 10 before | Expand all | Expand 10 after
1275 if (TRACE_CALLS) { 1277 if (TRACE_CALLS) {
1276 impactTransformer.registerBackendImpact( 1278 impactTransformer.registerBackendImpact(
1277 impactBuilder, impacts.traceHelper); 1279 impactBuilder, impacts.traceHelper);
1278 } 1280 }
1279 impactTransformer.registerBackendImpact( 1281 impactTransformer.registerBackendImpact(
1280 impactBuilder, impacts.assertUnreachable); 1282 impactBuilder, impacts.assertUnreachable);
1281 _registerCheckedModeHelpers(impactBuilder); 1283 _registerCheckedModeHelpers(impactBuilder);
1282 return impactBuilder; 1284 return impactBuilder;
1283 } 1285 }
1284 1286
1285 onResolutionComplete(ClosedWorldRefiner closedWorldRefiner) { 1287 onResolutionComplete(
1288 ClosedWorld closedWorld, ClosedWorldRefiner closedWorldRefiner) {
1286 for (Entity entity in compiler.enqueuer.resolution.processedEntities) { 1289 for (Entity entity in compiler.enqueuer.resolution.processedEntities) {
1287 processAnnotations(entity, closedWorldRefiner); 1290 processAnnotations(entity, closedWorldRefiner);
1288 } 1291 }
1289 super.onResolutionComplete(closedWorldRefiner); 1292 computeMembersNeededForReflection(closedWorld);
1290 computeMembersNeededForReflection(); 1293 rti.computeClassesNeedingRti(
1291 rti.computeClassesNeedingRti(); 1294 compiler.enqueuer.resolution.universe, closedWorld);
1292 _registeredMetadata.clear(); 1295 _registeredMetadata.clear();
1293 } 1296 }
1294 1297
1295 onTypeInferenceComplete() { 1298 onTypeInferenceComplete() {
1296 super.onTypeInferenceComplete(); 1299 super.onTypeInferenceComplete();
1297 noSuchMethodRegistry.onTypeInferenceComplete(); 1300 noSuchMethodRegistry.onTypeInferenceComplete();
1298 } 1301 }
1299 1302
1300 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod, 1303 WorldImpact registerCallMethodWithFreeTypeVariables(Element callMethod,
1301 {bool forResolution}) { 1304 {bool forResolution}) {
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after
1647 element == coreClasses.boolClass) { 1650 element == coreClasses.boolClass) {
1648 if (nativeCheckOnly) return null; 1651 if (nativeCheckOnly) return null;
1649 return typeCast ? 'boolTypeCast' : 'boolTypeCheck'; 1652 return typeCast ? 'boolTypeCast' : 'boolTypeCheck';
1650 } else if (element == helpers.jsIntClass || 1653 } else if (element == helpers.jsIntClass ||
1651 element == coreClasses.intClass || 1654 element == coreClasses.intClass ||
1652 element == helpers.jsUInt32Class || 1655 element == helpers.jsUInt32Class ||
1653 element == helpers.jsUInt31Class || 1656 element == helpers.jsUInt31Class ||
1654 element == helpers.jsPositiveIntClass) { 1657 element == helpers.jsPositiveIntClass) {
1655 if (nativeCheckOnly) return null; 1658 if (nativeCheckOnly) return null;
1656 return typeCast ? 'intTypeCast' : 'intTypeCheck'; 1659 return typeCast ? 'intTypeCast' : 'intTypeCheck';
1657 } else if (Elements.isNumberOrStringSupertype(element, compiler)) { 1660 } else if (Elements.isNumberOrStringSupertype(element, commonElements)) {
1658 if (nativeCheck) { 1661 if (nativeCheck) {
1659 return typeCast 1662 return typeCast
1660 ? 'numberOrStringSuperNativeTypeCast' 1663 ? 'numberOrStringSuperNativeTypeCast'
1661 : 'numberOrStringSuperNativeTypeCheck'; 1664 : 'numberOrStringSuperNativeTypeCheck';
1662 } else { 1665 } else {
1663 return typeCast 1666 return typeCast
1664 ? 'numberOrStringSuperTypeCast' 1667 ? 'numberOrStringSuperTypeCast'
1665 : 'numberOrStringSuperTypeCheck'; 1668 : 'numberOrStringSuperTypeCheck';
1666 } 1669 }
1667 } else if (Elements.isStringOnlySupertype(element, compiler)) { 1670 } else if (Elements.isStringOnlySupertype(element, commonElements)) {
1668 if (nativeCheck) { 1671 if (nativeCheck) {
1669 return typeCast 1672 return typeCast
1670 ? 'stringSuperNativeTypeCast' 1673 ? 'stringSuperNativeTypeCast'
1671 : 'stringSuperNativeTypeCheck'; 1674 : 'stringSuperNativeTypeCheck';
1672 } else { 1675 } else {
1673 return typeCast ? 'stringSuperTypeCast' : 'stringSuperTypeCheck'; 1676 return typeCast ? 'stringSuperTypeCast' : 'stringSuperTypeCheck';
1674 } 1677 }
1675 } else if ((element == coreClasses.listClass || 1678 } else if ((element == coreClasses.listClass ||
1676 element == helpers.jsArrayClass) && 1679 element == helpers.jsArrayClass) &&
1677 type.treatAsRaw) { 1680 type.treatAsRaw) {
1678 if (nativeCheckOnly) return null; 1681 if (nativeCheckOnly) return null;
1679 return typeCast ? 'listTypeCast' : 'listTypeCheck'; 1682 return typeCast ? 'listTypeCast' : 'listTypeCheck';
1680 } else { 1683 } else {
1681 if (Elements.isListSupertype(element, compiler)) { 1684 if (Elements.isListSupertype(element, commonElements)) {
1682 if (nativeCheck) { 1685 if (nativeCheck) {
1683 return typeCast 1686 return typeCast
1684 ? 'listSuperNativeTypeCast' 1687 ? 'listSuperNativeTypeCast'
1685 : 'listSuperNativeTypeCheck'; 1688 : 'listSuperNativeTypeCheck';
1686 } else { 1689 } else {
1687 return typeCast ? 'listSuperTypeCast' : 'listSuperTypeCheck'; 1690 return typeCast ? 'listSuperTypeCast' : 'listSuperTypeCheck';
1688 } 1691 }
1689 } else { 1692 } else {
1690 if (type.isInterfaceType && !type.treatAsRaw) { 1693 if (type.isInterfaceType && !type.treatAsRaw) {
1691 return typeCast ? 'subtypeCast' : 'assertSubtype'; 1694 return typeCast ? 'subtypeCast' : 'assertSubtype';
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
2018 * reflection. 2021 * reflection.
2019 * 2022 *
2020 * We have to precompute this set as we cannot easily answer the need for 2023 * We have to precompute this set as we cannot easily answer the need for
2021 * reflection locally when looking at the member: We lack the information by 2024 * reflection locally when looking at the member: We lack the information by
2022 * which classes a member is inherited. Called after resolution is complete. 2025 * which classes a member is inherited. Called after resolution is complete.
2023 * 2026 *
2024 * We filter out private libraries here, as their elements should not 2027 * We filter out private libraries here, as their elements should not
2025 * be visible by reflection unless some other interfaces makes them 2028 * be visible by reflection unless some other interfaces makes them
2026 * accessible. 2029 * accessible.
2027 */ 2030 */
2028 void computeMembersNeededForReflection() { 2031 void computeMembersNeededForReflection(ClosedWorld closedWorld) {
2029 if (_membersNeededForReflection != null) return; 2032 if (_membersNeededForReflection != null) return;
2030 if (compiler.commonElements.mirrorsLibrary == null) { 2033 if (closedWorld.commonElements.mirrorsLibrary == null) {
2031 _membersNeededForReflection = const ImmutableEmptySet<Element>(); 2034 _membersNeededForReflection = const ImmutableEmptySet<Element>();
2032 return; 2035 return;
2033 } 2036 }
2034 // Compute a mapping from class to the closures it contains, so we 2037 // Compute a mapping from class to the closures it contains, so we
2035 // can include the correct ones when including the class. 2038 // can include the correct ones when including the class.
2036 Map<ClassElement, List<LocalFunctionElement>> closureMap = 2039 Map<ClassElement, List<LocalFunctionElement>> closureMap =
2037 new Map<ClassElement, List<LocalFunctionElement>>(); 2040 new Map<ClassElement, List<LocalFunctionElement>>();
2038 for (LocalFunctionElement closure in compiler.resolverWorld.allClosures) { 2041 for (LocalFunctionElement closure in compiler.resolverWorld.allClosures) {
2039 closureMap.putIfAbsent(closure.enclosingClass, () => []).add(closure); 2042 closureMap.putIfAbsent(closure.enclosingClass, () => []).add(closure);
2040 } 2043 }
(...skipping 21 matching lines...) Expand all
2062 memberNames.add(member.name); 2065 memberNames.add(member.name);
2063 reflectableMembers.add(element); 2066 reflectableMembers.add(element);
2064 element.nestedClosures 2067 element.nestedClosures
2065 .forEach((SynthesizedCallMethodElementX callFunction) { 2068 .forEach((SynthesizedCallMethodElementX callFunction) {
2066 reflectableMembers.add(callFunction); 2069 reflectableMembers.add(callFunction);
2067 reflectableMembers.add(callFunction.closureClass); 2070 reflectableMembers.add(callFunction.closureClass);
2068 }); 2071 });
2069 } 2072 }
2070 }); 2073 });
2071 // 4) all overriding members of subclasses/subtypes (should be resolved) 2074 // 4) all overriding members of subclasses/subtypes (should be resolved)
2072 if (compiler.closedWorld.hasAnyStrictSubtype(cls)) { 2075 if (closedWorld.hasAnyStrictSubtype(cls)) {
2073 compiler.closedWorld.forEachStrictSubtypeOf(cls, 2076 closedWorld.forEachStrictSubtypeOf(cls, (ClassElement subcls) {
2074 (ClassElement subcls) {
2075 subcls.forEachClassMember((Member member) { 2077 subcls.forEachClassMember((Member member) {
2076 if (memberNames.contains(member.name)) { 2078 if (memberNames.contains(member.name)) {
2077 // TODO(20993): find out why this assertion fails. 2079 // TODO(20993): find out why this assertion fails.
2078 // assert(invariant(member.element, 2080 // assert(invariant(member.element,
2079 // resolution.hasBeenProcessed(member.element))); 2081 // resolution.hasBeenProcessed(member.element)));
2080 if (resolution.hasBeenProcessed(member.element)) { 2082 if (resolution.hasBeenProcessed(member.element)) {
2081 reflectableMembers.add(member.element); 2083 reflectableMembers.add(member.element);
2082 } 2084 }
2083 } 2085 }
2084 }); 2086 });
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
2143 // As we do not think about closures as classes, yet, we have to make sure 2145 // As we do not think about closures as classes, yet, we have to make sure
2144 // their superclasses are available for reflection manually. 2146 // their superclasses are available for reflection manually.
2145 if (foundClosure) { 2147 if (foundClosure) {
2146 reflectableMembers.add(helpers.closureClass); 2148 reflectableMembers.add(helpers.closureClass);
2147 } 2149 }
2148 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers; 2150 Set<Element> closurizedMembers = compiler.resolverWorld.closurizedMembers;
2149 if (closurizedMembers.any(reflectableMembers.contains)) { 2151 if (closurizedMembers.any(reflectableMembers.contains)) {
2150 reflectableMembers.add(helpers.boundClosureClass); 2152 reflectableMembers.add(helpers.boundClosureClass);
2151 } 2153 }
2152 // Add typedefs. 2154 // Add typedefs.
2153 reflectableMembers.addAll( 2155 reflectableMembers
2154 compiler.closedWorld.allTypedefs.where(referencedFromMirrorSystem)); 2156 .addAll(closedWorld.allTypedefs.where(referencedFromMirrorSystem));
2155 // Register all symbols of reflectable elements 2157 // Register all symbols of reflectable elements
2156 for (Element element in reflectableMembers) { 2158 for (Element element in reflectableMembers) {
2157 symbolsUsed.add(element.name); 2159 symbolsUsed.add(element.name);
2158 } 2160 }
2159 _membersNeededForReflection = reflectableMembers; 2161 _membersNeededForReflection = reflectableMembers;
2160 } 2162 }
2161 2163
2162 // TODO(20791): compute closure classes after resolution and move this code to 2164 // TODO(20791): compute closure classes after resolution and move this code to
2163 // [computeMembersNeededForReflection]. 2165 // [computeMembersNeededForReflection].
2164 void maybeMarkClosureAsNeededForReflection( 2166 void maybeMarkClosureAsNeededForReflection(
(...skipping 16 matching lines...) Expand all
2181 // chance of making the dispatch record access monomorphic. 2183 // chance of making the dispatch record access monomorphic.
2182 jsAst.PropertyAccess record = 2184 jsAst.PropertyAccess record =
2183 new jsAst.PropertyAccess(use2, dispatchProperty); 2185 new jsAst.PropertyAccess(use2, dispatchProperty);
2184 2186
2185 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record]; 2187 List<jsAst.Expression> arguments = <jsAst.Expression>[use1, record];
2186 FunctionElement helper = helpers.isJsIndexable; 2188 FunctionElement helper = helpers.isJsIndexable;
2187 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper); 2189 jsAst.Expression helperExpression = emitter.staticFunctionAccess(helper);
2188 return new jsAst.Call(helperExpression, arguments); 2190 return new jsAst.Call(helperExpression, arguments);
2189 } 2191 }
2190 2192
2191 bool isTypedArray(TypeMask mask) {
2192 // Just checking for [:TypedData:] is not sufficient, as it is an
2193 // abstract class any user-defined class can implement. So we also
2194 // check for the interface [JavaScriptIndexingBehavior].
2195 ClassElement typedDataClass = compiler.commonElements.typedDataClass;
2196 return typedDataClass != null &&
2197 compiler.closedWorld.isInstantiated(typedDataClass) &&
2198 mask.satisfies(typedDataClass, compiler.closedWorld) &&
2199 mask.satisfies(
2200 helpers.jsIndexingBehaviorInterface, compiler.closedWorld);
2201 }
2202
2203 bool couldBeTypedArray(TypeMask mask) {
2204 bool intersects(TypeMask type1, TypeMask type2) =>
2205 !type1.intersection(type2, compiler.closedWorld).isEmpty;
2206 // TODO(herhut): Maybe cache the TypeMask for typedDataClass and
2207 // jsIndexingBehaviourInterface.
2208 ClassElement typedDataClass = compiler.commonElements.typedDataClass;
2209 return typedDataClass != null &&
2210 compiler.closedWorld.isInstantiated(typedDataClass) &&
2211 intersects(
2212 mask, new TypeMask.subtype(typedDataClass, compiler.closedWorld)) &&
2213 intersects(
2214 mask,
2215 new TypeMask.subtype(
2216 helpers.jsIndexingBehaviorInterface, compiler.closedWorld));
2217 }
2218
2219 /// Returns all static fields that are referenced through [targetsUsed]. 2193 /// Returns all static fields that are referenced through [targetsUsed].
2220 /// If the target is a library or class all nested static fields are 2194 /// If the target is a library or class all nested static fields are
2221 /// included too. 2195 /// included too.
2222 Iterable<Element> _findStaticFieldTargets() { 2196 Iterable<Element> _findStaticFieldTargets() {
2223 List staticFields = []; 2197 List staticFields = [];
2224 2198
2225 void addFieldsInContainer(ScopeContainerElement container) { 2199 void addFieldsInContainer(ScopeContainerElement container) {
2226 container.forEachLocalMember((Element member) { 2200 container.forEachLocalMember((Element member) {
2227 if (!member.isInstanceMember && member.isField) { 2201 if (!member.isInstanceMember && member.isField) {
2228 staticFields.add(member); 2202 staticFields.add(member);
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after
3223 ClassElement get typeImplementation => helpers.typeLiteralClass; 3197 ClassElement get typeImplementation => helpers.typeLiteralClass;
3224 ClassElement get boolImplementation => helpers.jsBoolClass; 3198 ClassElement get boolImplementation => helpers.jsBoolClass;
3225 ClassElement get nullImplementation => helpers.jsNullClass; 3199 ClassElement get nullImplementation => helpers.jsNullClass;
3226 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable; 3200 ClassElement get syncStarIterableImplementation => helpers.syncStarIterable;
3227 ClassElement get asyncFutureImplementation => helpers.futureImplementation; 3201 ClassElement get asyncFutureImplementation => helpers.futureImplementation;
3228 ClassElement get asyncStarStreamImplementation => helpers.controllerStream; 3202 ClassElement get asyncStarStreamImplementation => helpers.controllerStream;
3229 ClassElement get functionImplementation => helpers.coreClasses.functionClass; 3203 ClassElement get functionImplementation => helpers.coreClasses.functionClass;
3230 ClassElement get indexableImplementation => helpers.jsIndexableClass; 3204 ClassElement get indexableImplementation => helpers.jsIndexableClass;
3231 ClassElement get mutableIndexableImplementation => 3205 ClassElement get mutableIndexableImplementation =>
3232 helpers.jsMutableIndexableClass; 3206 helpers.jsMutableIndexableClass;
3207 ClassElement get indexingBehaviorImplementation =>
3208 helpers.jsIndexingBehaviorInterface;
3233 3209
3234 bool isDefaultEqualityImplementation(Element element) { 3210 bool isDefaultEqualityImplementation(Element element) {
3235 assert(element.name == '=='); 3211 assert(element.name == '==');
3236 ClassElement classElement = element.enclosingClass; 3212 ClassElement classElement = element.enclosingClass;
3237 return classElement == helpers.coreClasses.objectClass || 3213 return classElement == helpers.coreClasses.objectClass ||
3238 classElement == helpers.jsInterceptorClass || 3214 classElement == helpers.jsInterceptorClass ||
3239 classElement == helpers.jsNullClass; 3215 classElement == helpers.jsNullClass;
3240 } 3216 }
3217
3218 @override
3219 bool isInterceptorClass(ClassElement cls) {
3220 return helpers.backend.isInterceptorClass(cls);
3221 }
3222
3223 @override
3224 bool isNative(Element element) {
3225 return helpers.backend.isNative(element);
3226 }
3241 } 3227 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart ('k') | pkg/compiler/lib/src/js_backend/patch_resolver.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698