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-27 22:14:15 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
687505
inline uv_loop_t* IsolateData::event_loop() const {
48
687505
  return event_loop_;
49
}
50
51
293685
inline bool IsolateData::uses_node_allocator() const {
52
293685
  return uses_node_allocator_;
53
}
54
55
389936
inline v8::ArrayBuffer::Allocator* IsolateData::allocator() const {
56
389936
  return allocator_;
57
}
58
59
299028
inline NodeArrayBufferAllocator* IsolateData::node_allocator() const {
60
299028
  return node_allocator_;
61
}
62
63
32119
inline MultiIsolatePlatform* IsolateData::platform() const {
64
32119
  return platform_;
65
}
66
67
4392
inline AsyncHooks::AsyncHooks()
68
    : async_ids_stack_(env()->isolate(), 16 * 2),
69
      fields_(env()->isolate(), kFieldsCount),
70
4392
      async_id_fields_(env()->isolate(), kUidFieldsCount) {
71
4392
  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
4392
  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
4392
  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
4392
  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
417240
  NODE_ASYNC_PROVIDER_TYPES(V)
102
#undef V
103
4392
}
104
2651166
inline AliasedUint32Array& AsyncHooks::fields() {
105
2651166
  return fields_;
106
}
107
108
2112871
inline AliasedFloat64Array& AsyncHooks::async_id_fields() {
109
2112871
  return async_id_fields_;
110
}
111
112
4391
inline AliasedFloat64Array& AsyncHooks::async_ids_stack() {
113
4391
  return async_ids_stack_;
114
}
115
116
1299906
inline v8::Local<v8::Array> AsyncHooks::execution_async_resources() {
117
1299906
  return PersistentToLocal::Strong(execution_async_resources_);
118
}
119
120
178163
inline v8::Local<v8::String> AsyncHooks::provider_string(int idx) {
121
356326
  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
2552318
inline Environment* AsyncHooks::env() {
129
2552318
  return Environment::ForAsyncHooks(this);
130
}
131
132
// Remember to keep this code aligned with pushAsyncContext() in JS.
133
648290
inline void AsyncHooks::push_async_context(double async_id,
134
                                           double trigger_async_id,
135
                                           v8::Local<v8::Value> resource) {
136
1296591
  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
648317
  if (fields_[kCheck] > 0) {
141
648307
    CHECK_GE(async_id, -1);
142
648307
    CHECK_GE(trigger_async_id, -1);
143
  }
144
145
648312
  uint32_t offset = fields_[kStackLength];
146
648301
  if (offset * 2 >= async_ids_stack_.Length())
147
8
    grow_async_ids_stack();
148
648296
  async_ids_stack_[2 * offset] = async_id_fields_[kExecutionAsyncId];
149
648305
  async_ids_stack_[2 * offset + 1] = async_id_fields_[kTriggerAsyncId];
150
648292
  fields_[kStackLength] += 1;
151
648309
  async_id_fields_[kExecutionAsyncId] = async_id;
152
648304
  async_id_fields_[kTriggerAsyncId] = trigger_async_id;
153
154
648297
  auto resources = execution_async_resources();
155
1296612
  USE(resources->Set(env()->context(), offset, resource));
156
648304
}
157
158
// Remember to keep this code aligned with popAsyncContext() in JS.
159
647908
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
647908
  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

647272
  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
647255
  uint32_t offset = fields_[kStackLength] - 1;
184
647264
  async_id_fields_[kExecutionAsyncId] = async_ids_stack_[2 * offset];
185
647245
  async_id_fields_[kTriggerAsyncId] = async_ids_stack_[2 * offset + 1];
186
647254
  fields_[kStackLength] = offset;
187
188
647270
  auto resources = execution_async_resources();
189
1294587
  USE(resources->Delete(env()->context(), offset));
190
191
647342
  return fields_[kStackLength] > 0;
192
}
193
194
// Keep in sync with clearAsyncIdStack in lib/internal/async_hooks.js.
195
4421
inline void AsyncHooks::clear_async_id_stack() {
196
4421
  auto isolate = env()->isolate();
197
8842
  v8::HandleScope handle_scope(isolate);
198
8842
  execution_async_resources_.Reset(isolate, v8::Array::New(isolate));
199
200
4421
  async_id_fields_[kExecutionAsyncId] = 0;
201
4421
  async_id_fields_[kTriggerAsyncId] = 0;
202
4421
  fields_[kStackLength] = 0;
203
4421
}
204
205
// The DefaultTriggerAsyncIdScope(AsyncWrap*) constructor is defined in
206
// async_wrap-inl.h to avoid a circular dependency.
207
208
448983
inline AsyncHooks::DefaultTriggerAsyncIdScope ::DefaultTriggerAsyncIdScope(
209
448983
    Environment* env, double default_trigger_async_id)
210
448983
    : async_hooks_(env->async_hooks()) {
211
448983
  if (env->async_hooks()->fields()[AsyncHooks::kCheck] > 0) {
212
448983
    CHECK_GE(default_trigger_async_id, 0);
213
  }
214
215
448983
  old_default_trigger_async_id_ =
216
897966
    async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
217
448983
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
218
448983
    default_trigger_async_id;
219
448983
}
220
221
897964
inline AsyncHooks::DefaultTriggerAsyncIdScope ::~DefaultTriggerAsyncIdScope() {
222
448982
  async_hooks_->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId] =
223
897964
    old_default_trigger_async_id_;
224
448982
}
225
226
2552262
Environment* Environment::ForAsyncHooks(AsyncHooks* hooks) {
227
2552262
  return ContainerOf(&Environment::async_hooks_, hooks);
228
}
229
230
647906
inline size_t Environment::async_callback_scope_depth() const {
231
647906
  return async_callback_scope_depth_;
232
}
233
234
648275
inline void Environment::PushAsyncCallbackScope() {
235
648275
  async_callback_scope_depth_++;
236
648275
}
237
238
647974
inline void Environment::PopAsyncCallbackScope() {
239
647974
  async_callback_scope_depth_--;
240
647974
}
241
242
4392
inline ImmediateInfo::ImmediateInfo(v8::Isolate* isolate)
243
4392
    : fields_(isolate, kFieldsCount) {}
244
245
4392
inline AliasedUint32Array& ImmediateInfo::fields() {
246
4392
  return fields_;
247
}
248
249
398197
inline uint32_t ImmediateInfo::count() const {
250
398197
  return fields_[kCount];
251
}
252
253
468421
inline uint32_t ImmediateInfo::ref_count() const {
254
468421
  return fields_[kRefCount];
255
}
256
257
29921
inline bool ImmediateInfo::has_outstanding() const {
258
29921
  return fields_[kHasOutstanding] == 1;
259
}
260
261
32429
inline void ImmediateInfo::ref_count_inc(uint32_t increment) {
262
32429
  fields_[kRefCount] += increment;
263
32429
}
264
265
406593
inline void ImmediateInfo::ref_count_dec(uint32_t decrement) {
266
406593
  fields_[kRefCount] -= decrement;
267
406600
}
268
269
4392
inline TickInfo::TickInfo(v8::Isolate* isolate)
270
4392
    : fields_(isolate, kFieldsCount) {}
271
272
4392
inline AliasedUint8Array& TickInfo::fields() {
273
4392
  return fields_;
274
}
275
276
1170619
inline bool TickInfo::has_tick_scheduled() const {
277
1170619
  return fields_[kHasTickScheduled] == 1;
278
}
279
280
185896
inline bool TickInfo::has_rejection_to_warn() const {
281
185896
  return fields_[kHasRejectionToWarn] == 1;
282
}
283
284
4953
inline void Environment::AssignToContext(v8::Local<v8::Context> context,
285
                                         const ContextInfo& info) {
286
4953
  context->SetAlignedPointerInEmbedderData(
287
4953
      ContextEmbedderIndex::kEnvironment, this);
288
  // Used by Environment::GetCurrent to know that we are on a node context.
289
9906
  context->SetAlignedPointerInEmbedderData(
290
4953
    ContextEmbedderIndex::kContextTag, Environment::kNodeContextTagPtr);
291
#if HAVE_INSPECTOR
292
4953
  inspector_agent()->ContextCreated(context, info);
293
#endif  // HAVE_INSPECTOR
294
4953
}
295
296
668479
inline Environment* Environment::GetCurrent(v8::Isolate* isolate) {
297
668479
  if (UNLIKELY(!isolate->InContext())) return nullptr;
298
1337150
  v8::HandleScope handle_scope(isolate);
299
668588
  return GetCurrent(isolate->GetCurrentContext());
300
}
301
302
969908
inline Environment* Environment::GetCurrent(v8::Local<v8::Context> context) {
303
969908
  if (UNLIKELY(context.IsEmpty())) {
304
1
    return nullptr;
305
  }
306
969907
  if (UNLIKELY(context->GetNumberOfEmbedderDataFields() <=
307
               ContextEmbedderIndex::kContextTag)) {
308
11
    return nullptr;
309
  }
310
1939866
  if (UNLIKELY(context->GetAlignedPointerFromEmbedderData(
311
                   ContextEmbedderIndex::kContextTag) !=
312
               Environment::kNodeContextTagPtr)) {
313
    return nullptr;
314
  }
315
  return static_cast<Environment*>(
316
969933
      context->GetAlignedPointerFromEmbedderData(
317
969933
          ContextEmbedderIndex::kEnvironment));
318
}
319
320
4286344
inline Environment* Environment::GetCurrent(
321
    const v8::FunctionCallbackInfo<v8::Value>& info) {
322
4286344
  return GetFromCallbackData(info.Data());
323
}
324
325
template <typename T>
326
1049489
inline Environment* Environment::GetCurrent(
327
    const v8::PropertyCallbackInfo<T>& info) {
328
1049489
  return GetFromCallbackData(info.Data());
329
}
330
331
5335615
inline Environment* Environment::GetFromCallbackData(v8::Local<v8::Value> val) {
332
  DCHECK(val->IsObject());
333
5335615
  v8::Local<v8::Object> obj = val.As<v8::Object>();
334
  DCHECK_GE(obj->InternalFieldCount(), 1);
335
  Environment* env =
336
10671232
      static_cast<Environment*>(obj->GetAlignedPointerFromInternalField(0));
337
  DCHECK(env->as_callback_data_template()->HasInstance(obj));
338
5335617
  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
30593338
inline v8::Isolate* Environment::isolate() const {
350
30593338
  return isolate_;
351
}
352
353
4596
inline Environment* Environment::from_timer_handle(uv_timer_t* handle) {
354
4596
  return ContainerOf(&Environment::timer_handle_, handle);
355
}
356
357
19895
inline uv_timer_t* Environment::timer_handle() {
358
19895
  return &timer_handle_;
359
}
360
361
398197
inline Environment* Environment::from_immediate_check_handle(
362
    uv_check_t* handle) {
363
398197
  return ContainerOf(&Environment::immediate_check_handle_, handle);
364
}
365
366
17568
inline uv_check_t* Environment::immediate_check_handle() {
367
17568
  return &immediate_check_handle_;
368
}
369
370
433469
inline uv_idle_t* Environment::immediate_idle_handle() {
371
433469
  return &immediate_idle_handle_;
372
}
373
374
26352
inline void Environment::RegisterHandleCleanup(uv_handle_t* handle,
375
                                               HandleCleanupCb cb,
376
                                               void* arg) {
377
26352
  handle_cleanup_queue_.push_back(HandleCleanup{handle, cb, arg});
378
26352
}
379
380
template <typename T, typename OnCloseCallback>
381
27733
inline void Environment::CloseHandle(T* handle, OnCloseCallback callback) {
382
27733
  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
27733
  handle->data = new CloseData { this, callback, handle->data };
394
110928
  uv_close(reinterpret_cast<uv_handle_t*>(handle), [](uv_handle_t* handle) {
395
55464
    std::unique_ptr<CloseData> data { static_cast<CloseData*>(handle->data) };
396
27732
    data->env->handle_cleanup_waiting_--;
397
27731
    handle->data = data->original_data;
398
27732
    data->callback(reinterpret_cast<T*>(handle));
399
27733
  });
400
27732
}
401
402
72939
void Environment::IncreaseWaitingRequestCounter() {
403
72939
  request_waiting_++;
404
72939
}
405
406
72934
void Environment::DecreaseWaitingRequestCounter() {
407
72934
  request_waiting_--;
408
72934
  CHECK_GE(request_waiting_, 0);
409
72934
}
410
411
683105
inline uv_loop_t* Environment::event_loop() const {
412
683105
  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
27133
inline bool Environment::is_in_inspector_console_call() const {
427
27133
  return is_in_inspector_console_call_;
428
}
429
430
54264
inline void Environment::set_is_in_inspector_console_call(bool value) {
431
54264
  is_in_inspector_console_call_ = value;
432
54264
}
433
#endif
434
435
5348580
inline AsyncHooks* Environment::async_hooks() {
436
5348580
  return &async_hooks_;
437
}
438
439
1339961
inline ImmediateInfo* Environment::immediate_info() {
440
1339961
  return &immediate_info_;
441
}
442
443
589719
inline TickInfo* Environment::tick_info() {
444
589719
  return &tick_info_;
445
}
446
447
46188
inline uint64_t Environment::timer_base() const {
448
46188
  return timer_base_;
449
}
450
451
1060939
inline std::shared_ptr<KVStore> Environment::env_vars() {
452
1060939
  return env_vars_;
453
}
454
455
4620
inline void Environment::set_env_vars(std::shared_ptr<KVStore> env_vars) {
456
4620
  env_vars_ = env_vars;
457
4620
}
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
7615
inline void Environment::set_trace_sync_io(bool value) {
468
7615
  trace_sync_io_ = value;
469
7615
}
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
4422
inline AliasedUint32Array& Environment::should_abort_on_uncaught_toggle() {
480
4422
  return should_abort_on_uncaught_toggle_;
481
}
482
483
1273314
inline AliasedInt32Array& Environment::stream_base_state() {
484
1273314
  return stream_base_state_;
485
}
486
487
29673
inline uint32_t Environment::get_next_module_id() {
488
29673
  return module_id_counter_++;
489
}
490
1818
inline uint32_t Environment::get_next_script_id() {
491
1818
  return script_id_counter_++;
492
}
493
24362
inline uint32_t Environment::get_next_function_id() {
494
24362
  return function_id_counter_++;
495
}
496
497
60995
ShouldNotAbortOnUncaughtScope::ShouldNotAbortOnUncaughtScope(
498
60995
    Environment* env)
499
60995
    : env_(env) {
500
60995
  env_->PushShouldNotAbortOnUncaughtScope();
501
60998
}
502
503
121993
ShouldNotAbortOnUncaughtScope::~ShouldNotAbortOnUncaughtScope() {
504
60996
  Close();
505
60997
}
506
507
61172
void ShouldNotAbortOnUncaughtScope::Close() {
508
61172
  if (env_ != nullptr) {
509
60996
    env_->PopShouldNotAbortOnUncaughtScope();
510
60997
    env_ = nullptr;
511
  }
512
61173
}
513
514
60995
inline void Environment::PushShouldNotAbortOnUncaughtScope() {
515
60995
  should_not_abort_scope_counter_++;
516
60995
}
517
518
60996
inline void Environment::PopShouldNotAbortOnUncaughtScope() {
519
60996
  should_not_abort_scope_counter_--;
520
60996
}
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
196716
inline std::vector<double>* Environment::destroy_async_id_list() {
527
196716
  return &destroy_async_id_list_;
528
}
529
530
178728
inline double Environment::new_async_id() {
531
178728
  async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter] += 1;
532
178728
  return async_hooks()->async_id_fields()[AsyncHooks::kAsyncIdCounter];
533
}
534
535
187862
inline double Environment::execution_async_id() {
536
187862
  return async_hooks()->async_id_fields()[AsyncHooks::kExecutionAsyncId];
537
}
538
539
37492
inline double Environment::trigger_async_id() {
540
37492
  return async_hooks()->async_id_fields()[AsyncHooks::kTriggerAsyncId];
541
}
542
543
178725
inline double Environment::get_default_trigger_async_id() {
544
  double default_trigger_async_id =
545
178725
    async_hooks()->async_id_fields()[AsyncHooks::kDefaultTriggerAsyncId];
546
  // If defaultTriggerAsyncId isn't set, use the executionAsyncId
547
178725
  if (default_trigger_async_id < 0)
548
149804
    default_trigger_async_id = execution_async_id();
549
178725
  return default_trigger_async_id;
550
}
551
552
1569
inline double* Environment::heap_statistics_buffer() const {
553
1569
  CHECK_NOT_NULL(heap_statistics_buffer_);
554
1569
  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
1569
inline double* Environment::heap_space_statistics_buffer() const {
564
1569
  CHECK(heap_space_statistics_buffer_);
565
1569
  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
11267
inline char* Environment::http_parser_buffer() const {
586
11267
  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
3751
inline bool Environment::http_parser_buffer_in_use() const {
595
3751
  return http_parser_buffer_in_use_;
596
}
597
598
7498
inline void Environment::set_http_parser_buffer_in_use(bool in_use) {
599
7498
  http_parser_buffer_in_use_ = in_use;
600
7498
}
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
1224759
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
1224759
  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
161430
inline AliasedFloat64Array* Environment::fs_stats_field_array() {
627
161430
  return &fs_stats_field_array_;
628
}
629
630
4377
inline AliasedBigUint64Array* Environment::fs_stats_field_bigint_array() {
631
4377
  return &fs_stats_field_bigint_array_;
632
}
633
634
inline std::vector<std::unique_ptr<fs::FileHandleReadWrap>>&
635
400
Environment::file_handle_read_wrap_freelist() {
636
400
  return file_handle_read_wrap_freelist_;
637
}
638
639
46408
inline std::shared_ptr<EnvironmentOptions> Environment::options() {
640
46408
  return options_;
641
}
642
643
12547
inline const std::vector<std::string>& Environment::argv() {
644
12547
  return argv_;
645
}
646
647
4571
inline const std::vector<std::string>& Environment::exec_argv() {
648
4571
  return exec_argv_;
649
}
650
651
8734
inline const std::string& Environment::exec_path() const {
652
8734
  return exec_path_;
653
}
654
655
#if HAVE_INSPECTOR
656
4361
inline void Environment::set_coverage_directory(const char* dir) {
657
4361
  coverage_directory_ = std::string(dir);
658
4361
}
659
660
4357
inline void Environment::set_coverage_connection(
661
    std::unique_ptr<profiler::V8CoverageConnection> connection) {
662
4357
  CHECK_NULL(coverage_connection_);
663
4357
  std::swap(coverage_connection_, connection);
664
4355
}
665
666
13064
inline profiler::V8CoverageConnection* Environment::coverage_connection() {
667
13064
  return coverage_connection_.get();
668
}
669
670
4330
inline const std::string& Environment::coverage_directory() const {
671
4330
  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
4372
Environment::cpu_profiler_connection() {
682
4372
  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
4362
Environment::heap_profiler_connection() {
717
4362
  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
8855
std::shared_ptr<ExclusiveAccess<HostPort>> Environment::inspector_host_port() {
748
8855
  return inspector_host_port_;
749
}
750
751
14386
inline std::shared_ptr<PerIsolateOptions> IsolateData::options() {
752
14386
  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
461638
Environment::NativeImmediateQueue::Shift() {
762
461638
  std::unique_ptr<Environment::NativeImmediateCallback> ret = std::move(head_);
763
461644
  if (ret) {
764
55042
    head_ = ret->get_next();
765
55042
    if (!head_)
766
49509
      tail_ = nullptr;  // The queue is now empty.
767
  }
768
461645
  size_--;
769
461644
  return ret;
770
}
771
772
55080
void Environment::NativeImmediateQueue::Push(
773
    std::unique_ptr<Environment::NativeImmediateCallback> cb) {
774
55080
  NativeImmediateCallback* prev_tail = tail_;
775
776
55080
  size_++;
777
55080
  tail_ = cb.get();
778
55080
  if (prev_tail != nullptr)
779
5541
    prev_tail->set_next(std::move(cb));
780
  else
781
49539
    head_ = std::move(cb);
782
55080
}
783
784
267
void Environment::NativeImmediateQueue::ConcatMove(
785
    NativeImmediateQueue&& other) {
786
267
  size_ += other.size_;
787
267
  if (tail_ != nullptr)
788
1
    tail_->set_next(std::move(other.head_));
789
  else
790
266
    head_ = std::move(other.head_);
791
267
  tail_ = other.tail_;
792
267
  other.tail_ = nullptr;
793
267
  other.size_ = 0;
794
267
}
795
796
813205
size_t Environment::NativeImmediateQueue::size() const {
797
1626412
  return size_.load();
798
}
799
800
template <typename Fn>
801
54788
void Environment::CreateImmediate(Fn&& cb, bool ref) {
802
  auto callback = std::make_unique<NativeImmediateCallbackImpl<Fn>>(
803
109576
      std::move(cb), ref);
804
54788
  native_immediates_.Push(std::move(callback));
805
54788
}
806
807
template <typename Fn>
808
32429
void Environment::SetImmediate(Fn&& cb) {
809
32429
  CreateImmediate(std::move(cb), true);
810
811


32429
  if (immediate_info()->ref_count() == 0)
812
24320
    ToggleImmediateRef(true);
813
32429
  immediate_info()->ref_count_inc(1);
814
32429
}
815
816
template <typename Fn>
817
22359
void Environment::SetUnrefImmediate(Fn&& cb) {
818
22359
  CreateImmediate(std::move(cb), false);
819
22359
}
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
55080
Environment::NativeImmediateCallback::NativeImmediateCallback(bool refed)
845
55080
  : refed_(refed) {}
846
847
110080
bool Environment::NativeImmediateCallback::is_refed() const {
848
110080
  return refed_;
849
}
850
851
std::unique_ptr<Environment::NativeImmediateCallback>
852
55042
Environment::NativeImmediateCallback::get_next() {
853
55042
  return std::move(next_);
854
}
855
856
5542
void Environment::NativeImmediateCallback::set_next(
857
    std::unique_ptr<NativeImmediateCallback> next) {
858
5542
  next_ = std::move(next);
859
5542
}
860
861
template <typename Fn>
862
55080
Environment::NativeImmediateCallbackImpl<Fn>::NativeImmediateCallbackImpl(
863
    Fn&& callback, bool refed)
864
  : NativeImmediateCallback(refed),
865
55080
    callback_(std::move(callback)) {}
866
867
template <typename Fn>
868
54877
void Environment::NativeImmediateCallbackImpl<Fn>::Call(Environment* env) {
869
54877
  callback_(env);
870
54873
}
871
872
2516480
inline bool Environment::can_call_into_js() const {
873

2516480
  return can_call_into_js_ && !is_stopping();
874
}
875
876
4021
inline void Environment::set_can_call_into_js(bool can_call_into_js) {
877
4021
  can_call_into_js_ = can_call_into_js;
878
4023
}
879
880
1181676
inline bool Environment::has_run_bootstrapping_code() const {
881
1181676
  return has_run_bootstrapping_code_;
882
}
883
884
4391
inline void Environment::set_has_run_bootstrapping_code(bool value) {
885
4391
  has_run_bootstrapping_code_ = value;
886
4391
}
887
888
16
inline bool Environment::has_serialized_options() const {
889
16
  return has_serialized_options_;
890
}
891
892
4367
inline void Environment::set_has_serialized_options(bool value) {
893
4367
  has_serialized_options_ = value;
894
4367
}
895
896
25306
inline bool Environment::is_main_thread() const {
897
25306
  return flags_ & kIsMainThread;
898
}
899
900
26106
inline bool Environment::owns_process_state() const {
901
26106
  return flags_ & kOwnsProcessState;
902
}
903
904
4368
inline bool Environment::owns_inspector() const {
905
4368
  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
8286
inline uint64_t Environment::thread_id() const {
917
8286
  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
2516249
inline bool Environment::is_stopping() const {
952
2516249
  return is_stopping_.load();
953
}
954
955
287
inline void Environment::set_stopping(bool value) {
956
287
  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
37196
inline performance::performance_state* Environment::performance_state() {
973
37196
  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
4866707
inline IsolateData* Environment::isolate_data() const {
982
4866707
  return isolate_data_;
983
}
984
985
342384
inline char* Environment::AllocateUnchecked(size_t size) {
986
  return static_cast<char*>(
987
342384
      isolate_data()->allocator()->AllocateUninitialized(size));
988
}
989
990
329041
inline char* Environment::Allocate(size_t size) {
991
329041
  char* ret = AllocateUnchecked(size);
992
329041
  CHECK_NE(ret, nullptr);
993
329041
  return ret;
994
}
995
996
817980
inline void Environment::Free(char* data, size_t size) {
997
817980
  if (data != nullptr)
998
47552
    isolate_data()->allocator()->Free(data, size);
999
817980
}
1000
1001
342384
inline AllocatedBuffer Environment::AllocateManaged(size_t size, bool checked) {
1002
342384
  char* data = checked ? Allocate(size) : AllocateUnchecked(size);
1003
342384
  if (data == nullptr) size = 0;
1004
342384
  return AllocatedBuffer(this, uv_buf_init(data, size));
1005
}
1006
1007
667680
inline AllocatedBuffer::AllocatedBuffer(Environment* env, uv_buf_t buf)
1008
667680
    : env_(env), buffer_(buf) {}
1009
1010
306366
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
306366
  char* new_data = env_->Reallocate(buffer_.base, buffer_.len,
1013
306366
                                    len > 0 ? len : 1);
1014
306366
  CHECK_NOT_NULL(new_data);
1015
306366
  buffer_ = uv_buf_init(new_data, len);
1016
306366
}
1017
1018
1490822
inline uv_buf_t AllocatedBuffer::release() {
1019
1490822
  uv_buf_t ret = buffer_;
1020
1490822
  buffer_ = uv_buf_init(nullptr, 0);
1021
1490822
  return ret;
1022
}
1023
1024
129991
inline char* AllocatedBuffer::data() {
1025
129991
  return buffer_.base;
1026
}
1027
1028
inline const char* AllocatedBuffer::data() const {
1029
  return buffer_.base;
1030
}
1031
1032
352534
inline size_t AllocatedBuffer::size() const {
1033
352534
  return buffer_.len;
1034
}
1035
1036
53188
inline AllocatedBuffer::AllocatedBuffer(Environment* env)
1037
53188
    : env_(env), buffer_(uv_buf_init(nullptr, 0)) {}
1038
1039
602
inline AllocatedBuffer::AllocatedBuffer(AllocatedBuffer&& other)
1040
602
    : AllocatedBuffer() {
1041
602
  *this = std::move(other);
1042
602
}
1043
1044
66430
inline AllocatedBuffer& AllocatedBuffer::operator=(AllocatedBuffer&& other) {
1045
66430
  clear();
1046
66430
  env_ = other.env_;
1047
66430
  buffer_ = other.release();
1048
66430
  return *this;
1049
}
1050
1051
1441534
inline AllocatedBuffer::~AllocatedBuffer() {
1052
720767
  clear();
1053
720767
}
1054
1055
817980
inline void AllocatedBuffer::clear() {
1056
817980
  uv_buf_t buf = release();
1057
817980
  env_->Free(buf.base, buf.len);
1058
817980
}
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
15283
inline v8::MaybeLocal<v8::Object> AllocatedBuffer::ToBuffer() {
1070
15283
  CHECK_NOT_NULL(env_);
1071
15283
  v8::MaybeLocal<v8::Object> obj = Buffer::New(env_, data(), size(), false);
1072
15283
  if (!obj.IsEmpty()) release();
1073
15283
  return obj;
1074
}
1075
1076
280191
inline v8::Local<v8::ArrayBuffer> AllocatedBuffer::ToArrayBuffer() {
1077
280191
  CHECK_NOT_NULL(env_);
1078
280191
  uv_buf_t buf = release();
1079
840405
  auto callback = [](void* data, size_t length, void* deleter_data){
1080
280107
    CHECK_NOT_NULL(deleter_data);
1081
1082
280107
    static_cast<v8::ArrayBuffer::Allocator*>(deleter_data)
1083
280107
        ->Free(data, length);
1084
840405
  };
1085
  std::unique_ptr<v8::BackingStore> backing =
1086
280191
      v8::ArrayBuffer::NewBackingStore(buf.base,
1087
                                       buf.len,
1088
                                       callback,
1089
280191
                                       env_->isolate()
1090
840573
                                          ->GetArrayBufferAllocator());
1091
280191
  return v8::ArrayBuffer::New(env_->isolate(),
1092
840573
                              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
1657111
    Environment::NewFunctionTemplate(v8::FunctionCallback callback,
1133
                                     v8::Local<v8::Signature> signature,
1134
                                     v8::ConstructorBehavior behavior,
1135
                                     v8::SideEffectType side_effect_type) {
1136
1657111
  v8::Local<v8::Object> external = as_callback_data();
1137
  return v8::FunctionTemplate::New(isolate(), callback, external,
1138
1657111
                                   signature, 0, behavior, side_effect_type);
1139
}
1140
1141
652300
inline void Environment::SetMethod(v8::Local<v8::Object> that,
1142
                                   const char* name,
1143
                                   v8::FunctionCallback callback) {
1144
652300
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
1145
  v8::Local<v8::Function> function =
1146
1304599
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1147
                          v8::ConstructorBehavior::kThrow,
1148
652298
                          v8::SideEffectType::kHasSideEffect)
1149
1304599
          ->GetFunction(context)
1150
652298
          .ToLocalChecked();
1151
  // kInternalized strings are created in the old space.
1152
652298
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1153
  v8::Local<v8::String> name_string =
1154
1304598
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1155
1304601
  that->Set(context, name_string, function).Check();
1156
652301
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1157
652300
}
1158
1159
293270
inline void Environment::SetMethodNoSideEffect(v8::Local<v8::Object> that,
1160
                                               const char* name,
1161
                                               v8::FunctionCallback callback) {
1162
293270
  v8::Local<v8::Context> context = isolate()->GetCurrentContext();
1163
  v8::Local<v8::Function> function =
1164
586540
      NewFunctionTemplate(callback, v8::Local<v8::Signature>(),
1165
                          v8::ConstructorBehavior::kThrow,
1166
293270
                          v8::SideEffectType::kHasNoSideEffect)
1167
586540
          ->GetFunction(context)
1168
293270
          .ToLocalChecked();
1169
  // kInternalized strings are created in the old space.
1170
293270
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1171
  v8::Local<v8::String> name_string =
1172
586539
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1173
586539
  that->Set(context, name_string, function).Check();
1174
293270
  function->SetName(name_string);  // NODE_SET_METHOD() compatibility.
1175
293270
}
1176
1177
488292
inline void Environment::SetProtoMethod(v8::Local<v8::FunctionTemplate> that,
1178
                                        const char* name,
1179
                                        v8::FunctionCallback callback) {
1180
488292
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1181
  v8::Local<v8::FunctionTemplate> t =
1182
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1183
488292
                          v8::SideEffectType::kHasSideEffect);
1184
  // kInternalized strings are created in the old space.
1185
488292
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1186
  v8::Local<v8::String> name_string =
1187
976584
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1188
976584
  that->PrototypeTemplate()->Set(name_string, t);
1189
488292
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1190
488292
}
1191
1192
47011
inline void Environment::SetProtoMethodNoSideEffect(
1193
    v8::Local<v8::FunctionTemplate> that,
1194
    const char* name,
1195
    v8::FunctionCallback callback) {
1196
47011
  v8::Local<v8::Signature> signature = v8::Signature::New(isolate(), that);
1197
  v8::Local<v8::FunctionTemplate> t =
1198
      NewFunctionTemplate(callback, signature, v8::ConstructorBehavior::kThrow,
1199
47011
                          v8::SideEffectType::kHasNoSideEffect);
1200
  // kInternalized strings are created in the old space.
1201
47011
  const v8::NewStringType type = v8::NewStringType::kInternalized;
1202
  v8::Local<v8::String> name_string =
1203
94022
      v8::String::NewFromUtf8(isolate(), name, type).ToLocalChecked();
1204
94022
  that->PrototypeTemplate()->Set(name_string, t);
1205
47011
  t->SetClassName(name_string);  // NODE_SET_PROTOTYPE_METHOD() compatibility.
1206
47011
}
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
569185
void Environment::AddCleanupHook(void (*fn)(void*), void* arg) {
1224
1138376
  auto insertion_info = cleanup_hooks_.emplace(CleanupHookCallback {
1225
569185
    fn, arg, cleanup_hook_counter_++
1226
569185
  });
1227
  // Make sure there was no existing element with these values.
1228
569191
  CHECK_EQ(insertion_info.second, true);
1229
569191
}
1230
1231
559692
void Environment::RemoveCleanupHook(void (*fn)(void*), void* arg) {
1232
559692
  CleanupHookCallback search { fn, arg, 0 };
1233
559691
  cleanup_hooks_.erase(search);
1234
559695
}
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
1303653
size_t CleanupHookCallback::Hash::operator()(
1243
    const CleanupHookCallback& cb) const {
1244
1303653
  return std::hash<void*>()(cb.arg_);
1245
}
1246
1247
650907
bool CleanupHookCallback::Equal::operator()(
1248
    const CleanupHookCallback& a, const CleanupHookCallback& b) const {
1249

650907
  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
1123488
void Environment::modify_base_object_count(int64_t delta) {
1269
1123488
  base_object_count_ += delta;
1270
1123488
}
1271
1272
4003
int64_t Environment::base_object_count() const {
1273
4003
  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
26344
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1286
574884
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1287
5498806
  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
13172
  PER_ISOLATE_PRIVATE_SYMBOL_PROPERTIES(VP)
1301
287285
  PER_ISOLATE_SYMBOL_PROPERTIES(VY)
1302
2745429
  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
405891
  ENVIRONMENT_STRONG_PERSISTENT_TEMPLATES(V)
1316
5226170
  ENVIRONMENT_STRONG_PERSISTENT_VALUES(V)
1317
#undef V
1318
1319
10716001
  inline v8::Local<v8::Context> Environment::context() const {
1320
10716001
    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_