-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgctime.cc
96 lines (72 loc) · 2.39 KB
/
gctime.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <nan.h>
using namespace v8;
#define NANOS_PER_SEC 1000000000
namespace gctime {
uint64_t start = 0;
uint64_t min = 0;
uint64_t max = 0;
uint64_t sum = 0;
uint32_t size = 0;
bool listening = false;
NAN_GC_CALLBACK(Prologue) {
start = uv_hrtime();
}
NAN_GC_CALLBACK(Epilogue) {
uint64_t duration = uv_hrtime() - start;
start = 0;
if (duration < min || size == 0) min = duration;
if (duration > max || size == 0) max = duration;
sum+= duration;
size++;
}
static void ResetStatistics() {
min = 0;
max = 0;
sum = 0;
size = 0;
}
NAN_METHOD(Start) {
if (listening) {
return Nan::ThrowError("Already started");
}
ResetStatistics();
listening = true;
Nan::AddGCPrologueCallback(Prologue);
Nan::AddGCEpilogueCallback(Epilogue);
}
NAN_METHOD(Transfer) {
// Lifted from Node's process.hrtime, avoids integer overflow.
Local<ArrayBuffer> ab = info[0].As<Uint32Array>()->Buffer();
uint32_t* fields = static_cast<uint32_t*>(ab->GetContents().Data());
// The first two entries contain seconds broken into upper/lower
// 32 bits. The third entry contains the remaining nanoseconds.
fields[0] = (min / NANOS_PER_SEC) >> 32;
fields[1] = (min / NANOS_PER_SEC) & 0xffffffff;
fields[2] = (min % NANOS_PER_SEC);
fields[3] = (max / NANOS_PER_SEC) >> 32;
fields[4] = (max / NANOS_PER_SEC) & 0xffffffff;
fields[5] = (max % NANOS_PER_SEC);
fields[6] = (sum / NANOS_PER_SEC) >> 32;
fields[7] = (sum / NANOS_PER_SEC) & 0xffffffff;
fields[8] = (sum % NANOS_PER_SEC);
fields[9] = size;
ResetStatistics();
}
NAN_METHOD(Stop) {
if (!listening) {
return Nan::ThrowError("Already stopped");
}
listening = false;
Nan::RemoveGCPrologueCallback(Prologue);
Nan::RemoveGCEpilogueCallback(Epilogue);
}
NAN_MODULE_INIT(Init) {
Local<Function> start = Nan::GetFunction(Nan::New<FunctionTemplate>(Start)).ToLocalChecked();
Nan::Set(target, Nan::New("start").ToLocalChecked(), start);
Local<Function> transfer = Nan::GetFunction(Nan::New<FunctionTemplate>(Transfer)).ToLocalChecked();
Nan::Set(target, Nan::New("transfer").ToLocalChecked(), transfer);
Local<Function> stop = Nan::GetFunction(Nan::New<FunctionTemplate>(Stop)).ToLocalChecked();
Nan::Set(target, Nan::New("stop").ToLocalChecked(), stop);
}
NODE_MODULE(gctime, Init)
}