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: 483 486 99.4 %
Date: 2019-03-02 22:23:06 Branches: 76 106 71.7 %

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


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


5908831
  if (UNLIKELY(context.IsEmpty() ||
304
      context->GetNumberOfEmbedderDataFields() <
305
          ContextEmbedderIndex::kContextTag ||
306
      context->GetAlignedPointerFromEmbedderData(
307
          ContextEmbedderIndex::kContextTag) !=
308
          Environment::kNodeContextTagPtr)) {
309
1
    return nullptr;
310
  }
311
312
  return static_cast<Environment*>(
313
      context->GetAlignedPointerFromEmbedderData(
314
2954416
          ContextEmbedderIndex::kEnvironment));
315
}
316
317
5432215
inline Environment* Environment::GetCurrent(
318
    const v8::FunctionCallbackInfo<v8::Value>& info) {
319
10864430
  CHECK(info.Data()->IsExternal());
320
16296651
  return static_cast<Environment*>(info.Data().As<v8::External>()->Value());
321
}
322
323
template <typename T>
324
12360
inline Environment* Environment::GetCurrent(
325
    const v8::PropertyCallbackInfo<T>& info) {
326

24720
  CHECK(info.Data()->IsExternal());
327
  return static_cast<Environment*>(
328
37080
      info.Data().template As<v8::External>()->Value());
329
}
330
331
7
inline Environment* Environment::GetThreadLocalEnv() {
332
7
  return static_cast<Environment*>(uv_key_get(&thread_local_env));
333
}
334
335
177
inline bool Environment::profiler_idle_notifier_started() const {
336
177
  return profiler_idle_notifier_started_;
337
}
338
339
65368114
inline v8::Isolate* Environment::isolate() const {
340
65368114
  return isolate_;
341
}
342
343
5837
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
344
5837
  return ContainerOf(&Environment::timer_handle_, handle);
345
}
346
347
21839
inline uv_timer_t* Environment::timer_handle() {
348
21839
  return &timer_handle_;
349
}
350
351
574732
inline Environment* Environment::from_immediate_check_handle(
352
    uv_check_t* handle) {
353
574732
  return ContainerOf(&Environment::immediate_check_handle_, handle);
354
}
355
356
17668
inline uv_check_t* Environment::immediate_check_handle() {
357
17668
  return &immediate_check_handle_;
358
}
359
360
83408
inline uv_idle_t* Environment::immediate_idle_handle() {
361
83408
  return &immediate_idle_handle_;
362
}
363
364
22085
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
365
                                               HandleCleanupCb cb,
366
                                               void* arg) {
367
22085
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
368
22085
}
369
370
template <typename T, typename OnCloseCallback>
371
20726
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
372
20726
  handle_cleanup_waiting_++;
373
  static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle");
374
  static_assert(offsetof(T, data) == offsetof(uv_handle_t, data),
375
                "T is a libuv handle");
376
  static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb),
377
                "T is a libuv handle");
378
  struct CloseData {
379
    Environment* env;
380
    OnCloseCallback callback;
381
    void* original_data;
382
  };
383
20726
  handle->data = new CloseData { this, callback, handle->data };
384
82864
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
385
20706
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
386
20706
    data->env->handle_cleanup_waiting_--;
387
20706
    handle->data = data->original_data;
388
20706
    data->callback(reinterpret_cast<T*>(handle));
389
62158
  });
390
20726
}
391
392
220472
void Environment::IncreaseWaitingRequestCounter() {
393
220472
  request_waiting_++;
394
220472
}
395
396
220453
void Environment::DecreaseWaitingRequestCounter() {
397
220453
  request_waiting_--;
398
220453
  CHECK_GE(request_waiting_, 0);
399
220453
}
400
401
1764266
inline uv_loop_t* Environment::event_loop() const {
402
1764266
  return isolate_data()->event_loop();
403
}
404
405
136
inline void Environment::TryLoadAddon(
406
    const char* filename,
407
    int flags,
408
    const std::function<bool(binding::DLib*)>& was_loaded) {
409
136
  loaded_addons_.emplace_back(filename, flags);
410
136
  if (!was_loaded(&loaded_addons_.back())) {
411
7
    loaded_addons_.pop_back();
412
  }
413
136
}
414
415
#if HAVE_INSPECTOR
416
128220
inline bool Environment::is_in_inspector_console_call() const {
417
128220
  return is_in_inspector_console_call_;
418
}
419
420
256438
inline void Environment::set_is_in_inspector_console_call(bool value) {
421
256438
  is_in_inspector_console_call_ = value;
422
256438
}
423
#endif
424
425
10858358
inline Environment::AsyncHooks* Environment::async_hooks() {
426
10858358
  return &async_hooks_;
427
}
428
429
882432
inline Environment::ImmediateInfo* Environment::immediate_info() {
430
882432
  return &immediate_info_;
431
}
432
433
1004150
inline Environment::TickInfo* Environment::tick_info() {
434
1004150
  return &tick_info_;
435
}
436
437
684563
inline uint64_t Environment::timer_base() const {
438
684563
  return timer_base_;
439
}
440
441
12
inline bool Environment::printed_error() const {
442
12
  return printed_error_;
443
}
444
445
12
inline void Environment::set_printed_error(bool value) {
446
12
  printed_error_ = value;
447
12
}
448
449
3880
inline void Environment::set_trace_sync_io(bool value) {
450
3880
  options_->trace_sync_io = value;
451
3880
}
452
453
19
inline bool Environment::abort_on_uncaught_exception() const {
454
19
  return options_->abort_on_uncaught_exception;
455
}
456
457
173
inline void Environment::set_abort_on_uncaught_exception(bool value) {
458
173
  options_->abort_on_uncaught_exception = value;
459
173
}
460
461
inline AliasedBuffer<uint32_t, v8::Uint32Array>&
462
4442
Environment::should_abort_on_uncaught_toggle() {
463
4442
  return should_abort_on_uncaught_toggle_;
464
}
465
466
inline AliasedBuffer<int32_t, v8::Int32Array>&
467
2315020
Environment::stream_base_state() {
468
2315020
  return stream_base_state_;
469
}
470
471
260
inline uint32_t Environment::get_next_module_id() {
472
260
  return module_id_counter_++;
473
}
474
4552
inline uint32_t Environment::get_next_script_id() {
475
4552
  return script_id_counter_++;
476
}
477
41632
inline uint32_t Environment::get_next_function_id() {
478
41632
  return function_id_counter_++;
479
}
480
481
4899
Environment::ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
482
    Environment* env)
483
4899
    : env_(env) {
484
4899
  env_->should_not_abort_scope_counter_++;
485
4899
}
486
487
4898
Environment::ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
488
4898
  Close();
489
4898
}
490
491
5098
void Environment::ShouldNotAbortOnUncaughtScope::Close() {
492
5098
  if (env_ != nullptr) {
493
4898
    env_->should_not_abort_scope_counter_--;
494
4898
    env_ = nullptr;
495
  }
496
5098
}
497
498
1
bool Environment::inside_should_not_abort_on_uncaught_scope() const {
499
1
  return should_not_abort_scope_counter_ > 0;
500
}
501
502
202815
inline std::vector<double>* Environment::destroy_async_id_list() {
503
202815
  return &destroy_async_id_list_;
504
}
505
506
453998
inline double Environment::new_async_id() {
507
453998
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
508
453998
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
509
}
510
511
384663
inline double Environment::execution_async_id() {
512
384663
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
513
}
514
515
37217
inline double Environment::trigger_async_id() {
516
37217
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
517
}
518
519
453995
inline double Environment::get_default_trigger_async_id() {
520
  double default_trigger_async_id =
521
453995
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
522
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
523
453995
  if (default_trigger_async_id < 0)
524
346798
    default_trigger_async_id = execution_async_id();
525
453995
  return default_trigger_async_id;
526
}
527
528
4406
inline double* Environment::heap_statistics_buffer() const {
529
4406
  CHECK_NOT_NULL(heap_statistics_buffer_);
530
4406
  return heap_statistics_buffer_;
531
}
532
533
4404
inline void Environment::set_heap_statistics_buffer(double* pointer) {
534
4404
  CHECK_NULL(heap_statistics_buffer_);  // Should be set only once.
535
4404
  heap_statistics_buffer_ = pointer;
536
4404
}
537
538
4405
inline double* Environment::heap_space_statistics_buffer() const {
539
4405
  CHECK_NOT_NULL(heap_space_statistics_buffer_);
540
4405
  return heap_space_statistics_buffer_;
541
}
542
543
4404
inline void Environment::set_heap_space_statistics_buffer(double* pointer) {
544
4404
  CHECK_NULL(heap_space_statistics_buffer_);  // Should be set only once.
545
4404
  heap_space_statistics_buffer_ = pointer;
546
4404
}
547
548
191515
inline char* Environment::http_parser_buffer() const {
549
191515
  return http_parser_buffer_;
550
}
551
552
282
inline void Environment::set_http_parser_buffer(char* buffer) {
553
282
  CHECK_NULL(http_parser_buffer_);  // Should be set only once.
554
282
  http_parser_buffer_ = buffer;
555
282
}
556
557
63832
inline bool Environment::http_parser_buffer_in_use() const {
558
63832
  return http_parser_buffer_in_use_;
559
}
560
561
127661
inline void Environment::set_http_parser_buffer_in_use(bool in_use) {
562
127661
  http_parser_buffer_in_use_ = in_use;
563
127661
}
564
565
19420
inline http2::Http2State* Environment::http2_state() const {
566
19420
  return http2_state_.get();
567
}
568
569
222
inline void Environment::set_http2_state(
570
    std::unique_ptr<http2::Http2State> buffer) {
571
222
  CHECK(!http2_state_);  // Should be set only once.
572
222
  http2_state_ = std::move(buffer);
573
222
}
574
575
718703
bool Environment::debug_enabled(DebugCategory category) const {
576
  DCHECK_GE(static_cast<int>(category), 0);
577
  DCHECK_LT(static_cast<int>(category),
578
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
579
718703
  return debug_enabled_[static_cast<int>(category)];
580
}
581
582
4
void Environment::set_debug_enabled(DebugCategory category, bool enabled) {
583
  DCHECK_GE(static_cast<int>(category), 0);
584
  DCHECK_LT(static_cast<int>(category),
585
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
586
4
  debug_enabled_[static_cast<int>(category)] = enabled;
587
4
}
588
589
inline AliasedBuffer<double, v8::Float64Array>*
590
194580
Environment::fs_stats_field_array() {
591
194580
  return &fs_stats_field_array_;
592
}
593
594
inline AliasedBuffer<uint64_t, v8::BigUint64Array>*
595
4417
Environment::fs_stats_field_bigint_array() {
596
4417
  return &fs_stats_field_bigint_array_;
597
}
598
599
inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>&
600
440
Environment::file_handle_read_wrap_freelist() {
601
440
  return file_handle_read_wrap_freelist_;
602
}
603
604
109206
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
605
109206
  return options_;
606
}
607
608
171
inline const std::vector<std::string>& Environment::exec_argv() {
609
171
  return exec_argv_;
610
}
611
612
8916
inline std::shared_ptr<HostPort> Environment::inspector_host_port() {
613
8916
  return inspector_host_port_;
614
}
615
616
13348
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
617
13348
  return options_;
618
}
619
620
6
inline void IsolateData::set_options(
621
    std::shared_ptr<PerIsolateOptions> options) {
622
6
  options_ = std::move(options);
623
6
}
624
625
49781
void Environment::CreateImmediate(native_immediate_callback cb,
626
                                  void* data,
627
                                  v8::Local<v8::Object> obj,
628
                                  bool ref) {
629
  native_immediate_callbacks_.push_back({
630
    cb,
631
    data,
632
    v8::Global<v8::Object>(isolate_, obj),
633
    ref
634
99562
  });
635
49781
  immediate_info()->count_inc(1);
636
49781
}
637
638
27570
void Environment::SetImmediate(native_immediate_callback cb,
639
                               void* data,
640
                               v8::Local<v8::Object> obj) {
641
27570
  CreateImmediate(cb, data, obj, true);
642
643
27570
  if (immediate_info()->ref_count() == 0)
644
22799
    ToggleImmediateRef(true);
645
27570
  immediate_info()->ref_count_inc(1);
646
27570
}
647
648
22211
void Environment::SetUnrefImmediate(native_immediate_callback cb,
649
                                    void* data,
650
                                    v8::Local<v8::Object> obj) {
651
22211
  CreateImmediate(cb, data, obj, false);
652
22211
}
653
654
4205556
inline bool Environment::can_call_into_js() const {
655

4205556
  return can_call_into_js_ && (is_main_thread() || !is_stopping_worker());
656
}
657
658
4048
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
659
4048
  can_call_into_js_ = can_call_into_js;
660
4048
}
661
662
4415
inline bool Environment::has_run_bootstrapping_code() const {
663
4415
  return has_run_bootstrapping_code_;
664
}
665
666
4413
inline void Environment::set_has_run_bootstrapping_code(bool value) {
667
4413
  has_run_bootstrapping_code_ = value;
668
4413
}
669
670
4236076
inline bool Environment::is_main_thread() const {
671
4236076
  return flags_ & kIsMainThread;
672
}
673
674
26744
inline bool Environment::owns_process_state() const {
675
26744
  return flags_ & kOwnsProcessState;
676
}
677
678
4416
inline bool Environment::owns_inspector() const {
679
4416
  return flags_ & kOwnsInspector;
680
}
681
682
4576
inline uint64_t Environment::thread_id() const {
683
4576
  return thread_id_;
684
}
685
686
inline worker::Worker* Environment::worker_context() const {
687
  return worker_context_;
688
}
689
690
173
inline void Environment::set_worker_context(worker::Worker* context) {
691
173
  CHECK_NULL(worker_context_);  // Should be set only once.
692
173
  worker_context_ = context;
693
173
}
694
695
176
inline void Environment::add_sub_worker_context(worker::Worker* context) {
696
176
  sub_worker_contexts_.insert(context);
697
176
}
698
699
199
inline void Environment::remove_sub_worker_context(worker::Worker* context) {
700
199
  sub_worker_contexts_.erase(context);
701
199
}
702
703
20685
inline bool Environment::is_stopping_worker() const {
704
20685
  CHECK(!is_main_thread());
705
20685
  return worker_context_->is_stopped();
706
}
707
708
34471
inline performance::performance_state* Environment::performance_state() {
709
34471
  return performance_state_.get();
710
}
711
712
inline std::unordered_map<std::string, uint64_t>*
713
42
    Environment::performance_marks() {
714
42
  return &performance_marks_;
715
}
716
717
8027389
inline IsolateData* Environment::isolate_data() const {
718
8027389
  return isolate_data_;
719
}
720
721
477187
inline char* Environment::AllocateUnchecked(size_t size) {
722
  return static_cast<char*>(
723
477187
      isolate_data()->allocator()->AllocateUninitialized(size));
724
}
725
726
455638
inline char* Environment::Allocate(size_t size) {
727
455638
  char* ret = AllocateUnchecked(size);
728
455638
  CHECK_NE(ret, nullptr);
729
455638
  return ret;
730
}
731
732
1008893
inline void Environment::Free(char* data, size_t size) {
733
1008893
  if (data != nullptr)
734
34052
    isolate_data()->allocator()->Free(data, size);
735
1008893
}
736
737
477187
inline AllocatedBuffer Environment::AllocateManaged(size_t size, bool checked) {
738
477187
  char* data = checked ? Allocate(size) : AllocateUnchecked(size);
739
477187
  if (data == nullptr) size = 0;
740
477187
  return AllocatedBuffer(this, uv_buf_init(data, size));
741
}
742
743
907547
inline AllocatedBuffer::AllocatedBuffer(Environment* env, uv_buf_t buf)
744
907547
    : env_(env), buffer_(buf) {}
745
746
409268
inline void AllocatedBuffer::Resize(size_t len) {
747
409268
  char* new_data = env_->Reallocate(buffer_.base, buffer_.len, len);
748

409268
  CHECK_IMPLIES(len > 0, new_data != nullptr);
749
409268
  buffer_ = uv_buf_init(new_data, len);
750
409268
}
751
752
1920402
inline uv_buf_t AllocatedBuffer::release() {
753
1920402
  uv_buf_t ret = buffer_;
754
1920402
  buffer_ = uv_buf_init(nullptr, 0);
755
1920402
  return ret;
756
}
757
758
376990
inline char* AllocatedBuffer::data() {
759
376990
  return buffer_.base;
760
}
761
762
inline const char* AllocatedBuffer::data() const {
763
  return buffer_.base;
764
}
765
766
722429
inline size_t AllocatedBuffer::size() const {
767
722429
  return buffer_.len;
768
}
769
770
52760
inline AllocatedBuffer::AllocatedBuffer(Environment* env)
771
52760
    : env_(env), buffer_(uv_buf_init(nullptr, 0)) {}
772
773
106
inline AllocatedBuffer::AllocatedBuffer(AllocatedBuffer&& other)
774
106
    : AllocatedBuffer() {
775
106
  *this = std::move(other);
776
106
}
777
778
48668
inline AllocatedBuffer& AllocatedBuffer::operator=(AllocatedBuffer&& other) {
779
48668
  clear();
780
48668
  env_ = other.env_;
781
48668
  buffer_ = other.release();
782
48668
  return *this;
783
}
784
785
960225
inline AllocatedBuffer::~AllocatedBuffer() {
786
960225
  clear();
787
960225
}
788
789
1008893
inline void AllocatedBuffer::clear() {
790
1008893
  uv_buf_t buf = release();
791
1008893
  env_->Free(buf.base, buf.len);
792
1008893
}
793
794
// It's a bit awkward to define this Buffer::New() overload here, but it
795
// avoids a circular dependency with node_internals.h.
796
namespace Buffer {
797
v8::MaybeLocal<v8::Object> New(Environment* env,
798
                               char* data,
799
                               size_t length,
800
                               bool uses_malloc);
801
}
802
803
43671
inline v8::MaybeLocal<v8::Object> AllocatedBuffer::ToBuffer() {
804
43671
  CHECK_NOT_NULL(env_);
805
43671
  v8::MaybeLocal<v8::Object> obj = Buffer::New(env_, data(), size(), false);
806
43671
  if (!obj.IsEmpty()) release();
807
43671
  return obj;
808
}
809
810
400621
inline v8::Local<v8::ArrayBuffer> AllocatedBuffer::ToArrayBuffer() {
811
400621
  CHECK_NOT_NULL(env_);
812
400621
  uv_buf_t buf = release();
813
  return v8::ArrayBuffer::New(env_->isolate(),
814
                              buf.base,
815
                              buf.len,
816
400621
                              v8::ArrayBufferCreationMode::kInternalized);
817
}
818
819
700
inline void Environment::ThrowError(const char* errmsg) {
820
700
  ThrowError(v8::Exception::Error, errmsg);
821
700
}
822
823
5
inline void Environment::ThrowTypeError(const char* errmsg) {
824
5
  ThrowError(v8::Exception::TypeError, errmsg);
825
5
}
826
827
inline void Environment::ThrowRangeError(const char* errmsg) {
828
  ThrowError(v8::Exception::RangeError, errmsg);
829
}
830
831
705
inline void Environment::ThrowError(
832
    v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
833
    const char* errmsg) {
834
705
  v8::HandleScope handle_scope(isolate());
835
705
  isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
836
705
}
837
838
3
inline void Environment::ThrowErrnoException(int errorno,
839
                                             const char* syscall,
840
                                             const char* message,
841
                                             const char* path) {
842
  isolate()->ThrowException(
843
3
      ErrnoException(isolate(), errorno, syscall, message, path));
844
3
}
845
846
14
inline void Environment::ThrowUVException(int errorno,
847
                                          const char* syscall,
848
                                          const char* message,
849
                                          const char* path,
850
                                          const char* dest) {
851
  isolate()->ThrowException(
852
14
      UVException(isolate(), errorno, syscall, message, path, dest));
853
14
}
854
855
inline v8::Local<v8::FunctionTemplate>
856
1622693
    Environment::NewFunctionTemplate(v8::FunctionCallback callback,
857
                                     v8::Local<v8::Signature> signature,
858
                                     v8::ConstructorBehavior behavior,
859
                                     v8::SideEffectType side_effect_type) {
860
1622693
  v8::Local<v8::External> external = as_external();
861
  return v8::FunctionTemplate::New(isolate(), callback, external,
862
1622695
                                   signature, 0, behavior, side_effect_type);
863
}
864
865
628083
inline void Environment::SetMethod(v8::Local<v8::Object> that,
866
                                   const char* name,
867
                                   v8::FunctionCallback callback) {
868
628083
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
869
  v8::Local<v8::Function> function =
870
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
871
                          // TODO(TimothyGu): Investigate if SetMethod is ever
872
                          // used for constructors.
873
                          v8::ConstructorBehavior::kAllow,
874
628084
                          v8::SideEffectType::kHasSideEffect)
875
1884250
          ->GetFunction(context)
876
1256168
          .ToLocalChecked();
877
  // kInternalized strings are created in the old space.
878
628084
  const v8::NewStringType type = v8::NewStringType::kInternalized;
879
  v8::Local<v8::String> name_string =
880
1256167
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
881
1256165
  that->Set(context, name_string, function).FromJust();
882
628082
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
883
628084
}
884
885
297285
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
886
                                               const char* name,
887
                                               v8::FunctionCallback callback) {
888
297285
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
889
  v8::Local<v8::Function> function =
890
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
891
                          // TODO(TimothyGu): Investigate if SetMethod is ever
892
                          // used for constructors.
893
                          v8::ConstructorBehavior::kAllow,
894
297287
                          v8::SideEffectType::kHasNoSideEffect)
895
891861
          ->GetFunction(context)
896
594574
          .ToLocalChecked();
897
  // kInternalized strings are created in the old space.
898
297287
  const v8::NewStringType type = v8::NewStringType::kInternalized;
899
  v8::Local<v8::String> name_string =
900
594574
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
901
594574
  that->Set(context, name_string, function).FromJust();
902
297287
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
903
297287
}
904
905
476398
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
906
                                        const char* name,
907
                                        v8::FunctionCallback callback) {
908
476398
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
909
  v8::Local<v8::FunctionTemplate> t =
910
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
911
476398
                          v8::SideEffectType::kHasSideEffect);
912
  // kInternalized strings are created in the old space.
913
476398
  const v8::NewStringType type = v8::NewStringType::kInternalized;
914
  v8::Local<v8::String> name_string =
915
952796
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
916
952796
  that->PrototypeTemplate()->Set(name_string, t);
917
476398
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
918
476398
}
919
920
41942
inline void Environment::SetProtoMethodNoSideEffect(
921
    v8::Local<v8::FunctionTemplate> that,
922
    const char* name,
923
    v8::FunctionCallback callback) {
924
41942
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
925
  v8::Local<v8::FunctionTemplate> t =
926
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
927
41942
                          v8::SideEffectType::kHasNoSideEffect);
928
  // kInternalized strings are created in the old space.
929
41942
  const v8::NewStringType type = v8::NewStringType::kInternalized;
930
  v8::Local<v8::String> name_string =
931
83884
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
932
83884
  that->PrototypeTemplate()->Set(name_string, t);
933
41942
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
934
41942
}
935
936
inline void Environment::SetTemplateMethod(v8::Local<v8::FunctionTemplate> that,
937
                                           const char* name,
938
                                           v8::FunctionCallback callback) {
939
  v8::Local<v8::FunctionTemplate> t =
940
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
941
                          v8::ConstructorBehavior::kAllow,
942
                          v8::SideEffectType::kHasSideEffect);
943
  // kInternalized strings are created in the old space.
944
  const v8::NewStringType type = v8::NewStringType::kInternalized;
945
  v8::Local<v8::String> name_string =
946
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
947
  that->Set(name_string, t);
948
  t->SetClassName(name_string);  // NODE_SET_METHOD() compatibility.
949
}
950
951
inline void Environment::SetTemplateMethodNoSideEffect(
952
    v8::Local<v8::FunctionTemplate> that,
953
    const char* name,
954
    v8::FunctionCallback callback) {
955
  v8::Local<v8::FunctionTemplate> t =
956
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
957
                          v8::ConstructorBehavior::kAllow,
958
                          v8::SideEffectType::kHasNoSideEffect);
959
  // kInternalized strings are created in the old space.
960
  const v8::NewStringType type = v8::NewStringType::kInternalized;
961
  v8::Local<v8::String> name_string =
962
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
963
  that->Set(name_string, t);
964
  t->SetClassName(name_string);  // NODE_SET_METHOD() compatibility.
965
}
966
967
856763
void Environment::AddCleanupHook(void (*fn)(void*), void* arg) {
968
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
969
    fn, arg, cleanup_hook_counter_++
970
856763
  });
971
  // Make sure there was no existing element with these values.
972
856763
  CHECK_EQ(insertion_info.second, true);
973
856763
}
974
975
854923
void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
976
854923
  CleanupHookCallback search { fn, arg, 0 };
977
854923
  cleanup_hooks_.erase(search);
978
854923
}
979
980
1792947
size_t Environment::CleanupHookCallback::Hash::operator()(
981
    const CleanupHookCallback& cb) const {
982
1792947
  return std::hash<void*>()(cb.arg_);
983
}
984
985
895626
bool Environment::CleanupHookCallback::Equal::operator()(
986
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
987

895626
  return a.fn_ == b.fn_ && a.arg_ == b.arg_;
988
}
989
990
94
BaseObject* Environment::CleanupHookCallback::GetBaseObject() const {
991
94
  if (fn_ == BaseObject::DeleteMe)
992
93
    return static_cast<BaseObject*>(arg_);
993
  else
994
1
    return nullptr;
995
}
996
997
template <typename T>
998
32
void Environment::ForEachBaseObject(T&& iterator) {
999
126
  for (const auto& hook : cleanup_hooks_) {
1000
94
    BaseObject* obj = hook.GetBaseObject();
1001
94
    if (obj != nullptr)
1002
93
      iterator(obj);
1003
  }
1004
32
}
1005
1006
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1007
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1008
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1009
#define V(TypeName, PropertyName)                                             \
1010
  inline                                                                      \
1011
  v8::Local<TypeName> IsolateData::PropertyName(v8::Isolate* isolate) const { \
1012
    /* Strings are immutable so casting away const-ness here is okay. */      \
1013
    return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate);    \
1014
  }
1015
77240
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1016
262246
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1017
8823418
  PER_ISOLATE_STRING_PROPERTIES(VS)
1018
#undef V
1019
#undef VS
1020
#undef VY
1021
#undef VP
1022
1023
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1024
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1025
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1026
#define V(TypeName, PropertyName)                                             \
1027
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1028
    return isolate_data()->PropertyName(isolate());                           \
1029
  }
1030
38620
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1031
131123
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1032
4411702
  PER_ISOLATE_STRING_PROPERTIES(VS)
1033
#undef V
1034
#undef VS
1035
#undef VY
1036
#undef VP
1037
1038
#define V(PropertyName, TypeName)                                             \
1039
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1040
    return PersistentToLocal::Strong(PropertyName ## _);                      \
1041
  }                                                                           \
1042
  inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) {  \
1043
    PropertyName ## _.Reset(isolate(), value);                                \
1044
  }
1045
23149886
  ENVIRONMENT_STRONG_PERSISTENT_PROPERTIES(V)
1046
#undef V
1047
1048
}  // namespace node
1049
1050
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1051
1052
#endif  // SRC_ENV_INL_H_