Skip to content

Commit 70ddf36

Browse files
committed
src: keep track of env properly in node_perf.cc
Currently, measuring GC timing using `node_perf` is somewhat broken, because Isolates and Node Environments do not necessarily match 1:1; each environment adds its own hook, so possibly the hook code runs multiple times, but since it can’t reliably compute its corresponding event loop based on the Isolate, each run targets the same Environment right now. This fixes that problem by using new overloads of the GC tracking APIs that can pass data to the callback through opaque pointers.
1 parent c82d22e commit 70ddf36

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

src/node_perf.cc

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -174,13 +174,14 @@ void SetupPerformanceObservers(const FunctionCallbackInfo<Value>& args) {
174174
env->set_performance_entry_callback(args[0].As<Function>());
175175
}
176176

177-
inline void PerformanceGCCallback(uv_async_t* handle) {
177+
void PerformanceGCCallback(uv_async_t* handle) {
178178
PerformanceEntry::Data* data =
179179
static_cast<PerformanceEntry::Data*>(handle->data);
180-
Isolate* isolate = Isolate::GetCurrent();
180+
Environment* env = data->env();
181+
Isolate* isolate = env->isolate();
181182
HandleScope scope(isolate);
182-
Environment* env = Environment::GetCurrent(isolate);
183183
Local<Context> context = env->context();
184+
Context::Scope context_scope(context);
184185
Local<Function> fn;
185186
Local<Object> obj;
186187
PerformanceGCKind kind = static_cast<PerformanceGCKind>(data->data());
@@ -203,28 +204,31 @@ inline void PerformanceGCCallback(uv_async_t* handle) {
203204
uv_close(reinterpret_cast<uv_handle_t*>(handle), closeCB);
204205
}
205206

206-
inline void MarkGarbageCollectionStart(Isolate* isolate,
207-
v8::GCType type,
208-
v8::GCCallbackFlags flags) {
207+
void MarkGarbageCollectionStart(Isolate* isolate,
208+
v8::GCType type,
209+
v8::GCCallbackFlags flags) {
209210
performance_last_gc_start_mark_ = PERFORMANCE_NOW();
210211
performance_last_gc_type_ = type;
211212
}
212213

213-
inline void MarkGarbageCollectionEnd(Isolate* isolate,
214-
v8::GCType type,
215-
v8::GCCallbackFlags flags) {
214+
void MarkGarbageCollectionEnd(Isolate* isolate,
215+
v8::GCType type,
216+
v8::GCCallbackFlags flags,
217+
void* data) {
218+
Environment* env = static_cast<Environment*>(data);
216219
uv_async_t *async = new uv_async_t;
217220
async->data =
218-
new PerformanceEntry::Data("gc", "gc",
221+
new PerformanceEntry::Data(env, "gc", "gc",
219222
performance_last_gc_start_mark_,
220223
PERFORMANCE_NOW(), type);
221-
uv_async_init(uv_default_loop(), async, PerformanceGCCallback);
224+
uv_async_init(env->event_loop(), async, PerformanceGCCallback);
222225
uv_async_send(async);
223226
}
224227

225-
inline void SetupGarbageCollectionTracking(Isolate* isolate) {
226-
isolate->AddGCPrologueCallback(MarkGarbageCollectionStart);
227-
isolate->AddGCEpilogueCallback(MarkGarbageCollectionEnd);
228+
inline void SetupGarbageCollectionTracking(Environment* env) {
229+
env->isolate()->AddGCPrologueCallback(MarkGarbageCollectionStart);
230+
env->isolate()->AddGCEpilogueCallback(MarkGarbageCollectionEnd,
231+
static_cast<void*>(env));
228232
}
229233

230234
inline Local<Value> GetName(Local<Function> fn) {
@@ -380,7 +384,7 @@ void Init(Local<Object> target,
380384
constants,
381385
attr).ToChecked();
382386

383-
SetupGarbageCollectionTracking(isolate);
387+
SetupGarbageCollectionTracking(env);
384388
}
385389

386390
} // namespace performance

src/node_perf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,17 +56,23 @@ class PerformanceEntry : public BaseObject {
5656
class Data {
5757
public:
5858
Data(
59+
Environment* env,
5960
const char* name,
6061
const char* type,
6162
uint64_t startTime,
6263
uint64_t endTime,
6364
int data = 0) :
65+
env_(env),
6466
name_(name),
6567
type_(type),
6668
startTime_(startTime),
6769
endTime_(endTime),
6870
data_(data) {}
6971

72+
Environment* env() const {
73+
return env_;
74+
}
75+
7076
std::string name() const {
7177
return name_;
7278
}
@@ -88,6 +94,7 @@ class PerformanceEntry : public BaseObject {
8894
}
8995

9096
private:
97+
Environment* env_;
9198
std::string name_;
9299
std::string type_;
93100
uint64_t startTime_;

0 commit comments

Comments
 (0)