| Index: pkg/compiler/lib/src/enqueue.dart | 
| diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart | 
| index b254e0d75b57c89d186b5c1b291c05430546dc88..660e2e866dedf682cf5e6a9e716f54cdcfdb7bc3 100644 | 
| --- a/pkg/compiler/lib/src/enqueue.dart | 
| +++ b/pkg/compiler/lib/src/enqueue.dart | 
| @@ -19,16 +19,12 @@ import 'elements/elements.dart' | 
| AnalyzableElement, | 
| AstElement, | 
| ClassElement, | 
| -        ConstructorElement, | 
| Element, | 
| -        Elements, | 
| Entity, | 
| FunctionElement, | 
| LibraryElement, | 
| -        Member, | 
| -        Name, | 
| -        TypedElement, | 
| -        TypedefElement; | 
| +        LocalFunctionElement, | 
| +        TypedElement; | 
| import 'native/native.dart' as native; | 
| import 'types/types.dart' show TypeMaskStrategy; | 
| import 'universe/selector.dart' show Selector; | 
| @@ -100,15 +96,7 @@ abstract class Enqueuer { | 
|  | 
| void enableIsolateSupport(); | 
|  | 
| -  /// Enqueue the static fields that have been marked as used by reflective | 
| -  /// usage through `MirrorsUsed`. | 
| -  void enqueueReflectiveStaticFields(Iterable<Element> elements); | 
| - | 
| -  /// Enqueue all elements that are matched by the mirrors used | 
| -  /// annotation or, in lack thereof, all elements. | 
| -  void enqueueReflectiveElements(Iterable<ClassElement> recents); | 
| - | 
| -  void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}); | 
| +  void registerInstantiatedType(InterfaceType type); | 
| void forEach(void f(WorkItem work)); | 
|  | 
| /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provided | 
| @@ -122,6 +110,8 @@ abstract class Enqueuer { | 
| bool isProcessed(Element member); | 
|  | 
| Iterable<Entity> get processedEntities; | 
| + | 
| +  Iterable<ClassElement> get processedClasses; | 
| } | 
|  | 
| /// [Enqueuer] which is specific to resolution. | 
| @@ -138,14 +128,8 @@ class ResolutionEnqueuer extends Enqueuer { | 
| final ResolutionWorldBuilderImpl _universe = | 
| new ResolutionWorldBuilderImpl(const TypeMaskStrategy()); | 
|  | 
| -  static final TRACE_MIRROR_ENQUEUING = | 
| -      const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING"); | 
| - | 
| bool queueIsClosed = false; | 
|  | 
| -  bool hasEnqueuedReflectiveElements = false; | 
| -  bool hasEnqueuedReflectiveStaticFields = false; | 
| - | 
| WorldImpactVisitor impactVisitor; | 
|  | 
| ResolutionEnqueuer(Compiler compiler, this.strategy) | 
| @@ -186,12 +170,19 @@ class ResolutionEnqueuer extends Enqueuer { | 
| } | 
| } | 
|  | 
| +  void registerInstantiatedType(InterfaceType type) { | 
| +    _registerInstantiatedType(type, globalDependency: true); | 
| +  } | 
| + | 
| void applyImpact(WorldImpact worldImpact, {Element impactSource}) { | 
| compiler.impactStrategy | 
| .visitImpact(impactSource, worldImpact, impactVisitor, impactUse); | 
| } | 
|  | 
| -  void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) { | 
| +  void _registerInstantiatedType(InterfaceType type, | 
| +      {bool mirrorUsage: false, | 
| +      bool nativeUsage: false, | 
| +      bool globalDependency: false}) { | 
| task.measure(() { | 
| ClassElement cls = type.element; | 
| cls.ensureResolved(resolution); | 
| @@ -199,9 +190,15 @@ class ResolutionEnqueuer extends Enqueuer { | 
| _universe.registerTypeInstantiation(type, | 
| isNative: isNative, | 
| byMirrors: mirrorUsage, onImplemented: (ClassElement cls) { | 
| -        compiler.backend | 
| -            .registerImplementedClass(cls, this, compiler.globalDependencies); | 
| +        compiler.backend.registerImplementedClass(cls, this); | 
| }); | 
| +      if (globalDependency && !mirrorUsage) { | 
| +        compiler.globalDependencies.registerDependency(type.element); | 
| +      } | 
| +      if (nativeUsage) { | 
| +        nativeEnqueuer.onInstantiatedType(type); | 
| +      } | 
| +      compiler.backend.registerInstantiatedType(type); | 
| // TODO(johnniwinther): Share this reasoning with [Universe]. | 
| if (!cls.isAbstract || isNative || mirrorUsage) { | 
| processInstantiatedClass(cls); | 
| @@ -325,8 +322,7 @@ class ResolutionEnqueuer extends Enqueuer { | 
| // We only tell the backend once that [superclass] was instantiated, so | 
| // any additional dependencies must be treated as global | 
| // dependencies. | 
| -        compiler.backend.registerInstantiatedClass( | 
| -            superclass, this, compiler.globalDependencies); | 
| +        compiler.backend.registerInstantiatedClass(superclass, this); | 
| } | 
|  | 
| ClassElement superclass = cls; | 
| @@ -345,172 +341,6 @@ class ResolutionEnqueuer extends Enqueuer { | 
| }); | 
| } | 
|  | 
| -  void logEnqueueReflectiveAction(action, [msg = ""]) { | 
| -    if (TRACE_MIRROR_ENQUEUING) { | 
| -      print("MIRROR_ENQUEUE (R): $action $msg"); | 
| -    } | 
| -  } | 
| - | 
| -  /// Enqeue the constructor [ctor] if it is required for reflection. | 
| -  /// | 
| -  /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 
| -  /// needed for reflection. | 
| -  void enqueueReflectiveConstructor( | 
| -      ConstructorElement ctor, bool enclosingWasIncluded) { | 
| -    if (shouldIncludeElementDueToMirrors(ctor, | 
| -        includedEnclosing: enclosingWasIncluded)) { | 
| -      logEnqueueReflectiveAction(ctor); | 
| -      ClassElement cls = ctor.declaration.enclosingClass; | 
| -      compiler.backend.registerInstantiatedType( | 
| -          cls.rawType, this, compiler.mirrorDependencies, | 
| -          mirrorUsage: true); | 
| -      registerStaticUse(new StaticUse.foreignUse(ctor.declaration)); | 
| -    } | 
| -  } | 
| - | 
| -  /// Enqeue the member [element] if it is required for reflection. | 
| -  /// | 
| -  /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 
| -  /// needed for reflection. | 
| -  void enqueueReflectiveMember(Element element, bool enclosingWasIncluded) { | 
| -    if (shouldIncludeElementDueToMirrors(element, | 
| -        includedEnclosing: enclosingWasIncluded)) { | 
| -      logEnqueueReflectiveAction(element); | 
| -      if (element.isTypedef) { | 
| -        TypedefElement typedef = element; | 
| -        typedef.ensureResolved(resolution); | 
| -      } else if (Elements.isStaticOrTopLevel(element)) { | 
| -        registerStaticUse(new StaticUse.foreignUse(element.declaration)); | 
| -      } else if (element.isInstanceMember) { | 
| -        // We need to enqueue all members matching this one in subclasses, as | 
| -        // well. | 
| -        // TODO(herhut): Use TypedSelector.subtype for enqueueing | 
| -        DynamicUse dynamicUse = | 
| -            new DynamicUse(new Selector.fromElement(element), null); | 
| -        registerDynamicUse(dynamicUse); | 
| -        if (element.isField) { | 
| -          DynamicUse dynamicUse = new DynamicUse( | 
| -              new Selector.setter( | 
| -                  new Name(element.name, element.library, isSetter: true)), | 
| -              null); | 
| -          registerDynamicUse(dynamicUse); | 
| -        } | 
| -      } | 
| -    } | 
| -  } | 
| - | 
| -  /// Enqeue the member [element] if it is required for reflection. | 
| -  /// | 
| -  /// [enclosingWasIncluded] provides a hint whether the enclosing element was | 
| -  /// needed for reflection. | 
| -  void enqueueReflectiveElementsInClass(ClassElement cls, | 
| -      Iterable<ClassElement> recents, bool enclosingWasIncluded) { | 
| -    if (cls.library.isInternalLibrary || cls.isInjected) return; | 
| -    bool includeClass = shouldIncludeElementDueToMirrors(cls, | 
| -        includedEnclosing: enclosingWasIncluded); | 
| -    if (includeClass) { | 
| -      logEnqueueReflectiveAction(cls, "register"); | 
| -      ClassElement decl = cls.declaration; | 
| -      decl.ensureResolved(resolution); | 
| -      compiler.backend.registerInstantiatedType( | 
| -          decl.rawType, this, compiler.mirrorDependencies, | 
| -          mirrorUsage: true); | 
| -    } | 
| -    // If the class is never instantiated, we know nothing of it can possibly | 
| -    // be reflected upon. | 
| -    // TODO(herhut): Add a warning if a mirrors annotation cannot hit. | 
| -    if (recents.contains(cls.declaration)) { | 
| -      logEnqueueReflectiveAction(cls, "members"); | 
| -      cls.constructors.forEach((Element element) { | 
| -        enqueueReflectiveConstructor(element, includeClass); | 
| -      }); | 
| -      cls.forEachClassMember((Member member) { | 
| -        enqueueReflectiveMember(member.element, includeClass); | 
| -      }); | 
| -    } | 
| -  } | 
| - | 
| -  /// Enqeue special classes that might not be visible by normal means or that | 
| -  /// would not normally be enqueued: | 
| -  /// | 
| -  /// [Closure] is treated specially as it is the superclass of all closures. | 
| -  /// Although it is in an internal library, we mark it as reflectable. Note | 
| -  /// that none of its methods are reflectable, unless reflectable by | 
| -  /// inheritance. | 
| -  void enqueueReflectiveSpecialClasses() { | 
| -    Iterable<ClassElement> classes = | 
| -        compiler.backend.classesRequiredForReflection; | 
| -    for (ClassElement cls in classes) { | 
| -      if (compiler.backend.referencedFromMirrorSystem(cls)) { | 
| -        logEnqueueReflectiveAction(cls); | 
| -        cls.ensureResolved(resolution); | 
| -        compiler.backend.registerInstantiatedType( | 
| -            cls.rawType, this, compiler.mirrorDependencies, | 
| -            mirrorUsage: true); | 
| -      } | 
| -    } | 
| -  } | 
| - | 
| -  /// Enqeue all local members of the library [lib] if they are required for | 
| -  /// reflection. | 
| -  void enqueueReflectiveElementsInLibrary( | 
| -      LibraryElement lib, Iterable<ClassElement> recents) { | 
| -    bool includeLibrary = | 
| -        shouldIncludeElementDueToMirrors(lib, includedEnclosing: false); | 
| -    lib.forEachLocalMember((Element member) { | 
| -      if (member.isInjected) return; | 
| -      if (member.isClass) { | 
| -        enqueueReflectiveElementsInClass(member, recents, includeLibrary); | 
| -      } else { | 
| -        enqueueReflectiveMember(member, includeLibrary); | 
| -      } | 
| -    }); | 
| -  } | 
| - | 
| -  /// Enqueue all elements that are matched by the mirrors used | 
| -  /// annotation or, in lack thereof, all elements. | 
| -  void enqueueReflectiveElements(Iterable<ClassElement> recents) { | 
| -    if (!hasEnqueuedReflectiveElements) { | 
| -      logEnqueueReflectiveAction("!START enqueueAll"); | 
| -      // First round of enqueuing, visit everything that is visible to | 
| -      // also pick up static top levels, etc. | 
| -      // Also, during the first round, consider all classes that have been seen | 
| -      // as recently seen, as we do not know how many rounds of resolution might | 
| -      // have run before tree shaking is disabled and thus everything is | 
| -      // enqueued. | 
| -      recents = _processedClasses.toSet(); | 
| -      reporter.log('Enqueuing everything'); | 
| -      for (LibraryElement lib in compiler.libraryLoader.libraries) { | 
| -        enqueueReflectiveElementsInLibrary(lib, recents); | 
| -      } | 
| -      enqueueReflectiveSpecialClasses(); | 
| -      hasEnqueuedReflectiveElements = true; | 
| -      hasEnqueuedReflectiveStaticFields = true; | 
| -      logEnqueueReflectiveAction("!DONE enqueueAll"); | 
| -    } else if (recents.isNotEmpty) { | 
| -      // Keep looking at new classes until fixpoint is reached. | 
| -      logEnqueueReflectiveAction("!START enqueueRecents"); | 
| -      recents.forEach((ClassElement cls) { | 
| -        enqueueReflectiveElementsInClass( | 
| -            cls, | 
| -            recents, | 
| -            shouldIncludeElementDueToMirrors(cls.library, | 
| -                includedEnclosing: false)); | 
| -      }); | 
| -      logEnqueueReflectiveAction("!DONE enqueueRecents"); | 
| -    } | 
| -  } | 
| - | 
| -  /// Enqueue the static fields that have been marked as used by reflective | 
| -  /// usage through `MirrorsUsed`. | 
| -  void enqueueReflectiveStaticFields(Iterable<Element> elements) { | 
| -    if (hasEnqueuedReflectiveStaticFields) return; | 
| -    hasEnqueuedReflectiveStaticFields = true; | 
| -    for (Element element in elements) { | 
| -      enqueueReflectiveMember(element, true); | 
| -    } | 
| -  } | 
| - | 
| void processSet( | 
| Map<String, Set<Element>> map, String memberName, bool f(Element e)) { | 
| Set<Element> members = map[memberName]; | 
| @@ -576,7 +406,7 @@ class ResolutionEnqueuer extends Enqueuer { | 
| assert(invariant(element, element.isDeclaration, | 
| message: "Element ${element} is not the declaration.")); | 
| _universe.registerStaticUse(staticUse); | 
| -    compiler.backend.registerStaticUse(element, forResolution: true); | 
| +    compiler.backend.registerStaticUse(this, element); | 
| bool addElement = true; | 
| switch (staticUse.kind) { | 
| case StaticUseKind.STATIC_TEAR_OFF: | 
| @@ -589,6 +419,10 @@ class ResolutionEnqueuer extends Enqueuer { | 
| // [FIELD_SET] contains [BoxFieldElement]s which we cannot enqueue. | 
| // Also [CLOSURE] contains [LocalFunctionElement] which we cannot | 
| // enqueue. | 
| +        LocalFunctionElement closure = staticUse.element; | 
| +        if (closure.type.containsTypeVariables) { | 
| +          universe.closuresWithFreeTypeVariables.add(closure); | 
| +        } | 
| addElement = false; | 
| break; | 
| case StaticUseKind.SUPER_FIELD_SET: | 
| @@ -613,7 +447,15 @@ class ResolutionEnqueuer extends Enqueuer { | 
| DartType type = typeUse.type; | 
| switch (typeUse.kind) { | 
| case TypeUseKind.INSTANTIATION: | 
| -        registerInstantiatedType(type); | 
| +        _registerInstantiatedType(type, globalDependency: false); | 
| +        break; | 
| +      case TypeUseKind.MIRROR_INSTANTIATION: | 
| +        _registerInstantiatedType(type, | 
| +            mirrorUsage: true, globalDependency: false); | 
| +        break; | 
| +      case TypeUseKind.NATIVE_INSTANTIATION: | 
| +        _registerInstantiatedType(type, | 
| +            nativeUsage: true, globalDependency: true); | 
| break; | 
| case TypeUseKind.IS_CHECK: | 
| case TypeUseKind.AS_CAST: | 
| @@ -639,16 +481,14 @@ class ResolutionEnqueuer extends Enqueuer { | 
| } | 
|  | 
| void registerCallMethodWithFreeTypeVariables(Element element) { | 
| -    compiler.backend.registerCallMethodWithFreeTypeVariables( | 
| -        element, this, compiler.globalDependencies); | 
| +    compiler.backend.registerCallMethodWithFreeTypeVariables(element, this); | 
| _universe.callMethodsWithFreeTypeVariables.add(element); | 
| } | 
|  | 
| void registerClosurizedMember(TypedElement element) { | 
| assert(element.isInstanceMember); | 
| if (element.computeType(resolution).containsTypeVariables) { | 
| -      compiler.backend.registerClosureWithFreeTypeVariables( | 
| -          element, this, compiler.globalDependencies); | 
| +      compiler.backend.registerClosureWithFreeTypeVariables(element, this); | 
| _universe.closuresWithFreeTypeVariables.add(element); | 
| } | 
| compiler.backend.registerBoundClosure(this); | 
| @@ -706,20 +546,6 @@ class ResolutionEnqueuer extends Enqueuer { | 
| } | 
|  | 
| /** | 
| -   * Decides whether an element should be included to satisfy requirements | 
| -   * of the mirror system. | 
| -   * | 
| -   * During resolution, we have to resort to matching elements against the | 
| -   * [MirrorsUsed] pattern, as we do not have a complete picture of the world, | 
| -   * yet. | 
| -   */ | 
| -  bool shouldIncludeElementDueToMirrors(Element element, | 
| -      {bool includedEnclosing}) { | 
| -    return includedEnclosing || | 
| -        compiler.backend.requiredByMirrorSystem(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. | 
| @@ -765,7 +591,7 @@ class ResolutionEnqueuer extends Enqueuer { | 
| // runtime type. | 
| compiler.enabledRuntimeType = true; | 
| // TODO(ahe): Record precise dependency here. | 
| -      compiler.backend.registerRuntimeType(this, compiler.globalDependencies); | 
| +      compiler.backend.registerRuntimeType(this); | 
| } else if (compiler.commonElements.isFunctionApplyMethod(element)) { | 
| compiler.enabledFunctionApply = true; | 
| } | 
|  |