Repository: electron/electron
Pull request: perf: avoid redundant Promise.GetContext calls

#### Description of Change

Several Promise methods call `GetContext()` multiple times. From looking at the assembly in obj/electron/electron_lib/promise.o, these redundant calls are actually being made -- they aren't optmized out.

This PR keeps the return value in a local variable to avoid extra calls.

#### Checklist

- [x] PR description included and stakeholders cc'd
- [x] `npm test` passes
- [x] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: none.

Changed files:
filename: shell/common/gin_helper/promise.cc
patch: @@ -30,35 +30,38 @@ PromiseBase& PromiseBase::operator=(PromiseBase&&) = default;
 
 v8::Maybe<bool> PromiseBase::Reject() {
   v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = GetContext();
   gin_helper::MicrotasksScope microtasks_scope{
-      isolate(), GetContext()->GetMicrotaskQueue(), false,
+      isolate(), context->GetMicrotaskQueue(), false,
       v8::MicrotasksScope::kRunMicrotasks};
-  v8::Context::Scope context_scope(GetContext());
+  v8::Context::Scope context_scope(context);
 
-  return GetInner()->Reject(GetContext(), v8::Undefined(isolate()));
+  return GetInner()->Reject(context, v8::Undefined(isolate()));
 }
 
 v8::Maybe<bool> PromiseBase::Reject(v8::Local<v8::Value> except) {
   v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = GetContext();
   gin_helper::MicrotasksScope microtasks_scope{
-      isolate(), GetContext()->GetMicrotaskQueue(), false,
+      isolate(), context->GetMicrotaskQueue(), false,
       v8::MicrotasksScope::kRunMicrotasks};
-  v8::Context::Scope context_scope(GetContext());
+  v8::Context::Scope context_scope(context);
 
-  return GetInner()->Reject(GetContext(), except);
+  return GetInner()->Reject(context, except);
 }
 
 v8::Maybe<bool> PromiseBase::RejectWithErrorMessage(
     const std::string_view message) {
   v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = GetContext();
   gin_helper::MicrotasksScope microtasks_scope{
-      isolate(), GetContext()->GetMicrotaskQueue(), false,
+      isolate(), context->GetMicrotaskQueue(), false,
       v8::MicrotasksScope::kRunMicrotasks};
-  v8::Context::Scope context_scope(GetContext());
+  v8::Context::Scope context_scope(context);
 
   v8::Local<v8::Value> error =
       v8::Exception::Error(gin::StringToV8(isolate(), message));
-  return GetInner()->Reject(GetContext(), (error));
+  return GetInner()->Reject(context, (error));
 }
 
 v8::Local<v8::Context> PromiseBase::GetContext() const {
@@ -95,12 +98,13 @@ v8::Local<v8::Promise> Promise<void>::ResolvedPromise(v8::Isolate* isolate) {
 
 v8::Maybe<bool> Promise<void>::Resolve() {
   v8::HandleScope handle_scope(isolate());
+  v8::Local<v8::Context> context = GetContext();
   gin_helper::MicrotasksScope microtasks_scope{
-      isolate(), GetContext()->GetMicrotaskQueue(), false,
+      isolate(), context->GetMicrotaskQueue(), false,
       v8::MicrotasksScope::kRunMicrotasks};
-  v8::Context::Scope context_scope(GetContext());
+  v8::Context::Scope context_scope(context);
 
-  return GetInner()->Resolve(GetContext(), v8::Undefined(isolate()));
+  return GetInner()->Resolve(context, v8::Undefined(isolate()));
 }
 
 }  // namespace gin_helper

filename: shell/common/gin_helper/promise.h
patch: @@ -123,13 +123,13 @@ class Promise : public PromiseBase {
   v8::Maybe<bool> Resolve(const RT& value) {
     gin_helper::Locker locker(isolate());
     v8::HandleScope handle_scope(isolate());
+    v8::Local<v8::Context> context = GetContext();
     gin_helper::MicrotasksScope microtasks_scope{
-        isolate(), GetContext()->GetMicrotaskQueue(), false,
+        isolate(), context->GetMicrotaskQueue(), false,
         v8::MicrotasksScope::kRunMicrotasks};
-    v8::Context::Scope context_scope(GetContext());
+    v8::Context::Scope context_scope(context);
 
-    return GetInner()->Resolve(GetContext(),
-                               gin::ConvertToV8(isolate(), value));
+    return GetInner()->Resolve(context, gin::ConvertToV8(isolate(), value));
   }
 
   template <typename... ResolveType>
@@ -144,12 +144,13 @@ class Promise : public PromiseBase {
         "promises resolve type");
     gin_helper::Locker locker(isolate());
     v8::HandleScope handle_scope(isolate());
-    v8::Context::Scope context_scope(GetContext());
+    v8::Local<v8::Context> context = GetContext();
+    v8::Context::Scope context_scope(context);
 
     v8::Local<v8::Value> value = gin::ConvertToV8(isolate(), std::move(cb));
     v8::Local<v8::Function> handler = value.As<v8::Function>();
 
-    return GetHandle()->Then(GetContext(), handler);
+    return GetHandle()->Then(context, handler);
   }
 };