OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 part of dart2js_incremental; | |
6 | |
7 /// Do not call this method directly. It will be made private. | |
8 // TODO(ahe): Make this method private. | |
9 Future<CompilerImpl> reuseCompiler( | |
10 {CompilerDiagnostics diagnosticHandler, | |
11 CompilerInput inputProvider, | |
12 CompilerOutput outputProvider, | |
13 List<String> options: const [], | |
14 CompilerImpl cachedCompiler, | |
15 Uri libraryRoot, | |
16 Uri packageRoot, | |
17 Uri packageConfig, | |
18 bool packagesAreImmutable: false, | |
19 Map<String, dynamic> environment, | |
20 Future<bool> reuseLibrary(LibraryElement library)}) { | |
21 UserTag oldTag = new UserTag('_reuseCompiler').makeCurrent(); | |
22 if (libraryRoot == null) { | |
23 throw 'Missing libraryRoot'; | |
24 } | |
25 if (inputProvider == null) { | |
26 throw 'Missing inputProvider'; | |
27 } | |
28 if (diagnosticHandler == null) { | |
29 throw 'Missing diagnosticHandler'; | |
30 } | |
31 if (outputProvider == null) { | |
32 outputProvider = const NullCompilerOutput(); | |
33 } | |
34 if (environment == null) { | |
35 environment = {}; | |
36 } | |
37 CompilerImpl compiler = cachedCompiler; | |
38 JavaScriptBackend backend = compiler?.backend; | |
39 if (compiler == null || | |
40 compiler.libraryRoot != libraryRoot || | |
41 !compiler.options.hasIncrementalSupport || | |
42 compiler.hasCrashed || | |
43 backend.mirrorsAnalysis.resolutionHandler.hasEnqueuedReflectiveElements || | |
44 compiler.deferredLoadTask.isProgramSplit) { | |
45 if (compiler != null && compiler.options.hasIncrementalSupport) { | |
46 print('***FLUSH***'); | |
47 if (compiler.hasCrashed) { | |
48 print('Unable to reuse compiler due to crash.'); | |
49 } else if (backend.mirrorsAnalysis.resolutionHandler | |
50 .hasEnqueuedReflectiveElements) { | |
51 print('Unable to reuse compiler due to dart:mirrors.'); | |
52 } else if (compiler.deferredLoadTask.isProgramSplit) { | |
53 print('Unable to reuse compiler due to deferred loading.'); | |
54 } else { | |
55 print('Unable to reuse compiler.'); | |
56 } | |
57 } | |
58 oldTag.makeCurrent(); | |
59 compiler = new CompilerImpl( | |
60 inputProvider, | |
61 outputProvider, | |
62 diagnosticHandler, | |
63 new CompilerOptions.parse( | |
64 libraryRoot: libraryRoot, | |
65 packageRoot: packageRoot, | |
66 packageConfig: packageConfig, | |
67 options: options, | |
68 environment: environment)); | |
69 backend = compiler.backend; | |
70 | |
71 Uri core = Uri.parse("dart:core"); | |
72 | |
73 return compiler.setupSdk().then((_) { | |
74 return compiler.libraryLoader.loadLibrary(core).then((_) { | |
75 // Likewise, always be prepared for runtimeType support. | |
76 // TODO(johnniwinther): Add global switch to force RTI. | |
77 compiler.resolutionWorldBuilder.hasRuntimeTypeSupport = true; | |
78 compiler.enqueuer.resolution.applyImpact(backend.registerRuntimeType()); | |
79 return compiler; | |
80 }); | |
81 }); | |
82 } else { | |
83 compiler.tasks.forEach((t) => t.clearMeasurements()); | |
84 compiler | |
85 ..userOutputProvider = outputProvider | |
86 ..provider = inputProvider | |
87 ..handler = diagnosticHandler | |
88 ..enqueuer.resolution.queueIsClosed = false | |
89 ..enqueuer.resolution.hasEnqueuedReflectiveElements = false | |
90 ..enqueuer.resolution.hasEnqueuedReflectiveStaticFields = false | |
91 ..enqueuer.codegen.queueIsClosed = false | |
92 ..enqueuer.codegen.hasEnqueuedReflectiveElements = false | |
93 ..enqueuer.codegen.hasEnqueuedReflectiveStaticFields = false | |
94 ..compilationFailed = false; | |
95 JavaScriptBackend backend = compiler.backend; | |
96 full.Emitter emitter = backend.emitter.emitter; | |
97 | |
98 // TODO(ahe): Seems this cache only serves to tell | |
99 // [emitter.invalidateCaches] if it was invoked on a full compile (in | |
100 // which case nothing should be invalidated), or if it is an incremental | |
101 // compilation (in which case, holders/owners of newly compiled methods | |
102 // must be invalidated). | |
103 emitter.cachedElements.add(null); | |
104 | |
105 compiler.enqueuer.codegen | |
106 ..newlyEnqueuedElements.clear() | |
107 ..newlySeenSelectors.clear(); | |
108 | |
109 emitter.nsmEmitter | |
110 ..trivialNsmHandlers.clear(); | |
111 | |
112 backend.emitter.typeTestRegistry | |
113 ..checkedClasses = null | |
114 ..checkedFunctionTypes = null | |
115 ..rtiNeededClasses.clear() | |
116 ..cachedClassesUsingTypeVariableTests = null; | |
117 | |
118 emitter.interceptorEmitter | |
119 ..interceptorInvocationNames.clear(); | |
120 | |
121 backend.emitter.nativeEmitter | |
122 ..hasNativeClasses = false | |
123 ..nativeMethods.clear(); | |
124 | |
125 backend.emitter.readTypeVariables.clear(); | |
126 | |
127 emitter | |
128 ..outputBuffers.clear() | |
129 ..classesCollector = null | |
130 ..mangledFieldNames.clear() | |
131 ..mangledGlobalFieldNames.clear() | |
132 ..recordedMangledNames.clear() | |
133 ..clearCspPrecompiledNodes() | |
134 ..elementDescriptors.clear(); | |
135 | |
136 backend | |
137 ..preMirrorsMethodCount = 0; | |
138 | |
139 if (reuseLibrary == null) { | |
140 reuseLibrary = (LibraryElement library) { | |
141 return new Future.value( | |
142 library.isPlatformLibrary || | |
143 (packagesAreImmutable && library.isPackageLibrary)); | |
144 }; | |
145 } | |
146 return compiler.libraryLoader.resetAsync(reuseLibrary).then((_) { | |
147 oldTag.makeCurrent(); | |
148 return compiler; | |
149 }); | |
150 } | |
151 } | |
152 | |
153 /// Helper class to collect sources. | |
154 class StringEventSink implements EventSink<String> { | |
155 List<String> data = <String>[]; | |
156 | |
157 final Function onClose; | |
158 | |
159 StringEventSink(this.onClose); | |
160 | |
161 void add(String event) { | |
162 if (data == null) throw 'StringEventSink is closed.'; | |
163 data.add(event); | |
164 } | |
165 | |
166 void addError(errorEvent, [StackTrace stackTrace]) { | |
167 throw 'addError($errorEvent, $stackTrace)'; | |
168 } | |
169 | |
170 void close() { | |
171 if (data != null) { | |
172 onClose(data.join()); | |
173 data = null; | |
174 } | |
175 } | |
176 } | |
177 | |
178 /// Output provider which collect output in [output]. | |
179 class OutputProvider implements CompilerOutput { | |
180 final Map<String, String> output = new Map<String, String>(); | |
181 | |
182 EventSink<String> createEventSink(String name, String extension) { | |
183 return new StringEventSink((String data) { | |
184 output['$name.$extension'] = data; | |
185 }); | |
186 } | |
187 | |
188 String operator[] (String key) => output[key]; | |
189 } | |
OLD | NEW |