Version 2.14.0-275.0.dev

Merge commit '074d7da47fe5d0dd36da9548a83de96e3ca098a7' into 'dev'
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 14dacfb..129caeb 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -308,11 +308,6 @@
   return Object::null();
 }
 
-DEFINE_NATIVE_ENTRY(Internal_deoptimizeFunctionsOnStack, 0, 0) {
-  DeoptimizeFunctionsOnStack();
-  return Object::null();
-}
-
 static bool ExtractInterfaceTypeArgs(Zone* zone,
                                      const Class& instance_cls,
                                      const TypeArguments& instance_type_args,
diff --git a/runtime/tests/vm/dart/isolates/regress_46539_test.dart b/runtime/tests/vm/dart/isolates/regress_46539_test.dart
deleted file mode 100644
index b07d133..0000000
--- a/runtime/tests/vm/dart/isolates/regress_46539_test.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2021, 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.
-
-// VMOptions=--optimization-filter=foo --enable-isolate-groups --experimental-enable-isolate-groups-jit --no-use-osr --optimization-counter-threshold=1 --deterministic
-
-// Important: This is a regression test for a concurrency issue, if this test
-// is flaky it is essentially failing!
-
-import 'dart:async';
-import 'dart:io';
-import 'dart:isolate';
-import 'dart:_internal' show VMInternalsForTesting;
-
-import 'package:expect/expect.dart';
-
-const int isolateCount = 3;
-const int deoptIsolateId = 0;
-const int polyIsolateId = 1;
-
-final bool isAOT = Platform.executable.contains('dart_precompiled_runtime');
-
-main() async {
-  // This test will cause deoptimizations (via helper in `dart:_internal`) and
-  // does therefore not run in AOT.
-  if (isAOT) return;
-
-  final onExit = ReceivePort();
-  final onError = ReceivePort()
-    ..listen((error) {
-      print('Error: $error');
-      exitCode = 250;
-    });
-  for (int i = 0; i < isolateCount; ++i) {
-    await Isolate.spawn(isolate, i,
-        onExit: onExit.sendPort, onError: onError.sendPort);
-  }
-  final onExits = StreamIterator(onExit);
-  for (int i = 0; i < isolateCount; ++i) {
-    Expect.isTrue(await onExits.moveNext());
-  }
-  onExits.cancel();
-  onError.close();
-}
-
-final globalA = A();
-final globalB = B();
-
-isolate(int isolateId) {
-  final A a = isolateId == polyIsolateId ? globalB : globalA;
-  if (isolateId == polyIsolateId) {
-    // We start deopting after 1 second.
-    sleep(500000);
-  }
-
-  // This runs in unoptimized mode and will therefore do switchable calls.
-  final sw = Stopwatch()..start();
-  while (sw.elapsedMicroseconds < 2000000) {
-    a.foo(isolateId);
-    a.foo(isolateId);
-    a.foo(isolateId);
-    a.foo(isolateId);
-  }
-}
-
-class A {
-  @pragma('vm:never-inline')
-  foo(int isolateId) {
-    if (isolateId == deoptIsolateId) {
-      VMInternalsForTesting.deoptimizeFunctionsOnStack();
-    }
-  }
-}
-
-class B implements A {
-  @pragma('vm:never-inline')
-  foo(int isolateId) {}
-}
-
-void sleep(int us) {
-  final sw = Stopwatch()..start();
-  while (sw.elapsedMicroseconds < us);
-}
diff --git a/runtime/tests/vm/dart_2/isolates/regress_46539_test.dart b/runtime/tests/vm/dart_2/isolates/regress_46539_test.dart
deleted file mode 100644
index b07d133..0000000
--- a/runtime/tests/vm/dart_2/isolates/regress_46539_test.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright (c) 2021, 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.
-
-// VMOptions=--optimization-filter=foo --enable-isolate-groups --experimental-enable-isolate-groups-jit --no-use-osr --optimization-counter-threshold=1 --deterministic
-
-// Important: This is a regression test for a concurrency issue, if this test
-// is flaky it is essentially failing!
-
-import 'dart:async';
-import 'dart:io';
-import 'dart:isolate';
-import 'dart:_internal' show VMInternalsForTesting;
-
-import 'package:expect/expect.dart';
-
-const int isolateCount = 3;
-const int deoptIsolateId = 0;
-const int polyIsolateId = 1;
-
-final bool isAOT = Platform.executable.contains('dart_precompiled_runtime');
-
-main() async {
-  // This test will cause deoptimizations (via helper in `dart:_internal`) and
-  // does therefore not run in AOT.
-  if (isAOT) return;
-
-  final onExit = ReceivePort();
-  final onError = ReceivePort()
-    ..listen((error) {
-      print('Error: $error');
-      exitCode = 250;
-    });
-  for (int i = 0; i < isolateCount; ++i) {
-    await Isolate.spawn(isolate, i,
-        onExit: onExit.sendPort, onError: onError.sendPort);
-  }
-  final onExits = StreamIterator(onExit);
-  for (int i = 0; i < isolateCount; ++i) {
-    Expect.isTrue(await onExits.moveNext());
-  }
-  onExits.cancel();
-  onError.close();
-}
-
-final globalA = A();
-final globalB = B();
-
-isolate(int isolateId) {
-  final A a = isolateId == polyIsolateId ? globalB : globalA;
-  if (isolateId == polyIsolateId) {
-    // We start deopting after 1 second.
-    sleep(500000);
-  }
-
-  // This runs in unoptimized mode and will therefore do switchable calls.
-  final sw = Stopwatch()..start();
-  while (sw.elapsedMicroseconds < 2000000) {
-    a.foo(isolateId);
-    a.foo(isolateId);
-    a.foo(isolateId);
-    a.foo(isolateId);
-  }
-}
-
-class A {
-  @pragma('vm:never-inline')
-  foo(int isolateId) {
-    if (isolateId == deoptIsolateId) {
-      VMInternalsForTesting.deoptimizeFunctionsOnStack();
-    }
-  }
-}
-
-class B implements A {
-  @pragma('vm:never-inline')
-  foo(int isolateId) {}
-}
-
-void sleep(int us) {
-  final sw = Stopwatch()..start();
-  while (sw.elapsedMicroseconds < us);
-}
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index e9710df6..7eb3452 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -344,7 +344,6 @@
   V(Internal_allocateTwoByteString, 1)                                         \
   V(Internal_writeIntoOneByteString, 3)                                        \
   V(Internal_writeIntoTwoByteString, 3)                                        \
-  V(Internal_deoptimizeFunctionsOnStack, 0)                                    \
   V(InvocationMirror_unpackTypeArguments, 2)                                   \
   V(NoSuchMethodError_existingMethodSignature, 3)                              \
   V(WeakProperty_getKey, 1)                                                    \
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 8b831c3..50f9b49 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -689,13 +689,13 @@
   // calling into the runtime.
   __ EnterStubFrame();
   __ LoadImmediate(R1, 0);
-  __ Push(R1);  // Result slot.
+  __ Push(R9);  // Preserve cache (guarded CID as Smi).
   __ Push(R0);  // Preserve receiver.
-  __ Push(R9);  // Preserve cache.
-  __ CallRuntime(kFixCallersTargetMonomorphicRuntimeEntry, 2);
-  __ Pop(R9);  // Restore cache.
+  __ Push(R1);
+  __ CallRuntime(kFixCallersTargetMonomorphicRuntimeEntry, 0);
+  __ Pop(CODE_REG);
   __ Pop(R0);  // Restore receiver.
-  __ Pop(CODE_REG);  // Get target Code object.
+  __ Pop(R9);  // Restore cache (guarded CID as Smi).
   // Remove the stub frame.
   __ LeaveStubFrame();
   // Jump to the dart function.
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 4d92ced..1e36ee5 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -804,13 +804,13 @@
   // Create a stub frame as we are pushing some objects on the stack before
   // calling into the runtime.
   __ EnterStubFrame();
-  __ Push(ZR);  // Result slot.
-  __ Push(R0);  // Preserve receiver.
   __ Push(R5);  // Preserve cache (guarded CID as Smi).
-  __ CallRuntime(kFixCallersTargetMonomorphicRuntimeEntry, 2);
-  __ Pop(R5);        // Restore cache (guarded CID as Smi).
-  __ Pop(R0);        // Restore receiver.
-  __ Pop(CODE_REG);  // Get target Code object.
+  __ Push(R0);  // Preserve receiver.
+  __ Push(ZR);
+  __ CallRuntime(kFixCallersTargetMonomorphicRuntimeEntry, 0);
+  __ Pop(CODE_REG);
+  __ Pop(R0);  // Restore receiver.
+  __ Pop(R5);  // Restore cache (guarded CID as Smi).
   // Remove the stub frame.
   __ LeaveStubFrame();
   // Jump to the dart function.
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 03fd79d..16ef27a 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -515,13 +515,13 @@
   __ Bind(&monomorphic);
   // This was a switchable call.
   __ EnterStubFrame();
-  __ pushl(Immediate(0));  // Result slot.
-  __ pushl(EBX);           // Preserve receiver.
   __ pushl(ECX);           // Preserve cache (guarded CID as Smi).
-  __ CallRuntime(kFixCallersTargetMonomorphicRuntimeEntry, 2);
-  __ popl(ECX);       // Restore cache (guarded CID as Smi).
+  __ pushl(EBX);           // Preserve receiver.
+  __ pushl(Immediate(0));  // Result slot.
+  __ CallRuntime(kFixCallersTargetMonomorphicRuntimeEntry, 0);
+  __ popl(CODE_REG);  // Get Code object.
   __ popl(EBX);       // Restore receiver.
-  __ popl(CODE_REG);  // Get target Code object.
+  __ popl(ECX);       // Restore cache (guarded CID as Smi).
   __ movl(EAX, FieldAddress(CODE_REG, target::Code::entry_point_offset(
                                           CodeEntryKind::kMonomorphic)));
   __ LeaveFrame();
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index 71c094c..e776269 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -721,13 +721,13 @@
   __ movq(CODE_REG,
           Address(THR, target::Thread::fix_callers_target_code_offset()));
   __ EnterStubFrame();
-  __ pushq(Immediate(0));  // Result slot.
+  __ pushq(RBX);           // Preserve cache (guarded CID as Smi).
   __ pushq(RDX);           // Preserve receiver.
-  __ pushq(RBX);           // Preserve cache.
-  __ CallRuntime(kFixCallersTargetMonomorphicRuntimeEntry, 2);
-  __ popq(RBX);       // Restore cache.
+  __ pushq(Immediate(0));  // Result slot.
+  __ CallRuntime(kFixCallersTargetMonomorphicRuntimeEntry, 0);
+  __ popq(CODE_REG);  // Get Code object.
   __ popq(RDX);       // Restore receiver.
-  __ popq(CODE_REG);  // Get target Code object.
+  __ popq(RBX);       // Restore cache (guarded CID as Smi).
   __ movq(RAX, FieldAddress(CODE_REG, target::Code::entry_point_offset(
                                           CodeEntryKind::kMonomorphic)));
   __ LeaveStubFrame();
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index c7305ca..856d43f 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1613,7 +1613,6 @@
 enum class MissHandler {
   kInlineCacheMiss,
   kSwitchableCallMiss,
-  kFixCallersTargetMonomorphic,
 };
 
 // Handles updating of type feedback and possible patching of instance calls.
@@ -2095,8 +2094,7 @@
   // If we instead only insert a new ICData entry and will return to the IC stub
   // which will call the target, the stub will take care of the increment.
   const bool call_target_directly =
-      miss_handler_ == MissHandler::kInlineCacheMiss ||
-      miss_handler_ == MissHandler::kFixCallersTargetMonomorphic;
+      miss_handler_ == MissHandler::kInlineCacheMiss;
   const intptr_t invocation_count = call_target_directly ? 1 : 0;
 
   if (caller_arguments_.length() == 1) {
@@ -2134,21 +2132,12 @@
                                      const Function& target) {
   // In JIT we can have two different miss handlers to which we return slightly
   // differently.
-  switch (miss_handler_) {
-    case MissHandler::kSwitchableCallMiss: {
-      arguments_.SetArgAt(0, stub);  // Second return value.
-      arguments_.SetReturn(data);
-      break;
-    }
-    case MissHandler::kFixCallersTargetMonomorphic: {
-      const auto& new_code = Code::Handle(zone_, target.EnsureHasCode());
-      arguments_.SetReturn(new_code);
-      break;
-    }
-    case MissHandler::kInlineCacheMiss: {
-      arguments_.SetReturn(target);
-      break;
-    }
+  if (miss_handler_ == MissHandler::kSwitchableCallMiss) {
+    arguments_.SetArgAt(0, stub);  // Second return value.
+    arguments_.SetReturn(data);
+  } else {
+    ASSERT(miss_handler_ == MissHandler::kInlineCacheMiss);
+    arguments_.SetReturn(target);
   }
 }
 
@@ -2975,25 +2964,49 @@
 
 // The caller must be a monomorphic call from unoptimized code.
 // Patch call to point to new target.
-DEFINE_RUNTIME_ENTRY(FixCallersTargetMonomorphic, 2) {
+DEFINE_RUNTIME_ENTRY(FixCallersTargetMonomorphic, 0) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
-  const Array& switchable_call_data =
-      Array::CheckedHandle(zone, arguments.ArgAt(1));
+  StackFrameIterator iterator(ValidationPolicy::kDontValidateFrames, thread,
+                              StackFrameIterator::kNoCrossThreadIteration);
+  StackFrame* frame = iterator.NextFrame();
+  ASSERT(frame != NULL);
+  while (frame->IsStubFrame() || frame->IsExitFrame()) {
+    frame = iterator.NextFrame();
+    ASSERT(frame != NULL);
+  }
+  if (frame->IsEntryFrame()) {
+    // Since function's current code is always unpatched, the entry frame always
+    // calls to unpatched code.
+    UNREACHABLE();
+  }
+  ASSERT(frame->IsDartFrame());
+  const Code& caller_code = Code::Handle(zone, frame->LookupDartCode());
+  RELEASE_ASSERT(!caller_code.is_optimized());
 
-  DartFrameIterator iterator(thread,
-                             StackFrameIterator::kNoCrossThreadIteration);
-  StackFrame* caller_frame = iterator.NextFrame();
-  const auto& caller_code = Code::Handle(zone, caller_frame->LookupDartCode());
-  const auto& caller_function =
-      Function::Handle(zone, caller_frame->LookupDartFunction());
-
-  GrowableArray<const Instance*> caller_arguments(1);
-  caller_arguments.Add(&receiver);
-  PatchableCallHandler handler(
-      thread, caller_arguments, MissHandler::kFixCallersTargetMonomorphic,
-      arguments, caller_frame, caller_code, caller_function);
-  handler.ResolveSwitchAndReturn(switchable_call_data);
+  Object& cache = Object::Handle(zone);
+  const Code& old_target_code = Code::Handle(
+      zone, CodePatcher::GetInstanceCallAt(frame->pc(), caller_code, &cache));
+  const Function& target_function =
+      Function::Handle(zone, old_target_code.function());
+  const Code& current_target_code =
+      Code::Handle(zone, target_function.EnsureHasCode());
+  CodePatcher::PatchInstanceCallAt(frame->pc(), caller_code, cache,
+                                   current_target_code);
+  if (FLAG_trace_patching) {
+    OS::PrintErr(
+        "FixCallersTargetMonomorphic: caller %#" Px
+        " "
+        "target '%s' -> %#" Px " (%s)\n",
+        frame->pc(), target_function.ToFullyQualifiedCString(),
+        current_target_code.EntryPoint(),
+        current_target_code.is_optimized() ? "optimized" : "unoptimized");
+  }
+  // With isolate groups enabled, it is possible that the target code
+  // has been deactivated just now(as a result of re-optimizatin for example),
+  // which will result in another run through FixCallersTarget.
+  ASSERT(!current_target_code.IsDisabled() ||
+         IsolateGroup::AreIsolateGroupsEnabled());
+  arguments.SetReturn(current_target_code);
 #else
   UNREACHABLE();
 #endif
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index 67501fb..6cc2388 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -193,9 +193,6 @@
 abstract class VMInternalsForTesting {
   // This function can be used by tests to enforce garbage collection.
   static void collectAllGarbage() native "Internal_collectAllGarbage";
-
-  static void deoptimizeFunctionsOnStack()
-      native "Internal_deoptimizeFunctionsOnStack";
 }
 
 @patch
diff --git a/tools/VERSION b/tools/VERSION
index 65fd8e1..b35aa89 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 14
 PATCH 0
-PRERELEASE 274
+PRERELEASE 275
 PRERELEASE_PATCH 0
\ No newline at end of file
diff --git a/tools/apps/update_homebrew/.gitignore b/tools/apps/update_homebrew/.gitignore
deleted file mode 100644
index e4da250a3..0000000
--- a/tools/apps/update_homebrew/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-.packages
-.dart_tool
diff --git a/tools/apps/update_homebrew/bin/generate.dart b/tools/apps/update_homebrew/bin/generate.dart
deleted file mode 100644
index ea29e06..0000000
--- a/tools/apps/update_homebrew/bin/generate.dart
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:path/path.dart' as p;
-import 'package:stack_trace/stack_trace.dart';
-import 'package:update_homebrew/update_homebrew.dart';
-
-void main(List<String> args) async {
-  final parser = ArgParser()
-    ..addOption('revision', abbr: 'r')
-    ..addOption('channel', abbr: 'c', allowed: supportedChannels);
-
-  final options = parser.parse(args);
-  final revision = options['revision'] as String;
-  final channel = options['channel'] as String;
-  if ([revision, channel].contains(null)) {
-    print(
-        "Usage: generate.dart -r revision -c channel <path_to_existing_dart.rb>");
-    exitCode = 1;
-    return;
-  }
-
-  if (options.rest.length != 1) {
-    print("Pass in the path to an existing '$dartRbFileName' file.");
-    exitCode = 1;
-    return;
-  }
-  final existingDartRb = options.rest.single;
-
-  var file = File(existingDartRb);
-
-  if (!file.existsSync()) {
-    print("Expected '$existingDartRb' to exist.");
-    exitCode = 1;
-    return;
-  }
-
-  if (p.basename(existingDartRb) != dartRbFileName) {
-    print("Expected provided path to end with '$dartRbFileName'.");
-    exitCode = 1;
-  }
-
-  await Chain.capture(() async {
-    await writeHomebrewInfo(channel, revision, file.parent.path);
-  }, onError: (error, chain) {
-    print(error);
-    print(chain.terse);
-    exitCode = 1;
-  });
-}
diff --git a/tools/apps/update_homebrew/bin/ssh_with_key b/tools/apps/update_homebrew/bin/ssh_with_key
deleted file mode 100755
index 6df4a04..0000000
--- a/tools/apps/update_homebrew/bin/ssh_with_key
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/usr/bin/env bash
-ssh -i $SSH_KEY_PATH $@
diff --git a/tools/apps/update_homebrew/bin/update_homebrew.dart b/tools/apps/update_homebrew/bin/update_homebrew.dart
deleted file mode 100644
index 68dc9e0..0000000
--- a/tools/apps/update_homebrew/bin/update_homebrew.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-
-import 'package:args/args.dart';
-import 'package:stack_trace/stack_trace.dart';
-import 'package:update_homebrew/update_homebrew.dart';
-
-void main(List<String> args) async {
-  final parser = ArgParser()
-    ..addFlag('dry-run', abbr: 'n')
-    ..addOption('revision', abbr: 'r')
-    ..addOption('channel', abbr: 'c', allowed: supportedChannels)
-    ..addOption('key', abbr: 'k');
-  final options = parser.parse(args);
-  final dryRun = options['dry-run'] as bool;
-  final revision = options['revision'] as String;
-  final channel = options['channel'] as String;
-  if ([revision, channel].contains(null)) {
-    print(
-        "Usage: update_homebrew.dart -r version -c channel [-k ssh_key] [-n]\n"
-        "  ssh_key should allow pushes to $githubRepo on github");
-    exitCode = 1;
-    return;
-  }
-
-  Map<String, String> gitEnvironment;
-
-  final key = options['key'] as String;
-  if (key != null) {
-    final sshWrapper = Platform.script.resolve('ssh_with_key').toFilePath();
-    gitEnvironment = {'GIT_SSH': sshWrapper, 'SSH_KEY_PATH': key};
-  }
-
-  await Chain.capture(() async {
-    var tempDir = await Directory.systemTemp.createTemp('update_homebrew');
-
-    try {
-      var repository = tempDir.path;
-
-      await runGit(['clone', 'git@github.com:$githubRepo.git', '.'], repository,
-          gitEnvironment);
-      await writeHomebrewInfo(channel, revision, repository);
-      await runGit([
-        'commit',
-        '-a',
-        '-m',
-        'Updated $channel branch to revision $revision'
-      ], repository, gitEnvironment);
-      if (dryRun) {
-        await runGit(['diff', 'origin/master'], repository, gitEnvironment);
-      } else {
-        await runGit(['push'], repository, gitEnvironment);
-      }
-    } finally {
-      await tempDir.delete(recursive: true);
-    }
-  }, onError: (error, chain) {
-    print(error);
-    print(chain.terse);
-    exitCode = 1;
-  });
-}
diff --git a/tools/apps/update_homebrew/lib/src/impl.dart b/tools/apps/update_homebrew/lib/src/impl.dart
deleted file mode 100644
index 2a07403..0000000
--- a/tools/apps/update_homebrew/lib/src/impl.dart
+++ /dev/null
@@ -1,65 +0,0 @@
-part of '../update_homebrew.dart';
-
-const _files = [
-  'dartsdk-macos-x64-release.zip',
-  'dartsdk-linux-x64-release.zip',
-  'dartsdk-linux-arm64-release.zip',
-  'dartsdk-linux-ia32-release.zip',
-  'dartsdk-linux-arm-release.zip',
-];
-
-const _host = 'https://storage.googleapis.com/dart-archive/channels';
-
-Future<String> _getHash256(
-    String channel, String version, String download) async {
-  var client = http.Client();
-  try {
-    var api = storage.StorageApi(client);
-    var url = 'channels/$channel/release/$version/sdk/$download.sha256sum';
-    var media = await api.objects.get('dart-archive', url,
-        downloadOptions: DownloadOptions.FullMedia) as Media;
-    var hashLine = await ascii.decodeStream(media.stream);
-    return RegExp('[0-9a-fA-F]*').stringMatch(hashLine);
-  } finally {
-    client.close();
-  }
-}
-
-Future<void> _updateFormula(String channel, File file, String version,
-    Map<String, String> hashes) async {
-  var contents = await file.readAsString();
-
-  // Replace the version identifier. Formulas with stable and pre-release
-  // versions have multiple identifiers and only the right one should be
-  // updated.
-  var versionId = channel == 'stable'
-      ? RegExp(r'version \"\d+\.\d+.\d+\"')
-      : RegExp(r'version \"\d+\.\d+.\d+\-.+\"');
-  contents = contents.replaceAll(versionId, 'version "$version"');
-
-  // Extract files and hashes that are stored in the formula in this format:
-  //  url "<url base>/<channel>/release/<version>/sdk/<artifact>.zip"
-  //  sha256 "<hash>"
-  var filesAndHashes = RegExp(
-      'channels/$channel/release'
-      r'/(\d[\w\d\-\.]*)/sdk/([\w\d\-\.]+)\"\n(\s+)sha256 \"[\da-f]+\"',
-      multiLine: true);
-  contents = contents.replaceAllMapped(filesAndHashes, (m) {
-    var currentVersion = m.group(1);
-    if (currentVersion == version) {
-      throw new ArgumentError(
-          'Channel $channel is already at version $version in homebrew.');
-    }
-    var artifact = m.group(2);
-    var indent = m.group(3);
-    return 'channels/$channel/release/$version/sdk/$artifact"\n'
-        '${indent}sha256 "${hashes[artifact]}"';
-  });
-  await file.writeAsString(contents, flush: true);
-}
-
-Future<Map<String, String>> _getHashes(String channel, String version) async {
-  return <String, String>{
-    for (var file in _files) file: await _getHash256(channel, version, file)
-  };
-}
diff --git a/tools/apps/update_homebrew/lib/update_homebrew.dart b/tools/apps/update_homebrew/lib/update_homebrew.dart
deleted file mode 100644
index e38e51f..0000000
--- a/tools/apps/update_homebrew/lib/update_homebrew.dart
+++ /dev/null
@@ -1,38 +0,0 @@
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-
-import 'package:_discoveryapis_commons/_discoveryapis_commons.dart';
-import 'package:googleapis/storage/v1.dart' as storage;
-import 'package:http/http.dart' as http;
-import 'package:path/path.dart' as p;
-
-part 'src/impl.dart';
-
-const githubRepo = 'dart-lang/homebrew-dart';
-
-const formulaByChannel = {
-  'beta': 'dart-beta.rb',
-  'dev': 'dart.rb',
-  'stable': 'dart.rb'
-};
-
-Iterable<String> get supportedChannels => formulaByChannel.keys;
-
-Future<void> writeHomebrewInfo(
-    String channel, String version, String repository) async {
-  var formula = File(p.join(repository, formulaByChannel[channel]));
-  var hashes = await _getHashes(channel, version);
-  await _updateFormula(channel, formula, version, hashes);
-}
-
-Future<void> runGit(List<String> args, String repository,
-    Map<String, String> gitEnvironment) async {
-  print("git ${args.join(' ')}");
-
-  var result = await Process.run('git', args,
-      workingDirectory: repository, environment: gitEnvironment);
-
-  print(result.stdout);
-  print(result.stderr);
-}
diff --git a/tools/apps/update_homebrew/pubspec.yaml b/tools/apps/update_homebrew/pubspec.yaml
deleted file mode 100644
index 9089614..0000000
--- a/tools/apps/update_homebrew/pubspec.yaml
+++ /dev/null
@@ -1,13 +0,0 @@
-name: update_homebrew
-
-publish_to: none
-environment:
-  sdk: '>=2.0.0 <3.0.0'
-
-dependencies:
-  _discoveryapis_commons: ^0.1.3+1
-  args: ^1.5.0
-  googleapis: ^0.51.0
-  http: ^0.11.1+1
-  path: ^1.4.1
-  stack_trace: ^1.3.2