summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2012-10-11 00:44:49 +0200
committerBen Noordhuis <info@bnoordhuis.nl>2012-10-11 01:05:18 +0200
commit6a128e037e5b9f0c5c84fc24d343db3364a56d64 (patch)
tree2d241507f5f3102ffe228a9c9813a87f254ba471
parent87518f1e3c0c91418df260258ee99101b8cb86de (diff)
downloadnode-6a128e037e5b9f0c5c84fc24d343db3364a56d64.tar.gz
buffer: report proper retained size in profiler
Make buffers report the proper retained size in heap snapshots. Before this commit, Buffer objects would show up in the heap profiler as being only a few hundred bytes large, even if the actual buffer was many megabytes.
-rw-r--r--src/node_buffer.cc62
1 files changed, 61 insertions, 1 deletions
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index e80611f87..98dfa5e00 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -24,6 +24,7 @@
#include "node_buffer.h"
#include "v8.h"
+#include "v8-profiler.h"
#include <assert.h>
#include <stdlib.h> // malloc, free
@@ -33,9 +34,10 @@
# include <arpa/inet.h> // htons, htonl
#endif
-
#define MIN(a,b) ((a) < (b) ? (a) : (b))
+#define BUFFER_CLASS_ID (0xBABE)
+
namespace node {
using namespace v8;
@@ -188,6 +190,7 @@ Buffer::Buffer(Handle<Object> wrapper, size_t length) : ObjectWrap() {
length_ = 0;
callback_ = NULL;
+ handle_.SetWrapperClassId(BUFFER_CLASS_ID);
Replace(NULL, length, NULL, NULL);
}
@@ -728,6 +731,61 @@ bool Buffer::HasInstance(v8::Handle<v8::Value> val) {
}
+class RetainedBufferInfo: public v8::RetainedObjectInfo {
+public:
+ RetainedBufferInfo(Buffer* buffer);
+ virtual void Dispose();
+ virtual bool IsEquivalent(RetainedObjectInfo* other);
+ virtual intptr_t GetHash();
+ virtual const char* GetLabel();
+ virtual intptr_t GetSizeInBytes();
+private:
+ Buffer* buffer_;
+ static const char label[];
+};
+
+const char RetainedBufferInfo::label[] = "Buffer";
+
+
+RetainedBufferInfo::RetainedBufferInfo(Buffer* buffer): buffer_(buffer) {
+}
+
+
+void RetainedBufferInfo::Dispose() {
+ buffer_ = NULL;
+ delete this;
+}
+
+
+bool RetainedBufferInfo::IsEquivalent(RetainedObjectInfo* other) {
+ return label == other->GetLabel() &&
+ buffer_ == static_cast<RetainedBufferInfo*>(other)->buffer_;
+}
+
+
+intptr_t RetainedBufferInfo::GetHash() {
+ return reinterpret_cast<intptr_t>(buffer_);
+}
+
+
+const char* RetainedBufferInfo::GetLabel() {
+ return label;
+}
+
+
+intptr_t RetainedBufferInfo::GetSizeInBytes() {
+ return Buffer::Length(buffer_);
+}
+
+
+RetainedObjectInfo* WrapperInfo(uint16_t class_id, Handle<Value> wrapper) {
+ assert(class_id == BUFFER_CLASS_ID);
+ assert(Buffer::HasInstance(wrapper));
+ Buffer* buffer = Buffer::Unwrap<Buffer>(wrapper.As<Object>());
+ return new RetainedBufferInfo(buffer);
+}
+
+
void Buffer::Initialize(Handle<Object> target) {
HandleScope scope;
@@ -775,6 +833,8 @@ void Buffer::Initialize(Handle<Object> target) {
Buffer::MakeFastBuffer);
target->Set(String::NewSymbol("SlowBuffer"), constructor_template->GetFunction());
+
+ HeapProfiler::DefineWrapperClass(BUFFER_CLASS_ID, WrapperInfo);
}