diff options
author | Anna Henningsen <anna@addaleax.net> | 2020-01-29 16:41:26 +0000 |
---|---|---|
committer | Rich Trott <rtrott@gmail.com> | 2020-02-03 07:04:13 -0800 |
commit | 875a4d1a58d6dec80518c9d2a05ae6107c70b066 (patch) | |
tree | 5223080453453fe6617e45dcc0df36e44695dab9 /src/heap_utils.cc | |
parent | f7a1ef6fb51f814223e3c26fffb9d39b08f91b1b (diff) | |
download | node-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.cc | 74 |
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 |