| Index: pkg/compiler/lib/src/dump_info.dart
|
| diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
|
| index 2a775a16522c4b3022c3ed335f969933b620ea75..82d02c51d6efc9d60ee72f9fb0412d8485f30297 100644
|
| --- a/pkg/compiler/lib/src/dump_info.dart
|
| +++ b/pkg/compiler/lib/src/dump_info.dart
|
| @@ -9,6 +9,7 @@ import 'dart:convert'
|
|
|
| import 'package:dart2js_info/info.dart';
|
|
|
| +import 'closure.dart';
|
| import 'common/tasks.dart' show CompilerTask;
|
| import 'common.dart';
|
| import 'compiler.dart' show Compiler;
|
| @@ -130,7 +131,6 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> {
|
| coverageId: '${element.hashCode}',
|
| type: '${element.type}',
|
| inferredType: '$inferredType',
|
| - size: size,
|
| code: code,
|
| outputUnit: _unitInfoForElement(element),
|
| isConst: element.isConst);
|
| @@ -143,19 +143,9 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> {
|
| }
|
| }
|
|
|
| - List<FunctionInfo> nestedClosures = <FunctionInfo>[];
|
| - for (Element closure in element.nestedClosures) {
|
| - Info child = this.process(closure);
|
| - if (child != null) {
|
| - ClassInfo parent = this.process(closure.enclosingElement);
|
| - if (parent != null) {
|
| - child.name = "${parent.name}.${child.name}";
|
| - }
|
| - nestedClosures.add(child);
|
| - size += child.size;
|
| - }
|
| - }
|
| - info.closures = nestedClosures;
|
| + int closureSize = _addClosureInfo(info, element);
|
| + info.size = size + closureSize;
|
| +
|
| result.fields.add(info);
|
| return info;
|
| }
|
| @@ -174,29 +164,14 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> {
|
| if (info is FieldInfo) {
|
| classInfo.fields.add(info);
|
| info.parent = classInfo;
|
| + for (ClosureInfo closureInfo in info.closures) {
|
| + size += closureInfo.size;
|
| + }
|
| } else {
|
| assert(info is FunctionInfo);
|
| classInfo.functions.add(info);
|
| info.parent = classInfo;
|
| - }
|
| -
|
| - // Closures are placed in the library namespace, but we want to attribute
|
| - // them to a function, and by extension, this class. Process and add the
|
| - // sizes here.
|
| - if (member is MemberElement) {
|
| - for (Element closure in member.nestedClosures) {
|
| - FunctionInfo closureInfo = this.process(closure);
|
| - if (closureInfo == null) continue;
|
| -
|
| - // TODO(sigmund): remove this legacy update on the name, represent the
|
| - // information explicitly in the info format.
|
| - // Look for the parent element of this closure might be the enclosing
|
| - // class or an enclosing function.
|
| - Element parent = closure.enclosingElement;
|
| - ClassInfo parentInfo = this.process(parent);
|
| - if (parentInfo != null) {
|
| - closureInfo.name = "${parentInfo.name}.${closureInfo.name}";
|
| - }
|
| + for (ClosureInfo closureInfo in (info as FunctionInfo).closures) {
|
| size += closureInfo.size;
|
| }
|
| }
|
| @@ -215,6 +190,26 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> {
|
| return classInfo;
|
| }
|
|
|
| + ClosureInfo visitClosureClassElement(ClosureClassElement element, _) {
|
| + ClosureInfo closureInfo = new ClosureInfo(
|
| + name: element.name,
|
| + outputUnit: _unitInfoForElement(element),
|
| + size: compiler.dumpInfoTask.sizeOf(element));
|
| + _elementToInfo[element] = closureInfo;
|
| +
|
| + ClosureClassMap closureMap =
|
| + compiler.closureToClassMapper.closureMappingCache[element.node];
|
| + assert(closureMap != null && closureMap.closureClassElement == element);
|
| +
|
| + FunctionInfo functionInfo = this.process(closureMap.callElement);
|
| + if (functionInfo == null) return null;
|
| + closureInfo.function = functionInfo;
|
| + functionInfo.parent = closureInfo;
|
| +
|
| + result.closures.add(closureInfo);
|
| + return closureInfo;
|
| + }
|
| +
|
| FunctionInfo visitFunctionElement(FunctionElement element, _) {
|
| int size = compiler.dumpInfoTask.sizeOf(element);
|
| // TODO(sigmund): consider adding a small info to represent unreachable
|
| @@ -294,27 +289,40 @@ class ElementInfoCollector extends BaseElementVisitor<Info, dynamic> {
|
| outputUnit: _unitInfoForElement(element));
|
| _elementToInfo[element] = info;
|
|
|
| - List<FunctionInfo> nestedClosures = <FunctionInfo>[];
|
| if (element is MemberElement) {
|
| - MemberElement member = element as MemberElement;
|
| - for (Element closure in member.nestedClosures) {
|
| - Info child = this.process(closure);
|
| - if (child != null) {
|
| - BasicInfo parent = this.process(closure.enclosingElement);
|
| - if (parent != null) {
|
| - child.name = "${parent.name}.${child.name}";
|
| - }
|
| - nestedClosures.add(child);
|
| - child.parent = parent;
|
| - size += child.size;
|
| - }
|
| - }
|
| + int closureSize = _addClosureInfo(info, element as MemberElement);
|
| + size += closureSize;
|
| + } else {
|
| + info.closures = <ClosureInfo>[];
|
| }
|
| - info.closures = nestedClosures;
|
| +
|
| result.functions.add(info);
|
| return info;
|
| }
|
|
|
| + /// Adds closure information to [info], using all nested closures in [member].
|
| + ///
|
| + /// Returns the total size of the nested closures, to add to the info size.
|
| + int _addClosureInfo(Info info, MemberElement member) {
|
| + assert(info is FunctionInfo || info is FieldInfo);
|
| + int size = 0;
|
| + List<ClosureInfo> nestedClosures = <ClosureInfo>[];
|
| + for (Element function in member.nestedClosures) {
|
| + assert(function is SynthesizedCallMethodElementX);
|
| + SynthesizedCallMethodElementX callMethod = function;
|
| + ClosureInfo closure = this.process(callMethod.closureClass);
|
| + if (closure != null) {
|
| + closure.parent = info;
|
| + nestedClosures.add(closure);
|
| + size += closure.size;
|
| + }
|
| + }
|
| + if (info is FunctionInfo) info.closures = nestedClosures;
|
| + if (info is FieldInfo) info.closures = nestedClosures;
|
| +
|
| + return size;
|
| + }
|
| +
|
| OutputUnitInfo _infoFromOutputUnit(OutputUnit outputUnit) {
|
| return _outputToInfo.putIfAbsent(outputUnit, () {
|
| // Dump-info currently only works with the full emitter. If another
|
|
|