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

Side by Side Diff: pkg/compiler/lib/src/world.dart

Issue 2582393002: Merge WorldImpl with ResolutionWorldBuilderImpl (Closed)
Patch Set: Updated cf. comment Created 3 years, 12 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 library dart2js.world; 5 library dart2js.world;
6 6
7 import 'cache_strategy.dart';
8 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX; 7 import 'closure.dart' show ClosureClassElement, SynthesizedCallMethodElementX;
9 import 'common/backend_api.dart' show BackendClasses; 8 import 'common/backend_api.dart' show BackendClasses;
10 import 'common.dart'; 9 import 'common.dart';
11 import 'constants/constant_system.dart'; 10 import 'constants/constant_system.dart';
12 import 'core_types.dart' show CoreTypes, CoreClasses, CommonElements; 11 import 'core_types.dart' show CoreTypes, CoreClasses, CommonElements;
13 import 'dart_types.dart'; 12 import 'dart_types.dart';
14 import 'elements/elements.dart' 13 import 'elements/elements.dart'
15 show 14 show
16 ClassElement, 15 ClassElement,
17 Element, 16 Element,
18 FunctionElement, 17 FunctionElement,
19 MixinApplicationElement, 18 MixinApplicationElement,
20 TypedefElement, 19 TypedefElement,
21 FieldElement; 20 FieldElement;
22 import 'js_backend/backend.dart' show JavaScriptBackend; 21 import 'js_backend/backend.dart' show JavaScriptBackend;
23 import 'ordered_typeset.dart'; 22 import 'ordered_typeset.dart';
24 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask; 23 import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
25 import 'universe/class_set.dart'; 24 import 'universe/class_set.dart';
26 import 'universe/function_set.dart' show FunctionSet, FunctionSetBuilder; 25 import 'universe/function_set.dart' show FunctionSet, FunctionSetBuilder;
27 import 'universe/selector.dart' show Selector; 26 import 'universe/selector.dart' show Selector;
28 import 'universe/side_effects.dart' show SideEffects; 27 import 'universe/side_effects.dart' show SideEffects;
29 import 'universe/world_builder.dart' 28 import 'universe/world_builder.dart' show ResolutionWorldBuilder;
30 show InstantiationInfo, ResolutionWorldBuilder;
31 import 'util/util.dart' show Link; 29 import 'util/util.dart' show Link;
32 30
33 /// Common superinterface for [OpenWorld] and [ClosedWorld]. 31 /// Common superinterface for [OpenWorld] and [ClosedWorld].
34 abstract class World {} 32 abstract class World {}
35 33
36 /// The [ClosedWorld] represents the information known about a program when 34 /// The [ClosedWorld] represents the information known about a program when
37 /// compiling with closed-world semantics. 35 /// compiling with closed-world semantics.
38 /// 36 ///
39 /// Given the entrypoint of an application, we can track what's reachable from 37 /// Given the entrypoint of an application, we can track what's reachable from
40 /// it, what functions are called, what classes are allocated, which native 38 /// it, what functions are called, what classes are allocated, which native
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 341
344 void registerUsedElement(Element element); 342 void registerUsedElement(Element element);
345 void registerTypedef(TypedefElement typedef); 343 void registerTypedef(TypedefElement typedef);
346 344
347 ClosedWorld closeWorld(DiagnosticReporter reporter); 345 ClosedWorld closeWorld(DiagnosticReporter reporter);
348 346
349 /// Returns an iterable over all mixin applications that mixin [cls]. 347 /// Returns an iterable over all mixin applications that mixin [cls].
350 Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls); 348 Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls);
351 } 349 }
352 350
353 class WorldImpl implements OpenWorld {
354 bool _closed = false;
355 ClosedWorld _closedWorldCache;
356
357 final JavaScriptBackend _backend;
358 FunctionSetBuilder _allFunctions;
359
360 final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>();
361
362 final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses =
363 new Map<ClassElement, Set<MixinApplicationElement>>();
364
365 // We keep track of subtype and subclass relationships in four
366 // distinct sets to make class hierarchy analysis faster.
367 final Map<ClassElement, ClassHierarchyNode> _classHierarchyNodes =
368 <ClassElement, ClassHierarchyNode>{};
369 final Map<ClassElement, ClassSet> _classSets = <ClassElement, ClassSet>{};
370
371 final Map<ClassElement, Map<ClassElement, bool>> _subtypeCoveredByCache =
372 <ClassElement, Map<ClassElement, bool>>{};
373
374 final Set<Element> alreadyPopulated;
375
376 final CommonElements commonElements;
377
378 final CoreTypes coreTypes;
379
380 final CacheStrategy cacheStrategy;
381
382 final ResolutionWorldBuilder resolverWorld;
383
384 bool get isClosed => _closed;
385
386 WorldImpl(this.resolverWorld, this._backend, this.commonElements,
387 this.coreTypes, CacheStrategy cacheStrategy)
388 : this.cacheStrategy = cacheStrategy,
389 alreadyPopulated = cacheStrategy.newSet() {
390 _allFunctions = new FunctionSetBuilder();
391 }
392
393 /// Returns an iterable over all mixin applications that mixin [cls].
394 Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls) {
395 Iterable<MixinApplicationElement> uses = _mixinUses[cls];
396 return uses != null ? uses : const <MixinApplicationElement>[];
397 }
398
399 /// Called to add [cls] to the set of known classes.
400 ///
401 /// This ensures that class hierarchy queries can be performed on [cls] and
402 /// classes that extend or implement it.
403 void registerClass(ClassElement cls) => _registerClass(cls);
404
405 void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) {
406 _ensureClassSet(cls);
407 if (isDirectlyInstantiated) {
408 _updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
409 }
410 }
411
412 void registerTypedef(TypedefElement typdef) {
413 _allTypedefs.add(typdef);
414 }
415
416 ClassHierarchyNode _ensureClassHierarchyNode(ClassElement cls) {
417 cls = cls.declaration;
418 return _classHierarchyNodes.putIfAbsent(cls, () {
419 ClassHierarchyNode parentNode;
420 if (cls.superclass != null) {
421 parentNode = _ensureClassHierarchyNode(cls.superclass);
422 }
423 return new ClassHierarchyNode(parentNode, cls);
424 });
425 }
426
427 ClassSet _ensureClassSet(ClassElement cls) {
428 cls = cls.declaration;
429 return _classSets.putIfAbsent(cls, () {
430 ClassHierarchyNode node = _ensureClassHierarchyNode(cls);
431 ClassSet classSet = new ClassSet(node);
432
433 for (InterfaceType type in cls.allSupertypes) {
434 // TODO(johnniwinther): Optimization: Avoid adding [cls] to
435 // superclasses.
436 ClassSet subtypeSet = _ensureClassSet(type.element);
437 subtypeSet.addSubtype(node);
438 }
439 if (cls.isMixinApplication) {
440 // TODO(johnniwinther): Store this in the [ClassSet].
441 MixinApplicationElement mixinApplication = cls;
442 if (mixinApplication.mixin != null) {
443 // If [mixinApplication] is malformed [mixin] is `null`.
444 registerMixinUse(mixinApplication, mixinApplication.mixin);
445 }
446 }
447
448 return classSet;
449 });
450 }
451
452 void _updateSuperClassHierarchyNodeForClass(ClassHierarchyNode node) {
453 // Ensure that classes implicitly implementing `Function` are in its
454 // subtype set.
455 ClassElement cls = node.cls;
456 if (cls != commonElements.functionClass &&
457 cls.implementsFunction(commonElements)) {
458 ClassSet subtypeSet = _ensureClassSet(commonElements.functionClass);
459 subtypeSet.addSubtype(node);
460 }
461 if (!node.isInstantiated && node.parentNode != null) {
462 _updateSuperClassHierarchyNodeForClass(node.parentNode);
463 }
464 }
465
466 void _updateClassHierarchyNodeForClass(ClassElement cls,
467 {bool directlyInstantiated: false, bool abstractlyInstantiated: false}) {
468 ClassHierarchyNode node = _ensureClassHierarchyNode(cls);
469 _updateSuperClassHierarchyNodeForClass(node);
470 if (directlyInstantiated) {
471 node.isDirectlyInstantiated = true;
472 }
473 if (abstractlyInstantiated) {
474 node.isAbstractlyInstantiated = true;
475 }
476 }
477
478 ClosedWorld closeWorld(DiagnosticReporter reporter) {
479 Map<ClassElement, Set<ClassElement>> typesImplementedBySubclasses =
480 new Map<ClassElement, Set<ClassElement>>();
481
482 /// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
483 /// properties of the [ClassHierarchyNode] for [cls].
484
485 void addSubtypes(ClassElement cls, InstantiationInfo info) {
486 if (!info.hasInstantiation) {
487 return;
488 }
489 if (cacheStrategy.hasIncrementalSupport && !alreadyPopulated.add(cls)) {
490 return;
491 }
492 assert(cls.isDeclaration);
493 if (!cls.isResolved) {
494 reporter.internalError(cls, 'Class "${cls.name}" is not resolved.');
495 }
496
497 _updateClassHierarchyNodeForClass(cls,
498 directlyInstantiated: info.isDirectlyInstantiated,
499 abstractlyInstantiated: info.isAbstractlyInstantiated);
500
501 // Walk through the superclasses, and record the types
502 // implemented by that type on the superclasses.
503 ClassElement superclass = cls.superclass;
504 while (superclass != null) {
505 Set<Element> typesImplementedBySubclassesOfCls =
506 typesImplementedBySubclasses.putIfAbsent(
507 superclass, () => new Set<ClassElement>());
508 for (DartType current in cls.allSupertypes) {
509 typesImplementedBySubclassesOfCls.add(current.element);
510 }
511 superclass = superclass.superclass;
512 }
513 }
514
515 // Use the [:seenClasses:] set to include non-instantiated
516 // classes: if the superclass of these classes require RTI, then
517 // they also need RTI, so that a constructor passes the type
518 // variables to the super constructor.
519 resolverWorld.forEachInstantiatedClass(addSubtypes);
520
521 _closed = true;
522 return _closedWorldCache = new ClosedWorldImpl(
523 backend: _backend,
524 commonElements: commonElements,
525 coreTypes: coreTypes,
526 resolverWorld: resolverWorld,
527 functionSetBuilder: _allFunctions,
528 allTypedefs: _allTypedefs,
529 mixinUses: _mixinUses,
530 typesImplementedBySubclasses: typesImplementedBySubclasses,
531 classHierarchyNodes: _classHierarchyNodes,
532 classSets: _classSets);
533 }
534
535 void registerMixinUse(
536 MixinApplicationElement mixinApplication, ClassElement mixin) {
537 // TODO(johnniwinther): Add map restricted to live classes.
538 // We don't support patch classes as mixin.
539 assert(mixin.isDeclaration);
540 Set<MixinApplicationElement> users =
541 _mixinUses.putIfAbsent(mixin, () => new Set<MixinApplicationElement>());
542 users.add(mixinApplication);
543 }
544
545 void registerUsedElement(Element element) {
546 if (element.isInstanceMember && !element.isAbstract) {
547 _allFunctions.add(element);
548 }
549 }
550
551 ClosedWorld get closedWorldCache {
552 assert(isClosed);
553 return _closedWorldCache;
554 }
555 }
556
557 /// Enum values defining subset of classes included in queries. 351 /// Enum values defining subset of classes included in queries.
558 enum ClassQuery { 352 enum ClassQuery {
559 /// Only the class itself is included. 353 /// Only the class itself is included.
560 EXACT, 354 EXACT,
561 355
562 /// The class and all subclasses (transitively) are included. 356 /// The class and all subclasses (transitively) are included.
563 SUBCLASS, 357 SUBCLASS,
564 358
565 /// The class and all classes that implement or subclass it (transitively) 359 /// The class and all classes that implement or subclass it (transitively)
566 /// are included. 360 /// are included.
(...skipping 751 matching lines...) Expand 10 before | Expand all | Expand 10 after
1318 return getMightBePassedToApply(element.expression); 1112 return getMightBePassedToApply(element.expression);
1319 } 1113 }
1320 return functionsThatMightBePassedToApply.contains(element); 1114 return functionsThatMightBePassedToApply.contains(element);
1321 } 1115 }
1322 1116
1323 @override 1117 @override
1324 bool getCurrentlyKnownMightBePassedToApply(Element element) { 1118 bool getCurrentlyKnownMightBePassedToApply(Element element) {
1325 return getMightBePassedToApply(element); 1119 return getMightBePassedToApply(element);
1326 } 1120 }
1327 } 1121 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/world_builder.dart ('k') | tests/compiler/dart2js/kernel/closed_world_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698