mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 12:14:36 +00:00
96d40d1caa
This is a preparation CL to remove the --enable-isolate-groups flag in the VM. The following tests were only running in --no-enable-isolate-groups and are therefore obsolete now: - runtime/tests/vm/dart/regress_47468_test.dart - runtime/tests/vm/dart_2/regress_47468_test.dart - tests/lib/isolate/illegal_msg_function_test.dart - tests/lib_2/isolate/illegal_msg_function_test.dart TEST=Changes tests only. Change-Id: I6257cb667eebca66a649614d3010139dd2cdd3ab Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/219100 Reviewed-by: Alexander Aprelev <aam@google.com> Commit-Queue: Martin Kustermann <kustermann@google.com>
178 lines
5.6 KiB
Dart
178 lines
5.6 KiB
Dart
// Copyright (c) 2019, 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:async';
|
|
import 'dart:developer';
|
|
import 'dart:io';
|
|
import 'dart:isolate';
|
|
import 'dart:math' as math;
|
|
|
|
import 'package:compiler/src/dart2js.dart' as dart2js_main;
|
|
import 'package:vm_service/vm_service.dart' as vm_service;
|
|
import 'package:vm_service/vm_service_io.dart' as vm_service_io;
|
|
|
|
const String compilerIsolateName = 'isolate-compiler';
|
|
|
|
class Result {
|
|
const Result(
|
|
this.rssOnStart, this.rssOnEnd, this.heapOnStart, this.heapOnEnd);
|
|
|
|
final int rssOnStart;
|
|
final int rssOnEnd;
|
|
final int heapOnStart;
|
|
final int heapOnEnd;
|
|
}
|
|
|
|
class StartMessage {
|
|
const StartMessage(this.wsUri, this.sendPort);
|
|
|
|
final String wsUri;
|
|
final SendPort sendPort;
|
|
}
|
|
|
|
class SpawnMemory {
|
|
SpawnMemory(this.name, this.wsUri);
|
|
|
|
Future<void> report() async {
|
|
int maxProcessRss = 0;
|
|
final timer = Timer.periodic(const Duration(microseconds: 100), (_) {
|
|
maxProcessRss = math.max(maxProcessRss, ProcessInfo.currentRss);
|
|
});
|
|
|
|
const numberOfBenchmarks = 3;
|
|
|
|
final beforeRss = ProcessInfo.currentRss;
|
|
final beforeHeap = await currentHeapUsage(wsUri);
|
|
|
|
final iterators = <StreamIterator>[];
|
|
final continuations = <SendPort>[];
|
|
|
|
// Start all isolates & make them wait.
|
|
for (int i = 0; i < numberOfBenchmarks; i++) {
|
|
final receivePort = ReceivePort();
|
|
final startMessage = StartMessage(wsUri, receivePort.sendPort);
|
|
await Isolate.spawn(isolateCompiler, startMessage,
|
|
debugName: compilerIsolateName);
|
|
final iterator = StreamIterator(receivePort);
|
|
|
|
if (!await iterator.moveNext()) throw 'failed';
|
|
continuations.add(iterator.current as SendPort);
|
|
|
|
iterators.add(iterator);
|
|
}
|
|
|
|
final readyRss = ProcessInfo.currentRss;
|
|
final readyHeap = await currentHeapUsage(wsUri);
|
|
|
|
// Let all isolates do the dart2js compilation.
|
|
for (int i = 0; i < numberOfBenchmarks; i++) {
|
|
final iterator = iterators[i];
|
|
final continuation = continuations[i];
|
|
continuation.send(null);
|
|
if (!await iterator.moveNext()) throw 'failed';
|
|
if (iterator.current != 'done') throw 'failed';
|
|
}
|
|
|
|
final doneRss = ProcessInfo.currentRss;
|
|
final doneHeap = await currentHeapUsage(wsUri);
|
|
|
|
// Shut down helper isolates
|
|
for (int i = 0; i < numberOfBenchmarks; i++) {
|
|
final iterator = iterators[i];
|
|
final continuation = continuations[i];
|
|
continuation.send(null);
|
|
if (!await iterator.moveNext()) throw 'failed';
|
|
if (iterator.current != 'shutdown') throw 'failed';
|
|
await iterator.cancel();
|
|
}
|
|
timer.cancel();
|
|
|
|
final readyDiffRss =
|
|
math.max(0, readyRss - beforeRss) ~/ numberOfBenchmarks;
|
|
final readyDiffHeap =
|
|
math.max(0, readyHeap - beforeHeap) ~/ numberOfBenchmarks;
|
|
final doneDiffRss = math.max(0, doneRss - beforeRss) ~/ numberOfBenchmarks;
|
|
final doneDiffHeap =
|
|
math.max(0, doneHeap - beforeHeap) ~/ numberOfBenchmarks;
|
|
|
|
print('${name}RssOnStart(MemoryUse): $readyDiffRss');
|
|
print('${name}RssOnEnd(MemoryUse): $doneDiffRss');
|
|
print('${name}HeapOnStart(MemoryUse): $readyDiffHeap');
|
|
print('${name}HeapOnEnd(MemoryUse): $doneDiffHeap');
|
|
print('${name}PeakProcessRss(MemoryUse): $maxProcessRss');
|
|
}
|
|
|
|
final String name;
|
|
final String wsUri;
|
|
}
|
|
|
|
Future<void> isolateCompiler(StartMessage startMessage) async {
|
|
final port = ReceivePort();
|
|
final iterator = StreamIterator(port);
|
|
|
|
// Let main isolate know we're ready.
|
|
startMessage.sendPort.send(port.sendPort);
|
|
await iterator.moveNext();
|
|
|
|
await runZoned(
|
|
() => dart2js_main.internalMain(<String>[
|
|
'benchmarks/IsolateSpawnMemory/dart/helloworld.dart',
|
|
'--libraries-spec=sdk/lib/libraries.json'
|
|
]),
|
|
zoneSpecification: ZoneSpecification(
|
|
print: (Zone self, ZoneDelegate parent, Zone zone, String line) {}));
|
|
|
|
// Let main isolate know we're done.
|
|
startMessage.sendPort.send('done');
|
|
await iterator.moveNext();
|
|
|
|
// Closes the port.
|
|
startMessage.sendPort.send('shutdown');
|
|
await iterator.cancel();
|
|
}
|
|
|
|
Future<int> currentHeapUsage(String wsUri) async {
|
|
final vmService = await vm_service_io.vmServiceConnectUri(wsUri);
|
|
final groupIds = await getGroupIds(vmService);
|
|
int sum = 0;
|
|
for (final groupId in groupIds) {
|
|
final usage = await vmService.getIsolateGroupMemoryUsage(groupId);
|
|
sum += usage.heapUsage + usage.externalUsage;
|
|
}
|
|
vmService.dispose();
|
|
return sum;
|
|
}
|
|
|
|
Future<void> main() async {
|
|
// Only if we successfully reach the end will we set 0 exit code.
|
|
exitCode = 255;
|
|
|
|
final info = await Service.controlWebServer(enable: true);
|
|
final observatoryUri = info.serverUri!;
|
|
final wsUri = 'ws://${observatoryUri.authority}${observatoryUri.path}ws';
|
|
await SpawnMemory('IsolateSpawnMemory.Dart2JSDelta', wsUri).report();
|
|
|
|
// Only if we successfully reach the end will we set 0 exit code.
|
|
exitCode = 0;
|
|
}
|
|
|
|
// Returns the set of isolate groups for which we should count the heap usage.
|
|
Future<List<String>> getGroupIds(vm_service.VmService vmService) async {
|
|
final groupIds = <String>{};
|
|
final vm = await vmService.getVM();
|
|
for (final groupRef in vm.isolateGroups) {
|
|
final group = await vmService.getIsolateGroup(groupRef.id);
|
|
for (final isolateRef in group.isolates) {
|
|
final isolateOrSentinel = await vmService.getIsolate(isolateRef.id);
|
|
if (isolateOrSentinel is vm_service.Isolate) {
|
|
groupIds.add(groupRef.id);
|
|
}
|
|
}
|
|
}
|
|
if (groupIds.isEmpty) {
|
|
throw 'Could not find main isolate';
|
|
}
|
|
return groupIds.toList();
|
|
}
|