| Index: pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
|
| diff --git a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
|
| index 2779c7699d64240405fa3f461218ff0a28c8a0f1..1f452399efd856f827b83975d324a686c6718c83 100644
|
| --- a/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
|
| +++ b/pkg/compiler/lib/src/kernel/kernel_backend_strategy.dart
|
| @@ -33,6 +33,7 @@ import '../universe/selector.dart';
|
| import '../universe/world_builder.dart';
|
| import '../universe/world_impact.dart';
|
| import '../world.dart';
|
| +import 'closure.dart';
|
| import 'element_map_impl.dart';
|
| import 'kernel_strategy.dart';
|
|
|
| @@ -42,9 +43,16 @@ import 'kernel_strategy.dart';
|
| class KernelBackendStrategy implements BackendStrategy {
|
| final Compiler _compiler;
|
| Sorter _sorter;
|
| + ClosureConversionTask _closureDataLookup;
|
| + GlobalLocalsMap _globalLocalsMap = new GlobalLocalsMap();
|
|
|
| KernelBackendStrategy(this._compiler);
|
|
|
| + KernelToElementMap get _elementMap {
|
| + KernelFrontEndStrategy frontendStrategy = _compiler.frontendStrategy;
|
| + return frontendStrategy.elementMap;
|
| + }
|
| +
|
| @override
|
| ClosedWorldRefiner createClosedWorldRefiner(KernelClosedWorld closedWorld) {
|
| return closedWorld;
|
| @@ -60,8 +68,9 @@ class KernelBackendStrategy implements BackendStrategy {
|
| }
|
|
|
| @override
|
| - ClosureConversionTask createClosureConversionTask(Compiler compiler) =>
|
| - new KernelClosureConversionTask(compiler.measurer);
|
| + ClosureConversionTask get closureDataLookup =>
|
| + _closureDataLookup ??= new KernelClosureConversionTask(
|
| + _compiler.measurer, _elementMap, _globalLocalsMap);
|
|
|
| @override
|
| WorkItemBuilder createCodegenWorkItemBuilder(ClosedWorld closedWorld) {
|
| @@ -73,9 +82,8 @@ class KernelBackendStrategy implements BackendStrategy {
|
| NativeBasicData nativeBasicData,
|
| ClosedWorld closedWorld,
|
| SelectorConstraintsStrategy selectorConstraintsStrategy) {
|
| - KernelFrontEndStrategy frontendStrategy = _compiler.frontendStrategy;
|
| return new KernelCodegenWorldBuilder(
|
| - frontendStrategy.elementMap,
|
| + _elementMap,
|
| closedWorld.elementEnvironment,
|
| nativeBasicData,
|
| closedWorld,
|
| @@ -85,9 +93,8 @@ class KernelBackendStrategy implements BackendStrategy {
|
| @override
|
| SsaBuilder createSsaBuilder(CompilerTask task, JavaScriptBackend backend,
|
| SourceInformationStrategy sourceInformationStrategy) {
|
| - KernelFrontEndStrategy strategy = backend.compiler.frontendStrategy;
|
| - KernelToElementMap elementMap = strategy.elementMap;
|
| - return new KernelSsaBuilder(task, backend.compiler, elementMap);
|
| + return new KernelSsaBuilder(
|
| + task, backend.compiler, _elementMap, _globalLocalsMap);
|
| }
|
|
|
| @override
|
| @@ -138,11 +145,14 @@ class KernelSsaBuilder implements SsaBuilder {
|
| final CompilerTask task;
|
| final Compiler _compiler;
|
| final KernelToElementMap _elementMap;
|
| + final GlobalLocalsMap _globalLocalsMap;
|
|
|
| - KernelSsaBuilder(this.task, this._compiler, this._elementMap);
|
| + KernelSsaBuilder(
|
| + this.task, this._compiler, this._elementMap, this._globalLocalsMap);
|
|
|
| @override
|
| HGraph build(CodegenWorkItem work, ClosedWorld closedWorld) {
|
| + KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(work.element);
|
| KernelSsaGraphBuilder builder = new KernelSsaGraphBuilder(
|
| work.element,
|
| work.element.enclosingClass,
|
| @@ -150,11 +160,11 @@ class KernelSsaBuilder implements SsaBuilder {
|
| _compiler,
|
| _elementMap,
|
| new KernelToTypeInferenceMapImpl(closedWorld),
|
| - new KernelToLocalsMapImpl(work.element),
|
| + localsMap,
|
| closedWorld,
|
| _compiler.codegenWorldBuilder,
|
| work.registry,
|
| - _compiler.closureDataLookup,
|
| + _compiler.backendStrategy.closureDataLookup,
|
| // TODO(johnniwinther): Support these:
|
| const SourceInformationBuilder(),
|
| null, // Function node used as capture scope id.
|
| @@ -248,6 +258,16 @@ class KernelToTypeInferenceMapImpl implements KernelToTypeInferenceMap {
|
| }
|
| }
|
|
|
| +class GlobalLocalsMap {
|
| + Map<MemberEntity, KernelToLocalsMap> _localsMaps =
|
| + <MemberEntity, KernelToLocalsMap>{};
|
| +
|
| + KernelToLocalsMap getLocalsMap(MemberEntity member) {
|
| + return _localsMaps.putIfAbsent(
|
| + member, () => new KernelToLocalsMapImpl(member));
|
| + }
|
| +}
|
| +
|
| class KernelToLocalsMapImpl implements KernelToLocalsMap {
|
| final List<MemberEntity> _members = <MemberEntity>[];
|
| Map<ir.VariableDeclaration, KLocal> _map = <ir.VariableDeclaration, KLocal>{};
|
| @@ -285,7 +305,7 @@ class KernelToLocalsMapImpl implements KernelToLocalsMap {
|
| @override
|
| LoopClosureRepresentationInfo getClosureRepresentationInfoForLoop(
|
| ClosureDataLookup closureLookup, ir.TreeNode node) {
|
| - return const LoopClosureRepresentationInfo();
|
| + return closureLookup.getClosureRepresentationInfoForLoop(node);
|
| }
|
| }
|
|
|
| @@ -313,57 +333,6 @@ class KLocal implements Local {
|
| }
|
| }
|
|
|
| -/// Closure conversion code using our new Entity model. Closure conversion is
|
| -/// necessary because the semantics of closures are slightly different in Dart
|
| -/// than JavaScript. Closure conversion is separated out into two phases:
|
| -/// generation of a new (temporary) representation to store where variables need
|
| -/// to be hoisted/captured up at another level to re-write the closure, and then
|
| -/// the code generation phase where we generate elements and/or instructions to
|
| -/// represent this new code path.
|
| -///
|
| -/// For a general explanation of how closure conversion works at a high level,
|
| -/// check out:
|
| -/// http://siek.blogspot.com/2012/07/essence-of-closure-conversion.html or
|
| -/// http://matt.might.net/articles/closure-conversion/.
|
| -class KernelClosureConversionTask extends ClosureConversionTask<ir.Node> {
|
| - KernelClosureConversionTask(Measurer measurer) : super(measurer);
|
| -
|
| - /// The combined steps of generating our intermediate representation of
|
| - /// closures that need to be rewritten and generating the element model.
|
| - /// Ultimately these two steps will be split apart with the second step
|
| - /// happening later in compilation just before codegen. These steps are
|
| - /// combined here currently to provide a consistent interface to the rest of
|
| - /// the compiler until we are ready to separate these phases.
|
| - @override
|
| - void convertClosures(Iterable<MemberEntity> processedEntities,
|
| - ClosedWorldRefiner closedWorldRefiner) {
|
| - // TODO(efortuna): implement.
|
| - }
|
| -
|
| - @override
|
| - ClosureAnalysisInfo getClosureAnalysisInfo(ir.Node node) {
|
| - return const ClosureAnalysisInfo();
|
| - }
|
| -
|
| - @override
|
| - LoopClosureRepresentationInfo getClosureRepresentationInfoForLoop(
|
| - ir.Node loopNode) {
|
| - return const LoopClosureRepresentationInfo();
|
| - }
|
| -
|
| - @override
|
| - ClosureRepresentationInfo getClosureRepresentationInfo(Entity entity) {
|
| - if (entity is MemberEntity) {
|
| - ThisLocal thisLocal;
|
| - if (entity.isInstanceMember) {
|
| - thisLocal = new ThisLocal(entity);
|
| - }
|
| - return new ClosureClassMap(null, null, null, thisLocal);
|
| - }
|
| - return const ClosureRepresentationInfo();
|
| - }
|
| -}
|
| -
|
| class KernelSorter implements Sorter {
|
| final KernelToElementMapImpl elementMap;
|
|
|
|
|