diff options
-rw-r--r-- | src/async-wrap-inl.h | 5 | ||||
-rw-r--r-- | src/async-wrap.cc | 90 | ||||
-rw-r--r-- | src/async-wrap.h | 6 | ||||
-rw-r--r-- | src/cares_wrap.cc | 28 | ||||
-rw-r--r-- | src/fs_event_wrap.cc | 2 | ||||
-rw-r--r-- | src/js_stream.h | 2 | ||||
-rw-r--r-- | src/node.cc | 1 | ||||
-rw-r--r-- | src/node_crypto.cc | 4 | ||||
-rw-r--r-- | src/node_crypto.h | 4 | ||||
-rw-r--r-- | src/node_file.cc | 2 | ||||
-rw-r--r-- | src/node_stat_watcher.h | 2 | ||||
-rw-r--r-- | src/node_zlib.cc | 2 | ||||
-rw-r--r-- | src/pipe_wrap.cc | 2 | ||||
-rw-r--r-- | src/pipe_wrap.h | 2 | ||||
-rw-r--r-- | src/process_wrap.cc | 2 | ||||
-rw-r--r-- | src/signal_wrap.cc | 2 | ||||
-rw-r--r-- | src/stream_base-inl.h | 2 | ||||
-rw-r--r-- | src/stream_base.h | 10 | ||||
-rw-r--r-- | src/tcp_wrap.cc | 1 | ||||
-rw-r--r-- | src/tcp_wrap.h | 2 | ||||
-rw-r--r-- | src/timer_wrap.cc | 2 | ||||
-rw-r--r-- | src/tls_wrap.h | 2 | ||||
-rw-r--r-- | src/tty_wrap.h | 2 | ||||
-rw-r--r-- | src/udp_wrap.cc | 1 | ||||
-rw-r--r-- | src/udp_wrap.h | 2 |
25 files changed, 175 insertions, 5 deletions
diff --git a/src/async-wrap-inl.h b/src/async-wrap-inl.h index bad634ddaf..5841c58faf 100644 --- a/src/async-wrap-inl.h +++ b/src/async-wrap-inl.h @@ -18,6 +18,11 @@ inline AsyncWrap::AsyncWrap(Environment* env, ProviderType provider, AsyncWrap* parent) : BaseObject(env, object), bits_(static_cast<uint32_t>(provider) << 1) { + // Only set wrapper class id if object will be Wrap'd. + if (object->InternalFieldCount() > 0) + // Shift provider value over to prevent id collision. + persistent().SetWrapperClassId(NODE_ASYNC_ID_OFFSET + provider); + // Check user controlled flag to see if the init callback should run. if (!env->using_asyncwrap()) return; 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) { diff --git a/src/async-wrap.h b/src/async-wrap.h index 5e898fe4c2..bb93872ff7 100644 --- a/src/async-wrap.h +++ b/src/async-wrap.h @@ -8,6 +8,8 @@ namespace node { +#define NODE_ASYNC_ID_OFFSET 0xA1C + #define NODE_ASYNC_PROVIDER_TYPES(V) \ V(NONE) \ V(CARES) \ @@ -64,6 +66,8 @@ class AsyncWrap : public BaseObject { int argc, v8::Handle<v8::Value>* argv); + virtual size_t self_size() const = 0; + private: inline AsyncWrap(); inline bool has_async_queue() const; @@ -74,6 +78,8 @@ class AsyncWrap : public BaseObject { uint32_t bits_; }; +void LoadAsyncWrapperInfo(Environment* env); + } // namespace node diff --git a/src/cares_wrap.cc b/src/cares_wrap.cc index c73f8c05cb..d4be7c9b9b 100644 --- a/src/cares_wrap.cc +++ b/src/cares_wrap.cc @@ -51,6 +51,8 @@ using v8::Value; class GetAddrInfoReqWrap : public ReqWrap<uv_getaddrinfo_t> { public: GetAddrInfoReqWrap(Environment* env, Local<Object> req_wrap_obj); + + size_t self_size() const override { return sizeof(*this); } }; GetAddrInfoReqWrap::GetAddrInfoReqWrap(Environment* env, @@ -66,8 +68,10 @@ static void NewGetAddrInfoReqWrap(const FunctionCallbackInfo<Value>& args) { class GetNameInfoReqWrap : public ReqWrap<uv_getnameinfo_t> { - public: - GetNameInfoReqWrap(Environment* env, Local<Object> req_wrap_obj); + public: + GetNameInfoReqWrap(Environment* env, Local<Object> req_wrap_obj); + + size_t self_size() const override { return sizeof(*this); } }; GetNameInfoReqWrap::GetNameInfoReqWrap(Environment* env, @@ -385,6 +389,8 @@ class QueryAWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -422,6 +428,8 @@ class QueryAaaaWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -459,6 +467,8 @@ class QueryCnameWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -498,6 +508,8 @@ class QueryMxWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -547,6 +559,8 @@ class QueryNsWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -583,6 +597,8 @@ class QueryTxtWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -638,6 +654,8 @@ class QuerySrvWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -692,6 +710,8 @@ class QueryNaptrWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -754,6 +774,8 @@ class QuerySoaWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(unsigned char* buf, int len) override { HandleScope handle_scope(env()->isolate()); @@ -820,6 +842,8 @@ class GetHostByAddrWrap: public QueryWrap { return 0; } + size_t self_size() const override { return sizeof(*this); } + protected: void Parse(struct hostent* host) override { HandleScope handle_scope(env()->isolate()); diff --git a/src/fs_event_wrap.cc b/src/fs_event_wrap.cc index a6ceff2776..e17f9ce58e 100644 --- a/src/fs_event_wrap.cc +++ b/src/fs_event_wrap.cc @@ -31,6 +31,8 @@ class FSEventWrap: public HandleWrap { static void Start(const FunctionCallbackInfo<Value>& args); static void Close(const FunctionCallbackInfo<Value>& args); + size_t self_size() const override { return sizeof(*this); } + private: FSEventWrap(Environment* env, Handle<Object> object); virtual ~FSEventWrap() override; diff --git a/src/js_stream.h b/src/js_stream.h index 6bc763b36e..9f7ba7de27 100644 --- a/src/js_stream.h +++ b/src/js_stream.h @@ -28,6 +28,8 @@ class JSStream : public StreamBase, public AsyncWrap { size_t count, uv_stream_t* send_handle) override; + size_t self_size() const override { return sizeof(*this); } + protected: JSStream(Environment* env, v8::Handle<v8::Object> obj, AsyncWrap* parent); diff --git a/src/node.cc b/src/node.cc index f47dd72205..18d0850433 100644 --- a/src/node.cc +++ b/src/node.cc @@ -3872,6 +3872,7 @@ Environment* CreateEnvironment(Isolate* isolate, env->set_process_object(process_object); SetupProcessObject(env, argc, argv, exec_argc, exec_argv); + LoadAsyncWrapperInfo(env); return env; } diff --git a/src/node_crypto.cc b/src/node_crypto.cc index 48a75d30f7..296ca0a606 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -4546,6 +4546,8 @@ class PBKDF2Request : public AsyncWrap { error_ = err; } + size_t self_size() const override { return sizeof(*this); } + uv_work_t work_req_; private: @@ -4776,6 +4778,8 @@ class RandomBytesRequest : public AsyncWrap { error_ = err; } + size_t self_size() const override { return sizeof(*this); } + uv_work_t work_req_; private: diff --git a/src/node_crypto.h b/src/node_crypto.h index 0ef9c02273..3a00b51932 100644 --- a/src/node_crypto.h +++ b/src/node_crypto.h @@ -308,6 +308,8 @@ class Connection : public SSLWrap<Connection>, public AsyncWrap { v8::Persistent<v8::String> servername_; #endif + size_t self_size() const override { return sizeof(*this); } + protected: static void New(const v8::FunctionCallbackInfo<v8::Value>& args); static void EncIn(const v8::FunctionCallbackInfo<v8::Value>& args); @@ -702,6 +704,8 @@ class Certificate : public AsyncWrap { const char* ExportPublicKey(const char* data, int len); const char* ExportChallenge(const char* data, int len); + size_t self_size() const override { return sizeof(*this); } + protected: static void New(const v8::FunctionCallbackInfo<v8::Value>& args); static void VerifySpkac(const v8::FunctionCallbackInfo<v8::Value>& args); diff --git a/src/node_file.cc b/src/node_file.cc index c8696f1295..0297b08e68 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -73,6 +73,8 @@ class FSReqWrap: public ReqWrap<uv_fs_t> { const char* syscall() const { return syscall_; } const char* data() const { return data_; } + size_t self_size() const override { return sizeof(*this); } + private: FSReqWrap(Environment* env, Local<Object> req, diff --git a/src/node_stat_watcher.h b/src/node_stat_watcher.h index bd21479104..e0ef76601f 100644 --- a/src/node_stat_watcher.h +++ b/src/node_stat_watcher.h @@ -22,6 +22,8 @@ class StatWatcher : public AsyncWrap { static void Start(const v8::FunctionCallbackInfo<v8::Value>& args); static void Stop(const v8::FunctionCallbackInfo<v8::Value>& args); + size_t self_size() const override { return sizeof(*this); } + private: static void Callback(uv_fs_poll_t* handle, int status, diff --git a/src/node_zlib.cc b/src/node_zlib.cc index 58dfce3975..699d5c453c 100644 --- a/src/node_zlib.cc +++ b/src/node_zlib.cc @@ -535,6 +535,8 @@ class ZCtx : public AsyncWrap { } } + size_t self_size() const override { return sizeof(*this); } + private: void Ref() { if (++refs_ == 1) { diff --git a/src/pipe_wrap.cc b/src/pipe_wrap.cc index 08fed68741..2e1ab5b262 100644 --- a/src/pipe_wrap.cc +++ b/src/pipe_wrap.cc @@ -37,6 +37,8 @@ using v8::Value; class PipeConnectWrap : public ReqWrap<uv_connect_t> { public: PipeConnectWrap(Environment* env, Local<Object> req_wrap_obj); + + size_t self_size() const override { return sizeof(*this); } }; diff --git a/src/pipe_wrap.h b/src/pipe_wrap.h index 6dc9a01bcd..6c74de984b 100644 --- a/src/pipe_wrap.h +++ b/src/pipe_wrap.h @@ -16,6 +16,8 @@ class PipeWrap : public StreamWrap { v8::Handle<v8::Value> unused, v8::Handle<v8::Context> context); + size_t self_size() const override { return sizeof(*this); } + private: PipeWrap(Environment* env, v8::Handle<v8::Object> object, diff --git a/src/process_wrap.cc b/src/process_wrap.cc index 56d1f28e4a..14bbb9c9e9 100644 --- a/src/process_wrap.cc +++ b/src/process_wrap.cc @@ -46,6 +46,8 @@ class ProcessWrap : public HandleWrap { constructor->GetFunction()); } + size_t self_size() const override { return sizeof(*this); } + private: static void New(const FunctionCallbackInfo<Value>& args) { // This constructor should not be exposed to public javascript. diff --git a/src/signal_wrap.cc b/src/signal_wrap.cc index 7cceb64560..4811aca53a 100644 --- a/src/signal_wrap.cc +++ b/src/signal_wrap.cc @@ -40,6 +40,8 @@ class SignalWrap : public HandleWrap { constructor->GetFunction()); } + size_t self_size() const override { return sizeof(*this); } + private: static void New(const FunctionCallbackInfo<Value>& args) { // This constructor should not be exposed to public javascript. diff --git a/src/stream_base-inl.h b/src/stream_base-inl.h index 26ba54b376..d74b47de60 100644 --- a/src/stream_base-inl.h +++ b/src/stream_base-inl.h @@ -92,7 +92,7 @@ WriteWrap* WriteWrap::New(Environment* env, size_t storage_size = ROUND_UP(sizeof(WriteWrap), kAlignSize) + extra; char* storage = new char[storage_size]; - return new(storage) WriteWrap(env, obj, wrap, cb); + return new(storage) WriteWrap(env, obj, wrap, cb, storage_size); } diff --git a/src/stream_base.h b/src/stream_base.h index dfb0d31c66..31854b3435 100644 --- a/src/stream_base.h +++ b/src/stream_base.h @@ -48,6 +48,7 @@ class ShutdownWrap : public ReqWrap<uv_shutdown_t>, } inline StreamBase* wrap() const { return wrap_; } + size_t self_size() const override { return sizeof(*this); } private: StreamBase* const wrap_; @@ -66,6 +67,8 @@ class WriteWrap: public ReqWrap<uv_write_t>, inline StreamBase* wrap() const { return wrap_; } + size_t self_size() const override { return storage_size_; } + static void NewWriteWrap(const v8::FunctionCallbackInfo<v8::Value>& args) { CHECK(args.IsConstructCall()); } @@ -76,10 +79,12 @@ class WriteWrap: public ReqWrap<uv_write_t>, WriteWrap(Environment* env, v8::Local<v8::Object> obj, StreamBase* wrap, - DoneCb cb) + DoneCb cb, + size_t storage_size) : ReqWrap(env, obj, AsyncWrap::PROVIDER_WRITEWRAP), StreamReq<WriteWrap>(cb), - wrap_(wrap) { + wrap_(wrap), + storage_size_(storage_size) { Wrap(obj, this); } @@ -96,6 +101,7 @@ class WriteWrap: public ReqWrap<uv_write_t>, void operator delete(void* ptr) { UNREACHABLE(); } StreamBase* const wrap_; + const size_t storage_size_; }; class StreamResource { diff --git a/src/tcp_wrap.cc b/src/tcp_wrap.cc index e16e140583..6980f8b28c 100644 --- a/src/tcp_wrap.cc +++ b/src/tcp_wrap.cc @@ -37,6 +37,7 @@ using v8::Value; class TCPConnectWrap : public ReqWrap<uv_connect_t> { public: TCPConnectWrap(Environment* env, Local<Object> req_wrap_obj); + size_t self_size() const override { return sizeof(*this); } }; diff --git a/src/tcp_wrap.h b/src/tcp_wrap.h index c41a36fbeb..ee1e9817b2 100644 --- a/src/tcp_wrap.h +++ b/src/tcp_wrap.h @@ -16,6 +16,8 @@ class TCPWrap : public StreamWrap { uv_tcp_t* UVHandle(); + size_t self_size() const override { return sizeof(*this); } + private: TCPWrap(Environment* env, v8::Handle<v8::Object> object, AsyncWrap* parent); ~TCPWrap(); diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc index f65290a516..d2c9a8c9ae 100644 --- a/src/timer_wrap.cc +++ b/src/timer_wrap.cc @@ -51,6 +51,8 @@ class TimerWrap : public HandleWrap { constructor->GetFunction()); } + size_t self_size() const override { return sizeof(*this); } + private: static void New(const FunctionCallbackInfo<Value>& args) { // This constructor should not be exposed to public javascript. diff --git a/src/tls_wrap.h b/src/tls_wrap.h index a304475190..b906d78de1 100644 --- a/src/tls_wrap.h +++ b/src/tls_wrap.h @@ -50,6 +50,8 @@ class TLSWrap : public crypto::SSLWrap<TLSWrap>, void NewSessionDoneCb(); + size_t self_size() const override { return sizeof(*this); } + protected: static const int kClearOutChunkSize = 1024; diff --git a/src/tty_wrap.h b/src/tty_wrap.h index 09cd71e781..6d423e1ae5 100644 --- a/src/tty_wrap.h +++ b/src/tty_wrap.h @@ -15,6 +15,8 @@ class TTYWrap : public StreamWrap { uv_tty_t* UVHandle(); + size_t self_size() const override { return sizeof(*this); } + private: TTYWrap(Environment* env, v8::Handle<v8::Object> object, diff --git a/src/udp_wrap.cc b/src/udp_wrap.cc index 3183d1f9f5..fe0ed76dd5 100644 --- a/src/udp_wrap.cc +++ b/src/udp_wrap.cc @@ -36,6 +36,7 @@ class SendWrap : public ReqWrap<uv_udp_send_t> { public: SendWrap(Environment* env, Local<Object> req_wrap_obj, bool have_callback); inline bool have_callback() const; + size_t self_size() const override { return sizeof(*this); } private: const bool have_callback_; }; diff --git a/src/udp_wrap.h b/src/udp_wrap.h index 0a33ae8cb2..3373cb9a2d 100644 --- a/src/udp_wrap.h +++ b/src/udp_wrap.h @@ -37,6 +37,8 @@ class UDPWrap: public HandleWrap { static v8::Local<v8::Object> Instantiate(Environment* env, AsyncWrap* parent); uv_udp_t* UVHandle(); + size_t self_size() const override { return sizeof(*this); } + private: UDPWrap(Environment* env, v8::Handle<v8::Object> object, AsyncWrap* parent); |