dart-sdk/benchmarks/IsolateSpawnMemory/dart/IsolateSpawnMemory.dart
Alexander Aprelev 208f3709b9 [vm/benchmark] Add IsolateSpawnMemory.Dart2JSDeltaRss benchmarks.
These new benchmarks better measure rss delta associated with spawning new dart2js isolate.

Also this moves IsolateSpawn heap measurement benchmarks into this group as well because
they are effectively new benchmarks.

Change-Id: Idf31f83b24713932d5ddfa096e23f36ae8195cd2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/123685
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
2019-11-04 23:53:05 +00:00

130 lines
4.4 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 '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;
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.groupRefId, this.sendPort);
final String wsUri;
final String groupRefId;
final SendPort sendPort;
}
class SpawnMemory {
SpawnMemory(this.name, this.wsUri, this.groupRefId);
Future<void> report() async {
const numberOfRuns = 5;
int sumDeltaRssOnStart = 0;
int sumDeltaRssOnEnd = 0;
int sumDeltaHeapOnStart = 0;
int sumDeltaHeapOnEnd = 0;
for (int i = 0; i < numberOfRuns; i++) {
final receivePort = ReceivePort();
final beforeRss = ProcessInfo.currentRss;
final beforeHeap = await currentHeapUsage(wsUri, groupRefId);
final startMessage =
StartMessage(wsUri, groupRefId, receivePort.sendPort);
await Isolate.spawn(isolateCompiler, startMessage);
final Result result = await receivePort.first;
sumDeltaRssOnStart += result.rssOnStart - beforeRss;
sumDeltaRssOnEnd += result.rssOnEnd - beforeRss;
sumDeltaHeapOnStart += result.heapOnStart - beforeHeap;
sumDeltaHeapOnEnd += result.heapOnEnd - beforeHeap;
}
print(
"${name}RssOnStart(MemoryUse): ${sumDeltaRssOnStart ~/ numberOfRuns}");
print("${name}RssOnEnd(MemoryUse): ${sumDeltaRssOnEnd ~/ numberOfRuns}");
print(
"${name}HeapOnStart(MemoryUse): ${sumDeltaHeapOnStart ~/ numberOfRuns}");
print("${name}HeapOnEnd(MemoryUse): ${sumDeltaHeapOnEnd ~/ numberOfRuns}");
}
final String name;
final String wsUri;
final String groupRefId;
RawReceivePort receivePort;
}
Future<void> isolateCompiler(StartMessage startMessage) async {
final rssOnStart = ProcessInfo.currentRss;
final heapOnStart =
await currentHeapUsage(startMessage.wsUri, startMessage.groupRefId);
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) {}));
startMessage.sendPort.send(Result(
rssOnStart,
ProcessInfo.currentRss,
heapOnStart,
await currentHeapUsage(startMessage.wsUri, startMessage.groupRefId)));
ReceivePort(); // prevent isolate from exiting to ensure Rss monotonically grows
}
Future<int> currentHeapUsage(String wsUri, String groupRefId) async {
final vm_service.VmService vmService =
await vm_service_io.vmServiceConnectUri(wsUri);
final vm_service.MemoryUsage usage =
await vmService.getIsolateGroupMemoryUsage(groupRefId);
vmService.dispose();
return usage.heapUsage + usage.externalUsage;
}
Future<void> main() async {
final ServiceProtocolInfo info = await Service.controlWebServer(enable: true);
final Uri observatoryUri = info.serverUri;
final String wsUri =
'ws://${observatoryUri.authority}${observatoryUri.path}ws';
final vm_service.VmService vmService =
await vm_service_io.vmServiceConnectUri(wsUri);
final String mainGroupRefId = await getMainGroupRefId(vmService);
vmService.dispose();
await SpawnMemory("IsolateSpawnMemory.Dart2JSDelta", wsUri, mainGroupRefId)
.report();
}
Future<String> getMainGroupRefId(vm_service.VmService vmService) async {
final vm = await vmService.getVM();
for (vm_service.IsolateGroupRef groupRef in vm.isolateGroups) {
final vm_service.IsolateGroup group =
await vmService.getIsolateGroup(groupRef.id);
for (vm_service.IsolateRef isolateRef in group.isolates) {
final isolateOrSentinel = await vmService.getIsolate(isolateRef.id);
if (isolateOrSentinel is vm_service.Isolate) {
final vm_service.Isolate isolate = isolateOrSentinel;
if (isolate.name == 'main') {
return groupRef.id;
}
}
}
}
throw "Could not find main isolate";
}