Skip to content

Commit a694680

Browse files
committed
Move GetAsyncId and GC callbacks out of the header file.
Use relaxed load/store with appropriate signal fences for cheaper reading/writing of gcCount.
1 parent bb0bc2d commit a694680

File tree

2 files changed

+40
-24
lines changed

2 files changed

+40
-24
lines changed

bindings/profilers/wall.cc

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ WallProfiler::WallProfiler(std::chrono::microseconds samplingPeriod,
531531

532532
curContext_.store(&context1_, std::memory_order_relaxed);
533533
collectionMode_.store(CollectionMode::kNoCollect, std::memory_order_relaxed);
534+
gcCount.store(0, std::memory_order_relaxed);
534535

535536
// TODO: bind to this isolate? Would fix the Dispose(nullptr) issue.
536537
auto isolate = v8::Isolate::GetCurrent();
@@ -543,7 +544,6 @@ WallProfiler::WallProfiler(std::chrono::microseconds samplingPeriod,
543544
jsArray_ = v8::Global<v8::Uint32Array>(isolate, jsArray);
544545
std::fill(fields_, fields_ + kFieldCount, 0);
545546

546-
gcCount = 0;
547547
isolate->AddGCPrologueCallback(&GCPrologueCallback, this);
548548
isolate->AddGCEpilogueCallback(&GCEpilogueCallback, this);
549549
}
@@ -1044,6 +1044,42 @@ NAN_METHOD(WallProfiler::Dispose) {
10441044
delete profiler;
10451045
}
10461046

1047+
int64_t GetAsyncIdNoGC(v8::Isolate* isolate) {
1048+
return isolate->InContext()
1049+
? static_cast<int64_t>(
1050+
node::AsyncHooksGetExecutionAsyncId(isolate))
1051+
: -1;
1052+
}
1053+
1054+
int64_t WallProfiler::GetAsyncId(v8::Isolate* isolate) {
1055+
auto curGcCount = gcCount.load(std::memory_order_relaxed);
1056+
std::atomic_signal_fence(std::memory_order_acquire);
1057+
if (curGcCount > 0) {
1058+
return gcAsyncId;
1059+
}
1060+
return GetAsyncIdNoGC(isolate);
1061+
}
1062+
1063+
void WallProfiler::OnGCStart(v8::Isolate* isolate) {
1064+
auto curCount = gcCount.load(std::memory_order_relaxed);
1065+
std::atomic_signal_fence(std::memory_order_acquire);
1066+
if (curCount == 0) {
1067+
gcAsyncId = GetAsyncIdNoGC(isolate);
1068+
}
1069+
gcCount.store(curCount + 1, std::memory_order_relaxed);
1070+
std::atomic_signal_fence(std::memory_order_release);
1071+
}
1072+
1073+
void WallProfiler::OnGCEnd() {
1074+
auto newCount = gcCount.load(std::memory_order_relaxed) - 1;
1075+
std::atomic_signal_fence(std::memory_order_acquire);
1076+
gcCount.store(newCount, std::memory_order_relaxed);
1077+
std::atomic_signal_fence(std::memory_order_release);
1078+
if (newCount == 0) {
1079+
gcAsyncId = -1;
1080+
}
1081+
}
1082+
10471083
void WallProfiler::PushContext(int64_t time_from,
10481084
int64_t time_to,
10491085
int64_t cpu_time,

bindings/profilers/wall.hh

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -152,29 +152,9 @@ class WallProfiler : public Nan::ObjectWrap {
152152
return threadCpuStopWatch_.GetAndReset();
153153
}
154154

155-
int64_t GetAsyncId(v8::Isolate* isolate) const {
156-
if (gcCount > 0) {
157-
return gcAsyncId;
158-
} else if (isolate->InContext()) {
159-
return static_cast<int64_t>(node::AsyncHooksGetExecutionAsyncId(isolate));
160-
}
161-
return -1;
162-
}
163-
164-
void OnGCStart(v8::Isolate* isolate) {
165-
if (gcCount == 0) {
166-
gcAsyncId = GetAsyncId(isolate);
167-
gcCount = 1;
168-
} else {
169-
++gcCount;
170-
}
171-
}
172-
173-
void OnGCEnd() {
174-
if (--gcCount == 0) {
175-
gcAsyncId = -1;
176-
}
177-
}
155+
int64_t GetAsyncId(v8::Isolate* isolate);
156+
void OnGCStart(v8::Isolate* isolate);
157+
void OnGCEnd();
178158

179159
static NAN_METHOD(New) GENERAL_REGS_ONLY;
180160
static NAN_METHOD(Start);

0 commit comments

Comments
 (0)