summaryrefslogtreecommitdiff
path: root/src/heap_utils.cc
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2020-01-29 16:41:26 +0000
committerRich Trott <rtrott@gmail.com>2020-02-03 07:04:13 -0800
commit875a4d1a58d6dec80518c9d2a05ae6107c70b066 (patch)
tree5223080453453fe6617e45dcc0df36e44695dab9 /src/heap_utils.cc
parentf7a1ef6fb51f814223e3c26fffb9d39b08f91b1b (diff)
downloadnode-new-875a4d1a58d6dec80518c9d2a05ae6107c70b066.tar.gz
worker: add ability to take heap snapshot from parent thread
PR-URL: https://github.com/nodejs/node/pull/31569 Reviewed-By: Denys Otrishko <shishugi@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
Diffstat (limited to 'src/heap_utils.cc')
-rw-r--r--src/heap_utils.cc74
1 files changed, 39 insertions, 35 deletions
diff --git a/src/heap_utils.cc b/src/heap_utils.cc
index b6c8c75c15..68cd532c23 100644
--- a/src/heap_utils.cc
+++ b/src/heap_utils.cc
@@ -236,18 +236,16 @@ class HeapSnapshotStream : public AsyncWrap,
public:
HeapSnapshotStream(
Environment* env,
- const HeapSnapshot* snapshot,
+ HeapSnapshotPointer&& snapshot,
v8::Local<v8::Object> obj) :
AsyncWrap(env, obj, AsyncWrap::PROVIDER_HEAPSNAPSHOT),
StreamBase(env),
- snapshot_(snapshot) {
+ snapshot_(std::move(snapshot)) {
MakeWeak();
StreamBase::AttachToObject(GetObject());
}
- ~HeapSnapshotStream() override {
- Cleanup();
- }
+ ~HeapSnapshotStream() override {}
int GetChunkSize() override {
return 65536; // big chunks == faster
@@ -255,7 +253,7 @@ class HeapSnapshotStream : public AsyncWrap,
void EndOfStream() override {
EmitRead(UV_EOF);
- Cleanup();
+ snapshot_.reset();
}
WriteResult WriteAsciiChunk(char* data, int size) override {
@@ -309,22 +307,13 @@ class HeapSnapshotStream : public AsyncWrap,
SET_SELF_SIZE(HeapSnapshotStream)
private:
- void Cleanup() {
- if (snapshot_ != nullptr) {
- const_cast<HeapSnapshot*>(snapshot_)->Delete();
- snapshot_ = nullptr;
- }
- }
-
-
- const HeapSnapshot* snapshot_;
+ HeapSnapshotPointer snapshot_;
};
inline void TakeSnapshot(Isolate* isolate, v8::OutputStream* out) {
- const HeapSnapshot* const snapshot =
- isolate->GetHeapProfiler()->TakeHeapSnapshot();
+ HeapSnapshotPointer snapshot {
+ isolate->GetHeapProfiler()->TakeHeapSnapshot() };
snapshot->Serialize(out, HeapSnapshot::kJSON);
- const_cast<HeapSnapshot*>(snapshot)->Delete();
}
inline bool WriteSnapshot(Isolate* isolate, const char* filename) {
@@ -339,20 +328,44 @@ inline bool WriteSnapshot(Isolate* isolate, const char* filename) {
} // namespace
-void CreateHeapSnapshotStream(const FunctionCallbackInfo<Value>& args) {
- Environment* env = Environment::GetCurrent(args);
+void DeleteHeapSnapshot(const v8::HeapSnapshot* snapshot) {
+ const_cast<HeapSnapshot*>(snapshot)->Delete();
+}
+
+BaseObjectPtr<AsyncWrap> CreateHeapSnapshotStream(
+ Environment* env, HeapSnapshotPointer&& snapshot) {
HandleScope scope(env->isolate());
- const HeapSnapshot* const snapshot =
- env->isolate()->GetHeapProfiler()->TakeHeapSnapshot();
- CHECK_NOT_NULL(snapshot);
+
+ if (env->streambaseoutputstream_constructor_template().IsEmpty()) {
+ // Create FunctionTemplate for HeapSnapshotStream
+ Local<FunctionTemplate> os = FunctionTemplate::New(env->isolate());
+ os->Inherit(AsyncWrap::GetConstructorTemplate(env));
+ Local<ObjectTemplate> ost = os->InstanceTemplate();
+ ost->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount);
+ os->SetClassName(
+ FIXED_ONE_BYTE_STRING(env->isolate(), "HeapSnapshotStream"));
+ StreamBase::AddMethods(env, os);
+ env->set_streambaseoutputstream_constructor_template(ost);
+ }
+
Local<Object> obj;
if (!env->streambaseoutputstream_constructor_template()
->NewInstance(env->context())
.ToLocal(&obj)) {
- return;
+ return {};
}
- HeapSnapshotStream* out = new HeapSnapshotStream(env, snapshot, obj);
- args.GetReturnValue().Set(out->object());
+ return MakeBaseObject<HeapSnapshotStream>(env, std::move(snapshot), obj);
+}
+
+void CreateHeapSnapshotStream(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ HeapSnapshotPointer snapshot {
+ env->isolate()->GetHeapProfiler()->TakeHeapSnapshot() };
+ CHECK(snapshot);
+ BaseObjectPtr<AsyncWrap> stream =
+ CreateHeapSnapshotStream(env, std::move(snapshot));
+ if (stream)
+ args.GetReturnValue().Set(stream->object());
}
void TriggerHeapSnapshot(const FunctionCallbackInfo<Value>& args) {
@@ -388,15 +401,6 @@ void Initialize(Local<Object> target,
env->SetMethod(target, "buildEmbedderGraph", BuildEmbedderGraph);
env->SetMethod(target, "triggerHeapSnapshot", TriggerHeapSnapshot);
env->SetMethod(target, "createHeapSnapshotStream", CreateHeapSnapshotStream);
-
- // Create FunctionTemplate for HeapSnapshotStream
- Local<FunctionTemplate> os = FunctionTemplate::New(env->isolate());
- os->Inherit(AsyncWrap::GetConstructorTemplate(env));
- Local<ObjectTemplate> ost = os->InstanceTemplate();
- ost->SetInternalFieldCount(StreamBase::kStreamBaseFieldCount);
- os->SetClassName(FIXED_ONE_BYTE_STRING(env->isolate(), "HeapSnapshotStream"));
- StreamBase::AddMethods(env, os);
- env->set_streambaseoutputstream_constructor_template(ost);
}
} // namespace heap