mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:49:47 +00:00
Decorate build mode with using PerformanceLog.
So, that we can redirect it into a file and see performance during large internal builds with using workers. R=brianwilkerson@google.com, paulberry@google.com BUG= Review-Url: https://codereview.chromium.org/2996773002 .
This commit is contained in:
parent
5597188067
commit
0567e8cbd8
|
@ -134,11 +134,13 @@ class BuildMode {
|
|||
|
||||
SummaryDataStore summaryDataStore;
|
||||
AnalysisOptions analysisOptions;
|
||||
AnalysisDriver analysisDriver;
|
||||
Map<Uri, File> uriToFileMap;
|
||||
final List<Source> explicitSources = <Source>[];
|
||||
final List<PackageBundle> unlinkedBundles = <PackageBundle>[];
|
||||
|
||||
PerformanceLog logger = new PerformanceLog(null);
|
||||
AnalysisDriver analysisDriver;
|
||||
|
||||
PackageBundleAssembler assembler;
|
||||
final Set<Source> processedSources = new Set<Source>();
|
||||
final Map<String, UnlinkedUnit> uriToUnit = <String, UnlinkedUnit>{};
|
||||
|
@ -153,91 +155,101 @@ class BuildMode {
|
|||
* Perform package analysis according to the given [options].
|
||||
*/
|
||||
Future<ErrorSeverity> analyze() async {
|
||||
// Write initial progress message.
|
||||
if (!options.machineFormat) {
|
||||
outSink.writeln("Analyzing ${options.sourceFiles.join(', ')}...");
|
||||
}
|
||||
return await logger.runAsync('Analyze', () async {
|
||||
// Write initial progress message.
|
||||
if (!options.machineFormat) {
|
||||
outSink.writeln("Analyzing ${options.sourceFiles.join(', ')}...");
|
||||
}
|
||||
|
||||
// Create the URI to file map.
|
||||
uriToFileMap = _createUriToFileMap(options.sourceFiles);
|
||||
if (uriToFileMap == null) {
|
||||
io.exitCode = ErrorSeverity.ERROR.ordinal;
|
||||
return ErrorSeverity.ERROR;
|
||||
}
|
||||
|
||||
// BuildMode expects sourceFiles in the format "<uri>|<filepath>",
|
||||
// but the rest of the code base does not understand this format.
|
||||
// Rewrite sourceFiles, stripping the "<uri>|" prefix, so that it
|
||||
// does not cause problems with code that does not expect this format.
|
||||
options.rewriteSourceFiles(options.sourceFiles
|
||||
.map((String uriPipePath) =>
|
||||
uriPipePath.substring(uriPipePath.indexOf('|') + 1))
|
||||
.toList());
|
||||
|
||||
// Prepare the analysis driver.
|
||||
try {
|
||||
_createAnalysisDriver();
|
||||
} on ConflictingSummaryException catch (e) {
|
||||
errorSink.writeln('$e');
|
||||
io.exitCode = ErrorSeverity.ERROR.ordinal;
|
||||
return ErrorSeverity.ERROR;
|
||||
}
|
||||
|
||||
// Add sources.
|
||||
for (Uri uri in uriToFileMap.keys) {
|
||||
File file = uriToFileMap[uri];
|
||||
if (!file.exists) {
|
||||
errorSink.writeln('File not found: ${file.path}');
|
||||
// Create the URI to file map.
|
||||
uriToFileMap = _createUriToFileMap(options.sourceFiles);
|
||||
if (uriToFileMap == null) {
|
||||
io.exitCode = ErrorSeverity.ERROR.ordinal;
|
||||
return ErrorSeverity.ERROR;
|
||||
}
|
||||
Source source = new FileSource(file, uri);
|
||||
explicitSources.add(source);
|
||||
}
|
||||
|
||||
// Write summary.
|
||||
assembler = new PackageBundleAssembler();
|
||||
if (_shouldOutputSummary) {
|
||||
// Prepare all unlinked units.
|
||||
for (var src in explicitSources) {
|
||||
await _prepareUnlinkedUnit('${src.uri}');
|
||||
// BuildMode expects sourceFiles in the format "<uri>|<filepath>",
|
||||
// but the rest of the code base does not understand this format.
|
||||
// Rewrite sourceFiles, stripping the "<uri>|" prefix, so that it
|
||||
// does not cause problems with code that does not expect this format.
|
||||
options.rewriteSourceFiles(options.sourceFiles
|
||||
.map((String uriPipePath) =>
|
||||
uriPipePath.substring(uriPipePath.indexOf('|') + 1))
|
||||
.toList());
|
||||
|
||||
// Prepare the analysis driver.
|
||||
try {
|
||||
logger.run('Prepare analysis driver', () {
|
||||
_createAnalysisDriver();
|
||||
});
|
||||
} on ConflictingSummaryException catch (e) {
|
||||
errorSink.writeln('$e');
|
||||
io.exitCode = ErrorSeverity.ERROR.ordinal;
|
||||
return ErrorSeverity.ERROR;
|
||||
}
|
||||
|
||||
// Build and assemble linked libraries.
|
||||
if (!options.buildSummaryOnlyUnlinked) {
|
||||
// Prepare URIs of unlinked units that should be linked.
|
||||
var unlinkedUris = new Set<String>();
|
||||
for (var bundle in unlinkedBundles) {
|
||||
unlinkedUris.addAll(bundle.unlinkedUnitUris);
|
||||
// Add sources.
|
||||
for (Uri uri in uriToFileMap.keys) {
|
||||
File file = uriToFileMap[uri];
|
||||
if (!file.exists) {
|
||||
errorSink.writeln('File not found: ${file.path}');
|
||||
io.exitCode = ErrorSeverity.ERROR.ordinal;
|
||||
return ErrorSeverity.ERROR;
|
||||
}
|
||||
for (var src in explicitSources) {
|
||||
unlinkedUris.add('${src.uri}');
|
||||
}
|
||||
// Perform linking.
|
||||
_computeLinkedLibraries(unlinkedUris);
|
||||
assembler.recordDependencies(summaryDataStore);
|
||||
Source source = new FileSource(file, uri);
|
||||
explicitSources.add(source);
|
||||
}
|
||||
|
||||
// Write the whole package bundle.
|
||||
PackageBundleBuilder bundle = assembler.assemble();
|
||||
if (options.buildSummaryOutput != null) {
|
||||
io.File file = new io.File(options.buildSummaryOutput);
|
||||
file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY);
|
||||
}
|
||||
if (options.buildSummaryOutputSemantic != null) {
|
||||
bundle.flushInformative();
|
||||
io.File file = new io.File(options.buildSummaryOutputSemantic);
|
||||
file.writeAsBytesSync(bundle.toBuffer(), mode: io.FileMode.WRITE_ONLY);
|
||||
}
|
||||
}
|
||||
// Write summary.
|
||||
assembler = new PackageBundleAssembler();
|
||||
if (_shouldOutputSummary) {
|
||||
await logger.runAsync('Build and write output summary', () async {
|
||||
// Prepare all unlinked units.
|
||||
await logger.runAsync('Prepare unlinked units', () async {
|
||||
for (var src in explicitSources) {
|
||||
await _prepareUnlinkedUnit('${src.uri}');
|
||||
}
|
||||
});
|
||||
|
||||
if (options.buildSummaryOnly) {
|
||||
return ErrorSeverity.NONE;
|
||||
} else {
|
||||
// Process errors.
|
||||
await _printErrors(outputPath: options.buildAnalysisOutput);
|
||||
return await _computeMaxSeverity();
|
||||
}
|
||||
// Build and assemble linked libraries.
|
||||
if (!options.buildSummaryOnlyUnlinked) {
|
||||
// Prepare URIs of unlinked units that should be linked.
|
||||
var unlinkedUris = new Set<String>();
|
||||
for (var bundle in unlinkedBundles) {
|
||||
unlinkedUris.addAll(bundle.unlinkedUnitUris);
|
||||
}
|
||||
for (var src in explicitSources) {
|
||||
unlinkedUris.add('${src.uri}');
|
||||
}
|
||||
// Perform linking.
|
||||
_computeLinkedLibraries(unlinkedUris);
|
||||
assembler.recordDependencies(summaryDataStore);
|
||||
}
|
||||
|
||||
// Write the whole package bundle.
|
||||
PackageBundleBuilder bundle = assembler.assemble();
|
||||
if (options.buildSummaryOutput != null) {
|
||||
io.File file = new io.File(options.buildSummaryOutput);
|
||||
file.writeAsBytesSync(bundle.toBuffer(),
|
||||
mode: io.FileMode.WRITE_ONLY);
|
||||
}
|
||||
if (options.buildSummaryOutputSemantic != null) {
|
||||
bundle.flushInformative();
|
||||
io.File file = new io.File(options.buildSummaryOutputSemantic);
|
||||
file.writeAsBytesSync(bundle.toBuffer(),
|
||||
mode: io.FileMode.WRITE_ONLY);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (options.buildSummaryOnly) {
|
||||
return ErrorSeverity.NONE;
|
||||
} else {
|
||||
// Process errors.
|
||||
await _printErrors(outputPath: options.buildAnalysisOutput);
|
||||
return await _computeMaxSeverity();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,19 +258,21 @@ class BuildMode {
|
|||
* add them to the [assembler].
|
||||
*/
|
||||
void _computeLinkedLibraries(Set<String> libraryUris) {
|
||||
LinkedLibrary getDependency(String absoluteUri) =>
|
||||
summaryDataStore.linkedMap[absoluteUri];
|
||||
logger.run('Link output summary', () {
|
||||
LinkedLibrary getDependency(String absoluteUri) =>
|
||||
summaryDataStore.linkedMap[absoluteUri];
|
||||
|
||||
UnlinkedUnit getUnit(String absoluteUri) =>
|
||||
summaryDataStore.unlinkedMap[absoluteUri] ?? uriToUnit[absoluteUri];
|
||||
UnlinkedUnit getUnit(String absoluteUri) =>
|
||||
summaryDataStore.unlinkedMap[absoluteUri] ?? uriToUnit[absoluteUri];
|
||||
|
||||
Map<String, LinkedLibraryBuilder> linkResult = link(
|
||||
libraryUris,
|
||||
getDependency,
|
||||
getUnit,
|
||||
analysisDriver.declaredVariables.get,
|
||||
options.strongMode);
|
||||
linkResult.forEach(assembler.addLinkedLibrary);
|
||||
Map<String, LinkedLibraryBuilder> linkResult = link(
|
||||
libraryUris,
|
||||
getDependency,
|
||||
getUnit,
|
||||
analysisDriver.declaredVariables.get,
|
||||
options.strongMode);
|
||||
linkResult.forEach(assembler.addLinkedLibrary);
|
||||
});
|
||||
}
|
||||
|
||||
Future<ErrorSeverity> _computeMaxSeverity() async {
|
||||
|
@ -291,48 +305,56 @@ class BuildMode {
|
|||
return bundle;
|
||||
}
|
||||
|
||||
for (var path in options.buildSummaryInputs) {
|
||||
var bundle = addBundle(path);
|
||||
if (bundle.linkedLibraryUris.isEmpty &&
|
||||
bundle.unlinkedUnitUris.isNotEmpty) {
|
||||
throw new ArgumentError(
|
||||
'Got an unlinked summary for --build-summary-input at `$path`. '
|
||||
'Unlinked summaries should be provided with the '
|
||||
'--build-summary-unlinked-input argument.');
|
||||
int numInputs = options.buildSummaryInputs.length +
|
||||
options.buildSummaryUnlinkedInputs.length;
|
||||
logger.run('Add $numInputs input summaries', () {
|
||||
for (var path in options.buildSummaryInputs) {
|
||||
var bundle = addBundle(path);
|
||||
if (bundle.linkedLibraryUris.isEmpty &&
|
||||
bundle.unlinkedUnitUris.isNotEmpty) {
|
||||
throw new ArgumentError(
|
||||
'Got an unlinked summary for --build-summary-input at `$path`. '
|
||||
'Unlinked summaries should be provided with the '
|
||||
'--build-summary-unlinked-input argument.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (var path in options.buildSummaryUnlinkedInputs) {
|
||||
var bundle = addBundle(path);
|
||||
unlinkedBundles.add(bundle);
|
||||
if (bundle.linkedLibraryUris.isNotEmpty) {
|
||||
throw new ArgumentError(
|
||||
'Got a linked summary for --build-summary-input-unlinked at `$path`'
|
||||
'. Linked bundles should be provided with the '
|
||||
'--build-summary-input argument.');
|
||||
for (var path in options.buildSummaryUnlinkedInputs) {
|
||||
var bundle = addBundle(path);
|
||||
unlinkedBundles.add(bundle);
|
||||
if (bundle.linkedLibraryUris.isNotEmpty) {
|
||||
throw new ArgumentError(
|
||||
'Got a linked summary for --build-summary-input-unlinked at `$path`'
|
||||
'. Linked bundles should be provided with the '
|
||||
'--build-summary-input argument.');
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
DartSdk sdk;
|
||||
PackageBundle sdkBundle;
|
||||
if (options.dartSdkSummaryPath != null) {
|
||||
SummaryBasedDartSdk summarySdk = new SummaryBasedDartSdk(
|
||||
options.dartSdkSummaryPath, options.strongMode);
|
||||
sdk = summarySdk;
|
||||
sdkBundle = summarySdk.bundle;
|
||||
} else {
|
||||
FolderBasedDartSdk dartSdk = new FolderBasedDartSdk(resourceProvider,
|
||||
resourceProvider.getFolder(options.dartSdkPath), options.strongMode);
|
||||
dartSdk.analysisOptions =
|
||||
Driver.createAnalysisOptionsForCommandLineOptions(
|
||||
resourceProvider, options);
|
||||
dartSdk.useSummary = !options.buildSummaryOnly;
|
||||
sdk = dartSdk;
|
||||
sdkBundle = dartSdk.getSummarySdkBundle(options.strongMode);
|
||||
}
|
||||
logger.run('Add SDK bundle', () {
|
||||
PackageBundle sdkBundle;
|
||||
if (options.dartSdkSummaryPath != null) {
|
||||
SummaryBasedDartSdk summarySdk = new SummaryBasedDartSdk(
|
||||
options.dartSdkSummaryPath, options.strongMode);
|
||||
sdk = summarySdk;
|
||||
sdkBundle = summarySdk.bundle;
|
||||
} else {
|
||||
FolderBasedDartSdk dartSdk = new FolderBasedDartSdk(
|
||||
resourceProvider,
|
||||
resourceProvider.getFolder(options.dartSdkPath),
|
||||
options.strongMode);
|
||||
dartSdk.analysisOptions =
|
||||
Driver.createAnalysisOptionsForCommandLineOptions(
|
||||
resourceProvider, options);
|
||||
dartSdk.useSummary = !options.buildSummaryOnly;
|
||||
sdk = dartSdk;
|
||||
sdkBundle = dartSdk.getSummarySdkBundle(options.strongMode);
|
||||
}
|
||||
|
||||
// Include SDK bundle to avoid parsing SDK sources.
|
||||
summaryDataStore.addBundle(null, sdkBundle);
|
||||
// Include SDK bundle to avoid parsing SDK sources.
|
||||
summaryDataStore.addBundle(null, sdkBundle);
|
||||
});
|
||||
|
||||
var sourceFactory = new SourceFactory(<UriResolver>[
|
||||
new DartUriResolver(sdk),
|
||||
|
@ -343,7 +365,6 @@ class BuildMode {
|
|||
analysisOptions = Driver.createAnalysisOptionsForCommandLineOptions(
|
||||
resourceProvider, options);
|
||||
|
||||
PerformanceLog logger = new PerformanceLog(null);
|
||||
AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(logger);
|
||||
analysisDriver = new AnalysisDriver(
|
||||
scheduler,
|
||||
|
@ -413,29 +434,32 @@ class BuildMode {
|
|||
* is sent to a new file at that path.
|
||||
*/
|
||||
Future<Null> _printErrors({String outputPath}) async {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
var severityProcessor = (AnalysisError error) =>
|
||||
determineProcessedSeverity(error, options, analysisOptions);
|
||||
ErrorFormatter formatter = options.machineFormat
|
||||
? new MachineErrorFormatter(buffer, options, stats,
|
||||
severityProcessor: severityProcessor)
|
||||
: new HumanErrorFormatter(buffer, options, stats,
|
||||
severityProcessor: severityProcessor);
|
||||
for (Source source in explicitSources) {
|
||||
var result = await analysisDriver.getErrors(source.fullName);
|
||||
var errorInfo = new AnalysisErrorInfoImpl(result.errors, result.lineInfo);
|
||||
formatter.formatErrors([errorInfo]);
|
||||
}
|
||||
formatter.flush();
|
||||
if (!options.machineFormat) {
|
||||
stats.print(buffer);
|
||||
}
|
||||
if (outputPath == null) {
|
||||
StringSink sink = options.machineFormat ? errorSink : outSink;
|
||||
sink.write(buffer);
|
||||
} else {
|
||||
new io.File(outputPath).writeAsStringSync(buffer.toString());
|
||||
}
|
||||
await logger.runAsync('Compute and print analysis errors', () async {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
var severityProcessor = (AnalysisError error) =>
|
||||
determineProcessedSeverity(error, options, analysisOptions);
|
||||
ErrorFormatter formatter = options.machineFormat
|
||||
? new MachineErrorFormatter(buffer, options, stats,
|
||||
severityProcessor: severityProcessor)
|
||||
: new HumanErrorFormatter(buffer, options, stats,
|
||||
severityProcessor: severityProcessor);
|
||||
for (Source source in explicitSources) {
|
||||
var result = await analysisDriver.getErrors(source.fullName);
|
||||
var errorInfo =
|
||||
new AnalysisErrorInfoImpl(result.errors, result.lineInfo);
|
||||
formatter.formatErrors([errorInfo]);
|
||||
}
|
||||
formatter.flush();
|
||||
if (!options.machineFormat) {
|
||||
stats.print(buffer);
|
||||
}
|
||||
if (outputPath == null) {
|
||||
StringSink sink = options.machineFormat ? errorSink : outSink;
|
||||
sink.write(buffer);
|
||||
} else {
|
||||
new io.File(outputPath).writeAsStringSync(buffer.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue