| 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 |