GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/env-inl.h Lines: 570 575 99.1 %
Date: 2019-07-27 22:37:30 Branches: 66 94 70.2 %

Line Branch Exec Source
1
// Copyright Joyent, Inc. and other Node contributors.
2
//
3
// Permission is hereby granted, free of charge, to any person obtaining a
4
// copy of this software and associated documentation files (the
5
// "Software"), to deal in the Software without restriction, including
6
// without limitation the rights to use, copy, modify, merge, publish,
7
// distribute, sublicense, and/or sell copies of the Software, and to permit
8
// persons to whom the Software is furnished to do so, subject to the
9
// following conditions:
10
//
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
13
//
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
17
// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
18
// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20
// USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22
#ifndef SRC_ENV_INL_H_
23
#define SRC_ENV_INL_H_
24
25
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
26
27
#include "aliased_buffer.h"
28
#include "env.h"
29
#include "node.h"
30
#include "util-inl.h"
31
#include "uv.h"
32
#include "v8.h"
33
#include "node_perf_common.h"
34
#include "node_context_data.h"
35
36
#include <cstddef>
37
#include <cstdint>
38
39
#include <utility>
40
41
namespace node {
42
43
10710
inline v8::Isolate* IsolateData::isolate() const {
44
10710
  return isolate_;
45
}
46
47
1302450
inline uv_loop_t* IsolateData::event_loop() const {
48
1302450
  return event_loop_;
49
}
50
51
323847
inline bool IsolateData::uses_node_allocator() const {
52
323847
  return uses_node_allocator_;
53
}
54
55
549978
inline v8::ArrayBuffer::Allocator* IsolateData::allocator() const {
56
549978
  return allocator_;
57
}
58
59
329151
inline NodeArrayBufferAllocator* IsolateData::node_allocator() const {
60
329151
  return node_allocator_;
61
}
62
63
233455
inline MultiIsolatePlatform* IsolateData::platform() const {
64
233455
  return platform_;
65
}
66
67
4967
inline AsyncHooks::AsyncHooks()
68
    : async_ids_stack_(env()->isolate(), 16 * 2),
69
      fields_(env()->isolate(), kFieldsCount),
70
4967
      async_id_fields_(env()->isolate(), kUidFieldsCount) {
71
4967
  v8::HandleScope handle_scope(env()->isolate());
72
73
  // Always perform async_hooks checks, not just when async_hooks is enabled.
74
  // TODO(AndreasMadsen): Consider removing this for LTS releases.
75
  // See discussion in https://github.com/nodejs/node/pull/15454
76
  // When removing this, do it by reverting the commit. Otherwise the test
77
  // and flag changes won't be included.
78
4967
  fields_[kCheck] = 1;
79
80
  // kDefaultTriggerAsyncId should be -1, this indicates that there is no
81
  // specified default value and it should fallback to the executionAsyncId.
82
  // 0 is not used as the magic value, because that indicates a missing context
83
  // which is different from a default context.
84
4967
  async_id_fields_[AsyncHooks::kDefaultTriggerAsyncId] = -1;
85
86
  // kAsyncIdCounter should start at 1 because that'll be the id the execution
87
  // context during bootstrap (code that runs before entering uv_run()).
88
4967
  async_id_fields_[AsyncHooks::kAsyncIdCounter] = 1;
89
90
  // Create all the provider strings that will be passed to JS. Place them in
91
  // an array so the array index matches the PROVIDER id offset. This way the
92
  // strings can be retrieved quickly.
93
#define V(Provider)                                                           \
94
  providers_[AsyncWrap::PROVIDER_ ## Provider].Set(                           \
95
      env()->isolate(),                                                       \
96
      v8::String::NewFromOneByte(                                             \
97
        env()->isolate(),                                                     \
98
        reinterpret_cast<const uint8_t*>(#Provider),                          \
99
        v8::NewStringType::kInternalized,                                     \
100
        sizeof(#Provider) - 1).ToLocalChecked());
101
432129
  NODE_ASYNC_PROVIDER_TYPES(V)
102
#undef V
103
4967
}
104
4324057
inline AliasedUint32Array& AsyncHooks::fields() {
105
4324057
  return fields_;
106
}
107
108
4169981
inline AliasedFloat64Array& AsyncHooks::async_id_fields() {
109
4169981
  return async_id_fields_;
110
}
111
112
4965
inline AliasedFloat64Array& AsyncHooks::async_ids_stack() {
113
4965
  return async_ids_stack_;
114
}
115
116
273431
inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) {
117
546862
  return providers_[idx].Get(env()->isolate());
118
}
119
120
1
inline void AsyncHooks::no_force_checks() {
121
1
  fields_[kCheck] -= 1;
122
1
}
123
124
720483
inline Environment* AsyncHooks::env() {
125
720483
  return Environment::ForAsyncHooks(this);
126
}
127
128
// Remember to keep this code aligned with pushAsyncIds() in JS.
129
1015483
inline void AsyncHooks::push_async_ids(double async_id,
130
                                       double trigger_async_id) {
131
  // Since async_hooks is experimental, do only perform the check
132
  // when async_hooks is enabled.
133
1015483
  if (fields_[kCheck] > 0) {
134
1015487
    CHECK_GE(async_id, -1);
135
1015487
    CHECK_GE(trigger_async_id, -1);
136
  }
137
138
1015489
  uint32_t offset = fields_[kStackLength];
139
1015480
  if (offset * 2 >= async_ids_stack_.Length())
140
8
    grow_async_ids_stack();
141
1015482
  async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId];
142
1015484
  async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId];
143
1015478
  fields_[kStackLength] += 1;
144
1015475
  async_id_fields_[kExecutionAsyncId] = async_id;
145
1015472
  async_id_fields_[kTriggerAsyncId] = trigger_async_id;
146
1015473
}
147
148
// Remember to keep this code aligned with popAsyncIds() in JS.
149
1015146
inline bool AsyncHooks::pop_async_id(double async_id) {
150
  // In case of an exception then this may have already been reset, if the
151
  // stack was multiple MakeCallback()'s deep.
152
1015146
  if (fields_[kStackLength] == 0) return false;
153
154
  // Ask for the async_id to be restored as a check that the stack
155
  // hasn't been corrupted.
156
  // Since async_hooks is experimental, do only perform the check
157
  // when async_hooks is enabled.
158


1014521
  if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) {
159
    fprintf(stderr,
160
            "Error: async hook stack has become corrupted ("
161
            "actual: %.f, expected: %.f)\n",
162
            async_id_fields_.GetValue(kExecutionAsyncId),
163
4
            async_id);
164
4
    DumpBacktrace(stderr);
165
4
    fflush(stderr);
166
4
    if (!env()->abort_on_uncaught_exception())
167
4
      exit(1);
168
    fprintf(stderr, "\n");
169
    fflush(stderr);
170
    ABORT_NO_BACKTRACE();
171
  }
172
173
1014516
  uint32_t offset = fields_[kStackLength] - 1;
174
1014516
  async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset];
175
1014518
  async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1];
176
1014518
  fields_[kStackLength] = offset;
177
178
1014519
  return fields_[kStackLength] > 0;
179
}
180
181
// Keep in sync with clearAsyncIdStack in lib/internal/async_hooks.js.
182
31
inline void AsyncHooks::clear_async_id_stack() {
183
31
  async_id_fields_[kExecutionAsyncId] = 0;
184
31
  async_id_fields_[kTriggerAsyncId] = 0;
185
31
  fields_[kStackLength] = 0;
186
31
}
187
188
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in
189
// async_wrap-inl.h to avoid a circular dependency.
190
191
1033011
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope(
192
    Environment* env, double default_trigger_async_id)
193
1033011
    : async_hooks_(env->async_hooks()) {
194
1033011
  if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) {
195
1033011
    CHECK_GE(default_trigger_async_id, 0);
196
  }
197
198
2066022
  old_default_trigger_async_id_ =
199
2066022
    async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
200
2066022
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
201
1033011
    default_trigger_async_id;
202
1033011
}
203
204
1033010
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() {
205
2066020
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
206
1033010
    old_default_trigger_async_id_;
207
1033010
}
208
209
210
720483
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
211
720483
  return ContainerOf(&Environment::async_hooks_, hooks);
212
}
213
214
1178938
inline AsyncCallbackScope::AsyncCallbackScope(Environment* env) : env_(env) {
215
1178938
  env_->PushAsyncCallbackScope();
216
1178944
}
217
218
1178560
inline AsyncCallbackScope::~AsyncCallbackScope() {
219
1178560
  env_->PopAsyncCallbackScope();
220
1178560
}
221
222
1010450
inline size_t Environment::async_callback_scope_depth() const {
223
1010450
  return async_callback_scope_depth_;
224
}
225
226
1178939
inline void Environment::PushAsyncCallbackScope() {
227
1178939
  async_callback_scope_depth_++;
228
1178939
}
229
230
1178559
inline void Environment::PopAsyncCallbackScope() {
231
1178559
  async_callback_scope_depth_--;
232
1178559
}
233
234
4967
inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
235
4967
    : fields_(isolate, kFieldsCount) {}
236
237
4965
inline AliasedUint32Array& ImmediateInfo::fields() {
238
4965
  return fields_;
239
}
240
241
435372
inline uint32_t ImmediateInfo::count() const {
242
435372
  return fields_[kCount];
243
}
244
245
87481
inline uint32_t ImmediateInfo::ref_count() const {
246
87481
  return fields_[kRefCount];
247
}
248
249
56257
inline bool ImmediateInfo::has_outstanding() const {
250
56257
  return fields_[kHasOutstanding] == 1;
251
}
252
253
53998
inline void ImmediateInfo::count_inc(uint32_t increment) {
254
53998
  fields_[kCount] += increment;
255
53998
}
256
257
48456
inline void ImmediateInfo::count_dec(uint32_t decrement) {
258
48456
  fields_[kCount] -= decrement;
259
48456
}
260
261
31745
inline void ImmediateInfo::ref_count_inc(uint32_t increment) {
262
31745
  fields_[kRefCount] += increment;
263
31745
}
264
265
48456
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
266
48456
  fields_[kRefCount] -= decrement;
267
48456
}
268
269
4967
inline TickInfo::TickInfo(v8::Isolate* isolate)
270
4967
    : fields_(isolate, kFieldsCount) {}
271
272
4965
inline AliasedUint8Array& TickInfo::fields() {
273
4965
  return fields_;
274
}
275
276
1621960
inline bool TickInfo::has_tick_scheduled() const {
277
1621960
  return fields_[kHasTickScheduled] == 1;
278
}
279
280
291917
inline bool TickInfo::has_rejection_to_warn() const {
281
291917
  return fields_[kHasRejectionToWarn] == 1;
282
}
283
284
5427
inline void Environment::AssignToContext(v8::Local<v8::Context> context,
285
                                         const ContextInfo& info) {
286
  context->SetAlignedPointerInEmbedderData(
287
5427
      ContextEmbedderIndex::kEnvironment, this);
288
  // Used by Environment::GetCurrent to know that we are on a node context.
289
  context->SetAlignedPointerInEmbedderData(
290
10854
    ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
291
#if HAVE_INSPECTOR
292
5427
  inspector_agent()->ContextCreated(context, info);
293
#endif  // HAVE_INSPECTOR
294
5427
}
295
296
1038778
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
297
1038778
  if (UNLIKELY(!isolate->InContext())) return nullptr;
298
1038784
  v8::HandleScope handle_scope(isolate);
299
1038790
  return GetCurrent(isolate->GetCurrentContext());
300
}
301
302
1346988
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
303
1346988
  if (UNLIKELY(context.IsEmpty())) {
304
    return nullptr;
305
  }
306
1346988
  if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
307
               ContextEmbedderIndex::kContextTag)) {
308
1
    return nullptr;
309
  }
310
2693978
  if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
311
                   ContextEmbedderIndex::kContextTag) !=
312
               Environment::kNodeContextTagPtr)) {
313
    return nullptr;
314
  }
315
  return static_cast<Environment*>(
316
      context->GetAlignedPointerFromEmbedderData(
317
2693978
          ContextEmbedderIndex::kEnvironment));
318
}
319
320
9370727
inline Environment* Environment::GetCurrent(
321
    const v8::FunctionCallbackInfo<v8::Value>& info) {
322
9370727
  return GetFromCallbackData(info.Data());
323
}
324
325
template <typename T>
326
2220092
inline Environment* Environment::GetCurrent(
327
    const v8::PropertyCallbackInfo<T>& info) {
328
2220092
  return GetFromCallbackData(info.Data());
329
}
330
331
11590823
inline Environment* Environment::GetFromCallbackData(v8::Local<v8::Value> val) {
332
  DCHECK(val->IsObject());
333
11590823
  v8::Local<v8::Object> obj = val.As<v8::Object>();
334
  DCHECK_GE(obj->InternalFieldCount(), 1);
335
  Environment* env =
336
23181646
      static_cast<Environment*>(obj->GetAlignedPointerFromInternalField(0));
337
  DCHECK(env->as_callback_data_template()->HasInstance(obj));
338
11590823
  return env;
339
}
340
341
7
inline Environment* Environment::GetThreadLocalEnv() {
342
7
  return static_cast<Environment*>(uv_key_get(&thread_local_env));
343
}
344
345
206
inline bool Environment::profiler_idle_notifier_started() const {
346
206
  return profiler_idle_notifier_started_;
347
}
348
349
65293843
inline v8::Isolate* Environment::isolate() const {
350
65293843
  return isolate_;
351
}
352
353
5037
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
354
5037
  return ContainerOf(&Environment::timer_handle_, handle);
355
}
356
357
22365
inline uv_timer_t* Environment::timer_handle() {
358
22365
  return &timer_handle_;
359
}
360
361
435371
inline Environment* Environment::from_immediate_check_handle(
362
    uv_check_t* handle) {
363
435371
  return ContainerOf(&Environment::immediate_check_handle_, handle);
364
}
365
366
19866
inline uv_check_t* Environment::immediate_check_handle() {
367
19866
  return &immediate_check_handle_;
368
}
369
370
90467
inline uv_idle_t* Environment::immediate_idle_handle() {
371
90467
  return &immediate_idle_handle_;
372
}
373
374
24835
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
375
                                               HandleCleanupCb cb,
376
                                               void* arg) {
377
24835
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
378
24834
}
379
380
template <typename T, typename OnCloseCallback>
381
27793
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
382
27793
  handle_cleanup_waiting_++;
383
  static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle");
384
  static_assert(offsetof(T, data) == offsetof(uv_handle_t, data),
385
                "T is a libuv handle");
386
  static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb),
387
                "T is a libuv handle");
388
  struct CloseData {
389
    Environment* env;
390
    OnCloseCallback callback;
391
    void* original_data;
392
  };
393
27793
  handle->data = new CloseData { this, callback, handle->data };
394
111124
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
395
27769
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
396
27769
    data->env->handle_cleanup_waiting_--;
397
27769
    handle->data = data->original_data;
398
27769
    data->callback(reinterpret_cast<T*>(handle));
399
83355
  });
400
27793
}
401
402
103846
void Environment::IncreaseWaitingRequestCounter() {
403
103846
  request_waiting_++;
404
103846
}
405
406
103831
void Environment::DecreaseWaitingRequestCounter() {
407
103831
  request_waiting_--;
408
103831
  CHECK_GE(request_waiting_, 0);
409
103831
}
410
411
1297481
inline uv_loop_t* Environment::event_loop() const {
412
1297481
  return isolate_data()->event_loop();
413
}
414
415
151
inline void Environment::TryLoadAddon(
416
    const char* filename,
417
    int flags,
418
    const std::function<bool(binding::DLib*)>& was_loaded) {
419
151
  loaded_addons_.emplace_back(filename, flags);
420
151
  if (!was_loaded(&loaded_addons_.back())) {
421
7
    loaded_addons_.pop_back();
422
  }
423
151
}
424
425
#if HAVE_INSPECTOR
426
228863
inline bool Environment::is_in_inspector_console_call() const {
427
228863
  return is_in_inspector_console_call_;
428
}
429
430
457724
inline void Environment::set_is_in_inspector_console_call(bool value) {
431
457724
  is_in_inspector_console_call_ = value;
432
457724
}
433
#endif
434
435
8736536
inline AsyncHooks* Environment::async_hooks() {
436
8736536
  return &async_hooks_;
437
}
438
439
766730
inline ImmediateInfo* Environment::immediate_info() {
440
766730
  return &immediate_info_;
441
}
442
443
815960
inline TickInfo* Environment::tick_info() {
444
815960
  return &tick_info_;
445
}
446
447
314601
inline uint64_t Environment::timer_base() const {
448
314601
  return timer_base_;
449
}
450
451
2233853
inline std::shared_ptr<KVStore> Environment::env_vars() {
452
2233853
  return env_vars_;
453
}
454
455
5161
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) {
456
5161
  env_vars_ = env_vars;
457
5161
}
458
459
12
inline bool Environment::printed_error() const {
460
12
  return printed_error_;
461
}
462
463
12
inline void Environment::set_printed_error(bool value) {
464
12
  printed_error_ = value;
465
12
}
466
467
4381
inline void Environment::set_trace_sync_io(bool value) {
468
4381
  options_->trace_sync_io = value;
469
4381
}
470
471
25
inline bool Environment::abort_on_uncaught_exception() const {
472
25
  return options_->abort_on_uncaught_exception;
473
}
474
475
194
inline void Environment::set_abort_on_uncaught_exception(bool value) {
476
194
  options_->abort_on_uncaught_exception = value;
477
194
}
478
479
4996
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
480
4996
  return should_abort_on_uncaught_toggle_;
481
}
482
483
2393576
inline AliasedInt32Array& Environment::stream_base_state() {
484
2393576
  return stream_base_state_;
485
}
486
487
381
inline uint32_t Environment::get_next_module_id() {
488
381
  return module_id_counter_++;
489
}
490
1746
inline uint32_t Environment::get_next_script_id() {
491
1746
  return script_id_counter_++;
492
}
493
39796
inline uint32_t Environment::get_next_function_id() {
494
39796
  return function_id_counter_++;
495
}
496
497
2247
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
498
    Environment* env)
499
2247
    : env_(env) {
500
2247
  env_->PushShouldNotAbortOnUncaughtScope();
501
2247
}
502
503
2246
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
504
2246
  Close();
505
2246
}
506
507
2444
void ShouldNotAbortOnUncaughtScope::Close() {
508
2444
  if (env_ != nullptr) {
509
2246
    env_->PopShouldNotAbortOnUncaughtScope();
510
2246
    env_ = nullptr;
511
  }
512
2444
}
513
514
2247
inline void Environment::PushShouldNotAbortOnUncaughtScope() {
515
2247
  should_not_abort_scope_counter_++;
516
2247
}
517
518
2246
inline void Environment::PopShouldNotAbortOnUncaughtScope() {
519
2246
  should_not_abort_scope_counter_--;
520
2246
}
521
522
1
inline bool Environment::inside_should_not_abort_on_uncaught_scope() const {
523
1
  return should_not_abort_scope_counter_ > 0;
524
}
525
526
198380
inline std::vector<double>* Environment::destroy_async_id_list() {
527
198380
  return &destroy_async_id_list_;
528
}
529
530
273992
inline double Environment::new_async_id() {
531
273992
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
532
273992
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
533
}
534
535
206429
inline double Environment::execution_async_id() {
536
206429
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
537
}
538
539
37582
inline double Environment::trigger_async_id() {
540
37582
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
541
}
542
543
273989
inline double Environment::get_default_trigger_async_id() {
544
  double default_trigger_async_id =
545
273989
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
546
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
547
273989
  if (default_trigger_async_id < 0)
548
168368
    default_trigger_async_id = execution_async_id();
549
273989
  return default_trigger_async_id;
550
}
551
552
67
inline double* Environment::heap_statistics_buffer() const {
553
67
  CHECK_NOT_NULL(heap_statistics_buffer_);
554
67
  return heap_statistics_buffer_;
555
}
556
557
65
inline void Environment::set_heap_statistics_buffer(double* pointer) {
558
65
  CHECK_NULL(heap_statistics_buffer_);  // Should be set only once.
559
65
  heap_statistics_buffer_ = pointer;
560
65
}
561
562
66
inline double* Environment::heap_space_statistics_buffer() const {
563
66
  CHECK_NOT_NULL(heap_space_statistics_buffer_);
564
66
  return heap_space_statistics_buffer_;
565
}
566
567
65
inline void Environment::set_heap_space_statistics_buffer(double* pointer) {
568
65
  CHECK_NULL(heap_space_statistics_buffer_);  // Should be set only once.
569
65
  heap_space_statistics_buffer_ = pointer;
570
65
}
571
572
231554
inline char* Environment::http_parser_buffer() const {
573
231554
  return http_parser_buffer_;
574
}
575
576
293
inline void Environment::set_http_parser_buffer(char* buffer) {
577
293
  CHECK_NULL(http_parser_buffer_);  // Should be set only once.
578
293
  http_parser_buffer_ = buffer;
579
293
}
580
581
77181
inline bool Environment::http_parser_buffer_in_use() const {
582
77181
  return http_parser_buffer_in_use_;
583
}
584
585
154356
inline void Environment::set_http_parser_buffer_in_use(bool in_use) {
586
154356
  http_parser_buffer_in_use_ = in_use;
587
154356
}
588
589
19480
inline http2::Http2State* Environment::http2_state() const {
590
19480
  return http2_state_.get();
591
}
592
593
227
inline void Environment::set_http2_state(
594
    std::unique_ptr<http2::Http2State> buffer) {
595
227
  CHECK(!http2_state_);  // Should be set only once.
596
227
  http2_state_ = std::move(buffer);
597
227
}
598
599
1251919
bool Environment::debug_enabled(DebugCategory category) const {
600
  DCHECK_GE(static_cast<int>(category), 0);
601
  DCHECK_LT(static_cast<int>(category),
602
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
603
1251919
  return debug_enabled_[static_cast<int>(category)];
604
}
605
606
22
void Environment::set_debug_enabled(DebugCategory category, bool enabled) {
607
  DCHECK_GE(static_cast<int>(category), 0);
608
  DCHECK_LT(static_cast<int>(category),
609
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
610
22
  debug_enabled_[static_cast<int>(category)] = enabled;
611
22
}
612
613
205519
inline AliasedFloat64Array* Environment::fs_stats_field_array() {
614
205519
  return &fs_stats_field_array_;
615
}
616
617
4973
inline AliasedBigUint64Array* Environment::fs_stats_field_bigint_array() {
618
4973
  return &fs_stats_field_bigint_array_;
619
}
620
621
inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>&
622
442
Environment::file_handle_read_wrap_freelist() {
623
442
  return file_handle_read_wrap_freelist_;
624
}
625
626
46758
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
627
46758
  return options_;
628
}
629
630
14367
inline const std::vector<std::string>& Environment::argv() {
631
14367
  return argv_;
632
}
633
634
5161
inline const std::vector<std::string>& Environment::exec_argv() {
635
5161
  return exec_argv_;
636
}
637
638
9928
inline const std::string& Environment::exec_path() const {
639
9928
  return exec_path_;
640
}
641
642
#if HAVE_INSPECTOR
643
4959
inline void Environment::set_coverage_directory(const char* dir) {
644
4959
  coverage_directory_ = std::string(dir);
645
4959
}
646
647
4956
inline void Environment::set_coverage_connection(
648
    std::unique_ptr<profiler::V8CoverageConnection> connection) {
649
4956
  CHECK_NULL(coverage_connection_);
650
4957
  std::swap(coverage_connection_, connection);
651
4957
}
652
653
14786
inline profiler::V8CoverageConnection* Environment::coverage_connection() {
654
14786
  return coverage_connection_.get();
655
}
656
657
4762
inline const std::string& Environment::coverage_directory() const {
658
4762
  return coverage_directory_;
659
}
660
661
10
inline void Environment::set_cpu_profiler_connection(
662
    std::unique_ptr<profiler::V8CpuProfilerConnection> connection) {
663
10
  CHECK_NULL(cpu_profiler_connection_);
664
10
  std::swap(cpu_profiler_connection_, connection);
665
10
}
666
667
inline profiler::V8CpuProfilerConnection*
668
4893
Environment::cpu_profiler_connection() {
669
4893
  return cpu_profiler_connection_.get();
670
}
671
672
10
inline void Environment::set_cpu_prof_interval(uint64_t interval) {
673
10
  cpu_prof_interval_ = interval;
674
10
}
675
676
10
inline uint64_t Environment::cpu_prof_interval() const {
677
10
  return cpu_prof_interval_;
678
}
679
680
10
inline void Environment::set_cpu_prof_name(const std::string& name) {
681
10
  cpu_prof_name_ = name;
682
10
}
683
684
10
inline const std::string& Environment::cpu_prof_name() const {
685
10
  return cpu_prof_name_;
686
}
687
688
10
inline void Environment::set_cpu_prof_dir(const std::string& dir) {
689
10
  cpu_prof_dir_ = dir;
690
10
}
691
692
10
inline const std::string& Environment::cpu_prof_dir() const {
693
10
  return cpu_prof_dir_;
694
}
695
696
10
inline void Environment::set_heap_profiler_connection(
697
    std::unique_ptr<profiler::V8HeapProfilerConnection> connection) {
698
10
  CHECK_NULL(heap_profiler_connection_);
699
10
  std::swap(heap_profiler_connection_, connection);
700
10
}
701
702
inline profiler::V8HeapProfilerConnection*
703
4883
Environment::heap_profiler_connection() {
704
4883
  return heap_profiler_connection_.get();
705
}
706
707
10
inline void Environment::set_heap_prof_name(const std::string& name) {
708
10
  heap_prof_name_ = name;
709
10
}
710
711
10
inline const std::string& Environment::heap_prof_name() const {
712
10
  return heap_prof_name_;
713
}
714
715
10
inline void Environment::set_heap_prof_dir(const std::string& dir) {
716
10
  heap_prof_dir_ = dir;
717
10
}
718
719
10
inline const std::string& Environment::heap_prof_dir() const {
720
10
  return heap_prof_dir_;
721
}
722
723
10
inline void Environment::set_heap_prof_interval(uint64_t interval) {
724
10
  heap_prof_interval_ = interval;
725
10
}
726
727
10
inline uint64_t Environment::heap_prof_interval() const {
728
10
  return heap_prof_interval_;
729
}
730
731
#endif  // HAVE_INSPECTOR
732
733
10018
inline std::shared_ptr<HostPort> Environment::inspector_host_port() {
734
10018
  return inspector_host_port_;
735
}
736
737
16147
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
738
16147
  return options_;
739
}
740
741
9
inline void IsolateData::set_options(
742
    std::shared_ptr<PerIsolateOptions> options) {
743
9
  options_ = std::move(options);
744
9
}
745
746
53998
void Environment::CreateImmediate(native_immediate_callback cb,
747
                                  void* data,
748
                                  v8::Local<v8::Object> obj,
749
                                  bool ref) {
750
  native_immediate_callbacks_.push_back({
751
    cb,
752
    data,
753
    v8::Global<v8::Object>(isolate_, obj),
754
    ref
755
107996
  });
756
53998
  immediate_info()->count_inc(1);
757
53998
}
758
759
31745
void Environment::SetImmediate(native_immediate_callback cb,
760
                               void* data,
761
                               v8::Local<v8::Object> obj) {
762
31745
  CreateImmediate(cb, data, obj, true);
763
764
31745
  if (immediate_info()->ref_count() == 0)
765
23781
    ToggleImmediateRef(true);
766
31745
  immediate_info()->ref_count_inc(1);
767
31745
}
768
769
22253
void Environment::SetUnrefImmediate(native_immediate_callback cb,
770
                                    void* data,
771
                                    v8::Local<v8::Object> obj) {
772
22253
  CreateImmediate(cb, data, obj, false);
773
22253
}
774
775
3595386
inline bool Environment::can_call_into_js() const {
776

3595386
  return can_call_into_js_ && !is_stopping();
777
}
778
779
4631
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
780
4631
  can_call_into_js_ = can_call_into_js;
781
4631
}
782
783
20743
inline bool Environment::has_run_bootstrapping_code() const {
784
20743
  return has_run_bootstrapping_code_;
785
}
786
787
4965
inline void Environment::set_has_run_bootstrapping_code(bool value) {
788
4965
  has_run_bootstrapping_code_ = value;
789
4965
}
790
791
16
inline bool Environment::has_serialized_options() const {
792
16
  return has_serialized_options_;
793
}
794
795
4965
inline void Environment::set_has_serialized_options(bool value) {
796
4965
  has_serialized_options_ = value;
797
4965
}
798
799
24314
inline bool Environment::is_main_thread() const {
800
24314
  return flags_ & kIsMainThread;
801
}
802
803
28603
inline bool Environment::owns_process_state() const {
804
28603
  return flags_ & kOwnsProcessState;
805
}
806
807
4966
inline bool Environment::owns_inspector() const {
808
4966
  return flags_ & kOwnsInspector;
809
}
810
811
8488
inline uint64_t Environment::thread_id() const {
812
8488
  return thread_id_;
813
}
814
815
inline worker::Worker* Environment::worker_context() const {
816
  return worker_context_;
817
}
818
819
194
inline void Environment::set_worker_context(worker::Worker* context) {
820
194
  CHECK_NULL(worker_context_);  // Should be set only once.
821
194
  worker_context_ = context;
822
194
}
823
824
205
inline void Environment::add_sub_worker_context(worker::Worker* context) {
825
205
  sub_worker_contexts_.insert(context);
826
205
}
827
828
229
inline void Environment::remove_sub_worker_context(worker::Worker* context) {
829
229
  sub_worker_contexts_.erase(context);
830
229
}
831
832
3594547
inline bool Environment::is_stopping() const {
833
3594547
  return thread_stopper_.is_stopped();
834
}
835
836
38776
inline performance::performance_state* Environment::performance_state() {
837
38776
  return performance_state_.get();
838
}
839
840
inline std::unordered_map<std::string, uint64_t>*
841
42
    Environment::performance_marks() {
842
42
  return &performance_marks_;
843
}
844
845
5993554
inline IsolateData* Environment::isolate_data() const {
846
5993554
  return isolate_data_;
847
}
848
849
467859
inline char* Environment::AllocateUnchecked(size_t size) {
850
  return static_cast<char*>(
851
467859
      isolate_data()->allocator()->AllocateUninitialized(size));
852
}
853
854
435430
inline char* Environment::Allocate(size_t size) {
855
435430
  char* ret = AllocateUnchecked(size);
856
435430
  CHECK_NE(ret, nullptr);
857
435430
  return ret;
858
}
859
860
1088572
inline void Environment::Free(char* data, size_t size) {
861
1088572
  if (data != nullptr)
862
82119
    isolate_data()->allocator()->Free(data, size);
863
1088572
}
864
865
467859
inline AllocatedBuffer Environment::AllocateManaged(size_t size, bool checked) {
866
467859
  char* data = checked ? Allocate(size) : AllocateUnchecked(size);
867
467859
  if (data == nullptr) size = 0;
868
467859
  return AllocatedBuffer(this, uv_buf_init(data, size));
869
}
870
871
847423
inline AllocatedBuffer::AllocatedBuffer(Environment* env, uv_buf_t buf)
872
847423
    : env_(env), buffer_(buf) {}
873
874
341000
inline void AllocatedBuffer::Resize(size_t len) {
875
  // The `len` check is to make sure we don't end up with `nullptr` as our base.
876
  char* new_data = env_->Reallocate(buffer_.base, buffer_.len,
877
341000
                                    len > 0 ? len : 1);
878
341000
  CHECK_NOT_NULL(new_data);
879
341000
  buffer_ = uv_buf_init(new_data, len);
880
341000
}
881
882
1940091
inline uv_buf_t AllocatedBuffer::release() {
883
1940091
  uv_buf_t ret = buffer_;
884
1940091
  buffer_ = uv_buf_init(nullptr, 0);
885
1940091
  return ret;
886
}
887
888
591208
inline char* AllocatedBuffer::data() {
889
591208
  return buffer_.base;
890
}
891
892
inline const char* AllocatedBuffer::data() const {
893
  return buffer_.base;
894
}
895
896
748893
inline size_t AllocatedBuffer::size() const {
897
748893
  return buffer_.len;
898
}
899
900
130927
inline AllocatedBuffer::AllocatedBuffer(Environment* env)
901
130927
    : env_(env), buffer_(uv_buf_init(nullptr, 0)) {}
902
903
847
inline AllocatedBuffer::AllocatedBuffer(AllocatedBuffer&& other)
904
847
    : AllocatedBuffer() {
905
847
  *this = std::move(other);
906
847
}
907
908
110405
inline AllocatedBuffer& AllocatedBuffer::operator=(AllocatedBuffer&& other) {
909
110405
  clear();
910
110405
  env_ = other.env_;
911
110405
  buffer_ = other.release();
912
110405
  return *this;
913
}
914
915
978167
inline AllocatedBuffer::~AllocatedBuffer() {
916
978167
  clear();
917
978167
}
918
919
1088572
inline void AllocatedBuffer::clear() {
920
1088572
  uv_buf_t buf = release();
921
1088572
  env_->Free(buf.base, buf.len);
922
1088572
}
923
924
// It's a bit awkward to define this Buffer::New() overload here, but it
925
// avoids a circular dependency with node_internals.h.
926
namespace Buffer {
927
v8::MaybeLocal<v8::Object> New(Environment* env,
928
                               char* data,
929
                               size_t length,
930
                               bool uses_malloc);
931
}
932
933
58447
inline v8::MaybeLocal<v8::Object> AllocatedBuffer::ToBuffer() {
934
58447
  CHECK_NOT_NULL(env_);
935
58447
  v8::MaybeLocal<v8::Object> obj = Buffer::New(env_, data(), size(), false);
936
58447
  if (!obj.IsEmpty()) release();
937
58447
  return obj;
938
}
939
940
332734
inline v8::Local<v8::ArrayBuffer> AllocatedBuffer::ToArrayBuffer() {
941
332734
  CHECK_NOT_NULL(env_);
942
332734
  uv_buf_t buf = release();
943
  return v8::ArrayBuffer::New(env_->isolate(),
944
                              buf.base,
945
                              buf.len,
946
332734
                              v8::ArrayBufferCreationMode::kInternalized);
947
}
948
949
697
inline void Environment::ThrowError(const char* errmsg) {
950
697
  ThrowError(v8::Exception::Error, errmsg);
951
697
}
952
953
5
inline void Environment::ThrowTypeError(const char* errmsg) {
954
5
  ThrowError(v8::Exception::TypeError, errmsg);
955
5
}
956
957
inline void Environment::ThrowRangeError(const char* errmsg) {
958
  ThrowError(v8::Exception::RangeError, errmsg);
959
}
960
961
702
inline void Environment::ThrowError(
962
    v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
963
    const char* errmsg) {
964
702
  v8::HandleScope handle_scope(isolate());
965
702
  isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
966
702
}
967
968
3
inline void Environment::ThrowErrnoException(int errorno,
969
                                             const char* syscall,
970
                                             const char* message,
971
                                             const char* path) {
972
  isolate()->ThrowException(
973
3
      ErrnoException(isolate(), errorno, syscall, message, path));
974
3
}
975
976
11
inline void Environment::ThrowUVException(int errorno,
977
                                          const char* syscall,
978
                                          const char* message,
979
                                          const char* path,
980
                                          const char* dest) {
981
  isolate()->ThrowException(
982
11
      UVException(isolate(), errorno, syscall, message, path, dest));
983
11
}
984
985
inline v8::Local<v8::FunctionTemplate>
986
1801486
    Environment::NewFunctionTemplate(v8::FunctionCallback callback,
987
                                     v8::Local<v8::Signature> signature,
988
                                     v8::ConstructorBehavior behavior,
989
                                     v8::SideEffectType side_effect_type) {
990
1801486
  v8::Local<v8::Object> external = as_callback_data();
991
  return v8::FunctionTemplate::New(isolate(), callback, external,
992
1801490
                                   signature, 0, behavior, side_effect_type);
993
}
994
995
738790
inline void Environment::SetMethod(v8::Local<v8::Object> that,
996
                                   const char* name,
997
                                   v8::FunctionCallback callback) {
998
738790
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
999
  v8::Local<v8::Function> function =
1000
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1001
                          v8::ConstructorBehavior::kThrow,
1002
738790
                          v8::SideEffectType::kHasSideEffect)
1003
2216371
          ->GetFunction(context)
1004
1477581
          .ToLocalChecked();
1005
  // kInternalized strings are created in the old space.
1006
738790
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1007
  v8::Local<v8::String> name_string =
1008
1477581
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1009
1477582
  that->Set(context, name_string, function).Check();
1010
738791
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1011
738790
}
1012
1013
330854
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
1014
                                               const char* name,
1015
                                               v8::FunctionCallback callback) {
1016
330854
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
1017
  v8::Local<v8::Function> function =
1018
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1019
                          v8::ConstructorBehavior::kThrow,
1020
330862
                          v8::SideEffectType::kHasNoSideEffect)
1021
992599
          ->GetFunction(context)
1022
661729
          .ToLocalChecked();
1023
  // kInternalized strings are created in the old space.
1024
330862
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1025
  v8::Local<v8::String> name_string =
1026
661733
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1027
661741
  that->Set(context, name_string, function).Check();
1028
330870
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1029
330870
}
1030
1031
495947
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
1032
                                        const char* name,
1033
                                        v8::FunctionCallback callback) {
1034
495947
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1035
  v8::Local<v8::FunctionTemplate> t =
1036
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1037
495947
                          v8::SideEffectType::kHasSideEffect);
1038
  // kInternalized strings are created in the old space.
1039
495947
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1040
  v8::Local<v8::String> name_string =
1041
991894
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1042
991894
  that->PrototypeTemplate()->Set(name_string, t);
1043
495946
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1044
495947
}
1045
1046
47503
inline void Environment::SetProtoMethodNoSideEffect(
1047
    v8::Local<v8::FunctionTemplate> that,
1048
    const char* name,
1049
    v8::FunctionCallback callback) {
1050
47503
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1051
  v8::Local<v8::FunctionTemplate> t =
1052
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1053
47503
                          v8::SideEffectType::kHasNoSideEffect);
1054
  // kInternalized strings are created in the old space.
1055
47503
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1056
  v8::Local<v8::String> name_string =
1057
95006
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1058
95006
  that->PrototypeTemplate()->Set(name_string, t);
1059
47503
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1060
47503
}
1061
1062
700272
void Environment::AddCleanupHook(void (*fn)(void*), void* arg) {
1063
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
1064
    fn, arg, cleanup_hook_counter_++
1065
700272
  });
1066
  // Make sure there was no existing element with these values.
1067
700272
  CHECK_EQ(insertion_info.second, true);
1068
700272
}
1069
1070
697053
void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
1071
697053
  CleanupHookCallback search { fn, arg, 0 };
1072
697054
  cleanup_hooks_.erase(search);
1073
697056
}
1074
1075
1549992
size_t CleanupHookCallback::Hash::operator()(
1076
    const CleanupHookCallback& cb) const {
1077
1549992
  return std::hash<void*>()(cb.arg_);
1078
}
1079
1080
772771
bool CleanupHookCallback::Equal::operator()(
1081
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
1082

772771
  return a.fn_ == b.fn_ && a.arg_ == b.arg_;
1083
}
1084
1085
349
BaseObject* CleanupHookCallback::GetBaseObject() const {
1086
349
  if (fn_ == BaseObject::DeleteMe)
1087
348
    return static_cast<BaseObject*>(arg_);
1088
  else
1089
1
    return nullptr;
1090
}
1091
1092
template <typename T>
1093
void Environment::ForEachBaseObject(T&& iterator) {
1094
  for (const auto& hook : cleanup_hooks_) {
1095
    BaseObject* obj = hook.GetBaseObject();
1096
    if (obj != nullptr)
1097
      iterator(obj);
1098
  }
1099
}
1100
1101
3594555
bool AsyncRequest::is_stopped() const {
1102
3594555
  return stopped_.load();
1103
}
1104
1105
5425
void AsyncRequest::set_stopped(bool flag) {
1106
5425
  stopped_.store(flag);
1107
5426
}
1108
1109
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1110
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1111
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1112
#define V(TypeName, PropertyName)                                             \
1113
  inline                                                                      \
1114
  v8::Local<TypeName> IsolateData::PropertyName(v8::Isolate* isolate) const { \
1115
    /* Strings are immutable so casting away const-ness here is okay. */      \
1116
    return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate);    \
1117
  }
1118
20926
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1119
627312
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1120
5647602
  PER_ISOLATE_STRING_PROPERTIES(VS)
1121
#undef V
1122
#undef VS
1123
#undef VY
1124
#undef VP
1125
1126
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1127
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1128
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1129
#define V(TypeName, PropertyName)                                             \
1130
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1131
    return isolate_data()->PropertyName(isolate());                           \
1132
  }
1133
10463
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1134
313457
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1135
2813294
  PER_ISOLATE_STRING_PROPERTIES(VS)
1136
#undef V
1137
#undef VS
1138
#undef VY
1139
#undef VP
1140
1141
#define V(PropertyName, TypeName)                                             \
1142
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1143
    return PersistentToLocal::Strong(PropertyName ## _);                      \
1144
  }                                                                           \
1145
  inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) {  \
1146
    PropertyName ## _.Reset(isolate(), value);                                \
1147
  }
1148
500545
  ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1149
7118865
  ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1150
#undef V
1151
1152
16828551
  inline v8::Local<v8::Context> Environment::context() const {
1153
16828551
    return PersistentToLocal::Strong(context_);
1154
  }
1155
}  // namespace node
1156
1157
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1158
1159
#endif  // SRC_ENV_INL_H_