diff --git a/pkg/front_end/test/incremental_compiler_leak_test.dart b/pkg/front_end/test/incremental_compiler_leak_test.dart
index 326c2e2..e8927d1 100644
--- a/pkg/front_end/test/incremental_compiler_leak_test.dart
+++ b/pkg/front_end/test/incremental_compiler_leak_test.dart
@@ -1,11 +1,8 @@
 import 'dart:async';
 import 'dart:io';
 
-import "package:vm_service/vm_service.dart" as vmService;
-import "package:vm_service/vm_service_io.dart" as vmService;
-
-import "vm_service_heap_helper.dart" as helper;
 import "simple_stats.dart";
+import "vm_service_helper.dart" as vmService;
 
 const int limit = 10;
 
@@ -22,7 +19,7 @@
   ]);
 }
 
-class LeakFinder extends helper.LaunchingVMServiceHeapHelper {
+class LeakFinder extends vmService.LaunchingVMServiceHelper {
   @override
   Future<void> run() async {
     vmService.VM vm = await serviceClient.getVM();
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index f858baf..e985d0b 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -129,6 +129,8 @@
 corners
 costly
 cov
+coverage
+coverages
 cp
 csi
 ctrl
@@ -282,6 +284,7 @@
 heuristics
 hi
 hints
+hits
 home
 hoo
 hosted
@@ -403,6 +406,7 @@
 mismatched
 misnamed
 miss
+misses
 misspelled
 mistake
 mistakes
@@ -500,6 +504,7 @@
 response
 result1
 result2
+resuming
 retaining
 retainingpath
 retains
diff --git a/pkg/front_end/test/vm_service_coverage.dart b/pkg/front_end/test/vm_service_coverage.dart
new file mode 100644
index 0000000..b144e3d
--- /dev/null
+++ b/pkg/front_end/test/vm_service_coverage.dart
@@ -0,0 +1,142 @@
+import 'dart:async';
+
+import 'vm_service_helper.dart' as vmService;
+
+main(List<String> args) async {
+  CoverageHelper coverageHelper = new CoverageHelper();
+
+  List<String> allArgs = new List<String>();
+  allArgs.addAll([
+    "--disable-dart-dev",
+    "--enable-asserts",
+    "--pause_isolates_on_exit",
+  ]);
+  allArgs.addAll(args);
+
+  coverageHelper.start(allArgs);
+}
+
+class CoverageHelper extends vmService.LaunchingVMServiceHelper {
+  final bool forceCompilation;
+  final bool printHits;
+
+  CoverageHelper({this.forceCompilation: false, this.printHits: true});
+
+  @override
+  Future<void> run() async {
+    vmService.VM vm = await serviceClient.getVM();
+    if (vm.isolates.length != 1) {
+      throw "Expected 1 isolate, got ${vm.isolates.length}";
+    }
+    vmService.IsolateRef isolateRef = vm.isolates.single;
+    await waitUntilIsolateIsRunnable(isolateRef.id);
+    await serviceClient.resume(isolateRef.id);
+    Completer<String> cTimeout = new Completer();
+    Timer timer = new Timer(new Duration(minutes: 20), () {
+      cTimeout.complete("Timeout");
+      killProcess();
+    });
+
+    Completer<String> cRunDone = new Completer();
+    // ignore: unawaited_futures
+    waitUntilPaused(isolateRef.id).then((value) => cRunDone.complete("Done"));
+
+    await Future.any([cRunDone.future, cTimeout.future, cProcessExited.future]);
+
+    timer.cancel();
+
+    if (!await isPausedAtExit(isolateRef.id)) {
+      killProcess();
+      throw "Expected to be paused at exit, but is just paused!";
+    }
+
+    // Get and process coverage information.
+    Stopwatch stopwatch = new Stopwatch()..start();
+    vmService.SourceReport sourceReport = await serviceClient.getSourceReport(
+        isolateRef.id, [vmService.SourceReportKind.kCoverage],
+        forceCompile: forceCompilation);
+    print("Got source report from VM in ${stopwatch.elapsedMilliseconds} ms");
+    stopwatch.reset();
+    Map<Uri, Coverage> coverages = {};
+    for (vmService.SourceReportRange range in sourceReport.ranges) {
+      vmService.ScriptRef script = sourceReport.scripts[range.scriptIndex];
+      Uri scriptUri = Uri.parse(script.uri);
+      if (!includeCoverageFor(scriptUri)) continue;
+      Coverage coverage = coverages[scriptUri] ??= new Coverage();
+
+      vmService.SourceReportCoverage sourceReportCoverage = range.coverage;
+      if (sourceReportCoverage == null) {
+        // Range not compiled. Record the range if provided.
+        assert(!range.compiled);
+        if (range.startPos >= 0 || range.endPos >= 0) {
+          coverage.notCompiled
+              .add(new StartEndPair(range.startPos, range.endPos));
+        }
+        continue;
+      }
+      coverage.hits.addAll(sourceReportCoverage.hits);
+      coverage.misses.addAll(sourceReportCoverage.misses);
+    }
+    print("Processed source report from VM in "
+        "${stopwatch.elapsedMilliseconds} ms");
+    stopwatch.reset();
+
+    // It's paused at exit, so resuming should allow us to exit.
+    await serviceClient.resume(isolateRef.id);
+
+    for (MapEntry<Uri, Coverage> entry in coverages.entries) {
+      assert(entry.value.hits.intersection(entry.value.misses).isEmpty);
+      if (entry.value.hits.isEmpty &&
+          entry.value.misses.isEmpty &&
+          entry.value.notCompiled.isEmpty) {
+        continue;
+      }
+      print(entry.key);
+      if (printHits) {
+        print("Hits: ${entry.value.hits.toList()..sort()}");
+      }
+      print("Misses: ${entry.value.misses.toList()..sort()}");
+      print("Not compiled: ${entry.value.notCompiled.toList()..sort()}");
+      print("");
+    }
+  }
+
+  Completer<String> cProcessExited = new Completer();
+  void processExited(int exitCode) {
+    cProcessExited.complete("Exit");
+  }
+
+  bool includeCoverageFor(Uri uri) {
+    if (uri.scheme == "dart") {
+      return false;
+    }
+    if (uri.scheme == "package") {
+      return uri.pathSegments.first == "front_end" ||
+          uri.pathSegments.first == "_fe_analyzer_shared" ||
+          uri.pathSegments.first == "kernel";
+    }
+    return true;
+  }
+}
+
+class Coverage {
+  final Set<int> hits = {};
+  final Set<int> misses = {};
+  final Set<StartEndPair> notCompiled = {};
+}
+
+class StartEndPair implements Comparable {
+  final int startPos;
+  final int endPos;
+
+  StartEndPair(this.startPos, this.endPos);
+
+  String toString() => "[$startPos - $endPos]";
+
+  @override
+  int compareTo(Object other) {
+    if (other is! StartEndPair) return -1;
+    StartEndPair o = other;
+    return startPos - o.startPos;
+  }
+}
diff --git a/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart b/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
new file mode 100644
index 0000000..4cab31b
--- /dev/null
+++ b/pkg/front_end/test/vm_service_coverage_constant_evaluator.dart
@@ -0,0 +1,27 @@
+import 'vm_service_coverage.dart' as helper;
+
+main(List<String> args) async {
+  CoverageHelper coverageHelper = new CoverageHelper();
+
+  List<String> allArgs = new List<String>();
+  allArgs.addAll([
+    "--disable-dart-dev",
+    "--enable-asserts",
+    "--pause_isolates_on_exit",
+  ]);
+  allArgs.addAll(args);
+
+  coverageHelper.start(allArgs);
+}
+
+class CoverageHelper extends helper.CoverageHelper {
+  CoverageHelper() : super(printHits: false);
+
+  bool includeCoverageFor(Uri uri) {
+    if (uri.scheme != "package") return false;
+    if (uri.path.startsWith("front_end/src/fasta/kernel/constant_")) {
+      return true;
+    }
+    return false;
+  }
+}
diff --git a/pkg/front_end/test/vm_service_heap_finder.dart b/pkg/front_end/test/vm_service_heap_finder.dart
index ea3bcea..2e85184 100644
--- a/pkg/front_end/test/vm_service_heap_finder.dart
+++ b/pkg/front_end/test/vm_service_heap_finder.dart
@@ -3,7 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "dart:io";
-import "vm_service_heap_helper.dart";
+
+import "vm_service_helper.dart" as vmService;
 
 class Foo {
   final String x;
@@ -31,7 +32,7 @@
   foos.add(new Foo("!", 44));
 
   if (connectTo == null) connectTo = ask("Connect to");
-  VMServiceHeapHelperBase vm = VMServiceHeapHelperBase();
+  VMServiceHeapHelperPrinter vm = VMServiceHeapHelperPrinter();
   await vm.connect(Uri.parse(connectTo.trim()));
   String isolateId = await vm.getIsolateId();
   if (classToFind == null) classToFind = ask("Find what class");
@@ -61,3 +62,97 @@
   stdout.write("$question: ");
   return stdin.readLineSync();
 }
+
+class VMServiceHeapHelperPrinter extends vmService.VMServiceHelper {
+  Future<void> printAllocationProfile(String isolateId, {String filter}) async {
+    await waitUntilIsolateIsRunnable(isolateId);
+    vmService.AllocationProfile allocationProfile =
+        await serviceClient.getAllocationProfile(isolateId);
+    for (vmService.ClassHeapStats member in allocationProfile.members) {
+      if (filter != null) {
+        if (member.classRef.name != filter) continue;
+      } else {
+        if (member.classRef.name == "") continue;
+        if (member.instancesCurrent == 0) continue;
+      }
+      vmService.Class c =
+          await serviceClient.getObject(isolateId, member.classRef.id);
+      if (c.location?.script?.uri == null) continue;
+      print("${member.classRef.name}: ${member.instancesCurrent}");
+    }
+  }
+
+  Future<void> filterAndPrintInstances(String isolateId, String filter,
+      String fieldName, Set<String> fieldValues) async {
+    await waitUntilIsolateIsRunnable(isolateId);
+    vmService.AllocationProfile allocationProfile =
+        await serviceClient.getAllocationProfile(isolateId);
+    for (vmService.ClassHeapStats member in allocationProfile.members) {
+      if (member.classRef.name != filter) continue;
+      vmService.Class c =
+          await serviceClient.getObject(isolateId, member.classRef.id);
+      if (c.location?.script?.uri == null) continue;
+      print("${member.classRef.name}: ${member.instancesCurrent}");
+      print(c.location.script.uri);
+
+      vmService.InstanceSet instances = await serviceClient.getInstances(
+          isolateId, member.classRef.id, 10000);
+      int instanceNum = 0;
+      for (vmService.ObjRef instance in instances.instances) {
+        instanceNum++;
+        vmService.Obj receivedObject =
+            await serviceClient.getObject(isolateId, instance.id);
+        if (receivedObject is! vmService.Instance) continue;
+        vmService.Instance object = receivedObject;
+        for (vmService.BoundField field in object.fields) {
+          if (field.decl.name == fieldName) {
+            if (field.value is vmService.Sentinel) continue;
+            vmService.Obj receivedValue =
+                await serviceClient.getObject(isolateId, field.value.id);
+            if (receivedValue is! vmService.Instance) continue;
+            String value = (receivedValue as vmService.Instance).valueAsString;
+            if (!fieldValues.contains(value)) continue;
+            print("${instanceNum}: ${field.decl.name}: "
+                "${value} --- ${instance.id}");
+          }
+        }
+      }
+    }
+    print("Done!");
+  }
+
+  Future<void> printRetainingPaths(String isolateId, String filter) async {
+    await waitUntilIsolateIsRunnable(isolateId);
+    vmService.AllocationProfile allocationProfile =
+        await serviceClient.getAllocationProfile(isolateId);
+    for (vmService.ClassHeapStats member in allocationProfile.members) {
+      if (member.classRef.name != filter) continue;
+      vmService.Class c =
+          await serviceClient.getObject(isolateId, member.classRef.id);
+      print("Found ${c.name} (location: ${c.location})");
+      print("${member.classRef.name}: "
+          "(instancesCurrent: ${member.instancesCurrent})");
+      print("");
+
+      vmService.InstanceSet instances = await serviceClient.getInstances(
+          isolateId, member.classRef.id, 10000);
+      print(" => Got ${instances.instances.length} instances");
+      print("");
+
+      for (vmService.ObjRef instance in instances.instances) {
+        vmService.Obj receivedObject =
+            await serviceClient.getObject(isolateId, instance.id);
+        print("Instance: $receivedObject");
+        vmService.RetainingPath retainingPath =
+            await serviceClient.getRetainingPath(isolateId, instance.id, 1000);
+        print("Retaining path: (length ${retainingPath.length}");
+        for (int i = 0; i < retainingPath.elements.length; i++) {
+          print("  [$i] = ${retainingPath.elements[i]}");
+        }
+
+        print("");
+      }
+    }
+    print("Done!");
+  }
+}
diff --git a/pkg/front_end/test/vm_service_heap_helper.dart b/pkg/front_end/test/vm_service_heap_helper.dart
index d801f3d..497c0b3 100644
--- a/pkg/front_end/test/vm_service_heap_helper.dart
+++ b/pkg/front_end/test/vm_service_heap_helper.dart
@@ -2,288 +2,11 @@
 // 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:convert";
-import "dart:io";
-
-import "package:vm_service/vm_service.dart" as vmService;
-import "package:vm_service/vm_service_io.dart" as vmService;
-
 import "dijkstras_sssp_algorithm.dart";
-
-class VMServiceHeapHelperBase {
-  vmService.VmService _serviceClient;
-  vmService.VmService get serviceClient => _serviceClient;
-
-  VMServiceHeapHelperBase();
-
-  Future connect(Uri observatoryUri) async {
-    String path = observatoryUri.path;
-    if (!path.endsWith("/")) path += "/";
-    String wsUriString = 'ws://${observatoryUri.authority}${path}ws';
-    _serviceClient = await vmService.vmServiceConnectUri(wsUriString,
-        log: const StdOutLog());
-  }
-
-  Future disconnect() async {
-    await _serviceClient.dispose();
-  }
-
-  Future<bool> waitUntilPaused(String isolateId) async {
-    int nulls = 0;
-    while (true) {
-      bool result = await _isPaused(isolateId);
-      if (result == null) {
-        nulls++;
-        if (nulls > 5) {
-          // We've now asked for the isolate 5 times and in all cases gotten
-          // `Sentinel`. Most likely things aren't working for whatever reason.
-          return false;
-        }
-      } else if (result) {
-        return true;
-      } else {
-        await Future.delayed(const Duration(milliseconds: 100));
-      }
-    }
-  }
-
-  Future<bool> _isPaused(String isolateId) async {
-    dynamic tmp = await _serviceClient.getIsolate(isolateId);
-    if (tmp is vmService.Isolate) {
-      vmService.Isolate isolate = tmp;
-      if (isolate.pauseEvent.kind != "Resume") return true;
-      return false;
-    }
-    return null;
-  }
-
-  Future<bool> _isPausedAtStart(String isolateId) async {
-    dynamic tmp = await _serviceClient.getIsolate(isolateId);
-    if (tmp is vmService.Isolate) {
-      vmService.Isolate isolate = tmp;
-      return isolate.pauseEvent.kind == "PauseStart";
-    }
-    return false;
-  }
-
-  Future<vmService.AllocationProfile> forceGC(String isolateId) async {
-    await waitUntilIsolateIsRunnable(isolateId);
-    int expectGcAfter = new DateTime.now().millisecondsSinceEpoch;
-    while (true) {
-      vmService.AllocationProfile allocationProfile;
-      try {
-        allocationProfile =
-            await _serviceClient.getAllocationProfile(isolateId, gc: true);
-      } catch (e) {
-        print(e.runtimeType);
-        rethrow;
-      }
-      if (allocationProfile.dateLastServiceGC != null &&
-          allocationProfile.dateLastServiceGC >= expectGcAfter) {
-        return allocationProfile;
-      }
-    }
-  }
-
-  Future<bool> isIsolateRunnable(String isolateId) async {
-    dynamic tmp = await _serviceClient.getIsolate(isolateId);
-    if (tmp is vmService.Isolate) {
-      vmService.Isolate isolate = tmp;
-      return isolate.runnable;
-    }
-    return null;
-  }
-
-  Future<void> waitUntilIsolateIsRunnable(String isolateId) async {
-    int nulls = 0;
-    while (true) {
-      bool result = await isIsolateRunnable(isolateId);
-      if (result == null) {
-        nulls++;
-        if (nulls > 5) {
-          // We've now asked for the isolate 5 times and in all cases gotten
-          // `Sentinel`. Most likely things aren't working for whatever reason.
-          return;
-        }
-      } else if (result) {
-        return;
-      } else {
-        await Future.delayed(const Duration(milliseconds: 100));
-      }
-    }
-  }
-
-  Future<void> printAllocationProfile(String isolateId, {String filter}) async {
-    await waitUntilIsolateIsRunnable(isolateId);
-    vmService.AllocationProfile allocationProfile =
-        await _serviceClient.getAllocationProfile(isolateId);
-    for (vmService.ClassHeapStats member in allocationProfile.members) {
-      if (filter != null) {
-        if (member.classRef.name != filter) continue;
-      } else {
-        if (member.classRef.name == "") continue;
-        if (member.instancesCurrent == 0) continue;
-      }
-      vmService.Class c =
-          await _serviceClient.getObject(isolateId, member.classRef.id);
-      if (c.location?.script?.uri == null) continue;
-      print("${member.classRef.name}: ${member.instancesCurrent}");
-    }
-  }
-
-  Future<void> filterAndPrintInstances(String isolateId, String filter,
-      String fieldName, Set<String> fieldValues) async {
-    await waitUntilIsolateIsRunnable(isolateId);
-    vmService.AllocationProfile allocationProfile =
-        await _serviceClient.getAllocationProfile(isolateId);
-    for (vmService.ClassHeapStats member in allocationProfile.members) {
-      if (member.classRef.name != filter) continue;
-      vmService.Class c =
-          await _serviceClient.getObject(isolateId, member.classRef.id);
-      if (c.location?.script?.uri == null) continue;
-      print("${member.classRef.name}: ${member.instancesCurrent}");
-      print(c.location.script.uri);
-
-      vmService.InstanceSet instances = await _serviceClient.getInstances(
-          isolateId, member.classRef.id, 10000);
-      int instanceNum = 0;
-      for (vmService.ObjRef instance in instances.instances) {
-        instanceNum++;
-        var receivedObject =
-            await _serviceClient.getObject(isolateId, instance.id);
-        if (receivedObject is! vmService.Instance) continue;
-        vmService.Instance object = receivedObject;
-        for (vmService.BoundField field in object.fields) {
-          if (field.decl.name == fieldName) {
-            if (field.value is vmService.Sentinel) continue;
-            var receivedValue =
-                await _serviceClient.getObject(isolateId, field.value.id);
-            if (receivedValue is! vmService.Instance) continue;
-            String value = (receivedValue as vmService.Instance).valueAsString;
-            if (!fieldValues.contains(value)) continue;
-            print("${instanceNum}: ${field.decl.name}: "
-                "${value} --- ${instance.id}");
-          }
-        }
-      }
-    }
-    print("Done!");
-  }
-
-  Future<void> printRetainingPaths(String isolateId, String filter) async {
-    await waitUntilIsolateIsRunnable(isolateId);
-    vmService.AllocationProfile allocationProfile =
-        await _serviceClient.getAllocationProfile(isolateId);
-    for (vmService.ClassHeapStats member in allocationProfile.members) {
-      if (member.classRef.name != filter) continue;
-      vmService.Class c =
-          await _serviceClient.getObject(isolateId, member.classRef.id);
-      print("Found ${c.name} (location: ${c.location})");
-      print("${member.classRef.name}: "
-          "(instancesCurrent: ${member.instancesCurrent})");
-      print("");
-
-      vmService.InstanceSet instances = await _serviceClient.getInstances(
-          isolateId, member.classRef.id, 10000);
-      print(" => Got ${instances.instances.length} instances");
-      print("");
-
-      for (vmService.ObjRef instance in instances.instances) {
-        var receivedObject =
-            await _serviceClient.getObject(isolateId, instance.id);
-        print("Instance: $receivedObject");
-        vmService.RetainingPath retainingPath =
-            await _serviceClient.getRetainingPath(isolateId, instance.id, 1000);
-        print("Retaining path: (length ${retainingPath.length}");
-        for (int i = 0; i < retainingPath.elements.length; i++) {
-          print("  [$i] = ${retainingPath.elements[i]}");
-        }
-
-        print("");
-      }
-    }
-    print("Done!");
-  }
-
-  Future<String> getIsolateId() async {
-    vmService.VM vm = await _serviceClient.getVM();
-    if (vm.isolates.length != 1) {
-      throw "Expected 1 isolate, got ${vm.isolates.length}";
-    }
-    vmService.IsolateRef isolateRef = vm.isolates.single;
-    return isolateRef.id;
-  }
-}
-
-abstract class LaunchingVMServiceHeapHelper extends VMServiceHeapHelperBase {
-  Process _process;
-  Process get process => _process;
-
-  bool _started = false;
-
-  void start(List<String> scriptAndArgs,
-      {void stdinReceiver(String line),
-      void stderrReceiver(String line)}) async {
-    if (_started) throw "Already started";
-    _started = true;
-    _process = await Process.start(
-        Platform.resolvedExecutable,
-        ["--pause_isolates_on_start", "--enable-vm-service=0"]
-          ..addAll(scriptAndArgs));
-    _process.stdout
-        .transform(utf8.decoder)
-        .transform(new LineSplitter())
-        .listen((line) {
-      const kObservatoryListening = 'Observatory listening on ';
-      if (line.startsWith(kObservatoryListening)) {
-        Uri observatoryUri =
-            Uri.parse(line.substring(kObservatoryListening.length));
-        _setupAndRun(observatoryUri).catchError((e, st) {
-          // Manually kill the process or it will leak,
-          // see http://dartbug.com/42918
-          killProcess();
-          // This seems to rethrow.
-          throw e;
-        });
-      }
-      if (stdinReceiver != null) {
-        stdinReceiver(line);
-      } else {
-        stdout.writeln("> $line");
-      }
-    });
-    _process.stderr
-        .transform(utf8.decoder)
-        .transform(new LineSplitter())
-        .listen((line) {
-      if (stderrReceiver != null) {
-        stderrReceiver(line);
-      } else {
-        stderr.writeln("> $line");
-      }
-    });
-    // ignore: unawaited_futures
-    _process.exitCode.then((value) {
-      processExited(value);
-    });
-  }
-
-  void processExited(int exitCode) {}
-
-  void killProcess() {
-    _process.kill();
-  }
-
-  Future _setupAndRun(Uri observatoryUri) async {
-    await connect(observatoryUri);
-    await run();
-  }
-
-  Future<void> run();
-}
+import "vm_service_helper.dart" as vmService;
 
 class VMServiceHeapHelperSpecificExactLeakFinder
-    extends LaunchingVMServiceHeapHelper {
+    extends vmService.LaunchingVMServiceHelper {
   final Map<Uri, Map<String, List<String>>> _interests =
       new Map<Uri, Map<String, List<String>>>();
   final Map<Uri, Map<String, List<String>>> _prettyPrints =
@@ -326,7 +49,7 @@
   }
 
   void pause() async {
-    await _serviceClient.pause(_isolateRef.id);
+    await serviceClient.pause(_isolateRef.id);
   }
 
   vmService.VM _vm;
@@ -336,7 +59,7 @@
 
   /// Best effort check if the isolate is idle.
   Future<bool> isIdle() async {
-    dynamic tmp = await _serviceClient.getIsolate(_isolateRef.id);
+    dynamic tmp = await serviceClient.getIsolate(_isolateRef.id);
     if (tmp is vmService.Isolate) {
       vmService.Isolate isolate = tmp;
       return isolate.pauseEvent.topFrame == null;
@@ -346,15 +69,15 @@
 
   @override
   Future<void> run() async {
-    _vm = await _serviceClient.getVM();
+    _vm = await serviceClient.getVM();
     if (_vm.isolates.length != 1) {
       throw "Expected 1 isolate, got ${_vm.isolates.length}";
     }
     _isolateRef = _vm.isolates.single;
     await forceGC(_isolateRef.id);
 
-    assert(await _isPausedAtStart(_isolateRef.id));
-    await _serviceClient.resume(_isolateRef.id);
+    assert(await isPausedAtStart(_isolateRef.id));
+    await serviceClient.resume(_isolateRef.id);
 
     _iterationNumber = 1;
     while (true) {
@@ -364,7 +87,7 @@
 
       vmService.HeapSnapshotGraph heapSnapshotGraph =
           await vmService.HeapSnapshotGraph.getSnapshot(
-              _serviceClient, _isolateRef);
+              serviceClient, _isolateRef);
 
       Set<String> duplicatePrints = {};
       Map<String, List<vmService.HeapSnapshotObject>> groupedByToString = {};
@@ -396,7 +119,7 @@
         }
       }
 
-      await _serviceClient.resume(_isolateRef.id);
+      await serviceClient.resume(_isolateRef.id);
       _iterationNumber++;
     }
   }
@@ -695,20 +418,6 @@
   Interest(this.uri, this.className, this.fieldNames);
 }
 
-class StdOutLog implements vmService.Log {
-  const StdOutLog();
-
-  @override
-  void severe(String message) {
-    print("> SEVERE: $message");
-  }
-
-  @override
-  void warning(String message) {
-    print("> WARNING: $message");
-  }
-}
-
 HeapGraph convertHeapGraph(vmService.HeapSnapshotGraph graph) {
   HeapGraphClassSentinel classSentinel = new HeapGraphClassSentinel();
   List<HeapGraphClassActual> classes =
diff --git a/pkg/front_end/test/vm_service_helper.dart b/pkg/front_end/test/vm_service_helper.dart
new file mode 100644
index 0000000..a80eb5a
--- /dev/null
+++ b/pkg/front_end/test/vm_service_helper.dart
@@ -0,0 +1,215 @@
+// Copyright (c) 2020, 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:convert";
+import "dart:io";
+
+import "package:vm_service/vm_service.dart" as vmService;
+import "package:vm_service/vm_service_io.dart" as vmService;
+
+export "package:vm_service/vm_service.dart";
+export "package:vm_service/vm_service_io.dart";
+
+class VMServiceHelper {
+  vmService.VmService _serviceClient;
+  vmService.VmService get serviceClient => _serviceClient;
+
+  VMServiceHelper();
+
+  Future connect(Uri observatoryUri) async {
+    String path = observatoryUri.path;
+    if (!path.endsWith("/")) path += "/";
+    String wsUriString = 'ws://${observatoryUri.authority}${path}ws';
+    _serviceClient = await vmService.vmServiceConnectUri(wsUriString,
+        log: const StdOutLog());
+  }
+
+  Future disconnect() async {
+    await _serviceClient.dispose();
+  }
+
+  Future<bool> waitUntilPaused(String isolateId) async {
+    int nulls = 0;
+    while (true) {
+      bool result = await isPaused(isolateId);
+      if (result == null) {
+        nulls++;
+        if (nulls > 5) {
+          // We've now asked for the isolate 5 times and in all cases gotten
+          // `Sentinel`. Most likely things aren't working for whatever reason.
+          return false;
+        }
+      } else if (result) {
+        return true;
+      } else {
+        await Future.delayed(const Duration(milliseconds: 100));
+      }
+    }
+  }
+
+  Future<bool> isPaused(String isolateId) async {
+    dynamic tmp = await _serviceClient.getIsolate(isolateId);
+    if (tmp is vmService.Isolate) {
+      vmService.Isolate isolate = tmp;
+      if (isolate.pauseEvent.kind != "Resume") return true;
+      return false;
+    }
+    return null;
+  }
+
+  Future<bool> isPausedAtStart(String isolateId) async {
+    dynamic tmp = await _serviceClient.getIsolate(isolateId);
+    if (tmp is vmService.Isolate) {
+      vmService.Isolate isolate = tmp;
+      return isolate.pauseEvent.kind == "PauseStart";
+    }
+    return false;
+  }
+
+  Future<bool> isPausedAtExit(String isolateId) async {
+    dynamic tmp = await _serviceClient.getIsolate(isolateId);
+    if (tmp is vmService.Isolate) {
+      vmService.Isolate isolate = tmp;
+      return isolate.pauseEvent.kind == "PauseExit";
+    }
+    return false;
+  }
+
+  Future<vmService.AllocationProfile> forceGC(String isolateId) async {
+    await waitUntilIsolateIsRunnable(isolateId);
+    int expectGcAfter = new DateTime.now().millisecondsSinceEpoch;
+    while (true) {
+      vmService.AllocationProfile allocationProfile;
+      try {
+        allocationProfile =
+            await _serviceClient.getAllocationProfile(isolateId, gc: true);
+      } catch (e) {
+        print(e.runtimeType);
+        rethrow;
+      }
+      if (allocationProfile.dateLastServiceGC != null &&
+          allocationProfile.dateLastServiceGC >= expectGcAfter) {
+        return allocationProfile;
+      }
+    }
+  }
+
+  Future<bool> isIsolateRunnable(String isolateId) async {
+    dynamic tmp = await _serviceClient.getIsolate(isolateId);
+    if (tmp is vmService.Isolate) {
+      vmService.Isolate isolate = tmp;
+      return isolate.runnable;
+    }
+    return null;
+  }
+
+  Future<void> waitUntilIsolateIsRunnable(String isolateId) async {
+    int nulls = 0;
+    while (true) {
+      bool result = await isIsolateRunnable(isolateId);
+      if (result == null) {
+        nulls++;
+        if (nulls > 5) {
+          // We've now asked for the isolate 5 times and in all cases gotten
+          // `Sentinel`. Most likely things aren't working for whatever reason.
+          return;
+        }
+      } else if (result) {
+        return;
+      } else {
+        await Future.delayed(const Duration(milliseconds: 100));
+      }
+    }
+  }
+
+  Future<String> getIsolateId() async {
+    vmService.VM vm = await _serviceClient.getVM();
+    if (vm.isolates.length != 1) {
+      throw "Expected 1 isolate, got ${vm.isolates.length}";
+    }
+    vmService.IsolateRef isolateRef = vm.isolates.single;
+    return isolateRef.id;
+  }
+}
+
+class StdOutLog implements vmService.Log {
+  const StdOutLog();
+
+  @override
+  void severe(String message) {
+    print("> SEVERE: $message");
+  }
+
+  @override
+  void warning(String message) {
+    print("> WARNING: $message");
+  }
+}
+
+abstract class LaunchingVMServiceHelper extends VMServiceHelper {
+  Process _process;
+  Process get process => _process;
+
+  bool _started = false;
+
+  void start(List<String> scriptAndArgs,
+      {void stdinReceiver(String line),
+      void stderrReceiver(String line)}) async {
+    if (_started) throw "Already started";
+    _started = true;
+    _process = await Process.start(
+        Platform.resolvedExecutable,
+        ["--pause_isolates_on_start", "--enable-vm-service=0"]
+          ..addAll(scriptAndArgs));
+    _process.stdout
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      const kObservatoryListening = 'Observatory listening on ';
+      if (line.startsWith(kObservatoryListening)) {
+        Uri observatoryUri =
+            Uri.parse(line.substring(kObservatoryListening.length));
+        _setupAndRun(observatoryUri).catchError((e, st) {
+          // Manually kill the process or it will leak,
+          // see http://dartbug.com/42918
+          killProcess();
+          // This seems to rethrow.
+          throw e;
+        });
+      }
+      if (stdinReceiver != null) {
+        stdinReceiver(line);
+      } else {
+        stdout.writeln("> $line");
+      }
+    });
+    _process.stderr
+        .transform(utf8.decoder)
+        .transform(new LineSplitter())
+        .listen((line) {
+      if (stderrReceiver != null) {
+        stderrReceiver(line);
+      } else {
+        stderr.writeln("> $line");
+      }
+    });
+    // ignore: unawaited_futures
+    _process.exitCode.then((value) {
+      processExited(value);
+    });
+  }
+
+  void processExited(int exitCode) {}
+
+  void killProcess() {
+    _process.kill();
+  }
+
+  Future _setupAndRun(Uri observatoryUri) async {
+    await connect(observatoryUri);
+    await run();
+  }
+
+  Future<void> run();
+}
