@@ -53,11 +53,11 @@ inline MultiIsolatePlatform* IsolateData::platform() const {
53
53
return platform_;
54
54
}
55
55
56
- inline Environment::AsyncHooks::AsyncHooks (v8::Isolate* isolate )
57
- : isolate_( isolate),
58
- fields_(isolate, kFieldsCount ),
59
- async_id_fields_(isolate, kUidFieldsCount ) {
60
- v8::HandleScope handle_scope (isolate_ );
56
+ inline Environment::AsyncHooks::AsyncHooks ()
57
+ : async_ids_stack_(env()-> isolate(), 16 * 2 ),
58
+ fields_(env()-> isolate() , kFieldsCount),
59
+ async_id_fields_(env()-> isolate() , kUidFieldsCount) {
60
+ v8::HandleScope handle_scope (env ()-> isolate () );
61
61
62
62
// Always perform async_hooks checks, not just when async_hooks is enabled.
63
63
// TODO(AndreasMadsen): Consider removing this for LTS releases.
@@ -81,9 +81,9 @@ inline Environment::AsyncHooks::AsyncHooks(v8::Isolate* isolate)
81
81
// strings can be retrieved quickly.
82
82
#define V (Provider ) \
83
83
providers_[AsyncWrap::PROVIDER_ ## Provider].Set ( \
84
- isolate_, \
84
+ env ()-> isolate (), \
85
85
v8::String::NewFromOneByte ( \
86
- isolate_, \
86
+ env ()-> isolate (), \
87
87
reinterpret_cast <const uint8_t *>(#Provider), \
88
88
v8::NewStringType::kInternalized , \
89
89
sizeof (#Provider) - 1 ).ToLocalChecked ());
@@ -101,15 +101,25 @@ Environment::AsyncHooks::async_id_fields() {
101
101
return async_id_fields_;
102
102
}
103
103
104
+ inline AliasedBuffer<double , v8::Float64Array>&
105
+ Environment::AsyncHooks::async_ids_stack () {
106
+ return async_ids_stack_;
107
+ }
108
+
104
109
inline v8::Local<v8::String> Environment::AsyncHooks::provider_string (int idx) {
105
- return providers_[idx].Get (isolate_ );
110
+ return providers_[idx].Get (env ()-> isolate () );
106
111
}
107
112
108
113
inline void Environment::AsyncHooks::no_force_checks () {
109
114
// fields_ does not have the -= operator defined
110
115
fields_[kCheck ] = fields_[kCheck ] - 1 ;
111
116
}
112
117
118
+ inline Environment* Environment::AsyncHooks::env () {
119
+ return Environment::ForAsyncHooks (this );
120
+ }
121
+
122
+ // Remember to keep this code aligned with pushAsyncIds() in JS.
113
123
inline void Environment::AsyncHooks::push_async_ids (double async_id,
114
124
double trigger_async_id) {
115
125
// Since async_hooks is experimental, do only perform the check
@@ -119,16 +129,21 @@ inline void Environment::AsyncHooks::push_async_ids(double async_id,
119
129
CHECK_GE (trigger_async_id, -1 );
120
130
}
121
131
122
- async_ids_stack_.push ({ async_id_fields_[kExecutionAsyncId ],
123
- async_id_fields_[kTriggerAsyncId ] });
132
+ uint32_t offset = fields_[kStackLength ];
133
+ if (offset * 2 >= async_ids_stack_.Length ())
134
+ grow_async_ids_stack ();
135
+ async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId ];
136
+ async_ids_stack_[2 * offset + 1 ] = async_id_fields_[kTriggerAsyncId ];
137
+ fields_[kStackLength ] = fields_[kStackLength ] + 1 ;
124
138
async_id_fields_[kExecutionAsyncId ] = async_id;
125
139
async_id_fields_[kTriggerAsyncId ] = trigger_async_id;
126
140
}
127
141
142
+ // Remember to keep this code aligned with popAsyncIds() in JS.
128
143
inline bool Environment::AsyncHooks::pop_async_id (double async_id) {
129
144
// In case of an exception then this may have already been reset, if the
130
145
// stack was multiple MakeCallback()'s deep.
131
- if (async_ids_stack_. empty () ) return false ;
146
+ if (fields_[ kStackLength ] == 0 ) return false ;
132
147
133
148
// Ask for the async_id to be restored as a check that the stack
134
149
// hasn't been corrupted.
@@ -140,32 +155,27 @@ inline bool Environment::AsyncHooks::pop_async_id(double async_id) {
140
155
" actual: %.f, expected: %.f)\n " ,
141
156
async_id_fields_.GetValue (kExecutionAsyncId ),
142
157
async_id);
143
- Environment* env = Environment::GetCurrent (isolate_);
144
158
DumpBacktrace (stderr);
145
159
fflush (stderr);
146
- if (!env->abort_on_uncaught_exception ())
160
+ if (!env () ->abort_on_uncaught_exception ())
147
161
exit (1 );
148
162
fprintf (stderr, " \n " );
149
163
fflush (stderr);
150
164
ABORT_NO_BACKTRACE ();
151
165
}
152
166
153
- auto async_ids = async_ids_stack_.top ();
154
- async_ids_stack_.pop ();
155
- async_id_fields_[kExecutionAsyncId ] = async_ids.async_id ;
156
- async_id_fields_[kTriggerAsyncId ] = async_ids.trigger_async_id ;
157
- return !async_ids_stack_.empty ();
158
- }
167
+ uint32_t offset = fields_[kStackLength ] - 1 ;
168
+ async_id_fields_[kExecutionAsyncId ] = async_ids_stack_[2 * offset];
169
+ async_id_fields_[kTriggerAsyncId ] = async_ids_stack_[2 * offset + 1 ];
170
+ fields_[kStackLength ] = offset;
159
171
160
- inline size_t Environment::AsyncHooks::stack_size () {
161
- return async_ids_stack_.size ();
172
+ return fields_[kStackLength ] > 0 ;
162
173
}
163
174
164
175
inline void Environment::AsyncHooks::clear_async_id_stack () {
165
- while (!async_ids_stack_.empty ())
166
- async_ids_stack_.pop ();
167
176
async_id_fields_[kExecutionAsyncId ] = 0 ;
168
177
async_id_fields_[kTriggerAsyncId ] = 0 ;
178
+ fields_[kStackLength ] = 0 ;
169
179
}
170
180
171
181
inline Environment::AsyncHooks::DefaultTriggerAsyncIdScope
@@ -189,6 +199,11 @@ inline Environment::AsyncHooks::DefaultTriggerAsyncIdScope
189
199
}
190
200
191
201
202
+ Environment* Environment::ForAsyncHooks (AsyncHooks* hooks) {
203
+ return ContainerOf (&Environment::async_hooks_, hooks);
204
+ }
205
+
206
+
192
207
inline Environment::AsyncCallbackScope::AsyncCallbackScope (Environment* env)
193
208
: env_(env) {
194
209
env_->makecallback_cntr_ ++;
@@ -254,7 +269,6 @@ inline Environment::Environment(IsolateData* isolate_data,
254
269
v8::Local<v8::Context> context)
255
270
: isolate_(context->GetIsolate ()),
256
271
isolate_data_(isolate_data),
257
- async_hooks_(context->GetIsolate ()),
258
272
timer_base_(uv_now(isolate_data->event_loop ())),
259
273
using_domains_(false ),
260
274
printed_error_(false ),
0 commit comments