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: 423 426 99.3 %
Date: 2019-02-23 22:23:05 Branches: 68 90 75.6 %

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
#include "node_worker.h"
36
37
#include <stddef.h>
38
#include <stdint.h>
39
40
#include <utility>
41
42
namespace node {
43
44
inline v8::Isolate* IsolateData::isolate() const {
45
  return isolate_;
46
}
47
48
1853225
inline uv_loop_t* IsolateData::event_loop() const {
49
1853225
  return event_loop_;
50
}
51
52
4400
inline uint32_t* IsolateData::zero_fill_field() const {
53
4400
  return zero_fill_field_;
54
}
55
56
132759
inline MultiIsolatePlatform* IsolateData::platform() const {
57
132759
  return platform_;
58
}
59
60
4405
inline Environment::AsyncHooks::AsyncHooks()
61
    : async_ids_stack_(env()->isolate(), 16 * 2),
62
      fields_(env()->isolate(), kFieldsCount),
63
185010
      async_id_fields_(env()->isolate(), kUidFieldsCount) {
64
4405
  v8::HandleScope handle_scope(env()->isolate());
65
66
  // Always perform async_hooks checks, not just when async_hooks is enabled.
67
  // TODO(AndreasMadsen): Consider removing this for LTS releases.
68
  // See discussion in https://github.com/nodejs/node/pull/15454
69
  // When removing this, do it by reverting the commit. Otherwise the test
70
  // and flag changes won't be included.
71
4405
  fields_[kCheck] = 1;
72
73
  // kDefaultTriggerAsyncId should be -1, this indicates that there is no
74
  // specified default value and it should fallback to the executionAsyncId.
75
  // 0 is not used as the magic value, because that indicates a missing context
76
  // which is different from a default context.
77
4405
  async_id_fields_[AsyncHooks::kDefaultTriggerAsyncId] = -1;
78
79
  // kAsyncIdCounter should start at 1 because that'll be the id the execution
80
  // context during bootstrap (code that runs before entering uv_run()).
81
4405
  async_id_fields_[AsyncHooks::kAsyncIdCounter] = 1;
82
83
  // Create all the provider strings that will be passed to JS. Place them in
84
  // an array so the array index matches the PROVIDER id offset. This way the
85
  // strings can be retrieved quickly.
86
#define V(Provider)                                                           \
87
  providers_[AsyncWrap::PROVIDER_ ## Provider].Set(                           \
88
      env()->isolate(),                                                       \
89
      v8::String::NewFromOneByte(                                             \
90
        env()->isolate(),                                                     \
91
        reinterpret_cast<const uint8_t*>(#Provider),                          \
92
        v8::NewStringType::kInternalized,                                     \
93
        sizeof(#Provider) - 1).ToLocalChecked());
94
365615
  NODE_ASYNC_PROVIDER_TYPES(V)
95
#undef V
96
4405
}
97
98
inline AliasedBuffer<uint32_t, v8::Uint32Array>&
99
5226601
Environment::AsyncHooks::fields() {
100
5226601
  return fields_;
101
}
102
103
inline AliasedBuffer<double, v8::Float64Array>&
104
4630201
Environment::AsyncHooks::async_id_fields() {
105
4630201
  return async_id_fields_;
106
}
107
108
inline AliasedBuffer<double, v8::Float64Array>&
109
4397
Environment::AsyncHooks::async_ids_stack() {
110
4397
  return async_ids_stack_;
111
}
112
113
357524
inline v8::Local<v8::String> Environment::AsyncHooks::provider_string(int idx) {
114
715048
  return providers_[idx].Get(env()->isolate());
115
}
116
117
1
inline void Environment::AsyncHooks::no_force_checks() {
118
1
  fields_[kCheck] -= 1;
119
1
}
120
121
833738
inline Environment* Environment::AsyncHooks::env() {
122
833738
  return Environment::ForAsyncHooks(this);
123
}
124
125
// Remember to keep this code aligned with pushAsyncIds() in JS.
126
1234155
inline void Environment::AsyncHooks::push_async_ids(double async_id,
127
                                                    double trigger_async_id) {
128
  // Since async_hooks is experimental, do only perform the check
129
  // when async_hooks is enabled.
130
1234155
  if (fields_[kCheck] > 0) {
131
1234151
    CHECK_GE(async_id, -1);
132
1234151
    CHECK_GE(trigger_async_id, -1);
133
  }
134
135
1234155
  uint32_t offset = fields_[kStackLength];
136
1234150
  if (offset * 2 >= async_ids_stack_.Length())
137
8
    grow_async_ids_stack();
138
1234154
  async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId];
139
1234155
  async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId];
140
1234151
  fields_[kStackLength] += 1;
141
1234151
  async_id_fields_[kExecutionAsyncId] = async_id;
142
1234152
  async_id_fields_[kTriggerAsyncId] = trigger_async_id;
143
1234152
}
144
145
// Remember to keep this code aligned with popAsyncIds() in JS.
146
1233823
inline bool Environment::AsyncHooks::pop_async_id(double async_id) {
147
  // In case of an exception then this may have already been reset, if the
148
  // stack was multiple MakeCallback()'s deep.
149
1233823
  if (fields_[kStackLength] == 0) return false;
150
151
  // Ask for the async_id to be restored as a check that the stack
152
  // hasn't been corrupted.
153
  // Since async_hooks is experimental, do only perform the check
154
  // when async_hooks is enabled.
155


1233188
  if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) {
156
    fprintf(stderr,
157
            "Error: async hook stack has become corrupted ("
158
            "actual: %.f, expected: %.f)\n",
159
            async_id_fields_.GetValue(kExecutionAsyncId),
160
4
            async_id);
161
4
    DumpBacktrace(stderr);
162
4
    fflush(stderr);
163
4
    if (!env()->abort_on_uncaught_exception())
164
4
      exit(1);
165
    fprintf(stderr, "\n");
166
    fflush(stderr);
167
    ABORT_NO_BACKTRACE();
168
  }
169
170
1233184
  uint32_t offset = fields_[kStackLength] - 1;
171
1233184
  async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset];
172
1233184
  async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1];
173
1233184
  fields_[kStackLength] = offset;
174
175
1233184
  return fields_[kStackLength] > 0;
176
}
177
178
// Keep in sync with clearAsyncIdStack in lib/internal/async_hooks.js.
179
55
inline void Environment::AsyncHooks::clear_async_id_stack() {
180
55
  async_id_fields_[kExecutionAsyncId] = 0;
181
55
  async_id_fields_[kTriggerAsyncId] = 0;
182
55
  fields_[kStackLength] = 0;
183
55
}
184
185
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in
186
// async_wrap-inl.h to avoid a circular dependency.
187
188
945679
inline Environment::AsyncHooks::DefaultTriggerAsyncIdScope
189
  ::DefaultTriggerAsyncIdScope(Environment* env,
190
                               double default_trigger_async_id)
191
945679
    : async_hooks_(env->async_hooks()) {
192
945679
  if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) {
193
945679
    CHECK_GE(default_trigger_async_id, 0);
194
  }
195
196
1891358
  old_default_trigger_async_id_ =
197
1891358
    async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
198
1891358
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
199
945679
    default_trigger_async_id;
200
945679
}
201
202
945678
inline Environment::AsyncHooks::DefaultTriggerAsyncIdScope
203
  ::~DefaultTriggerAsyncIdScope() {
204
1891356
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
205
945678
    old_default_trigger_async_id_;
206
945678
}
207
208
209
833738
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
210
833738
  return ContainerOf(&Environment::async_hooks_, hooks);
211
}
212
213
214
1405668
inline Environment::AsyncCallbackScope::AsyncCallbackScope(Environment* env)
215
1405668
    : env_(env) {
216
1405668
  env_->makecallback_cntr_++;
217
1405668
}
218
219
1405301
inline Environment::AsyncCallbackScope::~AsyncCallbackScope() {
220
1405301
  env_->makecallback_cntr_--;
221
1405301
}
222
223
1229494
inline size_t Environment::makecallback_depth() const {
224
1229494
  return makecallback_cntr_;
225
}
226
227
4405
inline Environment::ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
228
4405
    : fields_(isolate, kFieldsCount) {}
229
230
inline AliasedBuffer<uint32_t, v8::Uint32Array>&
231
4396
    Environment::ImmediateInfo::fields() {
232
4396
  return fields_;
233
}
234
235
564894
inline uint32_t Environment::ImmediateInfo::count() const {
236
564894
  return fields_[kCount];
237
}
238
239
80134
inline uint32_t Environment::ImmediateInfo::ref_count() const {
240
80134
  return fields_[kRefCount];
241
}
242
243
53152
inline bool Environment::ImmediateInfo::has_outstanding() const {
244
53152
  return fields_[kHasOutstanding] == 1;
245
}
246
247
49712
inline void Environment::ImmediateInfo::count_inc(uint32_t increment) {
248
49712
  fields_[kCount] += increment;
249
49712
}
250
251
46332
inline void Environment::ImmediateInfo::count_dec(uint32_t decrement) {
252
46332
  fields_[kCount] -= decrement;
253
46332
}
254
255
27503
inline void Environment::ImmediateInfo::ref_count_inc(uint32_t increment) {
256
27503
  fields_[kRefCount] += increment;
257
27503
}
258
259
46332
inline void Environment::ImmediateInfo::ref_count_dec(uint32_t decrement) {
260
46332
  fields_[kRefCount] -= decrement;
261
46332
}
262
263
4405
inline Environment::TickInfo::TickInfo(v8::Isolate* isolate)
264
4405
    : fields_(isolate, kFieldsCount) {}
265
266
4397
inline AliasedBuffer<uint8_t, v8::Uint8Array>& Environment::TickInfo::fields() {
267
4397
  return fields_;
268
}
269
270
2022728
inline bool Environment::TickInfo::has_tick_scheduled() const {
271
2022728
  return fields_[kHasTickScheduled] == 1;
272
}
273
274
443124
inline bool Environment::TickInfo::has_rejection_to_warn() const {
275
443124
  return fields_[kHasRejectionToWarn] == 1;
276
}
277
278
8952
inline void Environment::AssignToContext(v8::Local<v8::Context> context,
279
                                         const ContextInfo& info) {
280
  context->SetAlignedPointerInEmbedderData(
281
8952
      ContextEmbedderIndex::kEnvironment, this);
282
  // Used by EnvPromiseHook to know that we are on a node context.
283
  context->SetAlignedPointerInEmbedderData(
284
17904
    ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
285
#if HAVE_INSPECTOR
286
8952
  inspector_agent()->ContextCreated(context, info);
287
#endif  // HAVE_INSPECTOR
288
8952
}
289
290
1288140
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
291
1288140
  return GetCurrent(isolate->GetCurrentContext());
292
}
293
294
1513635
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
295


6054561
  if (UNLIKELY(context.IsEmpty() ||
296
      context->GetNumberOfEmbedderDataFields() <
297
          ContextEmbedderIndex::kContextTag ||
298
      context->GetAlignedPointerFromEmbedderData(
299
          ContextEmbedderIndex::kContextTag) !=
300
          Environment::kNodeContextTagPtr)) {
301
1
    return nullptr;
302
  }
303
304
  return static_cast<Environment*>(
305
      context->GetAlignedPointerFromEmbedderData(
306
3027276
          ContextEmbedderIndex::kEnvironment));
307
}
308
309
5497834
inline Environment* Environment::GetCurrent(
310
    const v8::FunctionCallbackInfo<v8::Value>& info) {
311
10995668
  CHECK(info.Data()->IsExternal());
312
16493508
  return static_cast<Environment*>(info.Data().As<v8::External>()->Value());
313
}
314
315
template <typename T>
316
12338
inline Environment* Environment::GetCurrent(
317
    const v8::PropertyCallbackInfo<T>& info) {
318

24676
  CHECK(info.Data()->IsExternal());
319
  return static_cast<Environment*>(
320
37014
      info.Data().template As<v8::External>()->Value());
321
}
322
323
7
inline Environment* Environment::GetThreadLocalEnv() {
324
7
  return static_cast<Environment*>(uv_key_get(&thread_local_env));
325
}
326
327
170
inline bool Environment::profiler_idle_notifier_started() const {
328
170
  return profiler_idle_notifier_started_;
329
}
330
331
64000947
inline v8::Isolate* Environment::isolate() const {
332
64000947
  return isolate_;
333
}
334
335
5891
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
336
5891
  return ContainerOf(&Environment::timer_handle_, handle);
337
}
338
339
21876
inline uv_timer_t* Environment::timer_handle() {
340
21876
  return &timer_handle_;
341
}
342
343
564895
inline Environment* Environment::from_immediate_check_handle(
344
    uv_check_t* handle) {
345
564895
  return ContainerOf(&Environment::immediate_check_handle_, handle);
346
}
347
348
17620
inline uv_check_t* Environment::immediate_check_handle() {
349
17620
  return &immediate_check_handle_;
350
}
351
352
83425
inline uv_idle_t* Environment::immediate_idle_handle() {
353
83425
  return &immediate_idle_handle_;
354
}
355
356
22025
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
357
                                               HandleCleanupCb cb,
358
                                               void* arg) {
359
22025
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
360
22025
}
361
362
template <typename T, typename OnCloseCallback>
363
20582
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
364
20582
  handle_cleanup_waiting_++;
365
  static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle");
366
  static_assert(offsetof(T, data) == offsetof(uv_handle_t, data),
367
                "T is a libuv handle");
368
  static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb),
369
                "T is a libuv handle");
370
  struct CloseData {
371
    Environment* env;
372
    OnCloseCallback callback;
373
    void* original_data;
374
  };
375
20582
  handle->data = new CloseData { this, callback, handle->data };
376
82282
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
377
20559
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
378
20559
    data->env->handle_cleanup_waiting_--;
379
20559
    handle->data = data->original_data;
380
20559
    data->callback(reinterpret_cast<T*>(handle));
381
61723
  });
382
20582
}
383
384
221513
void Environment::IncreaseWaitingRequestCounter() {
385
221513
  request_waiting_++;
386
221513
}
387
388
221496
void Environment::DecreaseWaitingRequestCounter() {
389
221496
  request_waiting_--;
390
221496
  CHECK_GE(request_waiting_, 0);
391
221496
}
392
393
1848819
inline uv_loop_t* Environment::event_loop() const {
394
1848819
  return isolate_data()->event_loop();
395
}
396
397
135
inline void Environment::TryLoadAddon(
398
    const char* filename,
399
    int flags,
400
    const std::function<bool(binding::DLib*)>& was_loaded) {
401
135
  loaded_addons_.emplace_back(filename, flags);
402
135
  if (!was_loaded(&loaded_addons_.back())) {
403
7
    loaded_addons_.pop_back();
404
  }
405
135
}
406
407
#if HAVE_INSPECTOR
408
128108
inline bool Environment::is_in_inspector_console_call() const {
409
128108
  return is_in_inspector_console_call_;
410
}
411
412
256214
inline void Environment::set_is_in_inspector_console_call(bool value) {
413
256214
  is_in_inspector_console_call_ = value;
414
256214
}
415
#endif
416
417
10892130
inline Environment::AsyncHooks* Environment::async_hooks() {
418
10892130
  return &async_hooks_;
419
}
420
421
872455
inline Environment::ImmediateInfo* Environment::immediate_info() {
422
872455
  return &immediate_info_;
423
}
424
425
1015765
inline Environment::TickInfo* Environment::tick_info() {
426
1015765
  return &tick_info_;
427
}
428
429
685575
inline uint64_t Environment::timer_base() const {
430
685575
  return timer_base_;
431
}
432
433
12
inline bool Environment::printed_error() const {
434
12
  return printed_error_;
435
}
436
437
12
inline void Environment::set_printed_error(bool value) {
438
12
  printed_error_ = value;
439
12
}
440
441
3875
inline void Environment::set_trace_sync_io(bool value) {
442
3875
  options_->trace_sync_io = value;
443
3875
}
444
445
19
inline bool Environment::abort_on_uncaught_exception() const {
446
19
  return options_->abort_on_uncaught_exception;
447
}
448
449
165
inline void Environment::set_abort_on_uncaught_exception(bool value) {
450
165
  options_->abort_on_uncaught_exception = value;
451
165
}
452
453
inline AliasedBuffer<uint32_t, v8::Uint32Array>&
454
4431
Environment::should_abort_on_uncaught_toggle() {
455
4431
  return should_abort_on_uncaught_toggle_;
456
}
457
458
inline AliasedBuffer<int32_t, v8::Int32Array>&
459
2296148
Environment::stream_base_state() {
460
2296148
  return stream_base_state_;
461
}
462
463
260
inline uint32_t Environment::get_next_module_id() {
464
260
  return module_id_counter_++;
465
}
466
4528
inline uint32_t Environment::get_next_script_id() {
467
4528
  return script_id_counter_++;
468
}
469
41458
inline uint32_t Environment::get_next_function_id() {
470
41458
  return function_id_counter_++;
471
}
472
473
4875
Environment::ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
474
    Environment* env)
475
4875
    : env_(env) {
476
4875
  env_->should_not_abort_scope_counter_++;
477
4875
}
478
479
4874
Environment::ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
480
4874
  Close();
481
4874
}
482
483
5076
void Environment::ShouldNotAbortOnUncaughtScope::Close() {
484
5076
  if (env_ != nullptr) {
485
4874
    env_->should_not_abort_scope_counter_--;
486
4874
    env_ = nullptr;
487
  }
488
5076
}
489
490
1
bool Environment::inside_should_not_abort_on_uncaught_scope() const {
491
1
  return should_not_abort_scope_counter_ > 0;
492
}
493
494
202960
inline std::vector<double>* Environment::destroy_async_id_list() {
495
202960
  return &destroy_async_id_list_;
496
}
497
498
455354
inline double Environment::new_async_id() {
499
455354
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
500
455354
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
501
}
502
503
384652
inline double Environment::execution_async_id() {
504
384652
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
505
}
506
507
37267
inline double Environment::trigger_async_id() {
508
37267
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
509
}
510
511
455351
inline double Environment::get_default_trigger_async_id() {
512
  double default_trigger_async_id =
513
455351
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
514
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
515
455351
  if (default_trigger_async_id < 0)
516
346727
    default_trigger_async_id = execution_async_id();
517
455351
  return default_trigger_async_id;
518
}
519
520
4390
inline double* Environment::heap_statistics_buffer() const {
521
4390
  CHECK_NOT_NULL(heap_statistics_buffer_);
522
4390
  return heap_statistics_buffer_;
523
}
524
525
4388
inline void Environment::set_heap_statistics_buffer(double* pointer) {
526
4388
  CHECK_NULL(heap_statistics_buffer_);  // Should be set only once.
527
4388
  heap_statistics_buffer_ = pointer;
528
4388
}
529
530
4389
inline double* Environment::heap_space_statistics_buffer() const {
531
4389
  CHECK_NOT_NULL(heap_space_statistics_buffer_);
532
4389
  return heap_space_statistics_buffer_;
533
}
534
535
4388
inline void Environment::set_heap_space_statistics_buffer(double* pointer) {
536
4388
  CHECK_NULL(heap_space_statistics_buffer_);  // Should be set only once.
537
4388
  heap_space_statistics_buffer_ = pointer;
538
4388
}
539
540
192139
inline char* Environment::http_parser_buffer() const {
541
192139
  return http_parser_buffer_;
542
}
543
544
281
inline void Environment::set_http_parser_buffer(char* buffer) {
545
281
  CHECK_NULL(http_parser_buffer_);  // Should be set only once.
546
281
  http_parser_buffer_ = buffer;
547
281
}
548
549
64040
inline bool Environment::http_parser_buffer_in_use() const {
550
64040
  return http_parser_buffer_in_use_;
551
}
552
553
128077
inline void Environment::set_http_parser_buffer_in_use(bool in_use) {
554
128077
  http_parser_buffer_in_use_ = in_use;
555
128077
}
556
557
19412
inline http2::Http2State* Environment::http2_state() const {
558
19412
  return http2_state_.get();
559
}
560
561
220
inline void Environment::set_http2_state(
562
    std::unique_ptr<http2::Http2State> buffer) {
563
220
  CHECK(!http2_state_);  // Should be set only once.
564
220
  http2_state_ = std::move(buffer);
565
220
}
566
567
717838
bool Environment::debug_enabled(DebugCategory category) const {
568
  DCHECK_GE(static_cast<int>(category), 0);
569
  DCHECK_LT(static_cast<int>(category),
570
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
571
717838
  return debug_enabled_[static_cast<int>(category)];
572
}
573
574
4
void Environment::set_debug_enabled(DebugCategory category, bool enabled) {
575
  DCHECK_GE(static_cast<int>(category), 0);
576
  DCHECK_LT(static_cast<int>(category),
577
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
578
4
  debug_enabled_[static_cast<int>(category)] = enabled;
579
4
}
580
581
inline AliasedBuffer<double, v8::Float64Array>*
582
193990
Environment::fs_stats_field_array() {
583
193990
  return &fs_stats_field_array_;
584
}
585
586
inline AliasedBuffer<uint64_t, v8::BigUint64Array>*
587
4401
Environment::fs_stats_field_bigint_array() {
588
4401
  return &fs_stats_field_bigint_array_;
589
}
590
591
inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>&
592
438
Environment::file_handle_read_wrap_freelist() {
593
438
  return file_handle_read_wrap_freelist_;
594
}
595
596
108950
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
597
108950
  return options_;
598
}
599
600
8893
inline std::shared_ptr<HostPort> Environment::inspector_host_port() {
601
8893
  return inspector_host_port_;
602
}
603
604
13327
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
605
13327
  return options_;
606
}
607
608
4
inline void IsolateData::set_options(
609
    std::shared_ptr<PerIsolateOptions> options) {
610
4
  options_ = std::move(options);
611
4
}
612
613
49712
void Environment::CreateImmediate(native_immediate_callback cb,
614
                                  void* data,
615
                                  v8::Local<v8::Object> obj,
616
                                  bool ref) {
617
  native_immediate_callbacks_.push_back({
618
    cb,
619
    data,
620
49712
    std::unique_ptr<Persistent<v8::Object>>(obj.IsEmpty() ?
621
27499
        nullptr : new Persistent<v8::Object>(isolate_, obj)),
622
    ref
623

126923
  });
624
49712
  immediate_info()->count_inc(1);
625
49712
}
626
627
27503
void Environment::SetImmediate(native_immediate_callback cb,
628
                               void* data,
629
                               v8::Local<v8::Object> obj) {
630
27503
  CreateImmediate(cb, data, obj, true);
631
632
27503
  if (immediate_info()->ref_count() == 0)
633
22752
    ToggleImmediateRef(true);
634
27503
  immediate_info()->ref_count_inc(1);
635
27503
}
636
637
22209
void Environment::SetUnrefImmediate(native_immediate_callback cb,
638
                                    void* data,
639
                                    v8::Local<v8::Object> obj) {
640
22209
  CreateImmediate(cb, data, obj, false);
641
22209
}
642
643
4231587
inline bool Environment::can_call_into_js() const {
644

4231587
  return can_call_into_js_ && (is_main_thread() || !is_stopping_worker());
645
}
646
647
4035
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
648
4035
  can_call_into_js_ = can_call_into_js;
649
4035
}
650
651
4404
inline bool Environment::has_run_bootstrapping_code() const {
652
4404
  return has_run_bootstrapping_code_;
653
}
654
655
4402
inline void Environment::set_has_run_bootstrapping_code(bool value) {
656
4402
  has_run_bootstrapping_code_ = value;
657
4402
}
658
659
4261812
inline bool Environment::is_main_thread() const {
660
4261812
  return flags_ & kIsMainThread;
661
}
662
663
26674
inline bool Environment::owns_process_state() const {
664
26674
  return flags_ & kOwnsProcessState;
665
}
666
667
4405
inline bool Environment::owns_inspector() const {
668
4405
  return flags_ & kOwnsInspector;
669
}
670
671
4558
inline uint64_t Environment::thread_id() const {
672
4558
  return thread_id_;
673
}
674
675
inline worker::Worker* Environment::worker_context() const {
676
  return worker_context_;
677
}
678
679
165
inline void Environment::set_worker_context(worker::Worker* context) {
680
165
  CHECK_NULL(worker_context_);  // Should be set only once.
681
165
  worker_context_ = context;
682
165
}
683
684
169
inline void Environment::add_sub_worker_context(worker::Worker* context) {
685
169
  sub_worker_contexts_.insert(context);
686
169
}
687
688
192
inline void Environment::remove_sub_worker_context(worker::Worker* context) {
689
192
  sub_worker_contexts_.erase(context);
690
192
}
691
692
20398
inline bool Environment::is_stopping_worker() const {
693
20398
  CHECK(!is_main_thread());
694
20398
  return worker_context_->is_stopped();
695
}
696
697
34416
inline performance::performance_state* Environment::performance_state() {
698
34416
  return performance_state_.get();
699
}
700
701
inline std::unordered_map<std::string, uint64_t>*
702
42
    Environment::performance_marks() {
703
42
  return &performance_marks_;
704
}
705
706
6741892
inline IsolateData* Environment::isolate_data() const {
707
6741892
  return isolate_data_;
708
}
709
710
700
inline void Environment::ThrowError(const char* errmsg) {
711
700
  ThrowError(v8::Exception::Error, errmsg);
712
700
}
713
714
5
inline void Environment::ThrowTypeError(const char* errmsg) {
715
5
  ThrowError(v8::Exception::TypeError, errmsg);
716
5
}
717
718
inline void Environment::ThrowRangeError(const char* errmsg) {
719
  ThrowError(v8::Exception::RangeError, errmsg);
720
}
721
722
705
inline void Environment::ThrowError(
723
    v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
724
    const char* errmsg) {
725
705
  v8::HandleScope handle_scope(isolate());
726
705
  isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
727
705
}
728
729
3
inline void Environment::ThrowErrnoException(int errorno,
730
                                             const char* syscall,
731
                                             const char* message,
732
                                             const char* path) {
733
  isolate()->ThrowException(
734
3
      ErrnoException(isolate(), errorno, syscall, message, path));
735
3
}
736
737
14
inline void Environment::ThrowUVException(int errorno,
738
                                          const char* syscall,
739
                                          const char* message,
740
                                          const char* path,
741
                                          const char* dest) {
742
  isolate()->ThrowException(
743
14
      UVException(isolate(), errorno, syscall, message, path, dest));
744
14
}
745
746
inline v8::Local<v8::FunctionTemplate>
747
1612531
    Environment::NewFunctionTemplate(v8::FunctionCallback callback,
748
                                     v8::Local<v8::Signature> signature,
749
                                     v8::ConstructorBehavior behavior,
750
                                     v8::SideEffectType side_effect_type) {
751
1612531
  v8::Local<v8::External> external = as_external();
752
  return v8::FunctionTemplate::New(isolate(), callback, external,
753
1612532
                                   signature, 0, behavior, side_effect_type);
754
}
755
756
626197
inline void Environment::SetMethod(v8::Local<v8::Object> that,
757
                                   const char* name,
758
                                   v8::FunctionCallback callback) {
759
626197
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
760
  v8::Local<v8::Function> function =
761
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
762
                          // TODO(TimothyGu): Investigate if SetMethod is ever
763
                          // used for constructors.
764
                          v8::ConstructorBehavior::kAllow,
765
626197
                          v8::SideEffectType::kHasSideEffect)
766
1878591
          ->GetFunction(context)
767
1252394
          .ToLocalChecked();
768
  // kInternalized strings are created in the old space.
769
626197
  const v8::NewStringType type = v8::NewStringType::kInternalized;
770
  v8::Local<v8::String> name_string =
771
1252395
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
772
1252396
  that->Set(context, name_string, function).FromJust();
773
626198
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
774
626198
}
775
776
296462
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
777
                                               const char* name,
778
                                               v8::FunctionCallback callback) {
779
296462
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
780
  v8::Local<v8::Function> function =
781
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
782
                          // TODO(TimothyGu): Investigate if SetMethod is ever
783
                          // used for constructors.
784
                          v8::ConstructorBehavior::kAllow,
785
296455
                          v8::SideEffectType::kHasNoSideEffect)
786
889377
          ->GetFunction(context)
787
592917
          .ToLocalChecked();
788
  // kInternalized strings are created in the old space.
789
296455
  const v8::NewStringType type = v8::NewStringType::kInternalized;
790
  v8::Local<v8::String> name_string =
791
592918
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
792
592925
  that->Set(context, name_string, function).FromJust();
793
296462
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
794
296461
}
795
796
474258
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
797
                                        const char* name,
798
                                        v8::FunctionCallback callback) {
799
474258
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
800
  v8::Local<v8::FunctionTemplate> t =
801
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
802
474258
                          v8::SideEffectType::kHasSideEffect);
803
  // kInternalized strings are created in the old space.
804
474259
  const v8::NewStringType type = v8::NewStringType::kInternalized;
805
  v8::Local<v8::String> name_string =
806
948518
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
807
948518
  that->PrototypeTemplate()->Set(name_string, t);
808
474259
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
809
474259
}
810
811
41724
inline void Environment::SetProtoMethodNoSideEffect(
812
    v8::Local<v8::FunctionTemplate> that,
813
    const char* name,
814
    v8::FunctionCallback callback) {
815
41724
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
816
  v8::Local<v8::FunctionTemplate> t =
817
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
818
41724
                          v8::SideEffectType::kHasNoSideEffect);
819
  // kInternalized strings are created in the old space.
820
41724
  const v8::NewStringType type = v8::NewStringType::kInternalized;
821
  v8::Local<v8::String> name_string =
822
83448
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
823
83448
  that->PrototypeTemplate()->Set(name_string, t);
824
41724
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
825
41724
}
826
827
inline void Environment::SetTemplateMethod(v8::Local<v8::FunctionTemplate> that,
828
                                           const char* name,
829
                                           v8::FunctionCallback callback) {
830
  v8::Local<v8::FunctionTemplate> t =
831
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
832
                          v8::ConstructorBehavior::kAllow,
833
                          v8::SideEffectType::kHasSideEffect);
834
  // kInternalized strings are created in the old space.
835
  const v8::NewStringType type = v8::NewStringType::kInternalized;
836
  v8::Local<v8::String> name_string =
837
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
838
  that->Set(name_string, t);
839
  t->SetClassName(name_string);  // NODE_SET_METHOD() compatibility.
840
}
841
842
inline void Environment::SetTemplateMethodNoSideEffect(
843
    v8::Local<v8::FunctionTemplate> that,
844
    const char* name,
845
    v8::FunctionCallback callback) {
846
  v8::Local<v8::FunctionTemplate> t =
847
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
848
                          v8::ConstructorBehavior::kAllow,
849
                          v8::SideEffectType::kHasNoSideEffect);
850
  // kInternalized strings are created in the old space.
851
  const v8::NewStringType type = v8::NewStringType::kInternalized;
852
  v8::Local<v8::String> name_string =
853
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
854
  that->Set(name_string, t);
855
  t->SetClassName(name_string);  // NODE_SET_METHOD() compatibility.
856
}
857
858
856692
void Environment::AddCleanupHook(void (*fn)(void*), void* arg) {
859
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
860
    fn, arg, cleanup_hook_counter_++
861
856692
  });
862
  // Make sure there was no existing element with these values.
863
856692
  CHECK_EQ(insertion_info.second, true);
864
856692
}
865
866
854812
void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
867
854812
  CleanupHookCallback search { fn, arg, 0 };
868
854812
  cleanup_hooks_.erase(search);
869
854812
}
870
871
1792670
size_t Environment::CleanupHookCallback::Hash::operator()(
872
    const CleanupHookCallback& cb) const {
873
1792670
  return std::hash<void*>()(cb.arg_);
874
}
875
876
895465
bool Environment::CleanupHookCallback::Equal::operator()(
877
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
878

895465
  return a.fn_ == b.fn_ && a.arg_ == b.arg_;
879
}
880
881
96
BaseObject* Environment::CleanupHookCallback::GetBaseObject() const {
882
96
  if (fn_ == BaseObject::DeleteMe)
883
95
    return static_cast<BaseObject*>(arg_);
884
  else
885
1
    return nullptr;
886
}
887
888
template <typename T>
889
32
void Environment::ForEachBaseObject(T&& iterator) {
890
128
  for (const auto& hook : cleanup_hooks_) {
891
96
    BaseObject* obj = hook.GetBaseObject();
892
96
    if (obj != nullptr)
893
95
      iterator(obj);
894
  }
895
32
}
896
897
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
898
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
899
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
900
#define V(TypeName, PropertyName)                                             \
901
  inline                                                                      \
902
  v8::Local<TypeName> IsolateData::PropertyName(v8::Isolate* isolate) const { \
903
    /* Strings are immutable so casting away const-ness here is okay. */      \
904
    return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate);    \
905
  }
906
76948
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
907
263668
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
908
8753846
  PER_ISOLATE_STRING_PROPERTIES(VS)
909
#undef V
910
#undef VS
911
#undef VY
912
#undef VP
913
914
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
915
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
916
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
917
#define V(TypeName, PropertyName)                                             \
918
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
919
    return isolate_data()->PropertyName(isolate());                           \
920
  }
921
38474
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
922
131834
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
923
4376917
  PER_ISOLATE_STRING_PROPERTIES(VS)
924
#undef V
925
#undef VS
926
#undef VY
927
#undef VP
928
929
#define V(PropertyName, TypeName)                                             \
930
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
931
    return PersistentToLocal::Strong(PropertyName ## _);                      \
932
  }                                                                           \
933
  inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) {  \
934
    PropertyName ## _.Reset(isolate(), value);                                \
935
  }
936
22988074
  ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
937
#undef V
938
939
}  // namespace node
940
941
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
942
943
#endif  // SRC_ENV_INL_H_