@@ -105,8 +105,17 @@ inline AliasedFloat64Array& AsyncHooks::async_ids_stack() {
105105 return async_ids_stack_;
106106}
107107
108- inline v8::Local<v8::Array> AsyncHooks::execution_async_resources () {
109- return PersistentToLocal::Strong (execution_async_resources_);
108+ v8::Local<v8::Array> AsyncHooks::js_execution_async_resources () {
109+ if (UNLIKELY (js_execution_async_resources_.IsEmpty ())) {
110+ js_execution_async_resources_.Reset (
111+ env ()->isolate (), v8::Array::New (env ()->isolate ()));
112+ }
113+ return PersistentToLocal::Strong (js_execution_async_resources_);
114+ }
115+
116+ v8::Local<v8::Object> AsyncHooks::native_execution_async_resource (size_t i) {
117+ if (i >= native_execution_async_resources_.size ()) return {};
118+ return PersistentToLocal::Strong (native_execution_async_resources_[i]);
110119}
111120
112121inline v8::Local<v8::String> AsyncHooks::provider_string (int idx) {
@@ -124,7 +133,7 @@ inline Environment* AsyncHooks::env() {
124133// Remember to keep this code aligned with pushAsyncContext() in JS.
125134inline void AsyncHooks::push_async_context (double async_id,
126135 double trigger_async_id,
127- v8::Local<v8::Value > resource) {
136+ v8::Local<v8::Object > resource) {
128137 v8::HandleScope handle_scope (env ()->isolate ());
129138
130139 // Since async_hooks is experimental, do only perform the check
@@ -143,8 +152,12 @@ inline void AsyncHooks::push_async_context(double async_id,
143152 async_id_fields_[kExecutionAsyncId ] = async_id;
144153 async_id_fields_[kTriggerAsyncId ] = trigger_async_id;
145154
146- auto resources = execution_async_resources ();
147- USE (resources->Set (env ()->context (), offset, resource));
155+ #ifdef DEBUG
156+ for (uint32_t i = offset; i < native_execution_async_resources_.size (); i++)
157+ CHECK (native_execution_async_resources_[i].IsEmpty ());
158+ #endif
159+ native_execution_async_resources_.resize (offset + 1 );
160+ native_execution_async_resources_[offset].Reset (env ()->isolate (), resource);
148161}
149162
150163// Remember to keep this code aligned with popAsyncContext() in JS.
@@ -177,17 +190,44 @@ inline bool AsyncHooks::pop_async_context(double async_id) {
177190 async_id_fields_[kTriggerAsyncId ] = async_ids_stack_[2 * offset + 1 ];
178191 fields_[kStackLength ] = offset;
179192
180- auto resources = execution_async_resources ();
181- USE (resources->Delete (env ()->context (), offset));
193+ if (LIKELY (offset < native_execution_async_resources_.size () &&
194+ !native_execution_async_resources_[offset].IsEmpty ())) {
195+ #ifdef DEBUG
196+ for (uint32_t i = offset + 1 ;
197+ i < native_execution_async_resources_.size ();
198+ i++) {
199+ CHECK (native_execution_async_resources_[i].IsEmpty ());
200+ }
201+ #endif
202+ native_execution_async_resources_.resize (offset);
203+ if (native_execution_async_resources_.size () <
204+ native_execution_async_resources_.capacity () / 2 &&
205+ native_execution_async_resources_.size () > 16 ) {
206+ native_execution_async_resources_.shrink_to_fit ();
207+ }
208+ }
209+
210+ if (UNLIKELY (js_execution_async_resources ()->Length () > offset)) {
211+ USE (js_execution_async_resources ()->Set (
212+ env ()->context (),
213+ env ()->length_string (),
214+ v8::Integer::NewFromUnsigned (env ()->isolate (), offset)));
215+ }
182216
183217 return fields_[kStackLength ] > 0 ;
184218}
185219
186- // Keep in sync with clearAsyncIdStack in lib/internal/async_hooks.js.
187- inline void AsyncHooks::clear_async_id_stack () {
188- auto isolate = env ()->isolate ();
220+ void AsyncHooks::clear_async_id_stack () {
221+ v8::Isolate* isolate = env ()->isolate ();
189222 v8::HandleScope handle_scope (isolate);
190- execution_async_resources_.Reset (isolate, v8::Array::New (isolate));
223+ if (!js_execution_async_resources_.IsEmpty ()) {
224+ USE (PersistentToLocal::Strong (js_execution_async_resources_)->Set (
225+ env ()->context (),
226+ env ()->length_string (),
227+ v8::Integer::NewFromUnsigned (isolate, 0 )));
228+ }
229+ native_execution_async_resources_.clear ();
230+ native_execution_async_resources_.shrink_to_fit ();
191231
192232 async_id_fields_[kExecutionAsyncId ] = 0 ;
193233 async_id_fields_[kTriggerAsyncId ] = 0 ;
0 commit comments