Skip to content

Commit

Permalink
Refactor enqueuers
Browse files Browse the repository at this point in the history
- limit use of globalDepencies
- remove mirrorDependencies
- compute native class through WorldImpact
- decouple reflectable elements analysis from enqueuers
- prepare for creating multiple enqueuers for closed world tests

R=het@google.com

Review URL: https://codereview.chromium.org/2494093002 .
  • Loading branch information
johnniwinther committed Nov 14, 2016
1 parent 7a43c64 commit 99cd985
Show file tree
Hide file tree
Showing 18 changed files with 628 additions and 741 deletions.
29 changes: 12 additions & 17 deletions pkg/compiler/lib/src/common/backend_api.dart
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ abstract class Backend extends Target {

void initializeHelperClasses() {}

void enqueueHelpers(ResolutionEnqueuer world, Registry registry);
void enqueueHelpers(ResolutionEnqueuer world);

/// Creates an [Enqueuer] for code generation specific to this backend.
Enqueuer createCodegenEnqueuer(Compiler compiler);
Expand Down Expand Up @@ -117,7 +117,8 @@ abstract class Backend extends Target {

/// Enable deferred loading. Returns `true` if the backend supports deferred
/// loading.
bool enableDeferredLoadingIfSupported(Spannable node, Registry registry);
bool enableDeferredLoadingIfSupported(
ResolutionEnqueuer enqueuer, Spannable node);

/// Called during codegen when [constant] has been used.
void computeImpactForCompileTimeConstant(ConstantValue constant,
Expand All @@ -126,22 +127,15 @@ abstract class Backend extends Target {
/// Called to notify to the backend that a class is being instantiated.
// TODO(johnniwinther): Remove this. It's only called once for each [cls] and
// only with [Compiler.globalDependencies] as [registry].
void registerInstantiatedClass(
ClassElement cls, Enqueuer enqueuer, Registry registry) {}
void registerInstantiatedClass(ClassElement cls, Enqueuer enqueuer) {}

/// Called to notify to the backend that a class is implemented by an
/// instantiated class.
void registerImplementedClass(
ClassElement cls, Enqueuer enqueuer, Registry registry) {}
void registerImplementedClass(ClassElement cls, Enqueuer enqueuer) {}

/// Called to instruct to the backend register [type] as instantiated on
/// [enqueuer].
void registerInstantiatedType(
InterfaceType type, Enqueuer enqueuer, Registry registry,
{bool mirrorUsage: false}) {
registry.registerDependency(type.element);
enqueuer.registerInstantiatedType(type, mirrorUsage: mirrorUsage);
}
void registerInstantiatedType(InterfaceType type) {}

/// Register a runtime type variable bound tests between [typeArgument] and
/// [bound].
Expand All @@ -153,12 +147,12 @@ abstract class Backend extends Target {
* method.
*/
void registerCallMethodWithFreeTypeVariables(
Element callMethod, Enqueuer enqueuer, Registry registry) {}
Element callMethod, Enqueuer enqueuer) {}

/// Called to instruct the backend to register that a closure exists for a
/// function on an instantiated generic class.
void registerClosureWithFreeTypeVariables(
Element closure, Enqueuer enqueuer, Registry registry) {}
Element closure, Enqueuer enqueuer) {}

/// Call this to register that a member has been closurized.
void registerBoundClosure(Enqueuer enqueuer) {}
Expand All @@ -169,7 +163,7 @@ abstract class Backend extends Target {
/**
* Call this to register that the [:runtimeType:] property has been accessed.
*/
void registerRuntimeType(Enqueuer enqueuer, Registry registry) {}
void registerRuntimeType(Enqueuer enqueuer) {}

/// Call this to register a `noSuchMethod` implementation.
void registerNoSuchMethod(FunctionElement noSuchMethodElement) {}
Expand Down Expand Up @@ -213,7 +207,7 @@ abstract class Backend extends Target {
return false;
}

void registerStaticUse(Element element, {bool forResolution}) {}
void registerStaticUse(Enqueuer enqueuer, Element element) {}

/// This method is called immediately after the [LibraryElement] [library] has
/// been created.
Expand Down Expand Up @@ -368,7 +362,8 @@ abstract class ForeignResolver {
class ImpactTransformer {
/// Transform the [ResolutionImpact] into a [WorldImpact] adding the
/// backend dependencies for features used in [worldImpact].
WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
WorldImpact transformResolutionImpact(
ResolutionEnqueuer enqueuer, ResolutionImpact worldImpact) {
return worldImpact;
}

Expand Down
92 changes: 41 additions & 51 deletions pkg/compiler/lib/src/compiler.dart
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ import 'universe/selector.dart' show Selector;
import 'universe/world_builder.dart'
show ResolutionWorldBuilder, CodegenWorldBuilder;
import 'universe/use.dart' show StaticUse;
import 'universe/world_impact.dart' show ImpactStrategy, WorldImpact;
import 'universe/world_impact.dart'
show ImpactStrategy, WorldImpact, WorldImpactBuilderImpl;
import 'util/util.dart' show Link, Setlet;
import 'world.dart' show ClosedWorld, ClosedWorldRefiner, OpenWorld, WorldImpl;

Expand Down Expand Up @@ -114,16 +115,6 @@ abstract class Compiler implements LibraryLoaderListener {
*/
GlobalDependencyRegistry globalDependencies;

/**
* Dependencies that are only included due to mirrors.
*
* We should get rid of this and ensure that all dependencies are
* associated with a particular element.
*/
// TODO(johnniwinther): This should not be a [ResolutionRegistry].
final Registry mirrorDependencies =
new ResolutionRegistry(null, new TreeElementMapping(null));

/// Options provided from command-line arguments.
final CompilerOptions options;

Expand Down Expand Up @@ -687,7 +678,7 @@ abstract class Compiler implements LibraryLoaderListener {
}
// Elements required by enqueueHelpers are global dependencies
// that are not pulled in by a particular element.
backend.enqueueHelpers(enqueuer.resolution, globalDependencies);
backend.enqueueHelpers(enqueuer.resolution);
resolveLibraryMetadata();
reporter.log('Resolving...');
processQueue(enqueuer.resolution, mainFunction);
Expand Down Expand Up @@ -737,7 +728,6 @@ abstract class Compiler implements LibraryLoaderListener {
reporter.log('Compiling...');
phase = PHASE_COMPILING;
backend.onCodegenStart();
// TODO(johnniwinther): Move these to [CodegenEnqueuer].
if (hasIsolateSupport) {
backend.enableIsolateSupport(enqueuer.codegen);
}
Expand Down Expand Up @@ -817,7 +807,7 @@ abstract class Compiler implements LibraryLoaderListener {
ClassElement cls = element;
cls.ensureResolved(resolution);
cls.forEachLocalMember(enqueuer.resolution.addToWorkList);
backend.registerInstantiatedType(cls.rawType, world, globalDependencies);
world.registerInstantiatedType(cls.rawType);
} else {
world.addToWorkList(element);
}
Expand Down Expand Up @@ -853,43 +843,42 @@ abstract class Compiler implements LibraryLoaderListener {
});
});

void processQueue(Enqueuer world, Element main) =>
selfTask.measureSubtask("Compiler.processQueue", () {
world.nativeEnqueuer.processNativeClasses(libraryLoader.libraries);
if (main != null && !main.isMalformed) {
FunctionElement mainMethod = main;
mainMethod.computeType(resolution);
if (mainMethod.functionSignature.parameterCount != 0) {
// The first argument could be a list of strings.
backend.backendClasses.listImplementation
.ensureResolved(resolution);
backend.registerInstantiatedType(
backend.backendClasses.listImplementation.rawType,
world,
globalDependencies);
backend.backendClasses.stringImplementation
.ensureResolved(resolution);
backend.registerInstantiatedType(
backend.backendClasses.stringImplementation.rawType,
world,
globalDependencies);

backend.registerMainHasArguments(world);
}
world.addToWorkList(main);
void processQueue(Enqueuer enqueuer, Element main) {
selfTask.measureSubtask("Compiler.processQueue", () {
WorldImpactBuilderImpl nativeImpact = new WorldImpactBuilderImpl();
enqueuer.nativeEnqueuer
.processNativeClasses(nativeImpact, libraryLoader.libraries);
enqueuer.applyImpact(nativeImpact);
if (main != null && !main.isMalformed) {
FunctionElement mainMethod = main;
mainMethod.computeType(resolution);
if (mainMethod.functionSignature.parameterCount != 0) {
// The first argument could be a list of strings.
backend.backendClasses.listImplementation.ensureResolved(resolution);
enqueuer.registerInstantiatedType(
backend.backendClasses.listImplementation.rawType);
backend.backendClasses.stringImplementation
.ensureResolved(resolution);
enqueuer.registerInstantiatedType(
backend.backendClasses.stringImplementation.rawType);

backend.registerMainHasArguments(enqueuer);
}
if (options.verbose) {
progress.reset();
}
emptyQueue(world);
world.queueIsClosed = true;
// Notify the impact strategy impacts are no longer needed for this
// enqueuer.
impactStrategy.onImpactUsed(world.impactUse);
backend.onQueueClosed();
assert(
compilationFailed || world.checkNoEnqueuedInvokedInstanceMethods());
});
enqueuer.addToWorkList(main);
}
if (options.verbose) {
progress.reset();
}
emptyQueue(enqueuer);
enqueuer.queueIsClosed = true;
// Notify the impact strategy impacts are no longer needed for this
// enqueuer.
impactStrategy.onImpactUsed(enqueuer.impactUse);
backend.onQueueClosed();
assert(compilationFailed ||
enqueuer.checkNoEnqueuedInvokedInstanceMethods());
});
}

/**
* Perform various checks of the queues. This includes checking that
Expand Down Expand Up @@ -2150,7 +2139,8 @@ class _CompilerResolution implements Resolution {
WorldImpact transformResolutionImpact(
Element element, ResolutionImpact resolutionImpact) {
WorldImpact worldImpact = compiler.backend.impactTransformer
.transformResolutionImpact(resolutionImpact);
.transformResolutionImpact(
compiler.enqueuer.resolution, resolutionImpact);
_worldImpactCache[element] = worldImpact;
return worldImpact;
}
Expand Down
4 changes: 3 additions & 1 deletion pkg/compiler/lib/src/deferred_load.dart
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@ class DeferredLoadTask extends CompilerTask {
}
break;
case TypeUseKind.INSTANTIATION:
case TypeUseKind.MIRROR_INSTANTIATION:
case TypeUseKind.NATIVE_INSTANTIATION:
case TypeUseKind.IS_CHECK:
case TypeUseKind.AS_CAST:
case TypeUseKind.CATCH_TYPE:
Expand Down Expand Up @@ -842,7 +844,7 @@ class DeferredLoadTask extends CompilerTask {
}
if (isProgramSplit) {
isProgramSplit = compiler.backend.enableDeferredLoadingIfSupported(
lastDeferred, compiler.globalDependencies);
compiler.enqueuer.resolution, lastDeferred);
}
}

Expand Down
Loading

0 comments on commit 99cd985

Please sign in to comment.