Index: pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart |
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart |
index d27eca3e384c64cd6d65620cdfc3a70fcd3d2bf7..3d7920c736dc2bd66902dab1b2dbaadbd093f656 100644 |
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart |
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart |
@@ -4,6 +4,9 @@ |
library dart2js.js_emitter.program_builder; |
+import 'dart:io'; |
+import 'dart:convert' show JSON; |
+ |
import '../../closure.dart' show ClosureTask, ClosureFieldElement; |
import '../../common.dart'; |
import '../../common/names.dart' show Names, Selectors; |
@@ -67,10 +70,14 @@ import '../js_emitter.dart' |
import '../model.dart'; |
import '../sorter.dart'; |
+part 'allocated_classes_profile.dart'; |
part 'collector.dart'; |
part 'field_visitor.dart'; |
part 'registry.dart'; |
+const allocatedClassesPath = |
+ const String.fromEnvironment("dart2js.allocatedClasses"); |
sra1
2017/05/02 20:40:12
Can you make this a command-line option?
floitsch
2017/05/06 19:25:43
done.
|
+ |
/// Builds a self-contained representation of the program that can then be |
/// emitted more easily by the individual emitters. |
class ProgramBuilder { |
@@ -266,7 +273,8 @@ class ProgramBuilder { |
_buildTypeToInterceptorMap(), _task.metadataCollector, finalizers, |
needsNativeSupport: needsNativeSupport, |
outputContainsConstantList: collector.outputContainsConstantList, |
- hasIsolateSupport: _backendUsage.isIsolateInUse); |
+ hasIsolateSupport: _backendUsage.isIsolateInUse, |
+ hasSoftDeferredClasses: _notSoftDeferred != null); |
} |
void _markEagerClasses() { |
@@ -584,6 +592,49 @@ class ProgramBuilder { |
library, uri, statics, classes, staticFieldsForReflection); |
} |
+ Set<ClassElement> _notSoftDeferred; |
+ |
+ bool _isSoftDeferred(ClassElement element) { |
+ if (_notSoftDeferred == null && |
+ (allocatedClassesPath != null || allocatedClassesJson != null)) { |
sra1
2017/05/02 20:40:13
Does this execute once?
Perhaps make it more clear
floitsch
2017/05/06 19:25:43
done.
|
+ var blackList = [ |
+ 'dart:_interceptors', |
+ 'dart:html', |
+ 'dart:typed_data_implementation', |
+ 'dart:_native_typed_data' |
+ ].toSet(); |
+ String data = allocatedClassesPath != null |
+ ? new File(allocatedClassesPath).readAsStringSync() |
+ : allocatedClassesJson; |
+ Set<String> allocatedClassesKeys = JSON.decode(data).keys.toSet(); |
+ Set<ClassElement> allocatedClasses = new Set<ClassElement>(); |
+ |
+ void collect(ClassElement element) { |
+ allocatedClasses.add(element); |
+ if (element.isMixinApplication) { |
+ collect(computeMixinClass(element)); |
+ } |
+ if (element.superclass != null) { |
+ collect(element.superclass); |
+ } |
+ } |
+ |
+ collector.outputClassLists.forEach((_, List<ClassElement> elements) { |
+ for (ClassElement element in elements) { |
+ var key = "${element.library.canonicalUri}:${element.name}"; |
+ if (allocatedClassesKeys.contains(key) || |
+ _nativeData.isJsInteropClass(element) || |
+ blackList.contains(element.library.canonicalUri.toString())) { |
+ collect(element); |
+ } |
+ } |
+ }); |
+ _notSoftDeferred = allocatedClasses; |
+ } |
+ if (_notSoftDeferred == null) return false; |
+ return !_notSoftDeferred.contains(element); |
+ } |
+ |
Class _buildClass(ClassElement element) { |
bool onlyForRti = collector.classesOnlyNeededForRti.contains(element); |
bool hasRtiField = _rtiNeed.classNeedsRtiField(element); |
@@ -752,7 +803,8 @@ class ProgramBuilder { |
hasRtiField: hasRtiField, |
onlyForRti: onlyForRti, |
isNative: _nativeData.isNativeClass(element), |
- isClosureBaseClass: isClosureBaseClass); |
+ isClosureBaseClass: isClosureBaseClass, |
+ isSoftDeferred: _isSoftDeferred(element)); |
} |
_classes[element] = result; |
return result; |