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: 689 693 99.4 %
Date: 2020-02-19 22:14:06 Branches: 90 120 75.0 %

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

648005
  if (fields_[kCheck] > 0 && async_id_fields_[kExecutionAsyncId] != async_id) {
169
4
    fprintf(stderr,
170
            "Error: async hook stack has become corrupted ("
171
            "actual: %.f, expected: %.f)\n",
172
            async_id_fields_.GetValue(kExecutionAsyncId),
173
4
            async_id);
174
4
    DumpBacktrace(stderr);
175
4
    fflush(stderr);
176
4
    if (!env()->abort_on_uncaught_exception())
177
4
      exit(1);
178
    fprintf(stderr, "\n");
179
    fflush(stderr);
180
    ABORT_NO_BACKTRACE();
181
  }
182
183
647995
  uint32_t offset = fields_[kStackLength] - 1;
184
647995
  async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset];
185
647986
  async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1];
186
647997
  fields_[kStackLength] = offset;
187
188
648002
  auto resources = execution_async_resources();
189
1296011
  USE(resources->Delete(env()->context(), offset));
190
191
648015
  return fields_[kStackLength] > 0;
192
}
193
194
// Keep in sync with clearAsyncIdStack in lib/internal/async_hooks.js.
195
4407
inline void AsyncHooks::clear_async_id_stack() {
196
4407
  auto isolate = env()->isolate();
197
8814
  v8::HandleScope handle_scope(isolate);
198
8814
  execution_async_resources_.Reset(isolate, v8::Array::New(isolate));
199
200
4407
  async_id_fields_[kExecutionAsyncId] = 0;
201
4407
  async_id_fields_[kTriggerAsyncId] = 0;
202
4407
  fields_[kStackLength] = 0;
203
4407
}
204
205
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in
206
// async_wrap-inl.h to avoid a circular dependency.
207
208
449787
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope(
209
449787
    Environment* env, double default_trigger_async_id)
210
449787
    : async_hooks_(env->async_hooks()) {
211
449787
  if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) {
212
449787
    CHECK_GE(default_trigger_async_id, 0);
213
  }
214
215
449787
  old_default_trigger_async_id_ =
216
899574
    async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
217
449787
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
218
449787
    default_trigger_async_id;
219
449787
}
220
221
899572
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() {
222
449786
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
223
899572
    old_default_trigger_async_id_;
224
449786
}
225
226
2551948
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
227
2551948
  return ContainerOf(&Environment::async_hooks_, hooks);
228
}
229
230
648588
inline size_t Environment::async_callback_scope_depth() const {
231
648588
  return async_callback_scope_depth_;
232
}
233
234
647926
inline void Environment::PushAsyncCallbackScope() {
235
647926
  async_callback_scope_depth_++;
236
647926
}
237
238
648653
inline void Environment::PopAsyncCallbackScope() {
239
648653
  async_callback_scope_depth_--;
240
648653
}
241
242
4378
inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
243
4378
    : fields_(isolate, kFieldsCount) {}
244
245
4377
inline AliasedUint32Array& ImmediateInfo::fields() {
246
4377
  return fields_;
247
}
248
249
398954
inline uint32_t ImmediateInfo::count() const {
250
398954
  return fields_[kCount];
251
}
252
253
469711
inline uint32_t ImmediateInfo::ref_count() const {
254
469711
  return fields_[kRefCount];
255
}
256
257
30358
inline bool ImmediateInfo::has_outstanding() const {
258
30358
  return fields_[kHasOutstanding] == 1;
259
}
260
261
32549
inline void ImmediateInfo::ref_count_inc(uint32_t increment) {
262
32549
  fields_[kRefCount] += increment;
263
32549
}
264
265
407321
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
266
407321
  fields_[kRefCount] -= decrement;
267
407329
}
268
269
4378
inline TickInfo::TickInfo(v8::Isolate* isolate)
270
4378
    : fields_(isolate, kFieldsCount) {}
271
272
4377
inline AliasedUint8Array& TickInfo::fields() {
273
4377
  return fields_;
274
}
275
276
1171533
inline bool TickInfo::has_tick_scheduled() const {
277
1171533
  return fields_[kHasTickScheduled] == 1;
278
}
279
280
185710
inline bool TickInfo::has_rejection_to_warn() const {
281
185710
  return fields_[kHasRejectionToWarn] == 1;
282
}
283
284
4936
inline void Environment::AssignToContext(v8::Local<v8::Context> context,
285
                                         const ContextInfo& info) {
286
4936
  context->SetAlignedPointerInEmbedderData(
287
4936
      ContextEmbedderIndex::kEnvironment, this);
288
  // Used by Environment::GetCurrent to know that we are on a node context.
289
9872
  context->SetAlignedPointerInEmbedderData(
290
4936
    ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
291
#if HAVE_INSPECTOR
292
4936
  inspector_agent()->ContextCreated(context, info);
293
#endif  // HAVE_INSPECTOR
294
4936
}
295
296
668296
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
297
668296
  if (UNLIKELY(!isolate->InContext())) return nullptr;
298
1337733
  v8::HandleScope handle_scope(isolate);
299
669204
  return GetCurrent(isolate->GetCurrentContext());
300
}
301
302
969911
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
303
969911
  if (UNLIKELY(context.IsEmpty())) {
304
1
    return nullptr;
305
  }
306
969910
  if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
307
               ContextEmbedderIndex::kContextTag)) {
308
11
    return nullptr;
309
  }
310
1940190
  if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
311
                   ContextEmbedderIndex::kContextTag) !=
312
               Environment::kNodeContextTagPtr)) {
313
    return nullptr;
314
  }
315
  return static_cast<Environment*>(
316
970095
      context->GetAlignedPointerFromEmbedderData(
317
970095
          ContextEmbedderIndex::kEnvironment));
318
}
319
320
4285945
inline Environment* Environment::GetCurrent(
321
    const v8::FunctionCallbackInfo<v8::Value>& info) {
322
4285945
  return GetFromCallbackData(info.Data());
323
}
324
325
template <typename T>
326
1048887
inline Environment* Environment::GetCurrent(
327
    const v8::PropertyCallbackInfo<T>& info) {
328
1048887
  return GetFromCallbackData(info.Data());
329
}
330
331
5334837
inline Environment* Environment::GetFromCallbackData(v8::Local<v8::Value> val) {
332
  DCHECK(val->IsObject());
333
5334837
  v8::Local<v8::Object> obj = val.As<v8::Object>();
334
  DCHECK_GE(obj->InternalFieldCount(), 1);
335
  Environment* env =
336
10669674
      static_cast<Environment*>(obj->GetAlignedPointerFromInternalField(0));
337
  DCHECK(env->as_callback_data_template()->HasInstance(obj));
338
5334837
  return env;
339
}
340
341
1
inline Environment* Environment::GetThreadLocalEnv() {
342
1
  return static_cast<Environment*>(uv_key_get(&thread_local_env));
343
}
344
345
230
inline bool Environment::profiler_idle_notifier_started() const {
346
230
  return profiler_idle_notifier_started_;
347
}
348
349
30553030
inline v8::Isolate* Environment::isolate() const {
350
30553030
  return isolate_;
351
}
352
353
4688
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
354
4688
  return ContainerOf(&Environment::timer_handle_, handle);
355
}
356
357
19935
inline uv_timer_t* Environment::timer_handle() {
358
19935
  return &timer_handle_;
359
}
360
361
398954
inline Environment* Environment::from_immediate_check_handle(
362
    uv_check_t* handle) {
363
398954
  return ContainerOf(&Environment::immediate_check_handle_, handle);
364
}
365
366
17512
inline uv_check_t* Environment::immediate_check_handle() {
367
17512
  return &immediate_check_handle_;
368
}
369
370
434320
inline uv_idle_t* Environment::immediate_idle_handle() {
371
434320
  return &immediate_idle_handle_;
372
}
373
374
26268
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
375
                                               HandleCleanupCb cb,
376
                                               void* arg) {
377
26268
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
378
26268
}
379
380
template <typename T, typename OnCloseCallback>
381
27632
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
382
27632
  handle_cleanup_waiting_++;
383
  static_assert(sizeof(T) >= sizeof(uv_handle_t), "T is a libuv handle");
384
  static_assert(offsetof(T, data) == offsetof(uv_handle_t, data),
385
                "T is a libuv handle");
386
  static_assert(offsetof(T, close_cb) == offsetof(uv_handle_t, close_cb),
387
                "T is a libuv handle");
388
  struct CloseData {
389
    Environment* env;
390
    OnCloseCallback callback;
391
    void* original_data;
392
  };
393
27632
  handle->data = new CloseData { this, callback, handle->data };
394
110530
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
395
55265
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
396
27633
    data->env->handle_cleanup_waiting_--;
397
27632
    handle->data = data->original_data;
398
27633
    data->callback(reinterpret_cast<T*>(handle));
399
27633
  });
400
27632
}
401
402
73027
void Environment::IncreaseWaitingRequestCounter() {
403
73027
  request_waiting_++;
404
73027
}
405
406
73022
void Environment::DecreaseWaitingRequestCounter() {
407
73022
  request_waiting_--;
408
73022
  CHECK_GE(request_waiting_, 0);
409
73022
}
410
411
684506
inline uv_loop_t* Environment::event_loop() const {
412
684506
  return isolate_data()->event_loop();
413
}
414
415
152
inline void Environment::TryLoadAddon(
416
    const char* filename,
417
    int flags,
418
    const std::function<bool(binding::DLib*)>& was_loaded) {
419
152
  loaded_addons_.emplace_back(filename, flags);
420
152
  if (!was_loaded(&loaded_addons_.back())) {
421
8
    loaded_addons_.pop_back();
422
  }
423
152
}
424
425
#if HAVE_INSPECTOR
426
27127
inline bool Environment::is_in_inspector_console_call() const {
427
27127
  return is_in_inspector_console_call_;
428
}
429
430
54252
inline void Environment::set_is_in_inspector_console_call(bool value) {
431
54252
  is_in_inspector_console_call_ = value;
432
54252
}
433
#endif
434
435
5352619
inline AsyncHooks* Environment::async_hooks() {
436
5352619
  return &async_hooks_;
437
}
438
439
1343277
inline ImmediateInfo* Environment::immediate_info() {
440
1343277
  return &immediate_info_;
441
}
442
443
590156
inline TickInfo* Environment::tick_info() {
444
590156
  return &tick_info_;
445
}
446
447
46669
inline uint64_t Environment::timer_base() const {
448
46669
  return timer_base_;
449
}
450
451
1060326
inline std::shared_ptr<KVStore> Environment::env_vars() {
452
1060326
  return env_vars_;
453
}
454
455
4606
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) {
456
4606
  env_vars_ = env_vars;
457
4606
}
458
459
14
inline bool Environment::printed_error() const {
460
14
  return printed_error_;
461
}
462
463
14
inline void Environment::set_printed_error(bool value) {
464
14
  printed_error_ = value;
465
14
}
466
467
7583
inline void Environment::set_trace_sync_io(bool value) {
468
7583
  trace_sync_io_ = value;
469
7583
}
470
471
26
inline bool Environment::abort_on_uncaught_exception() const {
472
26
  return options_->abort_on_uncaught_exception;
473
}
474
475
228
inline void Environment::set_abort_on_uncaught_exception(bool value) {
476
228
  options_->abort_on_uncaught_exception = value;
477
228
}
478
479
4408
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
480
4408
  return should_abort_on_uncaught_toggle_;
481
}
482
483
1273650
inline AliasedInt32Array& Environment::stream_base_state() {
484
1273650
  return stream_base_state_;
485
}
486
487
29551
inline uint32_t Environment::get_next_module_id() {
488
29551
  return module_id_counter_++;
489
}
490
1824
inline uint32_t Environment::get_next_script_id() {
491
1824
  return script_id_counter_++;
492
}
493
24316
inline uint32_t Environment::get_next_function_id() {
494
24316
  return function_id_counter_++;
495
}
496
497
60763
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
498
60763
    Environment* env)
499
60763
    : env_(env) {
500
60763
  env_->PushShouldNotAbortOnUncaughtScope();
501
60763
}
502
503
121522
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
504
60761
  Close();
505
60761
}
506
507
60932
void ShouldNotAbortOnUncaughtScope::Close() {
508
60932
  if (env_ != nullptr) {
509
60761
    env_->PopShouldNotAbortOnUncaughtScope();
510
60761
    env_ = nullptr;
511
  }
512
60932
}
513
514
60763
inline void Environment::PushShouldNotAbortOnUncaughtScope() {
515
60763
  should_not_abort_scope_counter_++;
516
60763
}
517
518
60761
inline void Environment::PopShouldNotAbortOnUncaughtScope() {
519
60761
  should_not_abort_scope_counter_--;
520
60761
}
521
522
1
inline bool Environment::inside_should_not_abort_on_uncaught_scope() const {
523
1
  return should_not_abort_scope_counter_ > 0;
524
}
525
526
196814
inline std::vector<double>* Environment::destroy_async_id_list() {
527
196814
  return &destroy_async_id_list_;
528
}
529
530
178906
inline double Environment::new_async_id() {
531
178906
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
532
178906
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
533
}
534
535
187909
inline double Environment::execution_async_id() {
536
187909
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
537
}
538
539
37468
inline double Environment::trigger_async_id() {
540
37468
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
541
}
542
543
178903
inline double Environment::get_default_trigger_async_id() {
544
  double default_trigger_async_id =
545
178903
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
546
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
547
178903
  if (default_trigger_async_id < 0)
548
149890
    default_trigger_async_id = execution_async_id();
549
178903
  return default_trigger_async_id;
550
}
551
552
1570
inline double* Environment::heap_statistics_buffer() const {
553
1570
  CHECK_NOT_NULL(heap_statistics_buffer_);
554
1570
  return static_cast<double*>(heap_statistics_buffer_->Data());
555
}
556
557
499
inline void Environment::set_heap_statistics_buffer(
558
    std::shared_ptr<v8::BackingStore> backing_store) {
559
499
  CHECK(!heap_statistics_buffer_);  // Should be set only once.
560
499
  heap_statistics_buffer_ = std::move(backing_store);
561
499
}
562
563
1570
inline double* Environment::heap_space_statistics_buffer() const {
564
1570
  CHECK(heap_space_statistics_buffer_);
565
1570
  return static_cast<double*>(heap_space_statistics_buffer_->Data());
566
}
567
568
499
inline void Environment::set_heap_space_statistics_buffer(
569
    std::shared_ptr<v8::BackingStore> backing_store) {
570
499
  CHECK(!heap_space_statistics_buffer_);  // Should be set only once.
571
499
  heap_space_statistics_buffer_ = std::move(backing_store);
572
499
}
573
574
1
inline double* Environment::heap_code_statistics_buffer() const {
575
1
  CHECK(heap_code_statistics_buffer_);
576
1
  return static_cast<double*>(heap_code_statistics_buffer_->Data());
577
}
578
579
499
inline void Environment::set_heap_code_statistics_buffer(
580
    std::shared_ptr<v8::BackingStore> backing_store) {
581
499
  CHECK(!heap_code_statistics_buffer_);  // Should be set only once.
582
499
  heap_code_statistics_buffer_ = std::move(backing_store);
583
499
}
584
585
11420
inline char* Environment::http_parser_buffer() const {
586
11420
  return http_parser_buffer_;
587
}
588
589
293
inline void Environment::set_http_parser_buffer(char* buffer) {
590
293
  CHECK_NULL(http_parser_buffer_);  // Should be set only once.
591
293
  http_parser_buffer_ = buffer;
592
293
}
593
594
3802
inline bool Environment::http_parser_buffer_in_use() const {
595
3802
  return http_parser_buffer_in_use_;
596
}
597
598
7600
inline void Environment::set_http_parser_buffer_in_use(bool in_use) {
599
7600
  http_parser_buffer_in_use_ = in_use;
600
7600
}
601
602
1738
inline http2::Http2State* Environment::http2_state() const {
603
1738
  return http2_state_.get();
604
}
605
606
227
inline void Environment::set_http2_state(
607
    std::unique_ptr<http2::Http2State> buffer) {
608
227
  CHECK(!http2_state_);  // Should be set only once.
609
227
  http2_state_ = std::move(buffer);
610
227
}
611
612
1227272
bool Environment::debug_enabled(DebugCategory category) const {
613
  DCHECK_GE(static_cast<int>(category), 0);
614
  DCHECK_LT(static_cast<int>(category),
615
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
616
1227272
  return debug_enabled_[static_cast<int>(category)];
617
}
618
619
42
void Environment::set_debug_enabled(DebugCategory category, bool enabled) {
620
  DCHECK_GE(static_cast<int>(category), 0);
621
  DCHECK_LT(static_cast<int>(category),
622
           static_cast<int>(DebugCategory::CATEGORY_COUNT));
623
42
  debug_enabled_[static_cast<int>(category)] = enabled;
624
42
}
625
626
161711
inline AliasedFloat64Array* Environment::fs_stats_field_array() {
627
161711
  return &fs_stats_field_array_;
628
}
629
630
4387
inline AliasedBigUint64Array* Environment::fs_stats_field_bigint_array() {
631
4387
  return &fs_stats_field_bigint_array_;
632
}
633
634
inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>&
635
424
Environment::file_handle_read_wrap_freelist() {
636
424
  return file_handle_read_wrap_freelist_;
637
}
638
639
46343
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
640
46343
  return options_;
641
}
642
643
12528
inline const std::vector<std::string>& Environment::argv() {
644
12528
  return argv_;
645
}
646
647
4581
inline const std::vector<std::string>& Environment::exec_argv() {
648
4581
  return exec_argv_;
649
}
650
651
8754
inline const std::string& Environment::exec_path() const {
652
8754
  return exec_path_;
653
}
654
655
#if HAVE_INSPECTOR
656
4371
inline void Environment::set_coverage_directory(const char* dir) {
657
4371
  coverage_directory_ = std::string(dir);
658
4371
}
659
660
4340
inline void Environment::set_coverage_connection(
661
    std::unique_ptr<profiler::V8CoverageConnection> connection) {
662
4340
  CHECK_NULL(coverage_connection_);
663
4341
  std::swap(coverage_connection_, connection);
664
4340
}
665
666
13017
inline profiler::V8CoverageConnection* Environment::coverage_connection() {
667
13017
  return coverage_connection_.get();
668
}
669
670
4313
inline const std::string& Environment::coverage_directory() const {
671
4313
  return coverage_directory_;
672
}
673
674
10
inline void Environment::set_cpu_profiler_connection(
675
    std::unique_ptr<profiler::V8CpuProfilerConnection> connection) {
676
10
  CHECK_NULL(cpu_profiler_connection_);
677
10
  std::swap(cpu_profiler_connection_, connection);
678
10
}
679
680
inline profiler::V8CpuProfilerConnection*
681
4356
Environment::cpu_profiler_connection() {
682
4356
  return cpu_profiler_connection_.get();
683
}
684
685
10
inline void Environment::set_cpu_prof_interval(uint64_t interval) {
686
10
  cpu_prof_interval_ = interval;
687
10
}
688
689
10
inline uint64_t Environment::cpu_prof_interval() const {
690
10
  return cpu_prof_interval_;
691
}
692
693
10
inline void Environment::set_cpu_prof_name(const std::string& name) {
694
10
  cpu_prof_name_ = name;
695
10
}
696
697
10
inline const std::string& Environment::cpu_prof_name() const {
698
10
  return cpu_prof_name_;
699
}
700
701
10
inline void Environment::set_cpu_prof_dir(const std::string& dir) {
702
10
  cpu_prof_dir_ = dir;
703
10
}
704
705
10
inline const std::string& Environment::cpu_prof_dir() const {
706
10
  return cpu_prof_dir_;
707
}
708
709
10
inline void Environment::set_heap_profiler_connection(
710
    std::unique_ptr<profiler::V8HeapProfilerConnection> connection) {
711
10
  CHECK_NULL(heap_profiler_connection_);
712
10
  std::swap(heap_profiler_connection_, connection);
713
10
}
714
715
inline profiler::V8HeapProfilerConnection*
716
4346
Environment::heap_profiler_connection() {
717
4346
  return heap_profiler_connection_.get();
718
}
719
720
10
inline void Environment::set_heap_prof_name(const std::string& name) {
721
10
  heap_prof_name_ = name;
722
10
}
723
724
10
inline const std::string& Environment::heap_prof_name() const {
725
10
  return heap_prof_name_;
726
}
727
728
10
inline void Environment::set_heap_prof_dir(const std::string& dir) {
729
10
  heap_prof_dir_ = dir;
730
10
}
731
732
10
inline const std::string& Environment::heap_prof_dir() const {
733
10
  return heap_prof_dir_;
734
}
735
736
10
inline void Environment::set_heap_prof_interval(uint64_t interval) {
737
10
  heap_prof_interval_ = interval;
738
10
}
739
740
10
inline uint64_t Environment::heap_prof_interval() const {
741
10
  return heap_prof_interval_;
742
}
743
744
#endif  // HAVE_INSPECTOR
745
746
inline
747
8826
std::shared_ptr<ExclusiveAccess<HostPort>> Environment::inspector_host_port() {
748
8826
  return inspector_host_port_;
749
}
750
751
14364
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
752
14364
  return options_;
753
}
754
755
28
inline void IsolateData::set_options(
756
    std::shared_ptr<PerIsolateOptions> options) {
757
28
  options_ = std::move(options);
758
28
}
759
760
std::unique_ptr<Environment::NativeImmediateCallback>
761
462490
Environment::NativeImmediateQueue::Shift() {
762
462490
  std::unique_ptr<Environment::NativeImmediateCallback> ret = std::move(head_);
763
462494
  if (ret) {
764
55164
    head_ = ret->get_next();
765
55164
    if (!head_)
766
49644
      tail_ = nullptr;  // The queue is now empty.
767
  }
768
462496
  size_--;
769
462493
  return ret;
770
}
771
772
55202
void Environment::NativeImmediateQueue::Push(
773
    std::unique_ptr<Environment::NativeImmediateCallback> cb) {
774
55202
  NativeImmediateCallback* prev_tail = tail_;
775
776
55202
  size_++;
777
55202
  tail_ = cb.get();
778
55202
  if (prev_tail != nullptr)
779
5528
    prev_tail->set_next(std::move(cb));
780
  else
781
49674
    head_ = std::move(cb);
782
55202
}
783
784
271
void Environment::NativeImmediateQueue::ConcatMove(
785
    NativeImmediateQueue&& other) {
786
271
  size_ += other.size_;
787
271
  if (tail_ != nullptr)
788
1
    tail_->set_next(std::move(other.head_));
789
  else
790
270
    head_ = std::move(other.head_);
791
271
  tail_ = other.tail_;
792
271
  other.tail_ = nullptr;
793
271
  other.size_ = 0;
794
271
}
795
796
814664
size_t Environment::NativeImmediateQueue::size() const {
797
1629332
  return size_.load();
798
}
799
800
template <typename Fn>
801
54910
void Environment::CreateImmediate(Fn&& cb, bool ref) {
802
  auto callback = std::make_unique<NativeImmediateCallbackImpl<Fn>>(
803
109820
      std::move(cb), ref);
804
54910
  native_immediates_.Push(std::move(callback));
805
54910
}
806
807
template <typename Fn>
808
32549
void Environment::SetImmediate(Fn&& cb) {
809
32549
  CreateImmediate(std::move(cb), true);
810
811


32549
  if (immediate_info()->ref_count() == 0)
812
24448
    ToggleImmediateRef(true);
813
32549
  immediate_info()->ref_count_inc(1);
814
32549
}
815
816
template <typename Fn>
817
22361
void Environment::SetUnrefImmediate(Fn&& cb) {
818
22361
  CreateImmediate(std::move(cb), false);
819
22361
}
820
821
template <typename Fn>
822
290
void Environment::SetImmediateThreadsafe(Fn&& cb) {
823
  auto callback = std::make_unique<NativeImmediateCallbackImpl<Fn>>(
824
580
      std::move(cb), false);
825
  {
826
580
    Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
827
290
    native_immediates_threadsafe_.Push(std::move(callback));
828
  }
829
290
  uv_async_send(&task_queues_async_);
830
290
}
831
832
template <typename Fn>
833
2
void Environment::RequestInterrupt(Fn&& cb) {
834
  auto callback = std::make_unique<NativeImmediateCallbackImpl<Fn>>(
835
4
      std::move(cb), false);
836
  {
837
4
    Mutex::ScopedLock lock(native_immediates_threadsafe_mutex_);
838
2
    native_immediates_interrupts_.Push(std::move(callback));
839
  }
840
2
  uv_async_send(&task_queues_async_);
841
2
  RequestInterruptFromV8();
842
2
}
843
844
55202
Environment::NativeImmediateCallback::NativeImmediateCallback(bool refed)
845
55202
  : refed_(refed) {}
846
847
110324
bool Environment::NativeImmediateCallback::is_refed() const {
848
110324
  return refed_;
849
}
850
851
std::unique_ptr<Environment::NativeImmediateCallback>
852
55164
Environment::NativeImmediateCallback::get_next() {
853
55164
  return std::move(next_);
854
}
855
856
5529
void Environment::NativeImmediateCallback::set_next(
857
    std::unique_ptr<NativeImmediateCallback> next) {
858
5529
  next_ = std::move(next);
859
5529
}
860
861
template <typename Fn>
862
55202
Environment::NativeImmediateCallbackImpl<Fn>::NativeImmediateCallbackImpl(
863
    Fn&& callback, bool refed)
864
  : NativeImmediateCallback(refed),
865
55202
    callback_(std::move(callback)) {}
866
867
template <typename Fn>
868
55001
void Environment::NativeImmediateCallbackImpl<Fn>::Call(Environment* env) {
869
55001
  callback_(env);
870
54997
}
871
872
2519056
inline bool Environment::can_call_into_js() const {
873

2519056
  return can_call_into_js_ && !is_stopping();
874
}
875
876
4007
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
877
4007
  can_call_into_js_ = can_call_into_js;
878
4008
}
879
880
1181373
inline bool Environment::has_run_bootstrapping_code() const {
881
1181373
  return has_run_bootstrapping_code_;
882
}
883
884
4377
inline void Environment::set_has_run_bootstrapping_code(bool value) {
885
4377
  has_run_bootstrapping_code_ = value;
886
4377
}
887
888
16
inline bool Environment::has_serialized_options() const {
889
16
  return has_serialized_options_;
890
}
891
892
4377
inline void Environment::set_has_serialized_options(bool value) {
893
4377
  has_serialized_options_ = value;
894
4377
}
895
896
25216
inline bool Environment::is_main_thread() const {
897
25216
  return flags_ & kIsMainThread;
898
}
899
900
26072
inline bool Environment::owns_process_state() const {
901
26072
  return flags_ & kOwnsProcessState;
902
}
903
904
4352
inline bool Environment::owns_inspector() const {
905
4352
  return flags_ & kOwnsInspector;
906
}
907
908
2
bool Environment::filehandle_close_warning() const {
909
2
  return emit_filehandle_warning_;
910
}
911
912
2
void Environment::set_filehandle_close_warning(bool on) {
913
2
  emit_filehandle_warning_ = on;
914
2
}
915
916
8256
inline uint64_t Environment::thread_id() const {
917
8256
  return thread_id_;
918
}
919
920
228
inline worker::Worker* Environment::worker_context() const {
921
228
  return worker_context_;
922
}
923
924
228
inline void Environment::set_worker_context(worker::Worker* context) {
925
228
  CHECK_NULL(worker_context_);  // Should be set only once.
926
228
  worker_context_ = context;
927
228
}
928
929
229
inline void Environment::add_sub_worker_context(worker::Worker* context) {
930
229
  sub_worker_contexts_.insert(context);
931
229
}
932
933
241
inline void Environment::remove_sub_worker_context(worker::Worker* context) {
934
241
  sub_worker_contexts_.erase(context);
935
241
}
936
937
template <typename Fn>
938
19
inline void Environment::ForEachWorker(Fn&& iterator) {
939
19
  for (worker::Worker* w : sub_worker_contexts_) iterator(w);
940
19
}
941
942
453
inline void Environment::add_refs(int64_t diff) {
943
453
  task_queues_async_refs_ += diff;
944
453
  CHECK_GE(task_queues_async_refs_, 0);
945
453
  if (task_queues_async_refs_ == 0)
946
111
    uv_unref(reinterpret_cast<uv_handle_t*>(&task_queues_async_));
947
  else
948
342
    uv_ref(reinterpret_cast<uv_handle_t*>(&task_queues_async_));
949
453
}
950
951
2519303
inline bool Environment::is_stopping() const {
952
2519303
  return is_stopping_.load();
953
}
954
955
289
inline void Environment::set_stopping(bool value) {
956
289
  is_stopping_.store(value);
957
289
}
958
959
1
inline std::list<node_module>* Environment::extra_linked_bindings() {
960
1
  return &extra_linked_bindings_;
961
}
962
963
3
inline node_module* Environment::extra_linked_bindings_head() {
964
4
  return extra_linked_bindings_.size() > 0 ?
965
4
      &extra_linked_bindings_.front() : nullptr;
966
}
967
968
3
inline const Mutex& Environment::extra_linked_bindings_mutex() const {
969
3
  return extra_linked_bindings_mutex_;
970
}
971
972
37274
inline performance::performance_state* Environment::performance_state() {
973
37274
  return performance_state_.get();
974
}
975
976
inline std::unordered_map<std::string, uint64_t>*
977
43
    Environment::performance_marks() {
978
43
  return &performance_marks_;
979
}
980
981
4869725
inline IsolateData* Environment::isolate_data() const {
982
4869725
  return isolate_data_;
983
}
984
985
342379
inline char* Environment::AllocateUnchecked(size_t size) {
986
  return static_cast<char*>(
987
342379
      isolate_data()->allocator()->AllocateUninitialized(size));
988
}
989
990
329015
inline char* Environment::Allocate(size_t size) {
991
329015
  char* ret = AllocateUnchecked(size);
992
329015
  CHECK_NE(ret, nullptr);
993
329015
  return ret;
994
}
995
996
818314
inline void Environment::Free(char* data, size_t size) {
997
818314
  if (data != nullptr)
998
47705
    isolate_data()->allocator()->Free(data, size);
999
818314
}
1000
1001
342379
inline AllocatedBuffer Environment::AllocateManaged(size_t size, bool checked) {
1002
342379
  char* data = checked ? Allocate(size) : AllocateUnchecked(size);
1003
342379
  if (data == nullptr) size = 0;
1004
342379
  return AllocatedBuffer(this, uv_buf_init(data, size));
1005
}
1006
1007
667639
inline AllocatedBuffer::AllocatedBuffer(Environment* env, uv_buf_t buf)
1008
667639
    : env_(env), buffer_(buf) {}
1009
1010
306283
inline void AllocatedBuffer::Resize(size_t len) {
1011
  // The `len` check is to make sure we don't end up with `nullptr` as our base.
1012
306283
  char* new_data = env_->Reallocate(buffer_.base, buffer_.len,
1013
306283
                                    len > 0 ? len : 1);
1014
306283
  CHECK_NOT_NULL(new_data);
1015
306283
  buffer_ = uv_buf_init(new_data, len);
1016
306283
}
1017
1018
1491117
inline uv_buf_t AllocatedBuffer::release() {
1019
1491117
  uv_buf_t ret = buffer_;
1020
1491117
  buffer_ = uv_buf_init(nullptr, 0);
1021
1491117
  return ret;
1022
}
1023
1024
130256
inline char* AllocatedBuffer::data() {
1025
130256
  return buffer_.base;
1026
}
1027
1028
inline const char* AllocatedBuffer::data() const {
1029
  return buffer_.base;
1030
}
1031
1032
352442
inline size_t AllocatedBuffer::size() const {
1033
352442
  return buffer_.len;
1034
}
1035
1036
53310
inline AllocatedBuffer::AllocatedBuffer(Environment* env)
1037
53310
    : env_(env), buffer_(uv_buf_init(nullptr, 0)) {}
1038
1039
600
inline AllocatedBuffer::AllocatedBuffer(AllocatedBuffer&& other)
1040
600
    : AllocatedBuffer() {
1041
600
  *this = std::move(other);
1042
600
}
1043
1044
66582
inline AllocatedBuffer& AllocatedBuffer::operator=(AllocatedBuffer&& other) {
1045
66582
  clear();
1046
66582
  env_ = other.env_;
1047
66582
  buffer_ = other.release();
1048
66582
  return *this;
1049
}
1050
1051
1441694
inline AllocatedBuffer::~AllocatedBuffer() {
1052
720847
  clear();
1053
720847
}
1054
1055
818314
inline void AllocatedBuffer::clear() {
1056
818314
  uv_buf_t buf = release();
1057
818314
  env_->Free(buf.base, buf.len);
1058
818314
}
1059
1060
// It's a bit awkward to define this Buffer::New() overload here, but it
1061
// avoids a circular dependency with node_internals.h.
1062
namespace Buffer {
1063
v8::MaybeLocal<v8::Object> New(Environment* env,
1064
                               char* data,
1065
                               size_t length,
1066
                               bool uses_malloc);
1067
}
1068
1069
15324
inline v8::MaybeLocal<v8::Object> AllocatedBuffer::ToBuffer() {
1070
15324
  CHECK_NOT_NULL(env_);
1071
15324
  v8::MaybeLocal<v8::Object> obj = Buffer::New(env_, data(), size(), false);
1072
15324
  if (!obj.IsEmpty()) release();
1073
15324
  return obj;
1074
}
1075
1076
279991
inline v8::Local<v8::ArrayBuffer> AllocatedBuffer::ToArrayBuffer() {
1077
279991
  CHECK_NOT_NULL(env_);
1078
279991
  uv_buf_t buf = release();
1079
839805
  auto callback = [](void* data, size_t length, void* deleter_data){
1080
279907
    CHECK_NOT_NULL(deleter_data);
1081
1082
279907
    static_cast<v8::ArrayBuffer::Allocator*>(deleter_data)
1083
279907
        ->Free(data, length);
1084
839805
  };
1085
  std::unique_ptr<v8::BackingStore> backing =
1086
279991
      v8::ArrayBuffer::NewBackingStore(buf.base,
1087
                                       buf.len,
1088
                                       callback,
1089
279991
                                       env_->isolate()
1090
839973
                                          ->GetArrayBufferAllocator());
1091
279991
  return v8::ArrayBuffer::New(env_->isolate(),
1092
839973
                              std::move(backing));
1093
}
1094
1095
706
inline void Environment::ThrowError(const char* errmsg) {
1096
706
  ThrowError(v8::Exception::Error, errmsg);
1097
706
}
1098
1099
2
inline void Environment::ThrowTypeError(const char* errmsg) {
1100
2
  ThrowError(v8::Exception::TypeError, errmsg);
1101
2
}
1102
1103
inline void Environment::ThrowRangeError(const char* errmsg) {
1104
  ThrowError(v8::Exception::RangeError, errmsg);
1105
}
1106
1107
708
inline void Environment::ThrowError(
1108
    v8::Local<v8::Value> (*fun)(v8::Local<v8::String>),
1109
    const char* errmsg) {
1110
1416
  v8::HandleScope handle_scope(isolate());
1111
708
  isolate()->ThrowException(fun(OneByteString(isolate(), errmsg)));
1112
708
}
1113
1114
3
inline void Environment::ThrowErrnoException(int errorno,
1115
                                             const char* syscall,
1116
                                             const char* message,
1117
                                             const char* path) {
1118
  isolate()->ThrowException(
1119
3
      ErrnoException(isolate(), errorno, syscall, message, path));
1120
3
}
1121
1122
13
inline void Environment::ThrowUVException(int errorno,
1123
                                          const char* syscall,
1124
                                          const char* message,
1125
                                          const char* path,
1126
                                          const char* dest) {
1127
  isolate()->ThrowException(
1128
13
      UVException(isolate(), errorno, syscall, message, path, dest));
1129
13
}
1130
1131
inline v8::Local<v8::FunctionTemplate>
1132
1648976
    Environment::NewFunctionTemplate(v8::FunctionCallback callback,
1133
                                     v8::Local<v8::Signature> signature,
1134
                                     v8::ConstructorBehavior behavior,
1135
                                     v8::SideEffectType side_effect_type) {
1136
1648976
  v8::Local<v8::Object> external = as_callback_data();
1137
  return v8::FunctionTemplate::New(isolate(), callback, external,
1138
1648976
                                   signature, 0, behavior, side_effect_type);
1139
}
1140
1141
647037
inline void Environment::SetMethod(v8::Local<v8::Object> that,
1142
                                   const char* name,
1143
                                   v8::FunctionCallback callback) {
1144
647037
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
1145
  v8::Local<v8::Function> function =
1146
1294075
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1147
                          v8::ConstructorBehavior::kThrow,
1148
647038
                          v8::SideEffectType::kHasSideEffect)
1149
1294075
          ->GetFunction(context)
1150
647038
          .ToLocalChecked();
1151
  // kInternalized strings are created in the old space.
1152
647038
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1153
  v8::Local<v8::String> name_string =
1154
1294076
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1155
1294074
  that->Set(context, name_string, function).Check();
1156
647036
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1157
647037
}
1158
1159
292397
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
1160
                                               const char* name,
1161
                                               v8::FunctionCallback callback) {
1162
292397
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
1163
  v8::Local<v8::Function> function =
1164
584794
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1165
                          v8::ConstructorBehavior::kThrow,
1166
292397
                          v8::SideEffectType::kHasNoSideEffect)
1167
584794
          ->GetFunction(context)
1168
292397
          .ToLocalChecked();
1169
  // kInternalized strings are created in the old space.
1170
292397
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1171
  v8::Local<v8::String> name_string =
1172
584794
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1173
584793
  that->Set(context, name_string, function).Check();
1174
292396
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1175
292397
}
1176
1177
487008
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
1178
                                        const char* name,
1179
                                        v8::FunctionCallback callback) {
1180
487008
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1181
  v8::Local<v8::FunctionTemplate> t =
1182
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1183
487008
                          v8::SideEffectType::kHasSideEffect);
1184
  // kInternalized strings are created in the old space.
1185
487008
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1186
  v8::Local<v8::String> name_string =
1187
974016
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1188
974016
  that->PrototypeTemplate()->Set(name_string, t);
1189
487008
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1190
487008
}
1191
1192
46556
inline void Environment::SetProtoMethodNoSideEffect(
1193
    v8::Local<v8::FunctionTemplate> that,
1194
    const char* name,
1195
    v8::FunctionCallback callback) {
1196
46556
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1197
  v8::Local<v8::FunctionTemplate> t =
1198
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1199
46556
                          v8::SideEffectType::kHasNoSideEffect);
1200
  // kInternalized strings are created in the old space.
1201
46556
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1202
  v8::Local<v8::String> name_string =
1203
93112
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1204
93112
  that->PrototypeTemplate()->Set(name_string, t);
1205
46556
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1206
46556
}
1207
1208
22
inline void Environment::SetInstanceMethod(v8::Local<v8::FunctionTemplate> that,
1209
                                           const char* name,
1210
                                           v8::FunctionCallback callback) {
1211
22
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1212
  v8::Local<v8::FunctionTemplate> t =
1213
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1214
22
                          v8::SideEffectType::kHasSideEffect);
1215
  // kInternalized strings are created in the old space.
1216
22
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1217
  v8::Local<v8::String> name_string =
1218
44
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1219
44
  that->InstanceTemplate()->Set(name_string, t);
1220
22
  t->SetClassName(name_string);
1221
22
}
1222
1223
568709
void Environment::AddCleanupHook(void (*fn)(void*), void* arg) {
1224
1137418
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
1225
568709
    fn, arg, cleanup_hook_counter_++
1226
568709
  });
1227
  // Make sure there was no existing element with these values.
1228
568709
  CHECK_EQ(insertion_info.second, true);
1229
568709
}
1230
1231
559166
void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
1232
559166
  CleanupHookCallback search { fn, arg, 0 };
1233
559167
  cleanup_hooks_.erase(search);
1234
559171
}
1235
1236
3
inline void Environment::RegisterFinalizationGroupForCleanup(
1237
    v8::Local<v8::FinalizationGroup> group) {
1238
3
  cleanup_finalization_groups_.emplace_back(isolate(), group);
1239
3
  uv_async_send(&task_queues_async_);
1240
3
}
1241
1242
1302362
size_t CleanupHookCallback::Hash::operator()(
1243
    const CleanupHookCallback& cb) const {
1244
1302362
  return std::hash<void*>()(cb.arg_);
1245
}
1246
1247
650225
bool CleanupHookCallback::Equal::operator()(
1248
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
1249

650225
  return a.fn_ == b.fn_ && a.arg_ == b.arg_;
1250
}
1251
1252
314
BaseObject* CleanupHookCallback::GetBaseObject() const {
1253
314
  if (fn_ == BaseObject::DeleteMe)
1254
294
    return static_cast<BaseObject*>(arg_);
1255
  else
1256
20
    return nullptr;
1257
}
1258
1259
template <typename T>
1260
void Environment::ForEachBaseObject(T&& iterator) {
1261
  for (const auto& hook : cleanup_hooks_) {
1262
    BaseObject* obj = hook.GetBaseObject();
1263
    if (obj != nullptr)
1264
      iterator(obj);
1265
  }
1266
}
1267
1268
1122503
void Environment::modify_base_object_count(int64_t delta) {
1269
1122503
  base_object_count_ += delta;
1270
1122503
}
1271
1272
3989
int64_t Environment::base_object_count() const {
1273
3989
  return base_object_count_;
1274
}
1275
1276
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1277
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1278
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1279
#define V(TypeName, PropertyName)                                             \
1280
  inline                                                                      \
1281
  v8::Local<TypeName> IsolateData::PropertyName(v8::Isolate* isolate) const { \
1282
    /* Strings are immutable so casting away const-ness here is okay. */      \
1283
    return const_cast<IsolateData*>(this)->PropertyName ## _.Get(isolate);    \
1284
  }
1285
26194
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1286
575186
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1287
5501380
  PER_ISOLATE_STRING_PROPERTIES(VS)
1288
#undef V
1289
#undef VS
1290
#undef VY
1291
#undef VP
1292
1293
#define VP(PropertyName, StringValue) V(v8::Private, PropertyName)
1294
#define VY(PropertyName, StringValue) V(v8::Symbol, PropertyName)
1295
#define VS(PropertyName, StringValue) V(v8::String, PropertyName)
1296
#define V(TypeName, PropertyName)                                             \
1297
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1298
    return isolate_data()->PropertyName(isolate());                           \
1299
  }
1300
13097
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1301
287348
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1302
2746434
  PER_ISOLATE_STRING_PROPERTIES(VS)
1303
#undef V
1304
#undef VS
1305
#undef VY
1306
#undef VP
1307
1308
#define V(PropertyName, TypeName)                                             \
1309
  inline v8::Local<TypeName> Environment::PropertyName() const {              \
1310
    return PersistentToLocal::Strong(PropertyName ## _);                      \
1311
  }                                                                           \
1312
  inline void Environment::set_ ## PropertyName(v8::Local<TypeName> value) {  \
1313
    PropertyName ## _.Reset(isolate(), value);                                \
1314
  }
1315
405599
  ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1316
5221060
  ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1317
#undef V
1318
1319
10719750
  inline v8::Local<v8::Context> Environment::context() const {
1320
10719750
    return PersistentToLocal::Strong(context_);
1321
  }
1322
}  // namespace node
1323
1324
#endif  // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
1325
1326
#endif  // SRC_ENV_INL_H_