| 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 7e8e812b56f261e8b5774aa945b7118de00570d9..2c51c32887fe7bad50f6caea011f728208e65578 100644
|
| --- a/sdk/lib/_internal/compiler/implementation/enqueue.dart
|
| +++ b/sdk/lib/_internal/compiler/implementation/enqueue.dart
|
| @@ -18,6 +18,10 @@ class EnqueueTask extends CompilerTask {
|
| super(compiler) {
|
| codegen.task = this;
|
| resolution.task = this;
|
| +
|
| + codegen.nativeEnqueuer = compiler.backend.nativeCodegenEnqueuer(codegen);
|
| + resolution.nativeEnqueuer =
|
| + compiler.backend.nativeResolutionEnqueuer(resolution);
|
| }
|
| }
|
|
|
| @@ -40,6 +44,7 @@ class Enqueuer {
|
|
|
| bool queueIsClosed = false;
|
| EnqueueTask task;
|
| + native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
|
|
|
| Enqueuer(this.name, this.compiler,
|
| ItemCompilationContext itemCompilationContextCreator())
|
| @@ -116,6 +121,8 @@ class Enqueuer {
|
| && library.uri.toString() == 'dart:isolate') {
|
| compiler.enableIsolateSupport(library);
|
| }
|
| +
|
| + nativeEnqueuer.registerElement(element);
|
| }
|
|
|
| /**
|
| @@ -168,7 +175,11 @@ class Enqueuer {
|
| if (universe.generatedCode.containsKey(member)) return;
|
| if (resolvedElements[member] != null) return;
|
| if (!member.isInstanceMember()) return;
|
| - if (member.isField()) return;
|
| + if (member.isField()) {
|
| + // Native fields need to go into instanceMembersByName as they are virtual
|
| + // instantiation points and escape points.
|
| + if (!member.enclosingElement.isNative()) return;
|
| + }
|
|
|
| String memberName = member.name.slowToString();
|
| Link<Element> members = instanceMembersByName.putIfAbsent(
|
| @@ -200,10 +211,19 @@ class Enqueuer {
|
| if (universe.hasInvocation(member, compiler)) {
|
| return addToWorkList(member);
|
| }
|
| - } else if (identical(member.kind, ElementKind.SETTER)) {
|
| + } else if (member.kind == ElementKind.SETTER) {
|
| if (universe.hasInvokedSetter(member, compiler)) {
|
| return addToWorkList(member);
|
| }
|
| + } else if (member.kind == ElementKind.FIELD &&
|
| + member.enclosingElement.isNative()) {
|
| + if (universe.hasInvokedGetter(member, compiler) ||
|
| + universe.hasInvocation(member, compiler)) {
|
| + nativeEnqueuer.registerFieldLoad(member);
|
| + }
|
| + if (universe.hasInvokedSetter(member, compiler)) {
|
| + nativeEnqueuer.registerFieldStore(member);
|
| + }
|
| }
|
| }
|
|
|
| @@ -293,7 +313,25 @@ class Enqueuer {
|
| void handleUnseenSelector(SourceString methodName, Selector selector) {
|
| processInstanceMembers(methodName, (Element member) {
|
| if (selector.applies(member, compiler)) {
|
| - addToWorkList(member);
|
| + if (member.isField() && member.enclosingElement.isNative()) {
|
| + if (selector.isGetter() || selector.isCall()) {
|
| + nativeEnqueuer.registerFieldLoad(member);
|
| + // We have to also handle storing to the field because we only get
|
| + // one look at each member and there might be a store we have not
|
| + // seen yet.
|
| + // TODO(sra): Process fields for storing separately.
|
| + nativeEnqueuer.registerFieldStore(member);
|
| + } else {
|
| + nativeEnqueuer.registerFieldStore(member);
|
| + // We have to also handle loading from the field because we only get
|
| + // one look at each member and there might be a load we have not
|
| + // seen yet.
|
| + // TODO(sra): Process fields for storing separately.
|
| + nativeEnqueuer.registerFieldLoad(member);
|
| + }
|
| + } else {
|
| + addToWorkList(member);
|
| + }
|
| return true;
|
| }
|
| return false;
|
| @@ -367,6 +405,13 @@ class Enqueuer {
|
|
|
| String toString() => 'Enqueuer($name)';
|
|
|
| + void logSummary(log(message)) {
|
| + log(isResolutionQueue
|
| + ? 'Resolved ${resolvedElements.length} elements.'
|
| + : 'Compiled ${universe.generatedCode.length} methods.');
|
| + nativeEnqueuer.logSummary(log);
|
| + }
|
| +
|
| registerUsedSelector(Selector selector) {
|
| Element interceptor = compiler.backend.getInterceptor(selector);
|
| if (interceptor != null) {
|
|
|