Revert "[VM/dartdev] Switch dartdev to use an AOT runtime."

This reverts commit 5399dbf6f6ed5210ed3e6474f877cf9153362f92.

Reason for revert : Flutter rolls are failing

TEST=ci

Change-Id: I76fede849705514496adbc2ab7f6c262de4103ca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/439661
Reviewed-by: Jason Simmons <jsimmons@google.com>
Commit-Queue: Siva Annamalai <asiva@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 25f4b6a..56c1c6a 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -42,7 +42,6 @@
 
   deps = [
     "runtime/bin:dart",
-    "runtime/bin:dartvm",
     "runtime/bin:ffi_test_dynamic_library",
     "runtime/bin:ffi_test_functions",
     "runtime/bin:process_test",
@@ -61,15 +60,12 @@
     deps += [
       "runtime/bin:dartaotruntime",
       "runtime/bin:dartaotruntime_product",
-      "utils/dartdev:dartdev_aot_snapshot",
       "utils/dds:dds_aot",
-      "utils/dtd:dtd_aot",
       "utils/kernel-service:frontend_server_aot_product",
     ]
   } else {
     deps += [
       "utils/dds:dds",
-      "utils/dtd:dtd",
       "utils/kernel-service:frontend_server",
     ]
   }
@@ -424,7 +420,7 @@
   }
 
   test_binaries = [
-    "dartvm",
+    "dart",
     "dartaotruntime",
     "run_vm_tests",
   ]
diff --git a/CHANGELOG.md b/CHANGELOG.md
index de6d293..9317c2a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -83,25 +83,6 @@
 
 [cross-compilation]: https://dart.dev/tools/dart-compile#cross-compilation-exe
 
-#### Dart CLI and Dart VM
-
-- The Dart CLI and Dart VM have been split into two seperate executables.
-
-  The Dart CLI tool has been split out of the VM into it's own embedder which
-  runs in AOT mode. The pure Dart VM executable is called `dartvm` and
-  has no Dart CLI functionality in it
-
-  The Dart CLI executable parses the CLI commands and invokes the rest
-  of the AOT tools in the same process, for the 'run' and 'test'
-  commands it execs a process which runs `dartvm`
-
-  `dart hello.dart` execs the `dartvm` process and runs 'hello.dart'
-
-  The Dart CLI is not generated for ia32 as we are not shipping a
-  Dart SDK for ia32 anymore (support to execute the `dartvm` for ia32
-  architecture is retained)
-
-
 #### Pub
 
 - Git dependencies can now be version-solved based on git tags.
diff --git a/build/dart/dart_action.gni b/build/dart/dart_action.gni
index 8f75a32..7b5d40c 100644
--- a/build/dart/dart_action.gni
+++ b/build/dart/dart_action.gni
@@ -10,7 +10,7 @@
 # - prebuilt_dart_action()
 #   Runs Dart scripts using the downloaded prebuilt Dart SDK. This is the
 #   preferred method of running Dart code during the build as it is much
-#   faster than using dartvm_action() in debug and cross builds.
+#   faster than using dart_action() in debug and cross builds.
 #   However, prebuilt_dart_action() should *not* be used to generate snapshots.
 #
 # - prebuilt_dartaotruntime_action()
@@ -18,7 +18,7 @@
 #   preferred method of running Dart AOT code during the build as it avoids
 #   the multiple layers of code that prebuilt_dart_action goes through.
 #
-# - dartvm_action()
+# - dart_action()
 #   Runs Dart scripts using the binary built for runtime/bin:dart using the
 #   host toolchain. It should only be used when an artifact agreeing exactly
 #   with the version of the Dart VM being built must be produced, for example
@@ -350,10 +350,10 @@
 #    outputs
 #    testonly
 #    visibility
-template("dartvm_action") {
+template("dart_action") {
   assert(defined(invoker.script), "script must be defined for $target_name")
   _built_tool_action(target_name) {
-    tool = "$_dart_root/runtime/bin:dartvm"
+    tool = "$_dart_root/runtime/bin:dart"
     forward_variables_from(invoker,
                            [
                              "args",
diff --git a/build/rbe/rewrapper_dart.py b/build/rbe/rewrapper_dart.py
index e81969d..11dfbd6 100644
--- a/build/rbe/rewrapper_dart.py
+++ b/build/rbe/rewrapper_dart.py
@@ -269,9 +269,6 @@
             elif arg.endswith('/dart'):
                 self.dart_subdir = os.path.dirname(arg)
                 return self.parse_dart()
-            elif arg.endswith('/dartvm'):
-                self.dart_subdir = os.path.dirname(arg)
-                return self.parse_dart()
             elif arg.endswith('/dartaotruntime'):
                 self.dart_subdir = os.path.dirname(arg)
                 return self.parse_dartaotruntime()
diff --git a/pkg/analysis_server/integration_test/analysis/get_errors_non_standard_sdk_test.dart b/pkg/analysis_server/integration_test/analysis/get_errors_non_standard_sdk_test.dart
index 4903ad8..d57a211 100644
--- a/pkg/analysis_server/integration_test/analysis/get_errors_non_standard_sdk_test.dart
+++ b/pkg/analysis_server/integration_test/analysis/get_errors_non_standard_sdk_test.dart
@@ -27,11 +27,6 @@
       return path.join(sdkPath, 'bin', name);
     }
 
-    String executableVmFilePathIn(String sdkPath) {
-      var name = Platform.isWindows ? 'dartvm.exe' : 'dartvm';
-      return path.join(sdkPath, 'bin', name);
-    }
-
     String serverSnapshotPathIn(String sdkPath) {
       return path.join(
         sdkPath,
@@ -56,10 +51,6 @@
     ).copySync(executableFilePathIn(sdkPath));
 
     File(
-      executableVmFilePathIn(standardSdkPath),
-    ).copySync(executableVmFilePathIn(sdkPath));
-
-    File(
       serverSnapshotPathIn(standardSdkPath),
     ).copySync(serverSnapshotPathIn(sdkPath));
 
diff --git a/pkg/dartdev/lib/src/commands/compile.dart b/pkg/dartdev/lib/src/commands/compile.dart
index 7a55052..ab36839 100644
--- a/pkg/dartdev/lib/src/commands/compile.dart
+++ b/pkg/dartdev/lib/src/commands/compile.dart
@@ -98,12 +98,19 @@
     }
     final args = argResults!;
     var snapshot = sdk.dart2jsAotSnapshot;
+    var script = sdk.dartAotRuntime;
+    var useExecProcess = true;
     if (!Sdk.checkArtifactExists(snapshot, logError: false)) {
-      log.stderr('Error: JS compilation failed');
-      log.stderr('Unable to find $snapshot');
-      return compileErrorExitCode;
+      // AOT snapshots cannot be generated on IA32, so we need this fallback
+      // branch until support for IA32 is dropped (https://dartbug.com/49969).
+      script = sdk.dart2jsSnapshot;
+      if (!Sdk.checkArtifactExists(script)) {
+        return genericErrorExitCode;
+      }
+      useExecProcess = false;
     }
     final dart2jsCommand = [
+      if (useExecProcess) snapshot,
       '--libraries-spec=${sdk.librariesJson}',
       '--cfe-invocation-modes=compile',
       '--invoker=dart_cli',
@@ -112,10 +119,10 @@
     ];
     try {
       VmInteropHandler.run(
-        snapshot,
+        script,
         dart2jsCommand,
         packageConfigOverride: null,
-        useExecProcess: false,
+        useExecProcess: useExecProcess,
       );
       return 0;
     } catch (e, st) {
@@ -156,21 +163,28 @@
     }
     final args = argResults!;
     var snapshot = sdk.ddcAotSnapshot;
+    var script = sdk.dartAotRuntime;
+    var useExecProcess = true;
     if (!Sdk.checkArtifactExists(snapshot, logError: false)) {
-      log.stderr('Error: JS compilation failed');
-      log.stderr('Unable to find $snapshot');
-      return compileErrorExitCode;
+      // AOT snapshots cannot be generated on IA32, so we need this fallback
+      // branch until support for IA32 is dropped (https://dartbug.com/49969).
+      script = sdk.ddcSnapshot;
+      if (!Sdk.checkArtifactExists(script)) {
+        return genericErrorExitCode;
+      }
+      useExecProcess = false;
     }
     final ddcCommand = <String>[
+      if (useExecProcess) snapshot,
       // Add the remaining arguments.
       if (args.rest.isNotEmpty) ...args.rest.sublist(0),
     ];
     try {
       VmInteropHandler.run(
-        snapshot,
+        script,
         ddcCommand,
         packageConfigOverride: null,
-        useExecProcess: false,
+        useExecProcess: useExecProcess,
       );
       return 0;
     } catch (e, st) {
@@ -445,7 +459,7 @@
 
     log.stdout('Compiling $sourcePath to jit-snapshot file $outputFile.');
     // TODO(bkonyi): perform compilation in same process.
-    return await runProcess([sdk.dartvm, ...buildArgs]);
+    return await runProcess([sdk.dart, ...buildArgs]);
   }
 }
 
diff --git a/pkg/dartdev/lib/src/commands/dart_mcp_server.dart b/pkg/dartdev/lib/src/commands/dart_mcp_server.dart
index 8d6f6ca..142c375 100644
--- a/pkg/dartdev/lib/src/commands/dart_mcp_server.dart
+++ b/pkg/dartdev/lib/src/commands/dart_mcp_server.dart
@@ -51,11 +51,12 @@
     }
     try {
       VmInteropHandler.run(
-        sdk.dartMCPServerAotSnapshot,
+        sdk.dartAotRuntime,
         [
+          sdk.dartMCPServerAotSnapshot,
           ...forwardedArgs,
         ],
-        useExecProcess: false,
+        useExecProcess: true,
       );
       return 0;
     } catch (e, st) {
diff --git a/pkg/dartdev/lib/src/commands/development_service.dart b/pkg/dartdev/lib/src/commands/development_service.dart
index bf80eba..f640da4 100644
--- a/pkg/dartdev/lib/src/commands/development_service.dart
+++ b/pkg/dartdev/lib/src/commands/development_service.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:io';
 
 import 'package:dds/src/arg_parser.dart';
 import 'package:path/path.dart';
@@ -36,22 +37,38 @@
   Future<int> run() async {
     final sdkDir = dirname(sdk.dart);
     final fullSdk = sdkDir.endsWith('bin');
+    var script = fullSdk
+        ? sdk.dartAotRuntime
+        : absolute(sdkDir, 'dartaotruntime${Platform.isWindows ? '.exe' : ''}');
     var snapshot = fullSdk
         ? sdk.ddsAotSnapshot
         : absolute(sdkDir, 'dds_aot.dart.snapshot');
+    var useExecProcess = true;
     final args = argResults!.arguments;
 
     if (!Sdk.checkArtifactExists(snapshot, logError: false)) {
-      log.stderr('Error: launching development server failed : '
-                 'Unable to find snapshot for the development server');
-      return 255;
+      // On ia32 platforms we do not have an AOT snapshot and so we need
+      // to run the JIT snapshot.
+      useExecProcess = false;
+      script =
+          fullSdk ? sdk.ddsSnapshot : absolute(sdkDir, 'dds.dart.snapshot');
+      if (!Sdk.checkArtifactExists(script, logError: false)) {
+        log.stderr('Error: launching development server failed : '
+            'Unable to find snapshot for the development server');
+        return 255;
+      }
     }
+    final ddsCommand = [
+      if (useExecProcess) snapshot,
+      // Add the remaining args.
+      if (args.isNotEmpty) ...args,
+    ];
     try {
       VmInteropHandler.run(
-        snapshot,
-        args,
+        script,
+        ddsCommand,
         packageConfigOverride: null,
-        useExecProcess: false,
+        useExecProcess: useExecProcess,
       );
       return 0;
     } catch (e, st) {
diff --git a/pkg/dartdev/lib/src/commands/language_server.dart b/pkg/dartdev/lib/src/commands/language_server.dart
index f4d95d2..9c446db 100644
--- a/pkg/dartdev/lib/src/commands/language_server.dart
+++ b/pkg/dartdev/lib/src/commands/language_server.dart
@@ -54,27 +54,26 @@
       args = [...args, '--$protocol=$lsp'];
     }
     try {
-      var script = sdk.analysisServerAotSnapshot;
-      var useExec = false;
       if (argResults!.flag(useAotSnapshotFlag)) {
-        if (!Sdk.checkArtifactExists(sdk.analysisServerAotSnapshot)) {
-          log.stderr('Error: launching language analysis server failed');
-          log.stderr('${sdk.analysisServerAotSnapshot} not found');
+        if (!Sdk.checkArtifactExists(sdk.dartAotRuntime)) {
           return _genericErrorExitCode;
         }
         args = [...args];
         args.remove('--$useAotSnapshotFlag');
+        VmInteropHandler.run(
+          sdk.dartAotRuntime,
+          [sdk.analysisServerAotSnapshot, ...args],
+          useExecProcess: true,
+        );
       } else {
         args = [...args];
         args.remove('--no-$useAotSnapshotFlag');
-        script = sdk.analysisServerSnapshot;
-        useExec = true;
+        VmInteropHandler.run(
+          sdk.analysisServerSnapshot,
+          args,
+          useExecProcess: false,
+        );
       }
-      VmInteropHandler.run(
-        script,
-        args,
-        useExecProcess: useExec,
-      );
       return 0;
     } catch (e, st) {
       log.stderr('Error: launching language analysis server failed');
@@ -82,7 +81,7 @@
       if (verbose) {
         log.stderr(st.toString());
       }
-      return _genericErrorExitCode;
+      return 255;
     }
   }
 
diff --git a/pkg/dartdev/lib/src/commands/run.dart b/pkg/dartdev/lib/src/commands/run.dart
index b897714..1035d4b 100644
--- a/pkg/dartdev/lib/src/commands/run.dart
+++ b/pkg/dartdev/lib/src/commands/run.dart
@@ -25,6 +25,7 @@
 import 'compilation_server.dart';
 
 class RunCommand extends DartdevCommand {
+  static const bool isProductMode = bool.fromEnvironment('dart.vm.product');
   static const String cmdName = 'run';
 
   // kErrorExitCode, as defined in runtime/bin/error_exit.h
@@ -91,101 +92,109 @@
     argParser.addSeparator(
       'Debugging options:',
     );
-    argParser
-      ..addOption(
-        'observe',
-        help: 'The observe flag is a convenience flag used to run a program '
-            'with a set of common options useful for debugging. '
-            'Run `dart help -v run` for details.',
-        valueHelp: '[<port>[/<bind-address>]]',
-      )
-      ..addFlag(
-        'enable-asserts',
-        help: 'Enable assert statements.',
-      )
-      ..addOption(
-        'launch-dds',
-        hide: true,
-        help: 'Launch DDS.',
-      );
+    if (!isProductMode) {
+      argParser
+        ..addOption(
+          'observe',
+          help: 'The observe flag is a convenience flag used to run a program '
+              'with a set of common options useful for debugging. '
+              'Run `dart help -v run` for details.',
+          valueHelp: '[<port>[/<bind-address>]]',
+        )
+        ..addFlag(
+          'enable-asserts',
+          help: 'Enable assert statements.',
+        )
+        ..addOption(
+          'launch-dds',
+          hide: true,
+          help: 'Launch DDS.',
+        );
 
-    if (verbose) {
-      argParser.addSeparator(
-          verbose ? 'Options implied by --observe are currently:' : '');
-    }
-    argParser
-      ..addOption(
-        'enable-vm-service',
-        help: 'Enables the VM service and listens on the specified port for '
-            'connections (default port number is 8181, default bind address '
-            'is localhost).',
-        valueHelp: '[<port>[/<bind-address>]]',
-        hide: !verbose,
-      )
-      ..addFlag(
-        'serve-devtools',
-        help: 'Serves an instance of the Dart DevTools debugger and profiler '
-            'via the VM service at <vm-service-uri>/devtools.',
-        defaultsTo: true,
-        hide: !verbose,
-      )
-      ..addFlag(
-        'pause-isolates-on-exit',
-        help: 'Pause isolates on exit when '
-            'running with --enable-vm-service.',
-        hide: !verbose,
-      )
-      ..addFlag(
-        'pause-isolates-on-unhandled-exceptions',
-        help: 'Pause isolates when an unhandled exception is encountered '
-            'when running with --enable-vm-service.',
-        hide: !verbose,
-      )
-      ..addFlag(
-        'warn-on-pause-with-no-debugger',
-        help:
-            'Print a warning when an isolate pauses with no attached debugger'
-            ' when running with --enable-vm-service.',
-        hide: !verbose,
-      )
-      ..addOption(
-        'timeline-streams',
-        help: 'Enables recording for specific timeline streams.\n'
-            'Valid streams include: all, API, Compiler, CompilerVerbose, Dart, '
-            'Debugger, Embedder, GC, Isolate, Microtask, VM.\n'
-            'Defaults to "Compiler, Dart, GC, Microtask" when --observe is '
-            'provided.',
-        valueHelp: 'str1, str2, ...',
-        hide: !verbose,
-      );
+      if (verbose) {
+        argParser.addSeparator(
+            verbose ? 'Options implied by --observe are currently:' : '');
+      }
+      argParser
+        ..addOption(
+          'enable-vm-service',
+          help: 'Enables the VM service and listens on the specified port for '
+              'connections (default port number is 8181, default bind address '
+              'is localhost).',
+          valueHelp: '[<port>[/<bind-address>]]',
+          hide: !verbose,
+        )
+        ..addFlag(
+          'serve-devtools',
+          help: 'Serves an instance of the Dart DevTools debugger and profiler '
+              'via the VM service at <vm-service-uri>/devtools.',
+          defaultsTo: true,
+          hide: !verbose,
+        )
+        ..addFlag(
+          'pause-isolates-on-exit',
+          help: 'Pause isolates on exit when '
+              'running with --enable-vm-service.',
+          hide: !verbose,
+        )
+        ..addFlag(
+          'pause-isolates-on-unhandled-exceptions',
+          help: 'Pause isolates when an unhandled exception is encountered '
+              'when running with --enable-vm-service.',
+          hide: !verbose,
+        )
+        ..addFlag(
+          'warn-on-pause-with-no-debugger',
+          help:
+              'Print a warning when an isolate pauses with no attached debugger'
+              ' when running with --enable-vm-service.',
+          hide: !verbose,
+        )
+        ..addOption(
+          'timeline-streams',
+          help: 'Enables recording for specific timeline streams.\n'
+              'Valid streams include: all, API, Compiler, CompilerVerbose, Dart, '
+              'Debugger, Embedder, GC, Isolate, Microtask, VM.\n'
+              'Defaults to "Compiler, Dart, GC, Microtask" when --observe is '
+              'provided.',
+          valueHelp: 'str1, str2, ...',
+          hide: !verbose,
+        );
 
-    if (verbose) {
-      argParser.addSeparator('Other debugging options:');
+      if (verbose) {
+        argParser.addSeparator('Other debugging options:');
+      }
+      argParser
+        ..addFlag(
+          'pause-isolates-on-start',
+          help: 'Pause isolates on start when '
+              'running with --enable-vm-service.',
+          hide: !verbose,
+        )
+        ..addOption(
+          'timeline-recorder',
+          help: 'Selects the timeline recorder to use.\n'
+              'Valid recorders include: none, ring, endless, startup, '
+              'systrace, file, callback, perfettofile.\n'
+              'Defaults to ring.',
+          valueHelp: 'recorder',
+          hide: !verbose,
+        )
+        ..addFlag(
+          'profile-microtasks',
+          hide: !verbose,
+          negatable: false,
+          help: 'Record information about each microtask. Information about '
+              'completed microtasks will be written to the "Microtask" '
+              'timeline stream.',
+        );
+    } else {
+      argParser.addOption('timeline-recorder',
+          help: 'Selects the timeline recorder to use.\n'
+              'Valid recorders include: none, systrace, file, callback.\n'
+              'Defaults to none.',
+          valueHelp: 'recorder');
     }
-    argParser
-      ..addFlag(
-        'pause-isolates-on-start',
-        help: 'Pause isolates on start when '
-            'running with --enable-vm-service.',
-        hide: !verbose,
-      )
-      ..addOption(
-        'timeline-recorder',
-        help: 'Selects the timeline recorder to use.\n'
-            'Valid recorders include: none, ring, endless, startup, '
-            'systrace, file, callback, perfettofile.\n'
-            'Defaults to ring.',
-        valueHelp: 'recorder',
-        hide: !verbose,
-      )
-      ..addFlag(
-        'profile-microtasks',
-        hide: !verbose,
-        negatable: false,
-        help: 'Record information about each microtask. Information about '
-            'completed microtasks will be written to the "Microtask" '
-            'timeline stream.',
-      );
 
     argParser.addSeparator('Logging options:');
     argParser.addOption(
@@ -206,24 +215,26 @@
       help: 'Define an environment declaration.',
       hide: !verbose,
     );
-    argParser
-      ..addFlag(
-        'disable-service-auth-codes',
-        hide: !verbose,
-        negatable: false,
-        help: 'Disables the requirement for an authentication code to '
-            'communicate with the VM service. Authentication codes help '
-            'protect against CSRF attacks, so it is not recommended to '
-            'disable them unless behind a firewall on a secure device.',
-      )
-      ..addFlag(
-        'enable-service-port-fallback',
-        hide: !verbose,
-        negatable: false,
-        help: 'When the VM service is told to bind to a particular port, '
-            'fallback to 0 if it fails to bind instead of failing to '
-            'start.',
-      );
+    if (!isProductMode) {
+      argParser
+        ..addFlag(
+          'disable-service-auth-codes',
+          hide: !verbose,
+          negatable: false,
+          help: 'Disables the requirement for an authentication code to '
+              'communicate with the VM service. Authentication codes help '
+              'protect against CSRF attacks, so it is not recommended to '
+              'disable them unless behind a firewall on a secure device.',
+        )
+        ..addFlag(
+          'enable-service-port-fallback',
+          hide: !verbose,
+          negatable: false,
+          help: 'When the VM service is told to bind to a particular port, '
+              'fallback to 0 if it fails to bind instead of failing to '
+              'start.',
+        );
+    }
     argParser
       ..addOption(
         'namespace',
@@ -260,38 +271,40 @@
             'supplies a mapping of package names\ninto paths.',
       );
 
-    argParser
-      ..addOption(
-        'write-service-info',
-        help: 'Outputs information necessary to connect to the VM service to '
-            'specified file in JSON format. Useful for clients which are '
-            'unable to listen to stdout for the Dart VM service listening '
-            'message.',
-        valueHelp: 'file',
-        hide: !verbose,
-      )
-      ..addFlag('dds',
+    if (!isProductMode) {
+      argParser
+        ..addOption(
+          'write-service-info',
+          help: 'Outputs information necessary to connect to the VM service to '
+              'specified file in JSON format. Useful for clients which are '
+              'unable to listen to stdout for the Dart VM service listening '
+              'message.',
+          valueHelp: 'file',
           hide: !verbose,
-          help:
-              'Use the Dart Development Service (DDS) for enhanced debugging '
-              'functionality. Note: Disabling DDS may break some '
-              'functionality in IDEs and other tooling.',
-          defaultsTo: true)
-      ..addFlag('serve-observatory',
+        )
+        ..addFlag('dds',
+            hide: !verbose,
+            help:
+                'Use the Dart Development Service (DDS) for enhanced debugging '
+                'functionality. Note: Disabling DDS may break some '
+                'functionality in IDEs and other tooling.',
+            defaultsTo: true)
+        ..addFlag('serve-observatory',
+            hide: !verbose,
+            help: 'Enable hosting Observatory through the VM Service.',
+            defaultsTo: true)
+        ..addFlag(
+          'print-dtd',
           hide: !verbose,
-          help: 'Enable hosting Observatory through the VM Service.',
-          defaultsTo: true)
-      ..addFlag(
-        'print-dtd',
-        hide: !verbose,
-        help: 'Prints connection details for the Dart Tooling Daemon (DTD).'
-            'Useful for Dart DevTools extension authors working with DTD in the '
-            'extension development environment.',
-      )
-      ..addFlag(
-        'debug-dds',
-        hide: true,
-      );
+          help: 'Prints connection details for the Dart Tooling Daemon (DTD).'
+              'Useful for Dart DevTools extension authors working with DTD in the '
+              'extension development environment.',
+        )
+        ..addFlag(
+          'debug-dds',
+          hide: true,
+        );
+    }
     argParser.addExperimentalFlags(verbose: verbose);
   }
 
@@ -515,7 +528,6 @@
       runArgs,
       packageConfigOverride:
           args.option('packages') ?? executable.packageConfig,
-      useExecProcess: true,
     );
     return 0;
   }
diff --git a/pkg/dartdev/lib/src/commands/test.dart b/pkg/dartdev/lib/src/commands/test.dart
index 3698559..d08a492 100644
--- a/pkg/dartdev/lib/src/commands/test.dart
+++ b/pkg/dartdev/lib/src/commands/test.dart
@@ -112,7 +112,6 @@
         testExecutable.executable,
         argsRestNoExperimentOrSuppressAnalytics,
         packageConfigOverride: testExecutable.packageConfig!,
-        useExecProcess: true,
         // TODO(bkonyi): remove once DartDev moves to AOT and this flag can be
         // provided directly to the process spawned by `dart run` and
         // `dart test`.
diff --git a/pkg/dartdev/lib/src/commands/tooling_daemon.dart b/pkg/dartdev/lib/src/commands/tooling_daemon.dart
index 0c09d06..59a1419 100644
--- a/pkg/dartdev/lib/src/commands/tooling_daemon.dart
+++ b/pkg/dartdev/lib/src/commands/tooling_daemon.dart
@@ -33,19 +33,28 @@
 
   @override
   Future<int> run() async {
+    var script = sdk.dartAotRuntime;
     var snapshot = sdk.dtdAotSnapshot;
+    var useExecProcess = true;
     final args = argResults!.arguments;
+
     if (!Sdk.checkArtifactExists(sdk.dtdAotSnapshot, logError: false)) {
-      log.stderr('Error: launching dart tooling daemon failed : '
-                 'Unable to find snapshot for the tooling daemon');
-      return 255;
+      // On ia32 platforms we do not have an AOT snapshot and so we need
+      // to run the JIT snapshot.
+      useExecProcess = false;
+      script = sdk.dtdSnapshot;
     }
+    final dtdCommand = [
+      if (useExecProcess) snapshot,
+      // Add the remaining args.
+      if (args.isNotEmpty) ...args,
+    ];
     try {
       VmInteropHandler.run(
-        snapshot,
-        args,
+        script,
+        dtdCommand,
         packageConfigOverride: null,
-        useExecProcess : false,
+        useExecProcess: useExecProcess,
       );
       return 0;
     } catch (e, st) {
diff --git a/pkg/dartdev/lib/src/dds_runner.dart b/pkg/dartdev/lib/src/dds_runner.dart
index b1cd2e6..f387d33 100644
--- a/pkg/dartdev/lib/src/dds_runner.dart
+++ b/pkg/dartdev/lib/src/dds_runner.dart
@@ -22,10 +22,6 @@
     required bool debugDds,
     required bool enableServicePortFallback,
   }) async {
-    void printError(String details) => stderr.writeln(
-          'Could not start the VM service:\n$details',
-        );
-
     final sdkDir = dirname(sdk.dart);
     final fullSdk = sdkDir.endsWith('bin');
     var execName = fullSdk
@@ -36,8 +32,14 @@
         : absolute(sdkDir, 'dds_aot.dart.snapshot');
     final isAot = Sdk.checkArtifactExists(snapshotName) ? true : false;
     if (!isAot) {
-      printError('Unable to find snapshot for the development server');
-      return false;
+      // On ia32 sdks we do not have an AOT runtime and so we would be
+      // using the regular executable.
+      snapshotName =
+          fullSdk ? sdk.ddsSnapshot : absolute(sdkDir, 'dds.dart.snapshot');
+      if (!Sdk.checkArtifactExists(snapshotName)) {
+        return false;
+      }
+      execName = sdk.dart;
     }
 
     final process = await Process.start(
@@ -79,6 +81,10 @@
     // DDS will close stderr once it's finished launching.
     final launchResult = await process.stderr.transform(utf8.decoder).join();
 
+    void printError(String details) => stderr.writeln(
+          'Could not start the VM service:\n$details',
+        );
+
     try {
       final result = json.decode(launchResult) as Map<String, dynamic>;
       if (result
diff --git a/pkg/dartdev/lib/src/generate_kernel.dart b/pkg/dartdev/lib/src/generate_kernel.dart
index 6241512..b84cd60 100644
--- a/pkg/dartdev/lib/src/generate_kernel.dart
+++ b/pkg/dartdev/lib/src/generate_kernel.dart
@@ -142,7 +142,17 @@
         mode: ProcessStartMode.detachedWithStdio,
       );
     } else {
-      throw StateError('Unable to find snapshot for frontend server');
+      // AOT snapshots cannot be generated on IA32, so we need this fallback
+      // branch until support for IA32 is dropped (https://dartbug.com/49969).
+      frontendServerProcess = await Process.start(
+        sdk.dart,
+        [
+          sdk.frontendServerSnapshot,
+          '--resident-info-file-name=${serverInfoFile.absolute.path}'
+        ],
+        workingDirectory: homeDir?.path,
+        mode: ProcessStartMode.detachedWithStdio,
+      );
     }
 
     final serverOutput =
diff --git a/pkg/dartdev/lib/src/processes.dart b/pkg/dartdev/lib/src/processes.dart
index 64c3a44..3223161 100644
--- a/pkg/dartdev/lib/src/processes.dart
+++ b/pkg/dartdev/lib/src/processes.dart
@@ -289,8 +289,7 @@
 }
 
 bool _isProcessDartRelated(ProcessInfo process) {
-  return process.command == 'dart' || process.command == 'dart.exe' ||
-      process.command == 'dartvm' || process.command == 'dartvm.exe';
+  return process.command == 'dart' || process.command == 'dart.exe';
 }
 
 String _getCommandFrom(String commandLine) {
diff --git a/pkg/dartdev/lib/src/sdk.dart b/pkg/dartdev/lib/src/sdk.dart
index dfd73ae..845c38d 100644
--- a/pkg/dartdev/lib/src/sdk.dart
+++ b/pkg/dartdev/lib/src/sdk.dart
@@ -53,19 +53,6 @@
     );
   }
 
-  String get dartvm {
-    final basename = Platform.isWindows? 'dartvm.exe' : 'dartvm';
-    return path.absolute(
-      _runFromBuildRoot
-          ? sdkPath
-          : path.absolute(
-              sdkPath,
-              'bin',
-            ),
-      basename,
-    );
-  }
-
   String get dartAotRuntime => _runFromBuildRoot
       ? path.absolute(
           sdkPath,
@@ -87,6 +74,10 @@
         'analysis_server.dart.snapshot',
       );
 
+  String get ddcSnapshot => _snapshotPathFor(
+        'dartdevc.dart.snapshot',
+      );
+
   String get ddcAotSnapshot => _runFromBuildRoot
       ? _snapshotPathFor(
           'dartdevc_aot_product.dart.snapshot',
@@ -95,6 +86,10 @@
           'dartdevc_aot.dart.snapshot',
         );
 
+  String get dart2jsSnapshot => _snapshotPathFor(
+        'dart2js.dart.snapshot',
+      );
+
   String get dart2jsAotSnapshot => _runFromBuildRoot
       ? _snapshotPathFor(
           'dart2js_aot_product.dart.snapshot',
@@ -111,10 +106,18 @@
         'dart_mcp_server_aot.dart.snapshot',
       );
 
+  String get ddsSnapshot => _snapshotPathFor(
+        'dds.dart.snapshot',
+      );
+
   String get ddsAotSnapshot => _snapshotPathFor(
         'dds_aot.dart.snapshot',
       );
 
+  String get frontendServerSnapshot => _snapshotPathFor(
+        'frontend_server.dart.snapshot',
+      );
+
   String get frontendServerAotSnapshot => _runFromBuildRoot
       ? _snapshotPathFor(
           'frontend_server_aot_product.dart.snapshot',
@@ -123,6 +126,10 @@
           'frontend_server_aot.dart.snapshot',
         );
 
+  String get dtdSnapshot => _snapshotPathFor(
+        'dart_tooling_daemon.dart.snapshot',
+      );
+
   String get dtdAotSnapshot => _snapshotPathFor(
         'dart_tooling_daemon_aot.dart.snapshot',
       );
@@ -222,7 +229,7 @@
       // non-standard SDK layouts that can involve symlinks (e.g., Brew
       // installations, google3 tests, etc).
       if (!checkArtifactExists(
-        path.join(snapshotsDir, 'dartdev_aot.dart.snapshot'),
+        path.join(snapshotsDir, 'dartdev.dart.snapshot'),
         logError: false,
       )) {
         return null;
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index c2814f5..42b1c87 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -100,10 +100,18 @@
   test('print Dart CLI help on usage error', () async {
     p = project();
     var result = await p.run(['---help']);
-    expect(result.exitCode, 64);
-    expect(result.stderr, contains('Could not find an option named "---help"'));
-    expectUsage(result.stderr);
-    expect(result.stdout, isEmpty);
+    expect(result.exitCode, 255);
+    expect(result.stdout, contains(DartdevRunner.dartdevDescription));
+    expect(result.stderr, isEmpty);
+  });
+
+  test('print VM help on usage error when --disable-dart-dev is provided',
+      () async {
+    p = project();
+    var result = await p.run(['---help', '--disable-dart-dev']);
+    expect(result.exitCode, 255);
+    expect(result.stdout, isNot(contains(DartdevRunner.dartdevDescription)));
+    expect(result.stderr, isEmpty);
   });
 
   test('help', () async {
diff --git a/pkg/dartdev/test/commands/info_linux_test.dart b/pkg/dartdev/test/commands/info_linux_test.dart
index 2425140..dac77ad 100644
--- a/pkg/dartdev/test/commands/info_linux_test.dart
+++ b/pkg/dartdev/test/commands/info_linux_test.dart
@@ -47,7 +47,7 @@
       expect(output, contains('providing this information'));
       expect(output, contains('## Process info'));
       expect(output, contains('Memory |'));
-      expect(output, contains(RegExp('| dart(vm)? ')));
+      expect(output, contains('| dart '));
     });
   }, timeout: longTimeout);
 }
diff --git a/pkg/dartdev/test/commands/info_macos_test.dart b/pkg/dartdev/test/commands/info_macos_test.dart
index 78695eb..8b5a2ab 100644
--- a/pkg/dartdev/test/commands/info_macos_test.dart
+++ b/pkg/dartdev/test/commands/info_macos_test.dart
@@ -59,7 +59,7 @@
       expect(output, contains('providing this information'));
       expect(output, contains('## Process info'));
       expect(output, contains('Memory |')); // Header is aligned right.
-      expect(output, contains(RegExp('| dart(vm)? ')));
+      expect(output, contains('| dart '));
     });
   }, timeout: longTimeout);
 }
diff --git a/pkg/dartdev/test/commands/info_windows_test.dart b/pkg/dartdev/test/commands/info_windows_test.dart
index ba4b29c..79815962 100644
--- a/pkg/dartdev/test/commands/info_windows_test.dart
+++ b/pkg/dartdev/test/commands/info_windows_test.dart
@@ -24,7 +24,7 @@
         expect(process.memoryMb, greaterThan(0));
         expect(process.cpuPercent, null);
         expect(process.elapsedTime, null);
-        expect(process.commandLine, startsWith('dart'));
+        expect(process.commandLine, startsWith('dart.exe'));
       }
     });
 
diff --git a/pkg/dartdev/test/commands/run_test.dart b/pkg/dartdev/test/commands/run_test.dart
index ae1d9b7..ba860408 100644
--- a/pkg/dartdev/test/commands/run_test.dart
+++ b/pkg/dartdev/test/commands/run_test.dart
@@ -838,8 +838,7 @@
         sub = process.stdout.transform(utf8.decoder).listen((event) async {
           if (event.contains('ready')) {
             readyCompleter.complete();
-          }
-          if (event.contains(devToolsMessagePrefix)) {
+          } else if (event.contains(devToolsMessagePrefix)) {
             await sub.cancel();
             completer.complete();
           }
@@ -929,6 +928,20 @@
     });
   });
 
+  test('running dartdev is a prerequisite for passing --resident', () async {
+    p = project(mainSrc: 'void main() {}');
+    final result = await p.run(['--resident', p.relativeFilePath]);
+
+    expect(result.exitCode, 255);
+    expect(
+      result.stderr,
+      contains(
+        'Passing the `--resident` flag to `dart` is invalid. It must be passed '
+        'to `dart run`.',
+      ),
+    );
+  });
+
   test(
       'passing --resident is a prerequisite for passing --resident-compiler-info-file',
       () async {
@@ -1090,7 +1103,8 @@
     final result = await p.run([
       'run',
       '--resident',
-      '--$residentCompilerInfoFileOption=${path.relative(serverInfoFile, from: p.dirPath)}',
+      '--$residentCompilerInfoFileOption',
+      path.relative(serverInfoFile, from: p.dirPath),
       p.relativeFilePath,
     ]);
 
diff --git a/pkg/dartdev/test/sdk_test.dart b/pkg/dartdev/test/sdk_test.dart
index a39439d..9ef7801 100644
--- a/pkg/dartdev/test/sdk_test.dart
+++ b/pkg/dartdev/test/sdk_test.dart
@@ -26,11 +26,11 @@
   });
 
   test('dds snapshot', () {
-    expectFileExists(Sdk().ddsAotSnapshot);
+    expectSnapshotExists(Sdk().ddsAotSnapshot, Sdk().ddsSnapshot);
   });
 
   test('dart2js snapshot', () {
-    expectFileExists(Sdk().dart2jsAotSnapshot);
+    expectSnapshotExists(Sdk().dart2jsAotSnapshot, Sdk().dart2jsSnapshot);
   });
 }
 
@@ -45,6 +45,10 @@
   expect(File(path).existsSync(), isTrue);
 }
 
+void expectSnapshotExists(String aotpath, String jitpath) {
+  expect(File(aotpath).existsSync() || File(jitpath).existsSync(), isTrue);
+}
+
 void expectDirectoryExists(String path) {
   expect(Directory(path).existsSync(), isTrue);
 }
diff --git a/pkg/dartdev/test/smoke/implicit_smoke_test.dart b/pkg/dartdev/test/smoke/implicit_smoke_test.dart
index 21094c4..a9dc7ad 100644
--- a/pkg/dartdev/test/smoke/implicit_smoke_test.dart
+++ b/pkg/dartdev/test/smoke/implicit_smoke_test.dart
@@ -73,8 +73,7 @@
           void onData(event) {
             if (event.contains(dartVMServiceMsg)) {
               sawServiceMsg = true;
-            }
-            if (event.contains('Observe smoke test!')) {
+            } else if (event.contains('Observe smoke test!')) {
               sawProgramMsg = true;
             }
             if (sawServiceMsg && sawProgramMsg) {
diff --git a/pkg/dartdev/test/smoke/smoke_test.dart b/pkg/dartdev/test/smoke/smoke_test.dart
index 95e3684..ea7a101 100644
--- a/pkg/dartdev/test/smoke/smoke_test.dart
+++ b/pkg/dartdev/test/smoke/smoke_test.dart
@@ -61,9 +61,9 @@
               script,
             ],
           );
-          expect(result.exitCode, 0);
           expect(result.stderr, isEmpty);
           expect(result.stdout, contains('Smoke test!'));
+          expect(result.exitCode, 0);
         }
       });
 
@@ -78,8 +78,7 @@
           void onData(event) {
             if (event.contains(dartVMServiceMsg)) {
               sawServiceMsg = true;
-            }
-            if (event.contains('Observe smoke test!')) {
+            } else if (event.contains('Observe smoke test!')) {
               sawProgramMsg = true;
             }
             if (sawServiceMsg && sawProgramMsg) {
@@ -154,9 +153,9 @@
             script,
           ],
         );
-        expect(result.exitCode, 0);
         expect(result.stderr, isEmpty);
         expect(result.stdout, contains('Smoke test!'));
+        expect(result.exitCode, 0);
       });
 
       // This test verifies that an error is thrown when an invalid experiment
@@ -172,9 +171,9 @@
             script,
           ],
         );
-        expect(result.exitCode, 254);
         expect(result.stderr, isNotEmpty);
         expect(result.stdout, isEmpty);
+        expect(result.exitCode, 254);
       });
     },
     timeout: Timeout.none,
diff --git a/pkg/dds/lib/src/devtools/dtd.dart b/pkg/dds/lib/src/devtools/dtd.dart
index 29417e8..72b06ed 100644
--- a/pkg/dds/lib/src/devtools/dtd.dart
+++ b/pkg/dds/lib/src/devtools/dtd.dart
@@ -34,19 +34,14 @@
       runFromBuildRoot = true;
     }
 
-    // Try to locate the DDS snapshot to determine if we're able to find
+    // Try to locate the DartDev snapshot to determine if we're able to find
     // the SDK snapshots with this SDK path. This is meant to handle
     // non-standard SDK layouts that can involve symlinks (e.g., Brew
     // installations, google3 tests, etc).
     if (!File(
-      path.join(snapshotsDir, 'dds_aot.dart.snapshot'),
+      path.join(snapshotsDir, 'dartdev.dart.snapshot'),
     ).existsSync()) {
-      // We do not have an AOT snpashot and hence look for the JIT snapshot.
-      if (!File(
-        path.join(snapshotsDir, 'dds.dart.snapshot'),
-      ).existsSync()) {
-        return null;
-      }
+      return null;
     }
     return (sdkPath, runFromBuildRoot);
   }
@@ -73,6 +68,11 @@
     snapshotDir,
     'dart_tooling_daemon_aot.dart.snapshot',
   );
+  final dtdSnapshot =  path.absolute(
+    snapshotDir,
+    'dart_tooling_daemon.dart.snapshot',
+  );
+
   final completer = Completer<DtdInfo?>();
   void completeForError() => completer.complete(null);
 
@@ -124,11 +124,8 @@
     );
   } catch (_, __) {
     // Spawning an isolate using the AOT snapshot of the tooling daemon failed,
-    // try again using the JIT snapshot of the tooling daemon.
-    final dtdSnapshot =  path.absolute(
-      snapshotDir,
-      'dart_tooling_daemon.dart.snapshot',
-    );
+    // we are probably in a JIT VM, try again using the JIT snapshot of the
+    // tooling daemon.
     try {
       await Isolate.spawnUri(
         Uri.file(dtdSnapshot),
diff --git a/pkg/dds/test/devtools_server/utils/server_driver.dart b/pkg/dds/test/devtools_server/utils/server_driver.dart
index b48e0b6..d2ad505 100644
--- a/pkg/dds/test/devtools_server/utils/server_driver.dart
+++ b/pkg/dds/test/devtools_server/utils/server_driver.dart
@@ -78,8 +78,10 @@
     int? tryPorts,
     List<String> additionalArgs = const [],
   }) async {
+    final script =
+        resolveTestRelativePath('devtools_server/utils/serve_devtools.dart');
     final args = [
-      'devtools',
+      script.toFilePath(),
       '--machine',
       '--port',
       '$port',
diff --git a/pkg/test_runner/lib/src/process_queue.dart b/pkg/test_runner/lib/src/process_queue.dart
index a426b75..62b670d 100644
--- a/pkg/test_runner/lib/src/process_queue.dart
+++ b/pkg/test_runner/lib/src/process_queue.dart
@@ -715,8 +715,6 @@
     steps
         .add(() => device.pushCachedData("$buildPath/dart", '$devicedir/dart'));
     steps.add(() => device
-        .pushCachedData("$buildPath/dartvm", '$devicedir/dartvm'));
-    steps.add(() => device
         .runAdbCommand(['push', hostKernelFile, '$deviceTestDir/out.dill']));
 
     steps.addAll(_pushLibraries(command, device, devicedir, deviceTestDir));
diff --git a/pkg/test_runner/lib/src/runtime_configuration.dart b/pkg/test_runner/lib/src/runtime_configuration.dart
index b2050ad..a2f2727 100644
--- a/pkg/test_runner/lib/src/runtime_configuration.dart
+++ b/pkg/test_runner/lib/src/runtime_configuration.dart
@@ -547,7 +547,7 @@
             argument.replaceAll(Directory.current.path, "pkg/data"))
         .toList();
 
-    var component = "dartvm_test_component.cm";
+    var component = "dart_test_component.cm";
     if (aot) {
       component = "dartaotruntime_test_component.cm";
       arguments[arguments.length - 1] =
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index dfa1dbc..6e3a35a 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -59,25 +59,6 @@
   ]
 }
 
-config("dartdev_config") {
-  defines = []
-  cflags = []
-  defines += [
-    "DART_PRECOMPILED_RUNTIME",
-    "EXCLUDE_CFE_AND_KERNEL_PLATFORM",
-  ]
-  if (!dart_debug) {
-    defines += [ "PRODUCT" ]
-    if (is_posix) {
-      cflags = [
-        # This is the equivalent from `build/config/BUILDCONFIG.gn` which includes
-        # `build/config/gcc:symbol_visibility_hidden` in product mode.
-        "-fvisibility=hidden",
-      ]
-    }
-  }
-}
-
 config("add_empty_macho_section_config") {
   if (is_mac || is_ios) {
     # We create an empty __space_for_note section in a __CUSTOM segment to
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index b3b71b3..63a919c 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -916,6 +916,8 @@
                 "error_exit.cc",
                 "error_exit.h",
                 "icu.cc",
+                "main_options.cc",
+                "main_options.h",
                 "options.cc",
                 "options.h",
                 "snapshot_utils.cc",
@@ -964,7 +966,7 @@
   }
 }
 
-dart_executable("dartvm") {
+dart_executable("dart") {
   extra_deps = [
     ":dart_snapshot_cc",
     "..:libdart_jit",
@@ -972,7 +974,8 @@
   ]
   extra_sources = [
     "builtin.cc",
-    "common_options.h",
+    "dartdev_isolate.cc",
+    "dartdev_isolate.h",
     "dfe.cc",
     "dfe.h",
     "gzip.cc",
@@ -981,8 +984,6 @@
     "loader.h",
     "main.cc",
     "main_impl.cc",
-    "main_options.cc",
-    "main_options.h",
   ]
   if (!exclude_kernel_service) {
     extra_deps += [ ":dart_kernel_platform_cc" ]
@@ -1006,15 +1007,12 @@
   ]
   extra_sources = [
     "builtin.cc",
-    "common_options.h",
     "gzip.cc",
     "gzip.h",
     "loader.cc",
     "loader.h",
     "main.cc",
     "main_impl.cc",
-    "main_options.cc",
-    "main_options.h",
     "snapshot_empty.cc",
   ]
 
@@ -1043,15 +1041,12 @@
   ]
   extra_sources = [
     "builtin.cc",
-    "common_options.h",
     "gzip.cc",
     "gzip.h",
     "loader.cc",
     "loader.h",
     "main.cc",
     "main_impl.cc",
-    "main_options.cc",
-    "main_options.h",
     "snapshot_empty.cc",
   ]
 
@@ -1061,40 +1056,6 @@
   ]
 }
 
-if (dart_target_arch != "ia32" && dart_target_arch != "x86") {
-  dart_executable("dart") {
-    use_product_mode = true
-    extra_configs = [
-      "..:dartdev_config",
-      "..:add_empty_macho_section_config",
-    ]
-    extra_deps = [
-      ":shared_object_loaders_product",
-      "..:libdart_aotruntime_product",
-      "../platform:libdart_platform_aotruntime_product",
-    ]
-    extra_sources = [
-      "builtin.cc",
-      "common_options.h",
-      "dartdev.cc",
-      "dartdev.h",
-      "dartdev_options.cc",
-      "dartdev_options.h",
-      "gzip.cc",
-      "gzip.h",
-      "loader.cc",
-      "loader.h",
-      "snapshot_empty.cc",
-    ]
-  }
-} else {
-  copy("dart") {
-    deps = [ ":dartvm" ]
-    sources = [ "$root_build_dir/dartvm${executable_suffix}" ]
-    outputs = [ "$root_build_dir/dart${executable_suffix}" ]
-  }
-}
-
 # This flag is set in runtime/runtime_args.gni
 # The analyze_snapshot tool is only supported on 64 bit AOT builds running under
 # linux and android platforms
@@ -1118,11 +1079,8 @@
     extra_sources = [
       "analyze_snapshot.cc",
       "builtin.cc",
-      "common_options.h",
       "loader.cc",
       "loader.h",
-      "main_options.cc",
-      "main_options.h",
     ]
 
     if (use_product_mode) {
@@ -1248,7 +1206,7 @@
 }
 
 shared_library("entrypoints_verification_test") {
-  deps = [ ":dartvm" ]
+  deps = [ ":dart" ]
   sources = [ "entrypoints_verification_test.cc" ]
   if (is_win) {
     sources += [ "dart_api_win.c" ]
@@ -1257,13 +1215,13 @@
 }
 
 shared_library("ffi_test_dynamic_library") {
-  deps = [ ":dartvm" ]
+  deps = [ ":dart" ]
   sources = [ "ffi_test/ffi_test_dynamic_library.cc" ]
   include_dirs = [ ".." ]
 }
 
 shared_library("ffi_test_functions") {
-  deps = [ ":dartvm" ]
+  deps = [ ":dart" ]
 
   sources = [
     # This file must be compiled in for dynamic linking.
@@ -1301,11 +1259,8 @@
     extra_sources = [
       "../vm/libfuzzer/dart_libfuzzer.cc",
       "builtin.cc",
-      "common_options.h",
       "dfe.cc",
       "dfe.h",
-      "main_options.cc",
-      "main_options.h",
     ]
     if (!exclude_kernel_service) {
       extra_deps += [ ":dart_kernel_platform_cc" ]
diff --git a/runtime/bin/common_options.h b/runtime/bin/common_options.h
deleted file mode 100644
index d375685..0000000
--- a/runtime/bin/common_options.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// Copyright (c) 2025, 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.
-
-#ifndef RUNTIME_BIN_COMMON_OPTIONS_H_
-#define RUNTIME_BIN_COMMON_OPTIONS_H_
-
-#include "include/dart_api.h"
-#include "platform/assert.h"
-#include "platform/globals.h"
-#include "platform/syslog.h"
-
-namespace dart {
-namespace bin {
-
-static void _PrintVersion() {
-  Syslog::Print("Dart SDK version: %s\n", Dart_VersionString());
-}
-
-// clang-format off
-static void _PrintUsage() {
-  Syslog::Print(
-      "Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]\n"
-      "\n"
-      "Executes the Dart script <dart-script-file> with "
-      "the given list of <script-arguments>.\n"
-      "\n");
-}
-
-static void _PrintNonVerboseUsage() {
-  Syslog::Print(
-"Common VM flags:\n"
-#if !defined(PRODUCT)
-"--enable-asserts\n"
-"  Enable assert statements.\n"
-#endif  // !defined(PRODUCT)
-"--help or -h\n"
-"  Display this message (add -v or --verbose for information about\n"
-"  all VM options).\n"
-"--packages=<path>\n"
-"  Where to find a package spec file.\n"
-"--define=<key>=<value> or -D<key>=<value>\n"
-"  Define an environment declaration. To specify multiple declarations,\n"
-"  use multiple instances of this option.\n"
-#if !defined(PRODUCT)
-"--observe[=<port>[/<bind-address>]]\n"
-"  The observe flag is a convenience flag used to run a program with a\n"
-"  set of options which are often useful for debugging under Dart DevTools.\n"
-"  These options are currently:\n"
-"      --enable-vm-service[=<port>[/<bind-address>]]\n"
-"      --serve-devtools\n"
-"      --pause-isolates-on-exit\n"
-"      --pause-isolates-on-unhandled-exceptions\n"
-"      --warn-on-pause-with-no-debugger\n"
-"      --timeline-streams=\"Compiler, Dart, GC, Microtask\"\n"
-"  This set is subject to change.\n"
-"  Please see these options (--help --verbose) for further documentation.\n"
-"--write-service-info=<file_uri>\n"
-"  Outputs information necessary to connect to the VM service to the\n"
-"  specified file in JSON format. Useful for clients which are unable to\n"
-"  listen to stdout for the Dart VM service listening message.\n"
-#endif  // !defined(PRODUCT)
-"--snapshot-kind=<snapshot_kind>\n"
-"--snapshot=<file_name>\n"
-"  These snapshot options are used to generate a snapshot of the loaded\n"
-"  Dart script:\n"
-"    <snapshot-kind> controls the kind of snapshot, it could be\n"
-"                    kernel(default) or app-jit\n"
-"    <file_name> specifies the file into which the snapshot is written\n"
-"--version\n"
-"  Print the SDK version.\n");
-}
-
-static void _PrintVerboseUsage() {
-  Syslog::Print(
-"Supported options:\n"
-#if !defined(PRODUCT)
-"--enable-asserts\n"
-"  Enable assert statements.\n"
-#endif  // !defined(PRODUCT)
-"--help or -h\n"
-"  Display this message (add -v or --verbose for information about\n"
-"  all VM options).\n"
-"--packages=<path>\n"
-"  Where to find a package spec file.\n"
-"--define=<key>=<value> or -D<key>=<value>\n"
-"  Define an environment declaration. To specify multiple declarations,\n"
-"  use multiple instances of this option.\n"
-#if !defined(PRODUCT)
-"--observe[=<port>[/<bind-address>]]\n"
-"  The observe flag is a convenience flag used to run a program with a\n"
-"  set of options which are often useful for debugging under Dart DevTools.\n"
-"  These options are currently:\n"
-"      --enable-vm-service[=<port>[/<bind-address>]]\n"
-"      --serve-devtools\n"
-"      --pause-isolates-on-exit\n"
-"      --pause-isolates-on-unhandled-exceptions\n"
-"      --warn-on-pause-with-no-debugger\n"
-"      --timeline-streams=\"Compiler, Dart, GC, Microtask\"\n"
-"  This set is subject to change.\n"
-"  Please see these options for further documentation.\n"
-"--profile-microtasks\n"
-"  Record information about each microtask. Information about completed\n"
-"  microtasks will be written to the \"Microtask\" timeline stream.\n"
-#endif  // !defined(PRODUCT)
-"--version\n"
-"  Print the VM version.\n"
-"\n"
-"--trace-loading\n"
-"  enables tracing of library and script loading\n"
-"\n"
-#if !defined(PRODUCT)
-"--enable-vm-service[=<port>[/<bind-address>]]\n"
-"  Enables the VM service and listens on specified port for connections\n"
-"  (default port number is 8181, default bind address is localhost).\n"
-"\n"
-"--disable-service-auth-codes\n"
-"  Disables the requirement for an authentication code to communicate with\n"
-"  the VM service. Authentication codes help protect against CSRF attacks,\n"
-"  so it is not recommended to disable them unless behind a firewall on a\n"
-"  secure device.\n"
-"\n"
-"--enable-service-port-fallback\n"
-"  When the VM service is told to bind to a particular port, fallback to 0 if\n"
-"  it fails to bind instead of failing to start.\n"
-"\n"
-#endif  // !defined(PRODUCT)
-"--root-certs-file=<path>\n"
-"  The path to a file containing the trusted root certificates to use for\n"
-"  secure socket connections.\n"
-"--root-certs-cache=<path>\n"
-"  The path to a cache directory containing the trusted root certificates to\n"
-"  use for secure socket connections.\n"
-#if defined(DART_HOST_OS_LINUX) || \
-    defined(DART_HOST_OS_ANDROID) || \
-    defined(DART_HOST_OS_FUCHSIA)
-"--namespace=<path>\n"
-"  The path to a directory that dart:io calls will treat as the root of the\n"
-"  filesystem.\n"
-#endif  // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
-"\n"
-"The following options are only used for VM development and may\n"
-"be changed in any future version:\n");
-    const char* print_flags = "--print_flags";
-    char* error = Dart_SetVMFlags(1, &print_flags);
-    ASSERT(error == nullptr);
-}
-// clang-format on
-
-// Returns true if arg starts with the characters "--" followed by option, but
-// all '_' in the option name are treated as '-'.
-static bool IsOption(const char* arg, const char* option) {
-  if (arg[0] != '-' || arg[1] != '-') {
-    // Special case first two characters to avoid recognizing __flag.
-    return false;
-  }
-  for (int i = 0; option[i] != '\0'; i++) {
-    auto c = arg[i + 2];
-    if (c == '\0') {
-      // Not long enough.
-      return false;
-    }
-    if ((c == '_' ? '-' : c) != option[i]) {
-      return false;
-    }
-  }
-  return true;
-}
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // RUNTIME_BIN_COMMON_OPTIONS_H_
diff --git a/runtime/bin/dartvm_test_component.cml b/runtime/bin/dart_test_component.cml
similarity index 93%
rename from runtime/bin/dartvm_test_component.cml
rename to runtime/bin/dart_test_component.cml
index 463d84e..3bff2c9 100644
--- a/runtime/bin/dartvm_test_component.cml
+++ b/runtime/bin/dart_test_component.cml
@@ -7,7 +7,7 @@
     "//runtime/vm-jit.shard.cml",
   ],
   program: {
-    binary: "exe.stripped/dartvm",
+    binary: "exe.stripped/dart",
     runner: "elf_test_runner",
   },
   capabilities: [
diff --git a/runtime/bin/dartdev.cc b/runtime/bin/dartdev.cc
deleted file mode 100644
index aa94be8..0000000
--- a/runtime/bin/dartdev.cc
+++ /dev/null
@@ -1,1137 +0,0 @@
-// Copyright (c) 2025, 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.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <memory>
-#include <utility>
-
-#include "bin/builtin.h"
-#include "bin/console.h"
-#include "bin/crashpad.h"
-#include "bin/dartdev_options.h"
-#include "bin/dartutils.h"
-#include "bin/error_exit.h"
-#include "bin/eventhandler.h"
-#include "bin/exe_utils.h"
-#include "bin/file.h"
-#include "bin/gzip.h"
-#include "bin/isolate_data.h"
-#include "bin/loader.h"
-#include "bin/lockers.h"
-#include "bin/platform.h"
-#include "bin/process.h"
-#include "bin/snapshot_utils.h"
-#include "bin/thread.h"
-#include "bin/utils.h"
-#if defined(DART_HOST_OS_WINDOWS)
-#include "bin/utils_win.h"
-#endif
-#include "bin/vmservice_impl.h"
-#include "include/bin/dart_io_api.h"
-#include "include/dart_api.h"
-#include "include/dart_embedder_api.h"
-#include "include/dart_native_api.h"
-#include "include/dart_tools_api.h"
-#include "platform/assert.h"
-#include "platform/globals.h"
-#include "platform/growable_array.h"
-#include "platform/hashmap.h"
-#include "platform/syslog.h"
-#include "platform/text_buffer.h"
-#include "platform/utils.h"
-
-namespace dart {
-namespace bin {
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-/**
- * Global state used to control and store generation of application snapshots.
- */
-static const uint8_t* ignore_vm_snapshot_data = nullptr;
-static const uint8_t* ignore_vm_snapshot_instructions = nullptr;
-static const uint8_t* app_isolate_snapshot_data = nullptr;
-static const uint8_t* app_isolate_snapshot_instructions = nullptr;
-
-#define SAVE_ERROR_AND_RETURN(result)                                          \
-  if (Dart_IsError(result)) {                                                  \
-    *error = Utils::StrDup(Dart_GetError(result));                             \
-    return false;                                                              \
-  }
-
-#define SAVE_ERROR_AND_EXIT(result)                                            \
-  *error = Utils::StrDup(Dart_GetError(result));                               \
-  if (Dart_IsCompilationError(result)) {                                       \
-    *exit_code = kCompilationErrorExitCode;                                    \
-  } else if (Dart_IsApiError(result)) {                                        \
-    *exit_code = kApiErrorExitCode;                                            \
-  } else {                                                                     \
-    *exit_code = kErrorExitCode;                                               \
-  }                                                                            \
-  Dart_ExitScope();                                                            \
-  Dart_ShutdownIsolate();                                                      \
-  return nullptr;
-
-#define CHECK_RESULT(result)                                                   \
-  if (Dart_IsError(result)) {                                                  \
-    SAVE_ERROR_AND_EXIT(result);                                               \
-  }
-
-#define CHECK_RESULT_CLEANUP(result, cleanup)                                  \
-  if (Dart_IsError(result)) {                                                  \
-    delete (cleanup);                                                          \
-    SAVE_ERROR_AND_EXIT(result);                                               \
-  }
-
-#define DART_DEV_ISOLATE_NAME "dartdev"
-
-// Helper class to ensure we enter a new Dart Scope and exit it.
-class DartScope {
- public:
-  DartScope() { Dart_EnterScope(); }
-  ~DartScope() { Dart_ExitScope(); }
-};
-
-static Dart_Handle SetupCoreLibraries(Dart_Isolate isolate,
-                                      IsolateData* isolate_data,
-                                      bool is_isolate_group_start,
-                                      const char** resolved_packages_config) {
-  auto isolate_group_data = isolate_data->isolate_group_data();
-  const auto packages_file = isolate_data->packages_file();
-  const auto script_uri = isolate_group_data->script_url;
-
-  Dart_Handle result;
-
-  // Prepare builtin and other core libraries for use to resolve URIs.
-  // Set up various closures, e.g: printing, timers etc.
-  // Set up package configuration for URI resolution.
-  result = DartUtils::PrepareForScriptLoading(false, false, false);
-  if (Dart_IsError(result)) return result;
-
-  // Setup packages config if specified.
-  result = DartUtils::SetupPackageConfig(packages_file);
-  if (Dart_IsError(result)) return result;
-  if (!Dart_IsNull(result) && resolved_packages_config != nullptr) {
-    result = Dart_StringToCString(result, resolved_packages_config);
-    if (Dart_IsError(result)) return result;
-    ASSERT(*resolved_packages_config != nullptr);
-  }
-
-  result = Dart_SetEnvironmentCallback(DartUtils::EnvironmentCallback);
-  if (Dart_IsError(result)) return result;
-
-  // Setup the native resolver as the snapshot does not carry it.
-  Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
-  Builtin::SetNativeResolver(Builtin::kIOLibrary);
-  Builtin::SetNativeResolver(Builtin::kCLILibrary);
-  VmService::SetNativeResolver();
-
-  const char* namespc = Options::namespc();
-  result =
-      DartUtils::SetupIOLibrary(namespc, script_uri, Options::exit_disabled());
-  if (Dart_IsError(result)) return result;
-
-  return Dart_Null();
-}
-
-static bool OnIsolateInitialize(void** child_callback_data, char** error) {
-  Dart_Isolate isolate = Dart_CurrentIsolate();
-  ASSERT(isolate != nullptr);
-
-  auto isolate_group_data =
-      reinterpret_cast<IsolateGroupData*>(Dart_CurrentIsolateGroupData());
-
-  auto isolate_data = new IsolateData(isolate_group_data);
-  *child_callback_data = isolate_data;
-
-  DartScope scope;  // Enter a new scope.
-  const auto script_uri = isolate_group_data->script_url;
-  const bool isolate_run_app_snapshot =
-      isolate_group_data->RunFromAppSnapshot();
-  Dart_Handle result = SetupCoreLibraries(isolate, isolate_data,
-                                          /*group_start=*/false,
-                                          /*resolved_packages_config=*/nullptr);
-  SAVE_ERROR_AND_RETURN(result);
-  if (isolate_run_app_snapshot) {
-    result = Loader::InitForSnapshot(script_uri, isolate_data);
-    SAVE_ERROR_AND_RETURN(result);
-  } else {
-    result = DartUtils::ResolveScript(Dart_NewStringFromCString(script_uri));
-    SAVE_ERROR_AND_RETURN(result);
-
-    if (isolate_group_data->kernel_buffer() != nullptr) {
-      // Various core-library parts will send requests to the Loader to resolve
-      // relative URIs and perform other related tasks. We need Loader to be
-      // initialized for this to work because loading from Kernel binary
-      // bypasses normal source code loading paths that initialize it.
-      const char* resolved_script_uri = nullptr;
-      result = Dart_StringToCString(result, &resolved_script_uri);
-      SAVE_ERROR_AND_RETURN(result);
-      result = Loader::InitForSnapshot(resolved_script_uri, isolate_data);
-      SAVE_ERROR_AND_RETURN(result);
-    }
-  }
-
-  return true;
-}
-
-static Dart_Isolate IsolateSetupHelper(Dart_Isolate isolate,
-                                       bool is_dartdev_isolate,
-                                       const char* script_uri,
-                                       const char* packages_config,
-                                       bool isolate_run_app_snapshot,
-                                       Dart_IsolateFlags* flags,
-                                       char** error,
-                                       int* exit_code) {
-  Dart_EnterScope();
-
-  // Set up the library tag handler for the isolate group shared by all
-  // isolates in the group.
-  Dart_Handle result = Dart_SetLibraryTagHandler(Loader::LibraryTagHandler);
-  CHECK_RESULT(result);
-  result = Dart_SetDeferredLoadHandler(Loader::DeferredLoadHandler);
-  CHECK_RESULT(result);
-
-  auto isolate_data = reinterpret_cast<IsolateData*>(Dart_IsolateData(isolate));
-
-  const char* resolved_packages_config = nullptr;
-  result = SetupCoreLibraries(isolate, isolate_data,
-                              /*is_isolate_group_start=*/true,
-                              &resolved_packages_config);
-  CHECK_RESULT(result);
-
-  if (isolate_run_app_snapshot) {
-    Dart_Handle result = Loader::InitForSnapshot(script_uri, isolate_data);
-    CHECK_RESULT(result);
-  } else {
-    UNREACHABLE();
-  }
-
-  // Make the isolate runnable so that it is ready to handle messages.
-  Dart_ExitScope();
-  Dart_ExitIsolate();
-  *error = Dart_IsolateMakeRunnable(isolate);
-  if (*error != nullptr) {
-    Dart_EnterIsolate(isolate);
-    Dart_ShutdownIsolate();
-    return nullptr;
-  }
-
-  return isolate;
-}
-
-// Returns newly created Isolate on success, nullptr on failure.
-static Dart_Isolate CreateIsolateGroupAndSetupHelper(
-    bool is_dartdev_isolate,
-    const char* script_uri,
-    const char* name,
-    const char* packages_config,
-    Dart_IsolateFlags* flags,
-    void* callback_data,
-    char** error,
-    int* exit_code) {
-  int64_t start = Dart_TimelineGetMicros();
-  ASSERT(script_uri != nullptr);
-  uint8_t* kernel_buffer = nullptr;
-  intptr_t kernel_buffer_size = 0;
-  AppSnapshot* app_snapshot = nullptr;
-
-  const uint8_t* isolate_snapshot_data = nullptr;
-  const uint8_t* isolate_snapshot_instructions = nullptr;
-  if (is_dartdev_isolate) {
-    isolate_snapshot_data = app_isolate_snapshot_data;
-    isolate_snapshot_instructions = app_isolate_snapshot_instructions;
-  } else {
-    // AOT: All isolates need to be run from AOT compiled snapshots.
-    app_snapshot = Snapshot::TryReadAppSnapshot(
-        script_uri, /*force_load_from_memory*/ false, /*decode_uri*/ true);
-    if (app_snapshot == nullptr || !app_snapshot->IsAOT()) {
-      *error = Utils::SCreate(
-          "The uri(%s) provided to `Isolate.spawnUri()` does not "
-          "contain a valid AOT snapshot.",
-          script_uri);
-      return nullptr;
-    }
-
-    app_snapshot->SetBuffers(
-        &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
-        &isolate_snapshot_data, &isolate_snapshot_instructions);
-  }
-
-  bool isolate_run_app_snapshot = true;
-
-  auto isolate_group_data = new IsolateGroupData(
-      script_uri, /*asset_resolution_base=*/nullptr, packages_config,
-      app_snapshot, isolate_run_app_snapshot);
-  if (kernel_buffer != nullptr) {
-    isolate_group_data->SetKernelBufferNewlyOwned(kernel_buffer,
-                                                  kernel_buffer_size);
-  }
-
-  Dart_Isolate isolate = nullptr;
-
-  IsolateData* isolate_data = nullptr;
-  isolate_data = new IsolateData(isolate_group_data);
-  isolate = Dart_CreateIsolateGroup(script_uri, name, isolate_snapshot_data,
-                                    isolate_snapshot_instructions, flags,
-                                    isolate_group_data, isolate_data, error);
-  Dart_Isolate created_isolate = nullptr;
-  if (isolate == nullptr) {
-    delete isolate_data;
-    delete isolate_group_data;
-  } else {
-    created_isolate = IsolateSetupHelper(
-        isolate, is_dartdev_isolate, script_uri, packages_config,
-        isolate_run_app_snapshot, flags, error, exit_code);
-  }
-  int64_t end = Dart_TimelineGetMicros();
-  Dart_RecordTimelineEvent("CreateIsolateGroupAndSetupHelper", start, end,
-                           /*flow_id_count=*/0, nullptr,
-                           Dart_Timeline_Event_Duration,
-                           /*argument_count=*/0, nullptr, nullptr);
-  return created_isolate;
-}
-
-#undef CHECK_RESULT
-
-static Dart_Isolate CreateIsolateGroupAndSetup(const char* script_uri,
-                                               const char* main,
-                                               const char* package_root,
-                                               const char* package_config,
-                                               Dart_IsolateFlags* flags,
-                                               void* callback_data,
-                                               char** error) {
-  // The VM should never call the isolate helper with a nullptr flags.
-  ASSERT(flags != nullptr);
-  ASSERT(flags->version == DART_FLAGS_CURRENT_VERSION);
-  ASSERT(package_root == nullptr);
-
-  if (error != nullptr) {
-    *error = nullptr;
-  }
-
-#if defined(DART_HOST_OS_LINUX)
-  // This would also be true in Linux, except that Google3 overrides the default
-  // ELF interpreter to one that apparently doesn't create proper mappings.
-  flags->snapshot_is_dontneed_safe = false;
-#else
-  flags->snapshot_is_dontneed_safe = true;
-#endif
-
-  int exit_code = 0;
-
-  if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
-    // We do not start the service isolate in the Dart CLI mode of execution.
-    // If profiling or debugging of the individual tools is desired it is
-    // possible to do that using the 'dartaotruntime' or 'dartvm' executables.
-    return nullptr;
-  }
-
-  bool is_dartdev_isolate = false;
-  return CreateIsolateGroupAndSetupHelper(is_dartdev_isolate, script_uri, main,
-                                          package_config, flags, callback_data,
-                                          error, &exit_code);
-}
-
-static void OnIsolateShutdown(void* isolate_group_data, void* isolate_data) {
-  Dart_EnterScope();
-  Dart_Handle sticky_error = Dart_GetStickyError();
-  if (!Dart_IsNull(sticky_error) && !Dart_IsFatalError(sticky_error)) {
-    Syslog::PrintErr("%s\n", Dart_GetError(sticky_error));
-  }
-  Dart_ExitScope();
-}
-
-static void DeleteIsolateData(void* isolate_group_data, void* callback_data) {
-  auto isolate_data = reinterpret_cast<IsolateData*>(callback_data);
-  delete isolate_data;
-}
-
-static void DeleteIsolateGroupData(void* callback_data) {
-  auto isolate_group_data = reinterpret_cast<IsolateGroupData*>(callback_data);
-  delete isolate_group_data;
-}
-
-static constexpr const char* kStdoutStreamId = "Stdout";
-static constexpr const char* kStderrStreamId = "Stderr";
-
-static bool ServiceStreamListenCallback(const char* stream_id) {
-  if (strcmp(stream_id, kStdoutStreamId) == 0) {
-    SetCaptureStdout(true);
-    return true;
-  } else if (strcmp(stream_id, kStderrStreamId) == 0) {
-    SetCaptureStderr(true);
-    return true;
-  }
-  return false;
-}
-
-static void ServiceStreamCancelCallback(const char* stream_id) {
-  if (strcmp(stream_id, kStdoutStreamId) == 0) {
-    SetCaptureStdout(false);
-  } else if (strcmp(stream_id, kStderrStreamId) == 0) {
-    SetCaptureStderr(false);
-  } else {
-    UNREACHABLE();
-  }
-}
-
-static bool FileModifiedCallback(const char* url, int64_t since) {
-  auto path = File::UriToPath(url);
-  if (path == nullptr) {
-    // If it isn't a file on local disk, we don't know if it has been
-    // modified.
-    return true;
-  }
-  int64_t data[File::kStatSize];
-  File::Stat(nullptr, path.get(), data);
-  if (data[File::kType] == File::kDoesNotExist) {
-    return true;
-  }
-  return data[File::kModifiedTime] > since;
-}
-
-static void EmbedderInformationCallback(Dart_EmbedderInformation* info) {
-  info->version = DART_EMBEDDER_INFORMATION_CURRENT_VERSION;
-  info->name = "Dart VM";
-  Process::GetRSSInformation(&(info->max_rss), &(info->current_rss));
-}
-
-#define CHECK_RESULT(result)                                                   \
-  if (Dart_IsError(result)) {                                                  \
-    const int exit_code = Dart_IsCompilationError(result)                      \
-                              ? kCompilationErrorExitCode                      \
-                              : kErrorExitCode;                                \
-    ErrorExit(exit_code, "%s\n", Dart_GetError(result));                       \
-  }
-
-static bool CheckForInvalidPath(const char* path) {
-  // TODO(zichangguo): "\\?\" is a prefix for paths on Windows.
-  // Arguments passed are parsed as an URI. "\\?\" causes problems as a part
-  // of URIs. This is a temporary workaround to prevent VM from crashing.
-  // Issue: https://github.com/dart-lang/sdk/issues/42779
-  if (strncmp(path, R"(\\?\)", 4) == 0) {
-    Syslog::PrintErr(R"(\\?\ prefix is not supported)");
-    return false;
-  }
-  return true;
-}
-
-class DartDev {
- public:
-  // Return codes from dartdev.
-  // Note: keep in sync with pkg/dartdev/lib/vm_interop_handler.dart
-  typedef enum {
-    DartDev_Result_Unknown = -1,
-    DartDev_Result_Run = 1,
-    DartDev_Result_RunExec = 2,
-    DartDev_Result_Exit = 3,
-  } DartDev_Result;
-
-  static CStringUniquePtr ResolvedDartVmPath() {
-#if defined(DART_HOST_OS_WINDOWS)
-    const char* filename = "dartvm.exe";
-#else
-    const char* filename = "dartvm";
-#endif  // defined(DART_HOST_OS_WINDOWS)
-    auto try_resolve_path = [&](CStringUniquePtr dir_prefix) {
-      // |dir_prefix| includes the last path separator.
-      // Assume 'dartvm' and 'dart' executables are in the same directory.
-      char* dartvm_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
-      if (File::Exists(nullptr, dartvm_path)) {
-        return CStringUniquePtr(dartvm_path);
-      }
-      free(dartvm_path);
-      return CStringUniquePtr(nullptr);
-    };
-
-    auto result =
-        try_resolve_path(EXEUtils::GetDirectoryPrefixFromResolvedExeName());
-    if (result == nullptr) {
-      result =
-          try_resolve_path(EXEUtils::GetDirectoryPrefixFromUnresolvedExeName());
-    }
-    return result;
-  }
-
-  static CStringUniquePtr ResolvedSnapshotPath() {
-    const char* filename = "dartdev_aot.dart.snapshot";
-
-    auto try_resolve_path = [&](CStringUniquePtr dir_prefix) {
-      // |dir_prefix| includes the last path separator.
-      // First assume we're in dart-sdk/bin.
-      char* snapshot_path =
-          Utils::SCreate("%ssnapshots/%s", dir_prefix.get(), filename);
-      if (File::Exists(nullptr, snapshot_path)) {
-        return CStringUniquePtr(snapshot_path);
-      }
-      free(snapshot_path);
-
-      // If we're not in dart-sdk/bin, we might be in one of the $SDK/out*/
-      // directories, Try to use a snapshot from that directory.
-      snapshot_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
-      if (File::Exists(nullptr, snapshot_path)) {
-        return CStringUniquePtr(snapshot_path);
-      }
-      free(snapshot_path);
-      return CStringUniquePtr(nullptr);
-    };
-
-    auto result =
-        try_resolve_path(EXEUtils::GetDirectoryPrefixFromResolvedExeName());
-    if (result == nullptr) {
-      result =
-          try_resolve_path(EXEUtils::GetDirectoryPrefixFromUnresolvedExeName());
-    }
-    return result;
-  }
-
-  // Invoke the Dart VM directly bypassing dartdev.
-  static void InvokeDartVM(int argc, char** argv, bool argv_converted) {
-    auto dartvm_path = DartDev::ResolvedDartVmPath();
-    char* exec_name = dartvm_path.get();
-    if (exec_name == nullptr || !CheckForInvalidPath(exec_name)) {
-      // Free environment if any.
-      Syslog::PrintErr("Unable to locate the Dart VM executable");
-      Options::Cleanup();
-      Platform::Exit(kErrorExitCode);
-    }
-    int idx = 0;
-    char err_msg[256];
-    err_msg[0] = '\0';
-    intptr_t num_args = argc + 2;
-    char** exec_argv = new char*[num_args];
-    exec_argv[idx] = Utils::StrDup(exec_name);
-    const size_t kPathBufSize = PATH_MAX + 1;
-    char dart_path[kPathBufSize];
-    Platform::ResolveExecutablePathInto(dart_path, kPathBufSize);
-    idx += 1;
-    exec_argv[idx] = Utils::SCreate("--executable_name=%s", dart_path);
-    for (intptr_t i = 1; i < argc; ++i) {
-#if defined(DART_HOST_OS_WINDOWS)
-      exec_argv[i + idx] = StringUtilsWin::ArgumentEscape(argv[i]);
-#else
-      exec_argv[i + idx] = Utils::StrDup(argv[i]);
-#endif  // defined(DART_HOST_OS_WINDOWS)
-    }
-    // Null terminate the exec_argv array.
-    exec_argv[num_args - 1] = nullptr;
-
-    // Exec the script to be run and pass the arguments.
-    int ret =
-        Process::Exec(nullptr, exec_name, const_cast<const char**>(exec_argv),
-                      (num_args - 1), nullptr, err_msg, sizeof(err_msg));
-    // Exec process done.
-    if (ret != 0) {
-      Syslog::PrintErr("%s\n", err_msg);
-    }
-    // Free copied argument strings if converted.
-    if (argv_converted) {
-      for (int i = 0; i < argc; i++) {
-        free(argv[i]);
-      }
-    }
-    for (int i = 0; i < argc; i++) {
-      free(exec_argv[i]);
-    }
-    delete[] exec_argv;
-
-    // Free environment if any.
-    Options::Cleanup();
-    Platform::Exit(ret);
-  }
-
-  // Process the DartDev_Result_Run result message produced by
-  // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
-  static void RunResultCallback(Dart_CObject* message) {
-    result_ = DartDev_Result_Run;
-    ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
-    auto item2 = GetArrayItem(message, 2);
-
-    ASSERT(item2->type == Dart_CObject_kString ||
-           item2->type == Dart_CObject_kNull);
-
-    auto item3 = GetArrayItem(message, 3);
-
-    // ignoring mark_main_isolate_as_system_isolate
-    ASSERT(item3->type == Dart_CObject_kBool);
-
-    script_name_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
-
-    ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
-    Dart_CObject* args = GetArrayItem(message, 4);
-    argc_ = args->value.as_array.length;
-    Dart_CObject** dart_args = args->value.as_array.values;
-
-    auto deleter = [](char** args) {
-      for (intptr_t i = 0; i < argc_; ++i) {
-        free(args[i]);
-      }
-      delete[] args;
-    };
-    argv_ =
-        std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_], deleter);
-    for (intptr_t i = 0; i < argc_; ++i) {
-      argv_[i] = Utils::StrDup(dart_args[i]->value.as_string);
-    }
-  }
-
-  // Process the DartDev_Result_RunExec result message produced by
-  // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
-  static void RunExecResultCallback(Dart_CObject* message) {
-    result_ = DartDev_Result_RunExec;
-    auto dartvm_path = DartDev::ResolvedDartVmPath();
-    char* exec_name = dartvm_path.get();
-    if (exec_name == nullptr || !CheckForInvalidPath(exec_name)) {
-      Syslog::PrintErr("Unable to locate the Dart VM executable");
-      Platform::Exit(kErrorExitCode);
-    }
-    ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
-    auto item2 = GetArrayItem(message, 2);
-
-    ASSERT(item2->type == Dart_CObject_kString ||
-           item2->type == Dart_CObject_kNull);
-
-    package_config_override_ = nullptr;
-
-    if (item2->type == Dart_CObject_kString) {
-      package_config_override_ = Utils::StrDup(item2->value.as_string);
-    }
-
-    intptr_t num_vm_options = dart_vm_options_->count();
-    const char** vm_options = dart_vm_options_->arguments();
-    ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
-    Dart_CObject* args = GetArrayItem(message, 4);
-    intptr_t argc = args->value.as_array.length;
-    Dart_CObject** dart_args = args->value.as_array.values;
-    auto item3 = GetArrayItem(message, 3);
-    ASSERT(item3->type == Dart_CObject_kBool);
-    const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
-    auto deleter = [](char** args) {
-      for (intptr_t i = 0; i < argc_; ++i) {
-        free(args[i]);
-      }
-      delete[] args;
-    };
-    // Total count of arguments to be passed to the script being execed.
-    if (mark_main_isolate_as_system_isolate) {
-      argc_ = argc + num_vm_options + 4;
-    } else {
-      argc_ = argc + num_vm_options + 3;
-    }
-
-    // Array of arguments to be passed to the script being execed.
-    argv_ = std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_ + 1],
-                                                       deleter);
-
-    intptr_t idx = 0;
-    // Copy in name of the executable to run (should be the dart vm).
-    script_name_ = Utils::StrDup(exec_name);
-    argv_[idx++] = script_name_;
-    // Copy in VM options if any.
-    // Copy in any vm options that need to be passed to the execed process.
-    for (intptr_t i = 0; i < num_vm_options; ++i) {
-      argv_[i + idx] = Utils::StrDup(vm_options[i]);
-    }
-    idx += num_vm_options;
-    {
-      const size_t kPathBufSize = PATH_MAX + 1;
-      char dart_path[kPathBufSize];
-      Platform::ResolveExecutablePathInto(dart_path, kPathBufSize);
-      argv_[idx++] = Utils::SCreate("--executable_name=%s", dart_path);
-    }
-    if (mark_main_isolate_as_system_isolate) {
-      argv_[idx++] = Utils::StrDup("--mark_main_isolate_as_system_isolate");
-    }
-    // Copy in name of the script to run.
-    argv_[idx++] = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
-    // Copy in the dart options that need to be passed to the script.
-    for (intptr_t i = 0; i < argc; ++i) {
-      argv_[i + idx] = Utils::StrDup(dart_args[i]->value.as_string);
-    }
-    // Null terminate the argv array.
-    argv_[argc + idx] = nullptr;
-  }
-
-  // Process the DartDev_Result_Exit result message produced by
-  // VmInteropHandler in pkg/dartdev/lib/src/vm_interop_handler.dart
-  static void ExitResultCallback(Dart_CObject* message) {
-    ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kInt32);
-    int32_t dartdev_exit_code = GetArrayItem(message, 1)->value.as_int32;
-
-    // If we're given a non-zero exit code, DartDev is signaling for us to
-    // shutdown.
-    Process::SetGlobalExitCode(dartdev_exit_code);
-
-    // If DartDev hasn't signaled for us to do anything else, we can assume
-    // there's nothing else for the VM to run and that we can exit.
-    if (result_ == DartDev_Result_Unknown || dartdev_exit_code != 0) {
-      result_ = DartDev_Result_Exit;
-    }
-    // Notify the dartdev runner that it can proceed with processing
-    // the result from execution of dartdev.
-    {
-      MonitorLocker locker(monitor_);
-      locker.Notify();
-    }
-  }
-
-  // Callback that processes the result from execution of dartdev
-  //
-  static void ResultCallback(Dart_Port dest_port_id, Dart_CObject* message) {
-    // These messages are produced in
-    // pkg/dartdev/lib/src/vm_interop_handler.dart.
-    ASSERT(message->type == Dart_CObject_kArray);
-    int32_t type = GetArrayItem(message, 0)->value.as_int32;
-    switch (type) {
-      case DartDev_Result_Run: {
-        RunResultCallback(message);
-        break;
-      }
-      case DartDev_Result_RunExec: {
-        RunExecResultCallback(message);
-        break;
-      }
-      case DartDev_Result_Exit: {
-        ExitResultCallback(message);
-        break;
-      }
-      default:
-        UNREACHABLE();
-    }
-  }
-
-  static void RunDartDev(const char* script_name,
-                         CommandLineOptions* dart_vm_options,
-                         CommandLineOptions* dart_options) {
-    ASSERT(script_name != nullptr);
-    const char* base_name = strrchr(script_name, '/');
-    if (base_name == nullptr) {
-      base_name = script_name;
-    } else {
-      base_name++;  // Skip '/'.
-    }
-    const intptr_t kMaxNameLength = 64;
-    char name[kMaxNameLength];
-    Utils::SNPrint(name, kMaxNameLength, "dart:%s", base_name);
-    Platform::SetProcessName(name);
-
-    dart_vm_options_ = dart_vm_options;
-
-    // Call CreateIsolateGroupAndSetup which creates an isolate and loads up
-    // the specified application script.
-    Dart_IsolateFlags flags;
-    Dart_IsolateFlagsInitialize(&flags);
-#if defined(DART_HOST_OS_LINUX)
-    // This would also be true in Linux, except that Google3 overrides the
-    // default ELF interpreter to one that apparently doesn't create proper
-    // mappings.
-    flags.snapshot_is_dontneed_safe = false;
-#else
-    flags.snapshot_is_dontneed_safe = true;
-#endif
-    flags.is_system_isolate = true;
-    SpawnIsolate(script_name, "_startIsolate",
-                 /*is_dartdev_isolate*/ true,
-                 /*package_config_override*/ nullptr, &flags, dart_options);
-
-    // Wait for the callbacks on the native port to be done before we
-    // proceed.
-    {
-      MonitorLocker locker(monitor_);
-      while (result_ == DartDev_Result_Unknown) {
-        locker.Wait();
-      }
-    }
-
-    /* Process the result returned by the dartdev isolate. */
-    switch (result_) {
-      case DartDev_Result_Run: {
-        flags.is_system_isolate = false;
-        SpawnIsolate(script_name_, "_startMainIsolate",
-                     /*is_dartdev_isolate*/ false, package_config_override_,
-                     &flags, dart_options);
-        free(script_name_);
-        free(package_config_override_);
-        break;
-      }
-      case DartDev_Result_RunExec: {
-        RunExec(script_name_);
-        break;
-      }
-      case DartDev_Result_Exit: {
-        // Nothing to do here, the process will terminate with the exit code
-        // set earlier.
-        break;
-      }
-      default:
-        UNREACHABLE();
-    }
-  }
-
- private:
-  static void SpawnIsolate(const char* script_name,
-                           const char* entry_point,
-                           bool is_dartdev_isolate,
-                           const char* package_config_override,
-                           Dart_IsolateFlags* flags,
-                           CommandLineOptions* dart_options) {
-    // Start a new Isolate with the specified AOT snapshot.
-    int exit_code = 0;
-    char* error = nullptr;
-
-    Dart_Isolate isolate = CreateIsolateGroupAndSetupHelper(
-        is_dartdev_isolate, script_name, "main",
-        Options::packages_file() == nullptr ? package_config_override
-                                            : Options::packages_file(),
-        flags, nullptr /* callback_data */, &error, &exit_code);
-
-    if (isolate == nullptr) {
-      if (error != nullptr) {
-        Syslog::PrintErr("Isolate spawning failed: %s\n", error);
-        free(error);
-      }
-      error = nullptr;
-      Process::TerminateExitCodeHandler();
-      error = Dart_Cleanup();
-      if (error != nullptr) {
-        Syslog::PrintErr("Dart_Cleanup failed: %s\n", error);
-        free(error);
-      }
-      dart::embedder::Cleanup();
-      Platform::Exit((exit_code != 0) ? exit_code : kErrorExitCode);
-    }
-
-    Dart_EnterIsolate(isolate);
-    ASSERT(isolate == Dart_CurrentIsolate());
-    ASSERT(isolate != nullptr);
-    Dart_Handle result;
-
-    Dart_EnterScope();
-
-    Dart_Handle send_port = Dart_Null();
-    Dart_Port send_port_id = ILLEGAL_PORT;
-    if (is_dartdev_isolate) {
-      // Create a SendPort that DartDev can use to communicate its results over.
-      send_port_id =
-          Dart_NewNativePort(DART_DEV_ISOLATE_NAME, ResultCallback, false);
-      ASSERT(send_port_id != ILLEGAL_PORT);
-      send_port = Dart_NewSendPort(send_port_id);
-      CHECK_RESULT(send_port);
-    }
-
-    // Lookup the library of the root script.
-    Dart_Handle root_lib = Dart_RootLibrary();
-
-    if (Dart_IsNull(root_lib)) {
-      ErrorExit(kErrorExitCode, "Unable to find root library for '%s'\n",
-                script_name);
-    }
-
-    // Create a closure for the main entry point which is in the exported
-    // namespace of the root library or invoke a getter of the same name
-    // in the exported namespace and return the resulting closure.
-    Dart_Handle main_closure =
-        Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
-    CHECK_RESULT(main_closure);
-    if (!Dart_IsClosure(main_closure)) {
-      ErrorExit(kErrorExitCode, "Unable to find 'main' in root library '%s'\n",
-                script_name);
-    }
-
-    Dart_Handle isolate_lib =
-        Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
-    if (is_dartdev_isolate) {
-      const intptr_t kNumIsolateArgs = 4;
-      Dart_Handle isolate_args[kNumIsolateArgs];
-      isolate_args[0] = main_closure;                          // entryPoint
-      isolate_args[1] = dart_options->CreateRuntimeOptions();  // args
-      isolate_args[2] = send_port;
-      isolate_args[3] = Dart_True();  // isSpawnUri
-      result = Dart_Invoke(isolate_lib, Dart_NewStringFromCString(entry_point),
-                           kNumIsolateArgs, isolate_args);
-    } else {
-      // Call _startIsolate in the isolate library to enable dispatching the
-      // initial startup message.
-      dart_options->Reset();
-      dart_options->AddArguments(const_cast<const char**>(argv_.get()), argc_);
-      const intptr_t kNumIsolateArgs = 2;
-      Dart_Handle isolate_args[kNumIsolateArgs];
-      isolate_args[0] = main_closure;                          // entryPoint
-      isolate_args[1] = dart_options->CreateRuntimeOptions();  // args
-      result = Dart_Invoke(isolate_lib, Dart_NewStringFromCString(entry_point),
-                           kNumIsolateArgs, isolate_args);
-    }
-    CHECK_RESULT(result);
-
-    // Keep handling messages until the last active receive port is closed.
-    result = Dart_RunLoop();
-    CHECK_RESULT(result);
-
-    if (is_dartdev_isolate) {
-      // DartDev is done processing the command. Close the native port, this
-      // will ensure we exit from the event handler loop and exit dartdev
-      // isolate.
-      Dart_CloseNativePort(send_port_id);
-    }
-    Dart_ExitScope();
-
-    // Shutdown the isolate.
-    Dart_ShutdownIsolate();
-  }
-
-  static void RunExec(const char* script_name) {
-    // Exec the JIT Dart VM with the specified script file.
-    char err_msg[256];
-    err_msg[0] = '\0';
-    int ret = Process::Exec(nullptr, script_name,
-                            const_cast<const char**>(argv_.get()), argc_,
-                            nullptr, err_msg, sizeof(err_msg));
-    if (ret != 0) {
-      Syslog::PrintErr("%s.\n", err_msg);
-      Process::SetGlobalExitCode(ret);
-    } else {
-      Process::SetGlobalExitCode(ret);
-    }
-  }
-
-  static Dart_CObject* GetArrayItem(Dart_CObject* message, intptr_t index) {
-    return message->value.as_array.values[index];
-  }
-
-  static Monitor* monitor_;
-  static DartDev_Result result_;
-  static char* script_name_;
-  static char* package_config_override_;
-  static CommandLineOptions* dart_vm_options_;
-  static std::unique_ptr<char*[], void (*)(char**)> argv_;
-  static intptr_t argc_;
-};
-
-Monitor* DartDev::monitor_ = new Monitor();
-DartDev::DartDev_Result DartDev::result_ = DartDev::DartDev_Result_Unknown;
-char* DartDev::script_name_ = nullptr;
-char* DartDev::package_config_override_ = nullptr;
-CommandLineOptions* DartDev::dart_vm_options_ = nullptr;
-std::unique_ptr<char*[], void (*)(char**)> DartDev::argv_ =
-    std::unique_ptr<char*[], void (*)(char**)>(nullptr, [](char**) {});
-intptr_t DartDev::argc_ = 0;
-
-#undef CHECK_RESULT
-
-static void FreeConvertedArgs(int argc, char** argv, bool argv_converted) {
-  // Free copied argument strings if converted.
-  if (argv_converted) {
-    for (int i = 0; i < argc; i++) {
-      free(argv[i]);
-    }
-  }
-}
-
-void main(int argc, char** argv) {
-#if !defined(DART_HOST_OS_WINDOWS)
-  // Very early so any crashes during startup can also be symbolized.
-  EXEUtils::LoadDartProfilerSymbols(argv[0]);
-#endif
-
-  const int EXTRA_VM_ARGUMENTS = 10;
-  // An invocation line is as follows
-  // dart <vm_opts> <cmd-name> <vm-opts-to-cmd> <script_name> <dart-options>
-
-  // vm-opts : Set of VM options that need to be passed to the AOT runtime
-  // running in this dartdev process.
-  CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
-
-  // vm-opts-to-cmd : Set of VM options that need to be passed to the runtime
-  // that executes the dartdev command.
-  CommandLineOptions dart_vm_options(argc + EXTRA_VM_ARGUMENTS);
-
-  // dart-options : Set of options to be passed to the Dart program
-  CommandLineOptions dart_options(argc + EXTRA_VM_ARGUMENTS);
-
-  // Perform platform specific initialization.
-  if (!Platform::Initialize()) {
-    Syslog::PrintErr("Initialization failed\n");
-    Platform::Exit(kErrorExitCode);
-  }
-
-  // Save the console state so we can restore it at shutdown.
-  Console::SaveConfig();
-
-  // On Windows, the argv strings are code page encoded and not
-  // utf8. We need to convert them to utf8.
-  bool argv_converted = ShellUtils::GetUtf8Argv(argc, argv);
-
-  // When running from the command line we assume that we are optimizing for
-  // throughput, and therefore use a larger new gen semi space size and a faster
-  // new gen growth factor unless others have been specified.
-  if (kWordSize <= 4) {
-    vm_options.AddArgument("--new_gen_semi_max_size=16");
-  } else {
-    vm_options.AddArgument("--new_gen_semi_max_size=32");
-  }
-  vm_options.AddArgument("--new_gen_growth_factor=4");
-
-  // Parse command line arguments.
-  bool skip_dartdev;
-  bool success = Options::ParseDartDevArguments(
-      argc, argv, &vm_options, &dart_vm_options, &dart_options, &skip_dartdev);
-  if (!success) {
-    FreeConvertedArgs(argc, argv, argv_converted);
-    if (Options::help_option()) {
-      Options::PrintUsage();
-      Platform::Exit(0);
-    } else if (Options::version_option()) {
-      Options::PrintVersion();
-      Platform::Exit(0);
-    } else {
-      Options::PrintUsage();
-      Platform::Exit(kErrorExitCode);
-    }
-  }
-  if (skip_dartdev) {
-    // We are skipping execution of dartdev as no Dart command line has
-    // been specified, in this case we directly exec the Dart JIT VM to
-    // run the specified script and pass in the original command line
-    // arguments.
-    DartDev::InvokeDartVM(argc, argv, argv_converted);
-  }
-
-  DartUtils::SetEnvironment(Options::environment());
-
-  if (Options::suppress_core_dump()) {
-    Platform::SetCoreDumpResourceLimit(0);
-  }
-
-  Loader::InitOnce();
-
-  // Setup script_name to point to the dartdev AOT snapshot.
-  auto dartdev_path = DartDev::ResolvedSnapshotPath();
-  char* script_name = dartdev_path.get();
-  if (script_name == nullptr || !CheckForInvalidPath(script_name)) {
-    Syslog::PrintErr("Unable to find AOT snapshot for dartdev\n");
-    FreeConvertedArgs(argc, argv, argv_converted);
-    Platform::Exit(kErrorExitCode);
-  }
-  AppSnapshot* app_snapshot = Snapshot::TryReadAppSnapshot(
-      script_name, /*force_load_from_memory*/ false, /*decode_uri*/ false);
-  if (app_snapshot == nullptr || !app_snapshot->IsAOT()) {
-    Syslog::PrintErr("%s is not an AOT snapshot\n", script_name);
-    FreeConvertedArgs(argc, argv, argv_converted);
-    if (app_snapshot != nullptr) {
-      delete app_snapshot;
-    }
-    Platform::Exit(kErrorExitCode);
-  }
-  app_snapshot->SetBuffers(
-      &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
-      &app_isolate_snapshot_data, &app_isolate_snapshot_instructions);
-
-  vm_options.AddArgument("--precompilation");
-
-  char* error = nullptr;
-  if (!dart::embedder::InitOnce(&error)) {
-    Syslog::PrintErr("dartdev embedder initialization failed: %s\n", error);
-    free(error);
-    FreeConvertedArgs(argc, argv, argv_converted);
-    delete app_snapshot;
-    Platform::Exit(kErrorExitCode);
-  }
-
-  error = Dart_SetVMFlags(vm_options.count(), vm_options.arguments());
-  if (error != nullptr) {
-    for (int i = 0; i < argc; i++) {
-      Syslog::PrintErr("argv[%d]: %s\n", i, argv[i]);
-    }
-    Syslog::PrintErr("Setting VM flags failed: %s\n", error);
-    free(error);
-    FreeConvertedArgs(argc, argv, argv_converted);
-    delete app_snapshot;
-    Platform::Exit(kErrorExitCode);
-  }
-
-  // Initialize the Dart VM.
-  Dart_InitializeParams init_params;
-  memset(&init_params, 0, sizeof(init_params));
-  init_params.version = DART_INITIALIZE_PARAMS_CURRENT_VERSION;
-  init_params.vm_snapshot_data = ignore_vm_snapshot_data;
-  init_params.vm_snapshot_instructions = ignore_vm_snapshot_instructions;
-  init_params.create_group = CreateIsolateGroupAndSetup;
-  init_params.initialize_isolate = OnIsolateInitialize;
-  init_params.shutdown_isolate = OnIsolateShutdown;
-  init_params.cleanup_isolate = DeleteIsolateData;
-  init_params.cleanup_group = DeleteIsolateGroupData;
-  init_params.file_open = DartUtils::OpenFile;
-  init_params.file_read = DartUtils::ReadFile;
-  init_params.file_write = DartUtils::WriteFile;
-  init_params.file_close = DartUtils::CloseFile;
-  init_params.entropy_source = DartUtils::EntropySource;
-  init_params.start_kernel_isolate = false;
-#if defined(DART_HOST_OS_FUCHSIA)
-  init_params.vmex_resource = ZX_HANDLE_INVALID;
-#endif
-
-  error = Dart_Initialize(&init_params);
-  if (error != nullptr) {
-    dart::embedder::Cleanup();
-    Syslog::PrintErr("VM initialization failed: %s\n", error);
-    free(error);
-    FreeConvertedArgs(argc, argv, argv_converted);
-    delete app_snapshot;
-    Platform::Exit(kErrorExitCode);
-  }
-
-  Dart_SetServiceStreamCallbacks(&ServiceStreamListenCallback,
-                                 &ServiceStreamCancelCallback);
-  Dart_SetFileModifiedCallback(&FileModifiedCallback);
-  Dart_SetEmbedderInformationCallback(&EmbedderInformationCallback);
-
-  // Run dartdev as the main isolate.
-  // The result from the running the dartdev isolate could result in one of
-  // these options
-  // - Exit the process due to some command parsing errors
-  // - Run the Dart script in a JIT mode by execing the JIT runtime
-  // - Run the Dart AOT snapshot by creating a new Isolate
-  DartDev::RunDartDev(script_name, &dart_vm_options, &dart_options);
-
-  // Terminate process exit-code handler.
-  Process::TerminateExitCodeHandler();
-
-  error = Dart_Cleanup();
-  if (error != nullptr) {
-    Syslog::PrintErr("VM cleanup failed: %s\n", error);
-    free(error);
-  }
-  const intptr_t global_exit_code = Process::GlobalExitCode();
-  dart::embedder::Cleanup();
-
-  delete app_snapshot;
-
-  // Free copied argument strings if converted.
-  if (argv_converted) {
-    for (int i = 0; i < argc; i++) {
-      free(argv[i]);
-    }
-  }
-
-  // Free environment if any.
-  Options::Cleanup();
-
-  Platform::Exit(global_exit_code);
-}
-#else
-void main(int argc, char** argv) {
-  Platform::Exit(kErrorExitCode);
-}
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-}  // namespace bin
-}  // namespace dart
-
-int main(int argc, char** argv) {
-  dart::bin::main(argc, argv);
-  UNREACHABLE();
-}
diff --git a/runtime/bin/dartdev_isolate.cc b/runtime/bin/dartdev_isolate.cc
new file mode 100644
index 0000000..7287db7
--- /dev/null
+++ b/runtime/bin/dartdev_isolate.cc
@@ -0,0 +1,415 @@
+// 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.
+
+#include "bin/dartdev_isolate.h"
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#include <functional>
+#include <memory>
+
+#include "bin/directory.h"
+#include "bin/error_exit.h"
+#include "bin/exe_utils.h"
+#include "bin/file.h"
+#include "bin/lockers.h"
+#include "bin/main_options.h"
+#include "bin/platform.h"
+#include "bin/process.h"
+#include "include/dart_embedder_api.h"
+#include "platform/utils.h"
+
+#define CHECK_RESULT(result)                                                   \
+  if (Dart_IsError(result)) {                                                  \
+    ProcessError(Dart_GetError(result), kErrorExitCode);                       \
+    if (send_port_id != ILLEGAL_PORT) {                                        \
+      Dart_CloseNativePort(send_port_id);                                      \
+    }                                                                          \
+    Dart_ExitScope();                                                          \
+    Dart_ShutdownIsolate();                                                    \
+    return;                                                                    \
+  }
+
+namespace dart {
+namespace bin {
+
+DartDevIsolate::DartDevRunner DartDevIsolate::runner_ =
+    DartDevIsolate::DartDevRunner();
+bool DartDevIsolate::should_run_dart_dev_ = false;
+bool DartDevIsolate::print_usage_error_ = false;
+CommandLineOptions* DartDevIsolate::vm_options_ = nullptr;
+Monitor* DartDevIsolate::DartDevRunner::monitor_ = new Monitor();
+DartDevIsolate::DartDev_Result DartDevIsolate::DartDevRunner::result_ =
+    DartDevIsolate::DartDev_Result_Unknown;
+char** DartDevIsolate::DartDevRunner::script_ = nullptr;
+char** DartDevIsolate::DartDevRunner::package_config_override_ = nullptr;
+std::unique_ptr<char*[], void (*)(char*[])>
+    DartDevIsolate::DartDevRunner::argv_ =
+        std::unique_ptr<char*[], void (*)(char**)>(nullptr, [](char**) {});
+intptr_t DartDevIsolate::DartDevRunner::argc_ = 0;
+
+bool DartDevIsolate::ShouldParseCommand(const char* script_uri) {
+  // If script_uri is a known DartDev command, we should not try to run it.
+  //
+  // Otherwise if script_uri is not a file path or of a known URI scheme, we
+  // assume this is a mistyped DartDev command.
+  //
+  // This should be kept in sync with the commands in
+  // `pkg/dartdev/lib/dartdev.dart`.
+  return (
+      (strcmp(script_uri, "analyze") == 0) ||
+      (strcmp(script_uri, "compilation-server") == 0) ||
+      (strcmp(script_uri, "build") == 0) ||
+      (strcmp(script_uri, "compile") == 0) ||
+      (strcmp(script_uri, "create") == 0) ||
+      (strcmp(script_uri, "development-service") == 0) ||
+      (strcmp(script_uri, "devtools") == 0) ||
+      (strcmp(script_uri, "doc") == 0) || (strcmp(script_uri, "fix") == 0) ||
+      (strcmp(script_uri, "format") == 0) ||
+      (strcmp(script_uri, "info") == 0) ||
+      (strcmp(script_uri, "mcp-server") == 0) ||
+      (strcmp(script_uri, "pub") == 0) || (strcmp(script_uri, "run") == 0) ||
+      (strcmp(script_uri, "test") == 0) || (strcmp(script_uri, "info") == 0) ||
+      (strcmp(script_uri, "language-server") == 0) ||
+      (strcmp(script_uri, "tooling-daemon") == 0) ||
+      (!File::ExistsUri(nullptr, script_uri) &&
+       (strncmp(script_uri, "http://", 7) != 0) &&
+       (strncmp(script_uri, "https://", 8) != 0) &&
+       (strncmp(script_uri, "file://", 7) != 0) &&
+       (strncmp(script_uri, "package:", 8) != 0) &&
+       (strncmp(script_uri, "google3://", 10) != 0)));
+}
+
+bool DartDevIsolate::ShouldParseVMOptions(const char* command) {
+  // If command is 'run' or 'test' parse the VM options as we need to pass
+  // it down to the VM that executes these commands.
+  return (strcmp(command, "run") == 0) || (strcmp(command, "test") == 0);
+}
+
+CStringUniquePtr DartDevIsolate::TryResolveArtifactPath(const char* filename) {
+  auto try_resolve_path = [&](CStringUniquePtr dir_prefix) {
+    // First assume we're in dart-sdk/bin.
+    char* snapshot_path =
+        Utils::SCreate("%ssnapshots/%s", dir_prefix.get(), filename);
+    if (File::Exists(nullptr, snapshot_path)) {
+      return CStringUniquePtr(snapshot_path);
+    }
+    free(snapshot_path);
+
+    // If we're not in dart-sdk/bin, we might be in one of the $SDK/out/*
+    // directories. Try to use a snapshot from a previously built SDK.
+    snapshot_path = Utils::SCreate("%s%s", dir_prefix.get(), filename);
+    if (File::Exists(nullptr, snapshot_path)) {
+      return CStringUniquePtr(snapshot_path);
+    }
+    free(snapshot_path);
+    return CStringUniquePtr(nullptr);
+  };
+
+  // Try to find the artifact using the resolved EXE path first. This can fail
+  // if the Dart SDK file structure is faked using symlinks and the actual
+  // artifacts are spread across directories on the file system (e.g., some
+  // google3 execution environments).
+  auto result =
+      try_resolve_path(EXEUtils::GetDirectoryPrefixFromResolvedExeName());
+  if (result == nullptr) {
+    result =
+        try_resolve_path(EXEUtils::GetDirectoryPrefixFromUnresolvedExeName());
+  }
+
+  return result;
+}
+
+CStringUniquePtr DartDevIsolate::TryResolveDartDevSnapshotPath() {
+  return TryResolveArtifactPath("dartdev.dart.snapshot");
+}
+
+void DartDevIsolate::DartDevRunner::Run(
+    Dart_IsolateGroupCreateCallback create_isolate,
+    char** packages_file,
+    char** script,
+    CommandLineOptions* dart_options) {
+  create_isolate_ = create_isolate;
+  dart_options_ = dart_options;
+  package_config_override_ = packages_file;
+  script_ = script;
+
+  // We've encountered an error during preliminary argument parsing so we'll
+  // output the standard help message and exit with an error code.
+  if (print_usage_error_) {
+    dart_options_->Reset();
+    dart_options_->AddArgument("--help");
+  }
+
+  MonitorLocker locker(monitor_);
+  Thread::Start("DartDev Runner", RunCallback, reinterpret_cast<uword>(this));
+  monitor_->WaitMicros(Monitor::kNoTimeout);
+
+  if (result_ == DartDevIsolate::DartDev_Result_Run) {
+    // Clear the DartDev dart_options and replace them with the processed
+    // options provided by DartDev.
+    dart_options_->Reset();
+    dart_options_->AddArguments(const_cast<const char**>(argv_.get()), argc_);
+  }
+}
+
+static Dart_CObject* GetArrayItem(Dart_CObject* message, intptr_t index) {
+  return message->value.as_array.values[index];
+}
+
+void DartDevIsolate::DartDevRunner::DartDevResultCallback(
+    Dart_Port dest_port_id,
+    Dart_CObject* message) {
+  // These messages are produced in pkg/dartdev/lib/src/vm_interop_handler.dart.
+  ASSERT(message->type == Dart_CObject_kArray);
+  int32_t type = GetArrayItem(message, 0)->value.as_int32;
+  switch (type) {
+    case DartDevIsolate::DartDev_Result_Run: {
+      result_ = DartDevIsolate::DartDev_Result_Run;
+      ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
+      auto item2 = GetArrayItem(message, 2);
+
+      ASSERT(item2->type == Dart_CObject_kString ||
+             item2->type == Dart_CObject_kNull);
+
+      auto item3 = GetArrayItem(message, 3);
+
+      ASSERT(item3->type == Dart_CObject_kBool);
+      const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
+      if (mark_main_isolate_as_system_isolate) {
+        Options::set_mark_main_isolate_as_system_isolate(true);
+      }
+
+      if (*script_ != nullptr) {
+        free(*script_);
+      }
+      if (*package_config_override_ != nullptr) {
+        free(*package_config_override_);
+        *package_config_override_ = nullptr;
+      }
+      *script_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
+
+      if (item2->type == Dart_CObject_kString) {
+        *package_config_override_ = Utils::StrDup(item2->value.as_string);
+      }
+
+      ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
+      Dart_CObject* args = GetArrayItem(message, 4);
+      argc_ = args->value.as_array.length;
+      Dart_CObject** dart_args = args->value.as_array.values;
+
+      auto deleter = [](char** args) {
+        for (intptr_t i = 0; i < argc_; ++i) {
+          free(args[i]);
+        }
+        delete[] args;
+      };
+      argv_ =
+          std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_], deleter);
+      for (intptr_t i = 0; i < argc_; ++i) {
+        argv_[i] = Utils::StrDup(dart_args[i]->value.as_string);
+      }
+      break;
+    }
+    case DartDevIsolate::DartDev_Result_RunExec: {
+      result_ = DartDevIsolate::DartDev_Result_RunExec;
+      ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kString);
+      auto item2 = GetArrayItem(message, 2);
+
+      ASSERT(item2->type == Dart_CObject_kString ||
+             item2->type == Dart_CObject_kNull);
+
+      auto item3 = GetArrayItem(message, 3);
+
+      ASSERT(item3->type == Dart_CObject_kBool);
+      const bool mark_main_isolate_as_system_isolate = item3->value.as_bool;
+      if (mark_main_isolate_as_system_isolate) {
+        Options::set_mark_main_isolate_as_system_isolate(true);
+      }
+
+      if (*script_ != nullptr) {
+        free(*script_);
+      }
+      if (*package_config_override_ != nullptr) {
+        free(*package_config_override_);
+        *package_config_override_ = nullptr;
+      }
+      *script_ = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
+
+      if (item2->type == Dart_CObject_kString) {
+        *package_config_override_ = Utils::StrDup(item2->value.as_string);
+      }
+
+      intptr_t num_vm_options = 0;
+      const char** vm_options = nullptr;
+      ASSERT(GetArrayItem(message, 4)->type == Dart_CObject_kArray);
+      Dart_CObject* args = GetArrayItem(message, 4);
+      intptr_t argc = args->value.as_array.length;
+      Dart_CObject** dart_args = args->value.as_array.values;
+
+      if (vm_options_ != nullptr) {
+        num_vm_options = vm_options_->count();
+        vm_options = vm_options_->arguments();
+      }
+      auto deleter = [](char** args) {
+        for (intptr_t i = 0; i < argc_; ++i) {
+          free(args[i]);
+        }
+        delete[] args;
+      };
+      // Total count of arguments to be passed to the script being execed.
+      argc_ = argc + num_vm_options + 1;
+
+      // Array of arguments to be passed to the script being execed.
+      argv_ = std::unique_ptr<char*[], void (*)(char**)>(new char*[argc_ + 1],
+                                                         deleter);
+
+      intptr_t idx = 0;
+      // Copy in name of the script to run (dartaotruntime).
+      argv_[0] = Utils::StrDup(GetArrayItem(message, 1)->value.as_string);
+      idx += 1;
+      // Copy in any vm options that need to be passed to the execed process.
+      for (intptr_t i = 0; i < num_vm_options; ++i) {
+        argv_[i + idx] = Utils::StrDup(vm_options[i]);
+      }
+      idx += num_vm_options;
+      // Copy in the dart options that need to be passed to the command.
+      for (intptr_t i = 0; i < argc; ++i) {
+        argv_[i + idx] = Utils::StrDup(dart_args[i]->value.as_string);
+      }
+      // Null terminate the argv array.
+      argv_[argc + idx] = nullptr;
+
+      // Exec the script to be run and pass the arguments.
+      char err_msg[256];
+      err_msg[0] = '\0';
+      int ret = Process::Exec(nullptr, *script_,
+                              const_cast<const char**>(argv_.get()), argc_,
+                              nullptr, err_msg, sizeof(err_msg));
+      if (ret != 0) {
+        ProcessError(err_msg, kErrorExitCode);
+      }
+      break;
+    }
+    case DartDevIsolate::DartDev_Result_Exit: {
+      ASSERT(GetArrayItem(message, 1)->type == Dart_CObject_kInt32);
+      int32_t dartdev_exit_code = GetArrayItem(message, 1)->value.as_int32;
+
+      // If we're given a non-zero exit code, DartDev is signaling for us to
+      // shutdown.
+      int32_t exit_code =
+          print_usage_error_ ? kErrorExitCode : dartdev_exit_code;
+      Process::SetGlobalExitCode(exit_code);
+
+      // If DartDev hasn't signaled for us to do anything else, we can assume
+      // there's nothing else for the VM to run and that we can exit.
+      if (result_ == DartDevIsolate::DartDev_Result_Unknown) {
+        result_ = DartDevIsolate::DartDev_Result_Exit;
+      }
+
+      // DartDev is done processing the command. Unblock the main thread and
+      // continue the launch procedure.
+      DartDevRunner::monitor_->Notify();
+      break;
+    }
+    default:
+      UNREACHABLE();
+  }
+}
+
+void DartDevIsolate::DartDevRunner::RunCallback(uword args) {
+  MonitorLocker locker_(DartDevRunner::monitor_);
+  DartDevRunner* runner = reinterpret_cast<DartDevRunner*>(args);
+
+  // Hardcode flags to match those used to generate the DartDev snapshot.
+  Dart_IsolateFlags flags;
+  Dart_IsolateFlagsInitialize(&flags);
+  flags.enable_asserts = false;
+  flags.use_field_guards = true;
+  flags.use_osr = true;
+  flags.is_system_isolate = true;
+  flags.branch_coverage = true;
+  flags.coverage = false;
+
+  char* error = nullptr;
+  Dart_Isolate dartdev_isolate = runner->create_isolate_(
+      DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, nullptr,
+      runner->packages_file_, &flags, /* callback_data */ nullptr,
+      const_cast<char**>(&error));
+
+  if (dartdev_isolate == nullptr) {
+    ProcessError(error, kErrorExitCode);
+    free(error);
+    return;
+  }
+
+  Dart_EnterIsolate(dartdev_isolate);
+  Dart_EnterScope();
+
+  // Retrieve the DartDev entrypoint.
+  Dart_Port send_port_id = ILLEGAL_PORT;
+  Dart_Handle root_lib = Dart_RootLibrary();
+  Dart_Handle main_closure =
+      Dart_GetField(root_lib, Dart_NewStringFromCString("main"));
+  CHECK_RESULT(main_closure);
+
+  if (!Dart_IsClosure(main_closure)) {
+    ProcessError("Unable to find 'main' in root library 'dartdev'",
+                 kErrorExitCode);
+    Dart_ExitScope();
+    Dart_ShutdownIsolate();
+    return;
+  }
+
+  // Create a SendPort that DartDev can use to communicate its results over.
+  send_port_id =
+      Dart_NewNativePort(DART_DEV_ISOLATE_NAME, DartDevResultCallback, false);
+  ASSERT(send_port_id != ILLEGAL_PORT);
+  Dart_Handle send_port = Dart_NewSendPort(send_port_id);
+  CHECK_RESULT(send_port);
+
+  const intptr_t kNumIsolateArgs = 4;
+  Dart_Handle isolate_args[kNumIsolateArgs];
+  isolate_args[0] = main_closure;  // entryPoint
+  isolate_args[1] = runner->dart_options_->CreateRuntimeOptions();  // args
+  isolate_args[2] = send_port;                                      // message
+  isolate_args[3] = Dart_True();  // isSpawnUri
+
+  Dart_Handle isolate_lib =
+      Dart_LookupLibrary(Dart_NewStringFromCString("dart:isolate"));
+  Dart_Handle result =
+      Dart_Invoke(isolate_lib, Dart_NewStringFromCString("_startIsolate"),
+                  kNumIsolateArgs, isolate_args);
+  CHECK_RESULT(result);
+  CHECK_RESULT(Dart_RunLoop());
+
+  Dart_CloseNativePort(send_port_id);
+
+  Dart_ExitScope();
+  Dart_ShutdownIsolate();
+}
+
+void DartDevIsolate::DartDevRunner::ProcessError(const char* msg,
+                                                 int32_t exit_code) {
+  Syslog::PrintErr("%s.\n", msg);
+  Process::SetGlobalExitCode(exit_code);
+  result_ = DartDevIsolate::DartDev_Result_Exit;
+  DartDevRunner::monitor_->Notify();
+}
+
+DartDevIsolate::DartDev_Result DartDevIsolate::RunDartDev(
+    Dart_IsolateGroupCreateCallback create_isolate,
+    char** packages_file,
+    char** script,
+    CommandLineOptions* vm_options,
+    CommandLineOptions* dart_options) {
+  vm_options_ = vm_options;
+  runner_.Run(create_isolate, packages_file, script, dart_options);
+  return runner_.result();
+}
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/bin/dartdev_isolate.h b/runtime/bin/dartdev_isolate.h
new file mode 100644
index 0000000..c5e476d
--- /dev/null
+++ b/runtime/bin/dartdev_isolate.h
@@ -0,0 +1,118 @@
+// 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.
+
+#ifndef RUNTIME_BIN_DARTDEV_ISOLATE_H_
+#define RUNTIME_BIN_DARTDEV_ISOLATE_H_
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+#include <memory>
+
+#include "bin/thread.h"
+#include "include/dart_api.h"
+#include "include/dart_native_api.h"
+#include "platform/globals.h"
+#include "platform/utils.h"
+
+#define DART_DEV_ISOLATE_NAME "dartdev"
+
+namespace dart {
+namespace bin {
+
+class CommandLineOptions;
+
+class DartDevIsolate {
+ public:
+  // Note: keep in sync with pkg/dartdev/lib/vm_interop_handler.dart
+  typedef enum {
+    DartDev_Result_Unknown = -1,
+    DartDev_Result_Run = 1,
+    DartDev_Result_RunExec = 2,
+    DartDev_Result_Exit = 3,
+  } DartDev_Result;
+
+  // Returns true if there does not exist a file at |script_uri| or the URI is
+  // not an HTTP resource.
+  static bool ShouldParseCommand(const char* script_uri);
+
+  // Returns true if VM options need to be recorded and passed to the VM
+  // that executes the command (this is true only for dart CL commands like
+  // 'run' and 'test'.
+  static bool ShouldParseVMOptions(const char* command);
+
+  static void set_should_run_dart_dev(bool enable) {
+    should_run_dart_dev_ = enable;
+  }
+
+  static void PrintUsageErrorOnRun() {
+    set_should_run_dart_dev(true);
+    print_usage_error_ = true;
+  }
+
+  static bool should_run_dart_dev() { return should_run_dart_dev_; }
+
+  // Attempts to find the path of the DartDev snapshot.
+  static CStringUniquePtr TryResolveDartDevSnapshotPath();
+
+  // Starts a DartDev instance in a new isolate and runs it to completion.
+  //
+  // Returns true if the VM should run the result in `script`, in which case
+  // `script` and `dart_options` will have been repopulated with the correct
+  // values.
+  static DartDev_Result RunDartDev(
+      Dart_IsolateGroupCreateCallback create_isolate,
+      char** packages_file,
+      char** script,
+      CommandLineOptions* vm_options,
+      CommandLineOptions* dart_options);
+
+ protected:
+  class DartDevRunner {
+   public:
+    DartDevRunner() {}
+
+    void Run(Dart_IsolateGroupCreateCallback create_isolate,
+             char** package_config_override_,
+             char** script,
+             CommandLineOptions* dart_options);
+
+    DartDev_Result result() const { return result_; }
+
+   private:
+    static void DartDevResultCallback(Dart_Port dest_port_id,
+                                      Dart_CObject* message);
+    static void RunCallback(uword arg);
+    static void ProcessError(const char* msg, int32_t exit_code);
+
+    static DartDev_Result result_;
+    static char** script_;
+    static char** package_config_override_;
+    static std::unique_ptr<char*[], void (*)(char**)> argv_;
+    static intptr_t argc_;
+    static Monitor* monitor_;
+
+    Dart_IsolateGroupCreateCallback create_isolate_;
+    CommandLineOptions* dart_options_;
+    const char* packages_file_;
+
+    DISALLOW_ALLOCATION();
+  };
+
+ private:
+  static CStringUniquePtr TryResolveArtifactPath(const char* filename);
+
+  static DartDevRunner runner_;
+  static bool should_run_dart_dev_;
+  static bool print_usage_error_;
+  static CommandLineOptions* vm_options_;
+
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(DartDevIsolate);
+};
+
+}  // namespace bin
+}  // namespace dart
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+#endif  // RUNTIME_BIN_DARTDEV_ISOLATE_H_
diff --git a/runtime/bin/dartdev_options.cc b/runtime/bin/dartdev_options.cc
deleted file mode 100644
index 5a9a144..0000000
--- a/runtime/bin/dartdev_options.cc
+++ /dev/null
@@ -1,378 +0,0 @@
-// Copyright (c) 2025, 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.
-
-#include "bin/dartdev_options.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "bin/common_options.h"
-#include "bin/error_exit.h"
-#include "bin/file_system_watcher.h"
-#include "bin/platform.h"
-#include "bin/socket.h"
-#include "bin/utils.h"
-#include "include/dart_api.h"
-#include "platform/assert.h"
-#include "platform/globals.h"
-#include "platform/hashmap.h"
-#include "platform/syslog.h"
-
-namespace dart {
-namespace bin {
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-
-static bool PotentialDartdevCommand(const char* script_uri) {
-  // If script_uri is a known DartDev command, we should not try to run it.
-  //
-  // Otherwise if script_uri is not a file path or of a known URI scheme, we
-  // assume this is a mistyped DartDev command.
-  //
-  // This should be kept in sync with the commands in
-  // `pkg/dartdev/lib/dartdev.dart`.
-  return (
-      (strcmp(script_uri, "analyze") == 0) ||
-      (strcmp(script_uri, "compilation-server") == 0) ||
-      (strcmp(script_uri, "build") == 0) ||
-      (strcmp(script_uri, "compile") == 0) ||
-      (strcmp(script_uri, "create") == 0) ||
-      (strcmp(script_uri, "development-service") == 0) ||
-      (strcmp(script_uri, "devtools") == 0) ||
-      (strcmp(script_uri, "doc") == 0) || (strcmp(script_uri, "fix") == 0) ||
-      (strcmp(script_uri, "format") == 0) ||
-      (strcmp(script_uri, "info") == 0) ||
-      (strcmp(script_uri, "mcp-server") == 0) ||
-      (strcmp(script_uri, "pub") == 0) || (strcmp(script_uri, "run") == 0) ||
-      (strcmp(script_uri, "test") == 0) || (strcmp(script_uri, "info") == 0) ||
-      (strcmp(script_uri, "language-server") == 0) ||
-      (strcmp(script_uri, "tooling-daemon") == 0) ||
-      (!File::ExistsUri(nullptr, script_uri) &&
-       (strncmp(script_uri, "http://", 7) != 0) &&
-       (strncmp(script_uri, "https://", 8) != 0) &&
-       (strncmp(script_uri, "file://", 7) != 0) &&
-       (strncmp(script_uri, "package:", 8) != 0) &&
-       (strncmp(script_uri, "google3://", 10) != 0)));
-}
-
-#define OPTION_FIELD(variable) Options::variable##_
-
-#define STRING_OPTION_DEFINITION(name, variable)                               \
-  const char* OPTION_FIELD(variable) = nullptr;                                \
-  DEFINE_STRING_OPTION(name, OPTION_FIELD(variable))
-STRING_OPTIONS_LIST(STRING_OPTION_DEFINITION)
-#undef STRING_OPTION_DEFINITION
-
-#define BOOL_OPTION_DEFINITION(name, variable)                                 \
-  bool OPTION_FIELD(variable) = false;                                         \
-  DEFINE_BOOL_OPTION(name, OPTION_FIELD(variable))
-BOOL_OPTIONS_LIST(BOOL_OPTION_DEFINITION)
-#undef BOOL_OPTION_DEFINITION
-
-#define SHORT_BOOL_OPTION_DEFINITION(short_name, long_name, variable)          \
-  bool OPTION_FIELD(variable) = false;                                         \
-  DEFINE_BOOL_OPTION_SHORT(short_name, long_name, OPTION_FIELD(variable))
-SHORT_BOOL_OPTIONS_LIST(SHORT_BOOL_OPTION_DEFINITION)
-#undef SHORT_BOOL_OPTION_DEFINITION
-
-#define CB_OPTION_DEFINITION(callback)                                         \
-  static bool callback##Helper(const char* arg, CommandLineOptions* o) {       \
-    return Options::callback(arg, o);                                          \
-  }                                                                            \
-  DEFINE_CB_OPTION(callback##Helper)
-CB_OPTIONS_LIST(CB_OPTION_DEFINITION)
-#undef CB_OPTION_DEFINITION
-
-// Explicitly handle VM flags that can be parsed by DartDev's run command.
-bool Options::ProcessVMOptions(const char* arg,
-                               CommandLineOptions* vm_options) {
-#define IS_VM_OPTION(name, arg)                                                \
-  if (OptionProcessor::ProcessOption(arg, name) != nullptr) {                  \
-    vm_options->AddArgument(arg);                                              \
-    return true;                                                               \
-  }
-
-// This is an exhaustive set of VM flags that are accepted by 'dart run' and
-// 'dart test' commands, these options need to be collected and passed to
-// the dart VM process that is going to run the command.
-//
-// NOTE: When updating this list of VM flags, be sure to make the corresponding
-// changes in pkg/dartdev/lib/src/commands/run.dart.
-#define HANDLE_DARTDEV_VM_OPTIONS(V, arg)                                      \
-  V("--enable-asserts", arg)                                                   \
-  V("--pause-isolates-on-exit", arg)                                           \
-  V("--no-pause-isolates-on-exit", arg)                                        \
-  V("--pause-isolates-on-start", arg)                                          \
-  V("--no-pause-isolates-on-start", arg)                                       \
-  V("--pause-isolates-on-unhandled-exception", arg)                            \
-  V("--no-pause-isolates-on-unhandled-exception", arg)                         \
-  V("--warn-on-pause-with-no-debugger", arg)                                   \
-  V("--no-warn-on-pause-with-no-debugger", arg)                                \
-  V("--timeline-streams", arg)                                                 \
-  V("--timeline-recorder", arg)                                                \
-  V("--dds", arg)                                                              \
-  V("--no-dds", arg)                                                           \
-  V("--profiler", arg)                                                         \
-  V("--disable-service-auth-codes", arg)                                       \
-  V("--write-service-info", arg)                                               \
-  V("--enable-service-port-fallback", arg)                                     \
-  V("--disable-service-auth-codes", arg)                                       \
-  V("--serve-observatory", arg)                                                \
-  V("--print-dtd", arg)                                                        \
-  V("--packages", arg)                                                         \
-  V("--resident", arg)                                                         \
-  V("--resident-server-info-file", arg)                                        \
-  V("--resident-compiler-info-file", arg)                                      \
-  V("--observe", arg)                                                          \
-  V("--enable-vm-service", arg)                                                \
-  V("--serve-devtools", arg)                                                   \
-  V("--no-serve-devtools", arg)                                                \
-  V("--serve-observatory", arg)                                                \
-  V("--no-serve-observatory", arg)                                             \
-  V("--profile-microtasks", arg)                                               \
-  V("--enable-experiment", arg)
-  HANDLE_DARTDEV_VM_OPTIONS(IS_VM_OPTION, arg);
-
-#undef IS_VM_OPTION
-#undef HANDLE_DARTDEV_VM_OPTIONS
-
-  return false;
-}
-
-bool Options::ParseDartDevArguments(int argc,
-                                    char** argv,
-                                    CommandLineOptions* vm_options,
-                                    CommandLineOptions* dart_vm_options,
-                                    CommandLineOptions* dart_options,
-                                    bool* skip_dartdev) {
-  // First figure out if a dartdev command has been explicitly specified.
-  *skip_dartdev = false;
-  int tmp_i = 1;
-  while (tmp_i < argc) {
-    // Check if this flag is a potentially valid VM flag, we skip over all
-    // VM flags until we see a command or a script file.
-    if (!OptionProcessor::IsValidFlag(argv[tmp_i]) &&
-        !OptionProcessor::IsValidShortFlag(argv[tmp_i])) {
-      break;
-    }
-    tmp_i++;
-  }
-  if (tmp_i < argc) {
-    // Check if we have a dartdev command.
-    if (!PotentialDartdevCommand(argv[tmp_i])) {
-      // We don't have a dartdev command so skip dartdev and execute the
-      // script directly.
-      *skip_dartdev = true;
-      return true;
-    }
-  }
-
-  bool enable_dartdev_analytics = false;
-  bool disable_dartdev_analytics = false;
-  char* packages_argument = nullptr;
-
-  // First parse out the vm options into dart_vm_options so that it can be
-  // passed down to the 'run' and 'test' commands.
-  // Start processing arguments after argv[0] which would be the executable.
-  int i = 1;
-  while (i < argc) {
-    bool skipVmOption = false;
-    if (!OptionProcessor::TryProcess(argv[i], dart_vm_options)) {
-      // Check if this flag is a potentially valid VM flag.
-      if (!OptionProcessor::IsValidFlag(argv[i])) {
-        break;
-      }
-      // The following flags are processed as DartDev flags and are not to
-      // be treated as if they are VM flags.
-      if (IsOption(argv[i], "enable-analytics")) {
-        enable_dartdev_analytics = true;
-        skipVmOption = true;
-      } else if (IsOption(argv[i], "disable-analytics")) {
-        disable_dartdev_analytics = true;
-        skipVmOption = true;
-      } else if (IsOption(argv[i], "disable-telemetry")) {
-        disable_dartdev_analytics = true;
-        skipVmOption = true;
-      } else if (IsOption(argv[i], "suppress-analytics")) {
-        dart_options->AddArgument("--suppress-analytics");
-        skipVmOption = true;
-      } else if (IsOption(argv[i], "no-analytics")) {
-        // Just add this option even if we don't go to dartdev.
-        // It is irrelevant for the vm.
-        dart_options->AddArgument("--no-analytics");
-        skipVmOption = true;
-      } else if (IsOption(argv[i], "serve-observatory")) {
-        // This flag is currently set by default in vmservice_io.dart, so we
-        // ignore it. --no-serve-observatory is a VM flag so we don't need to
-        // handle that case here.
-        skipVmOption = true;
-      } else if (IsOption(argv[i], "print-dtd-uri")) {
-        skipVmOption = true;
-      } else if (IsOption(argv[i], "executable-name")) {
-        skipVmOption = true;
-      } else if (IsOption(argv[i], "enable-experiment")) {
-        dart_options->AddArgument(argv[i]);
-      }
-    }
-    if (!skipVmOption) {
-      dart_vm_options->AddArgument(argv[i]);
-    }
-    if (IsOption(argv[i], "packages")) {
-      packages_argument = argv[i];
-    }
-    i++;
-  }
-
-  // The arguments to the VM are at positions 1 through i-1 in argv.
-  Platform::SetExecutableArguments(i, argv);
-
-  // If we have exhausted all the arguments and haven't see a dartdev
-  // command then we set up some scenarios where it still makes sense
-  // to start up dartdev and have it process the options.
-  if (i >= argc) {
-    // Handles following invocation arguments:
-    //   - dart help
-    //   - dart --help
-    //   - dart
-    if (((Options::help_option() && !Options::verbose_option()) ||
-         (argc == 1))) {
-      // Let DartDev handle the default help message.
-      dart_options->AddArgument("help");
-      return true;
-    }
-    // Handles cases where only analytics flags are provided. We need to launch
-    // DartDev for this.
-    else if (enable_dartdev_analytics || disable_dartdev_analytics) {  // NOLINT
-      // The analytics flags are a special case as we don't have a target script
-      // or DartDev command but we still want to launch DartDev.
-      dart_options->AddArgument(enable_dartdev_analytics
-                                    ? "--enable-analytics"
-                                    : "--disable-analytics");
-      return true;
-    }
-    // If it is not '--version' and '--help' we will launch DartDev
-    // to print its help message and set an error exit code.
-    else if (!Options::help_option() && !Options::version_option()) {  // NOLINT
-      // Pass in an invalid option so that dartdev prints the help message
-      // and exits with an error exit code.
-      dart_options->Reset();
-      dart_options->AddArgument(argv[argc - 1]);
-      dart_options->AddArgument("help");
-      return true;
-    }
-    return false;
-  }
-
-  USE(enable_dartdev_analytics);
-  USE(disable_dartdev_analytics);
-  USE(packages_argument);
-
-  // Record the dartdev command.
-  dart_options->AddArgument(argv[i++]);
-
-  // Bring any --packages option into the dartdev command
-  if (packages_argument != nullptr) {
-    dart_options->AddArgument(packages_argument);
-    dart_vm_options->AddArgument(packages_argument);
-  }
-
-  // Scan remaining arguments and separate them into
-  // dart_vm_options (vm options to be passed to the dart process executing
-  // the dartdev command) or dart_options (options to be passed to the
-  // executing dart script).
-  bool script_seen = false;
-  while (i < argc) {
-    if (!IsOption(argv[i], "disable-dart-dev")) {
-      if (!script_seen) {
-        // We scan for VM options that are passed to the 'run' and 'test'
-        // command. These options are accepted by both the VM and dartdev
-        // commands and need to be carried over to the VM running the app for
-        // these commands.
-        if (Options::ProcessVMOptions(argv[i], dart_vm_options)) {
-          // dartdev isn't able to parse these options properly. Since it
-          // doesn't need to use the values from these options, just strip them
-          // from the argument list passed to dartdev.
-          if (!IsOption(argv[i], "observe") &&
-              !IsOption(argv[i], "enable-vm-service")) {
-            dart_options->AddArgument(argv[i]);
-          }
-        } else {
-          if (!OptionProcessor::IsValidFlag(argv[i]) &&
-              !OptionProcessor::IsValidShortFlag(argv[i])) {
-            script_seen = true;
-          }
-          dart_options->AddArgument(argv[i]);
-        }
-      } else {
-        dart_options->AddArgument(argv[i]);
-      }
-    } else {
-      Syslog::PrintErr(
-          "Attempted to use --disable-dart-dev with a Dart CLI command.\n");
-      return false;
-    }
-    i++;
-  }
-
-  // Store the executable name.
-  Platform::SetExecutableName(argv[0]);
-
-  // Verify consistency of arguments.
-  if ((packages_file_ != nullptr) && (strlen(packages_file_) == 0)) {
-    Syslog::PrintErr("Empty package file name specified.\n");
-    return false;
-  }
-
-  return true;
-}
-
-void Options::PrintVersion() {
-  _PrintVersion();
-}
-
-// clang-format off
-void Options::PrintUsage() {
-  _PrintUsage();
-  if (!Options::verbose_option()) {
-    _PrintNonVerboseUsage();
-  } else {
-    _PrintVerboseUsage();
-  }
-}
-// clang-format on
-
-dart::SimpleHashMap* Options::environment_ = nullptr;
-bool Options::ProcessEnvironmentOption(const char* arg,
-                                       CommandLineOptions* vm_options) {
-  return OptionProcessor::ProcessEnvironmentOption(arg, vm_options,
-                                                   &Options::environment_);
-}
-
-void Options::Cleanup() {
-  DestroyEnvironment();
-}
-
-void Options::DestroyEnvironment() {
-  if (environment_ != nullptr) {
-    for (SimpleHashMap::Entry* p = environment_->Start(); p != nullptr;
-         p = environment_->Next(p)) {
-      free(p->key);
-      free(p->value);
-    }
-    delete environment_;
-    environment_ = nullptr;
-  }
-}
-
-char** Options::GetEnvArguments(int* argc) {
-  return nullptr;
-}
-
-void Options::DestroyEnvArgv() {}
-
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-}  // namespace bin
-}  // namespace dart
diff --git a/runtime/bin/dartdev_options.h b/runtime/bin/dartdev_options.h
deleted file mode 100644
index 912fa7f..0000000
--- a/runtime/bin/dartdev_options.h
+++ /dev/null
@@ -1,140 +0,0 @@
-// Copyright (c) 2025, 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.
-
-#ifndef RUNTIME_BIN_DARTDEV_OPTIONS_H_
-#define RUNTIME_BIN_DARTDEV_OPTIONS_H_
-
-#include "bin/dartutils.h"
-#include "bin/options.h"
-#include "platform/globals.h"
-#include "platform/growable_array.h"
-#include "platform/hashmap.h"
-
-namespace dart {
-namespace bin {
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-
-// A list of options taking string arguments. Organized as:
-//   V(flag_name, field_name)
-// The value of the flag can then be accessed with Options::field_name().
-#define STRING_OPTIONS_LIST(V)                                                 \
-  V(packages, packages_file)                                                   \
-  V(namespace, namespc)
-
-// As STRING_OPTIONS_LIST but for boolean valued options. The default value is
-// always false, and the presence of the flag switches the value to true.
-#define BOOL_OPTIONS_LIST(V)                                                   \
-  V(disable_exit, exit_disabled)                                               \
-  V(version, version_option)                                                   \
-  V(suppress_core_dump, suppress_core_dump)
-
-// Boolean flags that have a short form.
-#define SHORT_BOOL_OPTIONS_LIST(V)                                             \
-  V(h, help, help_option)                                                      \
-  V(v, verbose, verbose_option)
-
-// Callbacks passed to DEFINE_CB_OPTION().
-#define CB_OPTIONS_LIST(V)                                                     \
-  V(ProcessEnvironmentOption)                                                  \
-  V(ProcessVMOptions)
-
-enum VerbosityLevel {
-  kError,
-  kWarning,
-  kInfo,
-  kAll,
-};
-
-static const char* const kVerbosityLevelNames[] = {
-    "error", "warning", "info", "all", nullptr,
-};
-
-class Options {
- public:
-  // Returns true if argument parsing succeeded. False otherwise.
-  static bool ParseDartDevArguments(int argc,
-                                    char** argv,
-                                    CommandLineOptions* vm_options,
-                                    CommandLineOptions* dart_vm_options,
-                                    CommandLineOptions* dart_options,
-                                    bool* skip_dartdev);
-
-#define STRING_OPTION_GETTER(flag, variable)                                   \
-  static const char* variable() { return variable##_; }
-  STRING_OPTIONS_LIST(STRING_OPTION_GETTER)
-#undef STRING_OPTION_GETTER
-
-#define BOOL_OPTION_GETTER(flag, variable)                                     \
-  static bool variable() { return variable##_; }
-  BOOL_OPTIONS_LIST(BOOL_OPTION_GETTER)
-#undef BOOL_OPTION_GETTER
-
-#define SHORT_BOOL_OPTION_GETTER(short_name, long_name, variable)              \
-  static bool variable() { return variable##_; }
-  SHORT_BOOL_OPTIONS_LIST(SHORT_BOOL_OPTION_GETTER)
-#undef SHORT_BOOL_OPTION_GETTER
-
-// Callbacks have to be public.
-#define CB_OPTIONS_DECL(callback)                                              \
-  static bool callback(const char* arg, CommandLineOptions* vm_options);
-  CB_OPTIONS_LIST(CB_OPTIONS_DECL)
-#undef CB_OPTIONS_DECL
-
-  static dart::SimpleHashMap* environment() { return environment_; }
-
-  static void PrintUsage();
-  static void PrintVersion();
-
-  static void Cleanup();
-
-#if defined(DART_PRECOMPILED_RUNTIME)
-  // Get the list of options in DART_VM_OPTIONS.
-  static char** GetEnvArguments(int* argc);
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
- private:
-  static void DestroyEnvironment();
-#if defined(DART_PRECOMPILED_RUNTIME)
-  static void DestroyEnvArgv();
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-#define STRING_OPTION_DECL(flag, variable) static const char* variable##_;
-  STRING_OPTIONS_LIST(STRING_OPTION_DECL)
-#undef STRING_OPTION_DECL
-
-#define BOOL_OPTION_DECL(flag, variable) static bool variable##_;
-  BOOL_OPTIONS_LIST(BOOL_OPTION_DECL)
-#undef BOOL_OPTION_DECL
-
-#define SHORT_BOOL_OPTION_DECL(short_name, long_name, variable)                \
-  static bool variable##_;
-  SHORT_BOOL_OPTIONS_LIST(SHORT_BOOL_OPTION_DECL)
-#undef SHORT_BOOL_OPTION_DECL
-
-  static dart::SimpleHashMap* environment_;
-
-  static char** env_argv_;
-  static int env_argc_;
-
-#define OPTION_FRIEND(flag, variable) friend class OptionProcessor_##flag;
-  STRING_OPTIONS_LIST(OPTION_FRIEND)
-  BOOL_OPTIONS_LIST(OPTION_FRIEND)
-#undef OPTION_FRIEND
-
-#define SHORT_BOOL_OPTION_FRIEND(short_name, long_name, variable)              \
-  friend class OptionProcessor_##long_name;
-  SHORT_BOOL_OPTIONS_LIST(SHORT_BOOL_OPTION_FRIEND)
-#undef SHORT_BOOL_OPTION_FRIEND
-
-  DISALLOW_ALLOCATION();
-  DISALLOW_IMPLICIT_CONSTRUCTORS(Options);
-};
-
-#endif  // defined(DART_PRECOMPILED_RUNTIME)
-
-}  // namespace bin
-}  // namespace dart
-
-#endif  // RUNTIME_BIN_DARTDEV_OPTIONS_H_
diff --git a/runtime/bin/main_impl.cc b/runtime/bin/main_impl.cc
index 656205d..2e4d3c6 100644
--- a/runtime/bin/main_impl.cc
+++ b/runtime/bin/main_impl.cc
@@ -15,6 +15,7 @@
 #include "bin/builtin.h"
 #include "bin/console.h"
 #include "bin/crashpad.h"
+#include "bin/dartdev_isolate.h"
 #include "bin/dartutils.h"
 #include "bin/dfe.h"
 #include "bin/error_exit.h"
@@ -390,6 +391,17 @@
     CHECK_RESULT(result);
   }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  // Disable pausing the DartDev isolate on start and exit.
+  const char* isolate_name = nullptr;
+  result = Dart_StringToCString(Dart_DebugName(), &isolate_name);
+  CHECK_RESULT(result);
+  if (strstr(isolate_name, DART_DEV_ISOLATE_NAME) != nullptr) {
+    Dart_SetShouldPauseOnStart(false);
+    Dart_SetShouldPauseOnExit(false);
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 #if !defined(DART_PRECOMPILER)
   NativeAssetsApi native_assets;
   memset(&native_assets, 0, sizeof(native_assets));
@@ -562,7 +574,7 @@
   CHECK_RESULT(result);
 
   // We do not spawn the external dds process if DDS is explicitly disabled.
-  bool wait_for_dds_to_advertise_service = Options::enable_dds();
+  bool wait_for_dds_to_advertise_service = !Options::disable_dds();
   bool serve_devtools =
       Options::enable_devtools() || !Options::disable_devtools();
   // Load embedder specific bits and return.
@@ -594,6 +606,99 @@
 #endif  // !defined(PRODUCT)
 }
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+
+static Dart_Isolate CreateAndSetupDartDevIsolate(const char* script_uri,
+                                                 const char* packages_config,
+                                                 Dart_IsolateFlags* flags,
+                                                 char** error,
+                                                 int* exit_code) {
+  int64_t start = Dart_TimelineGetMicros();
+
+  auto dartdev_path = DartDevIsolate::TryResolveDartDevSnapshotPath();
+  if (dartdev_path.get() == nullptr) {
+    Syslog::PrintErr(
+        "Failed to start the Dart CLI isolate. Could not resolve DartDev "
+        "snapshot or kernel.\n");
+    if (error != nullptr && *error != nullptr) {
+      free(*error);
+      *error = nullptr;
+    }
+    return nullptr;
+  }
+
+  Dart_Isolate isolate = nullptr;
+  const uint8_t* isolate_snapshot_data = core_isolate_snapshot_data;
+  const uint8_t* isolate_snapshot_instructions =
+      core_isolate_snapshot_instructions;
+  IsolateGroupData* isolate_group_data = nullptr;
+  IsolateData* isolate_data = nullptr;
+  AppSnapshot* app_snapshot = nullptr;
+  bool isolate_run_app_snapshot = true;
+  // dartdev isolate uses an app JIT snapshot or uses the dill file.
+  if (((app_snapshot = Snapshot::TryReadAppSnapshot(
+            dartdev_path.get(), /*force_load_from_memory=*/false,
+            /*decode_uri=*/false)) != nullptr) &&
+      app_snapshot->IsJIT()) {
+    const uint8_t* isolate_snapshot_data = nullptr;
+    const uint8_t* isolate_snapshot_instructions = nullptr;
+    const uint8_t* ignore_vm_snapshot_data;
+    const uint8_t* ignore_vm_snapshot_instructions;
+    app_snapshot->SetBuffers(
+        &ignore_vm_snapshot_data, &ignore_vm_snapshot_instructions,
+        &isolate_snapshot_data, &isolate_snapshot_instructions);
+    isolate_group_data = new IsolateGroupData(
+        DART_DEV_ISOLATE_NAME, /*asset_resolution_base=*/nullptr,
+        packages_config, app_snapshot, isolate_run_app_snapshot);
+    isolate_data = new IsolateData(isolate_group_data);
+    isolate = Dart_CreateIsolateGroup(
+        DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, isolate_snapshot_data,
+        isolate_snapshot_instructions, flags, isolate_group_data, isolate_data,
+        error);
+  }
+
+  if (isolate == nullptr) {
+    // dartdev_path was not an application snapshot, try it as a kernel file.
+    // Clear error from app snapshot and retry from kernel.
+    if (error != nullptr && *error != nullptr) {
+      free(*error);
+      *error = nullptr;
+    }
+    isolate_run_app_snapshot = false;
+    if (app_snapshot != nullptr) {
+      delete app_snapshot;
+    }
+    isolate_group_data =
+        new IsolateGroupData(DART_DEV_ISOLATE_NAME, nullptr, packages_config,
+                             nullptr, isolate_run_app_snapshot);
+    uint8_t* application_kernel_buffer = nullptr;
+    intptr_t application_kernel_buffer_size = 0;
+    dfe.ReadScript(dartdev_path.get(), nullptr, &application_kernel_buffer,
+                   &application_kernel_buffer_size, /*decode_uri=*/false);
+    isolate_group_data->SetKernelBufferNewlyOwned(
+        application_kernel_buffer, application_kernel_buffer_size);
+
+    isolate_data = new IsolateData(isolate_group_data);
+    isolate = Dart_CreateIsolateGroup(
+        DART_DEV_ISOLATE_NAME, DART_DEV_ISOLATE_NAME, isolate_snapshot_data,
+        isolate_snapshot_instructions, flags, isolate_group_data, isolate_data,
+        error);
+  }
+
+  Dart_Isolate created_isolate =
+      IsolateSetupHelper(isolate, false, DART_DEV_ISOLATE_NAME, packages_config,
+                         isolate_run_app_snapshot, flags, error, exit_code);
+
+  int64_t end = Dart_TimelineGetMicros();
+  Dart_RecordTimelineEvent("CreateAndSetupDartDevIsolate", start, end,
+                           /*flow_id_count=*/0, nullptr,
+                           Dart_Timeline_Event_Duration,
+                           /*argument_count=*/0, nullptr, nullptr);
+  return created_isolate;
+}
+
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 // Returns newly created Isolate on success, nullptr on failure.
 static Dart_Isolate CreateIsolateGroupAndSetupHelper(
     bool is_main_isolate,
@@ -852,6 +957,13 @@
   }
 #endif  // !defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM)
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  if (strcmp(script_uri, DART_DEV_ISOLATE_NAME) == 0) {
+    return CreateAndSetupDartDevIsolate(script_uri, package_config, flags,
+                                        error, &exit_code);
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
   if (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0) {
     return CreateAndSetupServiceIsolate(script_uri, package_config, flags,
                                         error, &exit_code);
@@ -1098,11 +1210,13 @@
 
   char* script_name = nullptr;
   CStringUniquePtr asset_resolution_base = CStringUniquePtr();
+  // Allows the dartdev process to point to the desired package_config.
   char* package_config_override = nullptr;
   const int EXTRA_VM_ARGUMENTS = 10;
   CommandLineOptions vm_options(argc + EXTRA_VM_ARGUMENTS);
   CommandLineOptions dart_options(argc + EXTRA_VM_ARGUMENTS);
   bool print_flags_seen = false;
+  bool verbose_debug_seen = false;
 
   // Perform platform specific initialization.
   if (!Platform::Initialize()) {
@@ -1134,36 +1248,39 @@
   }
   vm_options.AddArgument("--new_gen_growth_factor=4");
 
-  auto parse_arguments =
-      [&](int argc, char** argv, CommandLineOptions* vm_options,
-          CommandLineOptions* dart_options, bool parsing_dart_vm_options) {
-        bool success = Options::ParseArguments(
-            argc, argv, vm_run_app_snapshot, parsing_dart_vm_options,
-            vm_options, &script_name, dart_options, &print_flags_seen);
-        if (!success) {
-          if (Options::help_option()) {
-            Options::PrintUsage();
-            Platform::Exit(0);
-          } else if (Options::version_option()) {
-            Options::PrintVersion();
-            Platform::Exit(0);
-          } else if (print_flags_seen) {
-            // Will set the VM flags, print them out and then we exit as no
-            // script was specified on the command line.
-            char* error =
-                Dart_SetVMFlags(vm_options->count(), vm_options->arguments());
-            if (error != nullptr) {
-              Syslog::PrintErr("Setting VM flags failed: %s\n", error);
-              free(error);
-              Platform::Exit(kErrorExitCode);
-            }
-            Platform::Exit(0);
-          } else {
-            Options::PrintUsage();
-            Platform::Exit(kErrorExitCode);
-          }
+  auto parse_arguments = [&](int argc, char** argv,
+                             CommandLineOptions* vm_options,
+                             CommandLineOptions* dart_options,
+                             bool parsing_dart_vm_options) {
+    bool success = Options::ParseArguments(
+        argc, argv, vm_run_app_snapshot, parsing_dart_vm_options, vm_options,
+        &script_name, dart_options, &print_flags_seen, &verbose_debug_seen);
+    if (!success) {
+      if (Options::help_option()) {
+        Options::PrintUsage();
+        Platform::Exit(0);
+      } else if (Options::version_option()) {
+        Options::PrintVersion();
+        Platform::Exit(0);
+      } else if (print_flags_seen) {
+        // Will set the VM flags, print them out and then we exit as no
+        // script was specified on the command line.
+        char* error =
+            Dart_SetVMFlags(vm_options->count(), vm_options->arguments());
+        if (error != nullptr) {
+          Syslog::PrintErr("Setting VM flags failed: %s\n", error);
+          free(error);
+          Platform::Exit(kErrorExitCode);
         }
-      };
+        Platform::Exit(0);
+      } else {
+        // This usage error case will only be invoked when
+        // Options::disable_dart_dev() is false.
+        Options::PrintUsage();
+        Platform::Exit(kErrorExitCode);
+      }
+    }
+  };
 
   AppSnapshot* app_snapshot = nullptr;
 #if defined(DART_PRECOMPILED_RUNTIME)
@@ -1261,8 +1378,9 @@
     }
   };
 
-  // At this point, script_name now points to a script or a valid file path
-  // was provided as the first non-flag argument.
+  // At this point, script_name now points to a script if DartDev is disabled
+  // or a valid file path was provided as the first non-flag argument.
+  // Otherwise, script_name can be nullptr if DartDev should be run.
   if (script_name != nullptr) {
     if (!CheckForInvalidPath(script_name)) {
       Platform::Exit(0);
@@ -1366,21 +1484,36 @@
                                  &ServiceStreamCancelCallback);
   Dart_SetFileModifiedCallback(&FileModifiedCallback);
   Dart_SetEmbedderInformationCallback(&EmbedderInformationCallback);
+  bool ran_dart_dev = false;
   bool should_run_user_program = true;
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  if (script_name == nullptr &&
-      Options::gen_snapshot_kind() != SnapshotKind::kNone) {
+  if (DartDevIsolate::should_run_dart_dev() && !Options::disable_dart_dev() &&
+      Options::gen_snapshot_kind() == SnapshotKind::kNone) {
+    DartDevIsolate::DartDev_Result dartdev_result = DartDevIsolate::RunDartDev(
+        CreateIsolateGroupAndSetup, &package_config_override, &script_name,
+        &vm_options, &dart_options);
+    ASSERT(dartdev_result != DartDevIsolate::DartDev_Result_Unknown);
+    ran_dart_dev = true;
+    should_run_user_program =
+        (dartdev_result == DartDevIsolate::DartDev_Result_Run);
+    if (should_run_user_program) {
+      try_load_snapshots_lambda();
+    }
+  } else if (script_name == nullptr &&
+             Options::gen_snapshot_kind() != SnapshotKind::kNone) {
     Syslog::PrintErr(
         "Snapshot generation should be done using the 'dart compile' "
         "command.\n");
     Platform::Exit(kErrorExitCode);
   }
-  if (!Options::resident() &&
-      (Options::resident_compiler_info_file_path() != nullptr ||
+
+  if (!ran_dart_dev &&
+      (Options::resident() ||
+       Options::resident_compiler_info_file_path() != nullptr ||
        Options::resident_server_info_file_path() != nullptr)) {
     Syslog::PrintErr(
-        "Error: the --resident flag must be passed whenever the "
-        "--resident-compiler-info-file option is passed.\n");
+        "Passing the `--resident` flag to `dart` is invalid. It must be passed "
+        "to `dart run`.\n");
     Platform::Exit(kErrorExitCode);
   }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
@@ -1417,6 +1550,9 @@
 
   delete app_snapshot;
   free(app_script_uri);
+  if (ran_dart_dev && script_name != nullptr) {
+    free(script_name);
+  }
   asset_resolution_base.reset();
 
   // Free copied argument strings if converted.
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 0340f58..b94961c 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -8,7 +8,7 @@
 #include <stdlib.h>
 #include <string.h>
 
-#include "bin/common_options.h"
+#include "bin/dartdev_isolate.h"
 #include "bin/error_exit.h"
 #include "bin/file_system_watcher.h"
 #if defined(DART_IO_SECURE_SOCKET_DISABLED)
@@ -16,6 +16,7 @@
 #else  // defined(DART_IO_SECURE_SOCKET_DISABLED)
 #include "bin/io_service.h"
 #endif  // defined(DART_IO_SECURE_SOCKET_DISABLED)
+#include "bin/options.h"
 #include "bin/platform.h"
 #include "bin/utils.h"
 #include "platform/syslog.h"
@@ -39,13 +40,14 @@
     nullptr,
 };
 
+// These strings must match the enum VerbosityLevel in main_options.h.
+static const char* const kVerbosityLevelNames[] = {
+    "error", "warning", "info", "all", nullptr,
+};
+
 SnapshotKind Options::gen_snapshot_kind_ = kNone;
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-DFE* Options::dfe_ = nullptr;
-
-DEFINE_STRING_OPTION_CB(dfe, { Options::dfe()->set_frontend_filename(value); });
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+VerbosityLevel Options::verbosity_ = kAll;
+bool Options::enable_vm_service_ = false;
 
 #define OPTION_FIELD(variable) Options::variable##_
 
@@ -83,6 +85,12 @@
 CB_OPTIONS_LIST(CB_OPTION_DEFINITION)
 #undef CB_OPTION_DEFINITION
 
+#if !defined(DART_PRECOMPILED_RUNTIME)
+DFE* Options::dfe_ = nullptr;
+
+DEFINE_STRING_OPTION_CB(dfe, { Options::dfe()->set_frontend_filename(value); });
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
 static void hot_reload_test_mode_callback(CommandLineOptions* vm_options) {
   // Identity reload.
   vm_options->AddArgument("--identity_reload");
@@ -123,175 +131,133 @@
 DEFINE_BOOL_OPTION_CB(hot_reload_rollback_test_mode,
                       hot_reload_rollback_test_mode_callback);
 
-bool Options::ParseArguments(int argc,
-                             char** argv,
-                             bool vm_run_app_snapshot,
-                             bool parsing_dart_vm_options,
-                             CommandLineOptions* vm_options,
-                             char** script_name,
-                             CommandLineOptions* dart_options,
-                             bool* print_flags_seen) {
-  int i = 0;
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  // DART_VM_OPTIONS is only implemented for compiled executables.
-  ASSERT(!parsing_dart_vm_options);
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-  if (!parsing_dart_vm_options) {
-    // Start processing arguments after argv[0] which would be the executable.
-    i = 1;
-  }
-
-  CommandLineOptions temp_vm_options(vm_options->max_count());
-  // Parse out the vm options.
-  while (i < argc) {
-    bool skipVmOption = false;
-    if (!OptionProcessor::TryProcess(argv[i], &temp_vm_options)) {
-      // Check if this flag is a potentially valid VM flag.
-      if (!OptionProcessor::IsValidFlag(argv[i])) {
-        break;
-      }
-      if (IsOption(argv[i], "print-flags")) {
-        *print_flags_seen = true;
-      } else if (IsOption(argv[i], "disable-dart-dev")) {
-        skipVmOption = true;
-      }
-      if (!skipVmOption) {
-        temp_vm_options.AddArgument(argv[i]);
-      }
-    } else if (IsOption(argv[i], "profile-microtasks")) {
-      temp_vm_options.AddArgument(argv[i]);
-    }
-    i++;
-  }
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  Options::dfe()->set_use_dfe();
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-  if (Options::deterministic()) {
-    // Both an embedder and VM flag.
-    temp_vm_options.AddArgument("--deterministic");
-  }
-
-  Socket::set_short_socket_read(Options::short_socket_read());
-  Socket::set_short_socket_write(Options::short_socket_write());
-#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
-  SSLCertContext::set_root_certs_file(Options::root_certs_file());
-  SSLCertContext::set_root_certs_cache(Options::root_certs_cache());
-  SSLCertContext::set_long_ssl_cert_evaluation(
-      Options::long_ssl_cert_evaluation());
-  SSLCertContext::set_bypass_trusting_system_roots(
-      Options::bypass_trusting_system_roots());
-#endif  // !defined(DART_IO_SECURE_SOCKET_DISABLED)
-
-  FileSystemWatcher::set_delayed_filewatch_callback(
-      Options::delayed_filewatch_callback());
-
-  if (Options::deterministic()) {
-    IOService::set_max_concurrency(1);
-  }
-
-  // The arguments to the VM are at positions 1 through i-1 in argv.
-  Platform::SetExecutableArguments(i, argv);
-
-  // Get the script name.
-  if (i < argc) {
-    *script_name = Utils::StrDup(argv[i]);
-    i++;
-    // Handle argument parsing errors and missing script / command name when not
-    // processing options set via DART_VM_OPTIONS.
-  } else if (!parsing_dart_vm_options || Options::help_option() ||  // NOLINT
-             Options::version_option()) {                           // NOLINT
-    return false;
-  }
-
-  const char** vm_argv = temp_vm_options.arguments();
-  int vm_argc = temp_vm_options.count();
-  vm_options->AddArguments(vm_argv, vm_argc);
-
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  // If we're parsing DART_VM_OPTIONS, there shouldn't be any script set or
-  // Dart arguments left to parse.
-  if (parsing_dart_vm_options) {
-    ASSERT(i == argc);
-    return true;
-  }
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
-
-  // Parse out options to be passed to dart main.
-  while (i < argc) {
-    dart_options->AddArgument(argv[i]);
-    i++;
-  }
-  if (!parsing_dart_vm_options) {
-    // Store the executable name.
-    if (Options::executable_name() != nullptr) {
-      Platform::SetExecutableName(Options::executable_name());
-      Platform::SetResolvedExecutableName(Options::executable_name());
-    } else {
-      Platform::SetExecutableName(argv[0]);
-    }
-  }
-
-  // Verify consistency of arguments.
-
-  // snapshot_depfile is an alias for depfile. Passing them both is an error.
-  if ((snapshot_deps_filename_ != nullptr) && (depfile_ != nullptr)) {
-    Syslog::PrintErr("Specify only one of --depfile and --snapshot_depfile\n");
-    return false;
-  }
-  if (snapshot_deps_filename_ != nullptr) {
-    depfile_ = snapshot_deps_filename_;
-    snapshot_deps_filename_ = nullptr;
-  }
-
-  if ((packages_file_ != nullptr) && (strlen(packages_file_) == 0)) {
-    Syslog::PrintErr("Empty package file name specified.\n");
-    return false;
-  }
-  if ((gen_snapshot_kind_ != kNone) && (snapshot_filename_ == nullptr)) {
-    Syslog::PrintErr(
-        "Generating a snapshot requires a filename (--snapshot).\n");
-    return false;
-  }
-  if ((gen_snapshot_kind_ == kNone) && (depfile_ != nullptr) &&
-      (snapshot_filename_ == nullptr) &&
-      (depfile_output_filename_ == nullptr)) {
-    Syslog::PrintErr(
-        "Generating a depfile requires an output filename"
-        " (--depfile-output-filename or --snapshot).\n");
-    return false;
-  }
-  if ((gen_snapshot_kind_ != kNone) && vm_run_app_snapshot) {
-    Syslog::PrintErr(
-        "Specifying an option to generate a snapshot and"
-        " run using a snapshot is invalid.\n");
-    return false;
-  }
-
-  // If --snapshot is given without --snapshot-kind, default to script snapshot.
-  if ((snapshot_filename_ != nullptr) && (gen_snapshot_kind_ == kNone)) {
-    gen_snapshot_kind_ = kKernel;
-  }
-
-  return true;
-}
-
-// These strings must match the enum VerbosityLevel in main_options.h.
-VerbosityLevel Options::verbosity_ = kAll;
-bool Options::enable_vm_service_ = false;
-bool Options::enable_dds_ = true;
-
 void Options::PrintVersion() {
-  _PrintVersion();
+  Syslog::Print("Dart SDK version: %s\n", Dart_VersionString());
 }
 
 // clang-format off
 void Options::PrintUsage() {
-  _PrintUsage();
+  Syslog::Print(
+      "Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]\n"
+      "\n"
+      "Executes the Dart script <dart-script-file> with "
+      "the given list of <script-arguments>.\n"
+      "\n");
   if (!Options::verbose_option()) {
-    _PrintNonVerboseUsage();
+    Syslog::Print(
+"Common VM flags:\n"
+#if !defined(PRODUCT)
+"--enable-asserts\n"
+"  Enable assert statements.\n"
+#endif  // !defined(PRODUCT)
+"--help or -h\n"
+"  Display this message (add -v or --verbose for information about\n"
+"  all VM options).\n"
+"--packages=<path>\n"
+"  Where to find a package spec file.\n"
+"--define=<key>=<value> or -D<key>=<value>\n"
+"  Define an environment declaration. To specify multiple declarations,\n"
+"  use multiple instances of this option.\n"
+#if !defined(PRODUCT)
+"--observe[=<port>[/<bind-address>]]\n"
+"  The observe flag is a convenience flag used to run a program with a\n"
+"  set of options which are often useful for debugging under Dart DevTools.\n"
+"  These options are currently:\n"
+"      --enable-vm-service[=<port>[/<bind-address>]]\n"
+"      --serve-devtools\n"
+"      --pause-isolates-on-exit\n"
+"      --pause-isolates-on-unhandled-exceptions\n"
+"      --warn-on-pause-with-no-debugger\n"
+"      --timeline-streams=\"Compiler, Dart, GC, Microtask\"\n"
+"  This set is subject to change.\n"
+"  Please see these options (--help --verbose) for further documentation.\n"
+"--write-service-info=<file_uri>\n"
+"  Outputs information necessary to connect to the VM service to the\n"
+"  specified file in JSON format. Useful for clients which are unable to\n"
+"  listen to stdout for the Dart VM service listening message.\n"
+#endif  // !defined(PRODUCT)
+"--snapshot-kind=<snapshot_kind>\n"
+"--snapshot=<file_name>\n"
+"  These snapshot options are used to generate a snapshot of the loaded\n"
+"  Dart script:\n"
+"    <snapshot-kind> controls the kind of snapshot, it could be\n"
+"                    kernel(default) or app-jit\n"
+"    <file_name> specifies the file into which the snapshot is written\n"
+"--version\n"
+"  Print the SDK version.\n");
   } else {
-    _PrintVerboseUsage();
+    Syslog::Print(
+"Supported options:\n"
+#if !defined(PRODUCT)
+"--enable-asserts\n"
+"  Enable assert statements.\n"
+#endif  // !defined(PRODUCT)
+"--help or -h\n"
+"  Display this message (add -v or --verbose for information about\n"
+"  all VM options).\n"
+"--packages=<path>\n"
+"  Where to find a package spec file.\n"
+"--define=<key>=<value> or -D<key>=<value>\n"
+"  Define an environment declaration. To specify multiple declarations,\n"
+"  use multiple instances of this option.\n"
+#if !defined(PRODUCT)
+"--observe[=<port>[/<bind-address>]]\n"
+"  The observe flag is a convenience flag used to run a program with a\n"
+"  set of options which are often useful for debugging under Dart DevTools.\n"
+"  These options are currently:\n"
+"      --enable-vm-service[=<port>[/<bind-address>]]\n"
+"      --serve-devtools\n"
+"      --pause-isolates-on-exit\n"
+"      --pause-isolates-on-unhandled-exceptions\n"
+"      --warn-on-pause-with-no-debugger\n"
+"      --timeline-streams=\"Compiler, Dart, GC, Microtask\"\n"
+"  This set is subject to change.\n"
+"  Please see these options for further documentation.\n"
+"--profile-microtasks\n"
+"  Record information about each microtask. Information about completed\n"
+"  microtasks will be written to the \"Microtask\" timeline stream.\n"
+#endif  // !defined(PRODUCT)
+"--version\n"
+"  Print the VM version.\n"
+"\n"
+"--trace-loading\n"
+"  enables tracing of library and script loading\n"
+"\n"
+#if !defined(PRODUCT)
+"--enable-vm-service[=<port>[/<bind-address>]]\n"
+"  Enables the VM service and listens on specified port for connections\n"
+"  (default port number is 8181, default bind address is localhost).\n"
+"\n"
+"--disable-service-auth-codes\n"
+"  Disables the requirement for an authentication code to communicate with\n"
+"  the VM service. Authentication codes help protect against CSRF attacks,\n"
+"  so it is not recommended to disable them unless behind a firewall on a\n"
+"  secure device.\n"
+"\n"
+"--enable-service-port-fallback\n"
+"  When the VM service is told to bind to a particular port, fallback to 0 if\n"
+"  it fails to bind instead of failing to start.\n"
+"\n"
+#endif  // !defined(PRODUCT)
+"--root-certs-file=<path>\n"
+"  The path to a file containing the trusted root certificates to use for\n"
+"  secure socket connections.\n"
+"--root-certs-cache=<path>\n"
+"  The path to a cache directory containing the trusted root certificates to\n"
+"  use for secure socket connections.\n"
+#if defined(DART_HOST_OS_LINUX) || \
+    defined(DART_HOST_OS_ANDROID) || \
+    defined(DART_HOST_OS_FUCHSIA)
+"--namespace=<path>\n"
+"  The path to a directory that dart:io calls will treat as the root of the\n"
+"  filesystem.\n"
+#endif  // defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_ANDROID)
+"\n"
+"The following options are only used for VM development and may\n"
+"be changed in any future version:\n");
+    const char* print_flags = "--print_flags";
+    char* error = Dart_SetVMFlags(1, &print_flags);
+    ASSERT(error == nullptr);
   }
 }
 // clang-format on
@@ -328,8 +294,8 @@
 //
 // DART_VM_OPTIONS should contain a list of comma-separated options and flags
 // with no spaces. Options that support providing multiple values as
-// comma-separated lists (e.g., --timeline-streams=Dart,GC,Compiler,Microtask)
-// are not supported and will cause argument parsing to fail.
+// comma-separated lists (e.g., --timeline-streams=Dart,GC,Compiler) are not
+// supported and will cause argument parsing to fail.
 char** Options::GetEnvArguments(int* argc) {
   ASSERT(argc != nullptr);
   const char* env_args_str = std::getenv("DART_VM_OPTIONS");
@@ -423,22 +389,36 @@
   return true;
 }
 
-#if !defined(PRODUCT)
-static constexpr const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost";
-static constexpr int DEFAULT_VM_SERVICE_SERVER_PORT = 8181;
-static constexpr int INVALID_VM_SERVICE_SERVER_PORT = -1;
+// Returns true if arg starts with the characters "--" followed by option, but
+// all '_' in the option name are treated as '-'.
+static bool IsOption(const char* arg, const char* option) {
+  if (arg[0] != '-' || arg[1] != '-') {
+    // Special case first two characters to avoid recognizing __flag.
+    return false;
+  }
+  for (int i = 0; option[i] != '\0'; i++) {
+    auto c = arg[i + 2];
+    if (c == '\0') {
+      // Not long enough.
+      return false;
+    }
+    if ((c == '_' ? '-' : c) != option[i]) {
+      return false;
+    }
+  }
+  return true;
+}
+
 const char* Options::vm_service_server_ip_ = DEFAULT_VM_SERVICE_SERVER_IP;
 int Options::vm_service_server_port_ = INVALID_VM_SERVICE_SERVER_PORT;
-#endif  // !defined(PRODUCT)
-
 bool Options::ProcessEnableVmServiceOption(const char* arg,
                                            CommandLineOptions* vm_options) {
+#if !defined(PRODUCT)
   const char* value =
       OptionProcessor::ProcessOption(arg, "--enable-vm-service");
   if (value == nullptr) {
     return false;
   }
-#if !defined(PRODUCT)
   if (!ExtractPortAndAddress(
           value, &vm_service_server_port_, &vm_service_server_ip_,
           DEFAULT_VM_SERVICE_SERVER_PORT, DEFAULT_VM_SERVICE_SERVER_IP)) {
@@ -460,11 +440,11 @@
 
 bool Options::ProcessObserveOption(const char* arg,
                                    CommandLineOptions* vm_options) {
+#if !defined(PRODUCT)
   const char* value = OptionProcessor::ProcessOption(arg, "--observe");
   if (value == nullptr) {
     return false;
   }
-#if !defined(PRODUCT)
   if (!ExtractPortAndAddress(
           value, &vm_service_server_port_, &vm_service_server_ip_,
           DEFAULT_VM_SERVICE_SERVER_PORT, DEFAULT_VM_SERVICE_SERVER_IP)) {
@@ -491,18 +471,352 @@
 #endif  // !defined(PRODUCT)
 }
 
-bool Options::ProcessDdsOption(const char* arg,
-                               CommandLineOptions* vm_options) {
-  const char* value = OptionProcessor::ProcessOption(arg, "--dds");
-  if (value == nullptr) {
-    value = OptionProcessor::ProcessOption(arg, "--no-dds");
-    if (value == nullptr) {
-      return false;
-    }
-    enable_dds_ = false;
-  } else {
-    enable_dds_ = true;
+bool Options::ProcessProfileMicrotasksOption(const char* arg,
+                                             CommandLineOptions* vm_options) {
+#if !defined(PRODUCT)
+  constexpr const char* kProfileMicrotasksFlagAsCstr = "--profile-microtasks";
+  constexpr const char* kAlternativeProfileMicrotasksFlagAsCstr =
+      "--profile_microtasks";
+  if (strncmp(kProfileMicrotasksFlagAsCstr, arg,
+              strlen(kProfileMicrotasksFlagAsCstr)) == 0 ||
+      strncmp(kAlternativeProfileMicrotasksFlagAsCstr, arg,
+              strlen(kAlternativeProfileMicrotasksFlagAsCstr)) == 0) {
+    profile_microtasks_ = true;
+    vm_options->AddArgument(kProfileMicrotasksFlagAsCstr);
+    return true;
   }
+#endif  // !defined(PRODUCT)
+  return false;
+}
+
+// Explicitly handle VM flags that can be parsed by DartDev's run command.
+bool Options::ProcessVMDebuggingOptions(const char* arg,
+                                        CommandLineOptions* vm_options) {
+#define IS_DEBUG_OPTION(name, arg)                                             \
+  if (strncmp(name, arg, strlen(name)) == 0) {                                 \
+    vm_options->AddArgument(arg);                                              \
+    return true;                                                               \
+  }
+
+// This is an exhaustive set of VM flags that are accepted by 'dart run'. Flags
+// defined in main_options.h do not need to be handled here as they already
+// have handlers generated.
+//
+// NOTE: When updating this list of VM flags, be sure to make the corresponding
+// changes in pkg/dartdev/lib/src/commands/run.dart.
+#define HANDLE_DARTDEV_VM_DEBUG_OPTIONS(V, arg)                                \
+  V("--enable-asserts", arg)                                                   \
+  V("--pause-isolates-on-exit", arg)                                           \
+  V("--no-pause-isolates-on-exit", arg)                                        \
+  V("--pause-isolates-on-start", arg)                                          \
+  V("--no-pause-isolates-on-start", arg)                                       \
+  V("--pause-isolates-on-unhandled-exception", arg)                            \
+  V("--no-pause-isolates-on-unhandled-exception", arg)                         \
+  V("--warn-on-pause-with-no-debugger", arg)                                   \
+  V("--no-warn-on-pause-with-no-debugger", arg)                                \
+  V("--timeline-streams", arg)                                                 \
+  V("--timeline-recorder", arg)                                                \
+  V("--enable-experiment", arg)
+  HANDLE_DARTDEV_VM_DEBUG_OPTIONS(IS_DEBUG_OPTION, arg);
+
+#undef IS_DEBUG_OPTION
+#undef HANDLE_DARTDEV_VM_DEBUG_OPTIONS
+
+  return false;
+}
+
+bool Options::ParseArguments(int argc,
+                             char** argv,
+                             bool vm_run_app_snapshot,
+                             bool parsing_dart_vm_options,
+                             CommandLineOptions* vm_options,
+                             char** script_name,
+                             CommandLineOptions* dart_options,
+                             bool* print_flags_seen,
+                             bool* verbose_debug_seen) {
+  int i = 0;
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  // DART_VM_OPTIONS is only implemented for compiled executables.
+  ASSERT(!parsing_dart_vm_options);
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  if (!parsing_dart_vm_options) {
+    // Store the executable name.
+    Platform::SetExecutableName(argv[0]);
+
+    // Start the rest after the executable name.
+    i = 1;
+  }
+
+  CommandLineOptions temp_vm_options(vm_options->max_count());
+
+  bool enable_dartdev_analytics = false;
+  bool disable_dartdev_analytics = false;
+  char* packages_argument = nullptr;
+
+  // Parse out the vm options.
+  while (i < argc) {
+    bool skipVmOption = false;
+    if (!OptionProcessor::TryProcess(argv[i], &temp_vm_options)) {
+      // Check if this flag is a potentially valid VM flag.
+      if (!OptionProcessor::IsValidFlag(argv[i])) {
+        break;
+      }
+      // The following flags are processed as DartDev flags and are not to
+      // be treated as if they are VM flags.
+      if (IsOption(argv[i], "print-flags")) {
+        *print_flags_seen = true;
+      } else if (IsOption(argv[i], "verbose-debug")) {
+        *verbose_debug_seen = true;
+      } else if (IsOption(argv[i], "enable-analytics")) {
+        enable_dartdev_analytics = true;
+        skipVmOption = true;
+      } else if (IsOption(argv[i], "disable-analytics")) {
+        disable_dartdev_analytics = true;
+        skipVmOption = true;
+      } else if (IsOption(argv[i], "disable-telemetry")) {
+        disable_dartdev_analytics = true;
+        skipVmOption = true;
+      } else if (IsOption(argv[i], "suppress-analytics")) {
+        dart_options->AddArgument("--suppress-analytics");
+        skipVmOption = true;
+      } else if (IsOption(argv[i], "no-analytics")) {
+        // Just add this option even if we don't go to dartdev.
+        // It is irrelevant for the vm.
+        dart_options->AddArgument("--no-analytics");
+        skipVmOption = true;
+      } else if (IsOption(argv[i], "dds")) {
+        // This flag is set by default in dartdev, so we ignore it. --no-dds is
+        // a VM flag as disabling DDS changes how we configure the VM service,
+        // so we don't need to handle that case here.
+        skipVmOption = true;
+      } else if (IsOption(argv[i], "serve-observatory")) {
+        // This flag is currently set by default in vmservice_io.dart, so we
+        // ignore it. --no-serve-observatory is a VM flag so we don't need to
+        // handle that case here.
+        skipVmOption = true;
+      } else if (IsOption(argv[i], "print-dtd-uri")) {
+        skipVmOption = true;
+      }
+      if (!skipVmOption) {
+        temp_vm_options.AddArgument(argv[i]);
+      }
+    }
+    if (IsOption(argv[i], "packages")) {
+      packages_argument = argv[i];
+    }
+    i++;
+  }
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  Options::dfe()->set_use_dfe();
+#else
+  // DartDev is not supported in AOT.
+  Options::disable_dart_dev_ = true;
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  if (Options::deterministic()) {
+    // Both an embedder and VM flag.
+    temp_vm_options.AddArgument("--deterministic");
+  }
+
+  Socket::set_short_socket_read(Options::short_socket_read());
+  Socket::set_short_socket_write(Options::short_socket_write());
+#if !defined(DART_IO_SECURE_SOCKET_DISABLED)
+  SSLCertContext::set_root_certs_file(Options::root_certs_file());
+  SSLCertContext::set_root_certs_cache(Options::root_certs_cache());
+  SSLCertContext::set_long_ssl_cert_evaluation(
+      Options::long_ssl_cert_evaluation());
+  SSLCertContext::set_bypass_trusting_system_roots(
+      Options::bypass_trusting_system_roots());
+#endif  // !defined(DART_IO_SECURE_SOCKET_DISABLED)
+
+  FileSystemWatcher::set_delayed_filewatch_callback(
+      Options::delayed_filewatch_callback());
+
+  if (Options::deterministic()) {
+    IOService::set_max_concurrency(1);
+  }
+
+  // The arguments to the VM are at positions 1 through i-1 in argv.
+  Platform::SetExecutableArguments(i, argv);
+
+  bool run_script = false;
+  // Get the script name.
+  if (i < argc) {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    // If the script name is a valid file or a URL, we'll run the script
+    // directly. Otherwise, this might be a DartDev command and we need to try
+    // to find the DartDev snapshot so we can forward the command and its
+    // arguments.
+    bool is_potential_file_path = !DartDevIsolate::ShouldParseCommand(argv[i]);
+#else
+    bool is_potential_file_path = true;
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+    if (Options::disable_dart_dev() ||
+        (Options::snapshot_filename() != nullptr) || is_potential_file_path) {
+      *script_name = Utils::StrDup(argv[i]);
+      run_script = true;
+      i++;
+    }
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    else {  // NOLINT
+      DartDevIsolate::set_should_run_dart_dev(true);
+    }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  }
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  else if (!Options::disable_dart_dev()) {  // NOLINT
+    // Handles following invocation arguments:
+    //   - dart help
+    //   - dart --help
+    //   - dart
+    if (((Options::help_option() && !Options::verbose_option()) ||
+         (argc == 1))) {
+      DartDevIsolate::set_should_run_dart_dev(true);
+      // Let DartDev handle the default help message.
+      dart_options->AddArgument("help");
+      return true;
+    }
+    // Handles cases where only analytics flags are provided. We need to start
+    // the DartDev isolate to set this state.
+    else if (enable_dartdev_analytics || disable_dartdev_analytics) {  // NOLINT
+      // The analytics flags are a special case as we don't have a target script
+      // or DartDev command but we still want to launch DartDev.
+      DartDevIsolate::set_should_run_dart_dev(true);
+      dart_options->AddArgument(enable_dartdev_analytics
+                                    ? "--enable-analytics"
+                                    : "--disable-analytics");
+      return true;
+    }
+    // Let the VM handle '--version' and '--help --disable-dart-dev'.
+    // Otherwise, we'll launch the DartDev isolate to print its help message
+    // and set an error exit code.
+    else if (!Options::help_option() && !Options::version_option()) {  // NOLINT
+      DartDevIsolate::PrintUsageErrorOnRun();
+      return true;
+    }
+    return false;
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  // Handle argument parsing errors and missing script / command name when not
+  // processing options set via DART_VM_OPTIONS.
+  else if (!parsing_dart_vm_options || Options::help_option() ||  // NOLINT
+           Options::version_option()) {                           // NOLINT
+    return false;
+  }
+  USE(enable_dartdev_analytics);
+  USE(disable_dartdev_analytics);
+  USE(packages_argument);
+
+  const char** vm_argv = temp_vm_options.arguments();
+  int vm_argc = temp_vm_options.count();
+
+  vm_options->AddArguments(vm_argv, vm_argc);
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  // If we're parsing DART_VM_OPTIONS, there shouldn't be any script set or
+  // Dart arguments left to parse.
+  if (parsing_dart_vm_options) {
+    ASSERT(i == argc);
+    return true;
+  }
+
+  // If running with dartdev, attempt to parse VM flags which are part of the
+  // dartdev command (e.g., --enable-vm-service, --observe, etc).
+  bool record_vm_options = false;
+  if ((i < argc) && DartDevIsolate::ShouldParseVMOptions(argv[i])) {
+    record_vm_options = true;
+  }
+  if (!run_script && record_vm_options) {
+    // Skip the command.
+    int tmp_i = i + 1;
+    while (tmp_i < argc) {
+      // Check if this flag is a potentially valid VM flag. If not, we've likely
+      // hit a script name and are done parsing VM flags.
+      if (!OptionProcessor::IsValidFlag(argv[tmp_i]) &&
+          !OptionProcessor::IsValidShortFlag(argv[tmp_i])) {
+        break;
+      }
+      OptionProcessor::TryProcess(argv[tmp_i], vm_options);
+      tmp_i++;
+    }
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+
+  bool first_option = true;
+  // Parse out options to be passed to dart main.
+  while (i < argc) {
+    // dart run isn't able to parse these options properly. Since it doesn't
+    // need to use the values from these options, just strip them from the
+    // argument list passed to dart run.
+    if (!IsOption(argv[i], "observe") &&
+        !IsOption(argv[i], "enable-vm-service")) {
+      dart_options->AddArgument(argv[i]);
+    }
+#if !defined(DART_PRECOMPILED_RUNTIME)
+    if (IsOption(argv[i], "disable-dart-dev")) {
+      Syslog::PrintErr(
+          "Attempted to use --disable-dart-dev with a Dart CLI command.\n");
+      Platform::Exit(kErrorExitCode);
+    }
+#endif  // !defined(DART_PRECOMIPLED_RUNTIME)
+    i++;
+    // Add DDS specific flags immediately after the dartdev command.
+    if (first_option) {
+      // DDS is only enabled for the run command. Make sure we don't pass DDS
+      // specific flags along with other commands, otherwise argument parsing
+      // will fail unexpectedly.
+#if !defined(DART_PRECOMPILED_RUNTIME)
+      // Bring any --packages option into the dartdev command
+      if (DartDevIsolate::should_run_dart_dev() &&
+          packages_argument != nullptr) {
+        dart_options->AddArgument(packages_argument);
+      }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+      first_option = false;
+    }
+  }
+
+  // Verify consistency of arguments.
+
+  // snapshot_depfile is an alias for depfile. Passing them both is an error.
+  if ((snapshot_deps_filename_ != nullptr) && (depfile_ != nullptr)) {
+    Syslog::PrintErr("Specify only one of --depfile and --snapshot_depfile\n");
+    return false;
+  }
+  if (snapshot_deps_filename_ != nullptr) {
+    depfile_ = snapshot_deps_filename_;
+    snapshot_deps_filename_ = nullptr;
+  }
+
+  if ((packages_file_ != nullptr) && (strlen(packages_file_) == 0)) {
+    Syslog::PrintErr("Empty package file name specified.\n");
+    return false;
+  }
+  if ((gen_snapshot_kind_ != kNone) && (snapshot_filename_ == nullptr)) {
+    Syslog::PrintErr(
+        "Generating a snapshot requires a filename (--snapshot).\n");
+    return false;
+  }
+  if ((gen_snapshot_kind_ == kNone) && (depfile_ != nullptr) &&
+      (snapshot_filename_ == nullptr) &&
+      (depfile_output_filename_ == nullptr)) {
+    Syslog::PrintErr(
+        "Generating a depfile requires an output filename"
+        " (--depfile-output-filename or --snapshot).\n");
+    return false;
+  }
+  if ((gen_snapshot_kind_ != kNone) && vm_run_app_snapshot) {
+    Syslog::PrintErr(
+        "Specifying an option to generate a snapshot and"
+        " run using a snapshot is invalid.\n");
+    return false;
+  }
+
+  // If --snapshot is given without --snapshot-kind, default to script snapshot.
+  if ((snapshot_filename_ != nullptr) && (gen_snapshot_kind_ == kNone)) {
+    gen_snapshot_kind_ = kKernel;
+  }
+
   return true;
 }
 
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index a4e9740..5b696f7 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -7,7 +7,6 @@
 
 #include "bin/dartutils.h"
 #include "bin/dfe.h"
-#include "bin/options.h"
 #include "platform/globals.h"
 #include "platform/growable_array.h"
 #include "platform/hashmap.h"
@@ -28,7 +27,6 @@
   V(root_certs_cache, root_certs_cache)                                        \
   V(namespace, namespc)                                                        \
   V(write_service_info, vm_write_service_info_filename)                        \
-  V(executable_name, executable_name)                                          \
   /* The purpose of these flags is documented in */                            \
   /* pkg/dartdev/lib/src/commands/compilation_server.dart. */                  \
   V(resident_server_info_file, resident_server_info_file_path)                 \
@@ -46,8 +44,11 @@
   V(short_socket_read, short_socket_read)                                      \
   V(short_socket_write, short_socket_write)                                    \
   V(disable_exit, exit_disabled)                                               \
+  V(preview_dart_2, nop_option)                                                \
   V(suppress_core_dump, suppress_core_dump)                                    \
   V(enable_service_port_fallback, enable_service_port_fallback)                \
+  V(disable_dart_dev, disable_dart_dev)                                        \
+  V(no_dds, disable_dds)                                                       \
   V(long_ssl_cert_evaluation, long_ssl_cert_evaluation)                        \
   V(bypass_trusting_system_roots, bypass_trusting_system_roots)                \
   V(delayed_filewatch_callback, delayed_filewatch_callback)                    \
@@ -84,7 +85,8 @@
   V(ProcessEnvironmentOption)                                                  \
   V(ProcessEnableVmServiceOption)                                              \
   V(ProcessObserveOption)                                                      \
-  V(ProcessDdsOption)
+  V(ProcessProfileMicrotasksOption)                                            \
+  V(ProcessVMDebuggingOptions)
 
 // This enum must match the strings in kSnapshotKindNames in main_options.cc.
 enum SnapshotKind {
@@ -93,6 +95,7 @@
   kAppJIT,
 };
 
+// This enum must match the strings in kVerbosityLevelNames in main_options.cc.
 enum VerbosityLevel {
   kError,
   kWarning,
@@ -100,9 +103,9 @@
   kAll,
 };
 
-static const char* const kVerbosityLevelNames[] = {
-    "error", "warning", "info", "all", nullptr,
-};
+static constexpr const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost";
+static constexpr int DEFAULT_VM_SERVICE_SERVER_PORT = 8181;
+static constexpr int INVALID_VM_SERVICE_SERVER_PORT = -1;
 
 class Options {
  public:
@@ -114,7 +117,8 @@
                              CommandLineOptions* vm_options,
                              char** script_name,
                              CommandLineOptions* dart_options,
-                             bool* print_flags_seen);
+                             bool* print_flags_seen,
+                             bool* verbose_debug_seen);
 
 #define STRING_OPTION_GETTER(flag, variable)                                   \
   static const char* variable() { return variable##_; }
@@ -145,14 +149,21 @@
   CB_OPTIONS_LIST(CB_OPTIONS_DECL)
 #undef CB_OPTIONS_DECL
 
+  static bool preview_dart_2() { return true; }
+
   static dart::SimpleHashMap* environment() { return environment_; }
 
   static bool enable_vm_service() { return enable_vm_service_; }
-#if !defined(PRODUCT)
   static const char* vm_service_server_ip() { return vm_service_server_ip_; }
   static int vm_service_server_port() { return vm_service_server_port_; }
-#endif  // !defined(PRODUCT)
-  static bool enable_dds() { return enable_dds_; }
+
+  // TODO(bkonyi): remove once DartDev moves to AOT and this flag can be
+  // provided directly to the process spawned by `dart run` and `dart test`.
+  //
+  // See https://github.com/dart-lang/sdk/issues/53576
+  static void set_mark_main_isolate_as_system_isolate(bool state) {
+    mark_main_isolate_as_system_isolate_ = state;
+  }
 
   static Dart_KernelCompilationVerbosityLevel verbosity_level() {
     return VerbosityLevelToDartAPI(verbosity_);
@@ -227,13 +238,9 @@
   }
 
   // VM Service argument processing.
-  static bool enable_vm_service_;
-#if !defined(PRODUCT)
   static const char* vm_service_server_ip_;
+  static bool enable_vm_service_;
   static int vm_service_server_port_;
-#endif  // !defined(PRODUCT)
-  static bool enable_dds_;
-
   static bool ExtractPortAndAddress(const char* option_value,
                                     int* out_port,
                                     const char** out_ip,
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index d8b6409..74acf31 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -72,13 +72,6 @@
     executable_name_ = executable_name;
   }
   static const char* GetExecutableName();
-
-  // Stores the resolved executable name.
-  static void SetResolvedExecutableName(const char* resolved_executable_name) {
-    const char* expect_old_is_null = nullptr;
-    resolved_executable_name_.compare_exchange_strong(expect_old_is_null,
-                                                      resolved_executable_name);
-  }
   static const char* GetResolvedExecutableName() {
     if (resolved_executable_name_.load() == nullptr) {
       // Try to resolve the executable path using platform specific APIs.
diff --git a/runtime/bin/process_linux.cc b/runtime/bin/process_linux.cc
index 4b26d9d..9778dd6 100644
--- a/runtime/bin/process_linux.cc
+++ b/runtime/bin/process_linux.cc
@@ -519,18 +519,15 @@
         ReportChildError();
       }
       close(write_out_[0]);
-      close(write_out_[1]);
 
       if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
         ReportChildError();
       }
-      close(read_in_[0]);
       close(read_in_[1]);
 
       if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
         ReportChildError();
       }
-      close(read_err_[0]);
       close(read_err_[1]);
     } else {
       ASSERT(mode_ == kInheritStdio);
@@ -598,13 +595,12 @@
             environ = program_environment_;
           }
 
+          // Report the final PID and do the exec.
+          ReportPid(getpid());  // getpid cannot fail.
           char realpath[PATH_MAX];
           if (!FindPathInNamespace(realpath, PATH_MAX)) {
             ReportChildError();
           }
-
-          // Report the final PID and do the exec.
-          ReportPid(getpid());  // getpid cannot fail.
           // TODO(dart:io) Test for the existence of execveat, and use it
           // instead.
           execvp(realpath, const_cast<char* const*>(program_arguments_));
diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc
index 8aebf47..9bae25e 100644
--- a/runtime/bin/process_macos.cc
+++ b/runtime/bin/process_macos.cc
@@ -451,18 +451,15 @@
         ReportChildError();
       }
       close(write_out_[0]);
-      close(write_out_[1]);
 
       if (TEMP_FAILURE_RETRY(dup2(read_in_[1], STDOUT_FILENO)) == -1) {
         ReportChildError();
       }
-      close(read_in_[0]);
       close(read_in_[1]);
 
       if (TEMP_FAILURE_RETRY(dup2(read_err_[1], STDERR_FILENO)) == -1) {
         ReportChildError();
       }
-      close(read_err_[0]);
       close(read_err_[1]);
     } else {
       ASSERT(mode_ == kInheritStdio);
diff --git a/runtime/bin/process_win.cc b/runtime/bin/process_win.cc
index cfbfabe..a531acf 100644
--- a/runtime/bin/process_win.cc
+++ b/runtime/bin/process_win.cc
@@ -1044,7 +1044,10 @@
     return -1;
   }
   CloseHandle(child_process);
-  return retval;
+  // We exit the process here to simulate the same behaviour as exec on systems
+  // that support it.
+  ExitProcess(retval);
+  return 0;
 }
 
 bool Process::Kill(intptr_t id, int signal) {
diff --git a/runtime/bin/utils_win.cc b/runtime/bin/utils_win.cc
index c73d972..9945245 100644
--- a/runtime/bin/utils_win.cc
+++ b/runtime/bin/utils_win.cc
@@ -8,7 +8,6 @@
 #include <errno.h>  // NOLINT
 #include <time.h>   // NOLINT
 #include <memory>
-#include <sstream>
 
 #include "bin/utils.h"
 #include "bin/utils_win.h"
@@ -189,70 +188,6 @@
       StringUtilsWin::Utf8ToWide(const_cast<char*>(utf8), len, result_len));
 }
 
-// This code is identical to the one in process_patch.dart, please ensure
-// changes made here are also done in process_patch.dart.
-char* StringUtilsWin::ArgumentEscape(const char* argument) {
-  std::string arg_str(argument);
-  if (arg_str.empty()) {
-    return Utils::StrDup(R"("")");
-  }
-  std::string result_str = arg_str;
-  if (arg_str.find('\t') != std::string::npos ||
-      arg_str.find(' ') != std::string::npos ||
-      arg_str.find('"') != std::string::npos) {
-    // Produce something that the C runtime on Windows will parse
-    // back as this string.
-
-    // Replace any number of '\' followed by '"' with
-    // twice as many '\' followed by '\"'.
-    char backslash = '\\';
-    std::stringstream sb;
-    size_t nextPos = 0;
-    size_t quotePos = arg_str.find('"', nextPos);
-
-    while (quotePos != std::string::npos) {
-      size_t numBackslash = 0;
-      size_t pos = quotePos - 1;
-      while (pos != std::string::npos && arg_str[pos] == backslash) {
-        numBackslash++;
-        pos--;
-      }
-      sb << arg_str.substr(nextPos, quotePos - numBackslash - nextPos);
-      for (size_t i = 0; i < numBackslash; i++) {
-        sb << R"(\\)";
-      }
-      sb << R"(\")";
-      nextPos = quotePos + 1;
-      quotePos = arg_str.find('"', nextPos);
-    }
-    sb << arg_str.substr(nextPos);
-    result_str = sb.str();
-
-    // Add '"' at the beginning and end and replace all '\' at
-    // the end with two '\'.
-    std::stringstream sb2;
-    sb2 << '"';
-    sb2 << result_str;
-
-    // Find the last non-backslash character to determine the actual end
-    // of the string
-    size_t lastCharPos = arg_str.length() - 1;
-    while (lastCharPos != std::string::npos &&
-           arg_str[lastCharPos] == backslash) {
-      sb2 << '\\';
-      lastCharPos--;
-    }
-    sb2 << '"';
-    result_str = sb2.str();
-  }
-  // Allocate memory for the C-style string and copy the content
-  intptr_t len = result_str.length() + 1;
-  char* c_str_result = static_cast<char*>(malloc(len * sizeof(char)));
-  if (c_str_result == nullptr) return nullptr;  // Allocation failure.
-  snprintf(c_str_result, len * sizeof(char), "%s", result_str.c_str());
-  return c_str_result;
-}
-
 bool ShellUtils::GetUtf8Argv(int argc, char** argv) {
   wchar_t* command_line = GetCommandLineW();
   int unicode_argc;
diff --git a/runtime/bin/utils_win.h b/runtime/bin/utils_win.h
index 00b105f..101760e 100644
--- a/runtime/bin/utils_win.h
+++ b/runtime/bin/utils_win.h
@@ -6,7 +6,6 @@
 #define RUNTIME_BIN_UTILS_WIN_H_
 
 #include <memory>
-#include <string>
 #include <utility>
 
 #include "platform/utils.h"
@@ -44,7 +43,6 @@
   static const wchar_t* Utf8ToWide(const char* utf8,
                                    intptr_t len = -1,
                                    intptr_t* result_len = nullptr);
-  static char* ArgumentEscape(const char* argument);
 
  private:
   DISALLOW_ALLOCATION();
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 4b040d1..c7bb1f7c 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -9,6 +9,7 @@
 #include "bin/builtin.h"
 #include "bin/dartutils.h"
 #include "bin/isolate_data.h"
+#include "bin/main_options.h"
 #include "bin/platform.h"
 #include "bin/thread.h"
 #include "bin/utils.h"
@@ -34,7 +35,6 @@
   }
 
 static constexpr const char* kVMServiceIOLibraryUri = "dart:vmservice_io";
-static constexpr const char* DEFAULT_VM_SERVICE_SERVER_IP = "localhost";
 
 void NotifyServerState(Dart_NativeArguments args) {
   Dart_EnterScope();
diff --git a/runtime/tests/vm/dart/exported_symbols_test.dart b/runtime/tests/vm/dart/exported_symbols_test.dart
index 7409613..dfeb535 100644
--- a/runtime/tests/vm/dart/exported_symbols_test.dart
+++ b/runtime/tests/vm/dart/exported_symbols_test.dart
@@ -4,7 +4,6 @@
 
 import "dart:io";
 import "package:expect/expect.dart";
-import 'package:path/path.dart' as p;
 
 import "use_flag_test_helper.dart";
 
@@ -36,9 +35,7 @@
     Platform.isMacOS ? "--extern-only" : "--dynamic",
     "--defined-only",
     "--format=just-symbols",
-    isAOTRuntime
-        ? Platform.executable
-        : p.join(p.dirname(Platform.executable), 'dartvm'),
+    Platform.executable,
   ]);
   if (result.exitCode != 0) {
     print("nm failed");
diff --git a/runtime/tests/vm/dart/use_flag_test_helper.dart b/runtime/tests/vm/dart/use_flag_test_helper.dart
index 38c14c4..6d12ad9 100644
--- a/runtime/tests/vm/dart/use_flag_test_helper.dart
+++ b/runtime/tests/vm/dart/use_flag_test_helper.dart
@@ -58,7 +58,7 @@
   }
   throw 'Could not find gen_snapshot for build directory $buildDir';
 }();
-final dart = path.join(buildDir, 'dartvm' + (Platform.isWindows ? '.exe' : ''));
+final dart = path.join(buildDir, 'dart' + (Platform.isWindows ? '.exe' : ''));
 final dartPrecompiledRuntime = path.join(
   buildDir,
   'dartaotruntime' + (Platform.isWindows ? '.exe' : ''),
diff --git a/runtime/tools/entitlements/dart.plist b/runtime/tools/entitlements/dart.plist
index 3322fe1..eeda4be 100644
--- a/runtime/tools/entitlements/dart.plist
+++ b/runtime/tools/entitlements/dart.plist
@@ -2,7 +2,7 @@
 <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
 <plist version="1.0">
     <dict>
-        <key>com.apple.security.cs.allow-unsigned-executable-memory</key>
+        <key>com.apple.security.cs.allow-jit</key>
         <true/>
         <key>com.apple.security.cs.disable-library-validation</key>
         <true/>
diff --git a/runtime/tools/entitlements/dartvm.plist b/runtime/tools/entitlements/dartvm.plist
deleted file mode 100644
index eeda4be..0000000
--- a/runtime/tools/entitlements/dartvm.plist
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-    <dict>
-        <key>com.apple.security.cs.allow-jit</key>
-        <true/>
-        <key>com.apple.security.cs.disable-library-validation</key>
-        <true/>
-    </dict>
-</plist>
\ No newline at end of file
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 136e9e4..17b6222 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -23,7 +23,6 @@
   dart_platform_sdk = true
 
   # Path to stripped dart binaries relative to build output directory.
-  dartvm_stripped_binary = "dartvm"
   dart_stripped_binary = "dart"
   dart_aotruntime_stripped_binary = "dartaotruntime_product"
   gen_snapshot_stripped_binary = "gen_snapshot_product"
@@ -38,23 +37,27 @@
 # ..dart-sdk/
 # ....bin/
 # ......dart or dart.exe (executable)
-# ......dartvm or dartvm.exe (executable)
 # ......dart.lib (import library for VM native extensions on Windows)
 # ......dartaotruntime or dartaotruntime.exe (executable)
 # ......utils/gen_snapshot or utils/gen_snapshot.exe (if not on ia32)
 # ......snapshots/
-# ........analysis_server.dart.snapshot (JIT snapshot)
+# ........analysis_server.dart.snapshot
 # ........analysis_server_aot.dart.snapshot (AOT snapshot, if not on ia32)
 # ........dart2bytecode.snapshot (AOT snapshot, for selected targets)
-# ........dart2js_aot.dart.snapshot (AOT snapshot)
-# ........dart2wasm_product.snapshot (AOT snapshot)
-# ........dartdev_aot.dart.snapshot (AOT snapshot)
-# ........dartdevc_aot.dart.snapshot (AOT snapshot)
-# ........dds_aot.dart.snapshot (AOT snapshot)
-# ........dart_tooling_daemon_aot.dart.snapshot (AOT snapshot)
-# ........frontend_server_aot.dart.snapshot (AOT snapshot)
-# ........gen_kernel_aot.dart.snapshot (AOT snapshot)
-# ........kernel-service.dart.snapshot (JIT snapshot)
+# ........dart2js_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........dart2js.dart.snapshot (JIT snapshot only on ia32)
+# ........dart2wasm_product.snapshot (if not on ia32)
+# ........dartdev.dart.snapshot (app-jit snapshot or kernel dill file)
+# ........dartdevc_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........dartdevc.dart.snapshot (JIT snapshot only on ia32)
+# ........dds_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........dds.dart.snapshot (JIT snapshot only on ia32)
+# ........dart_tooling_daemon_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........dart_tooling_daemon.dart.snapshot (JIT snapshot only on ia32)
+# ........frontend_server_aot.dart.snapshot (AOT snapshot, if not on ia32)
+# ........frontend_server.dart.snapshot (JIT snapshot only on ia32)
+# ........gen_kernel_aot.dart.snapshot (if not on ia32)
+# ........kernel-service.dart.snapshot
 # ........kernel_worker_aot.dart.snapshot (AOT snapshot)
 # ......resources/
 # ........dartdoc/
@@ -109,11 +112,23 @@
 _full_sdk_scripts = []
 
 # Snapshots that go under bin/snapshots
-_platform_sdk_snapshots = [ [
-      "analysis_server",
-      "../utils/analysis_server",
-      "analysis_server",
-    ] ]
+_platform_sdk_snapshots = [
+  [
+    "analysis_server",
+    "../utils/analysis_server",
+    "analysis_server",
+  ],
+  [
+    "dartdev",
+    "../utils/dartdev:dartdev",
+    "dartdev",
+  ],
+  [
+    "dart_tooling_daemon",
+    "../utils/dtd:dtd",
+    "dart_tooling_daemon",
+  ],
+]
 if (dart_target_arch != "ia32" && dart_target_arch != "x86") {
   _platform_sdk_snapshots += [
     [
@@ -127,11 +142,6 @@
       "frontend_server_aot",
     ],
     [
-      "dartdev_aot",
-      "../utils/dartdev:dartdev_aot",
-      "dartdev_aot",
-    ],
-    [
       "dds_aot_product",
       "../utils/dds:dds_aot",
       "dds_aot",
@@ -148,11 +158,18 @@
     ],
   ]
 } else {
-  _platform_sdk_snapshots += [ [
-        "dds",
-        "../utils/dds:dds",
-        "dds",
-      ] ]
+  _platform_sdk_snapshots += [
+    [
+      "frontend_server",
+      "../utils/kernel-service:frontend_server",
+      "frontend_server",
+    ],
+    [
+      "dds",
+      "../utils/dds:dds",
+      "dds",
+    ],
+  ]
 }
 if (dart_snapshot_kind == "app-jit") {
   _platform_sdk_snapshots += [ [
@@ -173,6 +190,9 @@
       ] ]
 }
 
+# AOT snapshots are not supported on the ia32 architecture, we continue
+# to use JIT snapshots on that architecture, the conditional code below
+# accounts for this.
 if (dart_target_arch != "ia32" && dart_target_arch != "x86") {
   _full_sdk_snapshots =
       _platform_sdk_snapshots + [
@@ -201,7 +221,23 @@
         ],
       ]
 } else {
-  _full_sdk_snapshots = _platform_sdk_snapshots
+  _full_sdk_snapshots = _platform_sdk_snapshots + [
+                          [
+                            "dart2js",
+                            "../utils/compiler:dart2js",
+                            "dart2js",
+                          ],
+                          [
+                            "dartdevc",
+                            "../utils/ddc:dartdevc",
+                            "dartdevc",
+                          ],
+                          [
+                            "kernel_worker",
+                            "../utils/bazel:kernel_worker",
+                            "kernel_worker",
+                          ],
+                        ]
 }
 
 # Libraries that go under lib/
@@ -313,13 +349,13 @@
   # make a link to the symlink rather than the symlink's target, and the
   # relative symlink interpreted from a different containing directory
   # will not find the actual binary.
-  action("copy_dartvm") {
+  action("copy_dart") {
     visibility = [ ":create_common_sdk" ]
-    dart_label = "../runtime/bin:dartvm"
+    dart_label = "../runtime/bin:dart"
     deps = [ dart_label ]
     dart_out = get_label_info(dart_label, "root_out_dir")
-    sources = [ "$dart_out/$dartvm_stripped_binary" ]
-    outputs = [ "$root_out_dir/$dart_sdk_output/bin/$dartvm_stripped_binary" ]
+    sources = [ "$dart_out/$dart_stripped_binary" ]
+    outputs = [ "$root_out_dir/$dart_sdk_output/bin/$dart_stripped_binary" ]
     script = "/bin/ln"
     args = [
       "-snf",
@@ -328,36 +364,18 @@
     ]
   }
 } else {
-  copy("copy_dartvm") {
-    visibility = [ ":create_common_sdk" ]
-    deps = [ "../runtime/bin:dartvm" ]
-    dart_out = get_label_info("../runtime/bin:dartvm", "root_out_dir")
-    sources = [ "$dart_out/${dartvm_stripped_binary}${executable_suffix}" ]
-    if (is_win && dart_lib_export_symbols) {
-      sources += [ "$dart_out/dartvm.lib" ]
-    }
-    if (_has_dot_sym) {
-      sources += [ "$dart_out/dartvm.sym" ]
-    }
-    outputs = [ "$root_out_dir/$dart_sdk_output/bin/{{source_file_part}}" ]
-  }
-}
-
-if (dart_target_arch != "ia32" && dart_target_arch != "x86") {
   copy("copy_dart") {
     visibility = [ ":create_common_sdk" ]
     deps = [ "../runtime/bin:dart" ]
-    src_dir = get_label_info("../runtime/bin:dart", "root_out_dir")
-    sources = [ "$src_dir/${dart_stripped_binary}${executable_suffix}" ]
-    outputs = [ "$root_out_dir/$dart_sdk_output/bin/dart${executable_suffix}" ]
-  }
-} else {
-  copy("copy_dart") {
-    visibility = [ ":create_common_sdk" ]
-    deps = [ "../runtime/bin:dartvm" ]
-    src_dir = get_label_info("../runtime/bin:dartvm", "root_out_dir")
-    sources = [ "$src_dir/${dartvm_stripped_binary}${executable_suffix}" ]
-    outputs = [ "$root_out_dir/$dart_sdk_output/bin/dart${executable_suffix}" ]
+    dart_out = get_label_info("../runtime/bin:dart", "root_out_dir")
+    sources = [ "$dart_out/${dart_stripped_binary}${executable_suffix}" ]
+    if (is_win && dart_lib_export_symbols) {
+      sources += [ "$dart_out/dart.lib" ]
+    }
+    if (_has_dot_sym) {
+      sources += [ "$dart_out/dart.sym" ]
+    }
+    outputs = [ "$root_out_dir/$dart_sdk_output/bin/{{source_file_part}}" ]
   }
 }
 
@@ -481,9 +499,9 @@
     root = root_out_dir
   }
 
-  # The dartdev, dds and dtd snapshots are output to root_out_dir in order to
-  # be compatible with the way the dart sdk is distributed internally.
-  if (snapshot[0] == "dartdev_aot" || snapshot[0] == "dds_aot_product" ||
+  # The dds and dtd snapshots are output to root_out_dir in order to be
+  # compatible with the way the dart sdk is distributed internally.
+  if (snapshot[0] == "dds_aot_product" ||
       snapshot[0] == "dart_tooling_daemon_aot_product") {
     root = root_out_dir
   }
@@ -800,7 +818,6 @@
     ":copy_api_readme",
     ":copy_dart",
     ":copy_dartdoc_files",
-    ":copy_dartvm",
     ":copy_headers",
     ":copy_libraries_specification",
     ":copy_license",
diff --git a/sdk/lib/_internal/vm/bin/vmservice_server.dart b/sdk/lib/_internal/vm/bin/vmservice_server.dart
index b905a34..9ea25e4 100644
--- a/sdk/lib/_internal/vm/bin/vmservice_server.dart
+++ b/sdk/lib/_internal/vm/bin/vmservice_server.dart
@@ -167,14 +167,8 @@
     if (FileSystemEntity.typeSync(script) == FileSystemEntityType.notFound) {
       script = [dartDir, 'dds_aot.dart.snapshot'].join(Platform.pathSeparator);
       if (FileSystemEntity.typeSync(script) == FileSystemEntityType.notFound) {
-        // We could be running on IA32 architecture so check if the JIT
-        // snapshot is available.
         executable = [dartDir, dart].join(Platform.pathSeparator);
-        script = [dartDir, 'dds.dart.snapshot'].join(Platform.pathSeparator);
-        if (FileSystemEntity.typeSync(script) ==
-            FileSystemEntityType.notFound) {
-          script = 'development-service';
-        }
+        script = 'development-service';
       }
     }
 
diff --git a/tests/ffi/native_assets/helpers.dart b/tests/ffi/native_assets/helpers.dart
index 18a82b0..40e95e6 100644
--- a/tests/ffi/native_assets/helpers.dart
+++ b/tests/ffi/native_assets/helpers.dart
@@ -29,10 +29,7 @@
 final cwdUri = Directory.current.uri;
 
 final platformExecutableUriAbsolute = cwdUri.resolveUri(
-  Uri.file(
-    Platform.resolvedExecutable.replaceAll(r'\', '/'),
-    windows: Platform.isWindows,
-  ),
+  Uri.file(Platform.resolvedExecutable),
 );
 
 /// The build folder on desktop platforms.
@@ -61,7 +58,7 @@
   'gen_snapshot$standaloneExtensionExe',
 );
 
-final dartUri = buildUriAbsolute.resolve('dartvm$standaloneExtensionExe');
+final dartUri = buildUriAbsolute.resolve('dart$standaloneExtensionExe');
 
 final dartPrecompiledRuntimeUri = buildUriAbsolute.resolve(
   'dartaotruntime$standaloneExtensionExe',
diff --git a/tests/standalone/regress_41329_absolute_test.dart b/tests/standalone/regress_41329_absolute_test.dart
index 97c333e..e0ae505 100644
--- a/tests/standalone/regress_41329_absolute_test.dart
+++ b/tests/standalone/regress_41329_absolute_test.dart
@@ -28,6 +28,6 @@
   final link2 = Link('dart')..createSync(linkLocation, recursive: true);
   final path = Uri.parse(link2.absolute.path).path;
   Directory.current = origDir;
-  final result = await Process.run('$path', ['--help']);
+  final result = await Process.run('$path', ['help']);
   Expect.equals(result.exitCode, 0);
 }
diff --git a/tests/standalone/regress_41329_relative_test.dart b/tests/standalone/regress_41329_relative_test.dart
index 2c29d9e..e35e126 100644
--- a/tests/standalone/regress_41329_relative_test.dart
+++ b/tests/standalone/regress_41329_relative_test.dart
@@ -27,6 +27,6 @@
   final link2 = Link('dart')..createSync(linkLocation, recursive: true);
   final path = Uri.parse(link2.absolute.path).path;
   Directory.current = origDir;
-  final result = await Process.run('${path}', ['--help']);
+  final result = await Process.run('${path}', ['help']);
   Expect.equals(result.exitCode, 0);
 }
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 756a980..3183926 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -150,7 +150,6 @@
       out/ReleaseX64/gen/kernel_service.dill \
       out/ReleaseX64/dart-sdk \
       out/ReleaseX64/dart \
-      out/ReleaseX64/dartvm \
       out/ReleaseX64/gen_snapshot \
       out/ReleaseX64/kernel-service.dart.snapshot \
       out/ReleaseX64/dart2wasm.snapshot \
diff --git a/tools/gn.py b/tools/gn.py
index ae9deb8..752c6aa 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -280,7 +280,6 @@
     # We don't support stripping on Windows
     if host_os != 'win':
         gn_args['dart_stripped_binary'] = 'exe.stripped/dart'
-        gn_args['dartvm_stripped_binary'] = 'exe.stripped/dartvm'
         gn_args['dart_aotruntime_stripped_binary'] = (
             'exe.stripped/dartaotruntime_product')
         gn_args['gen_snapshot_stripped_binary'] = (
diff --git a/tools/task_kill.py b/tools/task_kill.py
index 7c54c57..46a5bf5 100755
--- a/tools/task_kill.py
+++ b/tools/task_kill.py
@@ -25,8 +25,7 @@
     'win32': {
         'chrome': 'chrome.exe',
         'crashpad_handler': 'crashpad_handler.exe',
-        'dart': 'dart.exe',\
-        'dart_product': 'dart_product.exe',
+        'dart': 'dart.exe',
         'dartaotruntime': 'dartaotruntime.exe',
         'dartaotruntime_product': 'dartaotruntime_product.exe',
         'firefox': 'firefox.exe',
@@ -39,7 +38,6 @@
     'linux': {
         'chrome': 'chrome',
         'dart': 'dart',
-        'dart_product': 'dart_product',
         'dartaotruntime': 'dartaotruntime',
         'dartaotruntime_product': 'dartaotruntime_product',
         'firefox': 'firefox',
@@ -51,7 +49,6 @@
         'chrome': 'Chrome',
         'chrome_helper': 'Chrome Helper',
         'dart': 'dart',
-        'dart_product': 'dart_product',
         'dartaotruntime': 'dartaotruntime',
         'dartaotruntime_product': 'dartaotruntime_product',
         'firefox': 'firefox',
diff --git a/utils/application_snapshot.gni b/utils/application_snapshot.gni
index 414d25d..37037cf 100644
--- a/utils/application_snapshot.gni
+++ b/utils/application_snapshot.gni
@@ -186,7 +186,7 @@
       assert(training_deps != "", "Ignoring unused argument")
     }
   } else {
-    dartvm_action(target_name) {
+    dart_action(target_name) {
       if (defined(invoker.pool)) {
         pool = invoker.pool
       }
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
index c8dfe53..f621419 100644
--- a/utils/compiler/BUILD.gn
+++ b/utils/compiler/BUILD.gn
@@ -75,6 +75,13 @@
   ]
 }
 
+aot_snapshot("dart2js_aot") {
+  deps = [ ":dart2js_create_snapshot_entry" ]
+
+  main_dart = "$target_gen_dir/dart2js.dart"
+  name = "dart2js_aot"
+}
+
 aot_snapshot("dart2js_sdk_aot") {
   deps = [ ":dart2js_create_snapshot_entry" ]
 
diff --git a/utils/dartdev/BUILD.gn b/utils/dartdev/BUILD.gn
index 9a58e7a..89d4379 100644
--- a/utils/dartdev/BUILD.gn
+++ b/utils/dartdev/BUILD.gn
@@ -3,34 +3,8 @@
 # BSD-style license that can be found in the LICENSE file.
 
 import("../../build/dart/copy_tree.gni")
-import("../aot_snapshot.gni")
 import("../application_snapshot.gni")
 
-group("dartdev_aot") {
-  public_deps = [
-    ":copy_prebuilt_devtools",
-    ":dartdev_aot_snapshot",
-  ]
-}
-
-aot_snapshot("dartdev_aot_profile_snapshot") {
-  main_dart = "../../pkg/dartdev/bin/dartdev.dart"
-  output = "$root_out_dir/dartdev_aot_profile.dart.snapshot"
-}
-
-aot_snapshot("dartdev_aot_snapshot") {
-  main_dart = "../../pkg/dartdev/bin/dartdev.dart"
-  output = "$root_out_dir/dartdev_aot.dart.snapshot"
-
-  # dart has dart_product_config applied to it,
-  # so it is built in product mode in both release and
-  # product builds, and is only built in debug mode in debug
-  # builds. The following line ensures that the dart
-  # and dartdev_aot snapshot in an SDK build are
-  # always compatible with each other.
-  force_product_mode = !dart_debug
-}
-
 group("dartdev") {
   public_deps = [
     ":copy_dartdev_snapshot",
@@ -38,12 +12,6 @@
   ]
 }
 
-application_snapshot("generate_dartdev_snapshot") {
-  main_dart = "../../pkg/dartdev/bin/dartdev.dart"
-  training_args = [ "--help" ]
-  output = "$root_gen_dir/dartdev.dart.snapshot"
-}
-
 copy("copy_dartdev_snapshot") {
   visibility = [ ":dartdev" ]
   public_deps = [ ":generate_dartdev_snapshot" ]
@@ -51,11 +19,14 @@
   outputs = [ "$root_out_dir/dartdev.dart.snapshot" ]
 }
 
+application_snapshot("generate_dartdev_snapshot") {
+  main_dart = "../../pkg/dartdev/bin/dartdev.dart"
+  training_args = [ "--help" ]
+  output = "$root_gen_dir/dartdev.dart.snapshot"
+}
+
 copy_tree("copy_prebuilt_devtools") {
-  visibility = [
-    ":dartdev",
-    ":dartdev_aot",
-  ]
+  visibility = [ ":dartdev" ]
   source = "../../third_party/devtools/web"
   dest = "$root_out_dir/devtools"
   exclude = "{}"