-
Notifications
You must be signed in to change notification settings - Fork 8
wall profiler: track live PCPs via an intrusive list #341
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,9 +57,19 @@ class WallProfiler : public Nan::ObjectWrap { | |
| int cpedKeyHash_ = 0; | ||
| v8::Global<v8::ObjectTemplate> wrapObjectTemplate_; | ||
|
|
||
| // We track live context pointers in a set to avoid memory leaks. They will | ||
| // be deleted when the profiler is disposed. | ||
| std::unordered_set<PersistentContextPtr*> liveContextPtrs_; | ||
| // The list lets ~WallProfiler delete any PCPs V8 hasn't GC'd yet, so they | ||
| // don't show up as leaks under LSAN at exit. | ||
| // PCPs link themselves in at construction and unlink in their destructor. | ||
| // This used to be an unordered set, but storing two pointers in the PCP is | ||
| // much cheaper memorywise than the hash set's overhead of buckets and nodes. | ||
| PersistentContextPtr* liveContextPtrHead_ = nullptr; | ||
|
|
||
| // Number of PersistentContextPtr instances created by this profiler that | ||
| // are still alive. Incremented in PersistentContextPtr's constructor; | ||
| // decremented in its destructor when it unlinks from the list (i.e., while | ||
| // the profiler is still alive). PCPs cleaned up by ~WallProfiler's walk | ||
| // skip the decrement — the counter is going away with the profiler anyway. | ||
| std::atomic<size_t> liveContextPtrCount_{0}; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My only worry is GC callbacks, but I'll try to confirm from source code that they always run on the isolate thread (I know that some V8 GC stages can be multithreaded.) |
||
|
|
||
| std::atomic<int> gcCount = 0; | ||
| std::atomic<bool> setInProgress_ = false; | ||
|
|
@@ -175,6 +185,22 @@ class WallProfiler : public Nan::ObjectWrap { | |
|
|
||
| bool interceptSignal() const { return withContexts_ || workaroundV8Bug_; } | ||
|
|
||
| // Returns the address of the live-PCP list head so a newly constructed PCP | ||
| // can splice itself in. Only used by PersistentContextPtr's constructor. | ||
| PersistentContextPtr** liveContextPtrHeadSlot() { | ||
| return &liveContextPtrHead_; | ||
| } | ||
|
|
||
| void recordContextCreate() { | ||
| liveContextPtrCount_.fetch_add(1, std::memory_order_relaxed); | ||
| } | ||
| void recordContextRelease() { | ||
| liveContextPtrCount_.fetch_sub(1, std::memory_order_relaxed); | ||
| } | ||
| size_t liveContextPtrCount() const { | ||
| return liveContextPtrCount_.load(std::memory_order_relaxed); | ||
| } | ||
|
|
||
| int v8ProfilerStuckEventLoopDetected() const { | ||
| return v8ProfilerStuckEventLoopDetected_; | ||
| } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: the claim that
pprev(double pointer) enables O(1) unlink is dubious. Maybe better explain the benefits vs using a single pointer.