Browse files

broke out classes

  • Loading branch information...
1 parent 0de7aa1 commit 400fb8a6bd48ca041a1602d3818f34911300125b @dannycoates dannycoates committed Nov 27, 2010
Showing with 689 additions and 491 deletions.
  1. +91 −0 graph_edge.cc
  2. +27 −0 graph_edge.h
  3. +198 −0 graph_node.cc
  4. +36 −0 graph_node.h
  5. +74 −0 graph_path.cc
  6. +27 −0 graph_path.h
  7. +5 −490 heap.cc
  8. +98 −0 snapshot.cc
  9. +28 −0 snapshot.h
  10. +50 −0 snapshot_diff.cc
  11. +25 −0 snapshot_diff.h
  12. +22 −0 test.js
  13. +8 −1 wscript
View
91 graph_edge.cc
@@ -0,0 +1,91 @@
+#include "graph_edge.h"
+#include "graph_node.h"
+
+using namespace v8;
+
+namespace nodex {
+
+Persistent<ObjectTemplate> GraphEdge::edge_template_;
+
+void GraphEdge::Initialize() {
+ edge_template_ = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
+ edge_template_->SetInternalFieldCount(1);
+ edge_template_->SetAccessor(String::New("type"), GraphEdge::GetType);
+ edge_template_->SetAccessor(String::New("name"), GraphEdge::GetName);
+ edge_template_->SetAccessor(String::New("from"), GraphEdge::GetFrom);
+ edge_template_->SetAccessor(String::New("to"), GraphEdge::GetTo);
+}
+
+Handle<Value> GraphEdge::GetType(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ HeapGraphEdge::Type type = static_cast<HeapGraphEdge*>(ptr)->GetType();
+ Local<String> t;
+ switch(type) {
+ case HeapGraphEdge::kContextVariable :
+ t = String::New("ContextVariable");
+ break;
+ case HeapGraphEdge::kElement :
+ t = String::New("Element");
+ break;
+ case HeapGraphEdge::kProperty :
+ t = String::New("Property");
+ break;
+ case HeapGraphEdge::kInternal :
+ t = String::New("Internal");
+ break;
+ case HeapGraphEdge::kHidden :
+ t = String::New("Hidden");
+ break;
+ case HeapGraphEdge::kShortcut :
+ t = String::New("Shortcut");
+ break;
+ default:
+ t = String::New("Unknown");
+ break;
+ }
+ return scope.Close(t);
+}
+
+Handle<Value> GraphEdge::GetName(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ Handle<Value> title = static_cast<HeapGraphEdge*>(ptr)->GetName();
+ return scope.Close(title);
+}
+
+Handle<Value> GraphEdge::GetFrom(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphNode* node = static_cast<HeapGraphEdge*>(ptr)->GetFromNode();
+ return scope.Close(GraphNode::New(node));
+}
+
+Handle<Value> GraphEdge::GetTo(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphNode* node = static_cast<HeapGraphEdge*>(ptr)->GetToNode();
+ return scope.Close(GraphNode::New(node));
+}
+
+Handle<Value> GraphEdge::New(const HeapGraphEdge* edge) {
+ HandleScope scope;
+
+ if (edge_template_.IsEmpty()) {
+ GraphEdge::Initialize();
+ }
+
+ if(!edge) {
+ return Undefined();
+ }
+ else {
+ Local<Object> obj = edge_template_->NewInstance();
+ obj->SetPointerInInternalField(0, const_cast<HeapGraphEdge*>(edge));
+ return scope.Close(obj);
+ }
+}
+}
View
27 graph_edge.h
@@ -0,0 +1,27 @@
+
+
+#ifndef NODE_GRAPH_EDGE_
+#define NODE_GRAPH_EDGE_
+
+#include <v8.h>
+#include <v8-profiler.h>
+
+using namespace v8;
+
+namespace nodex {
+
+class GraphEdge {
+ public:
+ static Handle<Value> New(const HeapGraphEdge* edge);
+
+ private:
+ static Handle<Value> GetType(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetName(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetFrom(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetTo(Local<String> property, const AccessorInfo& info);
+ static void Initialize();
+ static Persistent<ObjectTemplate> edge_template_;
+};
+
+}
+#endif // NODE_GRAPH_EDGE_
View
198 graph_node.cc
@@ -0,0 +1,198 @@
+#include "graph_node.h"
+#include "graph_edge.h"
+#include "graph_path.h"
+
+using namespace v8;
+
+namespace nodex {
+
+Persistent<ObjectTemplate> GraphNode::node_template_;
+
+void GraphNode::Initialize() {
+ node_template_ = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
+ node_template_->SetInternalFieldCount(1);
+ node_template_->SetAccessor(String::New("type"), GraphNode::GetType);
+ node_template_->SetAccessor(String::New("name"), GraphNode::GetName);
+ node_template_->SetAccessor(String::New("id"), GraphNode::GetId);
+ node_template_->SetAccessor(String::New("instancesCount"), GraphNode::GetInstancesCount);
+ node_template_->SetAccessor(String::New("childrenCount"), GraphNode::GetChildrenCount);
+ node_template_->SetAccessor(String::New("retainersCount"), GraphNode::GetRetainersCount);
+ node_template_->SetAccessor(String::New("size"), GraphNode::GetSize);
+ node_template_->SetAccessor(String::New("retainingPathsCount"), GraphNode::GetRetainingPathsCount);
+ node_template_->SetAccessor(String::New("dominatorNode"), GraphNode::GetDominator);
+ node_template_->Set(String::New("getChild"), FunctionTemplate::New(GraphNode::GetChild));
+ node_template_->Set(String::New("retainedSize"), FunctionTemplate::New(GraphNode::GetRetainedSize));
+ node_template_->Set(String::New("getRetainer"), FunctionTemplate::New(GraphNode::GetRetainer));
+ node_template_->Set(String::New("getRetainingPath"), FunctionTemplate::New(GraphNode::GetRetainingPath));
+}
+
+Handle<Value> GraphNode::GetType(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ HeapGraphNode::Type type = static_cast<HeapGraphNode*>(ptr)->GetType();
+ Local<String> t;
+ switch(type) {
+ case HeapGraphNode::kArray :
+ t = String::New("Array");
+ break;
+ case HeapGraphNode::kString :
+ t = String::New("String");
+ break;
+ case HeapGraphNode::kObject :
+ t = String::New("Object");
+ break;
+ case HeapGraphNode::kCode :
+ t = String::New("Code");
+ break;
+ case HeapGraphNode::kClosure :
+ t = String::New("Closure");
+ break;
+ case HeapGraphNode::kRegExp :
+ t = String::New("RegExp");
+ break;
+ case HeapGraphNode::kHeapNumber :
+ t = String::New("HeapNumber");
+ break;
+ default:
+ t = String::New("Hidden");
+ break;
+ }
+ return scope.Close(t);
+}
+
+Handle<Value> GraphNode::GetName(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ Handle<String> title = static_cast<HeapGraphNode*>(ptr)->GetName();
+ return scope.Close(title);
+}
+
+Handle<Value> GraphNode::GetId(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ uint64_t id = static_cast<HeapGraphNode*>(ptr)->GetId();
+ return scope.Close(Integer::NewFromUnsigned(id));
+}
+
+Handle<Value> GraphNode::GetInstancesCount(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ int32_t count = static_cast<HeapGraphNode*>(ptr)->GetInstancesCount();
+ return scope.Close(Integer::New(count));
+}
+
+Handle<Value> GraphNode::GetChildrenCount(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ int32_t count = static_cast<HeapGraphNode*>(ptr)->GetChildrenCount();
+ return scope.Close(Integer::New(count));
+}
+
+Handle<Value> GraphNode::GetRetainersCount(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ int32_t count = static_cast<HeapGraphNode*>(ptr)->GetRetainersCount();
+ return scope.Close(Integer::New(count));
+}
+
+Handle<Value> GraphNode::GetSize(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ int32_t count = static_cast<HeapGraphNode*>(ptr)->GetSelfSize();
+ return scope.Close(Integer::New(count));
+}
+
+Handle<Value> GraphNode::GetChild(const Arguments& args) {
+ HandleScope scope;
+ if (args.Length() < 1) {
+ return ThrowException(Exception::Error(String::New("No index specified")));
+ } else if (!args[0]->IsInt32()) {
+ return ThrowException(Exception::Error(String::New("Argument must be integer")));
+ }
+ int32_t index = args[0]->Int32Value();
+ Handle<Object> self = args.This();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphEdge* edge = static_cast<HeapGraphNode*>(ptr)->GetChild(index);
+ return scope.Close(GraphEdge::New(edge));
+}
+
+Handle<Value> GraphNode::GetRetainedSize(const Arguments& args) {
+ HandleScope scope;
+ bool exact = false;
+ if (args.Length() > 0) {
+ exact = args[0]->BooleanValue();
+ }
+ Handle<Object> self = args.This();
+ void* ptr = self->GetPointerFromInternalField(0);
+ int32_t size = static_cast<HeapGraphNode*>(ptr)->GetRetainedSize(exact);
+ return scope.Close(Integer::New(size));
+}
+
+Handle<Value> GraphNode::GetRetainer(const Arguments& args) {
+ HandleScope scope;
+ if (args.Length() < 1) {
+ return ThrowException(Exception::Error(String::New("No index specified")));
+ } else if (!args[0]->IsInt32()) {
+ return ThrowException(Exception::Error(String::New("Argument must be integer")));
+ }
+ int32_t index = args[0]->Int32Value();
+ Handle<Object> self = args.This();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphEdge* edge = static_cast<HeapGraphNode*>(ptr)->GetRetainer(index);
+ return scope.Close(GraphEdge::New(edge));
+}
+
+Handle<Value> GraphNode::GetRetainingPathsCount(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ int32_t count = static_cast<HeapGraphNode*>(ptr)->GetRetainingPathsCount();
+ return scope.Close(Integer::New(count));
+}
+
+Handle<Value> GraphNode::GetRetainingPath(const Arguments& args) {
+ HandleScope scope;
+ if (args.Length() < 1) {
+ return ThrowException(Exception::Error(String::New("No index specified")));
+ } else if (!args[0]->IsInt32()) {
+ return ThrowException(Exception::Error(String::New("Argument must be integer")));
+ }
+ int32_t index = args[0]->Int32Value();
+ Handle<Object> self = args.This();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphPath* path = static_cast<HeapGraphNode*>(ptr)->GetRetainingPath(index);
+ return scope.Close(GraphPath::New(path));
+}
+
+Handle<Value> GraphNode::GetDominator(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphNode* node = static_cast<HeapGraphNode*>(ptr)->GetDominatorNode();
+ return scope.Close(GraphNode::New(node));
+}
+
+Handle<Value> GraphNode::New(const HeapGraphNode* node) {
+ HandleScope scope;
+
+ if (node_template_.IsEmpty()) {
+ GraphNode::Initialize();
+ }
+
+ if(!node) {
+ return Undefined();
+ }
+ else {
+ Local<Object> obj = node_template_->NewInstance();
+ obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
+ return scope.Close(obj);
+ }
+}
+}
View
36 graph_node.h
@@ -0,0 +1,36 @@
+
+
+#ifndef NODE_GRAPH_NODE_
+#define NODE_GRAPH_NODE_
+
+#include <v8.h>
+#include <v8-profiler.h>
+
+using namespace v8;
+
+namespace nodex {
+
+class GraphNode {
+ public:
+ static Handle<Value> New(const HeapGraphNode* node);
+
+ private:
+ static Handle<Value> GetType(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetName(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetId(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetInstancesCount(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetChildrenCount(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetRetainersCount(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetSize(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetChild(const Arguments& args);
+ static Handle<Value> GetRetainedSize(const Arguments& args);
+ static Handle<Value> GetRetainer(const Arguments& args);
+ static Handle<Value> GetRetainingPathsCount(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetRetainingPath(const Arguments& args);
+ static Handle<Value> GetDominator(Local<String> property, const AccessorInfo& info);
+ static void Initialize();
+ static Persistent<ObjectTemplate> node_template_;
+};
+
+}
+#endif // NODE_GRAPH_NODE_
View
74 graph_path.cc
@@ -0,0 +1,74 @@
+#include "graph_path.h"
+#include "graph_node.h"
+#include "graph_edge.h"
+
+using namespace v8;
+
+namespace nodex {
+
+Persistent<ObjectTemplate> GraphPath::path_template_;
+
+void GraphPath::Initialize() {
+ path_template_ = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
+ path_template_->SetInternalFieldCount(1);
+ path_template_->SetAccessor(String::New("edgesCount"), GraphPath::GetEdgesCount);
+ path_template_->SetAccessor(String::New("from"), GraphPath::GetFromNode);
+ path_template_->SetAccessor(String::New("to"), GraphPath::GetToNode);
+ path_template_->Set(String::New("getEdge"), FunctionTemplate::New(GraphPath::GetEdge));
+}
+
+Handle<Value> GraphPath::GetEdgesCount(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ int32_t count = static_cast<HeapGraphPath*>(ptr)->GetEdgesCount();
+ return scope.Close(Integer::New(count));
+}
+
+Handle<Value> GraphPath::GetEdge(const Arguments& args) {
+ HandleScope scope;
+ if (args.Length() < 1) {
+ return ThrowException(Exception::Error(String::New("No index specified")));
+ } else if (!args[0]->IsInt32()) {
+ return ThrowException(Exception::Error(String::New("Argument must be integer")));
+ }
+ int32_t index = args[0]->Int32Value();
+ Handle<Object> self = args.This();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphEdge* edge = static_cast<HeapGraphPath*>(ptr)->GetEdge(index);
+ return scope.Close(GraphEdge::New(edge));
+}
+
+Handle<Value> GraphPath::GetFromNode(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphNode* node = static_cast<HeapGraphPath*>(ptr)->GetFromNode();
+ return scope.Close(GraphNode::New(node));
+}
+
+Handle<Value> GraphPath::GetToNode(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphNode* node = static_cast<HeapGraphPath*>(ptr)->GetToNode();
+ return scope.Close(GraphNode::New(node));
+}
+
+Handle<Value> GraphPath::New(const HeapGraphPath* path) {
+ HandleScope scope;
+
+ if (path_template_.IsEmpty()) {
+ GraphPath::Initialize();
+ }
+
+ if(!path) {
+ return Undefined();
+ }
+ else {
+ Local<Object> obj = path_template_->NewInstance();
+ obj->SetPointerInInternalField(0, const_cast<HeapGraphPath*>(path));
+ return scope.Close(obj);
+ }
+}
+}
View
27 graph_path.h
@@ -0,0 +1,27 @@
+
+
+#ifndef NODE_GRAPH_PATH_
+#define NODE_GRAPH_PATH_
+
+#include <v8.h>
+#include <v8-profiler.h>
+
+using namespace v8;
+
+namespace nodex {
+
+class GraphPath {
+ public:
+ static Handle<Value> New(const HeapGraphPath* path);
+
+ private:
+ static Handle<Value> GetEdgesCount(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetToNode(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetFromNode(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetEdge(const Arguments& args);
+ static void Initialize();
+ static Persistent<ObjectTemplate> path_template_;
+};
+
+}
+#endif // NODE_GRAPH_PATH_
View
495 heap.cc
@@ -1,431 +1,11 @@
#include <v8.h>
#include <v8-profiler.h>
#include <node.h>
+#include "snapshot.h"
using namespace v8;
using namespace node;
-
-static Persistent<ObjectTemplate> snapshot_template;
-static Persistent<ObjectTemplate> graph_node_template;
-static Persistent<ObjectTemplate> graph_edge_template;
-static Persistent<ObjectTemplate> graph_path_template;
-static Persistent<ObjectTemplate> graph_diff_template;
-
-
-static Handle<Value> GetSnapshotUid(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- uint32_t uid = static_cast<HeapSnapshot*>(ptr)->GetUid();
- return scope.Close(Integer::NewFromUnsigned(uid));
-}
-
-
-static Handle<Value> GetSnapshotTitle(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- Handle<String> title = static_cast<HeapSnapshot*>(ptr)->GetTitle();
- return scope.Close(title);
-}
-
-static Handle<Value> GetSnapshotRoot(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphNode* node = static_cast<HeapSnapshot*>(ptr)->GetRoot();
- if(!node) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_node_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetSnapshotType(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- HeapSnapshot::Type type = static_cast<HeapSnapshot*>(ptr)->GetType();
- Local<String> t;
- switch(type) {
- case HeapSnapshot::kFull :
- t = String::New("Full");
- break;
- case HeapSnapshot::kAggregated :
- t = String::New("Aggregated");
- break;
- default:
- t = String::New("Unknown");
- break;
- }
- return scope.Close(t);
-}
-
-static Handle<Value> SnapshotCompare(const Arguments& args) {
- HandleScope scope;
- if (args.Length() < 1) {
- return ThrowException(Exception::Error(String::New("No index specified")));
- }
- Handle<Object> other = args[0]->ToObject();
- Handle<Object> self = args.This();
-
- void* ptr = self->GetPointerFromInternalField(0);
-
- void* optr = other->GetPointerFromInternalField(0);
-
- const HeapSnapshotsDiff* diff = static_cast<HeapSnapshot*>(ptr)->CompareWith(static_cast<HeapSnapshot*>(optr));
- if(!diff) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_diff_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapSnapshotsDiff*>(diff));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetNodeType(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- HeapGraphNode::Type type = static_cast<HeapGraphNode*>(ptr)->GetType();
- Local<String> t;
- switch(type) {
- case HeapGraphNode::kArray :
- t = String::New("Array");
- break;
- case HeapGraphNode::kString :
- t = String::New("String");
- break;
- case HeapGraphNode::kObject :
- t = String::New("Object");
- break;
- case HeapGraphNode::kCode :
- t = String::New("Code");
- break;
- case HeapGraphNode::kClosure :
- t = String::New("Closure");
- break;
- case HeapGraphNode::kRegExp :
- t = String::New("RegExp");
- break;
- case HeapGraphNode::kHeapNumber :
- t = String::New("HeapNumber");
- break;
- default:
- t = String::New("Hidden");
- break;
- }
- return scope.Close(t);
-}
-
-static Handle<Value> GetNodeName(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- Handle<String> title = static_cast<HeapGraphNode*>(ptr)->GetName();
- return scope.Close(title);
-}
-
-static Handle<Value> GetNodeId(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- uint64_t id = static_cast<HeapGraphNode*>(ptr)->GetId();
- return scope.Close(Integer::NewFromUnsigned(id));
-}
-
-static Handle<Value> GetNodeInstancesCount(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- int32_t count = static_cast<HeapGraphNode*>(ptr)->GetInstancesCount();
- return scope.Close(Integer::New(count));
-}
-
-static Handle<Value> GetNodeChildrenCount(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- int32_t count = static_cast<HeapGraphNode*>(ptr)->GetChildrenCount();
- return scope.Close(Integer::New(count));
-}
-
-static Handle<Value> GetNodeRetainersCount(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- int32_t count = static_cast<HeapGraphNode*>(ptr)->GetRetainersCount();
- return scope.Close(Integer::New(count));
-}
-
-static Handle<Value> GetNodeSize(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- int32_t count = static_cast<HeapGraphNode*>(ptr)->GetSelfSize();
- return scope.Close(Integer::New(count));
-}
-
-static Handle<Value> GetNodeChild(const Arguments& args) {
- HandleScope scope;
- if (args.Length() < 1) {
- return ThrowException(Exception::Error(String::New("No index specified")));
- } else if (!args[0]->IsInt32()) {
- return ThrowException(Exception::Error(String::New("Argument must be integer")));
- }
- int32_t index = args[0]->Int32Value();
- Handle<Object> self = args.This();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphEdge* edge = static_cast<HeapGraphNode*>(ptr)->GetChild(index);
- if(!edge) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_edge_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphEdge*>(edge));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetNodeRetainedSize(const Arguments& args) {
- HandleScope scope;
- bool exact = false;
- if (args.Length() > 0) {
- exact = args[0]->BooleanValue();
- }
- Handle<Object> self = args.This();
- void* ptr = self->GetPointerFromInternalField(0);
- int32_t size = static_cast<HeapGraphNode*>(ptr)->GetRetainedSize(exact);
- return scope.Close(Integer::New(size));
-}
-
-static Handle<Value> GetNodeRetainer(const Arguments& args) {
- HandleScope scope;
- if (args.Length() < 1) {
- return ThrowException(Exception::Error(String::New("No index specified")));
- } else if (!args[0]->IsInt32()) {
- return ThrowException(Exception::Error(String::New("Argument must be integer")));
- }
- int32_t index = args[0]->Int32Value();
- Handle<Object> self = args.This();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphEdge* edge = static_cast<HeapGraphNode*>(ptr)->GetRetainer(index);
- if(!edge) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_edge_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphEdge*>(edge));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetNodeRetainingPathsCount(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- int32_t count = static_cast<HeapGraphNode*>(ptr)->GetRetainingPathsCount();
- return scope.Close(Integer::New(count));
-}
-
-static Handle<Value> GetNodeRetainingPath(const Arguments& args) {
- HandleScope scope;
- if (args.Length() < 1) {
- return ThrowException(Exception::Error(String::New("No index specified")));
- } else if (!args[0]->IsInt32()) {
- return ThrowException(Exception::Error(String::New("Argument must be integer")));
- }
- int32_t index = args[0]->Int32Value();
- Handle<Object> self = args.This();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphPath* path = static_cast<HeapGraphNode*>(ptr)->GetRetainingPath(index);
- if(!path) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_path_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphPath*>(path));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetNodeDominator(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphNode* node = static_cast<HeapGraphNode*>(ptr)->GetDominatorNode();
- if(!node) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_node_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetEdgeType(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- HeapGraphEdge::Type type = static_cast<HeapGraphEdge*>(ptr)->GetType();
- Local<String> t;
- switch(type) {
- case HeapGraphEdge::kContextVariable :
- t = String::New("ContextVariable");
- break;
- case HeapGraphEdge::kElement :
- t = String::New("Element");
- break;
- case HeapGraphEdge::kProperty :
- t = String::New("Property");
- break;
- case HeapGraphEdge::kInternal :
- t = String::New("Internal");
- break;
- case HeapGraphEdge::kHidden :
- t = String::New("Hidden");
- break;
- case HeapGraphEdge::kShortcut :
- t = String::New("Shortcut");
- break;
- default:
- t = String::New("Unknown");
- break;
- }
- return scope.Close(t);
-}
-
-static Handle<Value> GetEdgeName(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- Handle<Value> title = static_cast<HeapGraphEdge*>(ptr)->GetName();
- return scope.Close(title);
-}
-
-static Handle<Value> GetEdgeFrom(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphNode* node = static_cast<HeapGraphEdge*>(ptr)->GetFromNode();
- if(!node) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_node_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetEdgeTo(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphNode* node = static_cast<HeapGraphEdge*>(ptr)->GetToNode();
- if(!node) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_node_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetPathEdgesCount(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- int32_t count = static_cast<HeapGraphPath*>(ptr)->GetEdgesCount();
- return scope.Close(Integer::New(count));
-}
-
-static Handle<Value> GetPathEdge(const Arguments& args) {
- HandleScope scope;
- if (args.Length() < 1) {
- return ThrowException(Exception::Error(String::New("No index specified")));
- } else if (!args[0]->IsInt32()) {
- return ThrowException(Exception::Error(String::New("Argument must be integer")));
- }
- int32_t index = args[0]->Int32Value();
- Handle<Object> self = args.This();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphEdge* edge = static_cast<HeapGraphPath*>(ptr)->GetEdge(index);
- if(!edge) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_edge_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphEdge*>(edge));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetPathFrom(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphNode* node = static_cast<HeapGraphPath*>(ptr)->GetFromNode();
- if(!node) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_node_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetPathTo(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphNode* node = static_cast<HeapGraphPath*>(ptr)->GetToNode();
- if(!node) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_node_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetDiffAdditions(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphNode* node = static_cast<HeapSnapshotsDiff*>(ptr)->GetAdditionsRoot();
- if(!node) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_node_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
- return scope.Close(obj);
- }
-}
-
-static Handle<Value> GetDiffDeletions(Local<String> property, const AccessorInfo& info) {
- HandleScope scope;
- Local<Object> self = info.Holder();
- void* ptr = self->GetPointerFromInternalField(0);
- const HeapGraphNode* node = static_cast<HeapSnapshotsDiff*>(ptr)->GetDeletionsRoot();
- if(!node) {
- return Undefined();
- }
- else {
- Local<Object> obj = graph_node_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapGraphNode*>(node));
- return scope.Close(obj);
- }
-}
+using namespace nodex;
static Handle<Value> TakeSnapshot(const Arguments& args) {
HandleScope scope;
@@ -434,15 +14,7 @@ static Handle<Value> TakeSnapshot(const Arguments& args) {
title = args[0]->ToString();
}
const HeapSnapshot* snapshot = HeapProfiler::TakeSnapshot(title);
- if(!snapshot) {
- return Undefined();
- }
- else {
- Local<Object> obj = snapshot_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapSnapshot*>(snapshot));
- //obj->SetInternalField(0, External::New(const_cast<HeapSnapshot*>(snapshot)));
- return scope.Close(obj);
- }
+ return scope.Close(Snapshot::New(snapshot));
}
static Handle<Value> GetSnapshot(const Arguments& args) {
@@ -454,14 +26,7 @@ static Handle<Value> GetSnapshot(const Arguments& args) {
}
int32_t index = args[0]->Int32Value();
const HeapSnapshot* snapshot = HeapProfiler::GetSnapshot(index);
- if(!snapshot) {
- return Undefined();
- }
- else {
- Local<Object> obj = snapshot_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapSnapshot*>(snapshot));
- return scope.Close(obj);
- }
+ return scope.Close(Snapshot::New(snapshot));
}
static Handle<Value> FindSnapshot(const Arguments& args) {
@@ -471,14 +36,7 @@ static Handle<Value> FindSnapshot(const Arguments& args) {
}
uint32_t uid = args[0]->Uint32Value();
const HeapSnapshot* snapshot = HeapProfiler::FindSnapshot(uid);
- if(!snapshot) {
- return Undefined();
- }
- else {
- Local<Object> obj = snapshot_template->NewInstance();
- obj->SetPointerInInternalField(0, const_cast<HeapSnapshot*>(snapshot));
- return scope.Close(obj);
- }
+ return scope.Close(Snapshot::New(snapshot));
}
static Handle<Value> GetSnapshotsCount(const Arguments& args) {
@@ -489,49 +47,6 @@ static Handle<Value> GetSnapshotsCount(const Arguments& args) {
extern "C" void init(Handle<Object> target) {
HandleScope scope;
- snapshot_template = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
- snapshot_template->SetInternalFieldCount(1);
- snapshot_template->SetAccessor(String::New("title"), GetSnapshotTitle);
- snapshot_template->SetAccessor(String::New("uid"), GetSnapshotUid);
- snapshot_template->SetAccessor(String::New("root"), GetSnapshotRoot);
- snapshot_template->SetAccessor(String::New("type"), GetSnapshotType);
- snapshot_template->Set(String::New("compareWith"), FunctionTemplate::New(SnapshotCompare));
-
- graph_node_template = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
- graph_node_template->SetInternalFieldCount(1);
- graph_node_template->SetAccessor(String::New("type"), GetNodeType);
- graph_node_template->SetAccessor(String::New("name"), GetNodeName);
- graph_node_template->SetAccessor(String::New("id"), GetNodeId);
- graph_node_template->SetAccessor(String::New("instancesCount"), GetNodeInstancesCount);
- graph_node_template->SetAccessor(String::New("childrenCount"), GetNodeChildrenCount);
- graph_node_template->SetAccessor(String::New("retainersCount"), GetNodeRetainersCount);
- graph_node_template->SetAccessor(String::New("size"), GetNodeSize);
- graph_node_template->SetAccessor(String::New("retainingPathsCount"), GetNodeRetainingPathsCount);
- graph_node_template->SetAccessor(String::New("dominatorNode"), GetNodeDominator);
- graph_node_template->Set(String::New("getChild"), FunctionTemplate::New(GetNodeChild));
- graph_node_template->Set(String::New("retainedSize"), FunctionTemplate::New(GetNodeRetainedSize));
- graph_node_template->Set(String::New("getRetainer"), FunctionTemplate::New(GetNodeRetainer));
- graph_node_template->Set(String::New("getRetainingPath"), FunctionTemplate::New(GetNodeRetainingPath));
-
- graph_edge_template = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
- graph_edge_template->SetInternalFieldCount(1);
- graph_edge_template->SetAccessor(String::New("type"), GetEdgeType);
- graph_edge_template->SetAccessor(String::New("name"), GetEdgeName);
- graph_edge_template->SetAccessor(String::New("from"), GetEdgeFrom);
- graph_edge_template->SetAccessor(String::New("to"), GetEdgeTo);
-
- graph_path_template = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
- graph_path_template->SetInternalFieldCount(1);
- graph_path_template->SetAccessor(String::New("edgesCount"), GetPathEdgesCount);
- graph_path_template->SetAccessor(String::New("from"), GetPathFrom);
- graph_path_template->SetAccessor(String::New("to"), GetPathTo);
- graph_path_template->Set(String::New("getEdge"), FunctionTemplate::New(GetPathEdge));
-
- graph_diff_template = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
- graph_diff_template->SetInternalFieldCount(1);
- graph_diff_template->SetAccessor(String::New("additions"), GetDiffAdditions);
- graph_diff_template->SetAccessor(String::New("deletions"), GetDiffDeletions);
-
NODE_SET_METHOD(target, "takeSnapshot", TakeSnapshot);
NODE_SET_METHOD(target, "getSnapshot", GetSnapshot);
NODE_SET_METHOD(target, "findSnapshot", FindSnapshot);
View
98 snapshot.cc
@@ -0,0 +1,98 @@
+#include "snapshot.h"
+#include "snapshot_diff.h"
+#include "graph_node.h"
+
+using namespace v8;
+
+namespace nodex {
+
+Persistent<ObjectTemplate> Snapshot::snapshot_template_;
+
+void Snapshot::Initialize() {
+ snapshot_template_ = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
+ snapshot_template_->SetInternalFieldCount(1);
+ snapshot_template_->SetAccessor(String::New("title"), Snapshot::GetTitle);
+ snapshot_template_->SetAccessor(String::New("uid"), Snapshot::GetUid);
+ snapshot_template_->SetAccessor(String::New("root"), Snapshot::GetRoot);
+ snapshot_template_->SetAccessor(String::New("type"), Snapshot::GetType);
+ snapshot_template_->Set(String::New("compareWith"), FunctionTemplate::New(Snapshot::CompareWith));
+}
+
+Handle<Value> Snapshot::GetUid(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ uint32_t uid = static_cast<HeapSnapshot*>(ptr)->GetUid();
+ return scope.Close(Integer::NewFromUnsigned(uid));
+}
+
+
+Handle<Value> Snapshot::GetTitle(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ Handle<String> title = static_cast<HeapSnapshot*>(ptr)->GetTitle();
+ return scope.Close(title);
+}
+
+Handle<Value> Snapshot::GetRoot(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphNode* node = static_cast<HeapSnapshot*>(ptr)->GetRoot();
+ return scope.Close(GraphNode::New(node));
+}
+
+Handle<Value> Snapshot::GetType(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ HeapSnapshot::Type type = static_cast<HeapSnapshot*>(ptr)->GetType();
+ Local<String> t;
+ switch(type) {
+ case HeapSnapshot::kFull :
+ t = String::New("Full");
+ break;
+ case HeapSnapshot::kAggregated :
+ t = String::New("Aggregated");
+ break;
+ default:
+ t = String::New("Unknown");
+ break;
+ }
+ return scope.Close(t);
+}
+
+Handle<Value> Snapshot::CompareWith(const Arguments& args) {
+ HandleScope scope;
+ if (args.Length() < 1) {
+ return ThrowException(Exception::Error(String::New("No index specified")));
+ }
+ Handle<Object> other = args[0]->ToObject();
+ Handle<Object> self = args.This();
+
+ void* ptr = self->GetPointerFromInternalField(0);
+
+ void* optr = other->GetPointerFromInternalField(0);
+
+ const HeapSnapshotsDiff* diff = static_cast<HeapSnapshot*>(ptr)->CompareWith(static_cast<HeapSnapshot*>(optr));
+ return scope.Close(SnapshotDiff::New(diff));
+}
+
+Handle<Value> Snapshot::New(const HeapSnapshot* snapshot) {
+ HandleScope scope;
+
+ if (snapshot_template_.IsEmpty()) {
+ Snapshot::Initialize();
+ }
+
+ if(!snapshot) {
+ return Undefined();
+ }
+ else {
+ Local<Object> obj = snapshot_template_->NewInstance();
+ obj->SetPointerInInternalField(0, const_cast<HeapSnapshot*>(snapshot));
+ return scope.Close(obj);
+ }
+}
+}
View
28 snapshot.h
@@ -0,0 +1,28 @@
+
+
+#ifndef NODE_SNAPSHOT_
+#define NODE_SNAPSHOT_
+
+#include <v8.h>
+#include <v8-profiler.h>
+
+using namespace v8;
+
+namespace nodex {
+
+class Snapshot {
+ public:
+ static Handle<Value> New(const HeapSnapshot* snapshot);
+
+ private:
+ static Handle<Value> GetUid(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetTitle(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetRoot(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetType(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> CompareWith(const Arguments& args);
+ static void Initialize();
+ static Persistent<ObjectTemplate> snapshot_template_;
+};
+
+}
+#endif // NODE_SNAPSHOT_
View
50 snapshot_diff.cc
@@ -0,0 +1,50 @@
+#include "snapshot_diff.h"
+#include "graph_node.h"
+
+using namespace v8;
+
+namespace nodex {
+
+Persistent<ObjectTemplate> SnapshotDiff::diff_template_;
+
+void SnapshotDiff::Initialize() {
+ diff_template_ = Persistent<ObjectTemplate>::New(ObjectTemplate::New());
+ diff_template_->SetInternalFieldCount(1);
+ diff_template_->SetAccessor(String::New("additions"), SnapshotDiff::GetAdditions);
+ diff_template_->SetAccessor(String::New("deletions"), SnapshotDiff::GetDeletions);
+}
+
+Handle<Value> SnapshotDiff::GetAdditions(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphNode* node = static_cast<HeapSnapshotsDiff*>(ptr)->GetAdditionsRoot();
+ return scope.Close(GraphNode::New(node));
+}
+
+Handle<Value> SnapshotDiff::GetDeletions(Local<String> property, const AccessorInfo& info) {
+ HandleScope scope;
+ Local<Object> self = info.Holder();
+ void* ptr = self->GetPointerFromInternalField(0);
+ const HeapGraphNode* node = static_cast<HeapSnapshotsDiff*>(ptr)->GetDeletionsRoot();
+ return scope.Close(GraphNode::New(node));
+}
+
+Handle<Value> SnapshotDiff::New(const HeapSnapshotsDiff* diff) {
+ HandleScope scope;
+
+ if (diff_template_.IsEmpty()) {
+ SnapshotDiff::Initialize();
+ }
+
+ if(!diff) {
+ return Undefined();
+ }
+ else {
+ Local<Object> obj = diff_template_->NewInstance();
+ obj->SetPointerInInternalField(0, const_cast<HeapSnapshotsDiff*>(diff));
+ return scope.Close(obj);
+ }
+}
+
+}
View
25 snapshot_diff.h
@@ -0,0 +1,25 @@
+
+
+#ifndef NODE_SNAPSHOT_DIFF_
+#define NODE_SNAPSHOT_DIFF_
+
+#include <v8.h>
+#include <v8-profiler.h>
+
+using namespace v8;
+
+namespace nodex {
+
+class SnapshotDiff {
+ public:
+ static Handle<Value> New(const HeapSnapshotsDiff* diff);
+
+ private:
+ static Handle<Value> GetAdditions(Local<String> property, const AccessorInfo& info);
+ static Handle<Value> GetDeletions(Local<String> property, const AccessorInfo& info);
+ static void Initialize();
+ static Persistent<ObjectTemplate> diff_template_;
+};
+
+}
+#endif // NODE_SNAPSHOT_DIFF_
View
22 test.js
@@ -0,0 +1,22 @@
+var assert = require('assert'),
+ heap = require('./build/default/heap-profiler');
+
+var x = heap.takeSnapshot('hello world');
+
+assert.equal(heap.snapshotCount(), 1);
+assert.equal(x.title, 'hello world');
+var root = x.root;
+assert.notEqual(root, null);
+
+assert.ok(x.root.childrenCount > 0);
+
+for (var i = 0; i < root.childrenCount; i++) {
+ assert.notEqual(root.getChild(i), undefined);
+}
+
+var y = heap.takeSnapshot();
+
+var delta = x.compareWith(y);
+assert.notEqual(delta.additions, null);
+
+console.log('done');
View
9 wscript
@@ -12,4 +12,11 @@ def configure(ctx):
def build(ctx):
t = ctx.new_task_gen('cxx', 'shlib', 'node_addon')
t.target = 'heap-profiler'
- t.source = 'heap.cc'
+ t.source = """
+ snapshot.cc
+ graph_edge.cc
+ graph_node.cc
+ graph_path.cc
+ snapshot_diff.cc
+ heap.cc
+ """

0 comments on commit 400fb8a

Please sign in to comment.