summaryrefslogtreecommitdiff
path: root/src/async-wrap.cc
diff options
context:
space:
mode:
authorTrevor Norris <trev.norris@gmail.com>2015-06-03 15:31:33 -0600
committerTrevor Norris <trev.norris@gmail.com>2015-06-17 12:58:39 -0600
commite56758a5e0ff6822e3105c0e69eb49accc42393c (patch)
tree25cc1ce181450f78f4dbce2a8d4489752c35cf7b /src/async-wrap.cc
parent5d0cee46bb90084e6dcd584deb5bc893862ce3b3 (diff)
downloadnode-new-e56758a5e0ff6822e3105c0e69eb49accc42393c.tar.gz
async-wrap: add provider id and object info cb
Re-add the wrapper class id to AsyncWrap instances so they can be tracked directly in a heapdump. Previously the class id was given without setting the heap dump wrapper class info provider. Causing a segfault when a heapdump was taken. This has been added, and the label_ set to the given provider name so each instance can be identified. The id will not be set of the passed object has no internal field count. As the class pointer cannot be retrieved from the object. In order to properly report the allocated size of each class, the new pure virtual method self_size() has been introduces. PR-URL: https://github.com/nodejs/io.js/pull/1896 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Diffstat (limited to 'src/async-wrap.cc')
-rw-r--r--src/async-wrap.cc90
1 files changed, 90 insertions, 0 deletions
diff --git a/src/async-wrap.cc b/src/async-wrap.cc
index 2da6b10293..454681e0c6 100644
--- a/src/async-wrap.cc
+++ b/src/async-wrap.cc
@@ -6,6 +6,7 @@
#include "util-inl.h"
#include "v8.h"
+#include "v8-profiler.h"
using v8::Array;
using v8::Context;
@@ -13,16 +14,95 @@ using v8::Function;
using v8::FunctionCallbackInfo;
using v8::Handle;
using v8::HandleScope;
+using v8::HeapProfiler;
using v8::Integer;
using v8::Isolate;
using v8::Local;
using v8::Object;
+using v8::RetainedObjectInfo;
using v8::TryCatch;
using v8::Value;
using v8::kExternalUint32Array;
namespace node {
+static const char* const provider_names[] = {
+#define V(PROVIDER) \
+ #PROVIDER,
+ NODE_ASYNC_PROVIDER_TYPES(V)
+#undef V
+};
+
+
+class RetainedAsyncInfo: public RetainedObjectInfo {
+ public:
+ explicit RetainedAsyncInfo(uint16_t class_id, AsyncWrap* wrap);
+
+ virtual void Dispose() override;
+ virtual bool IsEquivalent(RetainedObjectInfo* other) override;
+ virtual intptr_t GetHash() override;
+ virtual const char* GetLabel() override;
+ virtual intptr_t GetSizeInBytes() override;
+
+ private:
+ const char* label_;
+ const AsyncWrap* wrap_;
+ const int length_;
+};
+
+
+RetainedAsyncInfo::RetainedAsyncInfo(uint16_t class_id, AsyncWrap* wrap)
+ : label_(provider_names[class_id - NODE_ASYNC_ID_OFFSET]),
+ wrap_(wrap),
+ length_(wrap->self_size()) {
+}
+
+
+void RetainedAsyncInfo::Dispose() {
+ delete this;
+}
+
+
+bool RetainedAsyncInfo::IsEquivalent(RetainedObjectInfo* other) {
+ return label_ == other->GetLabel() &&
+ wrap_ == static_cast<RetainedAsyncInfo*>(other)->wrap_;
+}
+
+
+intptr_t RetainedAsyncInfo::GetHash() {
+ return reinterpret_cast<intptr_t>(wrap_);
+}
+
+
+const char* RetainedAsyncInfo::GetLabel() {
+ return label_;
+}
+
+
+intptr_t RetainedAsyncInfo::GetSizeInBytes() {
+ return length_;
+}
+
+
+RetainedObjectInfo* WrapperInfo(uint16_t class_id, Handle<Value> wrapper) {
+ // No class_id should be the provider type of NONE.
+ CHECK_NE(NODE_ASYNC_ID_OFFSET, class_id);
+ CHECK(wrapper->IsObject());
+ CHECK(!wrapper.IsEmpty());
+
+ Local<Object> object = wrapper.As<Object>();
+ CHECK_GT(object->InternalFieldCount(), 0);
+
+ AsyncWrap* wrap = Unwrap<AsyncWrap>(object);
+ CHECK_NE(nullptr, wrap);
+
+ return new RetainedAsyncInfo(class_id, wrap);
+}
+
+
+// end RetainedAsyncInfo
+
+
static void EnableHooksJS(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
env->async_hooks()->set_enable_callbacks(1);
@@ -71,6 +151,16 @@ static void Initialize(Handle<Object> target,
}
+void LoadAsyncWrapperInfo(Environment* env) {
+ HeapProfiler* heap_profiler = env->isolate()->GetHeapProfiler();
+#define V(PROVIDER) \
+ heap_profiler->SetWrapperClassInfoProvider( \
+ (NODE_ASYNC_ID_OFFSET + AsyncWrap::PROVIDER_ ## PROVIDER), WrapperInfo);
+ NODE_ASYNC_PROVIDER_TYPES(V)
+#undef V
+}
+
+
Handle<Value> AsyncWrap::MakeCallback(const Handle<Function> cb,
int argc,
Handle<Value>* argv) {