| Index: sdk/lib/_internal/compiler/implementation/enqueue.dart
|
| diff --git a/sdk/lib/_internal/compiler/implementation/enqueue.dart b/sdk/lib/_internal/compiler/implementation/enqueue.dart
|
| index 1f33ab2a8bd2e6d497b96d3acf4bf4e7a75cf298..35304168ac2e60063205afb3b82ca9a88c24caff 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
|
| @@ -82,6 +82,8 @@ abstract class Enqueuer {
|
| bool hasEnqueuedEverything = false;
|
| bool hasEnqueuedReflectiveStaticFields = false;
|
|
|
| + Relations get dependencies;
|
| +
|
| Enqueuer(this.name, this.compiler, this.itemCompilationContextCreator);
|
|
|
| Queue<WorkItem> get queue;
|
| @@ -99,13 +101,17 @@ abstract class Enqueuer {
|
| */
|
| void addToWorkList(Element element) {
|
| assert(invariant(element, element.isDeclaration));
|
| - internalAddToWorkList(element);
|
| + if (internalAddToWorkList(element)) {
|
| + dependencies.put('addsToWorklist', compiler.currentElement, element);
|
| + }
|
| }
|
|
|
| /**
|
| * Adds [element] to the work list if it has not already been processed.
|
| + *
|
| + * Returns [true] if the element was actually added to the queue.
|
| */
|
| - void internalAddToWorkList(Element element);
|
| + bool internalAddToWorkList(Element element);
|
|
|
| void registerInstantiatedType(InterfaceType type, Registry registry) {
|
| task.measure(() {
|
| @@ -217,6 +223,10 @@ abstract class Enqueuer {
|
| memberName, () => const Link<Element>());
|
| instanceFunctionsByName[memberName] = members.prepend(member);
|
| if (universe.hasInvocation(member, compiler)) {
|
| + for (Selector selector in
|
| + universe.getMatchingSelectors(member, compiler)) {
|
| + dependencies.enqueues(getContext(), member);
|
| + }
|
| addToWorkList(member);
|
| return;
|
| }
|
| @@ -245,6 +255,9 @@ abstract class Enqueuer {
|
| instanceMembersByName[memberName] = members.prepend(member);
|
| }
|
|
|
| + // TODO(karlklose): get the context.
|
| + getContext() => compiler.currentElement;
|
| +
|
| void enableNoSuchMethod(Element element) {}
|
| void enableIsolateSupport(LibraryElement element) {}
|
|
|
| @@ -278,32 +291,33 @@ abstract class Enqueuer {
|
| });
|
| }
|
|
|
| - void registerNewSelector(Selector selector,
|
| + void registerNewSelector(Element context,
|
| + Selector selector,
|
| Map<String, Set<Selector>> selectorsMap) {
|
| String name = selector.name;
|
| Set<Selector> selectors =
|
| selectorsMap.putIfAbsent(name, () => new Setlet<Selector>());
|
| if (!selectors.contains(selector)) {
|
| selectors.add(selector);
|
| - handleUnseenSelector(name, selector);
|
| + handleUnseenSelector(getContext(), name, selector);
|
| }
|
| }
|
|
|
| - void registerInvocation(Selector selector) {
|
| + void registerInvocation(Element context, Selector selector) {
|
| task.measure(() {
|
| - registerNewSelector(selector, universe.invokedNames);
|
| + registerNewSelector(context, selector, universe.invokedNames);
|
| });
|
| }
|
|
|
| - void registerInvokedGetter(Selector selector) {
|
| + void registerInvokedGetter(Element context, Selector selector) {
|
| task.measure(() {
|
| - registerNewSelector(selector, universe.invokedGetters);
|
| + registerNewSelector(context, selector, universe.invokedGetters);
|
| });
|
| }
|
|
|
| - void registerInvokedSetter(Selector selector) {
|
| + void registerInvokedSetter(Element context, Selector selector) {
|
| task.measure(() {
|
| - registerNewSelector(selector, universe.invokedSetters);
|
| + registerNewSelector(context, selector, universe.invokedSetters);
|
| });
|
| }
|
|
|
| @@ -329,11 +343,11 @@ abstract class Enqueuer {
|
| registerStaticUse(element.declaration);
|
| } else if (element.isInstanceMember) {
|
| Selector selector = new Selector.fromElement(element, compiler);
|
| - registerSelectorUse(selector);
|
| + registerSelectorUse(element, selector);
|
| if (element.isField) {
|
| Selector selector =
|
| new Selector.setter(element.name, element.library);
|
| - registerInvokedSetter(selector);
|
| + registerInvokedSetter(element, selector);
|
| }
|
| }
|
| }
|
| @@ -386,8 +400,11 @@ abstract class Enqueuer {
|
| processLink(instanceFunctionsByName, n, f);
|
| }
|
|
|
| - void handleUnseenSelector(String methodName, Selector selector) {
|
| + void handleUnseenSelector(Element context,
|
| + String methodName,
|
| + Selector selector) {
|
| processInstanceMembers(methodName, (Element member) {
|
| + dependencies.enqueues(context, member);
|
| if (selector.appliesUnnamed(member, compiler)) {
|
| if (member.isFunction && selector.isGetter) {
|
| registerClosurizedMember(member, compiler.globalDependencies);
|
| @@ -445,27 +462,27 @@ abstract class Enqueuer {
|
| universe.staticFunctionsNeedingGetter.add(element);
|
| }
|
|
|
| - void registerDynamicInvocation(Selector selector) {
|
| + void registerDynamicInvocation(Element context, Selector selector) {
|
| assert(selector != null);
|
| - registerInvocation(selector);
|
| + registerInvocation(context, selector);
|
| }
|
|
|
| - void registerSelectorUse(Selector selector) {
|
| + void registerSelectorUse(Element context, Selector selector) {
|
| if (selector.isGetter) {
|
| - registerInvokedGetter(selector);
|
| + registerInvokedGetter(context, selector);
|
| } else if (selector.isSetter) {
|
| - registerInvokedSetter(selector);
|
| + registerInvokedSetter(context, selector);
|
| } else {
|
| - registerInvocation(selector);
|
| + registerInvocation(context, selector);
|
| }
|
| }
|
|
|
| - void registerDynamicGetter(Selector selector) {
|
| - registerInvokedGetter(selector);
|
| + void registerDynamicGetter(Element context, Selector selector) {
|
| + registerInvokedGetter(context, selector);
|
| }
|
|
|
| - void registerDynamicSetter(Selector selector) {
|
| - registerInvokedSetter(selector);
|
| + void registerDynamicSetter(Element context, Selector selector) {
|
| + registerInvokedSetter(context, selector);
|
| }
|
|
|
| void registerGetterForSuperMethod(Element element) {
|
| @@ -571,12 +588,16 @@ class ResolutionEnqueuer extends Enqueuer {
|
| */
|
| final Queue<DeferredTask> deferredTaskQueue;
|
|
|
| + Relations dependencies;
|
| +
|
| ResolutionEnqueuer(Compiler compiler,
|
| ItemCompilationContext itemCompilationContextCreator())
|
| : super('resolution enqueuer', compiler, itemCompilationContextCreator),
|
| resolvedElements = new Map<Element, TreeElements>(),
|
| queue = new Queue<ResolutionWorkItem>(),
|
| - deferredTaskQueue = new Queue<DeferredTask>();
|
| + deferredTaskQueue = new Queue<DeferredTask>() {
|
| + dependencies = new Relations(this);
|
| + }
|
|
|
| bool get isResolutionQueue => true;
|
|
|
| @@ -605,10 +626,10 @@ class ResolutionEnqueuer extends Enqueuer {
|
| return resolvedElements[owner.declaration];
|
| }
|
|
|
| - void internalAddToWorkList(Element element) {
|
| + bool internalAddToWorkList(Element element) {
|
| assert(invariant(element, element is AnalyzableElement,
|
| message: 'Element $element is not analyzable.'));
|
| - if (getCachedElements(element) != null) return;
|
| + if (getCachedElements(element) != null) return false;
|
| if (queueIsClosed) {
|
| throw new SpannableAssertionFailure(element,
|
| "Resolution work list is closed. Trying to add $element.");
|
| @@ -652,6 +673,7 @@ class ResolutionEnqueuer extends Enqueuer {
|
| }
|
|
|
| nativeEnqueuer.registerElement(element);
|
| + return true;
|
| }
|
|
|
| void enableIsolateSupport(LibraryElement element) {
|
| @@ -671,7 +693,7 @@ class ResolutionEnqueuer extends Enqueuer {
|
|
|
| Selector selector = compiler.noSuchMethodSelector;
|
| compiler.enabledNoSuchMethod = true;
|
| - compiler.backend.enableNoSuchMethod(this);
|
| + compiler.backend.enableNoSuchMethod(element, this);
|
| }
|
|
|
| /**
|
| @@ -718,24 +740,28 @@ class CodegenEnqueuer extends Enqueuer {
|
| final Map<Element, js.Expression> generatedCode =
|
| new Map<Element, js.Expression>();
|
|
|
| + Relations dependencies;
|
| +
|
| CodegenEnqueuer(Compiler compiler,
|
| ItemCompilationContext itemCompilationContextCreator())
|
| : super('codegen enqueuer', compiler, itemCompilationContextCreator),
|
| - queue = new Queue<CodegenWorkItem>();
|
| + queue = new Queue<CodegenWorkItem>() {
|
| + dependencies = new Relations(this);
|
| + }
|
|
|
| bool isProcessed(Element member) =>
|
| member.isAbstract || generatedCode.containsKey(member);
|
|
|
| - void internalAddToWorkList(Element element) {
|
| + bool internalAddToWorkList(Element element) {
|
| // Don't generate code for foreign elements.
|
| - if (element.isForeign(compiler)) return;
|
| + if (element.isForeign(compiler)) return false;
|
|
|
| // Codegen inlines field initializers. It only needs to generate
|
| // code for checked setters.
|
| if (element.isField && element.isInstanceMember) {
|
| if (!compiler.enableTypeAssertions
|
| || element.enclosingElement.isClosure) {
|
| - return;
|
| + return false;
|
| }
|
| }
|
|
|
| @@ -746,6 +772,7 @@ class CodegenEnqueuer extends Enqueuer {
|
| CodegenWorkItem workItem = new CodegenWorkItem(
|
| element, itemCompilationContextCreator());
|
| queue.add(workItem);
|
| + return true;
|
| }
|
|
|
| void _logSpecificSummary(log(message)) {
|
|
|