Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library dump_info; | 5 library dump_info; |
| 6 | 6 |
| 7 import 'dart:convert' | 7 import 'dart:convert' |
| 8 show ChunkedConversionSink, JsonEncoder, StringConversionSink; | 8 show ChunkedConversionSink, JsonEncoder, StringConversionSink; |
| 9 | 9 |
| 10 import 'package:dart2js_info/info.dart'; | 10 import 'package:dart2js_info/info.dart'; |
| 11 | 11 |
| 12 import 'closure.dart'; | |
| 12 import 'common/tasks.dart' show CompilerTask; | 13 import 'common/tasks.dart' show CompilerTask; |
| 13 import 'common.dart'; | 14 import 'common.dart'; |
| 14 import 'compiler.dart' show Compiler; | 15 import 'compiler.dart' show Compiler; |
| 15 import 'constants/values.dart' show ConstantValue, InterceptorConstantValue; | 16 import 'constants/values.dart' show ConstantValue, InterceptorConstantValue; |
| 16 import 'deferred_load.dart' show OutputUnit; | 17 import 'deferred_load.dart' show OutputUnit; |
| 17 import 'elements/elements.dart'; | 18 import 'elements/elements.dart'; |
| 18 import 'elements/visitor.dart'; | 19 import 'elements/visitor.dart'; |
| 19 import 'js/js.dart' as jsAst; | 20 import 'js/js.dart' as jsAst; |
| 20 import 'js_backend/js_backend.dart' show JavaScriptBackend; | 21 import 'js_backend/js_backend.dart' show JavaScriptBackend; |
| 21 import 'js_emitter/full_emitter/emitter.dart' as full show Emitter; | 22 import 'js_emitter/full_emitter/emitter.dart' as full show Emitter; |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 isConst: element.isConst); | 137 isConst: element.isConst); |
| 137 _elementToInfo[element] = info; | 138 _elementToInfo[element] = info; |
| 138 if (element.isConst) { | 139 if (element.isConst) { |
| 139 var value = compiler.backend.constantCompilerTask | 140 var value = compiler.backend.constantCompilerTask |
| 140 .getConstantValue(element.constant); | 141 .getConstantValue(element.constant); |
| 141 if (value != null) { | 142 if (value != null) { |
| 142 info.initializer = _constantToInfo[value]; | 143 info.initializer = _constantToInfo[value]; |
| 143 } | 144 } |
| 144 } | 145 } |
| 145 | 146 |
| 146 List<FunctionInfo> nestedClosures = <FunctionInfo>[]; | 147 List<ClosureInfo> nestedClosures = <ClosureInfo>[]; |
|
Siggi Cherem (dart-lang)
2016/10/06 17:58:09
the code here and in line 313 seem almost the same
Harry Terkelsen
2016/10/06 18:22:43
Done.
| |
| 147 for (Element closure in element.nestedClosures) { | 148 for (FunctionElement function in element.nestedClosures) { |
| 148 Info child = this.process(closure); | 149 assert(function is SynthesizedCallMethodElementX); |
| 149 if (child != null) { | 150 SynthesizedCallMethodElementX callMethod = function; |
| 150 ClassInfo parent = this.process(closure.enclosingElement); | 151 ClosureInfo closure = this.process(callMethod.enclosingClass); |
| 151 if (parent != null) { | 152 if (closure != null) { |
| 152 child.name = "${parent.name}.${child.name}"; | 153 closure.parent = info; |
| 153 } | 154 nestedClosures.add(closure); |
| 154 nestedClosures.add(child); | 155 size += closure.size; |
| 155 size += child.size; | |
| 156 } | 156 } |
| 157 } | 157 } |
| 158 info.closures = nestedClosures; | 158 info.closures = nestedClosures; |
| 159 result.fields.add(info); | 159 result.fields.add(info); |
| 160 return info; | 160 return info; |
| 161 } | 161 } |
| 162 | 162 |
| 163 ClassInfo visitClassElement(ClassElement element, _) { | 163 ClassInfo visitClassElement(ClassElement element, _) { |
| 164 ClassInfo classInfo = new ClassInfo( | 164 ClassInfo classInfo = new ClassInfo( |
| 165 name: element.name, | 165 name: element.name, |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 177 } else { | 177 } else { |
| 178 assert(info is FunctionInfo); | 178 assert(info is FunctionInfo); |
| 179 classInfo.functions.add(info); | 179 classInfo.functions.add(info); |
| 180 info.parent = classInfo; | 180 info.parent = classInfo; |
| 181 } | 181 } |
| 182 | 182 |
| 183 // Closures are placed in the library namespace, but we want to attribute | 183 // Closures are placed in the library namespace, but we want to attribute |
| 184 // them to a function, and by extension, this class. Process and add the | 184 // them to a function, and by extension, this class. Process and add the |
| 185 // sizes here. | 185 // sizes here. |
| 186 if (member is MemberElement) { | 186 if (member is MemberElement) { |
| 187 for (Element closure in member.nestedClosures) { | 187 for (Element function in member.nestedClosures) { |
|
Siggi Cherem (dart-lang)
2016/10/06 17:58:09
we might be able to use the same function here I t
Harry Terkelsen
2016/10/06 18:22:43
I think we can just iterate over all closures in t
| |
| 188 FunctionInfo closureInfo = this.process(closure); | 188 assert(function is SynthesizedCallMethodElementX); |
| 189 if (closureInfo == null) continue; | 189 SynthesizedCallMethodElementX callMethod = function; |
| 190 | 190 ClosureInfo closure = this.process(callMethod.enclosingClass); |
| 191 // TODO(sigmund): remove this legacy update on the name, represent the | 191 if (closure != null) { |
| 192 // information explicitly in the info format. | 192 size += closure.size; |
| 193 // Look for the parent element of this closure might be the enclosing | |
| 194 // class or an enclosing function. | |
| 195 Element parent = closure.enclosingElement; | |
| 196 ClassInfo parentInfo = this.process(parent); | |
| 197 if (parentInfo != null) { | |
| 198 closureInfo.name = "${parentInfo.name}.${closureInfo.name}"; | |
| 199 } | 193 } |
| 200 size += closureInfo.size; | |
| 201 } | 194 } |
| 202 } | 195 } |
| 203 }); | 196 }); |
| 204 | 197 |
| 205 classInfo.size = size; | 198 classInfo.size = size; |
| 206 | 199 |
| 207 // Omit element if it is not needed. | 200 // Omit element if it is not needed. |
| 208 JavaScriptBackend backend = compiler.backend; | 201 JavaScriptBackend backend = compiler.backend; |
| 209 if (!backend.emitter.neededClasses.contains(element) && | 202 if (!backend.emitter.neededClasses.contains(element) && |
| 210 classInfo.fields.isEmpty && | 203 classInfo.fields.isEmpty && |
| 211 classInfo.functions.isEmpty) { | 204 classInfo.functions.isEmpty) { |
| 212 return null; | 205 return null; |
| 213 } | 206 } |
| 214 result.classes.add(classInfo); | 207 result.classes.add(classInfo); |
| 215 return classInfo; | 208 return classInfo; |
| 216 } | 209 } |
| 217 | 210 |
| 211 ClosureInfo visitClosureClassElement(ClosureClassElement element, _) { | |
| 212 ClosureInfo closureInfo = new ClosureInfo( | |
| 213 name: element.name, | |
| 214 outputUnit: _unitInfoForElement(element), | |
| 215 size: compiler.dumpInfoTask.sizeOf(element)); | |
| 216 _elementToInfo[element] = closureInfo; | |
| 217 | |
| 218 ClosureClassMap closureMap = | |
| 219 compiler.closureToClassMapper.closureMappingCache[element.node]; | |
| 220 assert(closureMap != null && closureMap.closureClassElement == element); | |
| 221 | |
| 222 FunctionInfo functionInfo = this.process(closureMap.callElement); | |
| 223 if (functionInfo == null) return null; | |
|
Siggi Cherem (dart-lang)
2016/10/06 17:58:08
when can this be null?
Harry Terkelsen
2016/10/06 18:22:43
If the closure is not actually output in the code
| |
| 224 closureInfo.function = functionInfo; | |
| 225 functionInfo.parent = closureInfo; | |
| 226 | |
| 227 result.closures.add(closureInfo); | |
| 228 return closureInfo; | |
| 229 } | |
| 230 | |
| 218 FunctionInfo visitFunctionElement(FunctionElement element, _) { | 231 FunctionInfo visitFunctionElement(FunctionElement element, _) { |
| 219 int size = compiler.dumpInfoTask.sizeOf(element); | 232 int size = compiler.dumpInfoTask.sizeOf(element); |
| 220 // TODO(sigmund): consider adding a small info to represent unreachable | 233 // TODO(sigmund): consider adding a small info to represent unreachable |
| 221 // code here. | 234 // code here. |
| 222 if (size == 0 && !shouldKeep(element)) return null; | 235 if (size == 0 && !shouldKeep(element)) return null; |
| 223 | 236 |
| 224 String name = element.name; | 237 String name = element.name; |
| 225 int kind = FunctionInfo.TOP_LEVEL_FUNCTION_KIND; | 238 int kind = FunctionInfo.TOP_LEVEL_FUNCTION_KIND; |
| 226 var enclosingElement = element.enclosingElement; | 239 var enclosingElement = element.enclosingElement; |
| 227 if (enclosingElement.isField || | 240 if (enclosingElement.isField || |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 287 returnType: returnType, | 300 returnType: returnType, |
| 288 inferredReturnType: inferredReturnType, | 301 inferredReturnType: inferredReturnType, |
| 289 parameters: parameters, | 302 parameters: parameters, |
| 290 sideEffects: sideEffects, | 303 sideEffects: sideEffects, |
| 291 inlinedCount: inlinedCount, | 304 inlinedCount: inlinedCount, |
| 292 code: code, | 305 code: code, |
| 293 type: element.type.toString(), | 306 type: element.type.toString(), |
| 294 outputUnit: _unitInfoForElement(element)); | 307 outputUnit: _unitInfoForElement(element)); |
| 295 _elementToInfo[element] = info; | 308 _elementToInfo[element] = info; |
| 296 | 309 |
| 297 List<FunctionInfo> nestedClosures = <FunctionInfo>[]; | 310 List<ClosureInfo> nestedClosures = <ClosureInfo>[]; |
| 298 if (element is MemberElement) { | 311 if (element is MemberElement) { |
| 299 MemberElement member = element as MemberElement; | 312 MemberElement member = element as MemberElement; |
| 300 for (Element closure in member.nestedClosures) { | 313 for (Element function in member.nestedClosures) { |
| 301 Info child = this.process(closure); | 314 assert(function is SynthesizedCallMethodElementX); |
| 302 if (child != null) { | 315 SynthesizedCallMethodElementX callMethod = function; |
| 303 BasicInfo parent = this.process(closure.enclosingElement); | 316 ClosureInfo closure = this.process(callMethod.enclosingClass); |
|
Siggi Cherem (dart-lang)
2016/10/06 17:58:09
is .enclosingClass the same as .enclosingElement (
Harry Terkelsen
2016/10/06 18:22:42
Done.
| |
| 304 if (parent != null) { | 317 if (closure != null) { |
| 305 child.name = "${parent.name}.${child.name}"; | 318 closure.parent = info; |
| 306 } | 319 nestedClosures.add(closure); |
| 307 nestedClosures.add(child); | 320 size += closure.size; |
| 308 child.parent = parent; | |
| 309 size += child.size; | |
| 310 } | 321 } |
| 311 } | 322 } |
| 312 } | 323 } |
| 313 info.closures = nestedClosures; | 324 info.closures = nestedClosures; |
| 325 | |
| 314 result.functions.add(info); | 326 result.functions.add(info); |
| 315 return info; | 327 return info; |
| 316 } | 328 } |
| 317 | 329 |
| 318 OutputUnitInfo _infoFromOutputUnit(OutputUnit outputUnit) { | 330 OutputUnitInfo _infoFromOutputUnit(OutputUnit outputUnit) { |
| 319 return _outputToInfo.putIfAbsent(outputUnit, () { | 331 return _outputToInfo.putIfAbsent(outputUnit, () { |
| 320 // Dump-info currently only works with the full emitter. If another | 332 // Dump-info currently only works with the full emitter. If another |
| 321 // emitter is used it will fail here. | 333 // emitter is used it will fail here. |
| 322 JavaScriptBackend backend = compiler.backend; | 334 JavaScriptBackend backend = compiler.backend; |
| 323 full.Emitter emitter = backend.emitter.emitter; | 335 full.Emitter emitter = backend.emitter.emitter; |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 588 | 600 |
| 589 ChunkedConversionSink<Object> sink = encoder.startChunkedConversion( | 601 ChunkedConversionSink<Object> sink = encoder.startChunkedConversion( |
| 590 new StringConversionSink.fromStringSink(buffer)); | 602 new StringConversionSink.fromStringSink(buffer)); |
| 591 sink.add(new AllInfoJsonCodec().encode(result)); | 603 sink.add(new AllInfoJsonCodec().encode(result)); |
| 592 compiler.reporter.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, { | 604 compiler.reporter.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, { |
| 593 'text': "View the dumped .info.json file at " | 605 'text': "View the dumped .info.json file at " |
| 594 "https://dart-lang.github.io/dump-info-visualizer" | 606 "https://dart-lang.github.io/dump-info-visualizer" |
| 595 }); | 607 }); |
| 596 } | 608 } |
| 597 } | 609 } |
| OLD | NEW |