[dart2js] Avoid N/A memory usage with dart compile js

dart compile js seems to run dart2js in product mode, so the developer service is unavailable.

Instead of always outputting "N/A", instead don't include memory usage in the output when it can't be determined.

Fixes https://github.com/dart-lang/sdk/issues/56074

Change-Id: I3eea98a20b717c75abb56a48b3fe2a923ed3ecf1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/424320
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
diff --git a/pkg/compiler/lib/src/common/ram_usage.dart b/pkg/compiler/lib/src/common/ram_usage.dart
index b094304..9974b64 100644
--- a/pkg/compiler/lib/src/common/ram_usage.dart
+++ b/pkg/compiler/lib/src/common/ram_usage.dart
@@ -25,21 +25,31 @@
     enable: true,
     silenceOutput: true,
   );
-  final observatoryUri = info.serverUri;
-  if (observatoryUri == null) return null;
-  final wsUri = 'ws://${observatoryUri.authority}${observatoryUri.path}ws';
-  final vmService = await vm_service_io.vmServiceConnectUri(wsUri);
-  int sum = 0;
-  for (final group in (await vmService.getVM()).isolateGroups!) {
+  final vmServiceWsUri = info.serverWebSocketUri?.toString();
+  if (vmServiceWsUri == null) return null;
+
+  final vmService = await vm_service_io.vmServiceConnectUri(vmServiceWsUri);
+  final vm = await vmService.getVM();
+
+  final nonSystemIsolateGroups = vm.isolateGroups;
+  final relevantSystemIsolateGroups = vm.systemIsolateGroups?.where(
+    (group) => group.name?.contains('dart2js') ?? false,
+  );
+
+  var relevantMemoryUsage = 0;
+  for (final group in [
+    ...?nonSystemIsolateGroups,
+    ...?relevantSystemIsolateGroups,
+  ]) {
     final usage = await vmService.getIsolateGroupMemoryUsage(group.id!);
-    sum += usage.heapCapacity!;
+    relevantMemoryUsage += usage.heapCapacity ?? 0;
   }
   vmService.dispose();
-  return sum;
+  return relevantMemoryUsage;
 }
 
-Future<String> currentHeapCapacityInMb() async {
+Future<String?> currentHeapCapacityInMb() async {
   final capacity = await _currentHeapCapacity();
-  if (capacity == null) return "N/A MB";
+  if (capacity == null || capacity == 0) return null;
   return "${(capacity / (1024 * 1024)).toStringAsFixed(3)} MB";
 }
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index d31425e..e4e9e4e 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -925,12 +925,16 @@
         break;
     }
 
+    final memoryUsed = await currentHeapCapacityInMb();
+    final memoryUsedString = memoryUsed != null
+        ? ' using $memoryUsed of memory'
+        : '';
+
     print(
       '$processName '
       '${_formatCharacterCount(inputSize)} $inputName to '
       '${_formatCharacterCount(outputSize)} $outputName in '
-      '${_formatDurationAsSeconds(wallclock.elapsed)} seconds using '
-      '${await currentHeapCapacityInMb()} of memory',
+      '${_formatDurationAsSeconds(wallclock.elapsed)} seconds$memoryUsedString',
     );
     if (primaryOutputSize != null && out != null) {
       diagnostic.info(
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 5dca3d0..e796ff1 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -1891,7 +1891,7 @@
                   .mainFunction]
               as FunctionInfo,
       size: _dumpInfoData.programSize,
-      ramUsage: await currentHeapCapacityInMb(),
+      ramUsage: await currentHeapCapacityInMb() ?? 'N/A MB',
       dart2jsVersion: options.hasBuildId ? options.buildId : null,
       compilationMoment: DateTime.now(),
       compilationDuration: measurer.elapsedWallClock,
@@ -1975,7 +1975,7 @@
                   .mainFunction]
               as FunctionInfo,
       size: _dumpInfoData.programSize,
-      ramUsage: await currentHeapCapacityInMb(),
+      ramUsage: await currentHeapCapacityInMb() ?? 'N/A MB',
       dart2jsVersion: options.hasBuildId ? options.buildId : null,
       compilationMoment: DateTime.now(),
       compilationDuration: measurer.elapsedWallClock,