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-28 22:34:34 Branches: 65 94 69.1 %

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
1301689
inline uv_loop_t* IsolateData::event_loop() const {
48
1301689
  return event_loop_;
49
}
50
51
323753
inline bool IsolateData::uses_node_allocator() const {
52
323753
  return uses_node_allocator_;
53
}
54
55
550285
inline v8::ArrayBuffer::Allocator* IsolateData::allocator() const {
56
550285
  return allocator_;
57
}
58
59
329057
inline NodeArrayBufferAllocator* IsolateData::node_allocator() const {
60
329057
  return node_allocator_;
61
}
62
63
234264
inline MultiIsolatePlatform* IsolateData::platform() const {
64
234264
  return platform_;
65
}
66
67
4965
inline AsyncHooks::AsyncHooks()
68
    : async_ids_stack_(env()->isolate(), 16 * 2),
69
      fields_(env()->isolate(), kFieldsCount),
70
4965
      async_id_fields_(env()->isolate(), kUidFieldsCount) {
71
4965
  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
4965
  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
4965
  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
4965
  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
431955
  NODE_ASYNC_PROVIDER_TYPES(V)
102
#undef V
103
4965
}
104
4321686
inline AliasedUint32Array& AsyncHooks::fields() {
105
4321686
  return fields_;
106
}
107
108
4168996
inline AliasedFloat64Array& AsyncHooks::async_id_fields() {
109
4168996
  return async_id_fields_;
110
}
111
112
4961
inline AliasedFloat64Array& AsyncHooks::async_ids_stack() {
113
4961
  return async_ids_stack_;
114
}
115
116
272933
inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) {
117
545866
  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
719811
inline Environment* AsyncHooks::env() {
125
719811
  return Environment::ForAsyncHooks(this);
126
}
127
128
// Remember to keep this code aligned with pushAsyncIds() in JS.
129
1014830
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
1014830
  if (fields_[kCheck] > 0) {
134
1014826
    CHECK_GE(async_id, -1);
135
1014826
    CHECK_GE(trigger_async_id, -1);
136
  }
137
138
1014830
  uint32_t offset = fields_[kStackLength];
139
1014824
  if (offset * 2 >= async_ids_stack_.Length())
140
8
    grow_async_ids_stack();
141
1014820
  async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId];
142
1014832
  async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId];
143
1014829
  fields_[kStackLength] += 1;
144
1014829
  async_id_fields_[kExecutionAsyncId] = async_id;
145
1014822
  async_id_fields_[kTriggerAsyncId] = trigger_async_id;
146
1014824
}
147
148
// Remember to keep this code aligned with popAsyncIds() in JS.
149
1014490
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
1014490
  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


1013859
  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
1013856
  uint32_t offset = fields_[kStackLength] - 1;
174
1013856
  async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset];
175
1013854
  async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1];
176
1013854
  fields_[kStackLength] = offset;
177
178
1013856
  return fields_[kStackLength] > 0;
179
}
180
181
// Keep in sync with clearAsyncIdStack in lib/internal/async_hooks.js.
182
33
inline void AsyncHooks::clear_async_id_stack() {
183
33
  async_id_fields_[kExecutionAsyncId] = 0;
184
33
  async_id_fields_[kTriggerAsyncId] = 0;
185
33
  fields_[kStackLength] = 0;
186
33
}
187
188
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in
189
// async_wrap-inl.h to avoid a circular dependency.
190
191
1033247
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope(
192
    Environment* env, double default_trigger_async_id)
193
1033247
    : async_hooks_(env->async_hooks()) {
194
1033247
  if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) {
195
1033247
    CHECK_GE(default_trigger_async_id, 0);
196
  }
197
198
2066494
  old_default_trigger_async_id_ =
199
2066494
    async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
200
2066494
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
201
1033247
    default_trigger_async_id;
202
1033247
}
203
204
1033246
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() {
205
2066492
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
206
1033246
    old_default_trigger_async_id_;
207
1033246
}
208
209
210
719811
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
211
719811
  return ContainerOf(&Environment::async_hooks_, hooks);
212
}
213
214
1178964
inline AsyncCallbackScope::AsyncCallbackScope(Environment* env) : env_(env) {
215
1178964
  env_->PushAsyncCallbackScope();
216
1178970
}
217
218
1178578
inline AsyncCallbackScope::~AsyncCallbackScope() {
219
1178578
  env_->PopAsyncCallbackScope();
220
1178578
}
221
222
1009800
inline size_t Environment::async_callback_scope_depth() const {
223
1009800
  return async_callback_scope_depth_;
224
}
225
226
1178964
inline void Environment::PushAsyncCallbackScope() {
227
1178964
  async_callback_scope_depth_++;
228
1178964
}
229
230
1178576
inline void Environment::PopAsyncCallbackScope() {
231
1178576
  async_callback_scope_depth_--;
232
1178576
}
233
234
4965
inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
235
4965
    : fields_(isolate, kFieldsCount) {}
236
237
4960
inline AliasedUint32Array& ImmediateInfo::fields() {
238
4960
  return fields_;
239
}
240
241
435346
inline uint32_t ImmediateInfo::count() const {
242
435346
  return fields_[kCount];
243
}
244
245
87157
inline uint32_t ImmediateInfo::ref_count() const {
246
87157
  return fields_[kRefCount];
247
}
248
249
55876
inline bool ImmediateInfo::has_outstanding() const {
250
55876
  return fields_[kHasOutstanding] == 1;
251
}
252
253
54060
inline void ImmediateInfo::count_inc(uint32_t increment) {
254
54060
  fields_[kCount] += increment;
255
54060
}
256
257
48522
inline void ImmediateInfo::count_dec(uint32_t decrement) {
258
48522
  fields_[kCount] -= decrement;
259
48522
}
260
261
31806
inline void ImmediateInfo::ref_count_inc(uint32_t increment) {
262
31806
  fields_[kRefCount] += increment;
263
31806
}
264
265
48522
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
266
48522
  fields_[kRefCount] -= decrement;
267
48522
}
268
269
4965
inline TickInfo::TickInfo(v8::Isolate* isolate)
270
4965
    : fields_(isolate, kFieldsCount) {}
271
272
4961
inline AliasedUint8Array& TickInfo::fields() {
273
4961
  return fields_;
274
}
275
276
1619387
inline bool TickInfo::has_tick_scheduled() const {
277
1619387
  return fields_[kHasTickScheduled] == 1;
278
}
279
280
291433
inline bool TickInfo::has_rejection_to_warn() const {
281
291433
  return fields_[kHasRejectionToWarn] == 1;
282
}
283
284
5428
inline void Environment::AssignToContext(v8::Local<v8::Context> context,
285
                                         const ContextInfo& info) {
286
  context->SetAlignedPointerInEmbedderData(
287
5428
      ContextEmbedderIndex::kEnvironment, this);
288
  // Used by Environment::GetCurrent to know that we are on a node context.
289
  context->SetAlignedPointerInEmbedderData(
290
10856
    ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
291
#if HAVE_INSPECTOR
292
5428
  inspector_agent()->ContextCreated(context, info);
293
#endif  // HAVE_INSPECTOR
294
5428
}
295
296
1038342
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
297
1038342
  if (UNLIKELY(!isolate->InContext())) return nullptr;
298
1038349
  v8::HandleScope handle_scope(isolate);
299
1038350
  return GetCurrent(isolate->GetCurrentContext());
300
}
301
302
1346024
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
303
1346024
  if (UNLIKELY(context.IsEmpty())) {
304
    return nullptr;
305
  }
306
1346024
  if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
307
               ContextEmbedderIndex::kContextTag)) {
308
1
    return nullptr;
309
  }
310
2692040
  if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
311
                   ContextEmbedderIndex::kContextTag) !=
312
               Environment::kNodeContextTagPtr)) {
313
    return nullptr;
314
  }
315
  return static_cast<Environment*>(
316
      context->GetAlignedPointerFromEmbedderData(
317
2692040
          ContextEmbedderIndex::kEnvironment));
318
}
319
320
9372238
inline Environment* Environment::GetCurrent(
321
    const v8::FunctionCallbackInfo<v8::Value>& info) {
322
9372238
  return GetFromCallbackData(info.Data());
323
}
324
325
template <typename T>
326
2209650
inline Environment* Environment::GetCurrent(
327
    const v8::PropertyCallbackInfo<T>& info) {
328
2209650
  return GetFromCallbackData(info.Data());
329
}
330
331
11581888
inline Environment* Environment::GetFromCallbackData(v8::Local<v8::Value> val) {
332
  DCHECK(val->IsObject());
333
11581888
  v8::Local<v8::Object> obj = val.As<v8::Object>();
334
  DCHECK_GE(obj->InternalFieldCount(), 1);
335
  Environment* env =
336
23163776
      static_cast<Environment*>(obj->GetAlignedPointerFromInternalField(0));
337
  DCHECK(env->as_callback_data_template()->HasInstance(obj));
338
11581888
  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
63833384
inline v8::Isolate* Environment::isolate() const {
350
63833384
  return isolate_;
351
}
352
353
5000
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
354
5000
  return ContainerOf(&Environment::timer_handle_, handle);
355
}
356
357
22321
inline uv_timer_t* Environment::timer_handle() {
358
22321
  return &timer_handle_;
359
}
360
361
435347
inline Environment* Environment::from_immediate_check_handle(
362
    uv_check_t* handle) {
363
435347
  return ContainerOf(&Environment::immediate_check_handle_, handle);
364
}
365
366
19860
inline uv_check_t* Environment::immediate_check_handle() {
367
19860
  return &immediate_check_handle_;
368
}
369
370
90145
inline uv_idle_t* Environment::immediate_idle_handle() {
371
90145
  return &immediate_idle_handle_;
372
}
373
374
24825
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
375
                                               HandleCleanupCb cb,
376
                                               void* arg) {
377
24825
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
378
24825
}
379
380
template <typename T, typename OnCloseCallback>
381
27781
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
382
27781
  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
27781
  handle->data = new CloseData { this, callback, handle->data };
394
111076
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
395
27757
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
396
27757
    data->env->handle_cleanup_waiting_--;
397
27757
    handle->data = data->original_data;
398
27757
    data->callback(reinterpret_cast<T*>(handle));
399
83319
  });
400
27781
}
401
402
103506
void Environment::IncreaseWaitingRequestCounter() {
403
103506
  request_waiting_++;
404
103506
}
405
406
103491
void Environment::DecreaseWaitingRequestCounter() {
407
103491
  request_waiting_--;
408
103491
  CHECK_GE(request_waiting_, 0);
409
103491
}
410
411
1296724
inline uv_loop_t* Environment::event_loop() const {
412
1296724
  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
229663
inline bool Environment::is_in_inspector_console_call() const {
427
229663
  return is_in_inspector_console_call_;
428
}
429
430
459324
inline void Environment::set_is_in_inspector_console_call(bool value) {
431
459324
  is_in_inspector_console_call_ = value;
432
459324
}
433
#endif
434
435
8730979
inline AsyncHooks* Environment::async_hooks() {
436
8730979
  return &async_hooks_;
437
}
438
439
766249
inline ImmediateInfo* Environment::immediate_info() {
440
766249
  return &immediate_info_;
441
}
442
443
814663
inline TickInfo* Environment::tick_info() {
444
814663
  return &tick_info_;
445
}
446
447
316587
inline uint64_t Environment::timer_base() const {
448
316587
  return timer_base_;
449
}
450
451
2223399
inline std::shared_ptr<KVStore> Environment::env_vars() {
452
2223399
  return env_vars_;
453
}
454
455
5162
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) {
456
5162
  env_vars_ = env_vars;
457
5162
}
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
4377
inline void Environment::set_trace_sync_io(bool value) {
468
4377
  options_->trace_sync_io = value;
469
4377
}
470
471
25
inline bool Environment::abort_on_uncaught_exception() const {
472
25
  return options_->abort_on_uncaught_exception;
473
}
474
475
197
inline void Environment::set_abort_on_uncaught_exception(bool value) {
476
197
  options_->abort_on_uncaught_exception = value;
477
197
}
478
479
4992
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
480
4992
  return should_abort_on_uncaught_toggle_;
481
}
482
483
2394158
inline AliasedInt32Array& Environment::stream_base_state() {
484
2394158
  return stream_base_state_;
485
}
486
487
381
inline uint32_t Environment::get_next_module_id() {
488
381
  return module_id_counter_++;
489
}
490
1749
inline uint32_t Environment::get_next_script_id() {
491
1749
  return script_id_counter_++;
492
}
493
39793
inline uint32_t Environment::get_next_function_id() {
494
39793
  return function_id_counter_++;
495
}
496
497
2250
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
498
    Environment* env)
499
2250
    : env_(env) {
500
2250
  env_->PushShouldNotAbortOnUncaughtScope();
501
2250
}
502
503
2249
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
504
2249
  Close();
505
2249
}
506
507
2447
void ShouldNotAbortOnUncaughtScope::Close() {
508
2447
  if (env_ != nullptr) {
509
2249
    env_->PopShouldNotAbortOnUncaughtScope();
510
2249
    env_ = nullptr;
511
  }
512
2447
}
513
514
2250
inline void Environment::PushShouldNotAbortOnUncaughtScope() {
515
2250
  should_not_abort_scope_counter_++;
516
2250
}
517
518
2249
inline void Environment::PopShouldNotAbortOnUncaughtScope() {
519
2249
  should_not_abort_scope_counter_--;
520
2249
}
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
198324
inline std::vector<double>* Environment::destroy_async_id_list() {
527
198324
  return &destroy_async_id_list_;
528
}
529
530
273494
inline double Environment::new_async_id() {
531
273494
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
532
273494
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
533
}
534
535
206263
inline double Environment::execution_async_id() {
536
206263
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
537
}
538
539
37553
inline double Environment::trigger_async_id() {
540
37553
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
541
}
542
543
273491
inline double Environment::get_default_trigger_async_id() {
544
  double default_trigger_async_id =
545
273491
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
546
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
547
273491
  if (default_trigger_async_id < 0)
548
168240
    default_trigger_async_id = execution_async_id();
549
273491
  return default_trigger_async_id;
550
}
551
552
69
inline double* Environment::heap_statistics_buffer() const {
553
69
  CHECK_NOT_NULL(heap_statistics_buffer_);
554
69
  return heap_statistics_buffer_;
555
}
556
557
67
inline void Environment::set_heap_statistics_buffer(double* pointer) {
558
67
  CHECK_NULL(heap_statistics_buffer_);  // Should be set only once.
559
67
  heap_statistics_buffer_ = pointer;
560
67
}
561
562
68
inline double* Environment::heap_space_statistics_buffer() const {
563
68
  CHECK_NOT_NULL(heap_space_statistics_buffer_);
564
68
  return heap_space_statistics_buffer_;
565
}
566
567
67
inline void Environment::set_heap_space_statistics_buffer(double* pointer) {
568
67
  CHECK_NULL(heap_space_statistics_buffer_);  // Should be set only once.
569
67
  heap_space_statistics_buffer_ = pointer;
570
67
}
571
572
231578
inline char* Environment::http_parser_buffer() const {
573
231578
  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
77189
inline bool Environment::http_parser_buffer_in_use() const {
582
77189
  return http_parser_buffer_in_use_;
583
}
584
585
154372
inline void Environment::set_http_parser_buffer_in_use(bool in_use) {
586
154372
  http_parser_buffer_in_use_ = in_use;
587
154372
}
588
589
19482
inline http2::Http2State* Environment::http2_state() const {
590
19482
  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
1253406
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
1253406
  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
205470
inline AliasedFloat64Array* Environment::fs_stats_field_array() {
614
205470
  return &fs_stats_field_array_;
615
}
616
617
4969
inline AliasedBigUint64Array* Environment::fs_stats_field_bigint_array() {
618
4969
  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
46683
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
627
46683
  return options_;
628
}
629
630
14355
inline const std::vector<std::string>& Environment::argv() {
631
14355
  return argv_;
632
}
633
634
5157
inline const std::vector<std::string>& Environment::exec_argv() {
635
5157
  return exec_argv_;
636
}
637
638
9920
inline const std::string& Environment::exec_path() const {
639
9920
  return exec_path_;
640
}
641
642
#if HAVE_INSPECTOR
643
4955
inline void Environment::set_coverage_directory(const char* dir) {
644
4955
  coverage_directory_ = std::string(dir);
645
4955
}
646
647
4955
inline void Environment::set_coverage_connection(
648
    std::unique_ptr<profiler::V8CoverageConnection> connection) {
649
4955
  CHECK_NULL(coverage_connection_);
650
4953
  std::swap(coverage_connection_, connection);
651
4954
}
652
653
14778
inline profiler::V8CoverageConnection* Environment::coverage_connection() {
654
14778
  return coverage_connection_.get();
655
}
656
657
4756
inline const std::string& Environment::coverage_directory() const {
658
4756
  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
4889
Environment::cpu_profiler_connection() {
669
4889
  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
4879
Environment::heap_profiler_connection() {
704
4879
  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
10014
inline std::shared_ptr<HostPort> Environment::inspector_host_port() {
734
10014
  return inspector_host_port_;
735
}
736
737
16136
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
738
16136
  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
54060
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
108120
  });
756
54060
  immediate_info()->count_inc(1);
757
54060
}
758
759
31806
void Environment::SetImmediate(native_immediate_callback cb,
760
                               void* data,
761
                               v8::Local<v8::Object> obj) {
762
31806
  CreateImmediate(cb, data, obj, true);
763
764
31806
  if (immediate_info()->ref_count() == 0)
765
23851
    ToggleImmediateRef(true);
766
31806
  immediate_info()->ref_count_inc(1);
767
31806
}
768
769
22254
void Environment::SetUnrefImmediate(native_immediate_callback cb,
770
                                    void* data,
771
                                    v8::Local<v8::Object> obj) {
772
22254
  CreateImmediate(cb, data, obj, false);
773
22254
}
774
775
3592153
inline bool Environment::can_call_into_js() const {
776

3592153
  return can_call_into_js_ && !is_stopping();
777
}
778
779
4628
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
780
4628
  can_call_into_js_ = can_call_into_js;
781
4628
}
782
783
20731
inline bool Environment::has_run_bootstrapping_code() const {
784
20731
  return has_run_bootstrapping_code_;
785
}
786
787
4960
inline void Environment::set_has_run_bootstrapping_code(bool value) {
788
4960
  has_run_bootstrapping_code_ = value;
789
4960
}
790
791
16
inline bool Environment::has_serialized_options() const {
792
16
  return has_serialized_options_;
793
}
794
795
4960
inline void Environment::set_has_serialized_options(bool value) {
796
4960
  has_serialized_options_ = value;
797
4960
}
798
799
24306
inline bool Environment::is_main_thread() const {
800
24306
  return flags_ & kIsMainThread;
801
}
802
803
28583
inline bool Environment::owns_process_state() const {
804
28583
  return flags_ & kOwnsProcessState;
805
}
806
807
4965
inline bool Environment::owns_inspector() const {
808
4965
  return flags_ & kOwnsInspector;
809
}
810
811
8484
inline uint64_t Environment::thread_id() const {
812
8484
  return thread_id_;
813
}
814
815
inline worker::Worker* Environment::worker_context() const {
816
  return worker_context_;
817
}
818
819
197
inline void Environment::set_worker_context(worker::Worker* context) {
820
197
  CHECK_NULL(worker_context_);  // Should be set only once.
821
197
  worker_context_ = context;
822
197
}
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
3590858
inline bool Environment::is_stopping() const {
833
3590858
  return thread_stopper_.is_stopped();
834
}
835
836
38849
inline performance::performance_state* Environment::performance_state() {
837
38849
  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
5989891
inline IsolateData* Environment::isolate_data() const {
846
5989891
  return isolate_data_;
847
}
848
849
467967
inline char* Environment::AllocateUnchecked(size_t size) {
850
  return static_cast<char*>(
851
467967
      isolate_data()->allocator()->AllocateUninitialized(size));
852
}
853
854
435574
inline char* Environment::Allocate(size_t size) {
855
435574
  char* ret = AllocateUnchecked(size);
856
435574
  CHECK_NE(ret, nullptr);
857
435574
  return ret;
858
}
859
860
1088689
inline void Environment::Free(char* data, size_t size) {
861
1088689
  if (data != nullptr)
862
82318
    isolate_data()->allocator()->Free(data, size);
863
1088689
}
864
865
467967
inline AllocatedBuffer Environment::AllocateManaged(size_t size, bool checked) {
866
467967
  char* data = checked ? Allocate(size) : AllocateUnchecked(size);
867
467967
  if (data == nullptr) size = 0;
868
467967
  return AllocatedBuffer(this, uv_buf_init(data, size));
869
}
870
871
847335
inline AllocatedBuffer::AllocatedBuffer(Environment* env, uv_buf_t buf)
872
847335
    : env_(env), buffer_(buf) {}
873
874
340945
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
340945
                                    len > 0 ? len : 1);
878
340945
  CHECK_NOT_NULL(new_data);
879
340945
  buffer_ = uv_buf_init(new_data, len);
880
340945
}
881
882
1940168
inline uv_buf_t AllocatedBuffer::release() {
883
1940168
  uv_buf_t ret = buffer_;
884
1940168
  buffer_ = uv_buf_init(nullptr, 0);
885
1940168
  return ret;
886
}
887
888
591369
inline char* AllocatedBuffer::data() {
889
591369
  return buffer_.base;
890
}
891
892
inline const char* AllocatedBuffer::data() const {
893
  return buffer_.base;
894
}
895
896
748811
inline size_t AllocatedBuffer::size() const {
897
748811
  return buffer_.len;
898
}
899
900
130993
inline AllocatedBuffer::AllocatedBuffer(Environment* env)
901
130993
    : env_(env), buffer_(uv_buf_init(nullptr, 0)) {}
902
903
852
inline AllocatedBuffer::AllocatedBuffer(AllocatedBuffer&& other)
904
852
    : AllocatedBuffer() {
905
852
  *this = std::move(other);
906
852
}
907
908
110544
inline AllocatedBuffer& AllocatedBuffer::operator=(AllocatedBuffer&& other) {
909
110544
  clear();
910
110544
  env_ = other.env_;
911
110544
  buffer_ = other.release();
912
110544
  return *this;
913
}
914
915
978145
inline AllocatedBuffer::~AllocatedBuffer() {
916
978145
  clear();
917
978145
}
918
919
1088689
inline void AllocatedBuffer::clear() {
920
1088689
  uv_buf_t buf = release();
921
1088689
  env_->Free(buf.base, buf.len);
922
1088689
}
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
58412
inline v8::MaybeLocal<v8::Object> AllocatedBuffer::ToBuffer() {
934
58412
  CHECK_NOT_NULL(env_);
935
58412
  v8::MaybeLocal<v8::Object> obj = Buffer::New(env_, data(), size(), false);
936
58412
  if (!obj.IsEmpty()) release();
937
58412
  return obj;
938
}
939
940
332624
inline v8::Local<v8::ArrayBuffer> AllocatedBuffer::ToArrayBuffer() {
941
332624
  CHECK_NOT_NULL(env_);
942
332624
  uv_buf_t buf = release();
943
  return v8::ArrayBuffer::New(env_->isolate(),
944
                              buf.base,
945
                              buf.len,
946
332624
                              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
1801072
    Environment::NewFunctionTemplate(v8::FunctionCallback callback,
987
                                     v8::Local<v8::Signature> signature,
988
                                     v8::ConstructorBehavior behavior,
989
                                     v8::SideEffectType side_effect_type) {
990
1801072
  v8::Local<v8::Object> external = as_callback_data();
991
  return v8::FunctionTemplate::New(isolate(), callback, external,
992
1801073
                                   signature, 0, behavior, side_effect_type);
993
}
994
995
738376
inline void Environment::SetMethod(v8::Local<v8::Object> that,
996
                                   const char* name,
997
                                   v8::FunctionCallback callback) {
998
738376
  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
738376
                          v8::SideEffectType::kHasSideEffect)
1003
2215130
          ->GetFunction(context)
1004
1476753
          .ToLocalChecked();
1005
  // kInternalized strings are created in the old space.
1006
738376
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1007
  v8::Local<v8::String> name_string =
1008
1476753
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1009
1476752
  that->Set(context, name_string, function).Check();
1010
738375
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1011
738376
}
1012
1013
330665
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
1014
                                               const char* name,
1015
                                               v8::FunctionCallback callback) {
1016
330665
  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
330665
                          v8::SideEffectType::kHasNoSideEffect)
1021
991992
          ->GetFunction(context)
1022
661328
          .ToLocalChecked();
1023
  // kInternalized strings are created in the old space.
1024
330665
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1025
  v8::Local<v8::String> name_string =
1026
661330
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1027
661330
  that->Set(context, name_string, function).Check();
1028
330665
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1029
330665
}
1030
1031
496113
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
1032
                                        const char* name,
1033
                                        v8::FunctionCallback callback) {
1034
496113
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1035
  v8::Local<v8::FunctionTemplate> t =
1036
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1037
496113
                          v8::SideEffectType::kHasSideEffect);
1038
  // kInternalized strings are created in the old space.
1039
496113
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1040
  v8::Local<v8::String> name_string =
1041
992226
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1042
992226
  that->PrototypeTemplate()->Set(name_string, t);
1043
496113
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1044
496113
}
1045
1046
47567
inline void Environment::SetProtoMethodNoSideEffect(
1047
    v8::Local<v8::FunctionTemplate> that,
1048
    const char* name,
1049
    v8::FunctionCallback callback) {
1050
47567
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1051
  v8::Local<v8::FunctionTemplate> t =
1052
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1053
47567
                          v8::SideEffectType::kHasNoSideEffect);
1054
  // kInternalized strings are created in the old space.
1055
47567
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1056
  v8::Local<v8::String> name_string =
1057
95134
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1058
95134
  that->PrototypeTemplate()->Set(name_string, t);
1059
47567
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1060
47567
}
1061
1062
700280
void Environment::AddCleanupHook(void (*fn)(void*), void* arg) {
1063
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
1064
    fn, arg, cleanup_hook_counter_++
1065
700280
  });
1066
  // Make sure there was no existing element with these values.
1067
700280
  CHECK_EQ(insertion_info.second, true);
1068
700280
}
1069
1070
697187
void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
1071
697187
  CleanupHookCallback search { fn, arg, 0 };
1072
697187
  cleanup_hooks_.erase(search);
1073
697189
}
1074
1075
1550033
size_t CleanupHookCallback::Hash::operator()(
1076
    const CleanupHookCallback& cb) const {
1077
1550033
  return std::hash<void*>()(cb.arg_);
1078
}
1079
1080
772848
bool CleanupHookCallback::Equal::operator()(
1081
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
1082

772848
  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
3590879
bool AsyncRequest::is_stopped() const {
1102
3590879
  return stopped_.load();
1103
}
1104
1105
5424
void AsyncRequest::set_stopped(bool flag) {
1106
5424
  stopped_.store(flag);
1107
5425
}
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
20974
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1119
627012
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1120
5639264
  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
10487
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1134
313305
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1135
2809120
  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
500152
  ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1149
7112613
  ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1150
#undef V
1151
1152
16830989
  inline v8::Local<v8::Context> Environment::context() const {
1153
16830989
    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_