@@ -121,20 +121,22 @@ JsStackFrames GetStackFrames(Isolate *isolate) {
121121}
122122
123123// Function to fetch the thread state from the async context store
124- std::string GetThreadState (Isolate *isolate,
125- std::optional<AsyncLocalStorageLookup> store) {
126- if (!store.has_value ()) {
124+ std::string
125+ GetThreadState (Isolate *isolate,
126+ const std::optional<AsyncLocalStorageLookup> &maybe_store) {
127+ if (!maybe_store.has_value ()) {
127128 return " " ;
128129 }
129130
131+ auto store = &maybe_store.value ();
132+
130133#if NODE_MAJOR_VERSION >= 22
131134 // Node.js stores the async local storage in the isolate's
132135 // "ContinuationPreservedEmbedderData" map, keyed by the
133136 // AsyncLocalStorage instance.
134137 // https://github.com/nodejs/node/blob/c6316f9db9869864cea84e5f07585fa08e3e06d2/src/async_context_frame.cc#L37
135138 auto data = isolate->GetContinuationPreservedEmbedderData ();
136- auto async_local_storage_local =
137- store.value ().async_local_storage .Get (isolate);
139+ auto async_local_storage_local = store->async_local_storage .Get (isolate);
138140
139141 if (data.IsEmpty () || async_local_storage_local.IsEmpty ()) {
140142 return " " ;
@@ -150,8 +152,8 @@ std::string GetThreadState(Isolate *isolate,
150152
151153 auto root_store = maybe_root_store.ToLocalChecked ();
152154
153- if (store. value (). storage_key .has_value () && root_store->IsObject ()) {
154- auto local_key = store. value (). storage_key ->Get (isolate);
155+ if (store-> storage_key .has_value () && root_store->IsObject ()) {
156+ auto local_key = store-> storage_key ->Get (isolate);
155157
156158 if (local_key->IsString () || local_key->IsSymbol ()) {
157159 auto root_obj = root_store.As <v8::Object>();
@@ -173,27 +175,25 @@ std::string GetThreadState(Isolate *isolate,
173175
174176struct InterruptArgs {
175177 std::promise<JsStackTrace> *promise;
176- std::optional<AsyncLocalStorageLookup> store;
178+ const std::optional<AsyncLocalStorageLookup> * store;
177179};
178180
179181// Function to be called when an isolate's execution is interrupted
180182static void ExecutionInterrupted (Isolate *isolate, void *data) {
181183 auto args = static_cast <InterruptArgs *>(data);
182184
183- v8::Locker locker (isolate);
184- v8::HandleScope scope (isolate);
185-
186185 auto frames = GetStackFrames (isolate);
187- auto state = GetThreadState (isolate, std::move ( *args->store ) );
186+ auto state = GetThreadState (isolate, *args->store );
188187
189188 args->promise ->set_value ({frames, state});
190189
191190 delete args;
192191}
193192
194193// Function to capture the stack trace of a single isolate
195- JsStackTrace CaptureStackTrace (Isolate *isolate,
196- std::optional<AsyncLocalStorageLookup> store) {
194+ JsStackTrace
195+ CaptureStackTrace (Isolate *isolate,
196+ const std::optional<AsyncLocalStorageLookup> &store) {
197197 if (isolate->IsExecutionTerminating ()) {
198198 return JsStackTrace{{}, " " };
199199 }
@@ -203,7 +203,7 @@ JsStackTrace CaptureStackTrace(Isolate *isolate,
203203
204204 // The v8 isolate must be interrupted to capture the stack trace
205205 isolate->RequestInterrupt (ExecutionInterrupted,
206- new InterruptArgs{&promise, std::move ( store) });
206+ new InterruptArgs{&promise, & store});
207207
208208 return future.get ();
209209}
@@ -228,21 +228,17 @@ void CaptureStackTraces(const FunctionCallbackInfo<Value> &args) {
228228
229229 futures.emplace_back (std::async (
230230 std::launch::async,
231- [thread_isolate, thread_name,
232- poll_state]( std::optional<AsyncLocalStorageLookup> async_store)
231+ [thread_isolate, thread_name, poll_state](
232+ const std::optional<AsyncLocalStorageLookup> & async_store)
233233 -> ThreadResult {
234- return ThreadResult{
235- thread_name,
236- CaptureStackTrace (thread_isolate, std::move (async_store)),
237- poll_state};
234+ return ThreadResult{thread_name,
235+ CaptureStackTrace (thread_isolate, async_store),
236+ poll_state};
238237 },
239- std::move (thread_info.async_store )));
238+ std::cref (thread_info.async_store )));
240239 }
241240 }
242241
243- v8::Locker locker (capture_from_isolate);
244- v8::HandleScope scope (capture_from_isolate);
245-
246242 auto current_context = capture_from_isolate->GetCurrentContext ();
247243
248244 Local<Object> output = Object::New (capture_from_isolate);
@@ -499,9 +495,6 @@ void ThreadPoll(const FunctionCallbackInfo<Value> &args) {
499495void GetThreadsLastSeen (const FunctionCallbackInfo<Value> &args) {
500496 Isolate *isolate = args.GetIsolate ();
501497
502- v8::Locker locker (isolate);
503- v8::HandleScope scope (isolate);
504-
505498 Local<Object> result = Object::New (isolate);
506499 milliseconds now = duration_cast<milliseconds>(
507500 GetUnbiasedMonotonicTime ().time_since_epoch ());
0 commit comments