Revert "[VM/Service] Record timeline events representing completed microtasks"

This reverts commit 22021cc12014feffd33f9a3d50e37447a980b99b.

Reason for revert: I didn't gate stacktrace collection behind `--profile-microtasks` correctly

Original change's description:
> [VM/Service] Record timeline events representing completed microtasks
>
> TEST=pkg/vm_service/test/timeline_events_for_completed_microtasks_test
>
> CoreLibraryReviewExempt: This CL does not include any core library API
> changes, it only modifies the implementation of microtasks (by
> instrumenting them).
> Change-Id: I54d886db9519c73f9e3218a9cc1c46bc9fe9acc3
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/420221
> Commit-Queue: Derek Xu <derekx@google.com>
> Reviewed-by: Ben Konyi <bkonyi@google.com>

No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Change-Id: I82b4a49764956254c51bd3abfee0cb3cd1b329d2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/423920
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Jessy Yameogo <yjessy@google.com>
Commit-Queue: Jessy Yameogo <yjessy@google.com>
Auto-Submit: Derek Xu <derekx@google.com>
diff --git a/pkg/vm_service/test/common/service_test_common.dart b/pkg/vm_service/test/common/service_test_common.dart
index fc208ac..ae04eb2 100644
--- a/pkg/vm_service/test/common/service_test_common.dart
+++ b/pkg/vm_service/test/common/service_test_common.dart
@@ -5,13 +5,11 @@
 library service_test_common;
 
 import 'dart:async';
-import 'dart:collection' show HashMap;
 import 'dart:typed_data';
 
 import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
 import 'package:vm_service/vm_service.dart';
-import 'package:vm_service_protos/vm_service_protos.dart' show DebugAnnotation;
 
 typedef IsolateTest = Future<void> Function(
   VmService service,
@@ -916,19 +914,3 @@
     }
   };
 }
-
-Map<String, String> mapFromListOfDebugAnnotations(
-  List<DebugAnnotation> debugAnnotations,
-) {
-  return HashMap.fromEntries(
-    debugAnnotations.map((a) {
-      if (a.hasStringValue()) {
-        return MapEntry(a.name, a.stringValue);
-      } else if (a.hasLegacyJsonValue()) {
-        return MapEntry(a.name, a.legacyJsonValue);
-      } else {
-        throw 'We should not be writing annotations without values';
-      }
-    }),
-  );
-}
diff --git a/pkg/vm_service/test/get_perfetto_vm_timeline_rpc_test.dart b/pkg/vm_service/test/get_perfetto_vm_timeline_rpc_test.dart
index 850b649..dcd2c7b 100644
--- a/pkg/vm_service/test/get_perfetto_vm_timeline_rpc_test.dart
+++ b/pkg/vm_service/test/get_perfetto_vm_timeline_rpc_test.dart
@@ -5,6 +5,7 @@
 // VMOptions=
 // VMOptions=--intern_strings_when_writing_perfetto_timeline
 
+import 'dart:collection';
 import 'dart:convert';
 import 'dart:developer';
 import 'dart:io' show Platform;
@@ -13,7 +14,6 @@
 import 'package:vm_service/vm_service.dart' hide Timeline;
 import 'package:vm_service_protos/vm_service_protos.dart';
 
-import 'common/service_test_common.dart' show mapFromListOfDebugAnnotations;
 import 'common/test_helper.dart';
 
 void primeTimeline() {
@@ -143,6 +143,22 @@
   return result;
 }
 
+Map<String, String> mapFromListOfDebugAnnotations(
+  List<DebugAnnotation> debugAnnotations,
+) {
+  return HashMap.fromEntries(
+    debugAnnotations.map((a) {
+      if (a.hasStringValue()) {
+        return MapEntry(a.name, a.stringValue);
+      } else if (a.hasLegacyJsonValue()) {
+        return MapEntry(a.name, a.legacyJsonValue);
+      } else {
+        throw 'We should not be writing annotations without values';
+      }
+    }),
+  );
+}
+
 void checkThatAllEventsHaveIsolateNumbers(Iterable<TrackEvent> events) {
   for (final event in events) {
     final debugAnnotations =
diff --git a/pkg/vm_service/test/timeline_events_for_completed_microtasks_test.dart b/pkg/vm_service/test/timeline_events_for_completed_microtasks_test.dart
deleted file mode 100644
index 8dfe37e..0000000
--- a/pkg/vm_service/test/timeline_events_for_completed_microtasks_test.dart
+++ /dev/null
@@ -1,64 +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.
-
-import 'dart:async';
-import 'dart:convert';
-
-import 'package:test/test.dart';
-import 'package:vm_service/vm_service.dart' hide Timeline;
-import 'package:vm_service_protos/vm_service_protos.dart';
-
-import 'common/service_test_common.dart' show mapFromListOfDebugAnnotations;
-import 'common/test_helper.dart';
-
-const String shortFile = 'timeline_events_for_completed_microtasks_test.dart';
-
-void primeTimeline() {
-  for (int i = 0; i < 5; i++) {
-    scheduleMicrotask(() {});
-  }
-}
-
-Iterable<TrackEvent> extractTrackEventsFromTracePackets(
-  List<TracePacket> packets,
-) =>
-    packets
-        .where((packet) => packet.hasTrackEvent())
-        .map((packet) => packet.trackEvent);
-
-final tests = <IsolateTest>[
-  (VmService service, IsolateRef isolateRef) async {
-    final result = await service.getPerfettoVMTimeline();
-
-    final trace = Trace.fromBuffer(base64Decode(result.trace!));
-    final packets = trace.packet;
-    final mainIsolateMicrotaskEvents =
-        extractTrackEventsFromTracePackets(packets)
-            .where((event) => event.name == 'Microtask')
-            .where((event) {
-      final debugAnnotations =
-          mapFromListOfDebugAnnotations(event.debugAnnotations);
-      return debugAnnotations['isolateId'] == isolateRef.id;
-    });
-    expect(mainIsolateMicrotaskEvents.length, greaterThanOrEqualTo(5));
-
-    for (final event in mainIsolateMicrotaskEvents) {
-      final debugAnnotations =
-          mapFromListOfDebugAnnotations(event.debugAnnotations);
-      expect(debugAnnotations['microtaskId'], isNotNull);
-      expect(
-        debugAnnotations['stack trace captured when microtask was enqueued'],
-        contains(shortFile),
-      );
-    }
-  },
-];
-
-void main([args = const <String>[]]) => runIsolateTests(
-      args,
-      tests,
-      shortFile,
-      testeeBefore: primeTimeline,
-      extraArgs: ['--profile-microtasks', '--timeline-streams=Microtask'],
-    );
diff --git a/runtime/lib/async.cc b/runtime/lib/async.cc
index 883ec1d..538c20e 100644
--- a/runtime/lib/async.cc
+++ b/runtime/lib/async.cc
@@ -5,17 +5,12 @@
 #include "vm/bootstrap_natives.h"
 #include "vm/debugger.h"
 #include "vm/exceptions.h"
-#include "vm/flags.h"
-#include "vm/microtask_mirror_queues.h"
 #include "vm/native_entry.h"
 #include "vm/object_store.h"
 #include "vm/runtime_entry.h"
 
 namespace dart {
 
-// This flag is defined in "vm/microtask_mirror_queues.cc".
-DECLARE_FLAG(bool, profile_microtasks);
-
 DEFINE_NATIVE_ENTRY(AsyncStarMoveNext_debuggerStepCheck, 0, 1) {
 #if !defined(PRODUCT)
   GET_NON_NULL_NATIVE_ARGUMENT(Closure, generator, arguments->NativeArgAt(0));
@@ -61,41 +56,4 @@
   return closure.ptr();
 }
 
-DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onScheduleAsyncCallback, 0, 1) {
-#if !defined(PRODUCT)
-  if (FLAG_profile_microtasks) {
-    GET_NON_NULL_NATIVE_ARGUMENT(StackTrace, stack_trace,
-                                 arguments->NativeArgAt(0));
-    MicrotaskMirrorQueues::GetQueue(static_cast<int64_t>(isolate->main_port()))
-        ->OnScheduleAsyncCallback(stack_trace);
-  }
-#endif  // !defined(PRODUCT)
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onSchedulePriorityAsyncCallback,
-                    0,
-                    0) {
-#if !defined(PRODUCT)
-  if (FLAG_profile_microtasks) {
-    MicrotaskMirrorQueues::GetQueue(static_cast<int64_t>(isolate->main_port()))
-        ->OnSchedulePriorityAsyncCallback();
-  }
-#endif  // !defined(PRODUCT)
-  return Object::null();
-}
-
-DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onAsyncCallbackComplete, 0, 2) {
-#if !defined(PRODUCT)
-  if (FLAG_profile_microtasks) {
-    GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_time,
-                                 arguments->NativeArgAt(0));
-    GET_NON_NULL_NATIVE_ARGUMENT(Integer, end_time, arguments->NativeArgAt(1));
-    MicrotaskMirrorQueues::GetQueue(static_cast<int64_t>(isolate->main_port()))
-        ->OnAsyncCallbackComplete(start_time.Value(), end_time.Value());
-  }
-#endif  // !defined(PRODUCT)
-  return Object::null();
-}
-
 }  // namespace dart
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 64c2096..1562fcc 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -149,9 +149,6 @@
   V(Timeline_getTraceClock, 0)                                                 \
   V(Timeline_isDartStreamEnabled, 0)                                           \
   V(Timeline_reportTaskEvent, 5)                                               \
-  V(MicrotaskMirrorQueue_onScheduleAsyncCallback, 1)                           \
-  V(MicrotaskMirrorQueue_onSchedulePriorityAsyncCallback, 0)                   \
-  V(MicrotaskMirrorQueue_onAsyncCallbackComplete, 2)                           \
   V(TypedDataBase_length, 1)                                                   \
   V(TypedDataBase_setClampedRange, 5)                                          \
   V(TypedData_GetFloat32, 2)                                                   \
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index d17a7a8..093cbef 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -33,7 +33,6 @@
 #include "vm/kernel_isolate.h"
 #include "vm/message_handler.h"
 #include "vm/metrics.h"
-#include "vm/microtask_mirror_queues.h"
 #include "vm/native_entry.h"
 #include "vm/native_message_handler.h"
 #include "vm/object.h"
@@ -765,7 +764,6 @@
   }
   Timeline::Cleanup();
 #endif
-  NOT_IN_PRODUCT(MicrotaskMirrorQueues::CleanUp());
   Zone::Cleanup();
   Random::Cleanup();
   // Delete the current thread's TLS and set it's TLS to null.
diff --git a/runtime/vm/microtask_mirror_queues.cc b/runtime/vm/microtask_mirror_queues.cc
deleted file mode 100644
index 74a0156..0000000
--- a/runtime/vm/microtask_mirror_queues.cc
+++ /dev/null
@@ -1,99 +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.
-
-#if !defined(PRODUCT)
-
-#include "vm/microtask_mirror_queues.h"
-
-#include <utility>
-
-#include "platform/hashmap.h"
-#include "vm/flags.h"
-#include "vm/object.h"
-#include "vm/timeline.h"
-
-namespace dart {
-
-DEFINE_FLAG(
-    bool,
-    profile_microtasks,
-    false,
-    "Record information about each microtask. Information about completed "
-    "microtasks will be written to the \"Microtask\" timeline stream.");
-
-MicrotaskMirrorQueue* MicrotaskMirrorQueues::GetQueue(int64_t isolate_id) {
-  void* key = reinterpret_cast<void*>(isolate_id);
-  const intptr_t hash = Utils::WordHash(isolate_id);
-
-  MutexLocker ml(&isolate_id_to_queue_lock_);
-
-  SimpleHashMap::Entry* entry = isolate_id_to_queue_.Lookup(key, hash, true);
-  if (entry->value == nullptr) {
-    entry->value = new MicrotaskMirrorQueue();
-  }
-  return static_cast<MicrotaskMirrorQueue*>(entry->value);
-}
-
-void MicrotaskMirrorQueue::OnScheduleAsyncCallback(const StackTrace& st) {
-  if (is_disabled_) {
-    return;
-  }
-
-  queue_.PushBack(MicrotaskMirrorQueueEntry(
-      next_available_id_++, CStringUniquePtr(Utils::StrDup(st.ToCString()))));
-}
-
-void MicrotaskMirrorQueue::OnSchedulePriorityAsyncCallback() {
-  // If this function is called, it means that the microtask queue can no longer
-  // be accurately modeled by a |ListQueue|. This only ever gets called when an
-  // exception goes unhandled, so we just handle the situation by disabling all
-  // further reads from / writes to this queue.
-  is_disabled_ = true;
-}
-
-void MicrotaskMirrorQueue::OnAsyncCallbackComplete(int64_t start_time,
-                                                   int64_t end_time) {
-  if (is_disabled_) {
-    return;
-  }
-
-  ASSERT(queue_.Length() >= 1);
-  MicrotaskMirrorQueueEntry&& front = std::move(queue_.PopFront());
-
-  TimelineStream* stream = Timeline::GetMicrotaskStream();
-  ASSERT(stream != nullptr);
-  TimelineEvent* event = stream->StartEvent();
-  if (event != nullptr) {
-    if (start_time < end_time) {
-      event->Duration("Microtask", start_time, end_time);
-    } else {
-      event->Instant("Microtask", start_time);
-    }
-
-    event->SetNumArguments(2);
-    event->FormatArgument(0, "microtaskId", "%" Pd, front.id());
-    event->SetArgument(1, "stack trace captured when microtask was enqueued",
-                       front.ReleaseStackTrace());
-    event->Complete();
-  }
-}
-
-Mutex MicrotaskMirrorQueues::isolate_id_to_queue_lock_;
-
-SimpleHashMap MicrotaskMirrorQueues::isolate_id_to_queue_(
-    &SimpleHashMap::SamePointerValue,
-    MicrotaskMirrorQueues::kIsolateIdToQueueInitialCapacity);
-
-void MicrotaskMirrorQueues::CleanUp() {
-  for (SimpleHashMap::Entry* entry = isolate_id_to_queue_.Start();
-       entry != nullptr; entry = isolate_id_to_queue_.Next(entry)) {
-    MicrotaskMirrorQueue* value =
-        static_cast<MicrotaskMirrorQueue*>(entry->value);
-    delete value;
-  }
-}
-
-}  // namespace dart
-
-#endif  // !defined(PRODUCT)
diff --git a/runtime/vm/microtask_mirror_queues.h b/runtime/vm/microtask_mirror_queues.h
deleted file mode 100644
index f47192f..0000000
--- a/runtime/vm/microtask_mirror_queues.h
+++ /dev/null
@@ -1,78 +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_VM_MICROTASK_MIRROR_QUEUES_H_
-#define RUNTIME_VM_MICROTASK_MIRROR_QUEUES_H_
-
-#include <utility>
-
-#include "platform/hashmap.h"
-#include "platform/list_queue.h"
-#include "platform/synchronization.h"
-#include "platform/utils.h"
-#include "vm/stack_frame.h"
-
-namespace dart {
-
-class MicrotaskMirrorQueueEntry : public ValueObject {
- public:
-  static constexpr intptr_t kInvalidId = -1;
-
-  MicrotaskMirrorQueueEntry() : id_(kInvalidId), stack_trace_(nullptr) {}
-  MicrotaskMirrorQueueEntry(intptr_t id, CStringUniquePtr&& st)
-      : id_(id), stack_trace_(std::move(st)) {}
-
-  void operator=(MicrotaskMirrorQueueEntry&& other) {
-    id_ = other.id_;
-    stack_trace_.swap(other.stack_trace_);
-  }
-
-  intptr_t id() const { return id_; }
-  CStringUniquePtr const& stack_trace() const { return stack_trace_; }
-  /// Releases ownership of the stack trace string that this entry is holding.
-  char* ReleaseStackTrace() { return stack_trace_.release(); }
-
- private:
-  intptr_t id_;
-  CStringUniquePtr stack_trace_;
-};
-
-/// A queue that mirrors the microtask queue of an isolate. This allows the VM
-/// Service to return information about microtasks.
-class MicrotaskMirrorQueue {
- public:
-  MicrotaskMirrorQueue()
-      : is_disabled_(false), queue_(), next_available_id_(0) {}
-
-  void OnScheduleAsyncCallback(const StackTrace& st);
-  void OnSchedulePriorityAsyncCallback();
-  void OnAsyncCallbackComplete(int64_t start_time, int64_t end_time);
-
- private:
-  bool is_disabled_;
-  ListQueue<MicrotaskMirrorQueueEntry> queue_;
-  // The unique ID that will be assigned to the next |MicrotaskMirrorQueueEntry|
-  // added to |queue_|.
-  intptr_t next_available_id_;
-
-  DISALLOW_COPY_AND_ASSIGN(MicrotaskMirrorQueue);
-};
-
-/// A wrapper around a map from isolate IDs to |MicrotaskMirrorQueue|s.
-class MicrotaskMirrorQueues : public AllStatic {
- public:
-  static MicrotaskMirrorQueue* GetQueue(int64_t isolate_id);
-  static void CleanUp();
-
- private:
-  static constexpr intptr_t kIsolateIdToQueueInitialCapacity = 1 << 4;  // 16
-  static Mutex isolate_id_to_queue_lock_;
-  static SimpleHashMap isolate_id_to_queue_;
-
-  DISALLOW_COPY_AND_ASSIGN(MicrotaskMirrorQueues);
-};
-
-}  // namespace dart
-
-#endif  // RUNTIME_VM_MICROTASK_MIRROR_QUEUES_H_
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index 70079cb..a983cbc 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -177,8 +177,6 @@
   "message_snapshot.h",
   "metrics.cc",
   "metrics.h",
-  "microtask_mirror_queues.cc",
-  "microtask_mirror_queues.h",
   "native_arguments.h",
   "native_entry.cc",
   "native_entry.h",
diff --git a/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart b/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart
index 3fc50aa..dd5bb1a 100644
--- a/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart
+++ b/sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart
@@ -5,24 +5,6 @@
 part of "async_patch.dart";
 
 @patch
-abstract final class _MicrotaskMirrorQueue {
-  @patch
-  @pragma("vm:external-name", "MicrotaskMirrorQueue_onScheduleAsyncCallback")
-  external static void _onScheduleAsyncCallback(StackTrace st);
-
-  @patch
-  @pragma(
-    "vm:external-name",
-    "MicrotaskMirrorQueue_onSchedulePriorityAsyncCallback",
-  )
-  external static void _onSchedulePriorityAsyncCallback();
-
-  @patch
-  @pragma("vm:external-name", "MicrotaskMirrorQueue_onAsyncCallbackComplete")
-  external static void _onAsyncCallbackComplete(int startTime, int endTime);
-}
-
-@patch
 class _AsyncRun {
   @patch
   static void _scheduleImmediate(void callback()) {
diff --git a/sdk/lib/async/async.dart b/sdk/lib/async/async.dart
index 7808477..af2f4c3 100644
--- a/sdk/lib/async/async.dart
+++ b/sdk/lib/async/async.dart
@@ -104,7 +104,6 @@
 library dart.async;
 
 import "dart:collection" show HashMap;
-import 'dart:developer' show Timeline;
 import "dart:_internal"
     show
         CastStream,
diff --git a/sdk/lib/async/schedule_microtask.dart b/sdk/lib/async/schedule_microtask.dart
index 66db6a0..25e7c03 100644
--- a/sdk/lib/async/schedule_microtask.dart
+++ b/sdk/lib/async/schedule_microtask.dart
@@ -37,17 +37,7 @@
     var next = entry.next;
     _nextCallback = next;
     if (next == null) _lastCallback = null;
-    if (const bool.fromEnvironment("dart.vm.product")) {
-      (entry.callback)();
-    } else {
-      final callbackStartTime = Timeline.now;
-      (entry.callback)();
-      final callbackEndTime = Timeline.now;
-      _MicrotaskMirrorQueue._onAsyncCallbackComplete(
-        callbackStartTime,
-        callbackEndTime,
-      );
-    }
+    (entry.callback)();
   }
 }
 
@@ -72,9 +62,6 @@
 /// microtasks, but as part of the current system event.
 void _scheduleAsyncCallback(_AsyncCallback callback) {
   _AsyncCallbackEntry newEntry = _AsyncCallbackEntry(callback);
-  if (!const bool.fromEnvironment("dart.vm.product")) {
-    _MicrotaskMirrorQueue._onScheduleAsyncCallback(StackTrace.current);
-  }
   _AsyncCallbackEntry? lastCallback = _lastCallback;
   if (lastCallback == null) {
     _nextCallback = _lastCallback = newEntry;
@@ -100,9 +87,6 @@
     return;
   }
   _AsyncCallbackEntry entry = _AsyncCallbackEntry(callback);
-  if (!const bool.fromEnvironment("dart.vm.product")) {
-    _MicrotaskMirrorQueue._onSchedulePriorityAsyncCallback();
-  }
   _AsyncCallbackEntry? lastPriorityCallback = _lastPriorityCallback;
   if (lastPriorityCallback == null) {
     entry.next = _nextCallback;
@@ -164,15 +148,6 @@
   Zone.current.scheduleMicrotask(Zone.current.bindCallbackGuarded(callback));
 }
 
-abstract final class _MicrotaskMirrorQueue {
-  // The VM implementations of these methods are in
-  // sdk/lib/_internal/vm/lib/schedule_microtask_patch.dart.
-
-  static void _onScheduleAsyncCallback(StackTrace st) {}
-  static void _onSchedulePriorityAsyncCallback() {}
-  static void _onAsyncCallbackComplete(int startTime, int endTime) {}
-}
-
 class _AsyncRun {
   /// Schedule the given callback before any other event in the event-loop.
   external static void _scheduleImmediate(void Function() callback);