GCC Code Coverage Report
Directory: ../ Exec Total Coverage
File: /home/iojs/build/workspace/node-test-commit-linux-coverage-daily/nodes/benchmark/out/../src/node_process_methods.cc Lines: 232 251 92.4 %
Date: 2020-06-24 22:13:30 Branches: 68 102 66.7 %

Line Branch Exec Source
1
#include "base_object-inl.h"
2
#include "debug_utils-inl.h"
3
#include "env-inl.h"
4
#include "memory_tracker-inl.h"
5
#include "node.h"
6
#include "node_errors.h"
7
#include "node_internals.h"
8
#include "node_process.h"
9
#include "util-inl.h"
10
#include "uv.h"
11
#include "v8-fast-api-calls.h"
12
#include "v8.h"
13
14
#include <vector>
15
16
#if HAVE_INSPECTOR
17
#include "inspector_io.h"
18
#endif
19
20
#include <climits>  // PATH_MAX
21
#include <cstdio>
22
23
#if defined(_MSC_VER)
24
#include <direct.h>
25
#include <io.h>
26
#define umask _umask
27
typedef int mode_t;
28
#else
29
#include <pthread.h>
30
#include <sys/resource.h>  // getrlimit, setrlimit
31
#include <termios.h>  // tcgetattr, tcsetattr
32
#endif
33
34
namespace node {
35
36
using v8::Array;
37
using v8::ArrayBuffer;
38
using v8::BackingStore;
39
using v8::Context;
40
using v8::Float64Array;
41
using v8::FunctionCallbackInfo;
42
using v8::HeapStatistics;
43
using v8::Integer;
44
using v8::Isolate;
45
using v8::Local;
46
using v8::NewStringType;
47
using v8::Number;
48
using v8::Object;
49
using v8::String;
50
using v8::Uint32;
51
using v8::Value;
52
53
namespace per_process {
54
4399
Mutex umask_mutex;
55
}   // namespace per_process
56
57
// Microseconds in a second, as a float, used in CPUUsage() below
58
#define MICROS_PER_SEC 1e6
59
// used in Hrtime() and Uptime() below
60
#define NANOS_PER_SEC 1000000000
61
62
static void Abort(const FunctionCallbackInfo<Value>& args) {
63
  Abort();
64
}
65
66
// For internal testing only, not exposed to userland.
67
static void CauseSegfault(const FunctionCallbackInfo<Value>& args) {
68
  // This should crash hard all platforms.
69
  volatile void** d = static_cast<volatile void**>(nullptr);
70
  *d = nullptr;
71
}
72
73
399
static void Chdir(const FunctionCallbackInfo<Value>& args) {
74
399
  Environment* env = Environment::GetCurrent(args);
75
399
  CHECK(env->owns_process_state());
76
77
399
  CHECK_EQ(args.Length(), 1);
78
1197
  CHECK(args[0]->IsString());
79
797
  Utf8Value path(env->isolate(), args[0]);
80
399
  int err = uv_chdir(*path);
81
399
  if (err) {
82
    // Also include the original working directory, since that will usually
83
    // be helpful information when debugging a `chdir()` failure.
84
    char buf[PATH_MAX_BYTES];
85
1
    size_t cwd_len = sizeof(buf);
86
1
    uv_cwd(buf, &cwd_len);
87
1
    return env->ThrowUVException(err, "chdir", nullptr, buf, *path);
88
  }
89
}
90
91
// CPUUsage use libuv's uv_getrusage() this-process resource usage accessor,
92
// to access ru_utime (user CPU time used) and ru_stime (system CPU time used),
93
// which are uv_timeval_t structs (long tv_sec, long tv_usec).
94
// Returns those values as Float64 microseconds in the elements of the array
95
// passed to the function.
96
33
static void CPUUsage(const FunctionCallbackInfo<Value>& args) {
97
  uv_rusage_t rusage;
98
99
  // Call libuv to get the values we'll return.
100
33
  int err = uv_getrusage(&rusage);
101
33
  if (err) {
102
    // On error, return the strerror version of the error code.
103
    Local<String> errmsg = OneByteString(args.GetIsolate(), uv_strerror(err));
104
    return args.GetReturnValue().Set(errmsg);
105
  }
106
107
  // Get the double array pointer from the Float64Array argument.
108
66
  CHECK(args[0]->IsFloat64Array());
109
66
  Local<Float64Array> array = args[0].As<Float64Array>();
110
33
  CHECK_EQ(array->Length(), 2);
111
33
  Local<ArrayBuffer> ab = array->Buffer();
112
33
  double* fields = static_cast<double*>(ab->GetBackingStore()->Data());
113
114
  // Set the Float64Array elements to be user / system values in microseconds.
115
33
  fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
116
33
  fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
117
}
118
119
5144
static void Cwd(const FunctionCallbackInfo<Value>& args) {
120
5144
  Environment* env = Environment::GetCurrent(args);
121
5144
  CHECK(env->has_run_bootstrapping_code());
122
  char buf[PATH_MAX_BYTES];
123
5144
  size_t cwd_len = sizeof(buf);
124
5144
  int err = uv_cwd(buf, &cwd_len);
125
5144
  if (err)
126
12
    return env->ThrowUVException(err, "uv_cwd");
127
128
10264
  Local<String> cwd = String::NewFromUtf8(env->isolate(),
129
                                          buf,
130
                                          NewStringType::kNormal,
131
10264
                                          cwd_len).ToLocalChecked();
132
10264
  args.GetReturnValue().Set(cwd);
133
}
134
135
63
static void Kill(const FunctionCallbackInfo<Value>& args) {
136
63
  Environment* env = Environment::GetCurrent(args);
137
63
  Local<Context> context = env->context();
138
139
63
  if (args.Length() != 2)
140
    return env->ThrowError("Bad argument.");
141
142
  int pid;
143
189
  if (!args[0]->Int32Value(context).To(&pid)) return;
144
  int sig;
145
189
  if (!args[1]->Int32Value(context).To(&sig)) return;
146
147
63
  uv_pid_t own_pid = uv_os_getpid();
148

187
  if (sig > 0 &&
149


150
      (pid == 0 || pid == -1 || pid == own_pid || pid == -own_pid) &&
150
27
      !HasSignalJSHandler(sig)) {
151
    // This is most likely going to terminate this process.
152
    // It's not an exact method but it might be close enough.
153
18
    RunAtExit(env);
154
  }
155
156
63
  int err = uv_kill(pid, sig);
157
126
  args.GetReturnValue().Set(err);
158
}
159
160
527
static void MemoryUsage(const FunctionCallbackInfo<Value>& args) {
161
527
  Environment* env = Environment::GetCurrent(args);
162
163
  size_t rss;
164
527
  int err = uv_resident_set_memory(&rss);
165
527
  if (err)
166
    return env->ThrowUVException(err, "uv_resident_set_memory");
167
168
527
  Isolate* isolate = env->isolate();
169
  // V8 memory usage
170
527
  HeapStatistics v8_heap_stats;
171
527
  isolate->GetHeapStatistics(&v8_heap_stats);
172
173
  NodeArrayBufferAllocator* array_buffer_allocator =
174
527
      env->isolate_data()->node_allocator();
175
176
  // Get the double array pointer from the Float64Array argument.
177
1054
  CHECK(args[0]->IsFloat64Array());
178
1054
  Local<Float64Array> array = args[0].As<Float64Array>();
179
527
  CHECK_EQ(array->Length(), 5);
180
527
  Local<ArrayBuffer> ab = array->Buffer();
181
527
  double* fields = static_cast<double*>(ab->GetBackingStore()->Data());
182
183
527
  fields[0] = rss;
184
527
  fields[1] = v8_heap_stats.total_heap_size();
185
527
  fields[2] = v8_heap_stats.used_heap_size();
186
527
  fields[3] = v8_heap_stats.external_memory();
187
1054
  fields[4] = array_buffer_allocator == nullptr ?
188
527
      0 : array_buffer_allocator->total_mem_usage();
189
}
190
191
13
void RawDebug(const FunctionCallbackInfo<Value>& args) {
192


52
  CHECK(args.Length() == 1 && args[0]->IsString() &&
193
        "must be called with a single string");
194
26
  Utf8Value message(args.GetIsolate(), args[0]);
195
13
  FPrintF(stderr, "%s\n", message);
196
13
  fflush(stderr);
197
13
}
198
199
static void StartProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
200
  Environment* env = Environment::GetCurrent(args);
201
  env->StartProfilerIdleNotifier();
202
}
203
204
static void StopProfilerIdleNotifier(const FunctionCallbackInfo<Value>& args) {
205
  Environment* env = Environment::GetCurrent(args);
206
  env->StopProfilerIdleNotifier();
207
}
208
209
3801
static void Umask(const FunctionCallbackInfo<Value>& args) {
210
3801
  Environment* env = Environment::GetCurrent(args);
211
3801
  CHECK(env->has_run_bootstrapping_code());
212
3801
  CHECK_EQ(args.Length(), 1);
213

18645
  CHECK(args[0]->IsUndefined() || args[0]->IsUint32());
214
7602
  Mutex::ScopedLock scoped_lock(per_process::umask_mutex);
215
216
  uint32_t old;
217
11403
  if (args[0]->IsUndefined()) {
218
180
    if (env->emit_insecure_umask_warning()) {
219
5
      env->set_emit_insecure_umask_warning(false);
220
10
      if (ProcessEmitDeprecationWarning(
221
              env,
222
              "Calling process.umask() with no arguments is prone to race "
223
              "conditions and is a potential security vulnerability.",
224
              "DEP0139").IsNothing()) {
225
        return;
226
      }
227
    }
228
229
180
    old = umask(0);
230
180
    umask(static_cast<mode_t>(old));
231
  } else {
232
10863
    int oct = args[0].As<Uint32>()->Value();
233
3621
    old = umask(static_cast<mode_t>(oct));
234
  }
235
236
7602
  args.GetReturnValue().Set(old);
237
}
238
239
4
static void Uptime(const FunctionCallbackInfo<Value>& args) {
240
4
  Environment* env = Environment::GetCurrent(args);
241
242
4
  uv_update_time(env->event_loop());
243
  double uptime =
244
4
      static_cast<double>(uv_hrtime() - per_process::node_start_time);
245
4
  Local<Number> result = Number::New(env->isolate(), uptime / NANOS_PER_SEC);
246
8
  args.GetReturnValue().Set(result);
247
4
}
248
249
1
static void GetActiveRequests(const FunctionCallbackInfo<Value>& args) {
250
1
  Environment* env = Environment::GetCurrent(args);
251
252
2
  std::vector<Local<Value>> request_v;
253
13
  for (ReqWrapBase* req_wrap : *env->req_wrap_queue()) {
254
12
    AsyncWrap* w = req_wrap->GetAsyncWrap();
255
24
    if (w->persistent().IsEmpty())
256
      continue;
257
12
    request_v.emplace_back(w->GetOwner());
258
  }
259
260
3
  args.GetReturnValue().Set(
261
      Array::New(env->isolate(), request_v.data(), request_v.size()));
262
1
}
263
264
// Non-static, friend of HandleWrap. Could have been a HandleWrap method but
265
// implemented here for consistency with GetActiveRequests().
266
4
void GetActiveHandles(const FunctionCallbackInfo<Value>& args) {
267
4
  Environment* env = Environment::GetCurrent(args);
268
269
8
  std::vector<Local<Value>> handle_v;
270
24
  for (auto w : *env->handle_wrap_queue()) {
271
20
    if (!HandleWrap::HasRef(w))
272
1
      continue;
273
19
    handle_v.emplace_back(w->GetOwner());
274
  }
275
12
  args.GetReturnValue().Set(
276
      Array::New(env->isolate(), handle_v.data(), handle_v.size()));
277
4
}
278
279
1
static void ResourceUsage(const FunctionCallbackInfo<Value>& args) {
280
1
  Environment* env = Environment::GetCurrent(args);
281
282
  uv_rusage_t rusage;
283
1
  int err = uv_getrusage(&rusage);
284
1
  if (err)
285
    return env->ThrowUVException(err, "uv_getrusage");
286
287
2
  CHECK(args[0]->IsFloat64Array());
288
2
  Local<Float64Array> array = args[0].As<Float64Array>();
289
1
  CHECK_EQ(array->Length(), 16);
290
1
  Local<ArrayBuffer> ab = array->Buffer();
291
1
  double* fields = static_cast<double*>(ab->GetBackingStore()->Data());
292
293
1
  fields[0] = MICROS_PER_SEC * rusage.ru_utime.tv_sec + rusage.ru_utime.tv_usec;
294
1
  fields[1] = MICROS_PER_SEC * rusage.ru_stime.tv_sec + rusage.ru_stime.tv_usec;
295
1
  fields[2] = rusage.ru_maxrss;
296
1
  fields[3] = rusage.ru_ixrss;
297
1
  fields[4] = rusage.ru_idrss;
298
1
  fields[5] = rusage.ru_isrss;
299
1
  fields[6] = rusage.ru_minflt;
300
1
  fields[7] = rusage.ru_majflt;
301
1
  fields[8] = rusage.ru_nswap;
302
1
  fields[9] = rusage.ru_inblock;
303
1
  fields[10] = rusage.ru_oublock;
304
1
  fields[11] = rusage.ru_msgsnd;
305
1
  fields[12] = rusage.ru_msgrcv;
306
1
  fields[13] = rusage.ru_nsignals;
307
1
  fields[14] = rusage.ru_nvcsw;
308
1
  fields[15] = rusage.ru_nivcsw;
309
}
310
311
#ifdef __POSIX__
312
3
static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
313
3
  Environment* env = Environment::GetCurrent(args);
314
315
3
  if (args.Length() != 1) {
316
    return env->ThrowError("Invalid number of arguments.");
317
  }
318
319
6
  CHECK(args[0]->IsNumber());
320
9
  pid_t pid = args[0].As<Integer>()->Value();
321
3
  int r = kill(pid, SIGUSR1);
322
323
3
  if (r != 0) {
324
1
    return env->ThrowErrnoException(errno, "kill");
325
  }
326
}
327
#endif  // __POSIX__
328
329
#ifdef _WIN32
330
static int GetDebugSignalHandlerMappingName(DWORD pid,
331
                                            wchar_t* buf,
332
                                            size_t buf_len) {
333
  return _snwprintf(buf, buf_len, L"node-debug-handler-%u", pid);
334
}
335
336
static void DebugProcess(const FunctionCallbackInfo<Value>& args) {
337
  Environment* env = Environment::GetCurrent(args);
338
  Isolate* isolate = args.GetIsolate();
339
340
  if (args.Length() != 1) {
341
    env->ThrowError("Invalid number of arguments.");
342
    return;
343
  }
344
345
  HANDLE process = nullptr;
346
  HANDLE thread = nullptr;
347
  HANDLE mapping = nullptr;
348
  wchar_t mapping_name[32];
349
  LPTHREAD_START_ROUTINE* handler = nullptr;
350
  DWORD pid = 0;
351
352
  auto cleanup = OnScopeLeave([&]() {
353
    if (process != nullptr) CloseHandle(process);
354
    if (thread != nullptr) CloseHandle(thread);
355
    if (handler != nullptr) UnmapViewOfFile(handler);
356
    if (mapping != nullptr) CloseHandle(mapping);
357
  });
358
359
  CHECK(args[0]->IsNumber());
360
  pid = args[0].As<Integer>()->Value();
361
362
  process =
363
      OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION |
364
                      PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
365
                  FALSE,
366
                  pid);
367
  if (process == nullptr) {
368
    isolate->ThrowException(
369
        WinapiErrnoException(isolate, GetLastError(), "OpenProcess"));
370
    return;
371
  }
372
373
  if (GetDebugSignalHandlerMappingName(
374
          pid, mapping_name, arraysize(mapping_name)) < 0) {
375
    env->ThrowErrnoException(errno, "sprintf");
376
    return;
377
  }
378
379
  mapping = OpenFileMappingW(FILE_MAP_READ, FALSE, mapping_name);
380
  if (mapping == nullptr) {
381
    isolate->ThrowException(
382
        WinapiErrnoException(isolate, GetLastError(), "OpenFileMappingW"));
383
    return;
384
  }
385
386
  handler = reinterpret_cast<LPTHREAD_START_ROUTINE*>(
387
      MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, sizeof *handler));
388
  if (handler == nullptr || *handler == nullptr) {
389
    isolate->ThrowException(
390
        WinapiErrnoException(isolate, GetLastError(), "MapViewOfFile"));
391
    return;
392
  }
393
394
  thread =
395
      CreateRemoteThread(process, nullptr, 0, *handler, nullptr, 0, nullptr);
396
  if (thread == nullptr) {
397
    isolate->ThrowException(
398
        WinapiErrnoException(isolate, GetLastError(), "CreateRemoteThread"));
399
    return;
400
  }
401
402
  // Wait for the thread to terminate
403
  if (WaitForSingleObject(thread, INFINITE) != WAIT_OBJECT_0) {
404
    isolate->ThrowException(
405
        WinapiErrnoException(isolate, GetLastError(), "WaitForSingleObject"));
406
    return;
407
  }
408
}
409
#endif  // _WIN32
410
411
5
static void DebugEnd(const FunctionCallbackInfo<Value>& args) {
412
#if HAVE_INSPECTOR
413
5
  Environment* env = Environment::GetCurrent(args);
414
5
  if (env->inspector_agent()->IsListening()) {
415
4
    env->inspector_agent()->Stop();
416
  }
417
#endif
418
5
}
419
420
301
static void ReallyExit(const FunctionCallbackInfo<Value>& args) {
421
301
  Environment* env = Environment::GetCurrent(args);
422
301
  RunAtExit(env);
423
1204
  int code = args[0]->Int32Value(env->context()).FromMaybe(0);
424
301
  env->Exit(code);
425
44
}
426
427
12697
class FastHrtime : public BaseObject {
428
 public:
429
4703
  static Local<Object> New(Environment* env) {
430
    Local<v8::FunctionTemplate> ctor =
431
4703
        v8::FunctionTemplate::New(env->isolate());
432
9406
    ctor->Inherit(BaseObject::GetConstructorTemplate(env));
433
4703
    Local<v8::ObjectTemplate> otmpl = ctor->InstanceTemplate();
434
4703
    otmpl->SetInternalFieldCount(FastHrtime::kInternalFieldCount);
435
436
18812
    auto create_func = [env](auto fast_func, auto slow_func) {
437
9406
      auto cfunc = v8::CFunction::Make(fast_func);
438
18812
      return v8::FunctionTemplate::New(env->isolate(),
439
                                       slow_func,
440
                                       Local<Value>(),
441
                                       Local<v8::Signature>(),
442
                                       0,
443
                                       v8::ConstructorBehavior::kThrow,
444
                                       v8::SideEffectType::kHasNoSideEffect,
445
18812
                                       &cfunc);
446
4703
    };
447
448
18812
    otmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "hrtime"),
449
4703
               create_func(FastNumber, SlowNumber));
450
18812
    otmpl->Set(FIXED_ONE_BYTE_STRING(env->isolate(), "hrtimeBigInt"),
451
4703
               create_func(FastBigInt, SlowBigInt));
452
453
14109
    Local<Object> obj = otmpl->NewInstance(env->context()).ToLocalChecked();
454
455
    Local<ArrayBuffer> ab =
456
        ArrayBuffer::New(env->isolate(),
457
4703
            std::max(sizeof(uint64_t), sizeof(uint32_t) * 3));
458
4703
    new FastHrtime(env, obj, ab);
459
9406
    obj->Set(
460
18812
           env->context(), FIXED_ONE_BYTE_STRING(env->isolate(), "buffer"), ab)
461
        .ToChecked();
462
463
4703
    return obj;
464
  }
465
466
 private:
467
4703
  FastHrtime(Environment* env,
468
             Local<Object> object,
469
             Local<ArrayBuffer> ab)
470
4703
      : BaseObject(env, object),
471
        array_buffer_(env->isolate(), ab),
472
9406
        backing_store_(ab->GetBackingStore()) {
473
4703
    MakeWeak();
474
4703
  }
475
476
19
  void MemoryInfo(MemoryTracker* tracker) const override {
477
19
    tracker->TrackField("array_buffer", array_buffer_);
478
19
  }
479
19
  SET_MEMORY_INFO_NAME(FastHrtime)
480
19
  SET_SELF_SIZE(FastHrtime)
481
482
  // This is the legacy version of hrtime before BigInt was introduced in
483
  // JavaScript.
484
  // The value returned by uv_hrtime() is a 64-bit int representing nanoseconds,
485
  // so this function instead fills in an Uint32Array with 3 entries,
486
  // to avoid any integer overflow possibility.
487
  // The first two entries contain the second part of the value
488
  // broken into the upper/lower 32 bits to be converted back in JS,
489
  // because there is no Uint64Array in JS.
490
  // The third entry contains the remaining nanosecond part of the value.
491
83149
  static void FastNumber(FastHrtime* receiver) {
492
83149
    uint64_t t = uv_hrtime();
493
83149
    uint32_t* fields = static_cast<uint32_t*>(receiver->backing_store_->Data());
494
83149
    fields[0] = (t / NANOS_PER_SEC) >> 32;
495
83149
    fields[1] = (t / NANOS_PER_SEC) & 0xffffffff;
496
83149
    fields[2] = t % NANOS_PER_SEC;
497
83149
  }
498
499
83149
  static void SlowNumber(const FunctionCallbackInfo<Value>& args) {
500
83149
    FastNumber(FromJSObject<FastHrtime>(args.Holder()));
501
83149
  }
502
503
1210950
  static void FastBigInt(FastHrtime* receiver) {
504
1210950
    uint64_t t = uv_hrtime();
505
1210950
    uint64_t* fields = static_cast<uint64_t*>(receiver->backing_store_->Data());
506
1210950
    fields[0] = t;
507
1210950
  }
508
509
1210950
  static void SlowBigInt(const FunctionCallbackInfo<Value>& args) {
510
1210950
    FastBigInt(FromJSObject<FastHrtime>(args.Holder()));
511
1210950
  }
512
513
  v8::Global<ArrayBuffer> array_buffer_;
514
  std::shared_ptr<BackingStore> backing_store_;
515
};
516
517
4703
static void InitializeProcessMethods(Local<Object> target,
518
                                     Local<Value> unused,
519
                                     Local<Context> context,
520
                                     void* priv) {
521
4703
  Environment* env = Environment::GetCurrent(context);
522
523
  // define various internal methods
524
4703
  if (env->owns_process_state()) {
525
4366
    env->SetMethod(target, "_debugProcess", DebugProcess);
526
4366
    env->SetMethod(target, "_debugEnd", DebugEnd);
527
4366
    env->SetMethod(target, "abort", Abort);
528
4366
    env->SetMethod(target, "causeSegfault", CauseSegfault);
529
4366
    env->SetMethod(target, "chdir", Chdir);
530
  }
531
532
  env->SetMethod(
533
4703
      target, "_startProfilerIdleNotifier", StartProfilerIdleNotifier);
534
4703
  env->SetMethod(target, "_stopProfilerIdleNotifier", StopProfilerIdleNotifier);
535
536
4703
  env->SetMethod(target, "umask", Umask);
537
4703
  env->SetMethod(target, "_rawDebug", RawDebug);
538
4703
  env->SetMethod(target, "memoryUsage", MemoryUsage);
539
4703
  env->SetMethod(target, "cpuUsage", CPUUsage);
540
4703
  env->SetMethod(target, "resourceUsage", ResourceUsage);
541
542
4703
  env->SetMethod(target, "_getActiveRequests", GetActiveRequests);
543
4703
  env->SetMethod(target, "_getActiveHandles", GetActiveHandles);
544
4703
  env->SetMethod(target, "_kill", Kill);
545
546
4703
  env->SetMethodNoSideEffect(target, "cwd", Cwd);
547
4703
  env->SetMethod(target, "dlopen", binding::DLOpen);
548
4703
  env->SetMethod(target, "reallyExit", ReallyExit);
549
4703
  env->SetMethodNoSideEffect(target, "uptime", Uptime);
550
4703
  env->SetMethod(target, "patchProcessObject", PatchProcessObject);
551
552
  target
553
9406
      ->Set(env->context(),
554
            FIXED_ONE_BYTE_STRING(env->isolate(), "hrtime"),
555
23515
            FastHrtime::New(env))
556
      .ToChecked();
557
4703
}
558
559
}  // namespace node
560
561
namespace v8 {
562
template <>
563
class WrapperTraits<node::FastHrtime> {
564
 public:
565
4337
  static const void* GetTypeInfo() {
566
    static const int tag = 0;
567
4337
    return reinterpret_cast<const void*>(&tag);
568
  }
569
};
570
}  // namespace v8
571
572

17595
NODE_MODULE_CONTEXT_AWARE_INTERNAL(process_methods,
573
                                   node::InitializeProcessMethods)