Skip to content

Commit

Permalink
/ applied changes originally performed by deepak1556 in this pull req…
Browse files Browse the repository at this point in the history
…uest: [lloyd#56]
  • Loading branch information
Brandon Papworth committed Sep 11, 2014
1 parent a48f0f3 commit bf95c3e
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 123 deletions.
125 changes: 63 additions & 62 deletions src/heapdiff.cc
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
/*
* 2012|lloyd|http://wtfpl.org
*/

#include "heapdiff.hh"
#include "util.hh"

#include <node.h>

#include <map>
#include <string>
#include <set>
Expand All @@ -15,14 +9,17 @@
#include <stdlib.h> // abs()
#include <time.h> // time()

#include "heapdiff.hh"
#include "util.hh"

using namespace v8;
using namespace node;
using namespace std;

static bool s_inProgress = false;
static time_t s_startTime;

bool heapdiff::HeapDiff::InProgress()
bool heapdiff::HeapDiff::InProgress()
{
return s_inProgress;
}
Expand All @@ -48,29 +45,27 @@ heapdiff::HeapDiff::~HeapDiff()
void
heapdiff::HeapDiff::Initialize ( v8::Handle<v8::Object> target )
{
v8::HandleScope scope;
v8::Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(New);
NanScope();

v8::Local<v8::FunctionTemplate> t = NanNew<v8::FunctionTemplate>(New);
t->InstanceTemplate()->SetInternalFieldCount(1);
t->SetClassName(String::NewSymbol("HeapDiff"));
t->SetClassName(NanNew("HeapDiff"));

NODE_SET_PROTOTYPE_METHOD(t, "end", End);

target->Set(v8::String::NewSymbol( "HeapDiff"), t->GetFunction());
target->Set(NanNew( "HeapDiff"), t->GetFunction());
}

v8::Handle<v8::Value>
heapdiff::HeapDiff::New (const v8::Arguments& args)
NAN_METHOD(heapdiff::HeapDiff::New)
{
// Don't blow up when the caller says "new require('memwatch').HeapDiff()"
// issue #30
// stolen from: https://github.com/kkaefer/node-cpp-modules/commit/bd9432026affafd8450ecfd9b49b7dc647b6d348
if (!args.IsConstructCall()) {
return ThrowException(
Exception::TypeError(
String::New("Use the new operator to create instances of this object.")));
return NanThrowTypeError("Use the new operator to create instances of this object.");
}

v8::HandleScope scope;
NanScope();

// allocate the underlying c++ class and wrap it up in the this pointer
HeapDiff * self = new HeapDiff();
Expand All @@ -79,22 +74,28 @@ heapdiff::HeapDiff::New (const v8::Arguments& args)
// take a snapshot and save a pointer to it
s_inProgress = true;
s_startTime = time(NULL);
self->before = v8::HeapProfiler::TakeSnapshot(v8::String::New(""));

#if (NODE_MODULE_VERSION > 0x000B)
self->before = v8::Isolate::GetCurrent()->GetHeapProfiler()->TakeHeapSnapshot(NanNew<v8::String>(""), NULL);
#else
self->before = v8::HeapProfiler::TakeSnapshot(NanNew<v8::String>(""), HeapSnapshot::kFull, NULL);
#endif

s_inProgress = false;

return args.This();
NanReturnValue(args.This());
}

static string handleToStr(const Handle<Value> & str)
{
String::Utf8Value utfString(str->ToString());
return *utfString;
String::Utf8Value utfString(str->ToString());
return *utfString;
}

static void
buildIDSet(set<uint64_t> * seen, const HeapGraphNode* cur, int & s)
{
v8::HandleScope scope;
NanScope();

// cycle detection
if (seen->find(cur->GetId()) != seen->end()) {
Expand Down Expand Up @@ -210,66 +211,66 @@ static void manageChange(changeset & changes, const HeapGraphNode * node, bool a

static Handle<Value> changesetToObject(changeset & changes)
{
v8::HandleScope scope;
Local<Array> a = Array::New();
NanEscapableScope();
Local<Array> a = NanNew<v8::Array>();

for (changeset::iterator i = changes.begin(); i != changes.end(); i++) {
Local<Object> d = Object::New();
d->Set(String::New("what"), String::New(i->first.c_str()));
d->Set(String::New("size_bytes"), Integer::New(i->second.size));
d->Set(String::New("size"), String::New(mw_util::niceSize(i->second.size).c_str()));
d->Set(String::New("+"), Integer::New(i->second.added));
d->Set(String::New("-"), Integer::New(i->second.released));
Local<Object> d = NanNew<v8::Object>();
d->Set(NanNew("what"), NanNew(i->first.c_str()));
d->Set(NanNew("size_bytes"), NanNew<v8::Number>(i->second.size));
d->Set(NanNew("size"), NanNew(mw_util::niceSize(i->second.size).c_str()));
d->Set(NanNew("+"), NanNew<v8::Number>(i->second.added));
d->Set(NanNew("-"), NanNew<v8::Number>(i->second.released));
a->Set(a->Length(), d);
}

return scope.Close(a);
return NanEscapeScope(a);
}


static v8::Handle<Value>
compare(const v8::HeapSnapshot * before, const v8::HeapSnapshot * after)
{
v8::HandleScope scope;
NanEscapableScope();
int s, diffBytes;

Local<Object> o = Object::New();
Local<Object> o = NanNew<v8::Object>();

// first let's append summary information
Local<Object> b = Object::New();
b->Set(String::New("nodes"), Integer::New(before->GetNodesCount()));
b->Set(String::New("time"), NODE_UNIXTIME_V8(s_startTime));
o->Set(String::New("before"), b);
Local<Object> b = NanNew<v8::Object>();
b->Set(NanNew("nodes"), NanNew(before->GetNodesCount()));
//b->Set(NanNew("time"), s_startTime);
o->Set(NanNew("before"), b);

Local<Object> a = Object::New();
a->Set(String::New("nodes"), Integer::New(after->GetNodesCount()));
a->Set(String::New("time"), NODE_UNIXTIME_V8(time(NULL)));
o->Set(String::New("after"), a);
Local<Object> a = NanNew<v8::Object>();
a->Set(NanNew("nodes"), NanNew(after->GetNodesCount()));
//a->Set(NanNew("time"), time(NULL));
o->Set(NanNew("after"), a);

// now let's get allocations by name
set<uint64_t> beforeIDs, afterIDs;
s = 0;
buildIDSet(&beforeIDs, before->GetRoot(), s);
b->Set(String::New("size_bytes"), Integer::New(s));
b->Set(String::New("size"), String::New(mw_util::niceSize(s).c_str()));
b->Set(NanNew("size_bytes"), NanNew(s));
b->Set(NanNew("size"), NanNew(mw_util::niceSize(s).c_str()));

diffBytes = s;
s = 0;
buildIDSet(&afterIDs, after->GetRoot(), s);
a->Set(String::New("size_bytes"), Integer::New(s));
a->Set(String::New("size"), String::New(mw_util::niceSize(s).c_str()));
a->Set(NanNew("size_bytes"), NanNew(s));
a->Set(NanNew("size"), NanNew(mw_util::niceSize(s).c_str()));

diffBytes = s - diffBytes;

Local<Object> c = Object::New();
c->Set(String::New("size_bytes"), Integer::New(diffBytes));
c->Set(String::New("size"), String::New(mw_util::niceSize(diffBytes).c_str()));
o->Set(String::New("change"), c);
Local<Object> c = NanNew<v8::Object>();
c->Set(NanNew("size_bytes"), NanNew(diffBytes));
c->Set(NanNew("size"), NanNew(mw_util::niceSize(diffBytes).c_str()));
o->Set(NanNew("change"), c);

// before - after will reveal nodes released (memory freed)
vector<uint64_t> changedIDs;
setDiff(beforeIDs, afterIDs, changedIDs);
c->Set(String::New("freed_nodes"), Integer::New(changedIDs.size()));
c->Set(NanNew("freed_nodes"), NanNew<v8::Number>(changedIDs.size()));

// here's where we'll collect all the summary information
changeset changes;
Expand All @@ -285,39 +286,39 @@ compare(const v8::HeapSnapshot * before, const v8::HeapSnapshot * after)
// after - before will reveal nodes added (memory allocated)
setDiff(afterIDs, beforeIDs, changedIDs);

c->Set(String::New("allocated_nodes"), Integer::New(changedIDs.size()));
c->Set(NanNew("allocated_nodes"), NanNew<v8::Number>(changedIDs.size()));

for (unsigned long i = 0; i < changedIDs.size(); i++) {
const HeapGraphNode * n = after->GetNodeById(changedIDs[i]);
manageChange(changes, n, true);
}

c->Set(String::New("details"), changesetToObject(changes));
c->Set(NanNew("details"), changesetToObject(changes));

return scope.Close(o);
return NanEscapeScope(o);
}

v8::Handle<Value>
heapdiff::HeapDiff::End( const Arguments& args )
NAN_METHOD(heapdiff::HeapDiff::End)
{
// take another snapshot and compare them
v8::HandleScope scope;
NanScope();

HeapDiff *t = Unwrap<HeapDiff>( args.This() );

// How shall we deal with double .end()ing? The only reasonable
// approach seems to be an exception, cause nothing else makes
// sense.
if (t->ended) {
return v8::ThrowException(
v8::Exception::Error(
v8::String::New("attempt to end() a HeapDiff that was "
"already ended")));
return NanThrowError("attempt to end() a HeapDiff that was already ended");
}
t->ended = true;

s_inProgress = true;
t->after = v8::HeapProfiler::TakeSnapshot(v8::String::New(""));
#if (NODE_MODULE_VERSION > 0x000B)
t->after = v8::Isolate::GetCurrent()->GetHeapProfiler()->TakeHeapSnapshot(NanNew<v8::String>(""), NULL);
#else
t->after = v8::HeapProfiler::TakeSnapshot(NanNew<v8::String>(""), HeapSnapshot::kFull, NULL);
#endif
s_inProgress = false;

v8::Handle<Value> comparison = compare(t->before, t->after);
Expand All @@ -328,5 +329,5 @@ heapdiff::HeapDiff::End( const Arguments& args )
((HeapSnapshot *) t->after)->Delete();
t->after = NULL;

return scope.Close(comparison);
NanReturnValue(comparison);
}
7 changes: 4 additions & 3 deletions src/heapdiff.hh
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,17 @@
#include <v8.h>
#include <v8-profiler.h>
#include <node.h>
#include <nan.h>

namespace heapdiff
namespace heapdiff
{
class HeapDiff : public node::ObjectWrap
{
public:
static void Initialize ( v8::Handle<v8::Object> target );

static v8::Handle<v8::Value> New( const v8::Arguments& args );
static v8::Handle<v8::Value> End( const v8::Arguments& args );
static NAN_METHOD(New);
static NAN_METHOD(End);
static bool InProgress();

protected:
Expand Down
2 changes: 1 addition & 1 deletion src/init.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
extern "C" {
void init (v8::Handle<v8::Object> target)
{
v8::HandleScope scope;
NanScope();
heapdiff::HeapDiff::Initialize(target);

NODE_SET_METHOD(target, "upon_gc", memwatch::upon_gc);
Expand Down
Loading

0 comments on commit bf95c3e

Please sign in to comment.