clavin

#46963: refactor: replace gin_helper::MicrotasksScope with v8::MicrotasksScope

Merged
Created: May 6, 2025, 1:32:37 PM
Merged: May 7, 2025, 3:10:35 PM
2 comments
Target: main

gin_helper::MicrotasksScope only has a handful of remaining uses. This PR replaces them with v8::MicrotasksScope directly and removes the helper class.

Nearly all uses have ignore_browser_checkpoint = true, making them no-ops in the browser process. Since the browser process runs with the explicit microtasks policy, using v8::MicrotasksScope is also a no-op because it only triggers a checkpoint in the scoped policy. Therefore, we can safely replace gin_helper::MicrotasksScope with v8::MicrotasksScope in these cases and they still don't trigger microtasks to run.

There are two remaining cases where the browser process runs a checkpoint (i.e. ignore_browser_checkpoint = false):

First, in ErrorMessageListener in node_bindings.cc we have a contradictory scope that runs a microtask checkpoint in the browser but specifies "do not run microtasks" elsewhere. Based on its history, it seems that the intention follows the more explicit "do not run microtasks" and that the browser checkpoint was an unintended result of the error we fixed in #43185. Therefore, we can correct this to be ignore_browser_checkpoint = true and apply the same logic as above to replace it.

That leaves only one (real) microtask checkpoint in the browser, which lives in gin_helper/promise.cc. Since this behavior is legitimate and now unique, I augmented PromiseBase::SettleScope to run the browser checkpoint instead.

As a result, there were no remaining uses and I was able to remove the gin_helper::MicrotasksScope class.

Fixes #46669

Differences

To aid in review, I'm explicitly highlighting the differences introduced in this change. That said, I believe these differences are all insignificant improvements.

  • gin_helper::MicrotasksScope had a std::optional wrapping its v8::MicrotasksScope. In the browser process branch, the v8::MicrotasksScope would not be created nor destroyed. With this change, v8::MicrotasksScope is no longer wrapped in std::optional. As part of its construction and destruction it does some bookkeeping on the microtask queue, but does not trigger any microtasks to run.
  • gin_helper::MicrotasksScope would run a microtask checkpoint at creation when ignore_browser_checkpoint = false. For the microtask checkpoint explicitly added to gin_helper/promise.cc, I chose to match the v8::MicrotasksScope behavior of triggering the checkpoint at destruction instead. This aligns with the behavior before gin_helper::MicrotaskScope was introduced.
    • Small difference: gin_helper::MicrotasksScope would call v8::MicrotasksScope::PerformCheckpoint(isolate) which triggered microtasks in the default microtask queue; the newly integrated checkpoint in gin_helper/promise.cc uses the microtask queue that is associated with the v8::Context instead.

Checklist

Release Notes

Notes: none

Backports

No Backports Requested

This pull request doesn't have any backports requested or created for older release branches.

What are backports?

Backports are copies of changes made to the main branch that are applied to older release branches. They ensure that bug fixes and important changes are available in maintained older versions of Electron.

Semver Impact

Major
Breaking changes
Minor
New features
Patch
Bug fixes
None
Docs, tests, etc.

Semantic Versioning helps users understand the impact of updates:

  • Major (X.y.z): Breaking changes that may require code modifications
  • Minor (x.Y.z): New features that maintain backward compatibility
  • Patch (x.y.Z): Bug fixes that don't change the API
  • None: Changes that don't affect using facing parts of Electron