| Index: pkg/compiler/lib/src/common/codegen.dart
|
| diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
|
| index c7efea9cba34065a33351918e4b107db3db4fa79..88d92dc70100e7509799aeef44a594c9f1081de1 100644
|
| --- a/pkg/compiler/lib/src/common/codegen.dart
|
| +++ b/pkg/compiler/lib/src/common/codegen.dart
|
| @@ -29,140 +29,306 @@ import '../universe/selector.dart' show
|
| import '../universe/universe.dart' show
|
| UniverseSelector;
|
| import '../universe/world_impact.dart' show
|
| - WorldImpact;
|
| + WorldImpact,
|
| + WorldImpactBuilder;
|
| import '../util/util.dart' show
|
| + Pair,
|
| Setlet;
|
| import 'registry.dart' show
|
| - Registry;
|
| + Registry,
|
| + EagerRegistry;
|
| import 'work.dart' show
|
| ItemCompilationContext,
|
| WorkItem;
|
|
|
| +class CodegenImpact extends WorldImpact {
|
| + const CodegenImpact();
|
| +
|
| + // TODO(johnniwinther): Remove this.
|
| + Registry get registry => null;
|
| +
|
| + Iterable<Element> get getterForSuperElements => const <Element>[];
|
| +
|
| + Iterable<Element> get fieldGetters => const <Element>[];
|
| +
|
| + Iterable<Element> get fieldSetters => const <Element>[];
|
| +
|
| + Iterable<ConstantValue> get compileTimeConstants => const <ConstantValue>[];
|
| +
|
| + Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
|
| + return const <Pair<DartType, DartType>>[];
|
| + }
|
| +
|
| + Iterable<String> get constSymbols => const <String>[];
|
| +
|
| + Iterable<Set<ClassElement>> get specializedGetInterceptors {
|
| + return const <Set<ClassElement>>[];
|
| + }
|
| +
|
| + bool get usesInterceptor => false;
|
| +
|
| + Iterable<ClassElement> get typeConstants => const <ClassElement>[];
|
| +
|
| + Iterable<Element> get asyncMarkers => const <FunctionElement>[];
|
| +}
|
| +
|
| +class _CodegenImpact extends WorldImpactBuilder implements CodegenImpact {
|
| + // TODO(johnniwinther): Remove this.
|
| + final Registry registry;
|
| +
|
| +
|
| + Setlet<Element> _getterForSuperElements;
|
| + Setlet<Element> _fieldGetters;
|
| + Setlet<Element> _fieldSetters;
|
| + Setlet<ConstantValue> _compileTimeConstants;
|
| + Setlet<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks;
|
| + Setlet<String> _constSymbols;
|
| + List<Set<ClassElement>> _specializedGetInterceptors;
|
| + bool _usesInterceptor = false;
|
| + Setlet<ClassElement> _typeConstants;
|
| + Setlet<FunctionElement> _asyncMarkers;
|
| +
|
| + _CodegenImpact(this.registry);
|
| +
|
| + void registerGetterForSuperMethod(Element element) {
|
| + if (_getterForSuperElements == null) {
|
| + _getterForSuperElements = new Setlet<Element>();
|
| + }
|
| + _getterForSuperElements.add(element);
|
| + }
|
| +
|
| + Iterable<Element> get getterForSuperElements {
|
| + return _getterForSuperElements != null
|
| + ? _getterForSuperElements : const <Element>[];
|
| + }
|
| +
|
| + void registerFieldGetter(Element element) {
|
| + if (_fieldGetters == null) {
|
| + _fieldGetters = new Setlet<Element>();
|
| + }
|
| + _fieldGetters.add(element);
|
| + }
|
| +
|
| + Iterable<Element> get fieldGetters {
|
| + return _fieldGetters != null
|
| + ? _fieldGetters : const <Element>[];
|
| + }
|
| +
|
| + void registerFieldSetter(Element element) {
|
| + if (_fieldSetters == null) {
|
| + _fieldSetters = new Setlet<Element>();
|
| + }
|
| + _fieldSetters.add(element);
|
| + }
|
| +
|
| + Iterable<Element> get fieldSetters {
|
| + return _fieldSetters != null
|
| + ? _fieldSetters : const <Element>[];
|
| + }
|
| +
|
| + void registerCompileTimeConstant(ConstantValue constant) {
|
| + if (_compileTimeConstants == null) {
|
| + _compileTimeConstants = new Setlet<ConstantValue>();
|
| + }
|
| + _compileTimeConstants.add(constant);
|
| + }
|
| +
|
| + Iterable<ConstantValue> get compileTimeConstants {
|
| + return _compileTimeConstants != null
|
| + ? _compileTimeConstants : const <ConstantValue>[];
|
| + }
|
| +
|
| + void registerTypeVariableBoundsSubtypeCheck(DartType subtype,
|
| + DartType supertype) {
|
| + if (_typeVariableBoundsSubtypeChecks == null) {
|
| + _typeVariableBoundsSubtypeChecks = new Setlet<Pair<DartType, DartType>>();
|
| + }
|
| + _typeVariableBoundsSubtypeChecks.add(
|
| + new Pair<DartType, DartType>(subtype, supertype));
|
| + }
|
| +
|
| + Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
|
| + return _typeVariableBoundsSubtypeChecks != null
|
| + ? _typeVariableBoundsSubtypeChecks : const <Pair<DartType, DartType>>[];
|
| + }
|
| +
|
| + void registerConstSymbol(String name) {
|
| + if (_constSymbols == null) {
|
| + _constSymbols = new Setlet<String>();
|
| + }
|
| + _constSymbols.add(name);
|
| + }
|
| +
|
| + Iterable<String> get constSymbols {
|
| + return _constSymbols != null
|
| + ? _constSymbols : const <String>[];
|
| + }
|
| +
|
| + void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
|
| + if (_specializedGetInterceptors == null) {
|
| + _specializedGetInterceptors = <Set<ClassElement>>[];
|
| + }
|
| + _specializedGetInterceptors.add(classes);
|
| + }
|
| +
|
| + Iterable<Set<ClassElement>> get specializedGetInterceptors {
|
| + return _specializedGetInterceptors != null
|
| + ? _specializedGetInterceptors : const <Set<ClassElement>>[];
|
| + }
|
| +
|
| + void registerUseInterceptor() {
|
| + _usesInterceptor = true;
|
| + }
|
| +
|
| + bool get usesInterceptor => _usesInterceptor;
|
| +
|
| + void registerTypeConstant(ClassElement element) {
|
| + if (_typeConstants == null) {
|
| + _typeConstants = new Setlet<ClassElement>();
|
| + }
|
| + _typeConstants.add(element);
|
| + }
|
| +
|
| + Iterable<ClassElement> get typeConstants {
|
| + return _typeConstants != null
|
| + ? _typeConstants : const <ClassElement>[];
|
| + }
|
| +
|
| + void registerAsyncMarker(FunctionElement element) {
|
| + if (_asyncMarkers == null) {
|
| + _asyncMarkers = new Setlet<FunctionElement>();
|
| + }
|
| + _asyncMarkers.add(element);
|
| + }
|
| +
|
| + Iterable<Element> get asyncMarkers {
|
| + return _asyncMarkers != null
|
| + ? _asyncMarkers : const <FunctionElement>[];
|
| + }
|
| +}
|
| +
|
| // TODO(johnniwinther): Split this class into interface and implementation.
|
| // TODO(johnniwinther): Move this implementation to the JS backend.
|
| class CodegenRegistry extends Registry {
|
| final Compiler compiler;
|
| - final TreeElements treeElements;
|
| + final Element currentElement;
|
| + final _CodegenImpact worldImpact;
|
|
|
| - CodegenRegistry(this.compiler, this.treeElements);
|
| + CodegenRegistry(Compiler compiler, AstElement currentElement)
|
| + : this.compiler = compiler,
|
| + this.currentElement = currentElement,
|
| + this.worldImpact = new _CodegenImpact(new EagerRegistry(
|
| + 'EagerRegistry for $currentElement', compiler.enqueuer.codegen));
|
|
|
| bool get isForResolution => false;
|
|
|
| - Element get currentElement => treeElements.analyzedElement;
|
| -
|
| String toString() => 'CodegenRegistry for $currentElement';
|
|
|
| - CodegenEnqueuer get world => compiler.enqueuer.codegen;
|
| - JavaScriptBackend get backend => compiler.backend;
|
| -
|
| - void registerAssert(bool hasMessage) {
|
| - // Codegen does not register asserts. They have been lowered to calls.
|
| - assert(false);
|
| - }
|
| -
|
| void registerInstantiatedClass(ClassElement element) {
|
| - backend.registerInstantiatedType(element.rawType, world, this);
|
| + registerInstantiatedType(element.rawType);
|
| }
|
|
|
| void registerInstantiatedType(InterfaceType type) {
|
| - backend.registerInstantiatedType(type, world, this);
|
| + worldImpact.registerInstantiatedType(type);
|
| }
|
|
|
| void registerStaticUse(Element element) {
|
| - world.registerStaticUse(element);
|
| + worldImpact.registerStaticUse(element);
|
| }
|
|
|
| void registerDynamicInvocation(UniverseSelector selector) {
|
| - world.registerDynamicInvocation(selector);
|
| + worldImpact.registerDynamicInvocation(selector);
|
| compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
|
| }
|
|
|
| void registerDynamicSetter(UniverseSelector selector) {
|
| - world.registerDynamicSetter(selector);
|
| + worldImpact.registerDynamicSetter(selector);
|
| compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
|
| }
|
|
|
| void registerDynamicGetter(UniverseSelector selector) {
|
| - world.registerDynamicGetter(selector);
|
| + worldImpact.registerDynamicGetter(selector);
|
| compiler.dumpInfoTask.elementUsesSelector(currentElement, selector);
|
| }
|
|
|
| void registerGetterForSuperMethod(Element element) {
|
| - world.registerGetterForSuperMethod(element);
|
| + worldImpact.registerGetterForSuperMethod(element);
|
| }
|
|
|
| void registerFieldGetter(Element element) {
|
| - world.registerFieldGetter(element);
|
| + worldImpact.registerFieldGetter(element);
|
| }
|
|
|
| void registerFieldSetter(Element element) {
|
| - world.registerFieldSetter(element);
|
| + worldImpact.registerFieldSetter(element);
|
| }
|
|
|
| void registerIsCheck(DartType type) {
|
| - world.registerIsCheck(type);
|
| - backend.registerIsCheckForCodegen(type, world, this);
|
| + worldImpact.registerIsCheck(type);
|
| }
|
|
|
| void registerCompileTimeConstant(ConstantValue constant) {
|
| - backend.registerCompileTimeConstant(constant, this);
|
| - backend.addCompileTimeConstantForEmission(constant);
|
| + worldImpact.registerCompileTimeConstant(constant);
|
| }
|
|
|
| void registerTypeVariableBoundsSubtypeCheck(DartType subtype,
|
| DartType supertype) {
|
| - backend.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
|
| + worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
|
| }
|
|
|
| void registerInstantiatedClosure(LocalFunctionElement element) {
|
| - backend.registerInstantiatedClosure(element, this);
|
| + worldImpact.registerClosure(element);
|
| }
|
|
|
| void registerGetOfStaticFunction(FunctionElement element) {
|
| - world.registerGetOfStaticFunction(element);
|
| + worldImpact.registerClosurizedFunction(element);
|
| }
|
|
|
| void registerSelectorUse(Selector selector) {
|
| - world.registerSelectorUse(new UniverseSelector(selector, null));
|
| + if (selector.isGetter) {
|
| + registerDynamicGetter(new UniverseSelector(selector, null));
|
| + } else if (selector.isSetter) {
|
| + registerDynamicSetter(new UniverseSelector(selector, null));
|
| + } else {
|
| + registerDynamicInvocation(new UniverseSelector(selector, null));
|
| + }
|
| }
|
|
|
| void registerConstSymbol(String name) {
|
| - backend.registerConstSymbol(name);
|
| + worldImpact.registerConstSymbol(name);
|
| }
|
|
|
| void registerSpecializedGetInterceptor(Set<ClassElement> classes) {
|
| - backend.registerSpecializedGetInterceptor(classes);
|
| + worldImpact.registerSpecializedGetInterceptor(classes);
|
| }
|
|
|
| void registerUseInterceptor() {
|
| - backend.registerUseInterceptor(world);
|
| + worldImpact.registerUseInterceptor();
|
| }
|
|
|
| void registerTypeConstant(ClassElement element) {
|
| - backend.customElementsAnalysis.registerTypeConstant(element, world);
|
| - backend.lookupMapAnalysis.registerTypeConstant(element);
|
| + worldImpact.registerTypeConstant(element);
|
| }
|
|
|
| void registerStaticInvocation(Element element) {
|
| - world.registerStaticUse(element);
|
| + registerStaticUse(element);
|
| }
|
|
|
| void registerSuperInvocation(Element element) {
|
| - world.registerStaticUse(element);
|
| + registerStaticUse(element);
|
| }
|
|
|
| void registerDirectInvocation(Element element) {
|
| - world.registerStaticUse(element);
|
| + registerStaticUse(element);
|
| }
|
|
|
| void registerInstantiation(InterfaceType type) {
|
| - backend.registerInstantiatedType(type, world, this);
|
| + registerInstantiatedType(type);
|
| }
|
|
|
| void registerAsyncMarker(FunctionElement element) {
|
| - backend.registerAsyncMarker(element, world, this);
|
| + worldImpact.registerAsyncMarker(element);
|
| }
|
| -
|
| }
|
|
|
| /// [WorkItem] used exclusively by the [CodegenEnqueuer].
|
| @@ -195,7 +361,7 @@ class CodegenWorkItem extends WorkItem {
|
| WorldImpact run(Compiler compiler, CodegenEnqueuer world) {
|
| if (world.isProcessed(element)) return const WorldImpact();
|
|
|
| - registry = new CodegenRegistry(compiler, resolutionTree);
|
| + registry = new CodegenRegistry(compiler, element);
|
| return compiler.codegen(this, world);
|
| }
|
| }
|
|
|