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: 547 552 99.1 %
Date: 2019-05-05 22:32:45 Branches: 63 92 68.5 %

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


948309
  if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) {
167
    fprintf(stderr,
168
            "Error: async hook stack has become corrupted ("
169
            "actual: %.f, expected: %.f)\n",
170
            async_id_fields_.GetValue(kExecutionAsyncId),
171
4
            async_id);
172
4
    DumpBacktrace(stderr);
173
4
    fflush(stderr);
174
4
    if (!env()->abort_on_uncaught_exception())
175
4
      exit(1);
176
    fprintf(stderr, "\n");
177
    fflush(stderr);
178
    ABORT_NO_BACKTRACE();
179
  }
180
181
948305
  uint32_t offset = fields_[kStackLength] - 1;
182
948305
  async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset];
183
948304
  async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1];
184
948304
  fields_[kStackLength] = offset;
185
186
948304
  return fields_[kStackLength] > 0;
187
}
188
189
// Keep in sync with clearAsyncIdStack in lib/internal/async_hooks.js.
190
37
inline void AsyncHooks::clear_async_id_stack() {
191
37
  async_id_fields_[kExecutionAsyncId] = 0;
192
37
  async_id_fields_[kTriggerAsyncId] = 0;
193
37
  fields_[kStackLength] = 0;
194
37
}
195
196
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in
197
// async_wrap-inl.h to avoid a circular dependency.
198
199
956818
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope(
200
    Environment* env, double default_trigger_async_id)
201
956818
    : async_hooks_(env->async_hooks()) {
202
956818
  if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) {
203
956818
    CHECK_GE(default_trigger_async_id, 0);
204
  }
205
206
1913636
  old_default_trigger_async_id_ =
207
1913636
    async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
208
1913636
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
209
956818
    default_trigger_async_id;
210
956818
}
211
212
956817
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() {
213
1913634
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
214
956817
    old_default_trigger_async_id_;
215
956817
}
216
217
218
660953
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
219
660953
  return ContainerOf(&Environment::async_hooks_, hooks);
220
}
221
222
1111369
inline AsyncCallbackScope::AsyncCallbackScope(Environment* env) : env_(env) {
223
1111369
  env_->PushAsyncCallbackScope();
224
1111371
}
225
226
1110985
inline AsyncCallbackScope::~AsyncCallbackScope() {
227
1110985
  env_->PopAsyncCallbackScope();
228
1110987
}
229
230
944549
inline size_t Environment::async_callback_scope_depth() const {
231
944549
  return async_callback_scope_depth_;
232
}
233
234
1111369
inline void Environment::PushAsyncCallbackScope() {
235
1111369
  async_callback_scope_depth_++;
236
1111369
}
237
238
1110986
inline void Environment::PopAsyncCallbackScope() {
239
1110986
  async_callback_scope_depth_--;
240
1110986
}
241
242
4651
inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
243
4651
    : fields_(isolate, kFieldsCount) {}
244
245
4644
inline AliasedUint32Array& ImmediateInfo::fields() {
246
4644
  return fields_;
247
}
248
249
399723
inline uint32_t ImmediateInfo::count() const {
250
399723
  return fields_[kCount];
251
}
252
253
82513
inline uint32_t ImmediateInfo::ref_count() const {
254
82513
  return fields_[kRefCount];
255
}
256
257
54416
inline bool ImmediateInfo::has_outstanding() const {
258
54416
  return fields_[kHasOutstanding] == 1;
259
}
260
261
50847
inline void ImmediateInfo::count_inc(uint32_t increment) {
262
50847
  fields_[kCount] += increment;
263
50847
}
264
265
46317
inline void ImmediateInfo::count_dec(uint32_t decrement) {
266
46317
  fields_[kCount] -= decrement;
267
46317
}
268
269
28618
inline void ImmediateInfo::ref_count_inc(uint32_t increment) {
270
28618
  fields_[kRefCount] += increment;
271
28618
}
272
273
46317
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
274
46317
  fields_[kRefCount] -= decrement;
275
46317
}
276
277
4651
inline TickInfo::TickInfo(v8::Isolate* isolate)
278
4651
    : fields_(isolate, kFieldsCount) {}
279
280
4646
inline AliasedUint8Array& TickInfo::fields() {
281
4646
  return fields_;
282
}
283
284
1479379
inline bool TickInfo::has_tick_scheduled() const {
285
1479379
  return fields_[kHasTickScheduled] == 1;
286
}
287
288
213991
inline bool TickInfo::has_rejection_to_warn() const {
289
213991
  return fields_[kHasRejectionToWarn] == 1;
290
}
291
292
5080
inline void Environment::AssignToContext(v8::Local<v8::Context> context,
293
                                         const ContextInfo& info) {
294
  context->SetAlignedPointerInEmbedderData(
295
5080
      ContextEmbedderIndex::kEnvironment, this);
296
  // Used by Environment::GetCurrent to know that we are on a node context.
297
  context->SetAlignedPointerInEmbedderData(
298
10160
    ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
299
#if HAVE_INSPECTOR
300
5080
  inspector_agent()->ContextCreated(context, info);
301
#endif  // HAVE_INSPECTOR
302
5080
}
303
304
972660
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
305
972660
  if (UNLIKELY(!isolate->InContext())) return nullptr;
306
972664
  v8::HandleScope handle_scope(isolate);
307
972663
  return GetCurrent(isolate->GetCurrentContext());
308
}
309
310
1193474
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
311
1193474
  if (UNLIKELY(context.IsEmpty())) {
312
    return nullptr;
313
  }
314
1193474
  if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
315
               ContextEmbedderIndex::kContextTag)) {
316
1
    return nullptr;
317
  }
318
2386950
  if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
319
                   ContextEmbedderIndex::kContextTag) !=
320
               Environment::kNodeContextTagPtr)) {
321
    return nullptr;
322
  }
323
  return static_cast<Environment*>(
324
      context->GetAlignedPointerFromEmbedderData(
325
2386950
          ContextEmbedderIndex::kEnvironment));
326
}
327
328
9469609
inline Environment* Environment::GetCurrent(
329
    const v8::FunctionCallbackInfo<v8::Value>& info) {
330
9469609
  return GetFromCallbackData(info.Data());
331
}
332
333
template <typename T>
334
1204996
inline Environment* Environment::GetCurrent(
335
    const v8::PropertyCallbackInfo<T>& info) {
336
1204996
  return GetFromCallbackData(info.Data());
337
}
338
339
10674603
inline Environment* Environment::GetFromCallbackData(v8::Local<v8::Value> val) {
340
  DCHECK(val->IsObject());
341
10674603
  v8::Local<v8::Object> obj = val.As<v8::Object>();
342
  DCHECK_GE(obj->InternalFieldCount(), 1);
343
  Environment* env =
344
21349207
      static_cast<Environment*>(obj->GetAlignedPointerFromInternalField(0));
345
  DCHECK(env->as_callback_data_template()->HasInstance(obj));
346
10674604
  return env;
347
}
348
349
7
inline Environment* Environment::GetThreadLocalEnv() {
350
7
  return static_cast<Environment*>(uv_key_get(&thread_local_env));
351
}
352
353
186
inline bool Environment::profiler_idle_notifier_started() const {
354
186
  return profiler_idle_notifier_started_;
355
}
356
357
64729185
inline v8::Isolate* Environment::isolate() const {
358
64729185
  return isolate_;
359
}
360
361
2851
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
362
2851
  return ContainerOf(&Environment::timer_handle_, handle);
363
}
364
365
19655
inline uv_timer_t* Environment::timer_handle() {
366
19655
  return &timer_handle_;
367
}
368
369
399724
inline Environment* Environment::from_immediate_check_handle(
370
    uv_check_t* handle) {
371
399724
  return ContainerOf(&Environment::immediate_check_handle_, handle);
372
}
373
374
18604
inline uv_check_t* Environment::immediate_check_handle() {
375
18604
  return &immediate_check_handle_;
376
}
377
378
86009
inline uv_idle_t* Environment::immediate_idle_handle() {
379
86009
  return &immediate_idle_handle_;
380
}
381
382
23255
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
383
                                               HandleCleanupCb cb,
384
                                               void* arg) {
385
23255
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
386
23255
}
387
388
template <typename T, typename OnCloseCallback>
389
25944
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
390
25944
  handle_cleanup_waiting_++;
391
  static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle");
392
  static_assert(offsetof(T, data) == offsetof(uv_handle_t, data),
393
                "T is a libuv handle");
394
  static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb),
395
                "T is a libuv handle");
396
  struct CloseData {
397
    Environment* env;
398
    OnCloseCallback callback;
399
    void* original_data;
400
  };
401
25944
  handle->data = new CloseData { this, callback, handle->data };
402
103736
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
403
25924
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
404
25924
    data->env->handle_cleanup_waiting_--;
405
25924
    handle->data = data->original_data;
406
25924
    data->callback(reinterpret_cast<T*>(handle));
407
77812
  });
408
25944
}
409
410
107256
void Environment::IncreaseWaitingRequestCounter() {
411
107256
  request_waiting_++;
412
107256
}
413
414
107238
void Environment::DecreaseWaitingRequestCounter() {
415
107238
  request_waiting_--;
416
107238
  CHECK_GE(request_waiting_, 0);
417
107238
}
418
419
1648515
inline uv_loop_t* Environment::event_loop() const {
420
1648515
  return isolate_data()->event_loop();
421
}
422
423
136
inline void Environment::TryLoadAddon(
424
    const char* filename,
425
    int flags,
426
    const std::function<bool(binding::DLib*)>& was_loaded) {
427
136
  loaded_addons_.emplace_back(filename, flags);
428
136
  if (!was_loaded(&loaded_addons_.back())) {
429
7
    loaded_addons_.pop_back();
430
  }
431
136
}
432
433
#if HAVE_INSPECTOR
434
146501
inline bool Environment::is_in_inspector_console_call() const {
435
146501
  return is_in_inspector_console_call_;
436
}
437
438
293000
inline void Environment::set_is_in_inspector_console_call(bool value) {
439
293000
  is_in_inspector_console_call_ = value;
440
293000
}
441
#endif
442
443
8043032
inline AsyncHooks* Environment::async_hooks() {
444
8043032
  return &async_hooks_;
445
}
446
447
713396
inline ImmediateInfo* Environment::immediate_info() {
448
713396
  return &immediate_info_;
449
}
450
451
744338
inline TickInfo* Environment::tick_info() {
452
744338
  return &tick_info_;
453
}
454
455
652870
inline uint64_t Environment::timer_base() const {
456
652870
  return timer_base_;
457
}
458
459
1223926
inline std::shared_ptr<KVStore> Environment::env_vars() {
460
1223926
  return env_vars_;
461
}
462
463
4833
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) {
464
4833
  env_vars_ = env_vars;
465
4833
}
466
467
12
inline bool Environment::printed_error() const {
468
12
  return printed_error_;
469
}
470
471
12
inline void Environment::set_printed_error(bool value) {
472
12
  printed_error_ = value;
473
12
}
474
475
4093
inline void Environment::set_trace_sync_io(bool value) {
476
4093
  options_->trace_sync_io = value;
477
4093
}
478
479
24
inline bool Environment::abort_on_uncaught_exception() const {
480
24
  return options_->abort_on_uncaught_exception;
481
}
482
483
182
inline void Environment::set_abort_on_uncaught_exception(bool value) {
484
182
  options_->abort_on_uncaught_exception = value;
485
182
}
486
487
4680
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
488
4680
  return should_abort_on_uncaught_toggle_;
489
}
490
491
2251760
inline AliasedInt32Array& Environment::stream_base_state() {
492
2251760
  return stream_base_state_;
493
}
494
495
379
inline uint32_t Environment::get_next_module_id() {
496
379
  return module_id_counter_++;
497
}
498
1547
inline uint32_t Environment::get_next_script_id() {
499
1547
  return script_id_counter_++;
500
}
501
43201
inline uint32_t Environment::get_next_function_id() {
502
43201
  return function_id_counter_++;
503
}
504
505
2036
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
506
    Environment* env)
507
2036
    : env_(env) {
508
2036
  env_->PushShouldNotAbortOnUncaughtScope();
509
2037
}
510
511
2035
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
512
2035
  Close();
513
2035
}
514
515
2237
void ShouldNotAbortOnUncaughtScope::Close() {
516
2237
  if (env_ != nullptr) {
517
2035
    env_->PopShouldNotAbortOnUncaughtScope();
518
2035
    env_ = nullptr;
519
  }
520
2237
}
521
522
2036
inline void Environment::PushShouldNotAbortOnUncaughtScope() {
523
2036
  should_not_abort_scope_counter_++;
524
2036
}
525
526
2035
inline void Environment::PopShouldNotAbortOnUncaughtScope() {
527
2035
  should_not_abort_scope_counter_--;
528
2035
}
529
530
1
inline bool Environment::inside_should_not_abort_on_uncaught_scope() const {
531
1
  return should_not_abort_scope_counter_ > 0;
532
}
533
534
200156
inline std::vector<double>* Environment::destroy_async_id_list() {
535
200156
  return &destroy_async_id_list_;
536
}
537
538
242898
inline double Environment::new_async_id() {
539
242898
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
540
242898
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
541
}
542
543
176226
inline double Environment::execution_async_id() {
544
176226
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
545
}
546
547
37496
inline double Environment::trigger_async_id() {
548
37496
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
549
}
550
551
242895
inline double Environment::get_default_trigger_async_id() {
552
  double default_trigger_async_id =
553
242895
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
554
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
555
242895
  if (default_trigger_async_id < 0)
556
138251
    default_trigger_async_id = execution_async_id();
557
242895
  return default_trigger_async_id;
558
}
559
560
66
inline double* Environment::heap_statistics_buffer() const {
561
66
  CHECK_NOT_NULL(heap_statistics_buffer_);
562
66
  return heap_statistics_buffer_;
563
}
564
565
64
inline void Environment::set_heap_statistics_buffer(double* pointer) {
566
64
  CHECK_NULL(heap_statistics_buffer_);  // Should be set only once.
567
64
  heap_statistics_buffer_ = pointer;
568
64
}
569
570
65
inline double* Environment::heap_space_statistics_buffer() const {
571
65
  CHECK_NOT_NULL(heap_space_statistics_buffer_);
572
65
  return heap_space_statistics_buffer_;
573
}
574
575
64
inline void Environment::set_heap_space_statistics_buffer(double* pointer) {
576
64
  CHECK_NULL(heap_space_statistics_buffer_);  // Should be set only once.
577
64
  heap_space_statistics_buffer_ = pointer;
578
64
}
579
580
183547
inline char* Environment::http_parser_buffer() const {
581
183547
  return http_parser_buffer_;
582
}
583
584
285
inline void Environment::set_http_parser_buffer(char* buffer) {
585
285
  CHECK_NULL(http_parser_buffer_);  // Should be set only once.
586
285
  http_parser_buffer_ = buffer;
587
285
}
588
589
61178
inline bool Environment::http_parser_buffer_in_use() const {
590
61178
  return http_parser_buffer_in_use_;
591
}
592
593
122352
inline void Environment::set_http_parser_buffer_in_use(bool in_use) {
594
122352
  http_parser_buffer_in_use_ = in_use;
595
122352
}
596
597
19428
inline http2::Http2State* Environment::http2_state() const {
598
19428
  return http2_state_.get();
599
}
600
601
223
inline void Environment::set_http2_state(
602
    std::unique_ptr<http2::Http2State> buffer) {
603
223
  CHECK(!http2_state_);  // Should be set only once.
604
223
  http2_state_ = std::move(buffer);
605
223
}
606
607
978168
bool Environment::debug_enabled(DebugCategory category) const {
608
  DCHECK_GE(static_cast<int>(category), 0);
609
  DCHECK_LT(static_cast<int>(category),
610
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
611
978168
  return debug_enabled_[static_cast<int>(category)];
612
}
613
614
13
void Environment::set_debug_enabled(DebugCategory category, bool enabled) {
615
  DCHECK_GE(static_cast<int>(category), 0);
616
  DCHECK_LT(static_cast<int>(category),
617
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
618
13
  debug_enabled_[static_cast<int>(category)] = enabled;
619
13
}
620
621
209594
inline AliasedFloat64Array* Environment::fs_stats_field_array() {
622
209594
  return &fs_stats_field_array_;
623
}
624
625
4653
inline AliasedBigUint64Array* Environment::fs_stats_field_bigint_array() {
626
4653
  return &fs_stats_field_bigint_array_;
627
}
628
629
inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>&
630
442
Environment::file_handle_read_wrap_freelist() {
631
442
  return file_handle_read_wrap_freelist_;
632
}
633
634
50627
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
635
50627
  return options_;
636
}
637
638
13431
inline const std::vector<std::string>& Environment::argv() {
639
13431
  return argv_;
640
}
641
642
4821
inline const std::vector<std::string>& Environment::exec_argv() {
643
4821
  return exec_argv_;
644
}
645
646
#if HAVE_INSPECTOR
647
4638
inline void Environment::set_coverage_directory(const char* dir) {
648
4638
  coverage_directory_ = std::string(dir);
649
4638
}
650
651
4646
inline void Environment::set_coverage_connection(
652
    std::unique_ptr<profiler::V8CoverageConnection> connection) {
653
4646
  CHECK_NULL(coverage_connection_);
654
4646
  std::swap(coverage_connection_, connection);
655
4646
}
656
657
13841
inline profiler::V8CoverageConnection* Environment::coverage_connection() {
658
13841
  return coverage_connection_.get();
659
}
660
661
4457
inline const std::string& Environment::coverage_directory() const {
662
4457
  return coverage_directory_;
663
}
664
665
10
inline void Environment::set_cpu_profiler_connection(
666
    std::unique_ptr<profiler::V8CpuProfilerConnection> connection) {
667
10
  CHECK_NULL(cpu_profiler_connection_);
668
10
  std::swap(cpu_profiler_connection_, connection);
669
10
}
670
671
inline profiler::V8CpuProfilerConnection*
672
4569
Environment::cpu_profiler_connection() {
673
4569
  return cpu_profiler_connection_.get();
674
}
675
676
10
inline void Environment::set_cpu_prof_interval(uint64_t interval) {
677
10
  cpu_prof_interval_ = interval;
678
10
}
679
680
10
inline uint64_t Environment::cpu_prof_interval() const {
681
10
  return cpu_prof_interval_;
682
}
683
684
10
inline void Environment::set_cpu_prof_name(const std::string& name) {
685
10
  cpu_prof_name_ = name;
686
10
}
687
688
10
inline const std::string& Environment::cpu_prof_name() const {
689
10
  return cpu_prof_name_;
690
}
691
692
10
inline void Environment::set_cpu_prof_dir(const std::string& dir) {
693
10
  cpu_prof_dir_ = dir;
694
10
}
695
696
10
inline const std::string& Environment::cpu_prof_dir() const {
697
10
  return cpu_prof_dir_;
698
}
699
700
#endif  // HAVE_INSPECTOR
701
702
9388
inline std::shared_ptr<HostPort> Environment::inspector_host_port() {
703
9388
  return inspector_host_port_;
704
}
705
706
15189
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
707
15189
  return options_;
708
}
709
710
8
inline void IsolateData::set_options(
711
    std::shared_ptr<PerIsolateOptions> options) {
712
8
  options_ = std::move(options);
713
8
}
714
715
50847
void Environment::CreateImmediate(native_immediate_callback cb,
716
                                  void* data,
717
                                  v8::Local<v8::Object> obj,
718
                                  bool ref) {
719
  native_immediate_callbacks_.push_back({
720
    cb,
721
    data,
722
    v8::Global<v8::Object>(isolate_, obj),
723
    ref
724
101694
  });
725
50847
  immediate_info()->count_inc(1);
726
50847
}
727
728
28618
void Environment::SetImmediate(native_immediate_callback cb,
729
                               void* data,
730
                               v8::Local<v8::Object> obj) {
731
28618
  CreateImmediate(cb, data, obj, true);
732
733
28618
  if (immediate_info()->ref_count() == 0)
734
22639
    ToggleImmediateRef(true);
735
28618
  immediate_info()->ref_count_inc(1);
736
28618
}
737
738
22229
void Environment::SetUnrefImmediate(native_immediate_callback cb,
739
                                    void* data,
740
                                    v8::Local<v8::Object> obj) {
741
22229
  CreateImmediate(cb, data, obj, false);
742
22229
}
743
744
3330254
inline bool Environment::can_call_into_js() const {
745

3330254
  return can_call_into_js_ && !is_stopping();
746
}
747
748
4334
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
749
4334
  can_call_into_js_ = can_call_into_js;
750
4334
}
751
752
20129
inline bool Environment::has_run_bootstrapping_code() const {
753
20129
  return has_run_bootstrapping_code_;
754
}
755
756
4650
inline void Environment::set_has_run_bootstrapping_code(bool value) {
757
4650
  has_run_bootstrapping_code_ = value;
758
4650
}
759
760
13
inline bool Environment::has_serialized_options() const {
761
13
  return has_serialized_options_;
762
}
763
764
4643
inline void Environment::set_has_serialized_options(bool value) {
765
4643
  has_serialized_options_ = value;
766
4643
}
767
768
18292
inline bool Environment::is_main_thread() const {
769
18292
  return flags_ & kIsMainThread;
770
}
771
772
26883
inline bool Environment::owns_process_state() const {
773
26883
  return flags_ & kOwnsProcessState;
774
}
775
776
4652
inline bool Environment::owns_inspector() const {
777
4652
  return flags_ & kOwnsInspector;
778
}
779
780
8045
inline uint64_t Environment::thread_id() const {
781
8045
  return thread_id_;
782
}
783
784
inline worker::Worker* Environment::worker_context() const {
785
  return worker_context_;
786
}
787
788
182
inline void Environment::set_worker_context(worker::Worker* context) {
789
182
  CHECK_NULL(worker_context_);  // Should be set only once.
790
182
  worker_context_ = context;
791
182
}
792
793
185
inline void Environment::add_sub_worker_context(worker::Worker* context) {
794
185
  sub_worker_contexts_.insert(context);
795
185
}
796
797
208
inline void Environment::remove_sub_worker_context(worker::Worker* context) {
798
208
  sub_worker_contexts_.erase(context);
799
208
}
800
801
3328916
inline bool Environment::is_stopping() const {
802
3328916
  return thread_stopper_.is_stopped();
803
}
804
805
35092
inline performance::performance_state* Environment::performance_state() {
806
35092
  return performance_state_.get();
807
}
808
809
inline std::unordered_map<std::string, uint64_t>*
810
42
    Environment::performance_marks() {
811
42
  return &performance_marks_;
812
}
813
814
5406041
inline IsolateData* Environment::isolate_data() const {
815
5406041
  return isolate_data_;
816
}
817
818
435922
inline char* Environment::AllocateUnchecked(size_t size) {
819
  return static_cast<char*>(
820
435922
      isolate_data()->allocator()->AllocateUninitialized(size));
821
}
822
823
406978
inline char* Environment::Allocate(size_t size) {
824
406978
  char* ret = AllocateUnchecked(size);
825
406978
  CHECK_NE(ret, nullptr);
826
406978
  return ret;
827
}
828
829
936234
inline void Environment::Free(char* data, size_t size) {
830
936234
  if (data != nullptr)
831
34136
    isolate_data()->allocator()->Free(data, size);
832
936234
}
833
834
435922
inline AllocatedBuffer Environment::AllocateManaged(size_t size, bool checked) {
835
435922
  char* data = checked ? Allocate(size) : AllocateUnchecked(size);
836
435922
  if (data == nullptr) size = 0;
837
435922
  return AllocatedBuffer(this, uv_buf_init(data, size));
838
}
839
840
817821
inline AllocatedBuffer::AllocatedBuffer(Environment* env, uv_buf_t buf)
841
817821
    : env_(env), buffer_(buf) {}
842
843
360523
inline void AllocatedBuffer::Resize(size_t len) {
844
  // The `len` check is to make sure we don't end up with `nullptr` as our base.
845
  char* new_data = env_->Reallocate(buffer_.base, buffer_.len,
846
360523
                                    len > 0 ? len : 1);
847
360523
  CHECK_NOT_NULL(new_data);
848
360523
  buffer_ = uv_buf_init(new_data, len);
849
360523
}
850
851
1766543
inline uv_buf_t AllocatedBuffer::release() {
852
1766543
  uv_buf_t ret = buffer_;
853
1766543
  buffer_ = uv_buf_init(nullptr, 0);
854
1766543
  return ret;
855
}
856
857
397082
inline char* AllocatedBuffer::data() {
858
397082
  return buffer_.base;
859
}
860
861
inline const char* AllocatedBuffer::data() const {
862
  return buffer_.base;
863
}
864
865
681156
inline size_t AllocatedBuffer::size() const {
866
681156
  return buffer_.len;
867
}
868
869
62008
inline AllocatedBuffer::AllocatedBuffer(Environment* env)
870
62008
    : env_(env), buffer_(uv_buf_init(nullptr, 0)) {}
871
872
203
inline AllocatedBuffer::AllocatedBuffer(AllocatedBuffer&& other)
873
203
    : AllocatedBuffer() {
874
203
  *this = std::move(other);
875
203
}
876
877
56491
inline AllocatedBuffer& AllocatedBuffer::operator=(AllocatedBuffer&& other) {
878
56491
  clear();
879
56491
  env_ = other.env_;
880
56491
  buffer_ = other.release();
881
56491
  return *this;
882
}
883
884
879743
inline AllocatedBuffer::~AllocatedBuffer() {
885
879743
  clear();
886
879743
}
887
888
936234
inline void AllocatedBuffer::clear() {
889
936234
  uv_buf_t buf = release();
890
936234
  env_->Free(buf.base, buf.len);
891
936234
}
892
893
// It's a bit awkward to define this Buffer::New() overload here, but it
894
// avoids a circular dependency with node_internals.h.
895
namespace Buffer {
896
v8::MaybeLocal<v8::Object> New(Environment* env,
897
                               char* data,
898
                               size_t length,
899
                               bool uses_malloc);
900
}
901
902
52148
inline v8::MaybeLocal<v8::Object> AllocatedBuffer::ToBuffer() {
903
52148
  CHECK_NOT_NULL(env_);
904
52148
  v8::MaybeLocal<v8::Object> obj = Buffer::New(env_, data(), size(), false);
905
52148
  if (!obj.IsEmpty()) release();
906
52148
  return obj;
907
}
908
909
352077
inline v8::Local<v8::ArrayBuffer> AllocatedBuffer::ToArrayBuffer() {
910
352077
  CHECK_NOT_NULL(env_);
911
352077
  uv_buf_t buf = release();
912
  return v8::ArrayBuffer::New(env_->isolate(),
913
                              buf.base,
914
                              buf.len,
915
352077
                              v8::ArrayBufferCreationMode::kInternalized);
916
}
917
918
706
inline void Environment::ThrowError(const char* errmsg) {
919
706
  ThrowError(v8::Exception::Error, errmsg);
920
706
}
921
922
5
inline void Environment::ThrowTypeError(const char* errmsg) {
923
5
  ThrowError(v8::Exception::TypeError, errmsg);
924
5
}
925
926
inline void Environment::ThrowRangeError(const char* errmsg) {
927
  ThrowError(v8::Exception::RangeError, errmsg);
928
}
929
930
711
inline void Environment::ThrowError(
931
    v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
932
    const char* errmsg) {
933
711
  v8::HandleScope handle_scope(isolate());
934
711
  isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
935
711
}
936
937
3
inline void Environment::ThrowErrnoException(int errorno,
938
                                             const char* syscall,
939
                                             const char* message,
940
                                             const char* path) {
941
  isolate()->ThrowException(
942
3
      ErrnoException(isolate(), errorno, syscall, message, path));
943
3
}
944
945
15
inline void Environment::ThrowUVException(int errorno,
946
                                          const char* syscall,
947
                                          const char* message,
948
                                          const char* path,
949
                                          const char* dest) {
950
  isolate()->ThrowException(
951
15
      UVException(isolate(), errorno, syscall, message, path, dest));
952
15
}
953
954
inline v8::Local<v8::FunctionTemplate>
955
1626768
    Environment::NewFunctionTemplate(v8::FunctionCallback callback,
956
                                     v8::Local<v8::Signature> signature,
957
                                     v8::ConstructorBehavior behavior,
958
                                     v8::SideEffectType side_effect_type) {
959
1626768
  v8::Local<v8::Object> external = as_callback_data();
960
  return v8::FunctionTemplate::New(isolate(), callback, external,
961
1626768
                                   signature, 0, behavior, side_effect_type);
962
}
963
964
660554
inline void Environment::SetMethod(v8::Local<v8::Object> that,
965
                                   const char* name,
966
                                   v8::FunctionCallback callback) {
967
660554
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
968
  v8::Local<v8::Function> function =
969
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
970
                          v8::ConstructorBehavior::kThrow,
971
660552
                          v8::SideEffectType::kHasSideEffect)
972
1981659
          ->GetFunction(context)
973
1321105
          .ToLocalChecked();
974
  // kInternalized strings are created in the old space.
975
660552
  const v8::NewStringType type = v8::NewStringType::kInternalized;
976
  v8::Local<v8::String> name_string =
977
1321106
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
978
1321108
  that->Set(context, name_string, function).Check();
979
660554
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
980
660553
}
981
982
308805
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
983
                                               const char* name,
984
                                               v8::FunctionCallback callback) {
985
308805
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
986
  v8::Local<v8::Function> function =
987
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
988
                          v8::ConstructorBehavior::kThrow,
989
308800
                          v8::SideEffectType::kHasNoSideEffect)
990
926410
          ->GetFunction(context)
991
617605
          .ToLocalChecked();
992
  // kInternalized strings are created in the old space.
993
308800
  const v8::NewStringType type = v8::NewStringType::kInternalized;
994
  v8::Local<v8::String> name_string =
995
617605
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
996
617610
  that->Set(context, name_string, function).Check();
997
308805
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
998
308805
}
999
1000
439134
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
1001
                                        const char* name,
1002
                                        v8::FunctionCallback callback) {
1003
439134
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1004
  v8::Local<v8::FunctionTemplate> t =
1005
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1006
439134
                          v8::SideEffectType::kHasSideEffect);
1007
  // kInternalized strings are created in the old space.
1008
439134
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1009
  v8::Local<v8::String> name_string =
1010
878268
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1011
878268
  that->PrototypeTemplate()->Set(name_string, t);
1012
439134
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1013
439134
}
1014
1015
43610
inline void Environment::SetProtoMethodNoSideEffect(
1016
    v8::Local<v8::FunctionTemplate> that,
1017
    const char* name,
1018
    v8::FunctionCallback callback) {
1019
43610
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1020
  v8::Local<v8::FunctionTemplate> t =
1021
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1022
43610
                          v8::SideEffectType::kHasNoSideEffect);
1023
  // kInternalized strings are created in the old space.
1024
43610
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1025
  v8::Local<v8::String> name_string =
1026
87220
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1027
87220
  that->PrototypeTemplate()->Set(name_string, t);
1028
43610
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1029
43610
}
1030
1031
655593
void Environment::AddCleanupHook(void (*fn)(void*), void* arg) {
1032
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
1033
    fn, arg, cleanup_hook_counter_++
1034
655593
  });
1035
  // Make sure there was no existing element with these values.
1036
655594
  CHECK_EQ(insertion_info.second, true);
1037
655594
}
1038
1039
654204
void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
1040
654204
  CleanupHookCallback search { fn, arg, 0 };
1041
654204
  cleanup_hooks_.erase(search);
1042
654202
}
1043
1044
1384496
size_t CleanupHookCallback::Hash::operator()(
1045
    const CleanupHookCallback& cb) const {
1046
1384496
  return std::hash<void*>()(cb.arg_);
1047
}
1048
1049
691626
bool CleanupHookCallback::Equal::operator()(
1050
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
1051

691626
  return a.fn_ == b.fn_ && a.arg_ == b.arg_;
1052
}
1053
1054
130
BaseObject* CleanupHookCallback::GetBaseObject() const {
1055
130
  if (fn_ == BaseObject::DeleteMe)
1056
129
    return static_cast<BaseObject*>(arg_);
1057
  else
1058
1
    return nullptr;
1059
}
1060
1061
template <typename T>
1062
void Environment::ForEachBaseObject(T&& iterator) {
1063
  for (const auto& hook : cleanup_hooks_) {
1064
    BaseObject* obj = hook.GetBaseObject();
1065
    if (obj != nullptr)
1066
      iterator(obj);
1067
  }
1068
}
1069
1070
3328918
bool AsyncRequest::is_stopped() const {
1071
3328918
  return stopped_.load();
1072
}
1073
1074
5081
void AsyncRequest::set_stopped(bool flag) {
1075
5081
  stopped_.store(flag);
1076
5081
}
1077
1078
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1079
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1080
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1081
#define V(TypeName, PropertyName)                                             \
1082
  inline                                                                      \
1083
  v8::Local<TypeName> IsolateData::PropertyName(v8::Isolate* isolate) const { \
1084
    /* Strings are immutable so casting away const-ness here is okay. */      \
1085
    return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate);    \
1086
  }
1087
20326
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1088
250164
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1089
4476060
  PER_ISOLATE_STRING_PROPERTIES(VS)
1090
#undef V
1091
#undef VS
1092
#undef VY
1093
#undef VP
1094
1095
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1096
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1097
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1098
#define V(TypeName, PropertyName)                                             \
1099
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1100
    return isolate_data()->PropertyName(isolate());                           \
1101
  }
1102
10163
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1103
124960
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1104
2229883
  PER_ISOLATE_STRING_PROPERTIES(VS)
1105
#undef V
1106
#undef VS
1107
#undef VY
1108
#undef VP
1109
1110
#define V(PropertyName, TypeName)                                             \
1111
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1112
    return PersistentToLocal::Strong(PropertyName ## _);                      \
1113
  }                                                                           \
1114
  inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) {  \
1115
    PropertyName ## _.Reset(isolate(), value);                                \
1116
  }
1117
352682
  ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1118
6642004
  ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1119
#undef V
1120
1121
16043879
  inline v8::Local<v8::Context> Environment::context() const {
1122
16043879
    return PersistentToLocal::Strong(context_);
1123
  }
1124
}  // namespace node
1125
1126
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1127
1128
#endif  // SRC_ENV_INL_H_