3dce89fbe0
Not having to do the read-allocate-copy dance for files to add a 0-byte at the end results in these changes when using the CFE to compile (a fixed version of) the CFE: ``` msec task-clock:u: -1.7356% +/- 0.2164% (-73.16 +/- 9.12) page-faults:u: -2.6957% +/- 0.0111% (-2914.83 +/- 12.00) cycles:u: -1.7128% +/- 0.2223% (-297927979.70 +/- 38660477.01) instructions:u: -1.6814% +/- 0.0002% (-361315766.86 +/- 36853.71) branch-misses:u: -3.3289% +/- 0.9669% (-2153126.00 +/- 625370.97) seconds time elapsed: -1.7372% +/- 0.2154% (-0.07 +/- 0.01) seconds user: -1.5998% +/- 0.2740% (-0.06 +/- 0.01) seconds sys: -4.1451% +/- 2.9801% (-0.01 +/- 0.01) Scavenge( new space) goes from 62 to 61 ``` TEST=Existing test coverage. Change-Id: I8e182bcee39839f6ed1e658c30c85c40ecf0b259 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/385722 Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Morgan :) <davidmorgan@google.com> Reviewed-by: Daco Harkes <dacoharkes@google.com> Reviewed-by: Srujan Gaddam <srujzs@google.com> Commit-Queue: Jens Johansen <jensj@google.com> Reviewed-by: Mayank Patke <fishythefish@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
175 lines
6.0 KiB
Dart
175 lines
6.0 KiB
Dart
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
|
|
// for details. All rights reserved. Use of this source code is governed by a
|
|
// BSD-style license that can be found in the LICENSE file.
|
|
|
|
import 'dart:io';
|
|
import 'dart:typed_data';
|
|
import 'package:compiler/compiler_api.dart' as api;
|
|
import 'package:compiler/src/commandline_options.dart';
|
|
import 'package:compiler/src/util/memory_compiler.dart';
|
|
import 'package:expect/expect.dart';
|
|
|
|
const int numShards = 4;
|
|
const List<String> dataDirs = ['data', '../inference/data'];
|
|
const Set<String> needsLibs = {'deferred.dart'};
|
|
|
|
const jsOutFilename = 'out.js';
|
|
const sourceMapFilename = '${jsOutFilename}.map';
|
|
const dumpInfoFilename = 'out.info.json';
|
|
|
|
typedef CompiledOutput = Map<api.OutputType, Map<String, String>>;
|
|
|
|
Future<CompiledOutput> compileWithSerialization(
|
|
{Uri? entryPoint,
|
|
required Map<String, dynamic> memorySourceFiles,
|
|
required List<String> options}) async {
|
|
final cfeDillUri = 'memory:cfe.dill';
|
|
final closedWorldUri = 'memory:world.data';
|
|
final globalDataUri = 'memory:global.data';
|
|
final codegenUri = 'memory:codegen';
|
|
final jsOutUri = 'memory:$jsOutFilename';
|
|
Future<CompiledOutput> compile(List<String> options) async {
|
|
final outputProvider = OutputCollector();
|
|
CompilationResult result = await runCompiler(
|
|
entryPoint: entryPoint,
|
|
memorySourceFiles: memorySourceFiles,
|
|
outputProvider: outputProvider,
|
|
options: options);
|
|
Expect.isTrue(result.isSuccess);
|
|
outputProvider.binaryOutputMap.forEach((fileName, binarySink) {
|
|
memorySourceFiles[fileName.path] = Uint8List.fromList(binarySink.list);
|
|
});
|
|
return outputProvider.clear();
|
|
}
|
|
|
|
final commonFlags = [
|
|
'${Flags.closedWorldUri}=$closedWorldUri',
|
|
'${Flags.globalInferenceUri}=$globalDataUri',
|
|
'${Flags.codegenUri}=$codegenUri',
|
|
'${Flags.codegenShards}=2',
|
|
];
|
|
|
|
await compile(
|
|
[...options, '--out=$cfeDillUri', '${Flags.stage}=cfe'] + commonFlags);
|
|
await compile([
|
|
...options,
|
|
'${Flags.inputDill}=$cfeDillUri',
|
|
'${Flags.stage}=closed-world',
|
|
] +
|
|
commonFlags);
|
|
await compile([
|
|
...options,
|
|
'${Flags.inputDill}=$cfeDillUri',
|
|
'${Flags.stage}=global-inference'
|
|
] +
|
|
commonFlags);
|
|
await compile([
|
|
...options,
|
|
'${Flags.inputDill}=$cfeDillUri',
|
|
'${Flags.stage}=codegen',
|
|
'${Flags.codegenShard}=0',
|
|
] +
|
|
commonFlags);
|
|
await compile([
|
|
...options,
|
|
'${Flags.inputDill}=$cfeDillUri',
|
|
'${Flags.stage}=codegen',
|
|
'${Flags.codegenShard}=1',
|
|
] +
|
|
commonFlags);
|
|
final output = await compile([
|
|
...options,
|
|
'${Flags.inputDill}=$cfeDillUri',
|
|
'--out=$jsOutUri',
|
|
'${Flags.stage}=emit-js',
|
|
] +
|
|
commonFlags);
|
|
return output;
|
|
}
|
|
|
|
Future<CompiledOutput> compileWithoutSerialization(
|
|
{Uri? entryPoint,
|
|
required Map<String, dynamic> memorySourceFiles,
|
|
required List<String> options}) async {
|
|
final jsOutUri = 'memory:$jsOutFilename';
|
|
final outputProvider = OutputCollector();
|
|
|
|
CompilationResult result = await runCompiler(
|
|
entryPoint: entryPoint,
|
|
memorySourceFiles: memorySourceFiles,
|
|
outputProvider: outputProvider,
|
|
options: [...options, '--out=$jsOutUri']);
|
|
Expect.isTrue(result.isSuccess);
|
|
|
|
return outputProvider.clear();
|
|
}
|
|
|
|
// TODO(natebiggs): Check dump info diff when the results are aligned with and
|
|
// without serialization.
|
|
Set<api.OutputType> _outputTypesToIgnore = {api.OutputType.dumpInfo};
|
|
|
|
Future<void> compareResults(CompiledOutput serializationResult,
|
|
CompiledOutput noSerializationResult) async {
|
|
serializationResult.forEach((outputType, outputs) {
|
|
if (_outputTypesToIgnore.contains(outputType)) return;
|
|
Expect.isTrue(noSerializationResult.containsKey(outputType));
|
|
final otherOutputs = noSerializationResult[outputType]!;
|
|
Expect.mapEquals(outputs, otherOutputs);
|
|
});
|
|
}
|
|
|
|
Future runTests(List<String> args, int shard) async {
|
|
assert(shard >= 0 && shard < numShards,
|
|
'Shard must be between 0 and ${numShards - 1} (inclusive)');
|
|
|
|
final libDirectory = Directory.fromUri(Platform.script.resolve('libs'));
|
|
|
|
final testFiles = dataDirs
|
|
.map((e) => Directory.fromUri(Platform.script.resolve('data')))
|
|
.expand((dataDir) => dataDir.listSync());
|
|
int i = 0;
|
|
for (final testFile in testFiles) {
|
|
if (!testFile.uri.pathSegments.last.endsWith('.dart')) continue;
|
|
if (i++ % numShards != shard) continue;
|
|
|
|
String name = testFile.uri.pathSegments.last;
|
|
List<String> testOptions = [Flags.dumpInfo];
|
|
print('----------------------------------------------------------------');
|
|
print('Test file: ${testFile.uri}');
|
|
String mainCode = await File.fromUri(testFile.uri).readAsString();
|
|
final mainUri = _createUri('src/main.dart');
|
|
Map<String, dynamic> memorySourceFiles = {mainUri.path: mainCode};
|
|
|
|
if (needsLibs.contains(name)) {
|
|
print('Supporting libraries:');
|
|
String filePrefix = name.substring(0, name.lastIndexOf('.'));
|
|
await for (final libFile in libDirectory.list()) {
|
|
String libFileName = libFile.uri.pathSegments.last;
|
|
if (libFileName.startsWith(filePrefix)) {
|
|
print(' - libs/$libFileName');
|
|
Uri libFileUri = _createUri('libs/$libFileName');
|
|
String libCode = await File.fromUri(libFile.uri).readAsString();
|
|
memorySourceFiles[libFileUri.path] = libCode;
|
|
}
|
|
}
|
|
}
|
|
|
|
final serializationResult = await compileWithSerialization(
|
|
entryPoint: mainUri,
|
|
memorySourceFiles: memorySourceFiles,
|
|
options: testOptions);
|
|
final noSerializationResult = await compileWithoutSerialization(
|
|
entryPoint: mainUri,
|
|
memorySourceFiles: memorySourceFiles,
|
|
options: testOptions);
|
|
|
|
await compareResults(serializationResult, noSerializationResult);
|
|
}
|
|
}
|
|
|
|
// Pretend this is a dart2js_native test to allow use of 'native' keyword
|
|
// and import of private libraries.
|
|
Uri _createUri(String fileName) {
|
|
return Uri.parse('memory:sdk/tests/web/native/$fileName');
|
|
}
|